LCOV - code coverage report
Current view: top level - codemaker/source/javamaker - javatype.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1228 1275 96.3 %
Date: 2015-06-13 12:38:46 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        5674 : bool isSpecialType(SpecialType special) {
     107        5674 :     return special >= SPECIAL_TYPE_UNSIGNED;
     108             : }
     109             : 
     110         371 : OString translateUnoidlEntityNameToJavaFullyQualifiedName(
     111             :     OUString const & name, OString const & prefix)
     112             : {
     113             :     assert(!name.startsWith("[]"));
     114             :     assert(name.indexOf('<') == -1);
     115         371 :     sal_Int32 i = name.lastIndexOf('.') + 1;
     116             :     return codemaker::convertString(name.copy(0, i)).replace('.', '/')
     117         742 :         + codemaker::java::translateUnoToJavaIdentifier(
     118        1113 :             codemaker::convertString(name.copy(i)), prefix);
     119             : }
     120             : 
     121       62922 : struct PolymorphicUnoType {
     122       13760 :     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       25448 : 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       25448 :     if (rank > 0xFF - (array ? 1 : 0)) {
     150             :         throw CannotDumpException(
     151           0 :             "Too many array dimensions for Java class file format");
     152             :     }
     153       25448 :     if (array) {
     154         158 :         ++rank;
     155             :     }
     156       27298 :     for (sal_Int32 i = 0; i != rank; ++i) {
     157        1850 :         if (descriptor != 0) {
     158        1826 :             descriptor->append('[');
     159             :         }
     160        1850 :         if (signature != 0) {
     161        1698 :             signature->append('[');
     162             :         }
     163             :     }
     164       25448 :     if (polymorphicUnoType != 0) {
     165       13752 :         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       13722 :             polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE;
     175             :         }
     176             :     }
     177       25448 :     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       18665 :                 = simpleTypeDescriptors[sort][rank == 0 && classType];
     213       18665 :             if (descriptor != 0) {
     214       18558 :                 descriptor->append(s);
     215             :             }
     216       18665 :             if (signature != 0) {
     217       18583 :                 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       18665 :             return simpleTypeSpecials[sort];
     227             :         }
     228             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
     229        4182 :         if (nucleus == "com.sun.star.uno.XInterface") {
     230         743 :             if (descriptor != 0) {
     231         741 :                 descriptor->append("Ljava/lang/Object;");
     232             :             }
     233         743 :             if (signature != 0) {
     234         742 :                 signature->append("Ljava/lang/Object;");
     235             :             }
     236         743 :             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        6040 :         if (dependencies != 0) {
     244        5642 :             dependencies->insert(nucleus);
     245             :         }
     246        6040 :         if (descriptor != 0) {
     247             :             descriptor->append(
     248       12012 :                 "L" + codemaker::convertString(nucleus).replace('.', '/')
     249        6006 :                 + ";");
     250             :         }
     251        6040 :         if (signature != 0) {
     252             :             signature->append(
     253        5797 :                 "L" + codemaker::convertString(nucleus).replace('.', '/'));
     254        5797 :             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        5797 :             signature->append(';');
     268             :         }
     269        6040 :         return SPECIAL_TYPE_NONE;
     270             :     default:
     271             :         throw CannotDumpException(
     272           0 :             "unexpected nucleus \"" + nucleus
     273           0 :             + "\" in call to translateUnoTypeToDescriptor");
     274             :     }
     275             : }
     276             : 
     277       25122 : 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       25122 :     OUString nucleus;
     285             :     sal_Int32 rank;
     286       50244 :     std::vector< OUString > args;
     287             :     codemaker::UnoType::Sort sort = manager->decompose(
     288       25122 :         type, true, &nucleus, &rank, &args, 0);
     289             :     return translateUnoTypeToDescriptor(
     290             :         manager, sort, nucleus, rank, args, array, classType, dependencies,
     291       50244 :         descriptor, signature, needsSignature, polymorphicUnoType);
     292             : }
     293             : 
     294        6794 : 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        6794 :     OStringBuffer desc;
     301       13588 :     OStringBuffer sig;
     302        6794 :     bool needsSig = false;
     303             :     SpecialType specialType = translateUnoTypeToDescriptor(
     304             :         manager, type, false, false, dependencies, &desc, &sig, &needsSig,
     305        6794 :         polymorphicUnoType);
     306        6794 :     *descriptor = desc.makeStringAndClear();
     307        6794 :     if (signature != 0) {
     308        5037 :         if (needsSig) {
     309           2 :             *signature = sig.makeStringAndClear();
     310             :         } else {
     311        5035 :             signature->clear();
     312             :         }
     313             :     }
     314       13588 :     return specialType;
     315             : }
     316             : 
     317        8100 : 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        8100 :     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        8100 : MethodDescriptor::MethodDescriptor(
     346             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
     347             :     OUString const & returnType, SpecialType * specialReturnType,
     348             :     PolymorphicUnoType * polymorphicUnoType):
     349        8100 :     m_manager(manager), m_dependencies(dependencies), m_needsSignature(false)
     350             : {
     351             :     assert(dependencies != 0);
     352        8100 :     m_descriptorStart.append('(');
     353        8100 :     m_signatureStart.append('(');
     354        8100 :     OStringBuffer descEnd;
     355        8100 :     descEnd.append(')');
     356       16200 :     OStringBuffer sigEnd;
     357        8100 :     sigEnd.append(')');
     358             :     SpecialType special = translateUnoTypeToDescriptor(
     359             :         m_manager, returnType, false, false, m_dependencies, &descEnd, &sigEnd,
     360        8100 :         &m_needsSignature, polymorphicUnoType);
     361        8100 :     m_descriptorEnd = descEnd.makeStringAndClear();
     362        8100 :     m_signatureEnd = sigEnd.makeStringAndClear();
     363        8100 :     if (specialReturnType != 0) {
     364        6316 :         *specialReturnType = special;
     365        8100 :     }
     366        8100 : }
     367             : 
     368       10085 : 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       10085 :         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        8997 : OString MethodDescriptor::getDescriptor() const {
     385        8997 :     OStringBuffer buf(m_descriptorStart);
     386        8997 :     buf.append(m_descriptorEnd);
     387        8997 :     return buf.makeStringAndClear();
     388             : }
     389             : 
     390             : 
     391       40997 : 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        8165 : 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        8165 :     sal_Int32 flags = specialTypeFlags[specialType];
     439        8165 :     if (inParameter) {
     440         136 :         flags |= 0x0001; /* IN */
     441             :     }
     442        8165 :     if (outParameter) {
     443         157 :         flags |= 0x0002; /* OUT */
     444             :     }
     445        8165 :     return flags;
     446             : }
     447             : 
     448        1613 : 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        1613 :     m_flags(translateSpecialTypeFlags(specialType, false, false)),
     454             :     m_index(index), m_polymorphicUnoType(polymorphicUnoType),
     455        3226 :     m_typeParameterIndex(typeParameterIndex)
     456             : {
     457             :     assert(
     458             :         polymorphicUnoType.kind == PolymorphicUnoType::KIND_NONE
     459             :         ? typeParameterIndex >= -1 : typeParameterIndex == -1);
     460        1613 : }
     461             : 
     462        6316 : 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        6316 :     m_flags(flags | translateSpecialTypeFlags(specialType, false, false)),
     467             :     m_index(index), m_polymorphicUnoType(polymorphicUnoType),
     468       12632 :     m_typeParameterIndex(0)
     469             : {
     470             :     assert(kind == KIND_ATTRIBUTE || kind == KIND_METHOD);
     471        6316 : }
     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        8165 : sal_uInt16 TypeInfo::generateCode(
     485             :     ClassFile::Code & code, Dependencies * dependencies) const
     486             : {
     487        8165 :     switch (m_kind) {
     488             :     case KIND_MEMBER:
     489        1613 :         code.instrNew("com/sun/star/lib/uno/typeinfo/MemberTypeInfo");
     490        1613 :         code.instrDup();
     491        1613 :         code.loadStringConstant(m_name);
     492        1613 :         code.loadIntegerConstant(m_index);
     493        1613 :         code.loadIntegerConstant(m_flags);
     494        1613 :         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        1611 :         } 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        1603 :                 "(Ljava/lang/String;II)V");
     512        1603 :             return 4;
     513             :         }
     514             :     case KIND_ATTRIBUTE:
     515         624 :         code.instrNew("com/sun/star/lib/uno/typeinfo/AttributeTypeInfo");
     516         624 :         code.instrDup();
     517         624 :         code.loadStringConstant(m_name);
     518         624 :         code.loadIntegerConstant(m_index);
     519         624 :         code.loadIntegerConstant(m_flags);
     520         624 :         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         620 :                 "(Ljava/lang/String;II)V");
     530         620 :             return 4;
     531             :         }
     532             :     case KIND_METHOD:
     533        5692 :         code.instrNew("com/sun/star/lib/uno/typeinfo/MethodTypeInfo");
     534        5692 :         code.instrDup();
     535        5692 :         code.loadStringConstant(m_name);
     536        5692 :         code.loadIntegerConstant(m_index);
     537        5692 :         code.loadIntegerConstant(m_flags);
     538        5692 :         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        5673 :                 "(Ljava/lang/String;II)V");
     548        5673 :             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        3294 : void writeClassFile(
     601             :     JavaOptions const & options, OString const & type,
     602             :     ClassFile const & classFile)
     603             : {
     604        3294 :     OString path;
     605        3294 :     if (options.isValid("-O")) {
     606        3294 :         path = options.getOption("-O");
     607             :     }
     608        6588 :     OString filename(createFileNameFromType(path, type, ".class"));
     609        3294 :     bool check = false;
     610        3294 :     if (fileExists(filename)) {
     611           0 :         if (options.isValid("-G")) {
     612        3294 :             return;
     613             :         }
     614           0 :         check = options.isValid("-Gc");
     615             :     }
     616        6588 :     FileStream tempfile;
     617        3294 :     tempfile.createTempFile(getTempDir(filename));
     618        3294 :     if (!tempfile.isValid()) {
     619             :         throw CannotDumpException(
     620           0 :             "Cannot create temporary file for " + b2u(filename));
     621             :     }
     622        6588 :     OString tempname(tempfile.getName());
     623             :     try {
     624        3294 :         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        3294 :     tempfile.close();
     635        3294 :     if (!makeValidTypeFile(filename, tempname, check)) {
     636             :         throw CannotDumpException(
     637           0 :             "Cannot create " + b2u(filename) + " from temporary file "
     638           0 :             + b2u(tempname));
     639        3294 :     }
     640             : }
     641             : 
     642        2372 : void addTypeInfo(
     643             :     OString const & className, std::vector< TypeInfo > const & typeInfo,
     644             :     Dependencies * dependencies, ClassFile * classFile)
     645             : {
     646             :     assert(classFile != 0);
     647        2372 :     std::vector< TypeInfo >::size_type typeInfos = typeInfo.size();
     648        2372 :     if (typeInfos > SAL_MAX_INT32) {
     649             :         throw CannotDumpException(
     650           0 :             "UNOTYPEINFO array too big for Java class file format");
     651             :     }
     652        2372 :     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        2132 :             0, "");
     659        2132 :         std::unique_ptr< ClassFile::Code > code(classFile->newCode());
     660        2132 :         code->loadIntegerConstant(static_cast< sal_Int32 >(typeInfos));
     661        2132 :         code->instrAnewarray("com/sun/star/lib/uno/typeinfo/TypeInfo");
     662        2132 :         sal_Int32 index = 0;
     663        2132 :         sal_uInt16 stack = 0;
     664       30891 :         for (std::vector< TypeInfo >::const_iterator i(typeInfo.begin());
     665       20594 :              i != typeInfo.end(); ++i)
     666             :         {
     667        8165 :             code->instrDup();
     668        8165 :             code->loadIntegerConstant(index++);
     669        8165 :             stack = std::max(stack, i->generateCode(*code, dependencies));
     670        8165 :             code->instrAastore();
     671             :         }
     672             :         code->instrPutstatic(
     673             :             className, "UNOTYPEINFO",
     674        2132 :             "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;");
     675        2132 :         code->instrReturn();
     676        2132 :         if (stack > SAL_MAX_UINT16 - 4) {
     677             :             throw CannotDumpException(
     678           0 :                 "Stack too big for Java class file format");
     679             :         }
     680        2132 :         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        2132 :             "<clinit>", "()V", code.get(), std::vector< OString >(), "");
     685             :     }
     686        2372 : }
     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        1613 : 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        1613 :     OString descriptor;
     847        3226 :     OString signature;
     848             :     SpecialType specialType;
     849        3226 :     PolymorphicUnoType polymorphicUnoType;
     850        1613 :     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        1605 :             &polymorphicUnoType);
     859             :     }
     860             :     classFile->addField(
     861             :         ClassFile::ACC_PUBLIC, codemaker::convertString(name), descriptor, 0,
     862        1613 :         signature);
     863             :     typeInfo->push_back(
     864             :         TypeInfo(
     865             :             codemaker::convertString(name), specialType, index,
     866        3226 :             polymorphicUnoType, typeParameterIndex));
     867        1613 : }
     868             : 
     869        2069 : 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        2069 :     if (typeParameter) {
     877           8 :         return 0;
     878             :     }
     879        2061 :     OString name(codemaker::convertString(fieldName));
     880        4122 :     OUString nucleus;
     881             :     sal_Int32 rank;
     882        4122 :     std::vector< rtl::OUString > args;
     883        4122 :     rtl::Reference< unoidl::Entity > ent;
     884             :     codemaker::UnoType::Sort sort = manager->decompose(
     885        2061 :         fieldType, true, &nucleus, &rank, &args, &ent);
     886        2061 :     if (rank == 0) {
     887        1927 :         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         555 :             code->loadLocalReference(0);
     903         555 :             code->loadStringConstant(OString());
     904         555 :             code->instrPutfield(className, name, "Ljava/lang/String;");
     905         555 :             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        2195 :     return 2;
     988             : }
     989             : 
     990        2888 : 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        2888 :     sal_uInt16 stack = 1;
    1001        2888 :     sal_uInt16 size = 1;
    1002        2888 :     if (typeParameter) {
    1003           8 :         code->loadLocalReference(*index);
    1004           8 :         stack = size = 1;
    1005             :     } else {
    1006        2880 :         OUString nucleus;
    1007             :         sal_Int32 rank;
    1008        5760 :         std::vector< OUString > args;
    1009             :         codemaker::UnoType::Sort sort = manager->decompose(
    1010        2880 :             type, true, &nucleus, &rank, &args, 0);
    1011        2880 :         if (rank == 0) {
    1012        2721 :             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         686 :                 code->loadLocalReference(*index);
    1195         686 :                 stack = size = 1;
    1196         686 :                 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         153 :                 code->loadLocalReference(*index);
    1201         153 :                 stack = size = 1;
    1202         153 :                 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         764 :                 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         687 :                     code->loadLocalReference(*index);
    1252         687 :                     stack = 1;
    1253             :                 }
    1254         764 :                 size = 1;
    1255         764 :                 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        2880 :         }
    1327             :     }
    1328        2888 :     if (*index > SAL_MAX_UINT16 - size) {
    1329             :         throw CannotDumpException(
    1330           0 :             "Too many local variables for Java class file format");
    1331             :     }
    1332        2888 :     *index = *index + size;
    1333        2888 :     return stack;
    1334             : }
    1335             : 
    1336        1765 : 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        1765 :     OString desc;
    1345        1765 :     if (typeParameter) {
    1346           8 :         methodDescriptor->addTypeParameter(fieldType);
    1347           8 :         desc = "Ljava/lang/Object;";
    1348             :     } else {
    1349        1757 :         methodDescriptor->addParameter(fieldType, false, true, 0);
    1350        1757 :         getFieldDescriptor(manager, dependencies, fieldType, &desc, 0, 0);
    1351             :     }
    1352        1765 :     code->loadLocalReference(0);
    1353             :     sal_uInt16 stack = addLoadLocal(
    1354        1765 :         manager, code, index, typeParameter, fieldType, false, dependencies);
    1355        1765 :     code->instrPutfield(className, fieldName, desc);
    1356        1765 :     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             :     unoidl::PlainStructTypeEntity& ent2(
    1375         115 :         dynamic_cast<unoidl::PlainStructTypeEntity&>(*ent.get()));
    1376         115 :     if (!ent2.getDirectBase().isEmpty()) {
    1377             :         addPlainStructBaseArguments(
    1378             :             manager, dependencies, methodDescriptor, code,
    1379          15 :             ent2.getDirectBase(), index);
    1380             :     }
    1381         936 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1382         115 :              ent2.getDirectMembers().begin());
    1383         624 :          i != ent2.getDirectMembers().end(); ++i)
    1384             :     {
    1385         197 :         methodDescriptor->addParameter(i->type, false, true, 0);
    1386         197 :         addLoadLocal(manager, code, index, false, i->type, false, dependencies);
    1387         115 :     }
    1388         115 : }
    1389             : 
    1390         405 : void handlePlainStructType(
    1391             :     const OUString& name,
    1392             :     rtl::Reference< unoidl::PlainStructTypeEntity > const & entity,
    1393             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1394             :     Dependencies * dependencies)
    1395             : {
    1396             :     assert(entity.is());
    1397             :     assert(dependencies != 0);
    1398         405 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1399         810 :     OString superClass;
    1400         405 :     if (entity->getDirectBase().isEmpty()) {
    1401         305 :         superClass = "java/lang/Object";
    1402             :     } else {
    1403         200 :         superClass = codemaker::convertString(entity->getDirectBase()).
    1404         100 :             replace('.', '/');
    1405         100 :         dependencies->insert(entity->getDirectBase());
    1406             :     }
    1407             :     std::unique_ptr< ClassFile > cf(
    1408             :         new ClassFile(
    1409             :             static_cast< ClassFile::AccessFlags >(
    1410             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1411         810 :             className, superClass, ""));
    1412         810 :     std::vector< TypeInfo > typeInfo;
    1413         405 :     sal_Int32 index = 0;
    1414        5565 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1415         405 :              entity->getDirectMembers().begin());
    1416        3710 :          i != entity->getDirectMembers().end(); ++i)
    1417             :     {
    1418             :         addField(
    1419        2900 :             manager, dependencies, cf.get(), &typeInfo, -1, i->type, i->name,
    1420        4350 :             index++);
    1421             :     }
    1422         810 :     std::unique_ptr< ClassFile::Code > code(cf->newCode());
    1423         405 :     code->loadLocalReference(0);
    1424         405 :     code->instrInvokespecial(superClass, "<init>", "()V");
    1425         405 :     sal_uInt16 stack = 0;
    1426        5565 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1427         405 :              entity->getDirectMembers().begin());
    1428        3710 :          i != entity->getDirectMembers().end(); ++i)
    1429             :     {
    1430             :         stack = std::max(
    1431             :             stack,
    1432             :             addFieldInit(
    1433        2900 :                 manager, className, i->name, false, i->type, dependencies,
    1434        4350 :                 code.get()));
    1435             :     }
    1436         405 :     code->instrReturn();
    1437         405 :     code->setMaxStackAndLocals(stack + 1, 1);
    1438             :     cf->addMethod(
    1439         405 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1440         810 :         std::vector< OString >(), "");
    1441         810 :     MethodDescriptor desc(manager, dependencies, "void", 0, 0);
    1442         405 :     code.reset(cf->newCode());
    1443         405 :     code->loadLocalReference(0);
    1444         405 :     sal_uInt16 index2 = 1;
    1445         405 :     if (!entity->getDirectBase().isEmpty()) {
    1446             :         addPlainStructBaseArguments(
    1447             :             manager, dependencies, &desc, code.get(), entity->getDirectBase(),
    1448         100 :             &index2);
    1449             :     }
    1450         405 :     code->instrInvokespecial(superClass, "<init>", desc.getDescriptor());
    1451         405 :     sal_uInt16 maxSize = index2;
    1452        5565 :     for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
    1453         405 :              entity->getDirectMembers().begin());
    1454        3710 :          i != entity->getDirectMembers().end(); ++i)
    1455             :     {
    1456             :         maxSize = std::max(
    1457             :             maxSize,
    1458             :             addDirectArgument(
    1459             :                 manager, dependencies, &desc, code.get(), &index2, className,
    1460        1450 :                 codemaker::convertString(i->name), false, i->type));
    1461             :     }
    1462         405 :     code->instrReturn();
    1463         405 :     code->setMaxStackAndLocals(maxSize, index2);
    1464             :     cf->addMethod(
    1465         405 :         ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
    1466         810 :         std::vector< OString >(), desc.getSignature());
    1467         405 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1468         810 :     writeClassFile(options, className, *cf.get());
    1469         405 : }
    1470             : 
    1471           6 : void handlePolyStructType(
    1472             :     const OUString& name,
    1473             :     rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const &
    1474             :         entity,
    1475             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1476             :     Dependencies * dependencies)
    1477             : {
    1478             :     assert(entity.is());
    1479           6 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1480          12 :     std::map< OUString, sal_Int32 > typeParameters;
    1481          12 :     OStringBuffer sig("<");
    1482           6 :     sal_Int32 index = 0;
    1483          42 :     for (std::vector< OUString >::const_iterator i(
    1484           6 :              entity->getTypeParameters().begin());
    1485          28 :          i != entity->getTypeParameters().end(); ++i)
    1486             :     {
    1487           8 :         sig.append(codemaker::convertString(*i) + ":Ljava/lang/Object;");
    1488          16 :         if (!typeParameters.insert(
    1489          16 :                 std::map< OUString, sal_Int32 >::value_type(*i, index++)).
    1490           8 :             second)
    1491             :         {
    1492           0 :             throw CannotDumpException("Bad type information"); //TODO
    1493             :         }
    1494             :     }
    1495           6 :     sig.append(">Ljava/lang/Object;");
    1496             :     std::unique_ptr< ClassFile > cf(
    1497             :         new ClassFile(
    1498             :             static_cast< ClassFile::AccessFlags >(
    1499             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1500          12 :             className, "java/lang/Object", sig.makeStringAndClear()));
    1501          12 :     std::vector< TypeInfo > typeInfo;
    1502           6 :     index = 0;
    1503          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1504           6 :              const_iterator i(entity->getMembers().begin());
    1505          34 :          i != entity->getMembers().end(); ++i)
    1506             :     {
    1507             :         sal_Int32 typeParameterIndex;
    1508          11 :         if (i->parameterized) {
    1509             :             std::map< OUString, sal_Int32 >::iterator it(
    1510           8 :                 typeParameters.find(i->type));
    1511           8 :             if (it == typeParameters.end()) {
    1512           0 :                 throw CannotDumpException("Bad type information"); //TODO
    1513             :             }
    1514           8 :             typeParameterIndex = it->second;
    1515             :         } else {
    1516           3 :             typeParameterIndex = -1;
    1517             :         }
    1518             :         addField(
    1519             :             manager, dependencies, cf.get(), &typeInfo, typeParameterIndex,
    1520          11 :             i->type, i->name, index++);
    1521             :     }
    1522          12 :     std::unique_ptr< ClassFile::Code > code(cf->newCode());
    1523           6 :     code->loadLocalReference(0);
    1524           6 :     code->instrInvokespecial("java/lang/Object", "<init>", "()V");
    1525           6 :     sal_uInt16 stack = 0;
    1526          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1527           6 :              const_iterator i(entity->getMembers().begin());
    1528          34 :          i != entity->getMembers().end(); ++i)
    1529             :     {
    1530             :         stack = std::max(
    1531             :             stack,
    1532             :             addFieldInit(
    1533          33 :                 manager, className, i->name, i->parameterized, i->type,
    1534          44 :                 dependencies, code.get()));
    1535             :     }
    1536           6 :     code->instrReturn();
    1537           6 :     code->setMaxStackAndLocals(stack + 1, 1);
    1538             :     cf->addMethod(
    1539           6 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1540          12 :         std::vector< OString >(), "");
    1541          12 :     MethodDescriptor desc(manager, dependencies, "void", 0, 0);
    1542           6 :     code.reset(cf->newCode());
    1543           6 :     code->loadLocalReference(0);
    1544           6 :     sal_uInt16 index2 = 1;
    1545             :     code->instrInvokespecial(
    1546           6 :         "java/lang/Object", "<init>", desc.getDescriptor());
    1547           6 :     sal_uInt16 maxSize = index2;
    1548          51 :     for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
    1549           6 :              const_iterator i(entity->getMembers().begin());
    1550          34 :          i != entity->getMembers().end(); ++i)
    1551             :     {
    1552             :         maxSize = std::max(
    1553             :             maxSize,
    1554             :             addDirectArgument(
    1555             :                 manager, dependencies, &desc, code.get(), &index2, className,
    1556          11 :                 codemaker::convertString(i->name), i->parameterized, i->type));
    1557             :     }
    1558           6 :     code->instrReturn();
    1559           6 :     code->setMaxStackAndLocals(maxSize, index2);
    1560             :     cf->addMethod(
    1561           6 :         ClassFile::ACC_PUBLIC, "<init>", desc.getDescriptor(), code.get(),
    1562          12 :         std::vector< OString >(), desc.getSignature());
    1563           6 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1564          12 :     writeClassFile(options, className, *cf.get());
    1565           6 : }
    1566             : 
    1567         832 : void addExceptionBaseArguments(
    1568             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies,
    1569             :     MethodDescriptor * methodDescriptor, ClassFile::Code * code,
    1570             :     OUString const & base, sal_uInt16 * index)
    1571             : {
    1572             :     assert(manager.is());
    1573             :     assert(methodDescriptor != 0);
    1574         832 :     rtl::Reference< unoidl::Entity > ent;
    1575         832 :     if (manager->getSort(base, &ent) != codemaker::UnoType::SORT_EXCEPTION_TYPE)
    1576             :     {
    1577             :         throw CannotDumpException(
    1578           0 :             "unexpected entity \"" + base
    1579           0 :             + "\" in call to addExceptionBaseArguments");
    1580             :     }
    1581             :     unoidl::ExceptionTypeEntity& ent2(
    1582         832 :         dynamic_cast<unoidl::ExceptionTypeEntity&>(*ent.get()));
    1583         832 :     bool baseException = base == "com.sun.star.uno.Exception";
    1584         832 :     if (!baseException) {
    1585             :         addExceptionBaseArguments(
    1586             :             manager, dependencies, methodDescriptor, code,
    1587         348 :             ent2.getDirectBase(), index);
    1588             :     }
    1589        5922 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1590         832 :              ent2.getDirectMembers().begin());
    1591        3948 :          i != ent2.getDirectMembers().end(); ++i)
    1592             :     {
    1593        1142 :         if (!baseException || i != ent2.getDirectMembers().begin()) {
    1594         658 :             methodDescriptor->addParameter(i->type, false, true, 0);
    1595             :             addLoadLocal(
    1596         658 :                 manager, code, index, false, i->type, false, dependencies);
    1597             :         }
    1598         832 :     }
    1599         832 : }
    1600             : 
    1601         244 : void handleExceptionType(
    1602             :     const OUString& name, rtl::Reference< unoidl::ExceptionTypeEntity > const & entity,
    1603             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1604             :     Dependencies * dependencies)
    1605             : {
    1606             :     assert(entity.is());
    1607             :     assert(dependencies != 0);
    1608         244 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1609         244 :     bool baseException = false;
    1610         244 :     bool baseRuntimeException = false;
    1611         488 :     OString superClass;
    1612         244 :     if (className == "com/sun/star/uno/Exception") {
    1613           1 :         baseException = true;
    1614           1 :         superClass = "java/lang/Exception";
    1615         243 :     } else if (className == "com/sun/star/uno/RuntimeException") {
    1616           1 :         baseRuntimeException = true;
    1617           1 :         superClass = "java/lang/RuntimeException";
    1618             :     } else {
    1619         242 :         if (entity->getDirectBase().isEmpty()) {
    1620             :             throw CannotDumpException(
    1621           0 :                 "Exception type \"" + name + "\" lacks base");
    1622             :         }
    1623         484 :         superClass = codemaker::convertString(entity->getDirectBase()).
    1624         242 :             replace('.', '/');
    1625         242 :         dependencies->insert(entity->getDirectBase());
    1626             :     }
    1627             :     std::unique_ptr< ClassFile > cf(
    1628             :         new ClassFile(
    1629             :             static_cast< ClassFile::AccessFlags >(
    1630             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
    1631         488 :             className, superClass, ""));
    1632         488 :     std::vector< TypeInfo > typeInfo;
    1633         244 :     sal_Int32 index = 0;
    1634         244 :     if (baseRuntimeException) {
    1635             :         addField(
    1636             :             manager, dependencies, cf.get(), &typeInfo, -1,
    1637           1 :             "com.sun.star.uno.XInterface", "Context", index++);
    1638             :     }
    1639        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1640         244 :              entity->getDirectMembers().begin());
    1641         792 :          i != entity->getDirectMembers().end(); ++i)
    1642             :     {
    1643         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1644             :             addField(
    1645         151 :                 manager, dependencies, cf.get(), &typeInfo, -1, i->type,
    1646         302 :                 i->name, index++);
    1647             :         }
    1648             :     }
    1649             : 
    1650             :     // create default constructor
    1651         488 :     std::unique_ptr< ClassFile::Code > code(cf->newCode());
    1652         244 :     code->loadLocalReference(0);
    1653         244 :     code->instrInvokespecial(superClass, "<init>", "()V");
    1654         244 :     sal_uInt16 stack = 0;
    1655         244 :     if (baseRuntimeException) {
    1656             :         stack = std::max(
    1657             :             stack,
    1658             :             addFieldInit(
    1659             :                 manager, className, "Context", false,
    1660           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1661             :     }
    1662        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1663         244 :              entity->getDirectMembers().begin());
    1664         792 :          i != entity->getDirectMembers().end(); ++i)
    1665             :     {
    1666         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1667             :             stack = std::max(
    1668             :                 stack,
    1669             :                 addFieldInit(
    1670         302 :                     manager, className, i->name, false, i->type, dependencies,
    1671         453 :                     code.get()));
    1672             :         }
    1673             :     }
    1674         244 :     code->instrReturn();
    1675         244 :     code->setMaxStackAndLocals(stack + 1, 1);
    1676             :     cf->addMethod(
    1677         244 :         ClassFile::ACC_PUBLIC, "<init>", "()V", code.get(),
    1678         488 :         std::vector< OString >(), "");
    1679             : 
    1680             : 
    1681             :     // create (Throwable Cause) constructor
    1682         244 :     code.reset(cf->newCode());
    1683         244 :     code->loadLocalReference(0);
    1684         244 :     code->loadLocalReference(1);
    1685         244 :     code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;)V");
    1686         244 :     stack = 0;
    1687         244 :     if (baseRuntimeException) {
    1688             :         stack = std::max(
    1689             :             stack,
    1690             :             addFieldInit(
    1691             :                 manager, className, "Context", false,
    1692           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1693             :     }
    1694        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1695         244 :              entity->getDirectMembers().begin());
    1696         792 :          i != entity->getDirectMembers().end(); ++i)
    1697             :     {
    1698         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1699             :             stack = std::max(
    1700             :                 stack,
    1701             :                 addFieldInit(
    1702         302 :                     manager, className, i->name, false, i->type, dependencies,
    1703         453 :                     code.get()));
    1704             :         }
    1705             :     }
    1706         244 :     code->instrReturn();
    1707         244 :     code->setMaxStackAndLocals(stack + 2, 2);
    1708             :     cf->addMethod(
    1709         244 :         ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;)V", code.get(),
    1710         488 :         std::vector< OString >(), "");
    1711             : 
    1712             :     // create (Throwable Cause, String Message) constructor
    1713         244 :     code.reset(cf->newCode());
    1714         244 :     code->loadLocalReference(0);
    1715         244 :     if (baseException || baseRuntimeException) {
    1716           2 :         code->loadLocalReference(2);
    1717           2 :         code->loadLocalReference(1);
    1718           2 :         code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
    1719             :     } else {
    1720         242 :         code->loadLocalReference(1);
    1721         242 :         code->loadLocalReference(2);
    1722         242 :         code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;Ljava/lang/String;)V");
    1723             :     }
    1724         244 :     stack = 0;
    1725         244 :     if (baseRuntimeException) {
    1726             :         stack = std::max(
    1727             :             stack,
    1728             :             addFieldInit(
    1729             :                 manager, className, "Context", false,
    1730           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1731             :     }
    1732        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1733         244 :              entity->getDirectMembers().begin());
    1734         792 :          i != entity->getDirectMembers().end(); ++i)
    1735             :     {
    1736         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1737             :             stack = std::max(
    1738             :                 stack,
    1739             :                 addFieldInit(
    1740         302 :                     manager, className, i->name, false, i->type, dependencies,
    1741         453 :                     code.get()));
    1742             :         }
    1743             :     }
    1744         244 :     code->instrReturn();
    1745         244 :     code->setMaxStackAndLocals(stack + 3, 3);
    1746             :     cf->addMethod(
    1747         244 :         ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;Ljava/lang/String;)V", code.get(),
    1748         488 :         std::vector< OString >(), "");
    1749             : 
    1750             :     // create (String Message) constructor
    1751         244 :     code.reset(cf->newCode());
    1752         244 :     code->loadLocalReference(0);
    1753         244 :     code->loadLocalReference(1);
    1754         244 :     code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/String;)V");
    1755         244 :     stack = 0;
    1756         244 :     if (baseRuntimeException) {
    1757             :         stack = std::max(
    1758             :             stack,
    1759             :             addFieldInit(
    1760             :                 manager, className, "Context", false,
    1761           1 :                 "com.sun.star.uno.XInterface", dependencies, code.get()));
    1762             :     }
    1763        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1764         244 :              entity->getDirectMembers().begin());
    1765         792 :          i != entity->getDirectMembers().end(); ++i)
    1766             :     {
    1767         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1768             :             stack = std::max(
    1769             :                 stack,
    1770             :                 addFieldInit(
    1771         302 :                     manager, className, i->name, false, i->type, dependencies,
    1772         453 :                     code.get()));
    1773             :         }
    1774             :     }
    1775         244 :     code->instrReturn();
    1776         244 :     code->setMaxStackAndLocals(stack + 2, 2);
    1777             :     cf->addMethod(
    1778         244 :         ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", code.get(),
    1779         488 :         std::vector< OString >(), "");
    1780             : 
    1781             : 
    1782             :     // create (String Message, Object Context, T1 m1, ..., Tn mn) constructor
    1783         488 :     MethodDescriptor desc1(manager, dependencies, "void", 0, 0);
    1784         244 :     code.reset(cf->newCode());
    1785         244 :     code->loadLocalReference(0);
    1786         244 :     sal_uInt16 index2 = 1;
    1787         244 :     code->loadLocalReference(index2++);
    1788         244 :     desc1.addParameter("string", false, true, 0);
    1789         244 :     if (!(baseException || baseRuntimeException)) {
    1790             :         addExceptionBaseArguments(
    1791             :             manager, dependencies, &desc1, code.get(), entity->getDirectBase(),
    1792         242 :             &index2);
    1793             :     }
    1794         244 :     code->instrInvokespecial(superClass, "<init>", desc1.getDescriptor());
    1795         244 :     sal_uInt16 maxSize = index2;
    1796         244 :     if (baseRuntimeException) {
    1797             :         maxSize = std::max(
    1798             :             maxSize,
    1799             :             addDirectArgument(
    1800             :                 manager, dependencies, &desc1, code.get(), &index2, className,
    1801           1 :                 "Context", false, "com.sun.star.uno.XInterface"));
    1802             :     }
    1803        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1804         244 :              entity->getDirectMembers().begin());
    1805         792 :          i != entity->getDirectMembers().end(); ++i)
    1806             :     {
    1807         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1808             :             maxSize = std::max(
    1809             :                 maxSize,
    1810             :                 addDirectArgument(
    1811             :                     manager, dependencies, &desc1, code.get(), &index2,
    1812         151 :                     className, codemaker::convertString(i->name), false,
    1813         302 :                     i->type));
    1814             :         }
    1815             :     }
    1816         244 :     code->instrReturn();
    1817         244 :     code->setMaxStackAndLocals(maxSize, index2);
    1818             :     cf->addMethod(
    1819         244 :         ClassFile::ACC_PUBLIC, "<init>", desc1.getDescriptor(), code.get(),
    1820         488 :         std::vector< OString >(), desc1.getSignature());
    1821             : 
    1822             :     // create (Throwable Cause, String Message, Object Context, T1 m1, ..., Tn mn) constructor
    1823         488 :     MethodDescriptor desc2(manager, dependencies, "void", 0, 0);
    1824         244 :     code.reset(cf->newCode());
    1825         244 :     code->loadLocalReference(0);
    1826         244 :     sal_uInt16 index3 = 3;
    1827             :     // Note that we hack in the java.lang.Throwable parameter further down,
    1828             :     // because MethodDescriptor does not know how to handle it.
    1829         244 :     desc2.addParameter("string", false, true, 0);
    1830         244 :     if (baseException || baseRuntimeException) {
    1831           2 :         code->loadLocalReference(2);
    1832           2 :         code->loadLocalReference(1);
    1833           2 :         code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V");
    1834             :     } else {
    1835         242 :         code->loadLocalReference(1);
    1836         242 :         code->loadLocalReference(2);
    1837             :         addExceptionBaseArguments(
    1838             :             manager, dependencies, &desc2, code.get(), entity->getDirectBase(),
    1839         242 :             &index3);
    1840         242 :         code->instrInvokespecial(superClass, "<init>", "(Ljava/lang/Throwable;" + desc2.getDescriptor().copy(1));
    1841             :     }
    1842         244 :     sal_uInt16 maxSize2 = index3;
    1843         244 :     if (baseRuntimeException) {
    1844             :         maxSize2 = std::max(
    1845             :             maxSize2,
    1846             :             addDirectArgument(
    1847             :                 manager, dependencies, &desc2, code.get(), &index3, className,
    1848           1 :                 "Context", false, "com.sun.star.uno.XInterface"));
    1849             :     }
    1850        1188 :     for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
    1851         244 :              entity->getDirectMembers().begin());
    1852         792 :          i != entity->getDirectMembers().end(); ++i)
    1853             :     {
    1854         152 :         if (!baseException || i != entity->getDirectMembers().begin()) {
    1855             :             maxSize2 = std::max(
    1856             :                 maxSize2,
    1857             :                 addDirectArgument(
    1858             :                     manager, dependencies, &desc2, code.get(), &index3,
    1859         151 :                     className, codemaker::convertString(i->name), false,
    1860         302 :                     i->type));
    1861             :         }
    1862             :     }
    1863         244 :     code->instrReturn();
    1864         244 :     code->setMaxStackAndLocals(maxSize2, index3);
    1865             :     cf->addMethod(
    1866         488 :         ClassFile::ACC_PUBLIC, "<init>", "(Ljava/lang/Throwable;" + desc2.getDescriptor().copy(1), code.get(),
    1867         732 :         std::vector< OString >(), desc2.getSignature());
    1868             : 
    1869         244 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    1870         488 :     writeClassFile(options, className, *cf.get());
    1871         244 : }
    1872             : 
    1873        6936 : void createExceptionsAttribute(
    1874             :     rtl::Reference< TypeManager > const & manager,
    1875             :     std::vector< OUString > const & exceptionTypes,
    1876             :     Dependencies * dependencies, std::vector< OString > * exceptions,
    1877             :     codemaker::ExceptionTree * tree)
    1878             : {
    1879             :     assert(dependencies != 0);
    1880             :     assert(exceptions != 0);
    1881       29607 :     for (std::vector< OUString >::const_iterator i(exceptionTypes.begin());
    1882       19738 :          i != exceptionTypes.end(); ++i)
    1883             :     {
    1884        2933 :         dependencies->insert(*i);
    1885        2933 :         OString type(codemaker::convertString(*i).replace('.', '/'));
    1886        2933 :         exceptions->push_back(type);
    1887        2933 :         if (tree != 0) {
    1888          53 :             tree->add(type.replace('/', '.'), manager);
    1889             :         }
    1890        2933 :     }
    1891        6936 : }
    1892             : 
    1893        1717 : void handleInterfaceType(
    1894             :     const OUString& name, rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
    1895             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    1896             :     Dependencies * dependencies)
    1897             : {
    1898             :     assert(entity.is());
    1899             :     assert(dependencies != 0);
    1900        1717 :     OString className(codemaker::convertString(name).replace('.', '/'));
    1901             :     std::unique_ptr< ClassFile > cf(
    1902             :         new ClassFile(
    1903             :             static_cast< ClassFile::AccessFlags >(
    1904             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
    1905             :                 | ClassFile::ACC_ABSTRACT),
    1906        3434 :             className, "java/lang/Object", ""));
    1907       11001 :     for (std::vector< unoidl::AnnotatedReference >::const_iterator i(
    1908        1717 :              entity->getDirectMandatoryBases().begin());
    1909        7334 :          i != entity->getDirectMandatoryBases().end(); ++i)
    1910             :     {
    1911        1950 :         dependencies->insert(i->name);
    1912        1950 :         cf->addInterface(codemaker::convertString(i->name).replace('.', '/'));
    1913             :     }
    1914             :     // As a special case, let com.sun.star.lang.XEventListener extend
    1915             :     // java.util.EventListener ("A tagging interface that all event listener
    1916             :     // interfaces must extend"):
    1917        1717 :     if (className == "com/sun/star/lang/XEventListener") {
    1918           1 :         cf->addInterface("java/util/EventListener");
    1919             :     }
    1920        3434 :     std::vector< TypeInfo > typeInfo;
    1921        1717 :     if (className != "com/sun/star/uno/XInterface") {
    1922        1716 :         sal_Int32 index = 0;
    1923        7020 :         for (std::vector< unoidl::InterfaceTypeEntity::Attribute >::
    1924        1716 :                  const_iterator i(entity->getDirectAttributes().begin());
    1925        4680 :              i != entity->getDirectAttributes().end(); ++i)
    1926             :         {
    1927             :             SpecialType specialType;
    1928         624 :             PolymorphicUnoType polymorphicUnoType;
    1929             :             MethodDescriptor gdesc(
    1930         624 :                 manager, dependencies, i->type, &specialType,
    1931        1248 :                 &polymorphicUnoType);
    1932        1248 :             std::vector< OString > exc;
    1933             :             createExceptionsAttribute(
    1934         624 :                 manager, i->getExceptions, dependencies, &exc, 0);
    1935        1248 :             OString attrName(codemaker::convertString(i->name));
    1936             :             cf->addMethod(
    1937             :                 static_cast< ClassFile::AccessFlags >(
    1938             :                     ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    1939        1248 :                 "get" + attrName, gdesc.getDescriptor(), 0, exc,
    1940        1872 :                 gdesc.getSignature());
    1941         624 :             if (!i->readOnly) {
    1942         487 :                 MethodDescriptor sdesc(manager, dependencies, "void", 0, 0);
    1943         487 :                 sdesc.addParameter(i->type, false, true, 0);
    1944         974 :                 std::vector< OString > exc2;
    1945             :                 createExceptionsAttribute(
    1946         487 :                     manager, i->setExceptions, dependencies, &exc2, 0);
    1947             :                 cf->addMethod(
    1948             :                     static_cast< ClassFile::AccessFlags >(
    1949             :                         ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    1950         974 :                     "set" + attrName, sdesc.getDescriptor(), 0, exc2,
    1951        1948 :                     sdesc.getSignature());
    1952             :             }
    1953             :             typeInfo.push_back(
    1954             :                 TypeInfo(
    1955             :                     TypeInfo::KIND_ATTRIBUTE, attrName, specialType,
    1956             :                     static_cast< TypeInfo::Flags >(
    1957         624 :                         (i->readOnly ? TypeInfo::FLAG_READONLY : 0)
    1958         624 :                         | (i->bound ? TypeInfo::FLAG_BOUND : 0)),
    1959         624 :                     index, polymorphicUnoType));
    1960         624 :             index += (i->readOnly ? 1 : 2);
    1961         624 :         }
    1962       22224 :         for (std::vector< unoidl::InterfaceTypeEntity::Method >::const_iterator
    1963        1716 :                  i(entity->getDirectMethods().begin());
    1964       14816 :              i != entity->getDirectMethods().end(); ++i)
    1965             :         {
    1966        5692 :             OString methodName(codemaker::convertString(i->name));
    1967             :             SpecialType specialReturnType;
    1968       11384 :             PolymorphicUnoType polymorphicUnoReturnType;
    1969             :             MethodDescriptor desc(
    1970        5692 :                 manager, dependencies, i->returnType, &specialReturnType,
    1971       11384 :                 &polymorphicUnoReturnType);
    1972             :             typeInfo.push_back(
    1973             :                 TypeInfo(
    1974             :                     TypeInfo::KIND_METHOD, methodName, specialReturnType,
    1975             :                     static_cast< TypeInfo::Flags >(0), index++,
    1976        5692 :                     polymorphicUnoReturnType));
    1977        5692 :             sal_Int32 paramIndex = 0;
    1978       34569 :             for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
    1979        5692 :                      const_iterator j(i->parameters.begin());
    1980       23046 :                  j != i->parameters.end(); ++j)
    1981             :             {
    1982        5831 :                 bool in = j->direction
    1983        5831 :                     != (unoidl::InterfaceTypeEntity::Method::Parameter::
    1984        5831 :                         DIRECTION_OUT);
    1985        5831 :                 bool out = j->direction
    1986        5831 :                     != (unoidl::InterfaceTypeEntity::Method::Parameter::
    1987        5831 :                         DIRECTION_IN);
    1988        5831 :                 PolymorphicUnoType polymorphicUnoType;
    1989             :                 SpecialType specialType = desc.addParameter(
    1990        5831 :                     j->type, out, true, &polymorphicUnoType);
    1991       11505 :                 if (out || isSpecialType(specialType)
    1992       11429 :                     || polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE)
    1993             :                 {
    1994             :                     typeInfo.push_back(
    1995             :                         TypeInfo(
    1996         236 :                             codemaker::convertString(j->name), specialType, in,
    1997         472 :                             out, methodName, paramIndex, polymorphicUnoType));
    1998             :                 }
    1999        5831 :                 ++paramIndex;
    2000        5831 :             }
    2001       11384 :             std::vector< OString > exc2;
    2002             :             createExceptionsAttribute(
    2003        5692 :                 manager, i->exceptions, dependencies, &exc2, 0);
    2004             :             cf->addMethod(
    2005             :                 static_cast< ClassFile::AccessFlags >(
    2006             :                     ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
    2007        5692 :                 methodName, desc.getDescriptor(), 0, exc2, desc.getSignature());
    2008        5692 :         }
    2009             :     }
    2010        1717 :     addTypeInfo(className, typeInfo, dependencies, cf.get());
    2011        3434 :     writeClassFile(options, className, *cf.get());
    2012        1717 : }
    2013             : 
    2014          19 : void handleTypedef(
    2015             :     rtl::Reference< unoidl::TypedefEntity > const & entity,
    2016             :     rtl::Reference< TypeManager > const & manager, Dependencies * dependencies)
    2017             : {
    2018             :     assert(entity.is());
    2019             :     assert(manager.is());
    2020             :     assert(dependencies != 0);
    2021          19 :     OUString nucleus;
    2022          19 :     switch (manager->decompose(entity->getType(), false, &nucleus, 0, 0, 0))
    2023             :     {
    2024             :     case codemaker::UnoType::SORT_BOOLEAN:
    2025             :     case codemaker::UnoType::SORT_BYTE:
    2026             :     case codemaker::UnoType::SORT_SHORT:
    2027             :     case codemaker::UnoType::SORT_UNSIGNED_SHORT:
    2028             :     case codemaker::UnoType::SORT_LONG:
    2029             :     case codemaker::UnoType::SORT_UNSIGNED_LONG:
    2030             :     case codemaker::UnoType::SORT_HYPER:
    2031             :     case codemaker::UnoType::SORT_UNSIGNED_HYPER:
    2032             :     case codemaker::UnoType::SORT_FLOAT:
    2033             :     case codemaker::UnoType::SORT_DOUBLE:
    2034             :     case codemaker::UnoType::SORT_CHAR:
    2035             :     case codemaker::UnoType::SORT_STRING:
    2036             :     case codemaker::UnoType::SORT_TYPE:
    2037             :     case codemaker::UnoType::SORT_ANY:
    2038           7 :         break;
    2039             :     case codemaker::UnoType::SORT_ENUM_TYPE:
    2040             :     case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    2041             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
    2042             :     case codemaker::UnoType::SORT_TYPEDEF:
    2043          12 :         dependencies->insert(nucleus);
    2044          12 :         break;
    2045             :     default:
    2046             :         assert(false); // this cannot happen
    2047          19 :     }
    2048          19 : }
    2049             : 
    2050         356 : void handleConstantGroup(
    2051             :     const OUString& name, rtl::Reference< unoidl::ConstantGroupEntity > const & entity,
    2052             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    2053             :     Dependencies * dependencies)
    2054             : {
    2055             :     assert(entity.is());
    2056         356 :     OString className(codemaker::convertString(name).replace('.', '/'));
    2057             :     std::unique_ptr< ClassFile > cf(
    2058             :         new ClassFile(
    2059             :             static_cast< ClassFile::AccessFlags >(
    2060             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
    2061             :                 | ClassFile::ACC_ABSTRACT),
    2062         712 :             className, "java/lang/Object", ""));
    2063       11364 :     for (std::vector< unoidl::ConstantGroupEntity::Member >::const_iterator i(
    2064         356 :              entity->getMembers().begin());
    2065        7576 :          i != entity->getMembers().end(); ++i)
    2066             :     {
    2067        3432 :         OUString type;
    2068        3432 :         sal_uInt16 valueIndex = sal_uInt16(); // avoid false warnings
    2069        3432 :         switch (i->value.type) {
    2070             :         case unoidl::ConstantValue::TYPE_BOOLEAN:
    2071           0 :             type = "boolean";
    2072           0 :             valueIndex = cf->addIntegerInfo(sal_Int32(i->value.booleanValue));
    2073           0 :             break;
    2074             :         case unoidl::ConstantValue::TYPE_BYTE:
    2075         245 :             type = "byte";
    2076         245 :             valueIndex = cf->addIntegerInfo(i->value.byteValue);
    2077         245 :             break;
    2078             :         case unoidl::ConstantValue::TYPE_SHORT:
    2079        2066 :             type = "short";
    2080        2066 :             valueIndex = cf->addIntegerInfo(i->value.shortValue);
    2081        2066 :             break;
    2082             :         case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
    2083           0 :             type = "unsigned short";
    2084           0 :             valueIndex = cf->addIntegerInfo(i->value.unsignedShortValue);
    2085           0 :             break;
    2086             :         case unoidl::ConstantValue::TYPE_LONG:
    2087        1072 :             type = "long";
    2088        1072 :             valueIndex = cf->addIntegerInfo(i->value.longValue);
    2089        1072 :             break;
    2090             :         case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
    2091           0 :             type = "unsigned long";
    2092             :             valueIndex = cf->addIntegerInfo(
    2093           0 :                 static_cast< sal_Int32 >(i->value.unsignedLongValue));
    2094           0 :             break;
    2095             :         case unoidl::ConstantValue::TYPE_HYPER:
    2096          29 :             type = "hyper";
    2097          29 :             valueIndex = cf->addLongInfo(i->value.hyperValue);
    2098          29 :             break;
    2099             :         case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
    2100           0 :             type = "unsigned hyper";
    2101             :             valueIndex = cf->addLongInfo(
    2102           0 :                 static_cast< sal_Int64 >(i->value.unsignedHyperValue));
    2103           0 :             break;
    2104             :         case unoidl::ConstantValue::TYPE_FLOAT:
    2105          20 :             type = "float";
    2106          20 :             valueIndex = cf->addFloatInfo(i->value.floatValue);
    2107          20 :             break;
    2108             :         case unoidl::ConstantValue::TYPE_DOUBLE:
    2109           0 :             type = "double";
    2110           0 :             valueIndex = cf->addDoubleInfo(i->value.doubleValue);
    2111           0 :             break;
    2112             :         }
    2113        3432 :         OString desc;
    2114        6864 :         OString sig;
    2115        3432 :         getFieldDescriptor(manager, dependencies, type, &desc, &sig, 0);
    2116             :         cf->addField(
    2117             :             static_cast< ClassFile::AccessFlags >(
    2118             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
    2119             :                 | ClassFile::ACC_FINAL),
    2120        3432 :             codemaker::convertString(i->name), desc, valueIndex, sig);
    2121        3432 :     }
    2122         712 :     writeClassFile(options, className, *cf.get());
    2123         356 : }
    2124             : 
    2125         379 : void addExceptionHandlers(
    2126             :     codemaker::ExceptionTreeNode const * node,
    2127             :     ClassFile::Code::Position start, ClassFile::Code::Position end,
    2128             :     ClassFile::Code::Position handler, ClassFile::Code * code)
    2129             : {
    2130             :     assert(node != 0);
    2131             :     assert(code != 0);
    2132         379 :     if (node->present) {
    2133          14 :         code->addException(start, end, handler, node->name.replace('.', '/'));
    2134             :     } else {
    2135        1140 :         for (codemaker::ExceptionTreeNode::Children::const_iterator i(
    2136         365 :                  node->children.begin());
    2137         760 :              i != node->children.end(); ++i)
    2138             :         {
    2139          15 :             addExceptionHandlers(*i, start, end, handler, code);
    2140             :         }
    2141             :     }
    2142         379 : }
    2143             : 
    2144         367 : void addConstructor(
    2145             :     rtl::Reference< TypeManager > const & manager,
    2146             :     OString const & realJavaBaseName, OString const & unoName,
    2147             :     OString const & className,
    2148             :     unoidl::SingleInterfaceBasedServiceEntity::Constructor const & constructor,
    2149             :     OUString const & returnType, Dependencies * dependencies,
    2150             :     ClassFile * classFile)
    2151             : {
    2152             :     assert(dependencies != 0);
    2153             :     assert(classFile != 0);
    2154         367 :     MethodDescriptor desc(manager, dependencies, returnType, 0, 0);
    2155         367 :     desc.addParameter("com.sun.star.uno.XComponentContext", false, false, 0);
    2156         734 :     std::unique_ptr< ClassFile::Code > code(classFile->newCode());
    2157         367 :     code->loadLocalReference(0);
    2158             :     // stack: context
    2159             :     code->instrInvokeinterface(
    2160             :         "com/sun/star/uno/XComponentContext", "getServiceManager",
    2161         367 :         "()Lcom/sun/star/lang/XMultiComponentFactory;", 1);
    2162             :     // stack: factory
    2163         367 :     code->loadStringConstant(unoName);
    2164             :     // stack: factory serviceName
    2165         734 :     codemaker::ExceptionTree tree;
    2166             :     ClassFile::Code::Position tryStart;
    2167             :     ClassFile::Code::Position tryEnd;
    2168         734 :     std::vector< OString > exc;
    2169             :     sal_uInt16 stack;
    2170         367 :     sal_uInt16 localIndex = 1;
    2171             :     ClassFile::AccessFlags access = static_cast< ClassFile::AccessFlags >(
    2172         367 :         ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC);
    2173         367 :     if (constructor.defaultConstructor) {
    2174         234 :         code->loadLocalReference(0);
    2175             :         // stack: factory serviceName context
    2176         234 :         tryStart = code->getPosition();
    2177             :         code->instrInvokeinterface(
    2178             :             "com/sun/star/lang/XMultiComponentFactory",
    2179             :             "createInstanceWithContext",
    2180             :             ("(Ljava/lang/String;Lcom/sun/star/uno/XComponentContext;)"
    2181             :              "Ljava/lang/Object;"),
    2182         234 :             3);
    2183         234 :         tryEnd = code->getPosition();
    2184             :         // stack: instance
    2185         234 :         stack = 3;
    2186             :     } else {
    2187         266 :         if (constructor.parameters.size() == 1
    2188         133 :             && constructor.parameters[0].rest)
    2189             :         {
    2190           1 :             desc.addParameter("any", true, true, 0);
    2191           1 :             code->loadLocalReference(localIndex++);
    2192             :             // stack: factory serviceName args
    2193           1 :             stack = 4;
    2194             :             access = static_cast< ClassFile::AccessFlags >(
    2195           1 :                 access | ClassFile::ACC_VARARGS);
    2196             :         } else {
    2197         132 :             code->loadIntegerConstant(constructor.parameters.size());
    2198             :             // stack: factory serviceName N
    2199         132 :             code->instrAnewarray("java/lang/Object");
    2200             :             // stack: factory serviceName args
    2201         132 :             stack = 0;
    2202         132 :             sal_Int32 n = 0;
    2203        1200 :             for (std::vector<
    2204             :                      unoidl::SingleInterfaceBasedServiceEntity::Constructor::
    2205             :                      Parameter >::const_iterator i(
    2206         132 :                          constructor.parameters.begin());
    2207         800 :                  i != constructor.parameters.end(); ++i)
    2208             :             {
    2209         268 :                 desc.addParameter(i->type, false, true, 0);
    2210         268 :                 code->instrDup();
    2211             :                 // stack: factory serviceName args args
    2212         268 :                 code->loadIntegerConstant(n++);
    2213             :                 // stack: factory serviceName args args i
    2214             :                 stack = std::max(
    2215             :                     stack,
    2216             :                     addLoadLocal(
    2217         268 :                         manager, code.get(), &localIndex, false, i->type, true,
    2218         268 :                         dependencies));
    2219             :                 // stack: factory serviceName args args i any
    2220         268 :                 code->instrAastore();
    2221             :                 // stack: factory serviceName args
    2222             :             }
    2223         132 :             stack += 5;
    2224             :         }
    2225         133 :         code->loadLocalReference(0);
    2226             :         // stack: factory serviceName args context
    2227         133 :         tryStart = code->getPosition();
    2228             :         code->instrInvokeinterface(
    2229             :             "com/sun/star/lang/XMultiComponentFactory",
    2230             :             "createInstanceWithArgumentsAndContext",
    2231             :             ("(Ljava/lang/String;[Ljava/lang/Object;"
    2232             :              "Lcom/sun/star/uno/XComponentContext;)Ljava/lang/Object;"),
    2233         133 :             4);
    2234         133 :         tryEnd = code->getPosition();
    2235             :         // stack: instance
    2236             :         createExceptionsAttribute(
    2237         133 :             manager, constructor.exceptions, dependencies, &exc, &tree);
    2238             :     }
    2239         367 :     code->loadLocalReference(0);
    2240             :     // stack: instance context
    2241             :     code->instrInvokestatic(
    2242             :         className, "$castInstance",
    2243             :         ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
    2244         367 :          "Ljava/lang/Object;"));
    2245             :     // stack: instance
    2246             :     code->instrCheckcast(
    2247         367 :         codemaker::convertString(returnType).replace('.', '/'));
    2248             :     // stack: instance
    2249         367 :     code->instrAreturn();
    2250         367 :     if (!tree.getRoot().present) {
    2251         364 :         ClassFile::Code::Position pos1 = code->getPosition();
    2252             :         // stack: e
    2253             :         code->instrInvokevirtual(
    2254         364 :             "java/lang/Throwable", "toString", "()Ljava/lang/String;");
    2255             :         // stack: str
    2256         364 :         localIndex = std::max< sal_uInt16 >(localIndex, 2);
    2257         364 :         code->storeLocalReference(1);
    2258             :         // stack: -
    2259         364 :         code->instrNew("com/sun/star/uno/DeploymentException");
    2260             :         // stack: ex
    2261         364 :         code->instrDup();
    2262             :         // stack: ex ex
    2263             :         code->loadStringConstant(
    2264         728 :             "component context fails to supply service " + unoName + " of type "
    2265         364 :             + realJavaBaseName + ": ");
    2266             :         // stack: ex ex "..."
    2267         364 :         code->loadLocalReference(1);
    2268             :         // stack: ex ex "..." str
    2269             :         code->instrInvokevirtual(
    2270             :             "java/lang/String", "concat",
    2271         364 :             "(Ljava/lang/String;)Ljava/lang/String;");
    2272             :         // stack: ex ex "..."
    2273         364 :         code->loadLocalReference(0);
    2274             :         // stack: ex ex "..." context
    2275             :         code->instrInvokespecial(
    2276             :             "com/sun/star/uno/DeploymentException", "<init>",
    2277         364 :             "(Ljava/lang/String;Ljava/lang/Object;)V");
    2278             :         // stack: ex
    2279         364 :         ClassFile::Code::Position pos2 = code->getPosition();
    2280         364 :         code->instrAthrow();
    2281             :         addExceptionHandlers(
    2282         364 :             &tree.getRoot(), tryStart, tryEnd, pos2, code.get());
    2283             :         code->addException(
    2284         364 :             tryStart, tryEnd, pos1, "com/sun/star/uno/Exception");
    2285         364 :         dependencies->insert("com.sun.star.uno.Exception");
    2286         364 :         stack = std::max< sal_uInt16 >(stack, 4);
    2287             :     }
    2288         367 :     code->setMaxStackAndLocals(stack, localIndex);
    2289             :     classFile->addMethod(
    2290             :         access,
    2291             :         codemaker::java::translateUnoToJavaIdentifier(
    2292             :             (constructor.defaultConstructor
    2293             :              ? OString("create") : codemaker::convertString(constructor.name)),
    2294             :             "method"),
    2295         734 :         desc.getDescriptor(), code.get(), exc, desc.getSignature());
    2296         367 : }
    2297             : 
    2298         340 : void handleService(
    2299             :     const OUString& name,
    2300             :     rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const & entity,
    2301             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    2302             :     Dependencies * dependencies)
    2303             : {
    2304             :     assert(entity.is());
    2305             :     assert(dependencies != 0);
    2306         340 :     OString unoName(codemaker::convertString(name));
    2307             :     OString className(
    2308         680 :         translateUnoidlEntityNameToJavaFullyQualifiedName(name, "service"));
    2309             :     std::unique_ptr< ClassFile > cf(
    2310             :         new ClassFile(
    2311             :             static_cast< ClassFile::AccessFlags >(
    2312             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
    2313             :                 | ClassFile::ACC_SUPER),
    2314         680 :             className, "java/lang/Object", ""));
    2315         340 :     if (!entity->getConstructors().empty()) {
    2316             :         OString realJavaBaseName(
    2317         323 :             codemaker::convertString(entity->getBase()));
    2318         323 :         dependencies->insert(entity->getBase());
    2319         323 :         dependencies->insert("com.sun.star.lang.XMultiComponentFactory");
    2320         323 :         dependencies->insert("com.sun.star.uno.DeploymentException");
    2321         323 :         dependencies->insert("com.sun.star.uno.TypeClass");
    2322         323 :         dependencies->insert("com.sun.star.uno.XComponentContext");
    2323        2070 :         for (std::vector<
    2324             :                  unoidl::SingleInterfaceBasedServiceEntity::Constructor >::
    2325         323 :                  const_iterator i(entity->getConstructors().begin());
    2326        1380 :              i != entity->getConstructors().end(); ++i)
    2327             :         {
    2328             :             addConstructor(
    2329         367 :                 manager, realJavaBaseName, unoName, className, *i,
    2330         734 :                 entity->getBase(), dependencies, cf.get());
    2331             :         }
    2332             :         // Synthetic castInstance method:
    2333             :         {
    2334         323 :             std::unique_ptr< ClassFile::Code > code(cf->newCode());
    2335         323 :             code->instrNew("com/sun/star/uno/Type");
    2336             :             // stack: type
    2337         323 :             code->instrDup();
    2338             :             // stack: type type
    2339         323 :             code->loadStringConstant(realJavaBaseName);
    2340             :             // stack: type type "..."
    2341             :             code->instrGetstatic(
    2342             :                 "com/sun/star/uno/TypeClass", "INTERFACE",
    2343         323 :                 "Lcom/sun/star/uno/TypeClass;");
    2344             :             // stack: type type "..." INTERFACE
    2345             :             code->instrInvokespecial(
    2346             :                 "com/sun/star/uno/Type", "<init>",
    2347         323 :                 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    2348             :             // stack: type
    2349         323 :             code->loadLocalReference(0);
    2350             :             // stack: type instance
    2351             :             code->instrInvokestatic(
    2352             :                 "com/sun/star/uno/UnoRuntime", "queryInterface",
    2353             :                 ("(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
    2354         323 :                  "Ljava/lang/Object;"));
    2355             :             // stack: instance
    2356         323 :             code->instrDup();
    2357             :             // stack: instance instance
    2358         323 :             ClassFile::Code::Branch branch = code->instrIfnull();
    2359             :             // stack: instance
    2360         323 :             code->instrAreturn();
    2361         323 :             code->branchHere(branch);
    2362         323 :             code->instrPop();
    2363             :             // stack: -
    2364         323 :             code->instrNew("com/sun/star/uno/DeploymentException");
    2365             :             // stack: ex
    2366         323 :             code->instrDup();
    2367             :             // stack: ex ex
    2368             :             code->loadStringConstant(
    2369         646 :                 "component context fails to supply service " + unoName
    2370         323 :                 + " of type " + realJavaBaseName);
    2371             :             // stack: ex ex "..."
    2372         323 :             code->loadLocalReference(1);
    2373             :             // stack: ex ex "..." context
    2374             :             code->instrInvokespecial(
    2375             :                 "com/sun/star/uno/DeploymentException", "<init>",
    2376         323 :                 "(Ljava/lang/String;Ljava/lang/Object;)V");
    2377             :             // stack: ex
    2378         323 :             code->instrAthrow();
    2379         323 :             code->setMaxStackAndLocals(4, 2);
    2380             :             cf->addMethod(
    2381             :                 static_cast< ClassFile::AccessFlags >(
    2382             :                     ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC
    2383             :                     | ClassFile::ACC_SYNTHETIC),
    2384             :                 "$castInstance",
    2385             :                 ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
    2386             :                  "Ljava/lang/Object;"),
    2387         323 :                 code.get(), std::vector< OString >(), "");
    2388         323 :         }
    2389             :     }
    2390         680 :     writeClassFile(options, className, *cf.get());
    2391         340 : }
    2392             : 
    2393          31 : void handleSingleton(
    2394             :     const OUString& name,
    2395             :     rtl::Reference< unoidl::InterfaceBasedSingletonEntity > const & entity,
    2396             :     rtl::Reference< TypeManager > const & manager, JavaOptions const & options,
    2397             :     Dependencies * dependencies)
    2398             : {
    2399             :     assert(entity.is());
    2400             :     assert(dependencies != 0);
    2401          31 :     OString realJavaBaseName(codemaker::convertString(entity->getBase()));
    2402          62 :     OString base(realJavaBaseName.replace('.', '/'));
    2403          31 :     dependencies->insert(entity->getBase());
    2404          62 :     OString unoName(codemaker::convertString(name));
    2405             :     OString className(
    2406          62 :         translateUnoidlEntityNameToJavaFullyQualifiedName(name, "singleton"));
    2407          31 :     dependencies->insert("com.sun.star.uno.DeploymentException");
    2408          31 :     dependencies->insert("com.sun.star.uno.TypeClass");
    2409          31 :     dependencies->insert("com.sun.star.uno.XComponentContext");
    2410             :     std::unique_ptr< ClassFile > cf(
    2411             :         new ClassFile(
    2412             :             static_cast< ClassFile::AccessFlags >(
    2413             :                 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
    2414             :                 | ClassFile::ACC_SUPER),
    2415          62 :             className, "java/lang/Object", ""));
    2416          62 :     MethodDescriptor desc(manager, dependencies, entity->getBase(), 0, 0);
    2417          31 :     desc.addParameter("com.sun.star.uno.XComponentContext", false, false, 0);
    2418          62 :     std::unique_ptr< ClassFile::Code > code(cf->newCode());
    2419          31 :     code->loadLocalReference(0);
    2420             :     // stack: context
    2421          31 :     code->loadStringConstant("/singletons/" + unoName);
    2422             :     // stack: context "..."
    2423             :     code->instrInvokeinterface(
    2424             :         "com/sun/star/uno/XComponentContext", "getValueByName",
    2425          31 :         "(Ljava/lang/String;)Ljava/lang/Object;", 2);
    2426             :     // stack: value
    2427          31 :     code->instrDup();
    2428             :     // stack: value value
    2429          31 :     code->instrInstanceof("com/sun/star/uno/Any");
    2430             :     // stack: value 0/1
    2431          31 :     ClassFile::Code::Branch branch1 = code->instrIfeq();
    2432             :     // stack: value
    2433          31 :     code->instrCheckcast("com/sun/star/uno/Any");
    2434             :     // stack: value
    2435          31 :     code->instrDup();
    2436             :     // stack: value value
    2437             :     code->instrInvokevirtual(
    2438          31 :         "com/sun/star/uno/Any", "getType", "()Lcom/sun/star/uno/Type;");
    2439             :     // stack: value type
    2440             :     code->instrInvokevirtual(
    2441             :         "com/sun/star/uno/Type", "getTypeClass",
    2442          31 :         "()Lcom/sun/star/uno/TypeClass;");
    2443             :     // stack: value typeClass
    2444             :     code->instrGetstatic(
    2445             :         "com/sun/star/uno/TypeClass", "INTERFACE",
    2446          31 :         "Lcom/sun/star/uno/TypeClass;");
    2447             :     // stack: value typeClass INTERFACE
    2448          31 :     ClassFile::Code::Branch branch2 = code->instrIfAcmpne();
    2449             :     // stack: value
    2450             :     code->instrInvokevirtual(
    2451          31 :         "com/sun/star/uno/Any", "getObject", "()Ljava/lang/Object;");
    2452             :     // stack: value
    2453          31 :     code->branchHere(branch1);
    2454          31 :     code->instrNew("com/sun/star/uno/Type");
    2455             :     // stack: value type
    2456          31 :     code->instrDup();
    2457             :     // stack: value type type
    2458          31 :     code->loadStringConstant(realJavaBaseName);
    2459             :     // stack: value type type "..."
    2460             :     code->instrGetstatic(
    2461             :         "com/sun/star/uno/TypeClass", "INTERFACE",
    2462          31 :         "Lcom/sun/star/uno/TypeClass;");
    2463             :     // stack: value type type "..." INTERFACE
    2464             :     code->instrInvokespecial(
    2465             :         "com/sun/star/uno/Type", "<init>",
    2466          31 :         "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V");
    2467             :     // stack: value type
    2468          31 :     code->instrSwap();
    2469             :     // stack: type value
    2470             :     code->instrInvokestatic(
    2471             :         "com/sun/star/uno/UnoRuntime", "queryInterface",
    2472          31 :         "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;");
    2473             :     // stack: instance
    2474          31 :     code->instrDup();
    2475             :     // stack: instance instance
    2476          31 :     ClassFile::Code::Branch branch3 = code->instrIfnull();
    2477             :     // stack: instance
    2478          31 :     code->instrCheckcast(base);
    2479             :     // stack: instance
    2480          31 :     code->instrAreturn();
    2481          31 :     code->branchHere(branch2);
    2482          31 :     code->branchHere(branch3);
    2483          31 :     code->instrPop();
    2484             :     // stack: -
    2485          31 :     code->instrNew("com/sun/star/uno/DeploymentException");
    2486             :     // stack: ex
    2487          31 :     code->instrDup();
    2488             :     // stack: ex ex
    2489             :     code->loadStringConstant(
    2490          62 :         "component context fails to supply singleton " + unoName + " of type "
    2491          31 :         + realJavaBaseName);
    2492             :     // stack: ex ex "..."
    2493          31 :     code->loadLocalReference(0);
    2494             :     // stack: ex ex "..." context
    2495             :     code->instrInvokespecial(
    2496             :         "com/sun/star/uno/DeploymentException", "<init>",
    2497          31 :         "(Ljava/lang/String;Ljava/lang/Object;)V");
    2498             :     // stack: ex
    2499          31 :     code->instrAthrow();
    2500          31 :     code->setMaxStackAndLocals(5, 1);
    2501             :     cf->addMethod(
    2502             :         static_cast< ClassFile::AccessFlags >(
    2503             :             ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
    2504          31 :         "get", desc.getDescriptor(), code.get(), std::vector< OString >(),
    2505          62 :         desc.getSignature());
    2506          62 :     writeClassFile(options, className, *cf.get());
    2507          31 : }
    2508             : 
    2509             : }
    2510             : 
    2511       12476 : void produce(
    2512             :     OUString const & name, rtl::Reference< TypeManager > const & manager,
    2513             :     codemaker::GeneratedTypeSet & generated, JavaOptions const & options)
    2514             : {
    2515       12476 :     if (generated.contains(u2b(name))) {
    2516       15930 :         return;
    2517             :     }
    2518        4684 :     generated.add(u2b(name));
    2519        4684 :     if (!manager->foundAtPrimaryProvider(name)) {
    2520         195 :         return;
    2521             :     }
    2522        4489 :     Dependencies deps;
    2523        8827 :     rtl::Reference< unoidl::Entity > ent;
    2524        8827 :     rtl::Reference< unoidl::MapCursor > cur;
    2525        4489 :     switch (manager->getSort(name, &ent, &cur)) {
    2526             :     case codemaker::UnoType::SORT_MODULE:
    2527             :         {
    2528         151 :             OUString prefix;
    2529         151 :             if (!name.isEmpty()) {
    2530         147 :                 prefix = name + ".";
    2531             :             }
    2532             :             for (;;) {
    2533        4748 :                 OUString mem;
    2534        4748 :                 if (!cur->getNext(&mem).is()) {
    2535         151 :                     break;
    2536             :                 }
    2537        4597 :                 produce(prefix + mem, manager, generated, options);
    2538        4597 :             }
    2539         151 :             return;
    2540             :         }
    2541             :     case codemaker::UnoType::SORT_ENUM_TYPE:
    2542             :         handleEnumType(
    2543         195 :             name, dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), options);
    2544         195 :         break;
    2545             :     case codemaker::UnoType::SORT_PLAIN_STRUCT_TYPE:
    2546             :         handlePlainStructType(
    2547         405 :             name, dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
    2548         405 :             manager, options, &deps);
    2549         405 :         break;
    2550             :     case codemaker::UnoType::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
    2551             :         handlePolyStructType(
    2552             :             name,
    2553             :             dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
    2554           6 :                 ent.get()),
    2555           6 :             manager, options, &deps);
    2556           6 :         break;
    2557             :     case codemaker::UnoType::SORT_EXCEPTION_TYPE:
    2558             :         handleExceptionType(
    2559         244 :             name, dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()),
    2560         244 :             manager, options, &deps);
    2561         244 :         break;
    2562             :     case codemaker::UnoType::SORT_INTERFACE_TYPE:
    2563             :         handleInterfaceType(
    2564        1717 :             name, dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()),
    2565        1717 :             manager, options, &deps);
    2566        1717 :         break;
    2567             :     case codemaker::UnoType::SORT_TYPEDEF:
    2568             :         handleTypedef(
    2569          19 :             dynamic_cast< unoidl::TypedefEntity * >(ent.get()), manager, &deps);
    2570          19 :         break;
    2571             :     case codemaker::UnoType::SORT_CONSTANT_GROUP:
    2572             :         handleConstantGroup(
    2573         356 :             name, dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()),
    2574         356 :             manager, options, &deps);
    2575         356 :         break;
    2576             :     case codemaker::UnoType::SORT_SINGLE_INTERFACE_BASED_SERVICE:
    2577             :         handleService(
    2578             :             name,
    2579             :             dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
    2580         340 :                 ent.get()),
    2581         340 :             manager, options, &deps);
    2582         340 :         break;
    2583             :     case codemaker::UnoType::SORT_INTERFACE_BASED_SINGLETON:
    2584             :         handleSingleton(
    2585             :             name,
    2586          31 :             dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(ent.get()),
    2587          31 :             manager, options, &deps);
    2588          31 :         break;
    2589             :     case codemaker::UnoType::SORT_ACCUMULATION_BASED_SERVICE:
    2590             :     case codemaker::UnoType::SORT_SERVICE_BASED_SINGLETON:
    2591        1025 :         break;
    2592             :     default:
    2593             :         throw CannotDumpException(
    2594           0 :             "unexpected entity \"" + name + "\" in call to produce");
    2595             :     }
    2596        4338 :     if (!options.isValid("-nD")) {
    2597       12170 :         for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) {
    2598        7875 :             produce(*i, manager, generated, options);
    2599             :         }
    2600        4338 :     }
    2601             : }
    2602             : 
    2603             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11