LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/codemaker/source/javamaker - javatype.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1164 1211 96.1 %
Date: 2013-07-09 Functions: 47 47 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : #include <list>
      25             : #include <map>
      26             : #include <memory>
      27             : #include <set>
      28             : #include <utility>
      29             : #include <vector>
      30             : 
      31             : #include "codemaker/codemaker.hxx"
      32             : #include "codemaker/exceptiontree.hxx"
      33             : #include "codemaker/generatedtypeset.hxx"
      34             : #include "codemaker/global.hxx"
      35             : #include "codemaker/options.hxx"
      36             : #include "codemaker/typemanager.hxx"
      37             : #include "codemaker/unotype.hxx"
      38             : #include "codemaker/commonjava.hxx"
      39             : #include "rtl/ref.hxx"
      40             : #include "rtl/strbuf.hxx"
      41             : #include "rtl/string.hxx"
      42             : #include "rtl/ustrbuf.hxx"
      43             : #include "rtl/ustring.hxx"
      44             : #include "sal/types.h"
      45             : #include "unoidl/unoidl.hxx"
      46             : 
      47             : #include "classfile.hxx"
      48             : #include "javaoptions.hxx"
      49             : #include "javatype.hxx"
      50             : 
      51             : using codemaker::javamaker::ClassFile;
      52             : 
      53             : namespace {
      54             : 
      55         234 : void appendUnoName(
      56             :     rtl::Reference< TypeManager > const & manager, OUString const & nucleus,
      57             :     sal_Int32 rank, std::vector< OUString > const & arguments,
      58             :     OUStringBuffer * buffer)
      59             : {
      60             :     assert(manager.is());
      61             :     assert(rank >= 0);
      62             :     assert(buffer != 0);
      63         294 :     for (sal_Int32 i = 0; i != rank; ++i) {
      64          60 :         buffer->append("[]");
      65             :     }
      66         234 :     buffer->append(nucleus);
      67         234 :     if (!arguments.empty()) {
      68         105 :         buffer->append('<');
      69         720 :         for (std::vector< OUString >::const_iterator i(arguments.begin());
      70         480 :              i != arguments.end(); ++i)
      71             :         {
      72         135 :             if (i != arguments.begin()) {
      73          30 :                 buffer->append(',');
      74             :             }
      75         135 :             OUString n;
      76             :             sal_Int32 k;
      77         270 :             std::vector< OUString > args;
      78         135 :             manager->decompose(*i, false, &n, &k, &args, 0);
      79         135 :             appendUnoName(manager, n, k, args, buffer);
      80         135 :         }
      81         105 :         buffer->append('>');
      82             :     }
      83         234 : }
      84             : 
      85             : // Translate the name of a UNOIDL entity (enum type, plain struct type,
      86             : // polymorphic struct type template, or interface type, decomposed into nucleus,
      87             : // sequence rank, and template arguments) into a core UNO type name:
      88          99 : OUString createUnoName(
      89             :     rtl::Reference< TypeManager > const & manager, OUString const & nucleus,
      90             :     sal_Int32 rank, std::vector< OUString > const & arguments)
      91             : {
      92          99 :     OUStringBuffer buf;
      93          99 :     appendUnoName(manager, nucleus, rank, arguments, &buf);
      94          99 :     return buf.makeStringAndClear();
      95             : }
      96             : 
      97             : typedef std::set< OUString > Dependencies;
      98             : 
      99             : enum SpecialType {
     100             :     SPECIAL_TYPE_NONE,
     101             :     SPECIAL_TYPE_ANY,
     102             :     SPECIAL_TYPE_UNSIGNED,
     103             :     SPECIAL_TYPE_INTERFACE
     104             : };
     105             : 
     106        5620 : bool isSpecialType(SpecialType special) {
     107        5620 :     return special >= SPECIAL_TYPE_UNSIGNED;
     108             : }
     109             : 
     110         356 : OString translateUnoidlEntityNameToJavaFullyQualifiedName(
     111             :     OUString const & name, OString const & prefix)
     112             : {
     113             :     assert(!name.startsWith("[]"));
     114             :     assert(name.indexOf('<') == -1);
     115         356 :     sal_Int32 i = name.lastIndexOf('.') + 1;
     116             :     return codemaker::convertString(name.copy(0, i)).replace('.', '/')
     117         712 :         + codemaker::java::translateUnoToJavaIdentifier(
     118        1068 :             codemaker::convertString(name.copy(i)), prefix);
     119             : }
     120             : 
     121       62101 : struct PolymorphicUnoType {
     122       13603 :     PolymorphicUnoType(): kind(KIND_NONE) {}
     123             : 
     124             :     enum Kind { KIND_NONE, KIND_STRUCT, KIND_SEQUENCE };
     125             :     Kind kind;
     126             :     OUString name;
     127             : };
     128             : 
     129             : SpecialType translateUnoTypeToDescriptor(
     130             :     rtl::Reference< TypeManager > const & manager, OUString const & type,
     131             :     bool array, bool classType, Dependencies * dependencies,
     132             :     OStringBuffer * descriptor, OStringBuffer * signature,
     133             :     bool * needsSignature, PolymorphicUnoType * polymorphicUnoType);
     134             : 
     135       23908 : SpecialType translateUnoTypeToDescriptor(
     136             :     rtl::Reference< TypeManager > const & manager,
     137             :     codemaker::UnoType::Sort sort, OUString const & nucleus, sal_Int32 rank,
     138             :     std::vector< OUString > const & arguments, bool array, bool classType,
     139             :     Dependencies * dependencies, OStringBuffer * descriptor,
     140             :     OStringBuffer * signature, bool * needsSignature,
     141             :     PolymorphicUnoType * polymorphicUnoType)
     142             : {
     143             :     assert(rank >= 0);
     144             :     assert((signature == 0) == (needsSignature == 0));
     145             :     assert(
     146             :         arguments.empty()
     147             :         == (sort
     148             :             != codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE));
     149       23908 :     if (rank > 0xFF - (array ? 1 : 0)) {
     150             :         throw CannotDumpException(
     151           0 :             "Too many array dimensions for Java class file format");
     152             :     }
     153       23908 :     if (array) {
     154         158 :         ++rank;
     155             :     }
     156       25705 :     for (sal_Int32 i = 0; i != rank; ++i) {
     157        1797 :         if (descriptor != 0) {
     158        1773 :             descriptor->append('[');
     159             :         }
     160        1797 :         if (signature != 0) {
     161        1668 :             signature->append('[');
     162             :         }
     163             :     }
     164       23908 :     if (polymorphicUnoType != 0) {
     165       13595 :         if (sort
     166             :             == codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE)
     167             :         {
     168             :             polymorphicUnoType->kind = rank == 0
     169             :                 ? PolymorphicUnoType::KIND_STRUCT
     170          30 :                 : PolymorphicUnoType::KIND_SEQUENCE;
     171          60 :             polymorphicUnoType->name = createUnoName(
     172          30 :                 manager, nucleus, rank, arguments);
     173             :         } else {
     174       13565 :             polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE;
     175             :         }
     176             :     }
     177       23908 :     switch (sort) {
     178             :     case codemaker::UnoType::SORT_VOID:
     179             :     case codemaker::UnoType::SORT_BOOLEAN:
     180             :     case codemaker::UnoType::SORT_BYTE:
     181             :     case codemaker::UnoType::SORT_SHORT:
     182             :     case codemaker::UnoType::SORT_UNSIGNED_SHORT:
     183             :     case codemaker::UnoType::SORT_LONG:
     184             :     case codemaker::UnoType::SORT_UNSIGNED_LONG:
     185             :     case codemaker::UnoType::SORT_HYPER:
     186             :     case codemaker::UnoType::SORT_UNSIGNED_HYPER:
     187             :     case codemaker::UnoType::SORT_FLOAT:
     188             :     case codemaker::UnoType::SORT_DOUBLE:
     189             :     case codemaker::UnoType::SORT_CHAR:
     190             :     case codemaker::UnoType::SORT_STRING:
     191             :     case codemaker::UnoType::SORT_TYPE:
     192             :     case codemaker::UnoType::SORT_ANY:
     193             :         {
     194             :             static char const * const
     195             :                 simpleTypeDescriptors[codemaker::UnoType::SORT_ANY + 1][2] = {
     196             :                 { "V", "Ljava/lang/Void;" },
     197             :                 { "Z", "Ljava/lang/Boolean;" },
     198             :                 { "B", "Ljava/lang/Byte;" },
     199             :                 { "S", "Ljava/lang/Short;" },
     200             :                 { "S", "Ljava/lang/Short;" },
     201             :                 { "I", "Ljava/lang/Integer;" },
     202             :                 { "I", "Ljava/lang/Integer;" },
     203             :                 { "J", "Ljava/lang/Long;" },
     204             :                 { "J", "Ljava/lang/Long;" },
     205             :                 { "F", "Ljava/lang/Float;" },
     206             :                 { "D", "Ljava/lang/Double;" },
     207             :                 { "C", "Ljava/lang/Character;" },
     208             :                 { "Ljava/lang/String;", "Ljava/lang/String;" },
     209             :                 { "Lcom/sun/star/uno/Type;", "Lcom/sun/star/uno/Type;" },
     210             :                 { "Ljava/lang/Object;", "Ljava/lang/Object;" } };
     211             :             char const * s
     212       17574 :                 = simpleTypeDescriptors[sort][rank == 0 && classType];
     213       17574 :             if (descriptor != 0) {
     214       17467 :                 descriptor->append(s);
     215             :             }
     216       17574 :             if (signature != 0) {
     217       17508 :                 signature->append(s);
     218             :             }
     219             :             static SpecialType const
     220             :                 simpleTypeSpecials[codemaker::UnoType::SORT_ANY + 1] = {
     221             :                 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE,
     222             :                 SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE,
     223             :                 SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED,
     224             :                 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE,
     225             :                 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_ANY };
     226       17574 :             return simpleTypeSpecials[sort];
     227             :         }
     228             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
     229        3871 :         if (nucleus == "com.sun.star.uno.XInterface") {
     230         495 :             if (descriptor != 0) {
     231         493 :                 descriptor->append("Ljava/lang/Object;");
     232             :             }
     233         495 :             if (signature != 0) {
     234         494 :                 signature->append("Ljava/lang/Object;");
     235             :             }
     236         495 :             return SPECIAL_TYPE_INTERFACE;
     237             :         }
     238             :         // fall through
     239             :     case codemaker::UnoType::SORT_SEQUENCE_TYPE:
     240             :     case codemaker::UnoType::SORT_ENUM_TYPE:
     241             :     case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
     242             :     case codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE:
     243        5839 :         if (dependencies != 0) {
     244        5457 :             dependencies->insert(nucleus);
     245             :         }
     246        5839 :         if (descriptor != 0) {
     247             :             descriptor->append(
     248       11610 :                 "L" + codemaker::convertString(nucleus).replace('.', '/')
     249        5805 :                 + ";");
     250             :         }
     251        5839 :         if (signature != 0) {
     252             :             signature->append(
     253        5628 :                 "L" + codemaker::convertString(nucleus).replace('.', '/'));
     254        5628 :             if (!arguments.empty()) {
     255         113 :                 signature->append('<');
     256         768 :                 for (std::vector< OUString >::const_iterator i(
     257         113 :                          arguments.begin());
     258         512 :                      i != arguments.end(); ++i)
     259             :                 {
     260             :                     translateUnoTypeToDescriptor(
     261         143 :                         manager, *i, false, true, dependencies, 0, signature,
     262         143 :                         needsSignature, 0);
     263             :                 }
     264         113 :                 signature->append('>');
     265         113 :                 *needsSignature = true;
     266             :             }
     267        5628 :             signature->append(';');
     268             :         }
     269        5839 :         return SPECIAL_TYPE_NONE;
     270             :     default:
     271             :         throw CannotDumpException(
     272           0 :             "unexpected nucleus \"" + nucleus
     273           0 :             + "\" in call to translateUnoTypeToDescriptor");
     274             :     }
     275             : }
     276             : 
     277       23630 : SpecialType translateUnoTypeToDescriptor(
     278             :     rtl::Reference< TypeManager > const & manager, OUString const & type,
     279             :     bool array, bool classType, Dependencies * dependencies,
     280             :     OStringBuffer * descriptor, OStringBuffer * signature,
     281             :     bool * needsSignature, PolymorphicUnoType * polymorphicUnoType)
     282             : {
     283             :     assert(manager.is());
     284       23630 :     OUString nucleus;
     285             :     sal_Int32 rank;
     286       47260 :     std::vector< OUString > args;
     287             :     codemaker::UnoType::Sort sort = manager->decompose(
     288       23630 :         type, true, &nucleus, &rank, &args, 0);
     289             :     return translateUnoTypeToDescriptor(
     290             :         manager, sort, nucleus, rank, args, array, classType, dependencies,
     291       47260 :         descriptor, signature, needsSignature, polymorphicUnoType);
     292             : }
     293             : 
     294        6474 : SpecialType getFieldDescriptor(
     295             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
     296             :     OUString const & type, OString * descriptor, OString * signature,
     297             :     PolymorphicUnoType * polymorphicUnoType)
     298             : {
     299             :     assert(descriptor != 0);
     300        6474 :     OStringBuffer desc;
     301       12948 :     OStringBuffer sig;
     302        6474 :     bool needsSig = false;
     303             :     SpecialType specialType = translateUnoTypeToDescriptor(
     304             :         manager, type, false, false, dependencies, &desc, &sig, &needsSig,
     305        6474 :         polymorphicUnoType);
     306        6474 :     *descriptor = desc.makeStringAndClear();
     307        6474 :     if (signature != 0) {
     308        4901 :         if (needsSig) {
     309           2 :             *signature = sig.makeStringAndClear();
     310             :         } else {
     311        4899 :             *signature = OString();
     312             :         }
     313             :     }
     314       12948 :     return specialType;
     315             : }
     316             : 
     317        7757 : class MethodDescriptor {
     318             : public:
     319             :     MethodDescriptor(
     320             :         rtl::Reference< TypeManager > const & manager,
     321             :         Dependencies * dependencies, OUString const & returnType,
     322             :         SpecialType * specialReturnType,
     323             :         PolymorphicUnoType * polymorphicUnoType);
     324             : 
     325             :     SpecialType addParameter(
     326             :         OUString const & type, bool array, bool dependency,
     327             :         PolymorphicUnoType * polymorphicUnoType);
     328             : 
     329             :     void addTypeParameter(OUString const & name);
     330             : 
     331             :     OString getDescriptor() const;
     332             : 
     333             :     OString getSignature() const;
     334             : 
     335             : private:
     336             :     rtl::Reference< TypeManager > m_manager;
     337             :     Dependencies * m_dependencies;
     338             :     OStringBuffer m_descriptorStart;
     339             :     OString m_descriptorEnd;
     340             :     OStringBuffer m_signatureStart;
     341             :     OString m_signatureEnd;
     342             :     bool m_needsSignature;
     343             : };
     344             : 
     345        7757 : MethodDescriptor::MethodDescriptor(
     346             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
     347             :     OUString const & returnType, SpecialType * specialReturnType,
     348             :     PolymorphicUnoType * polymorphicUnoType):
     349        7757 :     m_manager(manager), m_dependencies(dependencies), m_needsSignature(false)
     350             : {
     351             :     assert(dependencies != 0);
     352        7757 :     m_descriptorStart.append('(');
     353        7757 :     m_signatureStart.append('(');
     354        7757 :     OStringBuffer descEnd;
     355        7757 :     descEnd.append(')');
     356       15514 :     OStringBuffer sigEnd;
     357        7757 :     sigEnd.append(')');
     358             :     SpecialType special = translateUnoTypeToDescriptor(
     359             :         m_manager, returnType, false, false, m_dependencies, &descEnd, &sigEnd,
     360        7757 :         &m_needsSignature, polymorphicUnoType);
     361        7757 :     m_descriptorEnd = descEnd.makeStringAndClear();
     362        7757 :     m_signatureEnd = sigEnd.makeStringAndClear();
     363        7757 :     if (specialReturnType != 0) {
     364        6245 :         *specialReturnType = special;
     365        7757 :     }
     366        7757 : }
     367             : 
     368        9256 : SpecialType MethodDescriptor::addParameter(
     369             :     OUString const & type, bool array, bool dependency,
     370             :     PolymorphicUnoType * polymorphicUnoType)
     371             : {
     372             :     return translateUnoTypeToDescriptor(
     373             :         m_manager, type, array, false, dependency ? m_dependencies : 0,
     374             :         &m_descriptorStart, &m_signatureStart, &m_needsSignature,
     375        9256 :         polymorphicUnoType);
     376             : }
     377             : 
     378           8 : void MethodDescriptor::addTypeParameter(OUString const & name) {
     379           8 :     m_descriptorStart.append("Ljava/lang/Object;");
     380           8 :     m_signatureStart.append("T" + codemaker::convertString(name) + ";");
     381           8 :     m_needsSignature = true;
     382           8 : }
     383             : 
     384        8404 : OString MethodDescriptor::getDescriptor() const {
     385        8404 :     OStringBuffer buf(m_descriptorStart);
     386        8404 :     buf.append(m_descriptorEnd);
     387        8404 :     return buf.makeStringAndClear();
     388             : }
     389             : 
     390        7757 : OString MethodDescriptor::getSignature() const {
     391        7757 :     return m_needsSignature ?  m_signatureStart + m_signatureEnd : OString();
     392             : }
     393             : 
     394       40437 : class TypeInfo {
     395             : public:
     396             :     enum Kind { KIND_MEMBER, KIND_ATTRIBUTE, KIND_METHOD, KIND_PARAMETER };
     397             : 
     398             :     // Same values as in com/sun/star/lib/uno/typeinfo/TypeInfo.java:
     399             :     enum Flags {
     400             :         FLAG_READONLY = 0x008, FLAG_BOUND = 0x100
     401             :     };
     402             : 
     403             :     // KIND_MEMBER:
     404             :     TypeInfo(
     405             :         OString const & name, SpecialType specialType, sal_Int32 index,
     406             :         PolymorphicUnoType const & polymorphicUnoType,
     407             :         sal_Int32 typeParameterIndex);
     408             : 
     409             :     // KIND_ATTRIBUTE/METHOD:
     410             :     TypeInfo(
     411             :         Kind kind, OString const & name, SpecialType specialType, Flags flags,
     412             :         sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType);
     413             : 
     414             :     // KIND_PARAMETER:
     415             :     TypeInfo(
     416             :         OString const & parameterName, SpecialType specialType,
     417             :         bool inParameter, bool outParameter, OString const & methodName,
     418             :         sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType);
     419             : 
     420             :     sal_uInt16 generateCode(ClassFile::Code & code, Dependencies * dependencies)
     421             :         const;
     422             : 
     423             :     void generatePolymorphicUnoTypeCode(
     424             :         ClassFile::Code & code, Dependencies * dependencies) const;
     425             : 
     426             : private:
     427             :     Kind m_kind;
     428             :     OString m_name;
     429             :     sal_Int32 m_flags;
     430             :     sal_Int32 m_index;
     431             :     OString m_methodName;
     432             :     PolymorphicUnoType m_polymorphicUnoType;
     433             :     sal_Int32 m_typeParameterIndex;
     434             : };
     435             : 
     436        8061 : sal_Int32 translateSpecialTypeFlags(
     437             :     SpecialType specialType, bool inParameter, bool outParameter)
     438             : {
     439             :     static sal_Int32 const specialTypeFlags[SPECIAL_TYPE_INTERFACE + 1] = {
     440             :         0, 0x0040 /* ANY */, 0x0004 /* UNSIGNED */, 0x0080 /* INTERFACE */ };
     441        8061 :     sal_Int32 flags = specialTypeFlags[specialType];
     442        8061 :     if (inParameter) {
     443         135 :         flags |= 0x0001; /* IN */
     444             :     }
     445        8061 :     if (outParameter) {
     446         157 :         flags |= 0x0002; /* OUT */
     447             :     }
     448        8061 :     return flags;
     449             : }
     450             : 
     451        1581 : TypeInfo::TypeInfo(
     452             :     OString const & name, SpecialType specialType, sal_Int32 index,
     453             :     PolymorphicUnoType const & polymorphicUnoType,
     454             :     sal_Int32 typeParameterIndex):
     455             :     m_kind(KIND_MEMBER), m_name(name),
     456        1581 :     m_flags(translateSpecialTypeFlags(specialType, false, false)),
     457             :     m_index(index), m_polymorphicUnoType(polymorphicUnoType),
     458        3162 :     m_typeParameterIndex(typeParameterIndex)
     459             : {
     460             :     assert(
     461             :         polymorphicUnoType.kind == PolymorphicUnoType::KIND_NONE
     462             :         ? typeParameterIndex >= -1 : typeParameterIndex == -1);
     463        1581 : }
     464             : 
     465        6245 : TypeInfo::TypeInfo(
     466             :     Kind kind, OString const & name, SpecialType specialType, Flags flags,
     467             :     sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType):
     468             :     m_kind(kind), m_name(name),
     469        6245 :     m_flags(flags | translateSpecialTypeFlags(specialType, false, false)),
     470       12490 :     m_index(index), m_polymorphicUnoType(polymorphicUnoType)
     471             : {
     472             :     assert(kind == KIND_ATTRIBUTE || kind == KIND_METHOD);
     473        6245 : }
     474             : 
     475         235 : TypeInfo::TypeInfo(
     476             :     OString const & parameterName, SpecialType specialType, bool inParameter,
     477             :     bool outParameter, OString const & methodName, sal_Int32 index,
     478             :     PolymorphicUnoType const & polymorphicUnoType):
     479             :     m_kind(KIND_PARAMETER), m_name(parameterName),
     480         235 :     m_flags(translateSpecialTypeFlags(specialType, inParameter, outParameter)),
     481             :     m_index(index), m_methodName(methodName),
     482         470 :     m_polymorphicUnoType(polymorphicUnoType)
     483         235 : {}
     484             : 
     485        8061 : sal_uInt16 TypeInfo::generateCode(
     486             :     ClassFile::Code & code, Dependencies * dependencies) const
     487             : {
     488        8061 :     switch (m_kind) {
     489             :     case KIND_MEMBER:
     490        1581 :         code.instrNew("com/sun/star/lib/uno/typeinfo/MemberTypeInfo");
     491        1581 :         code.instrDup();
     492        1581 :         code.loadStringConstant(m_name);
     493        1581 :         code.loadIntegerConstant(m_index);
     494        1581 :         code.loadIntegerConstant(m_flags);
     495        1581 :         if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
     496           2 :             generatePolymorphicUnoTypeCode(code, dependencies);
     497           2 :             code.loadIntegerConstant(m_typeParameterIndex);
     498             :             code.instrInvokespecial(
     499             :                 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo", "<init>",
     500           2 :                 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V");
     501           2 :             return 8;
     502        1579 :         } else if (m_typeParameterIndex >= 0) {
     503           8 :             code.instrAconstNull();
     504           8 :             code.loadIntegerConstant(m_typeParameterIndex);
     505             :             code.instrInvokespecial(
     506             :                 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo", "<init>",
     507           8 :                 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V");
     508           8 :             return 6;
     509             :         } else {
     510             :             code.instrInvokespecial(
     511             :                 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo", "<init>",
     512        1571 :                 "(Ljava/lang/String;II)V");
     513        1571 :             return 4;
     514             :         }
     515             :     case KIND_ATTRIBUTE:
     516         620 :         code.instrNew("com/sun/star/lib/uno/typeinfo/AttributeTypeInfo");
     517         620 :         code.instrDup();
     518         620 :         code.loadStringConstant(m_name);
     519         620 :         code.loadIntegerConstant(m_index);
     520         620 :         code.loadIntegerConstant(m_flags);
     521         620 :         if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
     522           4 :             generatePolymorphicUnoTypeCode(code, dependencies);
     523             :             code.instrInvokespecial(
     524             :                 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo", "<init>",
     525           4 :                 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V");
     526           4 :             return 8;
     527             :         } else {
     528             :             code.instrInvokespecial(
     529             :                 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo", "<init>",
     530         616 :                 "(Ljava/lang/String;II)V");
     531         616 :             return 4;
     532             :         }
     533             :     case KIND_METHOD:
     534        5625 :         code.instrNew("com/sun/star/lib/uno/typeinfo/MethodTypeInfo");
     535        5625 :         code.instrDup();
     536        5625 :         code.loadStringConstant(m_name);
     537        5625 :         code.loadIntegerConstant(m_index);
     538        5625 :         code.loadIntegerConstant(m_flags);
     539        5625 :         if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
     540          19 :             generatePolymorphicUnoTypeCode(code, dependencies);
     541             :             code.instrInvokespecial(
     542             :                 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo", "<init>",
     543          19 :                 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V");
     544          19 :             return 8;
     545             :         } else {
     546             :             code.instrInvokespecial(
     547             :                 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo", "<init>",
     548        5606 :                 "(Ljava/lang/String;II)V");
     549        5606 :             return 4;
     550             :         }
     551             :     case KIND_PARAMETER:
     552         235 :         code.instrNew("com/sun/star/lib/uno/typeinfo/ParameterTypeInfo");
     553         235 :         code.instrDup();
     554         235 :         code.loadStringConstant(m_name);
     555         235 :         code.loadStringConstant(m_methodName);
     556         235 :         code.loadIntegerConstant(m_index);
     557         235 :         code.loadIntegerConstant(m_flags);
     558         235 :         if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
     559           5 :             generatePolymorphicUnoTypeCode(code, dependencies);
     560             :             code.instrInvokespecial(
     561             :                 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo", "<init>",
     562             :                 ("(Ljava/lang/String;Ljava/lang/String;II"
     563           5 :                  "Lcom/sun/star/uno/Type;)V"));
     564           5 :             return 9;
     565             :         } else {
     566             :             code.instrInvokespecial(
     567             :                 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo", "<init>",
     568         230 :                 "(Ljava/lang/String;Ljava/lang/String;II)V");
     569         230 :             return 5;
     570             :         }
     571             :     default:
     572             :         assert(false);
     573           0 :         return 0;
     574             :     }
     575             : }
     576             : 
     577          30 : void TypeInfo::generatePolymorphicUnoTypeCode(
     578             :     ClassFile::Code & code, Dependencies * dependencies) const
     579             : {
     580             :     assert(dependencies != 0);
     581             :     assert(m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE);
     582          30 :     code.instrNew("com/sun/star/uno/Type");
     583          30 :     code.instrDup();
     584             :     code.loadStringConstant(
     585          30 :         codemaker::convertString(m_polymorphicUnoType.name));
     586          30 :     if (m_polymorphicUnoType.kind == PolymorphicUnoType::KIND_STRUCT) {
     587             :         code.instrGetstatic(
     588             :             "com/sun/star/uno/TypeClass", "STRUCT",
     589          26 :             "Lcom/sun/star/uno/TypeClass;");
     590             :     } else {
     591             :         code.instrGetstatic(
     592             :             "com/sun/star/uno/TypeClass", "SEQUENCE",
     593           4 :             "Lcom/sun/star/uno/TypeClass;");
     594             :     }
     595          30 :     dependencies->insert("com.sun.star.uno.TypeClass");
     596             :     code.instrInvokespecial(
     597             :         "com/sun/star/uno/Type", "<init>",
     598          30 :         "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
     599          30 : }
     600             : 
     601        3239 : void writeClassFile(
     602             :     JavaOptions const & options, OString const & type,
     603             :     ClassFile const & classFile)
     604             : {
     605        3239 :     OString path;
     606        3239 :     if (options.isValid("-O")) {
     607        3239 :         path = options.getOption("-O");
     608             :     }
     609        6478 :     OString filename(createFileNameFromType(path, type, ".class"));
     610        3239 :     bool check = false;
     611        3239 :     if (fileExists(filename)) {
     612           0 :         if (options.isValid("-G")) {
     613        3239 :             return;
     614             :         }
     615           0 :         check = options.isValid("-Gc");
     616             :     }
     617        6478 :     FileStream tempfile;
     618        3239 :     tempfile.createTempFile(getTempDir(filename));
     619        3239 :     if (!tempfile.isValid()) {
     620             :         throw CannotDumpException(
     621           0 :             "Cannot create temporary file for " + b2u(filename));
     622             :     }
     623        6478 :     OString tempname(tempfile.getName());
     624             :     try {
     625        3239 :         classFile.write(tempfile);
     626           0 :     } catch (...) {
     627             :         // Remove existing file for consistency:
     628           0 :         if (fileExists(filename)) {
     629           0 :             removeTypeFile(filename);
     630             :         }
     631           0 :         tempfile.close();
     632           0 :         removeTypeFile(tempname);
     633           0 :         throw;
     634             :     }
     635        3239 :     tempfile.close();
     636        3239 :     if (!makeValidTypeFile(filename, tempname, check)) {
     637             :         throw CannotDumpException(
     638           0 :             "Cannot create " + b2u(filename) + " from temporary file "
     639           0 :             + b2u(tempname));
     640        3239 :     }
     641             : }
     642             : 
     643        2341 : void addTypeInfo(
     644             :     OString const & className, std::vector< TypeInfo > const & typeInfo,
     645             :     Dependencies * dependencies, ClassFile * classFile)
     646             : {
     647             :     assert(classFile != 0);
     648        2341 :     std::vector< TypeInfo >::size_type typeInfos = typeInfo.size();
     649        2341 :     if (typeInfos > SAL_MAX_INT32) {
     650             :         throw CannotDumpException(
     651           0 :             "UNOTYPEINFO array too big for Java class file format");
     652             :     }
     653        2341 :     if (typeInfos != 0) {
     654             :         classFile->addField(
     655             :             static_cast< ClassFile::AccessFlags >(
     656             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
     657             :                 | ClassFile::ACC_FINAL),
     658             :             "UNOTYPEINFO", "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;",
     659        2102 :             0, "");
     660             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     661        2102 :         std::auto_ptr< ClassFile::Code > code(classFile->newCode());
     662             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     663        2102 :         code->loadIntegerConstant(static_cast< sal_Int32 >(typeInfos));
     664        2102 :         code->instrAnewarray("com/sun/star/lib/uno/typeinfo/TypeInfo");
     665        2102 :         sal_Int32 index = 0;
     666        2102 :         sal_uInt16 stack = 0;
     667       30489 :         for (std::vector< TypeInfo >::const_iterator i(typeInfo.begin());
     668       20326 :              i != typeInfo.end(); ++i)
     669             :         {
     670        8061 :             code->instrDup();
     671        8061 :             code->loadIntegerConstant(index++);
     672        8061 :             stack = std::max(stack, i->generateCode(*code, dependencies));
     673        8061 :             code->instrAastore();
     674             :         }
     675             :         code->instrPutstatic(
     676             :             className, "UNOTYPEINFO",
     677        2102 :             "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;");
     678        2102 :         code->instrReturn();
     679        2102 :         if (stack > SAL_MAX_UINT16 - 4) {
     680             :             throw CannotDumpException(
     681           0 :                 "Stack too big for Java class file format");
     682             :         }
     683        2102 :         code->setMaxStackAndLocals(static_cast< sal_uInt16 >(stack + 4), 0);
     684             :         classFile->addMethod(
     685             :             static_cast< ClassFile::AccessFlags >(
     686             :                 ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC),
     687        2102 :             "<clinit>", "()V", code.get(), std::vector< OString >(), "");
     688             :     }
     689        2341 : }
     690             : 
     691         193 : void handleEnumType(
     692             :     OUString name, rtl::Reference< unoidl::EnumTypeEntity > const & entity,
     693             :     JavaOptions const & options)
     694             : {
     695             :     assert(entity.is());
     696         193 :     OString className(codemaker::convertString(name).replace('.', '/'));
     697             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     698             :     std::auto_ptr< ClassFile > cf(
     699             :         new ClassFile(
     700             :             static_cast< ClassFile::AccessFlags >(
     701             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
     702             :                 | ClassFile::ACC_SUPER),
     703         386 :             className, "com/sun/star/uno/Enum", ""));
     704             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     705         386 :     OString classDescriptor("L" + className + ";");
     706        4515 :     for (std::vector< unoidl::EnumTypeEntity::Member >::const_iterator i(
     707         193 :              entity->getMembers().begin());
     708        3010 :          i != entity->getMembers().end(); ++i)
     709             :     {
     710        1312 :         OString fieldName(codemaker::convertString(i->name));
     711             :         cf->addField(
     712             :             static_cast< ClassFile::AccessFlags >(
     713             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
     714             :                 | ClassFile::ACC_FINAL),
     715        1312 :             fieldName, classDescriptor, 0, OString());
     716             :         cf->addField(
     717             :             static_cast< ClassFile::AccessFlags >(
     718             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
     719             :                 | ClassFile::ACC_FINAL),
     720        2624 :             fieldName + "_value", "I",
     721        3936 :             cf->addIntegerInfo(i->value), "");
     722        1312 :     }
     723             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     724         386 :     std::auto_ptr< ClassFile::Code > code(cf->newCode());
     725             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     726         193 :     code->loadLocalReference(0);
     727         193 :     code->loadLocalInteger(1);
     728         193 :     code->instrInvokespecial("com/sun/star/uno/Enum", "<init>", "(I)V");
     729         193 :     code->instrReturn();
     730         193 :     code->setMaxStackAndLocals(2, 2);
     731             :     cf->addMethod(
     732             :         ClassFile::ACC_PRIVATE,
     733         193 :         "<init>", "(I)V", code.get(),
     734         386 :         std::vector< OString >(), "");
     735         193 :     code.reset(cf->newCode());
     736             :     code->instrGetstatic(
     737             :         className,
     738         193 :         codemaker::convertString(entity->getMembers()[0].name),
     739         193 :         classDescriptor);
     740         193 :     code->instrAreturn();
     741         193 :     code->setMaxStackAndLocals(1, 0);
     742             :     cf->addMethod(
     743             :         static_cast< ClassFile::AccessFlags >(
     744             :             ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
     745         386 :         "getDefault", "()" + classDescriptor,
     746         579 :         code.get(), std::vector< OString >(), "");
     747         193 :     code.reset(cf->newCode());
     748         193 :     code->loadLocalInteger(0);
     749         386 :     std::map< sal_Int32, OString > map;
     750         193 :     sal_Int32 min = SAL_MAX_INT32;
     751         193 :     sal_Int32 max = SAL_MIN_INT32;
     752        4515 :     for (std::vector< unoidl::EnumTypeEntity::Member >::const_iterator i(
     753         193 :              entity->getMembers().begin());
     754        3010 :          i != entity->getMembers().end(); ++i)
     755             :     {
     756        1312 :         min = std::min(min, i->value);
     757        1312 :         max = std::max(max, i->value);
     758             :         map.insert(
     759             :             std::map< sal_Int32, OString >::value_type(
     760        1312 :                 i->value, codemaker::convertString(i->name)));
     761             :     }
     762         193 :     sal_uInt64 size = static_cast< sal_uInt64 >(map.size());
     763         386 :     if ((static_cast< sal_uInt64 >(max) - static_cast< sal_uInt64 >(min)
     764         193 :          <= 2 * size)
     765           1 :         || size > SAL_MAX_INT32)
     766             :     {
     767             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     768         192 :         std::auto_ptr< ClassFile::Code > defCode(cf->newCode());
     769             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     770         192 :         defCode->instrAconstNull();
     771         192 :         defCode->instrAreturn();
     772         384 :         std::list< ClassFile::Code * > blocks;
     773             :             //FIXME: pointers contained in blocks may leak
     774         192 :         sal_Int32 last = SAL_MAX_INT32;
     775        4401 :         for (std::map< sal_Int32, OString >::iterator i(map.begin());
     776        2934 :              i != map.end(); ++i)
     777             :         {
     778        1275 :             sal_Int32 value = i->first;
     779        1275 :             if (last != SAL_MAX_INT32) {
     780        1088 :                 for (sal_Int32 j = last + 1; j < value; ++j) {
     781           5 :                     blocks.push_back(0);
     782             :                 }
     783             :             }
     784        1275 :             last = value;
     785             :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
     786        1275 :             std::auto_ptr< ClassFile::Code > blockCode(cf->newCode());
     787             :             SAL_WNODEPRECATED_DECLARATIONS_POP
     788        1275 :             blockCode->instrGetstatic(className, i->second, classDescriptor);
     789        1275 :             blockCode->instrAreturn();
     790        1275 :             blocks.push_back(blockCode.get());
     791        1275 :             blockCode.release();
     792        1275 :         }
     793         192 :         code->instrTableswitch(defCode.get(), min, blocks);
     794        4416 :         for (std::list< ClassFile::Code * >::iterator i(blocks.begin());
     795        2944 :               i != blocks.end(); ++i)
     796             :         {
     797        1280 :             delete *i;
     798         192 :         }
     799             :     } else{
     800             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     801           1 :         std::auto_ptr< ClassFile::Code > defCode(cf->newCode());
     802             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     803           1 :         defCode->instrAconstNull();
     804           1 :         defCode->instrAreturn();
     805           2 :         std::list< std::pair< sal_Int32, ClassFile::Code * > > blocks;
     806             :             //FIXME: pointers contained in blocks may leak
     807         114 :         for (std::map< sal_Int32, OString >::iterator i(map.begin());
     808          76 :              i != map.end(); ++i)
     809             :         {
     810             :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
     811          37 :             std::auto_ptr< ClassFile::Code > blockCode(cf->newCode());
     812             :             SAL_WNODEPRECATED_DECLARATIONS_POP
     813          37 :             blockCode->instrGetstatic(className, i->second, classDescriptor);
     814          37 :             blockCode->instrAreturn();
     815          37 :             blocks.push_back(std::make_pair(i->first, blockCode.get()));
     816          37 :             blockCode.release();
     817          37 :         }
     818           1 :         code->instrLookupswitch(defCode.get(), blocks);
     819         114 :         for (std::list< std::pair< sal_Int32, ClassFile::Code * > >::iterator
     820           1 :                  i(blocks.begin());
     821          76 :              i != blocks.end(); ++i)
     822             :         {
     823          37 :             delete i->second;
     824           1 :         }
     825             :     }
     826         193 :     code->setMaxStackAndLocals(1, 1);
     827             :     cf->addMethod(
     828             :         static_cast< ClassFile::AccessFlags >(
     829             :             ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
     830         386 :         "fromInt", "(I)" + classDescriptor, code.get(),
     831         579 :         std::vector< OString >(), "");
     832         193 :     code.reset(cf->newCode());
     833        4515 :     for (std::vector< unoidl::EnumTypeEntity::Member >::const_iterator i(
     834         193 :              entity->getMembers().begin());
     835        3010 :          i != entity->getMembers().end(); ++i)
     836             :     {
     837        1312 :         code->instrNew(className);
     838        1312 :         code->instrDup();
     839        1312 :         code->loadIntegerConstant(i->value);
     840        1312 :         code->instrInvokespecial(className, "<init>", "(I)V");
     841             :         code->instrPutstatic(
     842        1312 :             className, codemaker::convertString(i->name), classDescriptor);
     843             :     }
     844         193 :     code->instrReturn();
     845         193 :     code->setMaxStackAndLocals(3, 0);
     846             :     cf->addMethod(
     847             :         static_cast< ClassFile::AccessFlags >(
     848             :             ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC),
     849         193 :         "<clinit>", "()V", code.get(), std::vector< OString >(), "");
     850         386 :     writeClassFile(options, className, *cf.get());
     851         193 : }
     852             : 
     853        1581 : void addField(
     854             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
     855             :     ClassFile * classFile, std::vector< TypeInfo > * typeInfo,
     856             :     sal_Int32 typeParameterIndex, OUString const & type, OUString const & name,
     857             :     sal_Int32 index)
     858             : {
     859             :     assert(classFile != 0);
     860             :     assert(typeInfo != 0);
     861        1581 :     OString descriptor;
     862        3162 :     OString signature;
     863             :     SpecialType specialType;
     864        3162 :     PolymorphicUnoType polymorphicUnoType;
     865        1581 :     if (typeParameterIndex >= 0) {
     866           8 :         descriptor = "Ljava/lang/Object;";
     867          32 :         signature = "T" + codemaker::convertString(type).replace('.', '/')
     868          24 :             + ";";
     869           8 :         specialType = SPECIAL_TYPE_NONE; //TODO: SPECIAL_TYPE_TYPE_PARAMETER?
     870             :     } else {
     871             :         specialType = getFieldDescriptor(
     872             :             manager, dependencies, type, &descriptor, &signature,
     873        1573 :             &polymorphicUnoType);
     874             :     }
     875             :     classFile->addField(
     876             :         ClassFile::ACC_PUBLIC, codemaker::convertString(name), descriptor, 0,
     877        1581 :         signature);
     878             :     typeInfo->push_back(
     879             :         TypeInfo(
     880             :             codemaker::convertString(name), specialType, index,
     881        3162 :             polymorphicUnoType, typeParameterIndex));
     882        1581 : }
     883             : 
     884        1733 : sal_uInt16 addFieldInit(
     885             :     rtl::Reference< TypeManager > const & manager, OString const & className,
     886             :     OUString const & fieldName, bool typeParameter, OUString const & fieldType,
     887             :     Dependencies * dependencies, ClassFile::Code * code)
     888             : {
     889             :     assert(manager.is());
     890             :     assert(code != 0);
     891        1733 :     if (typeParameter) {
     892           8 :         return 0;
     893             :     }
     894        1725 :     OString name(codemaker::convertString(fieldName));
     895        3450 :     OUString nucleus;
     896             :     sal_Int32 rank;
     897        3450 :     std::vector< rtl::OUString > args;
     898        3450 :     rtl::Reference< unoidl::Entity > ent;
     899             :     codemaker::UnoType::Sort sort = manager->decompose(
     900        1725 :         fieldType, true, &nucleus, &rank, &args, &ent);
     901        1725 :     if (rank == 0) {
     902        1614 :         switch (sort) {
     903             :         case codemaker::UnoType::SORT_BOOLEAN:
     904             :         case codemaker::UnoType::SORT_BYTE:
     905             :         case codemaker::UnoType::SORT_SHORT:
     906             :         case codemaker::UnoType::SORT_UNSIGNED_SHORT:
     907             :         case codemaker::UnoType::SORT_LONG:
     908             :         case codemaker::UnoType::SORT_UNSIGNED_LONG:
     909             :         case codemaker::UnoType::SORT_HYPER:
     910             :         case codemaker::UnoType::SORT_UNSIGNED_HYPER:
     911             :         case codemaker::UnoType::SORT_FLOAT:
     912             :         case codemaker::UnoType::SORT_DOUBLE:
     913             :         case codemaker::UnoType::SORT_CHAR:
     914             :         case codemaker::UnoType::SORT_INTERFACE_TYPE:
     915         943 :             return 0;
     916             :         case codemaker::UnoType::SORT_STRING:
     917         412 :             code->loadLocalReference(0);
     918         412 :             code->loadStringConstant(OString());
     919         412 :             code->instrPutfield(className, name, "Ljava/lang/String;");
     920         412 :             return 2;
     921             :         case codemaker::UnoType::SORT_TYPE:
     922           5 :             code->loadLocalReference(0);
     923             :             code->instrGetstatic(
     924           5 :                 "com/sun/star/uno/Type", "VOID", "Lcom/sun/star/uno/Type;");
     925           5 :             code->instrPutfield(className, name, "Lcom/sun/star/uno/Type;");
     926           5 :             return 2;
     927             :         case codemaker::UnoType::SORT_ANY:
     928          96 :             code->loadLocalReference(0);
     929             :             code->instrGetstatic(
     930          96 :                 "com/sun/star/uno/Any", "VOID", "Lcom/sun/star/uno/Any;");
     931          96 :             code->instrPutfield(className, name, "Ljava/lang/Object;");
     932          96 :             return 2;
     933             :         case codemaker::UnoType::SORT_ENUM_TYPE:
     934             :             {
     935             :                 rtl::Reference< unoidl::EnumTypeEntity > ent2(
     936          67 :                     dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()));
     937             :                 assert(ent2.is());
     938          67 :                 code->loadLocalReference(0);
     939         134 :                 OStringBuffer descBuf;
     940             :                 translateUnoTypeToDescriptor(
     941             :                     manager, sort, nucleus, 0, std::vector< OUString >(), false,
     942          67 :                     false, dependencies, &descBuf, 0, 0, 0);
     943         134 :                 OString desc(descBuf.makeStringAndClear());
     944             :                 code->instrGetstatic(
     945             :                     codemaker::convertString(nucleus).replace('.', '/'),
     946          67 :                     codemaker::convertString(ent2->getMembers()[0].name), desc);
     947          67 :                 code->instrPutfield(className, name, desc);
     948         134 :                 return 2;
     949             :             }
     950             :         case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
     951             :         case codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE:
     952             :             {
     953          91 :                 code->loadLocalReference(0);
     954             :                 code->instrNew(
     955          91 :                     codemaker::convertString(nucleus).replace('.', '/'));
     956          91 :                 code->instrDup();
     957             :                 code->instrInvokespecial(
     958             :                     codemaker::convertString(nucleus).replace('.', '/'),
     959          91 :                     "<init>", "()V");
     960          91 :                 OStringBuffer desc;
     961             :                 translateUnoTypeToDescriptor(
     962             :                     manager, sort, nucleus, 0, args, false, false, dependencies,
     963          91 :                     &desc, 0, 0, 0);
     964          91 :                 code->instrPutfield(className, name, desc.makeStringAndClear());
     965          91 :                 return 3;
     966             :             }
     967             :         case codemaker::UnoType::SORT_SEQUENCE_TYPE:
     968             :         case codemaker::UnoType::SORT_TYPEDEF:
     969             :             assert(false); // this cannot happen
     970             :             // fall through
     971             :         default:
     972             :             throw CannotDumpException(
     973           0 :                 "unexpected entity \"" + fieldType
     974           0 :                 + "\" in call to addFieldInit");
     975             :         }
     976             :     }
     977         111 :     code->loadLocalReference(0);
     978         111 :     code->loadIntegerConstant(0);
     979         111 :     if (rank == 1) {
     980         102 :         if (sort >= codemaker::UnoType::SORT_BOOLEAN
     981         102 :             && sort <= codemaker::UnoType::SORT_CHAR)
     982             :         {
     983          27 :             code->instrNewarray(sort);
     984             :         } else {
     985             :             code->instrAnewarray(
     986             :                 codemaker::java::translateUnoToJavaType(
     987             :                     sort, codemaker::convertString(nucleus).replace('.', '/'),
     988          75 :                     false));
     989             :         }
     990             :     } else {
     991           9 :         OStringBuffer desc;
     992             :         translateUnoTypeToDescriptor(
     993             :             manager, sort, nucleus, rank - 1, std::vector< OUString >(), false,
     994           9 :             false, dependencies, &desc, 0, 0, 0);
     995           9 :         code->instrAnewarray(desc.makeStringAndClear());
     996             :     }
     997         111 :     OStringBuffer desc;
     998             :     translateUnoTypeToDescriptor(
     999             :         manager, sort, nucleus, rank, std::vector< OUString >(), false, false,
    1000         111 :         dependencies, &desc, 0, 0, 0);
    1001         111 :     code->instrPutfield(className, name, desc.makeStringAndClear());
    1002        1836 :     return 2;
    1003             : }
    1004             : 
    1005        2377 : sal_uInt16 addLoadLocal(
    1006             :     rtl::Reference< TypeManager > const & manager, ClassFile::Code * code,
    1007             :     sal_uInt16 * index, bool typeParameter, OUString const & type, bool any,
    1008             :     Dependencies * dependencies)
    1009             : {
    1010             :     assert(manager.is());
    1011             :     assert(code != 0);
    1012             :     assert(index != 0);
    1013             :     assert(!(typeParameter && any));
    1014             :     assert(dependencies != 0);
    1015        2377 :     sal_uInt16 stack = 1;
    1016        2377 :     sal_uInt16 size = 1;
    1017        2377 :     if (typeParameter) {
    1018           8 :         code->loadLocalReference(*index);
    1019           8 :         stack = size = 1;
    1020             :     } else {
    1021        2369 :         OUString nucleus;
    1022             :         sal_Int32 rank;
    1023        4738 :         std::vector< OUString > args;
    1024             :         codemaker::UnoType::Sort sort = manager->decompose(
    1025        2369 :             type, true, &nucleus, &rank, &args, 0);
    1026        2369 :         if (rank == 0) {
    1027        2222 :             switch (sort) {
    1028             :             case codemaker::UnoType::SORT_BOOLEAN:
    1029         168 :                 if (any) {
    1030          20 :                     code->instrNew("java/lang/Boolean");
    1031          20 :                     code->instrDup();
    1032          20 :                     code->loadLocalInteger(*index);
    1033             :                     code->instrInvokespecial(
    1034          20 :                         "java/lang/Boolean", "<init>", "(Z)V");
    1035          20 :                     stack = 3;
    1036             :                 } else {
    1037         148 :                     code->loadLocalInteger(*index);
    1038         148 :                     stack = 1;
    1039             :                 }
    1040         168 :                 size = 1;
    1041         168 :                 break;
    1042             :             case codemaker::UnoType::SORT_BYTE:
    1043          49 :                 if (any) {
    1044           1 :                     code->instrNew("java/lang/Byte");
    1045           1 :                     code->instrDup();
    1046           1 :                     code->loadLocalInteger(*index);
    1047             :                     code->instrInvokespecial(
    1048           1 :                         "java/lang/Byte", "<init>", "(B)V");
    1049           1 :                     stack = 3;
    1050             :                 } else {
    1051          48 :                     code->loadLocalInteger(*index);
    1052          48 :                     stack = 1;
    1053             :                 }
    1054          49 :                 size = 1;
    1055          49 :                 break;
    1056             :             case codemaker::UnoType::SORT_SHORT:
    1057         139 :                 if (any) {
    1058           3 :                     code->instrNew("java/lang/Short");
    1059           3 :                     code->instrDup();
    1060           3 :                     code->loadLocalInteger(*index);
    1061             :                     code->instrInvokespecial(
    1062           3 :                         "java/lang/Short", "<init>", "(S)V");
    1063           3 :                     stack = 3;
    1064             :                 } else {
    1065         136 :                     code->loadLocalInteger(*index);
    1066         136 :                     stack = 1;
    1067             :                 }
    1068         139 :                 size = 1;
    1069         139 :                 break;
    1070             :             case codemaker::UnoType::SORT_UNSIGNED_SHORT:
    1071          36 :                 if (any) {
    1072           1 :                     code->instrNew("com/sun/star/uno/Any");
    1073           1 :                     code->instrDup();
    1074             :                     code->instrGetstatic(
    1075             :                         "com/sun/star/uno/Type", "UNSIGNED_SHORT",
    1076           1 :                         "Lcom/sun/star/uno/Type;");
    1077           1 :                     code->instrNew("java/lang/Short");
    1078           1 :                     code->instrDup();
    1079           1 :                     code->loadLocalInteger(*index);
    1080             :                     code->instrInvokespecial(
    1081           1 :                         "java/lang/Short", "<init>", "(S)V");
    1082             :                     code->instrInvokespecial(
    1083             :                         "com/sun/star/uno/Any", "<init>",
    1084           1 :                         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1085           1 :                     stack = 6;
    1086             :                 } else {
    1087          35 :                     code->loadLocalInteger(*index);
    1088          35 :                     stack = 1;
    1089             :                 }
    1090          36 :                 size = 1;
    1091          36 :                 break;
    1092             :             case codemaker::UnoType::SORT_LONG:
    1093         325 :                 if (any) {
    1094          10 :                     code->instrNew("java/lang/Integer");
    1095          10 :                     code->instrDup();
    1096          10 :                     code->loadLocalInteger(*index);
    1097             :                     code->instrInvokespecial(
    1098          10 :                         "java/lang/Integer", "<init>", "(I)V");
    1099          10 :                     stack = 3;
    1100             :                 } else {
    1101         315 :                     code->loadLocalInteger(*index);
    1102         315 :                     stack = 1;
    1103             :                 }
    1104         325 :                 size = 1;
    1105         325 :                 break;
    1106             :             case codemaker::UnoType::SORT_UNSIGNED_LONG:
    1107          20 :                 if (any) {
    1108           1 :                     code->instrNew("com/sun/star/uno/Any");
    1109           1 :                     code->instrDup();
    1110             :                     code->instrGetstatic(
    1111             :                         "com/sun/star/uno/Type", "UNSIGNED_LONG",
    1112           1 :                         "Lcom/sun/star/uno/Type;");
    1113           1 :                     code->instrNew("java/lang/Integer");
    1114           1 :                     code->instrDup();
    1115           1 :                     code->loadLocalInteger(*index);
    1116             :                     code->instrInvokespecial(
    1117           1 :                         "java/lang/Integer", "<init>", "(I)V");
    1118             :                     code->instrInvokespecial(
    1119             :                         "com/sun/star/uno/Any", "<init>",
    1120           1 :                         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1121           1 :                     stack = 6;
    1122             :                 } else {
    1123          19 :                     code->loadLocalInteger(*index);
    1124          19 :                     stack = 1;
    1125             :                 }
    1126          20 :                 size = 1;
    1127          20 :                 break;
    1128             :             case codemaker::UnoType::SORT_HYPER:
    1129          29 :                 if (any) {
    1130           1 :                     code->instrNew("java/lang/Long");
    1131           1 :                     code->instrDup();
    1132           1 :                     code->loadLocalLong(*index);
    1133             :                     code->instrInvokespecial(
    1134           1 :                         "java/lang/Long", "<init>", "(J)V");
    1135           1 :                     stack = 4;
    1136             :                 } else {
    1137          28 :                     code->loadLocalLong(*index);
    1138          28 :                     stack = 2;
    1139             :                 }
    1140          29 :                 size = 2;
    1141          29 :                 break;
    1142             :             case codemaker::UnoType::SORT_UNSIGNED_HYPER:
    1143           7 :                 if (any) {
    1144           1 :                     code->instrNew("com/sun/star/uno/Any");
    1145           1 :                     code->instrDup();
    1146             :                     code->instrGetstatic(
    1147             :                         "com/sun/star/uno/Type", "UNSIGNED_HYPER",
    1148           1 :                         "Lcom/sun/star/uno/Type;");
    1149           1 :                     code->instrNew("java/lang/Long");
    1150           1 :                     code->instrDup();
    1151           1 :                     code->loadLocalLong(*index);
    1152             :                     code->instrInvokespecial(
    1153           1 :                         "java/lang/Long", "<init>", "(J)V");
    1154             :                     code->instrInvokespecial(
    1155             :                         "com/sun/star/uno/Any", "<init>",
    1156           1 :                         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1157           1 :                     stack = 7;
    1158             :                 } else {
    1159           6 :                     code->loadLocalLong(*index);
    1160           6 :                     stack = 2;
    1161             :                 }
    1162           7 :                 size = 2;
    1163           7 :                 break;
    1164             :             case codemaker::UnoType::SORT_FLOAT:
    1165          19 :                 if (any) {
    1166           1 :                     code->instrNew("java/lang/Float");
    1167           1 :                     code->instrDup();
    1168           1 :                     code->loadLocalFloat(*index);
    1169             :                     code->instrInvokespecial(
    1170           1 :                         "java/lang/Float", "<init>", "(F)V");
    1171           1 :                     stack = 3;
    1172             :                 } else {
    1173          18 :                     code->loadLocalFloat(*index);
    1174          18 :                     stack = 1;
    1175             :                 }
    1176          19 :                 size = 1;
    1177          19 :                 break;
    1178             :             case codemaker::UnoType::SORT_DOUBLE:
    1179         112 :                 if (any) {
    1180           1 :                     code->instrNew("java/lang/Double");
    1181           1 :                     code->instrDup();
    1182           1 :                     code->loadLocalDouble(*index);
    1183             :                     code->instrInvokespecial(
    1184           1 :                         "java/lang/Double", "<init>", "(D)V");
    1185           1 :                     stack = 4;
    1186             :                 } else {
    1187         111 :                     code->loadLocalDouble(*index);
    1188         111 :                     stack = 2;
    1189             :                 }
    1190         112 :                 size = 2;
    1191         112 :                 break;
    1192             :             case codemaker::UnoType::SORT_CHAR:
    1193          13 :                 if (any) {
    1194           1 :                     code->instrNew("java/lang/Character");
    1195           1 :                     code->instrDup();
    1196           1 :                     code->loadLocalInteger(*index);
    1197             :                     code->instrInvokespecial(
    1198           1 :                         "java/lang/Character", "<init>", "(C)V");
    1199           1 :                     stack = 3;
    1200             :                 } else {
    1201          12 :                     code->loadLocalInteger(*index);
    1202          12 :                     stack = 1;
    1203             :                 }
    1204          13 :                 size = 1;
    1205          13 :                 break;
    1206             :             case codemaker::UnoType::SORT_STRING:
    1207             :             case codemaker::UnoType::SORT_TYPE:
    1208             :             case codemaker::UnoType::SORT_ANY:
    1209         555 :                 code->loadLocalReference(*index);
    1210         555 :                 stack = size = 1;
    1211         555 :                 break;
    1212             :             case codemaker::UnoType::SORT_ENUM_TYPE:
    1213             :                 // Assuming that no Java types are derived from Java types that
    1214             :                 // are directly derived from com.sun.star.uno.Enum:
    1215         106 :                 code->loadLocalReference(*index);
    1216         106 :                 stack = size = 1;
    1217         106 :                 break;
    1218             :             case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    1219             :             case codemaker::UnoType::SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE:
    1220         132 :                 if (any) {
    1221          43 :                     code->instrNew("com/sun/star/uno/Any");
    1222          43 :                     code->instrDup();
    1223          43 :                     code->instrNew("com/sun/star/uno/Type");
    1224          43 :                     code->instrDup();
    1225             :                     code->loadStringConstant(
    1226             :                         codemaker::convertString(
    1227          43 :                             createUnoName(manager, nucleus, rank, args)));
    1228             :                     code->instrGetstatic(
    1229             :                         "com/sun/star/uno/TypeClass", "STRUCT",
    1230          43 :                         "Lcom/sun/star/uno/TypeClass;");
    1231          43 :                     dependencies->insert("com.sun.star.uno.TypeClass");
    1232             :                     code->instrInvokespecial(
    1233             :                         "com/sun/star/uno/Type", "<init>",
    1234          43 :                         "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    1235          43 :                     code->loadLocalReference(*index);
    1236             :                     code->instrInvokespecial(
    1237             :                         "com/sun/star/uno/Any", "<init>",
    1238          43 :                         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1239          43 :                     stack = 6;
    1240             :                 } else {
    1241          89 :                     code->loadLocalReference(*index);
    1242          89 :                     stack = 1;
    1243             :                 }
    1244         132 :                 size = 1;
    1245         132 :                 break;
    1246             :             case codemaker::UnoType::SORT_INTERFACE_TYPE:
    1247         512 :                 if (any && nucleus != "com.sun.star.uno.XInterface") {
    1248          80 :                     code->instrNew("com/sun/star/uno/Any");
    1249          80 :                     code->instrDup();
    1250          80 :                     code->instrNew("com/sun/star/uno/Type");
    1251          80 :                     code->instrDup();
    1252          80 :                     code->loadStringConstant(codemaker::convertString(nucleus));
    1253             :                     code->instrGetstatic(
    1254             :                         "com/sun/star/uno/TypeClass", "INTERFACE",
    1255          80 :                         "Lcom/sun/star/uno/TypeClass;");
    1256          80 :                     dependencies->insert("com.sun.star.uno.TypeClass");
    1257             :                     code->instrInvokespecial(
    1258             :                         "com/sun/star/uno/Type", "<init>",
    1259          80 :                         "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    1260          80 :                     code->loadLocalReference(*index);
    1261             :                     code->instrInvokespecial(
    1262             :                         "com/sun/star/uno/Any", "<init>",
    1263          80 :                         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1264          80 :                     stack = 6;
    1265             :                 } else {
    1266         432 :                     code->loadLocalReference(*index);
    1267         432 :                     stack = 1;
    1268             :                 }
    1269         512 :                 size = 1;
    1270         512 :                 break;
    1271             :             case codemaker::UnoType::SORT_SEQUENCE_TYPE:
    1272             :             case codemaker::UnoType::SORT_TYPEDEF:
    1273             :                 assert(false); // this cannot happen
    1274             :                 // fall through
    1275             :             default:
    1276             :                 throw CannotDumpException(
    1277           0 :                     "unexpected entity \"" + type
    1278           0 :                     + "\" in call to addLoadLocal");
    1279             :             }
    1280             :         } else {
    1281         147 :             bool wrap = false;
    1282         147 :             if (any) {
    1283          43 :                 switch (sort) {
    1284             :                 case codemaker::UnoType::SORT_BOOLEAN:
    1285             :                 case codemaker::UnoType::SORT_BYTE:
    1286             :                 case codemaker::UnoType::SORT_SHORT:
    1287             :                 case codemaker::UnoType::SORT_LONG:
    1288             :                 case codemaker::UnoType::SORT_HYPER:
    1289             :                 case codemaker::UnoType::SORT_FLOAT:
    1290             :                 case codemaker::UnoType::SORT_DOUBLE:
    1291             :                 case codemaker::UnoType::SORT_CHAR:
    1292             :                 case codemaker::UnoType::SORT_STRING:
    1293             :                 case codemaker::UnoType::SORT_TYPE:
    1294             :                         // assuming that no Java types are derived from
    1295             :                         // com.sun.star.uno.Type
    1296             :                 case codemaker::UnoType::SORT_ENUM_TYPE:
    1297             :                         // assuming that no Java types are derived from Java
    1298             :                         // types that are directly derived from
    1299             :                         // com.sun.star.uno.Enum
    1300          17 :                     break;
    1301             :                 case codemaker::UnoType::SORT_UNSIGNED_SHORT:
    1302             :                 case codemaker::UnoType::SORT_UNSIGNED_LONG:
    1303             :                 case codemaker::UnoType::SORT_UNSIGNED_HYPER:
    1304             :                 case codemaker::UnoType::SORT_ANY:
    1305             :                 case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    1306             :                 case codemaker::UnoType::
    1307             :                     SORT_INSTANTIATED_POLYMORPHIC_STRUCT_TYPE:
    1308             :                 case codemaker::UnoType::SORT_INTERFACE_TYPE:
    1309          26 :                     wrap = true;
    1310          26 :                     break;
    1311             :                 case codemaker::UnoType::SORT_SEQUENCE_TYPE:
    1312             :                 case codemaker::UnoType::SORT_TYPEDEF:
    1313             :                     assert(false); // this cannot happen
    1314             :                     // fall through
    1315             :                 default:
    1316             :                     throw CannotDumpException(
    1317           0 :                         "unexpected entity \"" + type
    1318           0 :                         + "\" in call to addLoadLocal");
    1319             :                 }
    1320             :             }
    1321         147 :             if (wrap) {
    1322          26 :                 code->instrNew("com/sun/star/uno/Any");
    1323          26 :                 code->instrDup();
    1324          26 :                 code->instrNew("com/sun/star/uno/Type");
    1325          26 :                 code->instrDup();
    1326             :                 code->loadStringConstant(
    1327             :                     codemaker::convertString(
    1328          26 :                         createUnoName(manager, nucleus, rank, args)));
    1329             :                 code->instrInvokespecial(
    1330          26 :                     "com/sun/star/uno/Type", "<init>", "(Ljava/lang/String;)V");
    1331          26 :                 code->loadLocalReference(*index);
    1332             :                 code->instrInvokespecial(
    1333             :                     "com/sun/star/uno/Any", "<init>",
    1334          26 :                     "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V");
    1335          26 :                 stack = 5;
    1336             :             } else {
    1337         121 :                 code->loadLocalReference(*index);
    1338         121 :                 stack = 1;
    1339             :             }
    1340         147 :             size = 1;
    1341        2369 :         }
    1342             :     }
    1343        2377 :     if (*index > SAL_MAX_UINT16 - size) {
    1344             :         throw CannotDumpException(
    1345           0 :             "Too many local variables for Java class file format");
    1346             :     }
    1347        2377 :     *index = *index + size;
    1348        2377 :     return stack;
    1349             : }
    1350             : 
    1351        1581 : sal_uInt16 addDirectArgument(
    1352             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
    1353             :     MethodDescriptor * methodDescriptor, ClassFile::Code * code,
    1354             :     sal_uInt16 * index, OString const & className, OString const & fieldName,
    1355             :     bool typeParameter, OUString const & fieldType)
    1356             : {
    1357             :     assert(methodDescriptor != 0);
    1358             :     assert(code != 0);
    1359        1581 :     OString desc;
    1360        1581 :     if (typeParameter) {
    1361           8 :         methodDescriptor->addTypeParameter(fieldType);
    1362           8 :         desc = "Ljava/lang/Object;";
    1363             :     } else {
    1364        1573 :         methodDescriptor->addParameter(fieldType, false, true, 0);
    1365        1573 :         getFieldDescriptor(manager, dependencies, fieldType, &desc, 0, 0);
    1366             :     }
    1367        1581 :     code->loadLocalReference(0);
    1368             :     sal_uInt16 stack = addLoadLocal(
    1369        1581 :         manager, code, index, typeParameter, fieldType, false, dependencies);
    1370        1581 :     code->instrPutfield(className, fieldName, desc);
    1371        1581 :     return stack + 1;
    1372             : }
    1373             : 
    1374         115 : void addPlainStructBaseArguments(
    1375             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
    1376             :     MethodDescriptor * methodDescriptor, ClassFile::Code * code,
    1377             :     OUString const & base, sal_uInt16 * index)
    1378             : {
    1379             :     assert(manager.is());
    1380             :     assert(methodDescriptor != 0);
    1381         115 :     rtl::Reference< unoidl::Entity > ent;
    1382         115 :     if (manager->getSort(base, &ent)
    1383             :         != codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE)
    1384             :     {
    1385             :         throw CannotDumpException(
    1386           0 :             "unexpected entity \"" + base
    1387           0 :             + "\" in call to addPlainStructBaseArguments");
    1388             :     }
    1389             :     rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
    1390         230 :         dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
    1391             :     assert(ent2.is());
    1392         115 :     if (!ent2->getDirectBase().isEmpty()) {
    1393             :         addPlainStructBaseArguments(
    1394             :             manager, dependencies, methodDescriptor, code,
    1395          15 :             ent2->getDirectBase(), index);
    1396             :     }
    1397         936 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1398         115 :              ent2->getDirectMembers().begin());
    1399         624 :          i != ent2->getDirectMembers().end(); ++i)
    1400             :     {
    1401         197 :         methodDescriptor->addParameter(i->type, false, true, 0);
    1402         197 :         addLoadLocal(manager, code, index, false, i->type, false, dependencies);
    1403         115 :     }
    1404         115 : }
    1405             : 
    1406         397 : void handlePlainStructType(
    1407             :     OUString name,
    1408             :     rtl::Reference< unoidl::PlainStructTypeEntity > const & entity,
    1409             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1410             :     Dependencies * dependencies)
    1411             : {
    1412             :     assert(entity.is());
    1413             :     assert(dependencies != 0);
    1414         397 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1415         794 :     OString superClass;
    1416         397 :     if (entity->getDirectBase().isEmpty()) {
    1417         297 :         superClass = "java/lang/Object";
    1418             :     } else {
    1419         200 :         superClass = codemaker::convertString(entity->getDirectBase()).
    1420         100 :             replace('.', '/');
    1421         100 :         dependencies->insert(entity->getDirectBase());
    1422             :     }
    1423             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1424             :     std::auto_ptr< ClassFile > cf(
    1425             :         new ClassFile(
    1426             :             static_cast< ClassFile::AccessFlags >(
    1427             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1428         794 :             className, superClass, ""));
    1429             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1430         794 :     std::vector< TypeInfo > typeInfo;
    1431         397 :     sal_Int32 index = 0;
    1432        5445 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1433         397 :              entity->getDirectMembers().begin());
    1434        3630 :          i != entity->getDirectMembers().end(); ++i)
    1435             :     {
    1436             :         addField(
    1437        2836 :             manager, dependencies, cf.get(), &typeInfo, -1, i->type, i->name,
    1438        4254 :             index++);
    1439             :     }
    1440             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1441         794 :     std::auto_ptr< ClassFile::Code > code(cf->newCode());
    1442             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1443         397 :     code->loadLocalReference(0);
    1444         397 :     code->instrInvokespecial(superClass, "<init>", "()V");
    1445         397 :     sal_uInt16 stack = 0;
    1446        5445 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1447         397 :              entity->getDirectMembers().begin());
    1448        3630 :          i != entity->getDirectMembers().end(); ++i)
    1449             :     {
    1450             :         stack = std::max(
    1451             :             stack,
    1452             :             addFieldInit(
    1453        2836 :                 manager, className, i->name, false, i->type, dependencies,
    1454        4254 :                 code.get()));
    1455             :     }
    1456         397 :     code->instrReturn();
    1457         397 :     code->setMaxStackAndLocals(stack + 1, 1);
    1458             :     cf->addMethod(
    1459         397 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1460         794 :         std::vector< OString >(), "");
    1461         794 :     MethodDescriptor desc(manager, dependencies, "void", 0, 0);
    1462         397 :     code.reset(cf->newCode());
    1463         397 :     code->loadLocalReference(0);
    1464         397 :     sal_uInt16 index2 = 1;
    1465         397 :     if (!entity->getDirectBase().isEmpty()) {
    1466             :         addPlainStructBaseArguments(
    1467             :             manager, dependencies, &desc, code.get(), entity->getDirectBase(),
    1468         100 :             &index2);
    1469             :     }
    1470         397 :     code->instrInvokespecial(superClass, "<init>", desc.getDescriptor());
    1471         397 :     sal_uInt16 maxSize = index2;
    1472        5445 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1473         397 :              entity->getDirectMembers().begin());
    1474        3630 :          i != entity->getDirectMembers().end(); ++i)
    1475             :     {
    1476             :         maxSize = std::max(
    1477             :             maxSize,
    1478             :             addDirectArgument(
    1479             :                 manager, dependencies, &desc, code.get(), &index2, className,
    1480        1418 :                 codemaker::convertString(i->name), false, i->type));
    1481             :     }
    1482         397 :     code->instrReturn();
    1483         397 :     code->setMaxStackAndLocals(maxSize, index2);
    1484             :     cf->addMethod(
    1485         397 :         ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
    1486         794 :         std::vector< OString >(), desc.getSignature());
    1487         397 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1488         794 :     writeClassFile(options, className, *cf.get());
    1489         397 : }
    1490             : 
    1491           6 : void handlePolyStructType(
    1492             :     OUString name,
    1493             :     rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const &
    1494             :         entity,
    1495             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1496             :     Dependencies * dependencies)
    1497             : {
    1498             :     assert(entity.is());
    1499           6 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1500          12 :     std::map< OUString, sal_Int32 > typeParameters;
    1501          12 :     OStringBuffer sig("<");
    1502           6 :     sal_Int32 index = 0;
    1503          42 :     for (std::vector< OUString >::const_iterator i(
    1504           6 :              entity->getTypeParameters().begin());
    1505          28 :          i != entity->getTypeParameters().end(); ++i)
    1506             :     {
    1507           8 :         sig.append(codemaker::convertString(*i) + ":Ljava/lang/Object;");
    1508          16 :         if (!typeParameters.insert(
    1509          16 :                 std::map< OUString, sal_Int32 >::value_type(*i, index++)).
    1510          16 :             second)
    1511             :         {
    1512           0 :             throw CannotDumpException("Bad type information"); //TODO
    1513             :         }
    1514             :     }
    1515           6 :     sig.append(">Ljava/lang/Object;");
    1516             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1517             :     std::auto_ptr< ClassFile > cf(
    1518             :         new ClassFile(
    1519             :             static_cast< ClassFile::AccessFlags >(
    1520             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1521          12 :             className, "java/lang/Object", sig.makeStringAndClear()));
    1522             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1523          12 :     std::vector< TypeInfo > typeInfo;
    1524           6 :     index = 0;
    1525          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1526           6 :              const_iterator i(entity->getMembers().begin());
    1527          34 :          i != entity->getMembers().end(); ++i)
    1528             :     {
    1529             :         sal_Int32 typeParameterIndex;
    1530          11 :         if (i->parameterized) {
    1531             :             std::map< OUString, sal_Int32 >::iterator it(
    1532           8 :                 typeParameters.find(i->type));
    1533           8 :             if (it == typeParameters.end()) {
    1534           0 :                 throw CannotDumpException("Bad type information"); //TODO
    1535             :             }
    1536           8 :             typeParameterIndex = it->second;
    1537             :         } else {
    1538           3 :             typeParameterIndex = -1;
    1539             :         }
    1540             :         addField(
    1541             :             manager, dependencies, cf.get(), &typeInfo, typeParameterIndex,
    1542          11 :             i->type, i->name, index++);
    1543             :     }
    1544             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1545          12 :     std::auto_ptr< ClassFile::Code > code(cf->newCode());
    1546             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1547           6 :     code->loadLocalReference(0);
    1548           6 :     code->instrInvokespecial("java/lang/Object", "<init>", "()V");
    1549           6 :     sal_uInt16 stack = 0;
    1550          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1551           6 :              const_iterator i(entity->getMembers().begin());
    1552          34 :          i != entity->getMembers().end(); ++i)
    1553             :     {
    1554             :         stack = std::max(
    1555             :             stack,
    1556             :             addFieldInit(
    1557          33 :                 manager, className, i->name, i->parameterized, i->type,
    1558          44 :                 dependencies, code.get()));
    1559             :     }
    1560           6 :     code->instrReturn();
    1561           6 :     code->setMaxStackAndLocals(stack + 1, 1);
    1562             :     cf->addMethod(
    1563           6 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1564          12 :         std::vector< OString >(), "");
    1565          12 :     MethodDescriptor desc(manager, dependencies, "void", 0, 0);
    1566           6 :     code.reset(cf->newCode());
    1567           6 :     code->loadLocalReference(0);
    1568           6 :     sal_uInt16 index2 = 1;
    1569             :     code->instrInvokespecial(
    1570           6 :         "java/lang/Object", "<init>", desc.getDescriptor());
    1571           6 :     sal_uInt16 maxSize = index2;
    1572          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1573           6 :              const_iterator i(entity->getMembers().begin());
    1574          34 :          i != entity->getMembers().end(); ++i)
    1575             :     {
    1576             :         maxSize = std::max(
    1577             :             maxSize,
    1578             :             addDirectArgument(
    1579             :                 manager, dependencies, &desc, code.get(), &index2, className,
    1580          11 :                 codemaker::convertString(i->name), i->parameterized, i->type));
    1581             :     }
    1582           6 :     code->instrReturn();
    1583           6 :     code->setMaxStackAndLocals(maxSize, index2);
    1584             :     cf->addMethod(
    1585           6 :         ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
    1586          12 :         std::vector< OString >(), desc.getSignature());
    1587           6 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1588          12 :     writeClassFile(options, className, *cf.get());
    1589           6 : }
    1590             : 
    1591         416 : void addExceptionBaseArguments(
    1592             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
    1593             :     MethodDescriptor * methodDescriptor, ClassFile::Code * code,
    1594             :     OUString const & base, sal_uInt16 * index)
    1595             : {
    1596             :     assert(manager.is());
    1597             :     assert(methodDescriptor != 0);
    1598         416 :     rtl::Reference< unoidl::Entity > ent;
    1599         416 :     if (manager->getSort(base, &ent) != codemaker::UnoType::SORT_EXCEPTION_TYPE)
    1600             :     {
    1601             :         throw CannotDumpException(
    1602           0 :             "unexpected entity \"" + base
    1603           0 :             + "\" in call to addExceptionBaseArguments");
    1604             :     }
    1605             :     rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
    1606         832 :         dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()));
    1607             :     assert(ent2.is());
    1608         416 :     bool baseException = base == "com.sun.star.uno.Exception";
    1609         416 :     if (!baseException) {
    1610             :         addExceptionBaseArguments(
    1611             :             manager, dependencies, methodDescriptor, code,
    1612         174 :             ent2->getDirectBase(), index);
    1613             :     }
    1614        2961 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1615         416 :              ent2->getDirectMembers().begin());
    1616        1974 :          i != ent2->getDirectMembers().end(); ++i)
    1617             :     {
    1618         571 :         if (!baseException || i != ent2->getDirectMembers().begin()) {
    1619         329 :             methodDescriptor->addParameter(i->type, false, true, 0);
    1620             :             addLoadLocal(
    1621         329 :                 manager, code, index, false, i->type, false, dependencies);
    1622             :         }
    1623         416 :     }
    1624         416 : }
    1625             : 
    1626         244 : void handleExceptionType(
    1627             :     OUString name, rtl::Reference< unoidl::ExceptionTypeEntity > const & entity,
    1628             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1629             :     Dependencies * dependencies)
    1630             : {
    1631             :     assert(entity.is());
    1632             :     assert(dependencies != 0);
    1633         244 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1634         244 :     bool baseException = false;
    1635         244 :     bool baseRuntimeException = false;
    1636         488 :     OString superClass;
    1637         244 :     if (className == "com/sun/star/uno/Exception") {
    1638           1 :         baseException = true;
    1639           1 :         superClass = "java/lang/Exception";
    1640         243 :     } else if (className == "com/sun/star/uno/RuntimeException") {
    1641           1 :         baseRuntimeException = true;
    1642           1 :         superClass = "java/lang/RuntimeException";
    1643             :     } else {
    1644         242 :         if (entity->getDirectBase().isEmpty()) {
    1645             :             throw CannotDumpException(
    1646           0 :                 "Exception type \"" + name + "\" lacks base");
    1647             :         }
    1648         484 :         superClass = codemaker::convertString(entity->getDirectBase()).
    1649         242 :             replace('.', '/');
    1650         242 :         dependencies->insert(entity->getDirectBase());
    1651             :     }
    1652             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1653             :     std::auto_ptr< ClassFile > cf(
    1654             :         new ClassFile(
    1655             :             static_cast< ClassFile::AccessFlags >(
    1656             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1657         488 :             className, superClass, ""));
    1658             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1659         488 :     std::vector< TypeInfo > typeInfo;
    1660         244 :     sal_Int32 index = 0;
    1661         244 :     if (baseRuntimeException) {
    1662             :         addField(
    1663             :             manager, dependencies, cf.get(), &typeInfo, -1,
    1664           1 :             "com.sun.star.uno.XInterface", "Context", index++);
    1665             :     }
    1666        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1667         244 :              entity->getDirectMembers().begin());
    1668         792 :          i != entity->getDirectMembers().end(); ++i)
    1669             :     {
    1670         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1671             :             addField(
    1672         151 :                 manager, dependencies, cf.get(), &typeInfo, -1, i->type,
    1673         302 :                 i->name, index++);
    1674             :         }
    1675             :     }
    1676             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1677         488 :     std::auto_ptr< ClassFile::Code > code(cf->newCode());
    1678             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1679         244 :     code->loadLocalReference(0);
    1680         244 :     code->instrInvokespecial(superClass, "<init>", "()V");
    1681         244 :     sal_uInt16 stack = 0;
    1682         244 :     if (baseRuntimeException) {
    1683             :         stack = std::max(
    1684             :             stack,
    1685             :             addFieldInit(
    1686             :                 manager, className, "Context", false,
    1687           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1688             :     }
    1689        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1690         244 :              entity->getDirectMembers().begin());
    1691         792 :          i != entity->getDirectMembers().end(); ++i)
    1692             :     {
    1693         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1694             :             stack = std::max(
    1695             :                 stack,
    1696             :                 addFieldInit(
    1697         302 :                     manager, className, i->name, false, i->type, dependencies,
    1698         453 :                     code.get()));
    1699             :         }
    1700             :     }
    1701         244 :     code->instrReturn();
    1702         244 :     code->setMaxStackAndLocals(stack + 1, 1);
    1703             :     cf->addMethod(
    1704         244 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1705         488 :         std::vector< OString >(), "");
    1706         244 :     code.reset(cf->newCode());
    1707         244 :     code->loadLocalReference(0);
    1708         244 :     code->loadLocalReference(1);
    1709         244 :     code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/String;)V");
    1710         244 :     stack = 0;
    1711         244 :     if (baseRuntimeException) {
    1712             :         stack = std::max(
    1713             :             stack,
    1714             :             addFieldInit(
    1715             :                 manager, className, "Context", false,
    1716           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1717             :     }
    1718        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1719         244 :              entity->getDirectMembers().begin());
    1720         792 :          i != entity->getDirectMembers().end(); ++i)
    1721             :     {
    1722         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1723             :             stack = std::max(
    1724             :                 stack,
    1725             :                 addFieldInit(
    1726         302 :                     manager, className, i->name, false, i->type, dependencies,
    1727         453 :                     code.get()));
    1728             :         }
    1729             :     }
    1730         244 :     code->instrReturn();
    1731         244 :     code->setMaxStackAndLocals(stack + 2, 2);
    1732             :     cf->addMethod(
    1733         244 :         ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", code.get(),
    1734         488 :         std::vector< OString >(), "");
    1735         488 :     MethodDescriptor desc(manager, dependencies, "void", 0, 0);
    1736         244 :     code.reset(cf->newCode());
    1737         244 :     code->loadLocalReference(0);
    1738         244 :     sal_uInt16 index2 = 1;
    1739         244 :     desc.addParameter("string", false, true, 0);
    1740         244 :     code->loadLocalReference(index2++);
    1741         244 :     if (!(baseException || baseRuntimeException)) {
    1742             :         addExceptionBaseArguments(
    1743             :             manager, dependencies, &desc, code.get(), entity->getDirectBase(),
    1744         242 :             &index2);
    1745             :     }
    1746         244 :     code->instrInvokespecial(superClass, "<init>", desc.getDescriptor());
    1747         244 :     sal_uInt16 maxSize = index2;
    1748         244 :     if (baseRuntimeException) {
    1749             :         maxSize = std::max(
    1750             :             maxSize,
    1751             :             addDirectArgument(
    1752             :                 manager, dependencies, &desc, code.get(), &index2, className,
    1753           1 :                 "Context", false, "com.sun.star.uno.XInterface"));
    1754             :     }
    1755        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1756         244 :              entity->getDirectMembers().begin());
    1757         792 :          i != entity->getDirectMembers().end(); ++i)
    1758             :     {
    1759         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1760             :             maxSize = std::max(
    1761             :                 maxSize,
    1762             :                 addDirectArgument(
    1763             :                     manager, dependencies, &desc, code.get(), &index2,
    1764         151 :                     className, codemaker::convertString(i->name), false,
    1765         302 :                     i->type));
    1766             :         }
    1767             :     }
    1768         244 :     code->instrReturn();
    1769         244 :     code->setMaxStackAndLocals(maxSize, index2);
    1770             :     cf->addMethod(
    1771         244 :         ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
    1772         488 :         std::vector< OString >(), desc.getSignature());
    1773         244 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1774         488 :     writeClassFile(options, className, *cf.get());
    1775         244 : }
    1776             : 
    1777        6863 : void createExceptionsAttribute(
    1778             :     rtl::Reference< TypeManager > const & manager,
    1779             :     std::vector< OUString > const & exceptionTypes,
    1780             :     Dependencies * dependencies, std::vector< OString > * exceptions,
    1781             :     codemaker::ExceptionTree * tree)
    1782             : {
    1783             :     assert(dependencies != 0);
    1784             :     assert(exceptions != 0);
    1785       29241 :     for (std::vector< OUString >::const_iterator i(exceptionTypes.begin());
    1786       19494 :          i != exceptionTypes.end(); ++i)
    1787             :     {
    1788        2884 :         dependencies->insert(*i);
    1789        2884 :         OString type(codemaker::convertString(*i).replace('.', '/'));
    1790        2884 :         exceptions->push_back(type);
    1791        2884 :         if (tree != 0) {
    1792          50 :             tree->add(type.replace('/', '.'), manager);
    1793             :         }
    1794        2884 :     }
    1795        6863 : }
    1796             : 
    1797        1694 : void handleInterfaceType(
    1798             :     OUString name, rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
    1799             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1800             :     Dependencies * dependencies)
    1801             : {
    1802             :     assert(entity.is());
    1803             :     assert(dependencies != 0);
    1804        1694 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1805             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1806             :     std::auto_ptr< ClassFile > cf(
    1807             :         new ClassFile(
    1808             :             static_cast< ClassFile::AccessFlags >(
    1809             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
    1810             :                 | ClassFile::ACC_ABSTRACT),
    1811        3388 :             className, "java/lang/Object", ""));
    1812             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1813       10851 :     for (std::vector< unoidl::AnnotatedReference >::const_iterator i(
    1814        1694 :              entity->getDirectMandatoryBases().begin());
    1815        7234 :          i != entity->getDirectMandatoryBases().end(); ++i)
    1816             :     {
    1817        1923 :         dependencies->insert(i->name);
    1818        1923 :         cf->addInterface(codemaker::convertString(i->name).replace('.', '/'));
    1819             :     }
    1820             :     // As a special case, let com.sun.star.lang.XEventListener extend
    1821             :     // java.util.EventListener ("A tagging interface that all event listener
    1822             :     // interfaces must extend"):
    1823        1694 :     if (className == "com/sun/star/lang/XEventListener") {
    1824           1 :         cf->addInterface("java/util/EventListener");
    1825             :     }
    1826        3388 :     std::vector< TypeInfo > typeInfo;
    1827        1694 :     if (className != "com/sun/star/uno/XInterface") {
    1828        1693 :         sal_Int32 index = 0;
    1829        6939 :         for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
    1830        1693 :                  const_iterator i(entity->getDirectAttributes().begin());
    1831        4626 :              i != entity->getDirectAttributes().end(); ++i)
    1832             :         {
    1833             :             SpecialType specialType;
    1834         620 :             PolymorphicUnoType polymorphicUnoType;
    1835             :             MethodDescriptor gdesc(
    1836         620 :                 manager, dependencies, i->type, &specialType,
    1837        1240 :                 &polymorphicUnoType);
    1838        1240 :             std::vector< OString > exc;
    1839             :             createExceptionsAttribute(
    1840         620 :                 manager, i->getExceptions, dependencies, &exc, 0);
    1841        1240 :             OString attrName(codemaker::convertString(i->name));
    1842             :             cf->addMethod(
    1843             :                 static_cast< ClassFile::AccessFlags >(
    1844             :                     ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    1845        1240 :                 "get" + attrName, gdesc.getDescriptor(), 0, exc,
    1846        1860 :                 gdesc.getSignature());
    1847         620 :             if (!i->readOnly) {
    1848         483 :                 MethodDescriptor sdesc(manager, dependencies, "void", 0, 0);
    1849         483 :                 sdesc.addParameter(i->type, false, true, 0);
    1850         966 :                 std::vector< OString > exc2;
    1851             :                 createExceptionsAttribute(
    1852         483 :                     manager, i->setExceptions, dependencies, &exc2, 0);
    1853             :                 cf->addMethod(
    1854             :                     static_cast< ClassFile::AccessFlags >(
    1855             :                         ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    1856         966 :                     "set" + attrName, sdesc.getDescriptor(), 0, exc2,
    1857        1932 :                     sdesc.getSignature());
    1858             :             }
    1859             :             typeInfo.push_back(
    1860             :                 TypeInfo(
    1861             :                     TypeInfo::KIND_ATTRIBUTE, attrName, specialType,
    1862             :                     static_cast< TypeInfo::Flags >(
    1863         620 :                         (i->readOnly ? TypeInfo::FLAG_READONLY : 0)
    1864         620 :                         | (i->bound ? TypeInfo::FLAG_BOUND : 0)),
    1865         620 :                     index, polymorphicUnoType));
    1866         620 :             index += (i->readOnly ? 1 : 2);
    1867         620 :         }
    1868       21954 :         for (std::vector< unoidl::InterfaceTypeEntity::Method >::const_iterator
    1869        1693 :                  i(entity->getDirectMethods().begin());
    1870       14636 :              i != entity->getDirectMethods().end(); ++i)
    1871             :         {
    1872        5625 :             OString methodName(codemaker::convertString(i->name));
    1873             :             SpecialType specialReturnType;
    1874       11250 :             PolymorphicUnoType polymorphicUnoReturnType;
    1875             :             MethodDescriptor desc(
    1876        5625 :                 manager, dependencies, i->returnType, &specialReturnType,
    1877       11250 :                 &polymorphicUnoReturnType);
    1878             :             typeInfo.push_back(
    1879             :                 TypeInfo(
    1880             :                     TypeInfo::KIND_METHOD, methodName, specialReturnType,
    1881             :                     static_cast< TypeInfo::Flags >(0), index++,
    1882        5625 :                     polymorphicUnoReturnType));
    1883        5625 :             sal_Int32 paramIndex = 0;
    1884       34206 :             for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
    1885        5625 :                      const_iterator j(i->parameters.begin());
    1886       22804 :                  j != i->parameters.end(); ++j)
    1887             :             {
    1888        5777 :                 bool in = j->direction
    1889        5777 :                     != (unoidl::InterfaceTypeEntity::Method::Parameter::
    1890        5777 :                         DIRECTION_OUT);
    1891        5777 :                 bool out = j->direction
    1892        5777 :                     != (unoidl::InterfaceTypeEntity::Method::Parameter::
    1893        5777 :                         DIRECTION_IN);
    1894        5777 :                 PolymorphicUnoType polymorphicUnoType;
    1895             :                 SpecialType specialType = desc.addParameter(
    1896        5777 :                     j->type, out, true, &polymorphicUnoType);
    1897       11397 :                 if (out || isSpecialType(specialType)
    1898       11322 :                     || polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE)
    1899             :                 {
    1900             :                     typeInfo.push_back(
    1901             :                         TypeInfo(
    1902         235 :                             codemaker::convertString(j->name), specialType, in,
    1903         470 :                             out, methodName, paramIndex, polymorphicUnoType));
    1904             :                 }
    1905        5777 :                 ++paramIndex;
    1906        5777 :             }
    1907       11250 :             std::vector< OString > exc2;
    1908             :             createExceptionsAttribute(
    1909        5625 :                 manager, i->exceptions, dependencies, &exc2, 0);
    1910             :             cf->addMethod(
    1911             :                 static_cast< ClassFile::AccessFlags >(
    1912             :                     ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    1913        5625 :                 methodName, desc.getDescriptor(), 0, exc2, desc.getSignature());
    1914        5625 :         }
    1915             :     }
    1916        1694 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1917        3388 :     writeClassFile(options, className, *cf.get());
    1918        1694 : }
    1919             : 
    1920          19 : void handleTypedef(
    1921             :     rtl::Reference< unoidl::TypedefEntity > const & entity,
    1922             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies)
    1923             : {
    1924             :     assert(entity.is());
    1925             :     assert(manager.is());
    1926             :     assert(dependencies != 0);
    1927          19 :     OUString nucleus;
    1928          19 :     switch (manager->decompose(entity->getType(), false, &nucleus, 0, 0, 0))
    1929             :     {
    1930             :     case codemaker::UnoType::SORT_BOOLEAN:
    1931             :     case codemaker::UnoType::SORT_BYTE:
    1932             :     case codemaker::UnoType::SORT_SHORT:
    1933             :     case codemaker::UnoType::SORT_UNSIGNED_SHORT:
    1934             :     case codemaker::UnoType::SORT_LONG:
    1935             :     case codemaker::UnoType::SORT_UNSIGNED_LONG:
    1936             :     case codemaker::UnoType::SORT_HYPER:
    1937             :     case codemaker::UnoType::SORT_UNSIGNED_HYPER:
    1938             :     case codemaker::UnoType::SORT_FLOAT:
    1939             :     case codemaker::UnoType::SORT_DOUBLE:
    1940             :     case codemaker::UnoType::SORT_CHAR:
    1941             :     case codemaker::UnoType::SORT_STRING:
    1942             :     case codemaker::UnoType::SORT_TYPE:
    1943             :     case codemaker::UnoType::SORT_ANY:
    1944          10 :         break;
    1945             :     case codemaker::UnoType::SORT_ENUM_TYPE:
    1946             :     case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    1947             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
    1948             :     case codemaker::UnoType::SORT_TYPEDEF:
    1949           9 :         dependencies->insert(nucleus);
    1950           9 :         break;
    1951             :     default:
    1952             :         assert(false); // this cannot happen
    1953          19 :     }
    1954          19 : }
    1955             : 
    1956         349 : void handleConstantGroup(
    1957             :     OUString name, rtl::Reference< unoidl::ConstantGroupEntity > const & entity,
    1958             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1959             :     Dependencies * dependencies)
    1960             : {
    1961             :     assert(entity.is());
    1962         349 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1963             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    1964             :     std::auto_ptr< ClassFile > cf(
    1965             :         new ClassFile(
    1966             :             static_cast< ClassFile::AccessFlags >(
    1967             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
    1968             :                 | ClassFile::ACC_ABSTRACT),
    1969         698 :             className, "java/lang/Object", ""));
    1970             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    1971       11031 :     for (std::vector< unoidl::ConstantGroupEntity::Member >::const_iterator i(
    1972         349 :              entity->getMembers().begin());
    1973        7354 :          i != entity->getMembers().end(); ++i)
    1974             :     {
    1975        3328 :         OUString type;
    1976        3328 :         sal_uInt16 valueIndex = sal_uInt16(); // avoid false warnings
    1977        3328 :         switch (i->value.type) {
    1978             :         case unoidl::ConstantValue::TYPE_BOOLEAN:
    1979           0 :             type = "boolean";
    1980           0 :             valueIndex = cf->addIntegerInfo(i->value.booleanValue);
    1981           0 :             break;
    1982             :         case unoidl::ConstantValue::TYPE_BYTE:
    1983         245 :             type = "byte";
    1984         245 :             valueIndex = cf->addIntegerInfo(i->value.byteValue);
    1985         245 :             break;
    1986             :         case unoidl::ConstantValue::TYPE_SHORT:
    1987        2044 :             type = "short";
    1988        2044 :             valueIndex = cf->addIntegerInfo(i->value.shortValue);
    1989        2044 :             break;
    1990             :         case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
    1991           0 :             type = "unsigned short";
    1992           0 :             valueIndex = cf->addIntegerInfo(i->value.unsignedShortValue);
    1993           0 :             break;
    1994             :         case unoidl::ConstantValue::TYPE_LONG:
    1995         990 :             type = "long";
    1996         990 :             valueIndex = cf->addIntegerInfo(i->value.longValue);
    1997         990 :             break;
    1998             :         case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
    1999           0 :             type = "unsigned long";
    2000             :             valueIndex = cf->addIntegerInfo(
    2001           0 :                 static_cast< sal_Int32 >(i->value.unsignedLongValue));
    2002           0 :             break;
    2003             :         case unoidl::ConstantValue::TYPE_HYPER:
    2004          29 :             type = "hyper";
    2005          29 :             valueIndex = cf->addLongInfo(i->value.hyperValue);
    2006          29 :             break;
    2007             :         case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
    2008           0 :             type = "unsigned hyper";
    2009             :             valueIndex = cf->addLongInfo(
    2010           0 :                 static_cast< sal_Int64 >(i->value.unsignedHyperValue));
    2011           0 :             break;
    2012             :         case unoidl::ConstantValue::TYPE_FLOAT:
    2013          20 :             type = "float";
    2014          20 :             valueIndex = cf->addFloatInfo(i->value.floatValue);
    2015          20 :             break;
    2016             :         case unoidl::ConstantValue::TYPE_DOUBLE:
    2017           0 :             type = "double";
    2018           0 :             valueIndex = cf->addDoubleInfo(i->value.doubleValue);
    2019           0 :             break;
    2020             :         }
    2021        3328 :         OString desc;
    2022        6656 :         OString sig;
    2023        3328 :         getFieldDescriptor(manager, dependencies, type, &desc, &sig, 0);
    2024             :         cf->addField(
    2025             :             static_cast< ClassFile::AccessFlags >(
    2026             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
    2027             :                 | ClassFile::ACC_FINAL),
    2028        3328 :             codemaker::convertString(i->name), desc, valueIndex, sig);
    2029        3328 :     }
    2030         698 :     writeClassFile(options, className, *cf.get());
    2031         349 : }
    2032             : 
    2033         376 : void addExceptionHandlers(
    2034             :     codemaker::ExceptionTreeNode const * node,
    2035             :     ClassFile::Code::Position start, ClassFile::Code::Position end,
    2036             :     ClassFile::Code::Position handler, ClassFile::Code * code)
    2037             : {
    2038             :     assert(node != 0);
    2039             :     assert(code != 0);
    2040         376 :     if (node->present) {
    2041          12 :         code->addException(start, end, handler, node->name.replace('.', '/'));
    2042             :     } else {
    2043        1131 :         for (codemaker::ExceptionTreeNode::Children::const_iterator i(
    2044         364 :                  node->children.begin());
    2045         754 :              i != node->children.end(); ++i)
    2046             :         {
    2047          13 :             addExceptionHandlers(*i, start, end, handler, code);
    2048             :         }
    2049             :     }
    2050         376 : }
    2051             : 
    2052         366 : void addConstructor(
    2053             :     rtl::Reference< TypeManager > const & manager,
    2054             :     OString const & realJavaBaseName, OString const & unoName,
    2055             :     OString const & className,
    2056             :     unoidl::SingleInterfaceBasedServiceEntity::Constructor const & constructor,
    2057             :     OUString const & returnType, Dependencies * dependencies,
    2058             :     ClassFile * classFile)
    2059             : {
    2060             :     assert(dependencies != 0);
    2061             :     assert(classFile != 0);
    2062         366 :     MethodDescriptor desc(manager, dependencies, returnType, 0, 0);
    2063         366 :     desc.addParameter("com.sun.star.uno.XComponentContext", false, false, 0);
    2064             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2065         732 :     std::auto_ptr< ClassFile::Code > code(classFile->newCode());
    2066             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2067         366 :     code->loadLocalReference(0);
    2068             :     // stack: context
    2069             :     code->instrInvokeinterface(
    2070             :         "com/sun/star/uno/XComponentContext", "getServiceManager",
    2071         366 :         "()Lcom/sun/star/lang/XMultiComponentFactory;", 1);
    2072             :     // stack: factory
    2073         366 :     code->loadStringConstant(unoName);
    2074             :     // stack: factory serviceName
    2075         732 :     codemaker::ExceptionTree tree;
    2076             :     ClassFile::Code::Position tryStart;
    2077             :     ClassFile::Code::Position tryEnd;
    2078         732 :     std::vector< OString > exc;
    2079             :     sal_uInt16 stack;
    2080         366 :     sal_uInt16 localIndex = 1;
    2081             :     ClassFile::AccessFlags access = static_cast< ClassFile::AccessFlags >(
    2082         366 :         ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC);
    2083         366 :     if (constructor.defaultConstructor) {
    2084         231 :         code->loadLocalReference(0);
    2085             :         // stack: factory serviceName context
    2086         231 :         tryStart = code->getPosition();
    2087             :         code->instrInvokeinterface(
    2088             :             "com/sun/star/lang/XMultiComponentFactory",
    2089             :             "createInstanceWithContext",
    2090             :             ("(Ljava/lang/String;Lcom/sun/star/uno/XComponentContext;)"
    2091             :              "Ljava/lang/Object;"),
    2092         231 :             3);
    2093         231 :         tryEnd = code->getPosition();
    2094             :         // stack: instance
    2095         231 :         stack = 3;
    2096             :     } else {
    2097         270 :         if (constructor.parameters.size() == 1
    2098         135 :             && constructor.parameters[0].rest)
    2099             :         {
    2100           1 :             desc.addParameter("any", true, true, 0);
    2101           1 :             code->loadLocalReference(localIndex++);
    2102             :             // stack: factory serviceName args
    2103           1 :             stack = 4;
    2104             :             access = static_cast< ClassFile::AccessFlags >(
    2105           1 :                 access | ClassFile::ACC_VARARGS);
    2106             :         } else {
    2107         134 :             code->loadIntegerConstant(constructor.parameters.size());
    2108             :             // stack: factory serviceName N
    2109         134 :             code->instrAnewarray("java/lang/Object");
    2110             :             // stack: factory serviceName args
    2111         134 :             stack = 0;
    2112         134 :             sal_Int32 n = 0;
    2113        1212 :             for (std::vector<
    2114             :                      unoidl::SingleInterfaceBasedServiceEntity::Constructor::
    2115             :                      Parameter >::const_iterator i(
    2116         134 :                          constructor.parameters.begin());
    2117         808 :                  i != constructor.parameters.end(); ++i)
    2118             :             {
    2119         270 :                 desc.addParameter(i->type, false, true, 0);
    2120         270 :                 code->instrDup();
    2121             :                 // stack: factory serviceName args args
    2122         270 :                 code->loadIntegerConstant(n++);
    2123             :                 // stack: factory serviceName args args i
    2124             :                 stack = std::max(
    2125             :                     stack,
    2126             :                     addLoadLocal(
    2127         270 :                         manager, code.get(), &localIndex, false, i->type, true,
    2128         270 :                         dependencies));
    2129             :                 // stack: factory serviceName args args i any
    2130         270 :                 code->instrAastore();
    2131             :                 // stack: factory serviceName args
    2132             :             }
    2133         134 :             stack += 5;
    2134             :         }
    2135         135 :         code->loadLocalReference(0);
    2136             :         // stack: factory serviceName args context
    2137         135 :         tryStart = code->getPosition();
    2138             :         code->instrInvokeinterface(
    2139             :             "com/sun/star/lang/XMultiComponentFactory",
    2140             :             "createInstanceWithArgumentsAndContext",
    2141             :             ("(Ljava/lang/String;[Ljava/lang/Object;"
    2142             :              "Lcom/sun/star/uno/XComponentContext;)Ljava/lang/Object;"),
    2143         135 :             4);
    2144         135 :         tryEnd = code->getPosition();
    2145             :         // stack: instance
    2146             :         createExceptionsAttribute(
    2147         135 :             manager, constructor.exceptions, dependencies, &exc, &tree);
    2148             :     }
    2149         366 :     code->loadLocalReference(0);
    2150             :     // stack: instance context
    2151             :     code->instrInvokestatic(
    2152             :         className, "$castInstance",
    2153             :         ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
    2154         366 :          "Ljava/lang/Object;"));
    2155             :     // stack: instance
    2156             :     code->instrCheckcast(
    2157         366 :         codemaker::convertString(returnType).replace('.', '/'));
    2158             :     // stack: instance
    2159         366 :     code->instrAreturn();
    2160         366 :     if (!tree.getRoot()->present) {
    2161         363 :         ClassFile::Code::Position pos1 = code->getPosition();
    2162             :         // stack: e
    2163             :         code->instrInvokevirtual(
    2164         363 :             "java/lang/Throwable", "toString", "()Ljava/lang/String;");
    2165             :         // stack: str
    2166         363 :         localIndex = std::max< sal_uInt16 >(localIndex, 2);
    2167         363 :         code->storeLocalReference(1);
    2168             :         // stack: -
    2169         363 :         code->instrNew("com/sun/star/uno/DeploymentException");
    2170             :         // stack: ex
    2171         363 :         code->instrDup();
    2172             :         // stack: ex ex
    2173             :         code->loadStringConstant(
    2174         726 :             "component context fails to supply service " + unoName + " of type "
    2175         363 :             + realJavaBaseName + ": ");
    2176             :         // stack: ex ex "..."
    2177         363 :         code->loadLocalReference(1);
    2178             :         // stack: ex ex "..." str
    2179             :         code->instrInvokevirtual(
    2180             :             "java/lang/String", "concat",
    2181         363 :             "(Ljava/lang/String;)Ljava/lang/String;");
    2182             :         // stack: ex ex "..."
    2183         363 :         code->loadLocalReference(0);
    2184             :         // stack: ex ex "..." context
    2185             :         code->instrInvokespecial(
    2186             :             "com/sun/star/uno/DeploymentException", "<init>",
    2187         363 :             "(Ljava/lang/String;Ljava/lang/Object;)V");
    2188             :         // stack: ex
    2189         363 :         ClassFile::Code::Position pos2 = code->getPosition();
    2190         363 :         code->instrAthrow();
    2191             :         addExceptionHandlers(
    2192         363 :             tree.getRoot(), tryStart, tryEnd, pos2, code.get());
    2193             :         code->addException(
    2194         363 :             tryStart, tryEnd, pos1, "com/sun/star/uno/Exception");
    2195         363 :         dependencies->insert("com.sun.star.uno.Exception");
    2196         363 :         stack = std::max< sal_uInt16 >(stack, 4);
    2197             :     }
    2198         366 :     code->setMaxStackAndLocals(stack, localIndex);
    2199             :     classFile->addMethod(
    2200             :         access,
    2201             :         codemaker::java::translateUnoToJavaIdentifier(
    2202             :             (constructor.defaultConstructor
    2203             :              ? OString("create") : codemaker::convertString(constructor.name)),
    2204             :             "method"),
    2205         732 :         desc.getDescriptor(), code.get(), exc, desc.getSignature());
    2206         366 : }
    2207             : 
    2208         340 : void handleService(
    2209             :     OUString name,
    2210             :     rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const & entity,
    2211             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    2212             :     Dependencies * dependencies)
    2213             : {
    2214             :     assert(entity.is());
    2215             :     assert(dependencies != 0);
    2216         340 :     OString unoName(codemaker::convertString(name));
    2217             :     OString className(
    2218         680 :         translateUnoidlEntityNameToJavaFullyQualifiedName(name, "service"));
    2219             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2220             :     std::auto_ptr< ClassFile > cf(
    2221             :         new ClassFile(
    2222             :             static_cast< ClassFile::AccessFlags >(
    2223             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
    2224             :                 | ClassFile::ACC_SUPER),
    2225         680 :             className, "java/lang/Object", ""));
    2226             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2227         340 :     if (!entity->getConstructors().empty()) {
    2228             :         OString realJavaBaseName(
    2229         321 :             codemaker::convertString(entity->getBase()));
    2230         321 :         dependencies->insert(entity->getBase());
    2231         321 :         dependencies->insert("com.sun.star.lang.XMultiComponentFactory");
    2232         321 :         dependencies->insert("com.sun.star.uno.DeploymentException");
    2233         321 :         dependencies->insert("com.sun.star.uno.TypeClass");
    2234         321 :         dependencies->insert("com.sun.star.uno.XComponentContext");
    2235        2061 :         for (std::vector<
    2236             :                  unoidl::SingleInterfaceBasedServiceEntity::Constructor >::
    2237         321 :                  const_iterator i(entity->getConstructors().begin());
    2238        1374 :              i != entity->getConstructors().end(); ++i)
    2239             :         {
    2240             :             addConstructor(
    2241         366 :                 manager, realJavaBaseName, unoName, className, *i,
    2242         732 :                 entity->getBase(), dependencies, cf.get());
    2243             :         }
    2244             :         // Synthetic castInstance method:
    2245             :         {
    2246             :             SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2247         321 :             std::auto_ptr< ClassFile::Code > code(cf->newCode());
    2248             :             SAL_WNODEPRECATED_DECLARATIONS_POP
    2249         321 :             code->instrNew("com/sun/star/uno/Type");
    2250             :             // stack: type
    2251         321 :             code->instrDup();
    2252             :             // stack: type type
    2253         321 :             code->loadStringConstant(realJavaBaseName);
    2254             :             // stack: type type "..."
    2255             :             code->instrGetstatic(
    2256             :                 "com/sun/star/uno/TypeClass", "INTERFACE",
    2257         321 :                 "Lcom/sun/star/uno/TypeClass;");
    2258             :             // stack: type type "..." INTERFACE
    2259             :             code->instrInvokespecial(
    2260             :                 "com/sun/star/uno/Type", "<init>",
    2261         321 :                 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    2262             :             // stack: type
    2263         321 :             code->loadLocalReference(0);
    2264             :             // stack: type instance
    2265             :             code->instrInvokestatic(
    2266             :                 "com/sun/star/uno/UnoRuntime", "queryInterface",
    2267             :                 ("(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
    2268         321 :                  "Ljava/lang/Object;"));
    2269             :             // stack: instance
    2270         321 :             code->instrDup();
    2271             :             // stack: instance instance
    2272         321 :             ClassFile::Code::Branch branch = code->instrIfnull();
    2273             :             // stack: instance
    2274         321 :             code->instrAreturn();
    2275         321 :             code->branchHere(branch);
    2276         321 :             code->instrPop();
    2277             :             // stack: -
    2278         321 :             code->instrNew("com/sun/star/uno/DeploymentException");
    2279             :             // stack: ex
    2280         321 :             code->instrDup();
    2281             :             // stack: ex ex
    2282             :             code->loadStringConstant(
    2283         642 :                 "component context fails to supply service " + unoName
    2284         321 :                 + " of type " + realJavaBaseName);
    2285             :             // stack: ex ex "..."
    2286         321 :             code->loadLocalReference(1);
    2287             :             // stack: ex ex "..." context
    2288             :             code->instrInvokespecial(
    2289             :                 "com/sun/star/uno/DeploymentException", "<init>",
    2290         321 :                 "(Ljava/lang/String;Ljava/lang/Object;)V");
    2291             :             // stack: ex
    2292         321 :             code->instrAthrow();
    2293         321 :             code->setMaxStackAndLocals(4, 2);
    2294             :             cf->addMethod(
    2295             :                 static_cast< ClassFile::AccessFlags >(
    2296             :                     ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC
    2297             :                     | ClassFile::ACC_SYNTHETIC),
    2298             :                 "$castInstance",
    2299             :                 ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
    2300             :                  "Ljava/lang/Object;"),
    2301         321 :                 code.get(), std::vector< OString >(), "");
    2302         321 :         }
    2303             :     }
    2304         680 :     writeClassFile(options, className, *cf.get());
    2305         340 : }
    2306             : 
    2307          16 : void handleSingleton(
    2308             :     OUString name,
    2309             :     rtl::Reference< unoidl::InterfaceBasedSingletonEntity > const & entity,
    2310             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    2311             :     Dependencies * dependencies)
    2312             : {
    2313             :     assert(entity.is());
    2314             :     assert(dependencies != 0);
    2315          16 :     OString realJavaBaseName(codemaker::convertString(entity->getBase()));
    2316          32 :     OString base(realJavaBaseName.replace('.', '/'));
    2317          16 :     dependencies->insert(entity->getBase());
    2318          32 :     OString unoName(codemaker::convertString(name));
    2319             :     OString className(
    2320          32 :         translateUnoidlEntityNameToJavaFullyQualifiedName(name, "singleton"));
    2321          16 :     dependencies->insert("com.sun.star.uno.DeploymentException");
    2322          16 :     dependencies->insert("com.sun.star.uno.TypeClass");
    2323          16 :     dependencies->insert("com.sun.star.uno.XComponentContext");
    2324             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2325             :     std::auto_ptr< ClassFile > cf(
    2326             :         new ClassFile(
    2327             :             static_cast< ClassFile::AccessFlags >(
    2328             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
    2329             :                 | ClassFile::ACC_SUPER),
    2330          32 :             className, "java/lang/Object", ""));
    2331             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2332          32 :     MethodDescriptor desc(manager, dependencies, entity->getBase(), 0, 0);
    2333          16 :     desc.addParameter("com.sun.star.uno.XComponentContext", false, false, 0);
    2334             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
    2335          32 :     std::auto_ptr< ClassFile::Code > code(cf->newCode());
    2336             :     SAL_WNODEPRECATED_DECLARATIONS_POP
    2337          16 :     code->loadLocalReference(0);
    2338             :     // stack: context
    2339          16 :     code->loadStringConstant("/singletons/" + unoName);
    2340             :     // stack: context "..."
    2341             :     code->instrInvokeinterface(
    2342             :         "com/sun/star/uno/XComponentContext", "getValueByName",
    2343          16 :         "(Ljava/lang/String;)Ljava/lang/Object;", 2);
    2344             :     // stack: value
    2345          16 :     code->instrDup();
    2346             :     // stack: value value
    2347          16 :     code->instrInstanceof("com/sun/star/uno/Any");
    2348             :     // stack: value 0/1
    2349          16 :     ClassFile::Code::Branch branch1 = code->instrIfeq();
    2350             :     // stack: value
    2351          16 :     code->instrCheckcast("com/sun/star/uno/Any");
    2352             :     // stack: value
    2353          16 :     code->instrDup();
    2354             :     // stack: value value
    2355             :     code->instrInvokevirtual(
    2356          16 :         "com/sun/star/uno/Any", "getType", "()Lcom/sun/star/uno/Type;");
    2357             :     // stack: value type
    2358             :     code->instrInvokevirtual(
    2359             :         "com/sun/star/uno/Type", "getTypeClass",
    2360          16 :         "()Lcom/sun/star/uno/TypeClass;");
    2361             :     // stack: value typeClass
    2362             :     code->instrGetstatic(
    2363             :         "com/sun/star/uno/TypeClass", "INTERFACE",
    2364          16 :         "Lcom/sun/star/uno/TypeClass;");
    2365             :     // stack: value typeClass INTERFACE
    2366          16 :     ClassFile::Code::Branch branch2 = code->instrIfAcmpne();
    2367             :     // stack: value
    2368             :     code->instrInvokevirtual(
    2369          16 :         "com/sun/star/uno/Any", "getObject", "()Ljava/lang/Object;");
    2370             :     // stack: value
    2371          16 :     code->branchHere(branch1);
    2372          16 :     code->instrNew("com/sun/star/uno/Type");
    2373             :     // stack: value type
    2374          16 :     code->instrDup();
    2375             :     // stack: value type type
    2376          16 :     code->loadStringConstant(realJavaBaseName);
    2377             :     // stack: value type type "..."
    2378             :     code->instrGetstatic(
    2379             :         "com/sun/star/uno/TypeClass", "INTERFACE",
    2380          16 :         "Lcom/sun/star/uno/TypeClass;");
    2381             :     // stack: value type type "..." INTERFACE
    2382             :     code->instrInvokespecial(
    2383             :         "com/sun/star/uno/Type", "<init>",
    2384          16 :         "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    2385             :     // stack: value type
    2386          16 :     code->instrSwap();
    2387             :     // stack: type value
    2388             :     code->instrInvokestatic(
    2389             :         "com/sun/star/uno/UnoRuntime", "queryInterface",
    2390          16 :         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;");
    2391             :     // stack: instance
    2392          16 :     code->instrDup();
    2393             :     // stack: instance instance
    2394          16 :     ClassFile::Code::Branch branch3 = code->instrIfnull();
    2395             :     // stack: instance
    2396          16 :     code->instrCheckcast(base);
    2397             :     // stack: instance
    2398          16 :     code->instrAreturn();
    2399          16 :     code->branchHere(branch2);
    2400          16 :     code->branchHere(branch3);
    2401          16 :     code->instrPop();
    2402             :     // stack: -
    2403          16 :     code->instrNew("com/sun/star/uno/DeploymentException");
    2404             :     // stack: ex
    2405          16 :     code->instrDup();
    2406             :     // stack: ex ex
    2407             :     code->loadStringConstant(
    2408          32 :         "component context fails to supply singleton " + unoName + " of type "
    2409          16 :         + realJavaBaseName);
    2410             :     // stack: ex ex "..."
    2411          16 :     code->loadLocalReference(0);
    2412             :     // stack: ex ex "..." context
    2413             :     code->instrInvokespecial(
    2414             :         "com/sun/star/uno/DeploymentException", "<init>",
    2415          16 :         "(Ljava/lang/String;Ljava/lang/Object;)V");
    2416             :     // stack: ex
    2417          16 :     code->instrAthrow();
    2418          16 :     code->setMaxStackAndLocals(5, 1);
    2419             :     cf->addMethod(
    2420             :         static_cast< ClassFile::AccessFlags >(
    2421             :             ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
    2422          16 :         "get", desc.getDescriptor(), code.get(), std::vector< OString >(),
    2423          32 :         desc.getSignature());
    2424          32 :     writeClassFile(options, className, *cf.get());
    2425          16 : }
    2426             : 
    2427             : }
    2428             : 
    2429       12478 : void produce(
    2430             :     OUString const & name, rtl::Reference< TypeManager > const & manager,
    2431             :     codemaker::GeneratedTypeSet & generated, JavaOptions const & options)
    2432             : {
    2433       12478 :     if (generated.contains(u2b(name))) {
    2434       15930 :         return;
    2435             :     }
    2436        4748 :     generated.add(u2b(name));
    2437        4748 :     if (!manager->foundAtPrimaryProvider(name)) {
    2438         316 :         return;
    2439             :     }
    2440        4432 :     Dependencies deps;
    2441        8710 :     rtl::Reference< unoidl::Entity > ent;
    2442        8710 :     rtl::Reference< unoidl::MapCursor > cur;
    2443        4432 :     switch (manager->getSort(name, &ent, &cur)) {
    2444             :     case codemaker::UnoType::SORT_MODULE:
    2445             :         {
    2446         154 :             OUString prefix;
    2447         154 :             if (!name.isEmpty()) {
    2448         150 :                 prefix = name + ".";
    2449             :             }
    2450             :             for (;;) {
    2451        4895 :                 OUString mem;
    2452        4895 :                 if (!cur->getNext(&mem).is()) {
    2453         154 :                     break;
    2454             :                 }
    2455        4741 :                 produce(prefix + mem, manager, generated, options);
    2456        4741 :             }
    2457         154 :             return;
    2458             :         }
    2459             :     case codemaker::UnoType::SORT_ENUM_TYPE:
    2460             :         handleEnumType(
    2461         193 :             name, dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), options);
    2462         193 :         break;
    2463             :     case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    2464             :         handlePlainStructType(
    2465         397 :             name, dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
    2466         397 :             manager, options, &deps);
    2467         397 :         break;
    2468             :     case codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
    2469             :         handlePolyStructType(
    2470             :             name,
    2471             :             dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
    2472           6 :                 ent.get()),
    2473           6 :             manager, options, &deps);
    2474           6 :         break;
    2475             :     case codemaker::UnoType::SORT_EXCEPTION_TYPE:
    2476             :         handleExceptionType(
    2477         244 :             name, dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()),
    2478         244 :             manager, options, &deps);
    2479         244 :         break;
    2480             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
    2481             :         handleInterfaceType(
    2482        1694 :             name, dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()),
    2483        1694 :             manager, options, &deps);
    2484        1694 :         break;
    2485             :     case codemaker::UnoType::SORT_TYPEDEF:
    2486             :         handleTypedef(
    2487          19 :             dynamic_cast< unoidl::TypedefEntity * >(ent.get()), manager, &deps);
    2488          19 :         break;
    2489             :     case codemaker::UnoType::SORT_CONSTANT_GROUP:
    2490             :         handleConstantGroup(
    2491         349 :             name, dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()),
    2492         349 :             manager, options, &deps);
    2493         349 :         break;
    2494             :     case codemaker::UnoType::SORT_SINGLE_INTERFACE_BASED_SERVICE:
    2495             :         handleService(
    2496             :             name,
    2497             :             dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
    2498         340 :                 ent.get()),
    2499         340 :             manager, options, &deps);
    2500         340 :         break;
    2501             :     case codemaker::UnoType::SORT_INTERFACE_BASED_SINGLETON:
    2502             :         handleSingleton(
    2503             :             name,
    2504          16 :             dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(ent.get()),
    2505          16 :             manager, options, &deps);
    2506          16 :         break;
    2507             :     case codemaker::UnoType::SORT_ACCUMULATION_BASED_SERVICE:
    2508             :     case codemaker::UnoType::SORT_SERVICE_BASED_SINGLETON:
    2509        1020 :         break;
    2510             :     default:
    2511             :         throw CannotDumpException(
    2512           0 :             "unexpected entity \"" + name + "\" in call to produce");
    2513             :     }
    2514        4278 :     if (!options.isValid("-nD")) {
    2515       11968 :         for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) {
    2516        7733 :             produce(*i, manager, generated, options);
    2517             :         }
    2518        4278 :     }
    2519             : }
    2520             : 
    2521             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10