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

Generated by: LCOV version 1.10