merge the formfield patch from ooo-build
[ooovba.git] / codemaker / source / javamaker / javatype.cxx
blob37c97a0bafc957cb72d415a20cdc719a7b3691a2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: javatype.cxx,v $
10 * $Revision: 1.35 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_codemaker.hxx"
34 #include "javatype.hxx"
36 #include "classfile.hxx"
37 #include "javaoptions.hxx"
39 #include "codemaker/exceptiontree.hxx"
40 #include "codemaker/generatedtypeset.hxx"
41 #include "codemaker/global.hxx"
42 #include "codemaker/options.hxx"
43 #include "codemaker/typemanager.hxx"
44 #include "codemaker/unotype.hxx"
45 #include "codemaker/commonjava.hxx"
47 #include "osl/diagnose.h"
48 #include "registry/reader.hxx"
49 #include "registry/refltype.hxx"
50 #include "registry/types.h"
51 #include "rtl/strbuf.hxx"
52 #include "rtl/string.h"
53 #include "rtl/string.hxx"
54 #include "rtl/textcvt.h"
55 #include "rtl/textenc.h"
56 #include "rtl/ustring.h"
57 #include "rtl/ustring.hxx"
58 #include "sal/types.h"
60 #include <algorithm>
61 #include <list>
62 #include <map>
63 #include <memory>
64 #include <set>
65 #include <utility>
66 #include <vector>
68 using codemaker::javamaker::ClassFile;
70 namespace {
72 void checkNoTypeArguments(std::vector< rtl::OString > const & arguments) {
73 if (!arguments.empty()) {
74 throw CannotDumpException(
75 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
76 //TODO
80 // helper function for createUnoName
81 void appendUnoName(
82 TypeManager const & manager, rtl::OString const & nucleus, sal_Int32 rank,
83 std::vector< rtl::OString > const & arguments, rtl::OStringBuffer * buffer)
85 OSL_ASSERT(rank >= 0 && buffer != 0);
86 for (sal_Int32 i = 0; i < rank; ++i) {
87 buffer->append(RTL_CONSTASCII_STRINGPARAM("[]"));
89 buffer->append(nucleus.replace('/', '.'));
90 if (!arguments.empty()) {
91 buffer->append('<');
92 for (std::vector< rtl::OString >::const_iterator i(arguments.begin());
93 i != arguments.end(); ++i)
95 if (i != arguments.begin()) {
96 buffer->append(',');
98 RTTypeClass argTypeClass;
99 rtl::OString argNucleus;
100 sal_Int32 argRank;
101 std::vector< rtl::OString > argArgs;
102 codemaker::decomposeAndResolve(
103 manager, *i, true, false, false, &argTypeClass, &argNucleus,
104 &argRank, &argArgs);
105 appendUnoName(manager, argNucleus, argRank, argArgs, buffer);
107 buffer->append('>');
111 // Translate the name of a UNO type registry entity (enum type, plain struct
112 // type, polymorphic struct type template, or interface type, decomposed into
113 // nucleus, rank, and arguments) into a core UNO type name:
114 rtl::OString createUnoName(
115 TypeManager const & manager, rtl::OString const & nucleus, sal_Int32 rank,
116 std::vector< rtl::OString > const & arguments)
118 rtl::OStringBuffer buf;
119 appendUnoName(manager, nucleus, rank, arguments, &buf);
120 return buf.makeStringAndClear();
124 Set of UTF-8--encoded names of UNO type registry entities a given UNO type
125 registry entity depends on.
127 UNO type registry entities are enum types, plain struct types, polymorphic
128 struct type templates, exception types, interface types, typedefs, modules,
129 constant groupds, single-interface--based services, accumulation-based
130 services, interface-based singletons, and service-based singletons.
132 typedef std::set< rtl::OString > Dependencies;
134 enum SpecialType {
135 SPECIAL_TYPE_NONE,
136 SPECIAL_TYPE_ANY,
137 SPECIAL_TYPE_UNSIGNED,
138 SPECIAL_TYPE_INTERFACE
141 bool isSpecialType(SpecialType special) {
142 return special >= SPECIAL_TYPE_UNSIGNED;
145 rtl::OString translateUnoTypeToJavaFullyQualifiedName(
146 rtl::OString const & type, rtl::OString const & prefix)
148 sal_Int32 i = type.lastIndexOf('/') + 1;
149 return type.copy(0, i) +
150 codemaker::java::translateUnoToJavaIdentifier(type.copy(i), prefix);
153 struct PolymorphicUnoType {
154 PolymorphicUnoType(): kind(KIND_NONE) {}
156 enum Kind { KIND_NONE, KIND_STRUCT, KIND_SEQUENCE };
157 Kind kind;
158 rtl::OString name;
161 SpecialType translateUnoTypeToDescriptor(
162 TypeManager const & manager, rtl::OString const & type, bool array,
163 bool classType, Dependencies * dependencies,
164 rtl::OStringBuffer * descriptor, rtl::OStringBuffer * signature,
165 bool * needsSignature, PolymorphicUnoType * polymorphicUnoType);
167 SpecialType translateUnoTypeToDescriptor(
168 TypeManager const & manager, codemaker::UnoType::Sort sort,
169 RTTypeClass typeClass, rtl::OString const & nucleus, sal_Int32 rank,
170 std::vector< rtl::OString > const & arguments, bool array, bool classType,
171 Dependencies * dependencies, rtl::OStringBuffer * descriptor,
172 rtl::OStringBuffer * signature, bool * needsSignature,
173 PolymorphicUnoType * polymorphicUnoType)
175 OSL_ASSERT(rank >= 0 && (signature == 0) == (needsSignature == 0));
176 if (rank > 0xFF - (array ? 1 : 0)) {
177 throw CannotDumpException(
178 rtl::OString(
179 RTL_CONSTASCII_STRINGPARAM(
180 "Too many array dimensions for Java class file format")));
182 if (array) {
183 ++rank;
185 for (sal_Int32 i = 0; i < rank; ++i) {
186 if (descriptor != 0) {
187 descriptor->append('[');
189 if (signature != 0) {
190 signature->append('[');
193 if (sort == codemaker::UnoType::SORT_COMPLEX) {
194 //TODO: check that nucleus is a valid (Java-modified UTF-8) identifier
195 rtl::OString superClass;
196 if (typeClass == RT_TYPE_INTERFACE
197 && (nucleus
198 == rtl::OString(
199 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface"))))
201 if (descriptor != 0) {
202 descriptor->append(
203 rtl::OString(
204 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")));
206 if (signature != 0) {
207 signature->append(
208 rtl::OString(
209 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")));
211 if (polymorphicUnoType != 0) {
212 polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE;
214 return SPECIAL_TYPE_INTERFACE;
215 } else {
216 if (dependencies != 0) {
217 dependencies->insert(nucleus);
219 if (descriptor != 0) {
220 descriptor->append('L');
221 descriptor->append(nucleus);
222 descriptor->append(';');
224 if (signature != 0) {
225 signature->append('L');
226 signature->append(nucleus);
227 if (!arguments.empty()) {
228 signature->append('<');
229 for (std::vector< rtl::OString >::const_iterator i(
230 arguments.begin());
231 i != arguments.end(); ++i)
233 translateUnoTypeToDescriptor(
234 manager, *i, false, true, dependencies, 0,
235 signature, needsSignature, 0);
237 signature->append('>');
238 *needsSignature = true;
240 signature->append(';');
242 if (polymorphicUnoType != 0) {
243 if (arguments.empty()) {
244 polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE;
245 } else {
246 polymorphicUnoType->kind = rank == 0
247 ? PolymorphicUnoType::KIND_STRUCT
248 : PolymorphicUnoType::KIND_SEQUENCE;
249 polymorphicUnoType->name = createUnoName(
250 manager, nucleus, rank, arguments);
253 return SPECIAL_TYPE_NONE;
255 } else {
256 static rtl::OString const
257 simpleTypeDescriptors[codemaker::UnoType::SORT_ANY + 1][2] = {
258 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("V")),
259 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Void;"))
261 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("Z")),
262 rtl::OString(
263 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Boolean;"))
265 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("B")),
266 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Byte;"))
268 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("S")),
269 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Short;"))
271 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("S")),
272 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Short;"))
274 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")),
275 rtl::OString(
276 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Integer;"))
278 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")),
279 rtl::OString(
280 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Integer;"))
282 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("J")),
283 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Long;"))
285 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("J")),
286 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Long;"))
288 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("F")),
289 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Float;"))
291 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("D")),
292 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Double;"))
294 { rtl::OString(RTL_CONSTASCII_STRINGPARAM("C")),
295 rtl::OString(
296 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Character;"))
298 { rtl::OString(
299 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;")),
300 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;"))
302 { rtl::OString(
303 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;")),
304 rtl::OString(
305 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;"))
307 { rtl::OString(
308 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")),
309 rtl::OString(
310 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"))
311 } };
312 rtl::OString const & s
313 = simpleTypeDescriptors[sort][rank == 0 && classType];
314 if (descriptor != 0) {
315 descriptor->append(s);
317 if (signature != 0) {
318 signature->append(s);
320 if (polymorphicUnoType != 0) {
321 polymorphicUnoType->kind = PolymorphicUnoType::KIND_NONE;
323 static SpecialType const
324 simpleTypeSpecials[codemaker::UnoType::SORT_ANY + 1] = {
325 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE,
326 SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE,
327 SPECIAL_TYPE_UNSIGNED, SPECIAL_TYPE_NONE, SPECIAL_TYPE_UNSIGNED,
328 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE,
329 SPECIAL_TYPE_NONE, SPECIAL_TYPE_NONE, SPECIAL_TYPE_ANY };
330 return simpleTypeSpecials[sort];
334 SpecialType translateUnoTypeToDescriptor(
335 TypeManager const & manager, rtl::OString const & type, bool array,
336 bool classType, Dependencies * dependencies,
337 rtl::OStringBuffer * descriptor, rtl::OStringBuffer * signature,
338 bool * needsSignature, PolymorphicUnoType * polymorphicUnoType)
340 RTTypeClass typeClass;
341 rtl::OString nucleus;
342 sal_Int32 rank;
343 std::vector< rtl::OString > args;
344 codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
345 manager, type, true, true, false, &typeClass, &nucleus, &rank, &args);
346 OSL_ASSERT(rank < SAL_MAX_INT32);
347 return translateUnoTypeToDescriptor(
348 manager, sort, typeClass, nucleus, rank, args, array, classType,
349 dependencies, descriptor, signature, needsSignature,
350 polymorphicUnoType);
353 SpecialType getFieldDescriptor(
354 TypeManager const & manager, Dependencies * dependencies,
355 rtl::OString const & type, rtl::OString * descriptor,
356 rtl::OString * signature, PolymorphicUnoType * polymorphicUnoType)
358 OSL_ASSERT(dependencies != 0 && descriptor != 0);
359 rtl::OStringBuffer desc;
360 rtl::OStringBuffer sig;
361 bool needsSig = false;
362 SpecialType specialType = translateUnoTypeToDescriptor(
363 manager, type, false, false, dependencies, &desc, &sig, &needsSig,
364 polymorphicUnoType);
365 *descriptor = desc.makeStringAndClear();
366 if (signature != 0) {
367 if (needsSig) {
368 *signature = sig.makeStringAndClear();
369 } else {
370 *signature = rtl::OString();
373 return specialType;
376 class MethodDescriptor {
377 public:
378 MethodDescriptor(
379 TypeManager const & manager, Dependencies * dependencies,
380 rtl::OString const & returnType, SpecialType * specialReturnType,
381 PolymorphicUnoType * polymorphicUnoType);
383 SpecialType addParameter(
384 rtl::OString const & type, bool array, bool dependency,
385 PolymorphicUnoType * polymorphicUnoType);
387 void addTypeParameter(rtl::OString const & name);
389 rtl::OString getDescriptor() const;
391 rtl::OString getSignature() const;
393 private:
394 TypeManager const & m_manager;
395 Dependencies * m_dependencies;
396 rtl::OStringBuffer m_descriptorStart;
397 rtl::OString m_descriptorEnd;
398 rtl::OStringBuffer m_signatureStart;
399 rtl::OString m_signatureEnd;
400 bool m_needsSignature;
403 MethodDescriptor::MethodDescriptor(
404 TypeManager const & manager, Dependencies * dependencies,
405 rtl::OString const & returnType, SpecialType * specialReturnType,
406 PolymorphicUnoType * polymorphicUnoType):
407 m_manager(manager), m_dependencies(dependencies), m_needsSignature(false)
409 OSL_ASSERT(dependencies != 0);
410 m_descriptorStart.append('(');
411 m_signatureStart.append('(');
412 rtl::OStringBuffer descEnd;
413 descEnd.append(')');
414 rtl::OStringBuffer sigEnd;
415 sigEnd.append(')');
416 SpecialType special = translateUnoTypeToDescriptor(
417 m_manager, returnType, false, false, m_dependencies, &descEnd, &sigEnd,
418 &m_needsSignature, polymorphicUnoType);
419 m_descriptorEnd = descEnd.makeStringAndClear();
420 m_signatureEnd = sigEnd.makeStringAndClear();
421 if (specialReturnType != 0) {
422 *specialReturnType = special;
426 SpecialType MethodDescriptor::addParameter(
427 rtl::OString const & type, bool array, bool dependency,
428 PolymorphicUnoType * polymorphicUnoType)
430 return translateUnoTypeToDescriptor(
431 m_manager, type, array, false, dependency ? m_dependencies : 0,
432 &m_descriptorStart, &m_signatureStart, &m_needsSignature,
433 polymorphicUnoType);
436 void MethodDescriptor::addTypeParameter(rtl::OString const & name) {
437 m_descriptorStart.append(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
438 m_signatureStart.append('T');
439 m_signatureStart.append(name);
440 m_signatureStart.append(';');
441 m_needsSignature = true;
444 rtl::OString MethodDescriptor::getDescriptor() const {
445 rtl::OStringBuffer buf(m_descriptorStart);
446 buf.append(m_descriptorEnd);
447 return buf.makeStringAndClear();
450 rtl::OString MethodDescriptor::getSignature() const {
451 if (m_needsSignature) {
452 rtl::OStringBuffer buf(m_signatureStart);
453 buf.append(m_signatureEnd);
454 return buf.makeStringAndClear();
455 } else {
456 return rtl::OString();
460 class TypeInfo {
461 public:
462 enum Kind { KIND_MEMBER, KIND_ATTRIBUTE, KIND_METHOD, KIND_PARAMETER };
464 // Same values as in com/sun/star/lib/uno/typeinfo/TypeInfo.java:
465 enum Flags {
466 FLAG_READONLY = 0x008, FLAG_BOUND = 0x100, FLAG_ONEWAY = 0x010
469 // KIND_MEMBER:
470 TypeInfo(
471 rtl::OString const & name, SpecialType specialType, sal_Int32 index,
472 PolymorphicUnoType const & polymorphicUnoType,
473 sal_Int32 typeParameterIndex);
475 // KIND_ATTRIBUTE/METHOD:
476 TypeInfo(
477 Kind kind, rtl::OString const & name, SpecialType specialType,
478 Flags flags, sal_Int32 index,
479 PolymorphicUnoType const & polymorphicUnoType);
481 // KIND_PARAMETER:
482 TypeInfo(
483 rtl::OString const & parameterName, SpecialType specialType,
484 bool inParameter, bool outParameter, rtl::OString const & methodName,
485 sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType);
487 sal_uInt16 generateCode(ClassFile::Code & code, Dependencies * dependencies)
488 const;
490 void generatePolymorphicUnoTypeCode(
491 ClassFile::Code & code, Dependencies * dependencies) const;
493 private:
494 Kind m_kind;
495 rtl::OString m_name;
496 sal_Int32 m_flags;
497 sal_Int32 m_index;
498 rtl::OString m_methodName;
499 PolymorphicUnoType m_polymorphicUnoType;
500 sal_Int32 m_typeParameterIndex;
503 sal_Int32 translateSpecialTypeFlags(
504 SpecialType specialType, bool inParameter, bool outParameter)
506 static sal_Int32 const specialTypeFlags[SPECIAL_TYPE_INTERFACE + 1] = {
507 0, 0x0040 /* ANY */, 0x0004 /* UNSIGNED */, 0x0080 /* INTERFACE */ };
508 sal_Int32 flags = specialTypeFlags[specialType];
509 if (inParameter) {
510 flags |= 0x0001; /* IN */
512 if (outParameter) {
513 flags |= 0x0002; /* OUT */
515 return flags;
518 TypeInfo::TypeInfo(
519 rtl::OString const & name, SpecialType specialType, sal_Int32 index,
520 PolymorphicUnoType const & polymorphicUnoType,
521 sal_Int32 typeParameterIndex):
522 m_kind(KIND_MEMBER), m_name(name),
523 m_flags(translateSpecialTypeFlags(specialType, false, false)),
524 m_index(index), m_polymorphicUnoType(polymorphicUnoType),
525 m_typeParameterIndex(typeParameterIndex)
527 OSL_ASSERT(
528 polymorphicUnoType.kind == PolymorphicUnoType::KIND_NONE
529 ? typeParameterIndex >= -1 : typeParameterIndex == -1);
532 TypeInfo::TypeInfo(
533 Kind kind, rtl::OString const & name, SpecialType specialType,
534 Flags flags, sal_Int32 index,
535 PolymorphicUnoType const & polymorphicUnoType):
536 m_kind(kind), m_name(name),
537 m_flags(flags | translateSpecialTypeFlags(specialType, false, false)),
538 m_index(index), m_polymorphicUnoType(polymorphicUnoType)
540 OSL_ASSERT(kind == KIND_ATTRIBUTE || kind == KIND_METHOD);
543 TypeInfo::TypeInfo(
544 rtl::OString const & parameterName, SpecialType specialType,
545 bool inParameter, bool outParameter, rtl::OString const & methodName,
546 sal_Int32 index, PolymorphicUnoType const & polymorphicUnoType):
547 m_kind(KIND_PARAMETER), m_name(parameterName),
548 m_flags(translateSpecialTypeFlags(specialType, inParameter, outParameter)),
549 m_index(index), m_methodName(methodName),
550 m_polymorphicUnoType(polymorphicUnoType)
553 sal_uInt16 TypeInfo::generateCode(
554 ClassFile::Code & code, Dependencies * dependencies) const
556 OSL_ASSERT(dependencies != 0);
557 switch (m_kind) {
558 case KIND_MEMBER:
559 code.instrNew(
560 rtl::OString(
561 RTL_CONSTASCII_STRINGPARAM(
562 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")));
563 code.instrDup();
564 code.loadStringConstant(m_name);
565 code.loadIntegerConstant(m_index);
566 code.loadIntegerConstant(m_flags);
567 if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
568 generatePolymorphicUnoTypeCode(code, dependencies);
569 code.loadIntegerConstant(m_typeParameterIndex);
570 code.instrInvokespecial(
571 rtl::OString(
572 RTL_CONSTASCII_STRINGPARAM(
573 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")),
574 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
575 rtl::OString(
576 RTL_CONSTASCII_STRINGPARAM(
577 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V")));
578 return 8;
579 } else if (m_typeParameterIndex >= 0) {
580 code.instrAconstNull();
581 code.loadIntegerConstant(m_typeParameterIndex);
582 code.instrInvokespecial(
583 rtl::OString(
584 RTL_CONSTASCII_STRINGPARAM(
585 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")),
586 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
587 rtl::OString(
588 RTL_CONSTASCII_STRINGPARAM(
589 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V")));
590 return 6;
591 } else {
592 code.instrInvokespecial(
593 rtl::OString(
594 RTL_CONSTASCII_STRINGPARAM(
595 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo")),
596 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
597 rtl::OString(
598 RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V")));
599 return 4;
602 case KIND_ATTRIBUTE:
603 code.instrNew(
604 rtl::OString(
605 RTL_CONSTASCII_STRINGPARAM(
606 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo")));
607 code.instrDup();
608 code.loadStringConstant(m_name);
609 code.loadIntegerConstant(m_index);
610 code.loadIntegerConstant(m_flags);
611 if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
612 generatePolymorphicUnoTypeCode(code, dependencies);
613 code.instrInvokespecial(
614 rtl::OString(
615 RTL_CONSTASCII_STRINGPARAM(
616 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo")),
617 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
618 rtl::OString(
619 RTL_CONSTASCII_STRINGPARAM(
620 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V")));
621 return 8;
622 } else {
623 code.instrInvokespecial(
624 rtl::OString(
625 RTL_CONSTASCII_STRINGPARAM(
626 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo")),
627 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
628 rtl::OString(
629 RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V")));
630 return 4;
633 case KIND_METHOD:
634 code.instrNew(
635 rtl::OString(
636 RTL_CONSTASCII_STRINGPARAM(
637 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo")));
638 code.instrDup();
639 code.loadStringConstant(m_name);
640 code.loadIntegerConstant(m_index);
641 code.loadIntegerConstant(m_flags);
642 if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
643 generatePolymorphicUnoTypeCode(code, dependencies);
644 code.instrInvokespecial(
645 rtl::OString(
646 RTL_CONSTASCII_STRINGPARAM(
647 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo")),
648 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
649 rtl::OString(
650 RTL_CONSTASCII_STRINGPARAM(
651 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V")));
652 return 8;
653 } else {
654 code.instrInvokespecial(
655 rtl::OString(
656 RTL_CONSTASCII_STRINGPARAM(
657 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo")),
658 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
659 rtl::OString(
660 RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;II)V")));
661 return 4;
664 case KIND_PARAMETER:
665 code.instrNew(
666 rtl::OString(
667 RTL_CONSTASCII_STRINGPARAM(
668 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo")));
669 code.instrDup();
670 code.loadStringConstant(m_name);
671 code.loadStringConstant(m_methodName);
672 code.loadIntegerConstant(m_index);
673 code.loadIntegerConstant(m_flags);
674 if (m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE) {
675 generatePolymorphicUnoTypeCode(code, dependencies);
676 code.instrInvokespecial(
677 rtl::OString(
678 RTL_CONSTASCII_STRINGPARAM(
679 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo")),
680 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
681 rtl::OString(
682 RTL_CONSTASCII_STRINGPARAM(
683 "(Ljava/lang/String;Ljava/lang/String;II"
684 "Lcom/sun/star/uno/Type;)V")));
685 return 9;
686 } else {
687 code.instrInvokespecial(
688 rtl::OString(
689 RTL_CONSTASCII_STRINGPARAM(
690 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo")),
691 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
692 rtl::OString(
693 RTL_CONSTASCII_STRINGPARAM(
694 "(Ljava/lang/String;Ljava/lang/String;II)V")));
695 return 5;
698 default:
699 OSL_ASSERT(false);
700 return 0;
704 void TypeInfo::generatePolymorphicUnoTypeCode(
705 ClassFile::Code & code, Dependencies * dependencies) const
707 OSL_ASSERT(
708 dependencies != 0
709 && m_polymorphicUnoType.kind != PolymorphicUnoType::KIND_NONE);
710 code.instrNew(
711 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")));
712 code.instrDup();
713 code.loadStringConstant(m_polymorphicUnoType.name);
714 if (m_polymorphicUnoType.kind == PolymorphicUnoType::KIND_STRUCT) {
715 code.instrGetstatic(
716 rtl::OString(
717 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")),
718 rtl::OString(RTL_CONSTASCII_STRINGPARAM("STRUCT")),
719 rtl::OString(
720 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;")));
721 } else {
722 code.instrGetstatic(
723 rtl::OString(
724 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")),
725 rtl::OString(RTL_CONSTASCII_STRINGPARAM("SEQUENCE")),
726 rtl::OString(
727 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;")));
729 dependencies->insert(
730 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")));
731 code.instrInvokespecial(
732 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
733 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
734 rtl::OString(
735 RTL_CONSTASCII_STRINGPARAM(
736 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V")));
739 void writeClassFile(
740 JavaOptions /*TODO const*/ & options, rtl::OString const & type,
741 ClassFile const & classFile)
743 rtl::OString path;
744 if (options.isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-O")))) {
745 path = options.getOption(
746 rtl::OString(RTL_CONSTASCII_STRINGPARAM("-O")));
748 rtl::OString filename(
749 createFileNameFromType(
750 path, type, rtl::OString(RTL_CONSTASCII_STRINGPARAM(".class"))));
751 bool check = false;
752 if (fileExists(filename)) {
753 if (options.isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-G")))) {
754 return;
756 check = options.isValid(
757 rtl::OString(RTL_CONSTASCII_STRINGPARAM("-Gc")));
759 FileStream tempfile;
760 tempfile.createTempFile(getTempDir(filename));
761 if (!tempfile.isValid()) {
762 throw CannotDumpException(
763 rtl::OString(
764 RTL_CONSTASCII_STRINGPARAM("Cannot create temporary file for "))
765 + filename);
767 rtl::OString tempname(tempfile.getName());
768 try {
769 classFile.write(tempfile);
770 } catch (...) {
771 // Remove existing file for consistency:
772 if (fileExists(filename)) {
773 removeTypeFile(filename);
775 tempfile.close();
776 removeTypeFile(tempname);
777 throw;
779 tempfile.close();
780 if (!makeValidTypeFile(filename, tempname, check)) {
781 rtl::OStringBuffer msg;
782 msg.append(RTL_CONSTASCII_STRINGPARAM("Cannot create "));
783 msg.append(filename);
784 msg.append(RTL_CONSTASCII_STRINGPARAM(" from temporary file "));
785 msg.append(tempname);
786 throw CannotDumpException(msg.makeStringAndClear());
790 void addTypeInfo(
791 rtl::OString const & className, std::vector< TypeInfo > const & typeInfo,
792 Dependencies * dependencies, ClassFile * classFile)
794 OSL_ASSERT(dependencies != 0 && classFile != 0);
795 std::vector< TypeInfo >::size_type typeInfos = typeInfo.size();
796 if (typeInfos > SAL_MAX_INT32) {
797 throw CannotDumpException(
798 rtl::OString(
799 RTL_CONSTASCII_STRINGPARAM(
800 "UNOTYPEINFO array too big for Java class file format")));
802 if (typeInfos != 0) {
803 classFile->addField(
804 static_cast< ClassFile::AccessFlags >(
805 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
806 | ClassFile::ACC_FINAL),
807 rtl::OString(RTL_CONSTASCII_STRINGPARAM("UNOTYPEINFO")),
808 rtl::OString(
809 RTL_CONSTASCII_STRINGPARAM(
810 "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;")),
811 0, rtl::OString());
812 std::auto_ptr< ClassFile::Code > code(classFile->newCode());
813 code->loadIntegerConstant(static_cast< sal_Int32 >(typeInfos));
814 code->instrAnewarray(
815 rtl::OString(
816 RTL_CONSTASCII_STRINGPARAM(
817 "com/sun/star/lib/uno/typeinfo/TypeInfo")));
818 sal_Int32 index = 0;
819 sal_uInt16 stack = 0;
820 for (std::vector< TypeInfo >::const_iterator i(typeInfo.begin());
821 i != typeInfo.end(); ++i)
823 code->instrDup();
824 code->loadIntegerConstant(index++);
825 stack = std::max(stack, i->generateCode(*code, dependencies));
826 code->instrAastore();
828 code->instrPutstatic(
829 className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("UNOTYPEINFO")),
830 rtl::OString(
831 RTL_CONSTASCII_STRINGPARAM(
832 "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;")));
833 code->instrReturn();
834 if (stack > SAL_MAX_UINT16 - 4) {
835 throw CannotDumpException(
836 rtl::OString(
837 RTL_CONSTASCII_STRINGPARAM(
838 "Stack too big for Java class file format")));
840 code->setMaxStackAndLocals(static_cast< sal_uInt16 >(stack + 4), 0);
841 classFile->addMethod(
842 static_cast< ClassFile::AccessFlags >(
843 ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC),
844 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<clinit>")),
845 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(),
846 std::vector< rtl::OString >(), rtl::OString());
850 typedef void (* handleUnoTypeRegistryEntityFunction)(
851 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
852 typereg::Reader const & reader, Dependencies * dependencies);
854 void handleEnumType(
855 TypeManager const &, JavaOptions /*TODO const*/ & options,
856 typereg::Reader const & reader, Dependencies *)
858 sal_uInt16 fields = reader.getFieldCount();
859 if (fields == 0 || reader.getSuperTypeCount() != 0
860 || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0)
862 throw CannotDumpException(
863 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
864 //TODO
866 rtl::OString className(codemaker::convertString(reader.getTypeName()));
867 std::auto_ptr< ClassFile > cf(
868 new ClassFile(
869 static_cast< ClassFile::AccessFlags >(
870 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
871 | ClassFile::ACC_SUPER),
872 className,
873 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Enum")),
874 rtl::OString()));
875 rtl::OStringBuffer buf;
876 buf.append('L');
877 buf.append(className);
878 buf.append(';');
879 rtl::OString classDescriptor(buf.makeStringAndClear());
880 {for (sal_uInt16 i = 0; i < fields; ++i) {
881 RTConstValue fieldValue(reader.getFieldValue(i));
882 if (fieldValue.m_type != RT_TYPE_INT32
883 || reader.getFieldFlags(i) != RT_ACCESS_CONST
884 || reader.getFieldTypeName(i).getLength() != 0)
886 throw CannotDumpException(
887 rtl::OString(
888 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
890 rtl::OString fieldName(
891 codemaker::convertString(reader.getFieldName(i)));
892 cf->addField(
893 static_cast< ClassFile::AccessFlags >(
894 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
895 | ClassFile::ACC_FINAL),
896 fieldName, classDescriptor, 0, rtl::OString());
897 cf->addField(
898 static_cast< ClassFile::AccessFlags >(
899 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
900 | ClassFile::ACC_FINAL),
901 fieldName + rtl::OString(RTL_CONSTASCII_STRINGPARAM("_value")),
902 rtl::OString(RTL_CONSTASCII_STRINGPARAM("I")),
903 cf->addIntegerInfo(fieldValue.m_value.aLong), rtl::OString());
905 std::auto_ptr< ClassFile::Code > code(cf->newCode());
906 code->loadLocalReference(0);
907 code->loadLocalInteger(1);
908 code->instrInvokespecial(
909 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Enum")),
910 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
911 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")));
912 code->instrReturn();
913 code->setMaxStackAndLocals(2, 2);
914 cf->addMethod(
915 ClassFile::ACC_PRIVATE,
916 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
917 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")), code.get(),
918 std::vector< rtl::OString >(), rtl::OString());
919 code.reset(cf->newCode());
920 code->instrGetstatic(
921 className,
922 codemaker::convertString(reader.getFieldName(0)), classDescriptor);
923 code->instrAreturn();
924 code->setMaxStackAndLocals(1, 0);
925 cf->addMethod(
926 static_cast< ClassFile::AccessFlags >(
927 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
928 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getDefault")),
929 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()")) + classDescriptor,
930 code.get(), std::vector< rtl::OString >(), rtl::OString());
931 code.reset(cf->newCode());
932 code->loadLocalInteger(0);
933 std::map< sal_Int32, rtl::OString > map;
934 sal_Int32 min = SAL_MAX_INT32;
935 sal_Int32 max = SAL_MIN_INT32;
936 {for (sal_uInt16 i = 0; i < fields; ++i) {
937 sal_Int32 value = reader.getFieldValue(i).m_value.aLong;
938 min = std::min(min, value);
939 max = std::max(max, value);
940 map.insert(
941 std::map< sal_Int32, rtl::OString >::value_type(
942 value, codemaker::convertString(reader.getFieldName(i))));
944 sal_uInt64 size = static_cast< sal_uInt64 >(map.size());
945 if ((static_cast< sal_uInt64 >(max) - static_cast< sal_uInt64 >(min)
946 <= 2 * size)
947 || size > SAL_MAX_INT32)
949 std::auto_ptr< ClassFile::Code > defCode(cf->newCode());
950 defCode->instrAconstNull();
951 defCode->instrAreturn();
952 std::list< ClassFile::Code * > blocks;
953 //FIXME: pointers contained in blocks may leak
954 sal_Int32 last = SAL_MAX_INT32;
955 for (std::map< sal_Int32, rtl::OString >::iterator i(map.begin());
956 i != map.end(); ++i)
958 sal_Int32 value = i->first;
959 if (last != SAL_MAX_INT32) {
960 for (sal_Int32 j = last + 1; j < value; ++j) {
961 blocks.push_back(0);
964 last = value;
965 std::auto_ptr< ClassFile::Code > blockCode(cf->newCode());
966 blockCode->instrGetstatic(className, i->second, classDescriptor);
967 blockCode->instrAreturn();
968 blocks.push_back(blockCode.get());
969 blockCode.release();
971 code->instrTableswitch(defCode.get(), min, blocks);
972 {for (std::list< ClassFile::Code * >::iterator i(blocks.begin());
973 i != blocks.end(); ++i)
975 delete *i;
977 } else {
978 std::auto_ptr< ClassFile::Code > defCode(cf->newCode());
979 defCode->instrAconstNull();
980 defCode->instrAreturn();
981 std::list< std::pair< sal_Int32, ClassFile::Code * > > blocks;
982 //FIXME: pointers contained in blocks may leak
983 for (std::map< sal_Int32, rtl::OString >::iterator i(map.begin());
984 i != map.end(); ++i)
986 std::auto_ptr< ClassFile::Code > blockCode(cf->newCode());
987 blockCode->instrGetstatic(className, i->second, classDescriptor);
988 blockCode->instrAreturn();
989 blocks.push_back(std::make_pair(i->first, blockCode.get()));
990 blockCode.release();
992 code->instrLookupswitch(defCode.get(), blocks);
993 {for (std::list< std::pair< sal_Int32, ClassFile::Code * > >::iterator
994 i(blocks.begin());
995 i != blocks.end(); ++i)
997 delete i->second;
1000 code->setMaxStackAndLocals(1, 1);
1001 cf->addMethod(
1002 static_cast< ClassFile::AccessFlags >(
1003 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
1004 rtl::OString(RTL_CONSTASCII_STRINGPARAM("fromInt")),
1005 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)")) + classDescriptor,
1006 code.get(), std::vector< rtl::OString >(), rtl::OString());
1007 code.reset(cf->newCode());
1008 {for (sal_uInt16 i = 0; i < fields; ++i) {
1009 code->instrNew(className);
1010 code->instrDup();
1011 code->loadIntegerConstant(reader.getFieldValue(i).m_value.aLong);
1012 code->instrInvokespecial(
1013 className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1014 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")));
1015 code->instrPutstatic(
1016 className,
1017 codemaker::convertString(reader.getFieldName(i)),
1018 classDescriptor);
1020 code->instrReturn();
1021 code->setMaxStackAndLocals(3, 0);
1022 cf->addMethod(
1023 static_cast< ClassFile::AccessFlags >(
1024 ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC),
1025 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<clinit>")),
1026 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(),
1027 std::vector< rtl::OString >(), rtl::OString());
1028 writeClassFile(options, className, *cf.get());
1031 void addField(
1032 TypeManager const & manager, Dependencies * dependencies,
1033 ClassFile * classFile, std::vector< TypeInfo > * typeInfo,
1034 sal_Int32 typeParameterIndex, rtl::OString const & type,
1035 rtl::OString const & name, sal_Int32 index)
1037 OSL_ASSERT(dependencies != 0 && classFile != 0 && typeInfo != 0);
1038 rtl::OString descriptor;
1039 rtl::OString signature;
1040 SpecialType specialType;
1041 PolymorphicUnoType polymorphicUnoType;
1042 if (typeParameterIndex >= 0) {
1043 descriptor = rtl::OString(
1044 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
1045 rtl::OStringBuffer buf;
1046 buf.append('T');
1047 buf.append(type);
1048 buf.append(';');
1049 signature = buf.makeStringAndClear();
1050 specialType = SPECIAL_TYPE_NONE; //TODO: SPECIAL_TYPE_TYPE_PARAMETER?
1051 } else {
1052 specialType = getFieldDescriptor(
1053 manager, dependencies, type, &descriptor, &signature,
1054 &polymorphicUnoType);
1056 classFile->addField(ClassFile::ACC_PUBLIC, name, descriptor, 0, signature);
1057 typeInfo->push_back(
1058 TypeInfo(
1059 name, specialType, index, polymorphicUnoType, typeParameterIndex));
1062 sal_uInt16 addFieldInit(
1063 TypeManager const & manager, rtl::OString const & className,
1064 rtl::OString const & fieldName, bool typeParameter,
1065 rtl::OString const & fieldType, Dependencies * dependencies,
1066 ClassFile::Code * code)
1068 OSL_ASSERT(dependencies != 0 && code != 0);
1069 if (typeParameter) {
1070 return 0;
1071 } else {
1072 RTTypeClass typeClass;
1073 rtl::OString nucleus;
1074 sal_Int32 rank;
1075 std::vector< rtl::OString > args;
1076 codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
1077 manager, fieldType, true, false, false, &typeClass, &nucleus, &rank,
1078 &args);
1079 if (rank == 0) {
1080 switch (sort) {
1081 case codemaker::UnoType::SORT_STRING:
1082 code->loadLocalReference(0);
1083 code->loadStringConstant(rtl::OString());
1084 code->instrPutfield(
1085 className, fieldName,
1086 rtl::OString(
1087 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;")));
1088 return 2;
1090 case codemaker::UnoType::SORT_TYPE:
1091 code->loadLocalReference(0);
1092 code->instrGetstatic(
1093 rtl::OString(
1094 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
1095 rtl::OString(RTL_CONSTASCII_STRINGPARAM("VOID")),
1096 rtl::OString(
1097 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;")));
1098 code->instrPutfield(
1099 className, fieldName,
1100 rtl::OString(
1101 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;")));
1102 return 2;
1104 case codemaker::UnoType::SORT_ANY:
1105 code->loadLocalReference(0);
1106 code->instrGetstatic(
1107 rtl::OString(
1108 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
1109 rtl::OString(RTL_CONSTASCII_STRINGPARAM("VOID")),
1110 rtl::OString(
1111 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Any;")));
1112 code->instrPutfield(
1113 className, fieldName,
1114 rtl::OString(
1115 RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;")));
1116 return 2;
1118 case codemaker::UnoType::SORT_COMPLEX:
1119 switch (typeClass) {
1120 case RT_TYPE_ENUM:
1122 code->loadLocalReference(0);
1123 typereg::Reader reader(manager.getTypeReader(nucleus));
1124 if (reader.getFieldCount() == 0) {
1125 throw CannotDumpException(
1126 rtl::OString(
1127 RTL_CONSTASCII_STRINGPARAM(
1128 "Bad type information"))); //TODO
1130 rtl::OStringBuffer descBuf;
1131 translateUnoTypeToDescriptor(
1132 manager, sort, typeClass, nucleus, 0,
1133 std::vector< rtl::OString >(), false, false,
1134 dependencies, &descBuf, 0, 0, 0);
1135 rtl::OString desc(descBuf.makeStringAndClear());
1136 code->instrGetstatic(
1137 nucleus,
1138 codemaker::convertString(reader.getFieldName(0)),
1139 desc);
1140 code->instrPutfield(className, fieldName, desc);
1141 return 2;
1144 case RT_TYPE_STRUCT:
1146 code->loadLocalReference(0);
1147 code->instrNew(nucleus);
1148 code->instrDup();
1149 code->instrInvokespecial(
1150 nucleus,
1151 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1152 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")));
1153 rtl::OStringBuffer desc;
1154 translateUnoTypeToDescriptor(
1155 manager, sort, typeClass, nucleus, 0,
1156 std::vector< rtl::OString >(), false, false,
1157 dependencies, &desc, 0, 0, 0);
1158 code->instrPutfield(
1159 className, fieldName, desc.makeStringAndClear());
1160 return 3;
1163 default:
1164 OSL_ASSERT(typeClass == RT_TYPE_INTERFACE);
1165 return 0;
1168 default:
1169 return 0;
1171 } else {
1172 code->loadLocalReference(0);
1173 code->loadIntegerConstant(0);
1174 if (rank == 1) {
1175 if (sort >= codemaker::UnoType::SORT_BOOLEAN
1176 && sort <= codemaker::UnoType::SORT_CHAR)
1178 code->instrNewarray(sort);
1179 } else {
1180 code->instrAnewarray(
1181 codemaker::java::translateUnoToJavaType(sort, typeClass,
1182 nucleus, 0));
1184 } else {
1185 rtl::OStringBuffer desc;
1186 translateUnoTypeToDescriptor(
1187 manager, sort, typeClass, nucleus, rank - 1,
1188 std::vector< rtl::OString >(), false, false, dependencies,
1189 &desc, 0, 0, 0);
1190 code->instrAnewarray(desc.makeStringAndClear());
1192 rtl::OStringBuffer desc;
1193 translateUnoTypeToDescriptor(
1194 manager, sort, typeClass, nucleus, rank,
1195 std::vector< rtl::OString >(), false, false, dependencies,
1196 &desc, 0, 0, 0);
1197 code->instrPutfield(
1198 className, fieldName, desc.makeStringAndClear());
1199 return 2;
1204 sal_uInt16 addLoadLocal(
1205 TypeManager const & manager, ClassFile::Code * code, sal_uInt16 * index,
1206 bool typeParameter, rtl::OString const & type, bool any,
1207 Dependencies * dependencies)
1209 OSL_ASSERT(
1210 code != 0 && index != 0 && !(typeParameter && any)
1211 && dependencies != 0);
1212 sal_uInt16 stack = 1;
1213 sal_uInt16 size = 1;
1214 if (typeParameter) {
1215 code->loadLocalReference(*index);
1216 stack = size = 1;
1217 } else {
1218 RTTypeClass typeClass;
1219 rtl::OString nucleus;
1220 sal_Int32 rank;
1221 std::vector< rtl::OString > args;
1222 codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
1223 manager, type, true, false, false, &typeClass, &nucleus, &rank, &args);
1224 if (rank == 0) {
1225 switch (sort) {
1226 case codemaker::UnoType::SORT_BOOLEAN:
1227 if (any) {
1228 code->instrNew(
1229 rtl::OString(
1230 RTL_CONSTASCII_STRINGPARAM("java/lang/Boolean")));
1231 code->instrDup();
1232 code->loadLocalInteger(*index);
1233 code->instrInvokespecial(
1234 rtl::OString(
1235 RTL_CONSTASCII_STRINGPARAM("java/lang/Boolean")),
1236 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1237 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Z)V")));
1238 stack = 3;
1239 } else {
1240 code->loadLocalInteger(*index);
1241 stack = 1;
1243 size = 1;
1244 break;
1246 case codemaker::UnoType::SORT_BYTE:
1247 if (any) {
1248 code->instrNew(
1249 rtl::OString(
1250 RTL_CONSTASCII_STRINGPARAM("java/lang/Byte")));
1251 code->instrDup();
1252 code->loadLocalInteger(*index);
1253 code->instrInvokespecial(
1254 rtl::OString(
1255 RTL_CONSTASCII_STRINGPARAM("java/lang/Byte")),
1256 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1257 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(B)V")));
1258 stack = 3;
1259 } else {
1260 code->loadLocalInteger(*index);
1261 stack = 1;
1263 size = 1;
1264 break;
1266 case codemaker::UnoType::SORT_SHORT:
1267 if (any) {
1268 code->instrNew(
1269 rtl::OString(
1270 RTL_CONSTASCII_STRINGPARAM("java/lang/Short")));
1271 code->instrDup();
1272 code->loadLocalInteger(*index);
1273 code->instrInvokespecial(
1274 rtl::OString(
1275 RTL_CONSTASCII_STRINGPARAM("java/lang/Short")),
1276 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1277 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(S)V")));
1278 stack = 3;
1279 } else {
1280 code->loadLocalInteger(*index);
1281 stack = 1;
1283 size = 1;
1284 break;
1286 case codemaker::UnoType::SORT_UNSIGNED_SHORT:
1287 if (any) {
1288 code->instrNew(
1289 rtl::OString(
1290 RTL_CONSTASCII_STRINGPARAM(
1291 "com/sun/star/uno/Any")));
1292 code->instrDup();
1293 code->instrGetstatic(
1294 rtl::OString(
1295 RTL_CONSTASCII_STRINGPARAM(
1296 "com/sun/star/uno/Type")),
1297 rtl::OString(
1298 RTL_CONSTASCII_STRINGPARAM("UNSIGNED_SHORT")),
1299 rtl::OString(
1300 RTL_CONSTASCII_STRINGPARAM(
1301 "Lcom/sun/star/uno/Type;")));
1302 code->instrNew(
1303 rtl::OString(
1304 RTL_CONSTASCII_STRINGPARAM("java/lang/Short")));
1305 code->instrDup();
1306 code->loadLocalInteger(*index);
1307 code->instrInvokespecial(
1308 rtl::OString(
1309 RTL_CONSTASCII_STRINGPARAM("java/lang/Short")),
1310 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1311 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(S)V")));
1312 code->instrInvokespecial(
1313 rtl::OString(
1314 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
1315 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1316 rtl::OString(
1317 RTL_CONSTASCII_STRINGPARAM(
1318 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
1319 "V")));
1320 stack = 6;
1321 } else {
1322 code->loadLocalInteger(*index);
1323 stack = 1;
1325 size = 1;
1326 break;
1328 case codemaker::UnoType::SORT_LONG:
1329 if (any) {
1330 code->instrNew(
1331 rtl::OString(
1332 RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")));
1333 code->instrDup();
1334 code->loadLocalInteger(*index);
1335 code->instrInvokespecial(
1336 rtl::OString(
1337 RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")),
1338 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1339 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")));
1340 stack = 3;
1341 } else {
1342 code->loadLocalInteger(*index);
1343 stack = 1;
1345 size = 1;
1346 break;
1348 case codemaker::UnoType::SORT_UNSIGNED_LONG:
1349 if (any) {
1350 code->instrNew(
1351 rtl::OString(
1352 RTL_CONSTASCII_STRINGPARAM(
1353 "com/sun/star/uno/Any")));
1354 code->instrDup();
1355 code->instrGetstatic(
1356 rtl::OString(
1357 RTL_CONSTASCII_STRINGPARAM(
1358 "com/sun/star/uno/Type")),
1359 rtl::OString(
1360 RTL_CONSTASCII_STRINGPARAM("UNSIGNED_LONG")),
1361 rtl::OString(
1362 RTL_CONSTASCII_STRINGPARAM(
1363 "Lcom/sun/star/uno/Type;")));
1364 code->instrNew(
1365 rtl::OString(
1366 RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")));
1367 code->instrDup();
1368 code->loadLocalInteger(*index);
1369 code->instrInvokespecial(
1370 rtl::OString(
1371 RTL_CONSTASCII_STRINGPARAM("java/lang/Integer")),
1372 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1373 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(I)V")));
1374 code->instrInvokespecial(
1375 rtl::OString(
1376 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
1377 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1378 rtl::OString(
1379 RTL_CONSTASCII_STRINGPARAM(
1380 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
1381 "V")));
1382 stack = 6;
1383 } else {
1384 code->loadLocalInteger(*index);
1385 stack = 1;
1387 size = 1;
1388 break;
1390 case codemaker::UnoType::SORT_HYPER:
1391 if (any) {
1392 code->instrNew(
1393 rtl::OString(
1394 RTL_CONSTASCII_STRINGPARAM("java/lang/Long")));
1395 code->instrDup();
1396 code->loadLocalLong(*index);
1397 code->instrInvokespecial(
1398 rtl::OString(
1399 RTL_CONSTASCII_STRINGPARAM("java/lang/Long")),
1400 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1401 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(J)V")));
1402 stack = 4;
1403 } else {
1404 code->loadLocalLong(*index);
1405 stack = 2;
1407 size = 2;
1408 break;
1410 case codemaker::UnoType::SORT_UNSIGNED_HYPER:
1411 if (any) {
1412 code->instrNew(
1413 rtl::OString(
1414 RTL_CONSTASCII_STRINGPARAM(
1415 "com/sun/star/uno/Any")));
1416 code->instrDup();
1417 code->instrGetstatic(
1418 rtl::OString(
1419 RTL_CONSTASCII_STRINGPARAM(
1420 "com/sun/star/uno/Type")),
1421 rtl::OString(
1422 RTL_CONSTASCII_STRINGPARAM("UNSIGNED_HYPER")),
1423 rtl::OString(
1424 RTL_CONSTASCII_STRINGPARAM(
1425 "Lcom/sun/star/uno/Type;")));
1426 code->instrNew(
1427 rtl::OString(
1428 RTL_CONSTASCII_STRINGPARAM("java/lang/Long")));
1429 code->instrDup();
1430 code->loadLocalLong(*index);
1431 code->instrInvokespecial(
1432 rtl::OString(
1433 RTL_CONSTASCII_STRINGPARAM("java/lang/Long")),
1434 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1435 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(J)V")));
1436 code->instrInvokespecial(
1437 rtl::OString(
1438 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
1439 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1440 rtl::OString(
1441 RTL_CONSTASCII_STRINGPARAM(
1442 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
1443 "V")));
1444 stack = 7;
1445 } else {
1446 code->loadLocalLong(*index);
1447 stack = 2;
1449 size = 2;
1450 break;
1452 case codemaker::UnoType::SORT_FLOAT:
1453 if (any) {
1454 code->instrNew(
1455 rtl::OString(
1456 RTL_CONSTASCII_STRINGPARAM("java/lang/Float")));
1457 code->instrDup();
1458 code->loadLocalFloat(*index);
1459 code->instrInvokespecial(
1460 rtl::OString(
1461 RTL_CONSTASCII_STRINGPARAM("java/lang/Float")),
1462 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1463 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(F)V")));
1464 stack = 3;
1465 } else {
1466 code->loadLocalFloat(*index);
1467 stack = 1;
1469 size = 1;
1470 break;
1472 case codemaker::UnoType::SORT_DOUBLE:
1473 if (any) {
1474 code->instrNew(
1475 rtl::OString(
1476 RTL_CONSTASCII_STRINGPARAM("java/lang/Double")));
1477 code->instrDup();
1478 code->loadLocalDouble(*index);
1479 code->instrInvokespecial(
1480 rtl::OString(
1481 RTL_CONSTASCII_STRINGPARAM("java/lang/Double")),
1482 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1483 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(D)V")));
1484 stack = 4;
1485 } else {
1486 code->loadLocalDouble(*index);
1487 stack = 2;
1489 size = 2;
1490 break;
1492 case codemaker::UnoType::SORT_CHAR:
1493 if (any) {
1494 code->instrNew(
1495 rtl::OString(
1496 RTL_CONSTASCII_STRINGPARAM("java/lang/Character")));
1497 code->instrDup();
1498 code->loadLocalInteger(*index);
1499 code->instrInvokespecial(
1500 rtl::OString(
1501 RTL_CONSTASCII_STRINGPARAM("java/lang/Character")),
1502 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1503 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(C)V")));
1504 stack = 3;
1505 } else {
1506 code->loadLocalInteger(*index);
1507 stack = 1;
1509 size = 1;
1510 break;
1512 case codemaker::UnoType::SORT_STRING:
1513 case codemaker::UnoType::SORT_TYPE:
1514 case codemaker::UnoType::SORT_ANY:
1515 code->loadLocalReference(*index);
1516 stack = size = 1;
1517 break;
1519 case codemaker::UnoType::SORT_COMPLEX:
1520 switch (typeClass) {
1521 case RT_TYPE_ENUM:
1522 // Assuming that no Java types are derived from Java types
1523 // that are directly derived from com.sun.star.uno.Enum:
1524 code->loadLocalReference(*index);
1525 stack = size = 1;
1526 break;
1528 case RT_TYPE_STRUCT:
1529 if (any) {
1530 code->instrNew(
1531 rtl::OString(
1532 RTL_CONSTASCII_STRINGPARAM(
1533 "com/sun/star/uno/Any")));
1534 code->instrDup();
1535 code->instrNew(
1536 rtl::OString(
1537 RTL_CONSTASCII_STRINGPARAM(
1538 "com/sun/star/uno/Type")));
1539 code->instrDup();
1540 code->loadStringConstant(
1541 createUnoName(manager, nucleus, rank, args));
1542 code->instrGetstatic(
1543 rtl::OString(
1544 RTL_CONSTASCII_STRINGPARAM(
1545 "com/sun/star/uno/TypeClass")),
1546 rtl::OString(RTL_CONSTASCII_STRINGPARAM("STRUCT")),
1547 rtl::OString(
1548 RTL_CONSTASCII_STRINGPARAM(
1549 "Lcom/sun/star/uno/TypeClass;")));
1550 dependencies->insert(
1551 rtl::OString(
1552 RTL_CONSTASCII_STRINGPARAM(
1553 "com/sun/star/uno/TypeClass")));
1554 code->instrInvokespecial(
1555 rtl::OString(
1556 RTL_CONSTASCII_STRINGPARAM(
1557 "com/sun/star/uno/Type")),
1558 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1559 rtl::OString(
1560 RTL_CONSTASCII_STRINGPARAM(
1561 "(Ljava/lang/String;"
1562 "Lcom/sun/star/uno/TypeClass;)V")));
1563 code->loadLocalReference(*index);
1564 code->instrInvokespecial(
1565 rtl::OString(
1566 RTL_CONSTASCII_STRINGPARAM(
1567 "com/sun/star/uno/Any")),
1568 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1569 rtl::OString(
1570 RTL_CONSTASCII_STRINGPARAM(
1571 "(Lcom/sun/star/uno/Type;"
1572 "Ljava/lang/Object;)V")));
1573 stack = 6;
1574 } else {
1575 code->loadLocalReference(*index);
1576 stack = 1;
1578 size = 1;
1579 break;
1581 case RT_TYPE_INTERFACE:
1582 if (any
1583 && (nucleus
1584 != rtl::OString(
1585 RTL_CONSTASCII_STRINGPARAM(
1586 "com/sun/star/uno/XInterface"))))
1588 code->instrNew(
1589 rtl::OString(
1590 RTL_CONSTASCII_STRINGPARAM(
1591 "com/sun/star/uno/Any")));
1592 code->instrDup();
1593 code->instrNew(
1594 rtl::OString(
1595 RTL_CONSTASCII_STRINGPARAM(
1596 "com/sun/star/uno/Type")));
1597 code->instrDup();
1598 code->loadStringConstant(nucleus.replace('/', '.'));
1599 code->instrGetstatic(
1600 rtl::OString(
1601 RTL_CONSTASCII_STRINGPARAM(
1602 "com/sun/star/uno/TypeClass")),
1603 rtl::OString(
1604 RTL_CONSTASCII_STRINGPARAM("INTERFACE")),
1605 rtl::OString(
1606 RTL_CONSTASCII_STRINGPARAM(
1607 "Lcom/sun/star/uno/TypeClass;")));
1608 dependencies->insert(
1609 rtl::OString(
1610 RTL_CONSTASCII_STRINGPARAM(
1611 "com/sun/star/uno/TypeClass")));
1612 code->instrInvokespecial(
1613 rtl::OString(
1614 RTL_CONSTASCII_STRINGPARAM(
1615 "com/sun/star/uno/Type")),
1616 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1617 rtl::OString(
1618 RTL_CONSTASCII_STRINGPARAM(
1619 "(Ljava/lang/String;"
1620 "Lcom/sun/star/uno/TypeClass;)V")));
1621 code->loadLocalReference(*index);
1622 code->instrInvokespecial(
1623 rtl::OString(
1624 RTL_CONSTASCII_STRINGPARAM(
1625 "com/sun/star/uno/Any")),
1626 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1627 rtl::OString(
1628 RTL_CONSTASCII_STRINGPARAM(
1629 "(Lcom/sun/star/uno/Type;"
1630 "Ljava/lang/Object;)V")));
1631 stack = 6;
1632 } else {
1633 code->loadLocalReference(*index);
1634 stack = 1;
1636 size = 1;
1637 break;
1639 default:
1640 OSL_ASSERT(false);
1641 break;
1643 break;
1645 default:
1646 OSL_ASSERT(false);
1647 break;
1649 } else {
1650 bool wrap = false;
1651 if (any) {
1652 switch (sort) {
1653 case codemaker::UnoType::SORT_BOOLEAN:
1654 case codemaker::UnoType::SORT_BYTE:
1655 case codemaker::UnoType::SORT_SHORT:
1656 case codemaker::UnoType::SORT_LONG:
1657 case codemaker::UnoType::SORT_HYPER:
1658 case codemaker::UnoType::SORT_FLOAT:
1659 case codemaker::UnoType::SORT_DOUBLE:
1660 case codemaker::UnoType::SORT_CHAR:
1661 case codemaker::UnoType::SORT_STRING:
1662 case codemaker::UnoType::SORT_TYPE:
1663 // assuming that no Java types are derived from
1664 // com.sun.star.uno.Type
1665 break;
1667 case codemaker::UnoType::SORT_UNSIGNED_SHORT:
1668 case codemaker::UnoType::SORT_UNSIGNED_LONG:
1669 case codemaker::UnoType::SORT_UNSIGNED_HYPER:
1670 case codemaker::UnoType::SORT_ANY:
1671 wrap = true;
1672 break;
1674 case codemaker::UnoType::SORT_COMPLEX:
1675 switch (typeClass) {
1676 case RT_TYPE_ENUM:
1677 // assuming that no Java types are derived from Java
1678 // types that are directly derived from
1679 // com.sun.star.uno.Enum
1680 break;
1682 case RT_TYPE_STRUCT:
1683 case RT_TYPE_INTERFACE:
1684 wrap = true;
1685 break;
1687 default:
1688 OSL_ASSERT(false);
1689 break;
1691 break;
1693 default:
1694 OSL_ASSERT(false);
1695 break;
1698 if (wrap) {
1699 code->instrNew(
1700 rtl::OString(
1701 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")));
1702 code->instrDup();
1703 code->instrNew(
1704 rtl::OString(
1705 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")));
1706 code->instrDup();
1707 code->loadStringConstant(
1708 createUnoName(manager, nucleus, rank, args));
1709 code->instrInvokespecial(
1710 rtl::OString(
1711 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
1712 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1713 rtl::OString(
1714 RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V")));
1715 code->loadLocalReference(*index);
1716 code->instrInvokespecial(
1717 rtl::OString(
1718 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
1719 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1720 rtl::OString(
1721 RTL_CONSTASCII_STRINGPARAM(
1722 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V")));
1723 stack = 5;
1724 } else {
1725 code->loadLocalReference(*index);
1726 stack = 1;
1728 size = 1;
1731 if (*index > SAL_MAX_UINT16 - size) {
1732 throw CannotDumpException(
1733 rtl::OString(
1734 RTL_CONSTASCII_STRINGPARAM(
1735 "Too many local variables for Java class file format")));
1737 *index = *index + size;
1738 return stack;
1741 void addBaseArguments(
1742 TypeManager const & manager, Dependencies * dependencies,
1743 MethodDescriptor * methodDescriptor, ClassFile::Code * code,
1744 RTTypeClass typeClass, rtl::OString const & type, sal_uInt16 * index)
1746 OSL_ASSERT(
1747 dependencies != 0 && methodDescriptor != 0 && code != 0 && index != 0);
1748 typereg::Reader reader(manager.getTypeReader(type));
1749 if (!reader.isValid() || reader.getTypeClass() != typeClass
1750 || codemaker::convertString(reader.getTypeName()) != type
1751 || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0)
1753 throw CannotDumpException(
1754 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
1755 //TODO
1757 sal_uInt16 superTypes = reader.getSuperTypeCount();
1758 sal_uInt16 fields = reader.getFieldCount();
1759 sal_uInt16 firstField = 0;
1760 if (type
1761 == rtl::OString(
1762 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception")))
1764 if (typeClass != RT_TYPE_EXCEPTION || superTypes != 0 || fields != 2) {
1765 throw CannotDumpException(
1766 rtl::OString(
1767 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1769 firstField = 1;
1770 } else {
1771 if (
1772 (typeClass == RT_TYPE_STRUCT && (superTypes > 1 || fields == 0)) ||
1773 (typeClass == RT_TYPE_EXCEPTION && superTypes != 1)
1776 throw CannotDumpException(
1777 rtl::OString(
1778 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1780 if (superTypes == 1) {
1781 addBaseArguments(
1782 manager, dependencies, methodDescriptor, code, typeClass,
1783 codemaker::convertString(reader.getSuperTypeName(0)), index);
1786 for (sal_uInt16 i = firstField; i < fields; ++i) {
1787 if (reader.getFieldFlags(i) != RT_ACCESS_READWRITE
1788 || reader.getFieldValue(i).m_type != RT_TYPE_NONE)
1790 throw CannotDumpException(
1791 rtl::OString(
1792 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1794 rtl::OString fieldType(
1795 codemaker::convertString(reader.getFieldTypeName(i)));
1796 methodDescriptor->addParameter(fieldType, false, true, 0);
1797 addLoadLocal(
1798 manager, code, index, false, fieldType, false, dependencies);
1802 sal_uInt16 addDirectArgument(
1803 TypeManager const & manager, Dependencies * dependencies,
1804 MethodDescriptor * methodDescriptor, ClassFile::Code * code,
1805 sal_uInt16 * index, rtl::OString const & className,
1806 rtl::OString const & fieldName, bool typeParameter,
1807 rtl::OString const & fieldType)
1809 OSL_ASSERT(
1810 dependencies != 0 && methodDescriptor != 0 && code != 0 && index != 0);
1811 rtl::OString desc;
1812 if (typeParameter) {
1813 methodDescriptor->addTypeParameter(fieldType);
1814 desc = rtl::OString(RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
1815 } else {
1816 methodDescriptor->addParameter(fieldType, false, true, 0);
1817 getFieldDescriptor(manager, dependencies, fieldType, &desc, 0, 0);
1819 code->loadLocalReference(0);
1820 sal_uInt16 stack = addLoadLocal(
1821 manager, code, index, typeParameter, fieldType, false, dependencies);
1822 code->instrPutfield(className, fieldName, desc);
1823 return stack + 1;
1826 void handleAggregatingType(
1827 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
1828 typereg::Reader const & reader, Dependencies * dependencies)
1830 OSL_ASSERT(dependencies != 0);
1831 if (reader.getMethodCount() != 0)
1833 throw CannotDumpException(
1834 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
1835 //TODO
1837 RTTypeClass typeClass = reader.getTypeClass();
1838 rtl::OString className(codemaker::convertString(reader.getTypeName()));
1839 sal_uInt16 superTypes = reader.getSuperTypeCount();
1840 sal_uInt16 fields = reader.getFieldCount();
1841 sal_uInt16 firstField = 0;
1842 sal_uInt16 references = reader.getReferenceCount();
1843 bool runtimeException = false;
1844 rtl::OString superClass;
1845 if (className
1846 == rtl::OString(
1847 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception")))
1849 if (typeClass != RT_TYPE_EXCEPTION || superTypes != 0 || fields != 2
1850 || references != 0)
1852 throw CannotDumpException(
1853 rtl::OString(
1854 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1856 firstField = 1;
1857 superClass = rtl::OString(
1858 RTL_CONSTASCII_STRINGPARAM("java/lang/Exception"));
1859 } else if (className
1860 == rtl::OString(
1861 RTL_CONSTASCII_STRINGPARAM(
1862 "com/sun/star/uno/RuntimeException")))
1864 if (typeClass != RT_TYPE_EXCEPTION || superTypes != 1 || fields != 0
1865 || references != 0)
1867 throw CannotDumpException(
1868 rtl::OString(
1869 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1871 superTypes = 0;
1872 superClass = rtl::OString(
1873 RTL_CONSTASCII_STRINGPARAM("java/lang/RuntimeException"));
1874 runtimeException = true;
1875 } else {
1876 if (
1878 typeClass == RT_TYPE_STRUCT &&
1880 fields == 0 ||
1881 (references == 0 ? superTypes > 1 : superTypes != 0)
1883 ) ||
1884 (typeClass == RT_TYPE_EXCEPTION && superTypes != 1)
1887 throw CannotDumpException(
1888 rtl::OString(
1889 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1891 if (superTypes == 0) {
1892 superClass = rtl::OString(
1893 RTL_CONSTASCII_STRINGPARAM("java/lang/Object"));
1894 } else {
1895 superClass = codemaker::convertString(reader.getSuperTypeName(0));
1896 dependencies->insert(superClass);
1899 rtl::OString sig;
1900 std::map< rtl::OString, sal_Int32 > typeParameters;
1901 if (references != 0) {
1902 rtl::OStringBuffer buf;
1903 buf.append('<');
1904 for (sal_uInt16 i = 0; i < references; ++i) {
1905 if (reader.getReferenceFlags(i) != RT_ACCESS_INVALID
1906 || reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER)
1908 throw CannotDumpException(
1909 rtl::OString(
1910 RTL_CONSTASCII_STRINGPARAM("Bad type information")));
1911 //TODO
1913 rtl::OString name(
1914 codemaker::convertString(reader.getReferenceTypeName(i)));
1915 buf.append(name);
1916 buf.append(RTL_CONSTASCII_STRINGPARAM(":Ljava/lang/Object;"));
1917 if (!typeParameters.insert(
1918 std::map< rtl::OString, sal_Int32 >::value_type(name, i)).
1919 second)
1921 throw CannotDumpException(
1922 rtl::OString(
1923 RTL_CONSTASCII_STRINGPARAM("Bad type information")));
1924 //TODO
1927 buf.append(RTL_CONSTASCII_STRINGPARAM(">Ljava/lang/Object;"));
1928 sig = buf.makeStringAndClear();
1930 std::auto_ptr< ClassFile > cf(
1931 new ClassFile(
1932 static_cast< ClassFile::AccessFlags >(
1933 ClassFile::ACC_PUBLIC | ClassFile::ACC_SUPER),
1934 className, superClass, sig));
1935 std::vector< TypeInfo > typeInfo;
1936 {for (sal_uInt16 i = firstField; i < fields; ++i) {
1937 RTFieldAccess flags = reader.getFieldFlags(i);
1938 if ((flags != RT_ACCESS_READWRITE
1939 && flags != (RT_ACCESS_READWRITE | RT_ACCESS_PARAMETERIZED_TYPE))
1940 || ((flags & RT_ACCESS_PARAMETERIZED_TYPE) != 0 && references == 0)
1941 || reader.getFieldValue(i).m_type != RT_TYPE_NONE)
1943 throw CannotDumpException(
1944 rtl::OString(
1945 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
1947 rtl::OString type(
1948 codemaker::convertString(reader.getFieldTypeName(i)));
1949 sal_Int32 typeParameterIndex;
1950 if ((flags & RT_ACCESS_PARAMETERIZED_TYPE) == 0) {
1951 typeParameterIndex = -1;
1952 } else {
1953 std::map< rtl::OString, sal_Int32 >::iterator it(
1954 typeParameters.find(type));
1955 if (it == typeParameters.end()) {
1956 throw CannotDumpException(
1957 rtl::OString(
1958 RTL_CONSTASCII_STRINGPARAM("Bad type information")));
1959 //TODO
1961 typeParameterIndex = it->second;
1963 addField(
1964 manager, dependencies, cf.get(), &typeInfo, typeParameterIndex,
1965 type, codemaker::convertString(reader.getFieldName(i)), i - firstField);
1967 if (runtimeException) {
1968 addField(
1969 manager, dependencies, cf.get(), &typeInfo, -1,
1970 rtl::OString(
1971 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")),
1972 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), 0);
1974 std::auto_ptr< ClassFile::Code > code(cf->newCode());
1975 code->loadLocalReference(0);
1976 code->instrInvokespecial(
1977 superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
1978 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")));
1979 sal_uInt16 stack = 0;
1980 {for (sal_uInt16 i = firstField; i < fields; ++i) {
1981 stack = std::max(
1982 stack,
1983 addFieldInit(
1984 manager, className,
1985 codemaker::convertString(reader.getFieldName(i)),
1986 (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0,
1987 codemaker::convertString(reader.getFieldTypeName(i)),
1988 dependencies, code.get()));
1990 if (runtimeException) {
1991 stack = std::max(
1992 stack,
1993 addFieldInit(
1994 manager, className,
1995 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false,
1996 rtl::OString(
1997 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")),
1998 dependencies, code.get()));
2000 code->instrReturn();
2001 code->setMaxStackAndLocals(stack + 1, 1);
2002 cf->addMethod(
2003 ClassFile::ACC_PUBLIC,
2004 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2005 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()V")), code.get(),
2006 std::vector< rtl::OString >(), rtl::OString());
2007 if (typeClass == RT_TYPE_EXCEPTION) {
2008 code.reset(cf->newCode());
2009 code->loadLocalReference(0);
2010 code->loadLocalReference(1);
2011 code->instrInvokespecial(
2012 superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2013 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V")));
2014 stack = 0;
2015 for (sal_uInt16 i = firstField; i < fields; ++i) {
2016 stack = std::max(
2017 stack,
2018 addFieldInit(
2019 manager, className,
2020 codemaker::convertString(reader.getFieldName(i)),
2021 ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE)
2022 != 0),
2023 codemaker::convertString(reader.getFieldTypeName(i)),
2024 dependencies, code.get()));
2026 if (runtimeException) {
2027 stack = std::max(
2028 stack,
2029 addFieldInit(
2030 manager, className,
2031 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false,
2032 rtl::OString(
2033 RTL_CONSTASCII_STRINGPARAM(
2034 "com/sun/star/uno/XInterface")),
2035 dependencies, code.get()));
2037 code->instrReturn();
2038 code->setMaxStackAndLocals(stack + 2, 2);
2039 cf->addMethod(
2040 ClassFile::ACC_PUBLIC,
2041 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2042 rtl::OString(RTL_CONSTASCII_STRINGPARAM("(Ljava/lang/String;)V")),
2043 code.get(), std::vector< rtl::OString >(), rtl::OString());
2045 MethodDescriptor desc(
2046 manager, dependencies, rtl::OString(RTL_CONSTASCII_STRINGPARAM("void")),
2047 0, 0);
2048 code.reset(cf->newCode());
2049 code->loadLocalReference(0);
2050 sal_uInt16 index = 1;
2051 if (typeClass == RT_TYPE_EXCEPTION) {
2052 desc.addParameter(
2053 rtl::OString(RTL_CONSTASCII_STRINGPARAM("string")), false, true, 0);
2054 code->loadLocalReference(index++);
2056 if (superTypes != 0) {
2057 addBaseArguments(
2058 manager, dependencies, &desc, code.get(), typeClass, superClass,
2059 &index);
2061 code->instrInvokespecial(
2062 superClass, rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2063 desc.getDescriptor());
2064 sal_uInt16 maxSize = index;
2065 {for (sal_uInt16 i = firstField; i < fields; ++i) {
2066 maxSize = std::max(
2067 maxSize,
2068 addDirectArgument(
2069 manager, dependencies, &desc, code.get(), &index, className,
2070 codemaker::convertString(reader.getFieldName(i)),
2071 (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) != 0,
2072 codemaker::convertString(reader.getFieldTypeName(i))));
2074 if (runtimeException) {
2075 maxSize = std::max(
2076 maxSize,
2077 addDirectArgument(
2078 manager, dependencies, &desc, code.get(), &index, className,
2079 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Context")), false,
2080 rtl::OString(
2081 RTL_CONSTASCII_STRINGPARAM(
2082 "com/sun/star/uno/XInterface"))));
2084 code->instrReturn();
2085 code->setMaxStackAndLocals(maxSize, index);
2086 cf->addMethod(
2087 ClassFile::ACC_PUBLIC,
2088 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2089 desc.getDescriptor(), code.get(), std::vector< rtl::OString >(),
2090 desc.getSignature());
2091 addTypeInfo(className, typeInfo, dependencies, cf.get());
2092 writeClassFile(options, className, *cf.get());
2095 void createExceptionsAttribute(
2096 TypeManager const & manager, typereg::Reader const & reader,
2097 sal_uInt16 methodIndex, Dependencies * dependencies,
2098 std::vector< rtl::OString > * exceptions, codemaker::ExceptionTree * tree)
2100 OSL_ASSERT(dependencies != 0 && exceptions != 0);
2101 sal_uInt16 n = reader.getMethodExceptionCount(methodIndex);
2102 for (sal_uInt16 i = 0; i < n; ++i) {
2103 rtl::OString type(
2104 codemaker::convertString(
2105 reader.getMethodExceptionTypeName(methodIndex, i)));
2106 dependencies->insert(type);
2107 exceptions->push_back(type);
2108 if (tree != 0) {
2109 tree->add(type, manager);
2114 void handleInterfaceType(
2115 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
2116 typereg::Reader const & reader, Dependencies * dependencies)
2118 OSL_ASSERT(dependencies != 0);
2120 rtl::OString className(codemaker::convertString(reader.getTypeName()));
2121 sal_uInt16 superTypes = reader.getSuperTypeCount();
2122 sal_uInt16 fields = reader.getFieldCount();
2123 sal_uInt16 methods = reader.getMethodCount();
2124 if (className
2125 == rtl::OString(
2126 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XInterface")))
2128 if (superTypes != 0 || fields != 0 || methods != 3) {
2129 throw CannotDumpException(
2130 rtl::OString(
2131 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2133 methods = 0;
2134 } else if (superTypes == 0) {
2135 throw CannotDumpException(
2136 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2137 //TODO
2139 std::auto_ptr< ClassFile > cf(
2140 new ClassFile(
2141 static_cast< ClassFile::AccessFlags >(
2142 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
2143 | ClassFile::ACC_ABSTRACT),
2144 className,
2145 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")),
2146 rtl::OString()));
2147 {for (sal_uInt16 i = 0; i < superTypes; ++i) {
2148 rtl::OString t(codemaker::convertString(reader.getSuperTypeName(i)));
2149 dependencies->insert(t);
2150 cf->addInterface(t);
2152 // As a special case, let com.sun.star.lang.XEventListener extend
2153 // java.util.EventListener ("A tagging interface that all event listener
2154 // interfaces must extend"):
2155 if (className ==
2156 rtl::OString(
2157 RTL_CONSTASCII_STRINGPARAM("com/sun/star/lang/XEventListener")))
2159 cf->addInterface(
2160 rtl::OString(
2161 RTL_CONSTASCII_STRINGPARAM("java/util/EventListener")));
2163 std::vector< TypeInfo > typeInfo;
2164 sal_Int32 index = 0;
2165 {for (sal_uInt16 i = 0; i < fields; ++i) {
2166 RTFieldAccess flags = reader.getFieldFlags(i);
2167 //TODO: ok if both READONLY and BOUND?
2168 if (((((flags & RT_ACCESS_READWRITE) != 0)
2169 ^ ((flags & RT_ACCESS_READONLY) != 0))
2170 == 0)
2171 || ((flags
2172 & ~(RT_ACCESS_READWRITE | RT_ACCESS_READONLY
2173 | RT_ACCESS_BOUND))
2174 != 0)
2175 || reader.getFieldValue(i).m_type != RT_TYPE_NONE)
2177 throw CannotDumpException(
2178 rtl::OString(
2179 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2181 //TODO: exploit the fact that attribute getter/setter methods preceed
2182 // real methods
2183 rtl::OUString attrNameUtf16(reader.getFieldName(i));
2184 sal_uInt16 getter = SAL_MAX_UINT16;
2185 sal_uInt16 setter = SAL_MAX_UINT16;
2186 for (sal_uInt16 j = 0; j < methods; ++j) {
2187 RTMethodMode mflags = reader.getMethodFlags(j);
2188 if ((mflags == RT_MODE_ATTRIBUTE_GET
2189 || mflags == RT_MODE_ATTRIBUTE_SET)
2190 && reader.getMethodName(j) == attrNameUtf16)
2192 if (!reader.getMethodReturnTypeName(j).equalsAsciiL(
2193 RTL_CONSTASCII_STRINGPARAM("void"))
2194 || reader.getMethodParameterCount(j) != 0
2195 || (mflags == RT_MODE_ATTRIBUTE_GET
2196 ? getter != SAL_MAX_UINT16
2197 : (setter != SAL_MAX_UINT16
2198 || (flags & RT_ACCESS_READONLY) != 0)))
2200 throw CannotDumpException(
2201 rtl::OString(
2202 RTL_CONSTASCII_STRINGPARAM(
2203 "Bad type information"))); //TODO
2205 OSL_ASSERT(j != SAL_MAX_UINT16);
2206 (mflags == RT_MODE_ATTRIBUTE_GET ? getter : setter) = j;
2209 rtl::OString fieldType(
2210 codemaker::convertString(reader.getFieldTypeName(i)));
2211 SpecialType specialType;
2212 PolymorphicUnoType polymorphicUnoType;
2213 MethodDescriptor gdesc(
2214 manager, dependencies, fieldType, &specialType,
2215 &polymorphicUnoType);
2216 std::vector< rtl::OString > exc;
2217 if (getter != SAL_MAX_UINT16) {
2218 createExceptionsAttribute(
2219 manager, reader, getter, dependencies, &exc, 0);
2221 rtl::OString attrName(codemaker::convertString(attrNameUtf16));
2222 cf->addMethod(
2223 static_cast< ClassFile::AccessFlags >(
2224 ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
2225 rtl::OString(RTL_CONSTASCII_STRINGPARAM("get")) + attrName,
2226 gdesc.getDescriptor(), 0, exc, gdesc.getSignature());
2227 if ((flags & RT_ACCESS_READONLY) == 0) {
2228 MethodDescriptor sdesc(
2229 manager, dependencies,
2230 rtl::OString(RTL_CONSTASCII_STRINGPARAM("void")), 0, 0);
2231 sdesc.addParameter(fieldType, false, true, 0);
2232 std::vector< rtl::OString > exc2;
2233 if (setter != SAL_MAX_UINT16) {
2234 createExceptionsAttribute(
2235 manager, reader, setter, dependencies, &exc2, 0);
2237 cf->addMethod(
2238 static_cast< ClassFile::AccessFlags >(
2239 ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
2240 rtl::OString(RTL_CONSTASCII_STRINGPARAM("set")) + attrName,
2241 sdesc.getDescriptor(), 0, exc2, sdesc.getSignature());
2243 typeInfo.push_back(
2244 TypeInfo(
2245 TypeInfo::KIND_ATTRIBUTE, attrName, specialType,
2246 static_cast< TypeInfo::Flags >(
2247 ((flags & RT_ACCESS_READONLY) == 0
2248 ? 0 : TypeInfo::FLAG_READONLY)
2249 | ((flags & RT_ACCESS_BOUND) == 0
2250 ? 0 : TypeInfo::FLAG_BOUND)),
2251 index, polymorphicUnoType));
2252 index += ((flags & RT_ACCESS_READONLY) == 0 ? 2 : 1);
2254 {for (sal_uInt16 i = 0; i < methods; ++i) {
2255 RTMethodMode flags = reader.getMethodFlags(i);
2256 switch (flags) {
2257 case RT_MODE_ONEWAY:
2258 case RT_MODE_TWOWAY:
2260 rtl::OString methodName(
2261 codemaker::convertString(reader.getMethodName(i)));
2262 SpecialType specialReturnType;
2263 PolymorphicUnoType polymorphicUnoReturnType;
2264 MethodDescriptor desc(
2265 manager, dependencies,
2266 codemaker::convertString(
2267 reader.getMethodReturnTypeName(i)),
2268 &specialReturnType, &polymorphicUnoReturnType);
2269 typeInfo.push_back(
2270 TypeInfo(
2271 TypeInfo::KIND_METHOD, methodName, specialReturnType,
2272 static_cast< TypeInfo::Flags >(
2273 flags == RT_MODE_ONEWAY
2274 ? TypeInfo::FLAG_ONEWAY : 0),
2275 index++, polymorphicUnoReturnType));
2276 for (sal_uInt16 j = 0; j < reader.getMethodParameterCount(i);
2277 ++j)
2279 bool in;
2280 bool out;
2281 switch (reader.getMethodParameterFlags(i, j)) {
2282 case RT_PARAM_IN:
2283 in = true;
2284 out = false;
2285 break;
2287 case RT_PARAM_OUT:
2288 in = false;
2289 out = true;
2290 break;
2292 case RT_PARAM_INOUT:
2293 in = true;
2294 out = true;
2295 break;
2297 default:
2298 throw CannotDumpException(
2299 rtl::OString(
2300 RTL_CONSTASCII_STRINGPARAM(
2301 "Bad type information"))); //TODO
2303 PolymorphicUnoType polymorphicUnoType;
2304 SpecialType specialType = desc.addParameter(
2305 codemaker::convertString(
2306 reader.getMethodParameterTypeName(i, j)),
2307 out, true, &polymorphicUnoType);
2308 if (out || isSpecialType(specialType)
2309 || (polymorphicUnoType.kind
2310 != PolymorphicUnoType::KIND_NONE))
2312 typeInfo.push_back(
2313 TypeInfo(
2314 codemaker::convertString(
2315 reader.getMethodParameterName(i, j)),
2316 specialType, in, out, methodName, j,
2317 polymorphicUnoType));
2320 std::vector< rtl::OString > exc2;
2321 createExceptionsAttribute(
2322 manager, reader, i, dependencies, &exc2, 0);
2323 cf->addMethod(
2324 static_cast< ClassFile::AccessFlags >(
2325 ClassFile::ACC_PUBLIC | ClassFile::ACC_ABSTRACT),
2326 methodName, desc.getDescriptor(), 0, exc2,
2327 desc.getSignature());
2328 break;
2331 case RT_MODE_ATTRIBUTE_GET:
2332 case RT_MODE_ATTRIBUTE_SET:
2334 //TODO: exploit the fact that attribute getter/setter methods
2335 // are ordered the same way as the attribute fields themselves
2336 rtl::OUString methodNameUtf16(reader.getMethodName(i));
2337 bool found = false;
2338 for (sal_uInt16 j = 0; j < fields; ++j) {
2339 if (reader.getFieldName(j) == methodNameUtf16) {
2340 found = true;
2341 break;
2344 if (found) {
2345 break;
2348 default:
2349 throw CannotDumpException(
2350 rtl::OString(
2351 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2354 addTypeInfo(className, typeInfo, dependencies, cf.get());
2355 writeClassFile(options, className, *cf.get());
2358 void handleTypedef(
2359 TypeManager const & manager, JavaOptions /*TODO const*/ &,
2360 typereg::Reader const & reader, Dependencies * dependencies)
2362 OSL_ASSERT(dependencies != 0);
2363 if (reader.getSuperTypeCount() != 1 || reader.getFieldCount() != 0
2364 || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0)
2366 throw CannotDumpException(
2367 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2368 //TODO
2370 RTTypeClass typeClass;
2371 rtl::OString nucleus;
2372 sal_Int32 rank;
2373 std::vector< rtl::OString > args;
2374 if (codemaker::decomposeAndResolve(
2375 manager, codemaker::convertString(reader.getSuperTypeName(0)),
2376 false, false, false, &typeClass, &nucleus, &rank, &args)
2377 == codemaker::UnoType::SORT_COMPLEX)
2379 switch (typeClass) {
2380 case RT_TYPE_STRUCT:
2381 if (!args.empty()) {
2382 throw CannotDumpException(
2383 rtl::OString(
2384 RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2385 //TODO
2387 case RT_TYPE_ENUM:
2388 case RT_TYPE_INTERFACE:
2389 case RT_TYPE_TYPEDEF:
2390 dependencies->insert(nucleus);
2391 break;
2393 default:
2394 OSL_ASSERT(false);
2395 break;
2400 void addConstant(
2401 TypeManager const & manager, typereg::Reader const & reader,
2402 bool publishable, sal_uInt16 index, Dependencies * dependencies,
2403 ClassFile * classFile)
2405 OSL_ASSERT(dependencies != 0 && classFile != 0);
2406 RTFieldAccess flags = reader.getFieldFlags(index);
2407 if (flags != RT_ACCESS_CONST
2408 && (!publishable || flags != (RT_ACCESS_CONST | RT_ACCESS_PUBLISHED)))
2410 throw CannotDumpException(
2411 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2412 //TODO
2414 RTConstValue fieldValue(reader.getFieldValue(index));
2415 sal_uInt16 valueIndex;
2416 RTTypeClass typeClass;
2417 rtl::OString nucleus;
2418 sal_Int32 rank;
2419 std::vector< rtl::OString > args;
2420 switch (codemaker::decomposeAndResolve(
2421 manager,
2422 codemaker::convertString(reader.getFieldTypeName(index)),
2423 true, false, false, &typeClass, &nucleus, &rank, &args))
2425 case codemaker::UnoType::SORT_BOOLEAN:
2426 if (fieldValue.m_type != RT_TYPE_BOOL) {
2427 throw CannotDumpException(
2428 rtl::OString(
2429 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2431 valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aBool);
2432 break;
2434 case codemaker::UnoType::SORT_BYTE:
2435 if (fieldValue.m_type != RT_TYPE_BYTE) {
2436 throw CannotDumpException(
2437 rtl::OString(
2438 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2440 valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aByte);
2441 break;
2443 case codemaker::UnoType::SORT_SHORT:
2444 if (fieldValue.m_type != RT_TYPE_INT16) {
2445 throw CannotDumpException(
2446 rtl::OString(
2447 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2449 valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aShort);
2450 break;
2452 case codemaker::UnoType::SORT_UNSIGNED_SHORT:
2453 case codemaker::UnoType::SORT_CHAR:
2454 if (fieldValue.m_type != RT_TYPE_UINT16) {
2455 throw CannotDumpException(
2456 rtl::OString(
2457 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2459 valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aUShort);
2460 break;
2462 case codemaker::UnoType::SORT_LONG:
2463 if (fieldValue.m_type != RT_TYPE_INT32) {
2464 throw CannotDumpException(
2465 rtl::OString(
2466 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2468 valueIndex = classFile->addIntegerInfo(fieldValue.m_value.aLong);
2469 break;
2471 case codemaker::UnoType::SORT_UNSIGNED_LONG:
2472 if (fieldValue.m_type != RT_TYPE_UINT32) {
2473 throw CannotDumpException(
2474 rtl::OString(
2475 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2477 valueIndex = classFile->addIntegerInfo(
2478 static_cast< sal_Int32 >(fieldValue.m_value.aULong));
2479 break;
2481 case codemaker::UnoType::SORT_HYPER:
2482 if (fieldValue.m_type != RT_TYPE_INT64) {
2483 throw CannotDumpException(
2484 rtl::OString(
2485 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2487 valueIndex = classFile->addLongInfo(fieldValue.m_value.aHyper);
2488 break;
2490 case codemaker::UnoType::SORT_UNSIGNED_HYPER:
2491 if (fieldValue.m_type != RT_TYPE_UINT64) {
2492 throw CannotDumpException(
2493 rtl::OString(
2494 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2496 valueIndex = classFile->addLongInfo(
2497 static_cast< sal_Int64 >(fieldValue.m_value.aUHyper));
2498 break;
2500 case codemaker::UnoType::SORT_FLOAT:
2501 if (fieldValue.m_type != RT_TYPE_FLOAT) {
2502 throw CannotDumpException(
2503 rtl::OString(
2504 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2506 valueIndex = classFile->addFloatInfo(fieldValue.m_value.aFloat);
2507 break;
2509 case codemaker::UnoType::SORT_DOUBLE:
2510 if (fieldValue.m_type != RT_TYPE_DOUBLE) {
2511 throw CannotDumpException(
2512 rtl::OString(
2513 RTL_CONSTASCII_STRINGPARAM("Bad type information"))); //TODO
2515 valueIndex = classFile->addDoubleInfo(fieldValue.m_value.aDouble);
2516 break;
2518 default:
2519 throw CannotDumpException(
2520 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2521 //TODO
2523 rtl::OString desc;
2524 rtl::OString sig;
2525 getFieldDescriptor(
2526 manager, dependencies,
2527 codemaker::convertString(reader.getFieldTypeName(index)),
2528 &desc, &sig, 0);
2529 classFile->addField(
2530 static_cast< ClassFile::AccessFlags >(
2531 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC
2532 | ClassFile::ACC_FINAL),
2533 codemaker::convertString(reader.getFieldName(index)),
2534 desc, valueIndex, sig);
2537 void handleConstantGroup(
2538 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
2539 typereg::Reader const & reader, Dependencies * dependencies)
2541 OSL_ASSERT(dependencies != 0);
2542 if (reader.getSuperTypeCount() != 0 || reader.getMethodCount() != 0
2543 || reader.getReferenceCount() != 0)
2545 throw CannotDumpException(
2546 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2547 //TODO
2549 rtl::OString className(codemaker::convertString(reader.getTypeName()));
2550 std::auto_ptr< ClassFile > cf(
2551 new ClassFile(
2552 static_cast< ClassFile::AccessFlags >(
2553 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
2554 | ClassFile::ACC_ABSTRACT),
2555 className,
2556 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")),
2557 rtl::OString()));
2558 sal_uInt16 fields = reader.getFieldCount();
2559 for (sal_uInt16 i = 0; i < fields; ++i) {
2560 addConstant(manager, reader, false, i, dependencies, cf.get());
2562 writeClassFile(options, className, *cf.get());
2565 void handleModule(
2566 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
2567 typereg::Reader const & reader, Dependencies * dependencies)
2569 OSL_ASSERT(dependencies != 0);
2570 if (reader.getSuperTypeCount() != 0 || reader.getMethodCount() != 0
2571 || reader.getReferenceCount() != 0)
2573 throw CannotDumpException(
2574 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2575 //TODO
2577 rtl::OStringBuffer buf(codemaker::convertString(reader.getTypeName()));
2578 buf.append('/');
2579 rtl::OString prefix(buf.makeStringAndClear());
2580 sal_uInt16 fields = reader.getFieldCount();
2581 for (sal_uInt16 i = 0; i < fields; ++i) {
2582 rtl::OString className(
2583 prefix + codemaker::convertString(reader.getFieldName(i)));
2584 std::auto_ptr< ClassFile > cf(
2585 new ClassFile(
2586 static_cast< ClassFile::AccessFlags >(
2587 ClassFile::ACC_PUBLIC | ClassFile::ACC_INTERFACE
2588 | ClassFile::ACC_ABSTRACT),
2589 className,
2590 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")),
2591 rtl::OString()));
2592 addConstant(manager, reader, true, i, dependencies, cf.get());
2593 writeClassFile(options, className, *cf.get());
2597 void addExceptionHandlers(
2598 codemaker::ExceptionTreeNode const * node,
2599 ClassFile::Code::Position start, ClassFile::Code::Position end,
2600 ClassFile::Code::Position handler, ClassFile::Code * code)
2602 OSL_ASSERT(node != 0 && code != 0);
2603 if (node->present) {
2604 code->addException(start, end, handler, node->name);
2605 } else {
2606 for (codemaker::ExceptionTreeNode::Children::const_iterator i(
2607 node->children.begin());
2608 i != node->children.end(); ++i)
2610 addExceptionHandlers(*i, start, end, handler, code);
2615 void addConstructor(
2616 TypeManager const & manager, rtl::OString const & realJavaBaseName,
2617 rtl::OString const & unoName, rtl::OString const & className,
2618 typereg::Reader const & reader, sal_uInt16 methodIndex,
2619 rtl::OString const & methodName, rtl::OString const & returnType,
2620 bool defaultConstructor, Dependencies * dependencies, ClassFile * classFile)
2622 OSL_ASSERT(dependencies != 0 && classFile != 0);
2623 MethodDescriptor desc(manager, dependencies, returnType, 0, 0);
2624 desc.addParameter(
2625 rtl::OString(
2626 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")),
2627 false, false, 0);
2628 std::auto_ptr< ClassFile::Code > code(classFile->newCode());
2629 code->loadLocalReference(0);
2630 // stack: context
2631 code->instrInvokestatic(
2632 className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("$getFactory")),
2633 rtl::OString(
2634 RTL_CONSTASCII_STRINGPARAM(
2635 "(Lcom/sun/star/uno/XComponentContext;)"
2636 "Lcom/sun/star/lang/XMultiComponentFactory;")));
2637 // stack: factory
2638 code->loadStringConstant(unoName);
2639 // stack: factory serviceName
2640 codemaker::ExceptionTree tree;
2641 ClassFile::Code::Position tryStart;
2642 ClassFile::Code::Position tryEnd;
2643 std::vector< rtl::OString > exc;
2644 sal_uInt16 stack;
2645 sal_uInt16 localIndex = 1;
2646 ClassFile::AccessFlags access = static_cast< ClassFile::AccessFlags >(
2647 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC);
2648 if (defaultConstructor) {
2649 code->loadLocalReference(0);
2650 // stack: factory serviceName context
2651 tryStart = code->getPosition();
2652 code->instrInvokeinterface(
2653 rtl::OString(
2654 RTL_CONSTASCII_STRINGPARAM(
2655 "com/sun/star/lang/XMultiComponentFactory")),
2656 rtl::OString(
2657 RTL_CONSTASCII_STRINGPARAM(
2658 "createInstanceWithContext")),
2659 rtl::OString(
2660 RTL_CONSTASCII_STRINGPARAM(
2661 "(Ljava/lang/String;Lcom/sun/star/uno/XComponentContext;)"
2662 "Ljava/lang/Object;")),
2664 tryEnd = code->getPosition();
2665 // stack: instance
2666 stack = 3;
2667 } else {
2668 sal_uInt16 parameters = reader.getMethodParameterCount(methodIndex);
2669 if (parameters == 1
2670 && (reader.getMethodParameterFlags(methodIndex, 0)
2671 == (RT_PARAM_IN | RT_PARAM_REST))
2672 && (reader.getMethodParameterTypeName(methodIndex, 0)
2673 == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any"))))
2675 desc.addParameter(
2676 rtl::OString(RTL_CONSTASCII_STRINGPARAM("any")), true, true, 0);
2677 code->loadLocalReference(localIndex++);
2678 // stack: factory serviceName args
2679 stack = 4;
2680 access = static_cast< ClassFile::AccessFlags >(
2681 access | ClassFile::ACC_VARARGS);
2682 } else {
2683 code->loadIntegerConstant(parameters);
2684 // stack: factory serviceName N
2685 code->instrAnewarray(
2686 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")));
2687 // stack: factory serviceName args
2688 stack = 0;
2689 for (sal_uInt16 i = 0; i < parameters; ++i) {
2690 RTParamMode flags = reader.getMethodParameterFlags(
2691 methodIndex, i);
2692 rtl::OString paramType(
2693 codemaker::convertString(
2694 reader.getMethodParameterTypeName(methodIndex, i)));
2695 if ((flags != RT_PARAM_IN
2696 && flags != (RT_PARAM_IN | RT_PARAM_REST))
2697 || ((flags & RT_PARAM_REST) != 0
2698 && (parameters != 1
2699 || (paramType
2700 != rtl::OString(
2701 RTL_CONSTASCII_STRINGPARAM("any"))))))
2703 throw CannotDumpException(
2704 rtl::OString(
2705 RTL_CONSTASCII_STRINGPARAM(
2706 "Bad type information"))); //TODO
2708 desc.addParameter(paramType, false, true, 0);
2709 code->instrDup();
2710 // stack: factory serviceName args args
2711 code->loadIntegerConstant(i);
2712 // stack: factory serviceName args args i
2713 stack = std::max(
2714 stack,
2715 addLoadLocal(
2716 manager, code.get(), &localIndex, false, paramType,
2717 true, dependencies));
2718 // stack: factory serviceName args args i any
2719 code->instrAastore();
2720 // stack: factory serviceName args
2722 stack += 5;
2724 code->loadLocalReference(0);
2725 // stack: factory serviceName args context
2726 tryStart = code->getPosition();
2727 code->instrInvokeinterface(
2728 rtl::OString(
2729 RTL_CONSTASCII_STRINGPARAM(
2730 "com/sun/star/lang/XMultiComponentFactory")),
2731 rtl::OString(
2732 RTL_CONSTASCII_STRINGPARAM(
2733 "createInstanceWithArgumentsAndContext")),
2734 rtl::OString(
2735 RTL_CONSTASCII_STRINGPARAM(
2736 "(Ljava/lang/String;[Ljava/lang/Object;"
2737 "Lcom/sun/star/uno/XComponentContext;)Ljava/lang/Object;")),
2739 tryEnd = code->getPosition();
2740 // stack: instance
2741 createExceptionsAttribute(
2742 manager, reader, methodIndex, dependencies, &exc, &tree);
2744 code->loadLocalReference(0);
2745 // stack: instance context
2746 code->instrInvokestatic(
2747 className, rtl::OString(RTL_CONSTASCII_STRINGPARAM("$castInstance")),
2748 rtl::OString(
2749 RTL_CONSTASCII_STRINGPARAM(
2750 "(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
2751 "Ljava/lang/Object;")));
2752 // stack: instance
2753 code->instrCheckcast(returnType);
2754 // stack: instance
2755 code->instrAreturn();
2756 if (!tree.getRoot()->present) {
2757 ClassFile::Code::Position pos1 = code->getPosition();
2758 // stack: e
2759 code->instrInvokevirtual(
2760 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Throwable")),
2761 rtl::OString(RTL_CONSTASCII_STRINGPARAM("toString")),
2762 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Ljava/lang/String;")));
2763 // stack: str
2764 localIndex = std::max< sal_uInt16 >(localIndex, 2);
2765 code->storeLocalReference(1);
2766 // stack: -
2767 code->instrNew(
2768 rtl::OString(
2769 RTL_CONSTASCII_STRINGPARAM(
2770 "com/sun/star/uno/DeploymentException")));
2771 // stack: ex
2772 code->instrDup();
2773 // stack: ex ex
2774 rtl::OStringBuffer msg;
2775 msg.append(
2776 RTL_CONSTASCII_STRINGPARAM(
2777 "component context fails to supply service "));
2778 msg.append(unoName);
2779 msg.append(RTL_CONSTASCII_STRINGPARAM(" of type "));
2780 msg.append(realJavaBaseName);
2781 msg.append(RTL_CONSTASCII_STRINGPARAM(": "));
2782 code->loadStringConstant(msg.makeStringAndClear());
2783 // stack: ex ex "..."
2784 code->loadLocalReference(1);
2785 // stack: ex ex "..." str
2786 code->instrInvokevirtual(
2787 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/String")),
2788 rtl::OString(RTL_CONSTASCII_STRINGPARAM("concat")),
2789 rtl::OString(
2790 RTL_CONSTASCII_STRINGPARAM(
2791 "(Ljava/lang/String;)Ljava/lang/String;")));
2792 // stack: ex ex "..."
2793 code->loadLocalReference(0);
2794 // stack: ex ex "..." context
2795 code->instrInvokespecial(
2796 rtl::OString(
2797 RTL_CONSTASCII_STRINGPARAM(
2798 "com/sun/star/uno/DeploymentException")),
2799 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2800 rtl::OString(
2801 RTL_CONSTASCII_STRINGPARAM(
2802 "(Ljava/lang/String;Ljava/lang/Object;)V")));
2803 // stack: ex
2804 ClassFile::Code::Position pos2 = code->getPosition();
2805 code->instrAthrow();
2806 addExceptionHandlers(
2807 tree.getRoot(), tryStart, tryEnd, pos2, code.get());
2808 code->addException(
2809 tryStart, tryEnd, pos1,
2810 rtl::OString(
2811 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception")));
2812 dependencies->insert(
2813 rtl::OString(
2814 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Exception")));
2815 stack = std::max< sal_uInt16 >(stack, 4);
2817 code->setMaxStackAndLocals(stack, localIndex);
2818 classFile->addMethod(
2819 access, methodName, desc.getDescriptor(), code.get(), exc,
2820 desc.getSignature());
2823 void handleService(
2824 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
2825 typereg::Reader const & reader, Dependencies * dependencies)
2827 OSL_ASSERT(dependencies != 0);
2828 sal_uInt16 superTypes = reader.getSuperTypeCount();
2829 sal_uInt16 methods = reader.getMethodCount();
2830 if (superTypes == 0
2831 ? methods != 0
2832 : (superTypes != 1 || reader.getFieldCount() != 0
2833 || reader.getReferenceCount() != 0))
2835 throw CannotDumpException(
2836 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2837 //TODO
2839 if (superTypes == 0) {
2840 return;
2842 rtl::OString unoName(codemaker::convertString(reader.getTypeName()));
2843 rtl::OString className(
2844 translateUnoTypeToJavaFullyQualifiedName(
2845 unoName, rtl::OString(RTL_CONSTASCII_STRINGPARAM("service"))));
2846 unoName = unoName.replace('/', '.');
2847 std::auto_ptr< ClassFile > cf(
2848 new ClassFile(
2849 static_cast< ClassFile::AccessFlags >(
2850 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
2851 | ClassFile::ACC_SUPER),
2852 className,
2853 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")),
2854 rtl::OString()));
2855 if (methods > 0) {
2856 rtl::OString base(codemaker::convertString(
2857 reader.getSuperTypeName(0)));
2858 rtl::OString realJavaBaseName(base.replace('/', '.'));
2859 dependencies->insert(base);
2860 dependencies->insert(
2861 rtl::OString(
2862 RTL_CONSTASCII_STRINGPARAM(
2863 "com/sun/star/lang/XMultiComponentFactory")));
2864 dependencies->insert(
2865 rtl::OString(
2866 RTL_CONSTASCII_STRINGPARAM(
2867 "com/sun/star/uno/DeploymentException")));
2868 dependencies->insert(
2869 rtl::OString(
2870 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")));
2871 dependencies->insert(
2872 rtl::OString(
2873 RTL_CONSTASCII_STRINGPARAM(
2874 "com/sun/star/uno/XComponentContext")));
2875 for (sal_uInt16 i = 0; i < methods; ++i) {
2876 rtl::OString name(codemaker::convertString(
2877 reader.getMethodName(i)));
2878 bool defaultCtor = name.getLength() == 0;
2879 if (reader.getMethodFlags(i) != RT_MODE_TWOWAY
2880 || (!reader.getMethodReturnTypeName(i).equalsAsciiL(
2881 RTL_CONSTASCII_STRINGPARAM("void")))
2882 || (defaultCtor
2883 && (methods != 1 || reader.getMethodParameterCount(i) != 0
2884 || reader.getMethodExceptionCount(i) != 0)))
2886 throw CannotDumpException(
2887 rtl::OString(
2888 RTL_CONSTASCII_STRINGPARAM("Bad type information")));
2889 //TODO
2891 if (defaultCtor) {
2892 name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("create"));
2893 } else {
2894 name = codemaker::java::translateUnoToJavaIdentifier(
2895 name, rtl::OString(RTL_CONSTASCII_STRINGPARAM("method")));
2897 addConstructor(
2898 manager, realJavaBaseName, unoName, className, reader, i, name,
2899 base, defaultCtor, dependencies, cf.get());
2901 // Synthetic getFactory method:
2903 std::auto_ptr< ClassFile::Code > code(cf->newCode());
2904 code->loadLocalReference(0);
2905 // stack: context
2906 code->instrInvokeinterface(
2907 rtl::OString(
2908 RTL_CONSTASCII_STRINGPARAM(
2909 "com/sun/star/uno/XComponentContext")),
2910 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getServiceManager")),
2911 rtl::OString(
2912 RTL_CONSTASCII_STRINGPARAM(
2913 "()Lcom/sun/star/lang/XMultiComponentFactory;")),
2915 // stack: factory
2916 code->instrDup();
2917 // stack: factory factory
2918 ClassFile::Code::Branch branch = code->instrIfnull();
2919 // stack: factory
2920 code->instrAreturn();
2921 code->branchHere(branch);
2922 code->instrPop();
2923 // stack: -
2924 code->instrNew(
2925 rtl::OString(
2926 RTL_CONSTASCII_STRINGPARAM(
2927 "com/sun/star/uno/DeploymentException")));
2928 // stack: ex
2929 code->instrDup();
2930 // stack: ex ex
2931 code->loadStringConstant(
2932 rtl::OString(
2933 RTL_CONSTASCII_STRINGPARAM(
2934 "component context fails to supply service manager")));
2935 // stack: ex ex "..."
2936 code->loadLocalReference(0);
2937 // stack: ex ex "..." context
2938 code->instrInvokespecial(
2939 rtl::OString(
2940 RTL_CONSTASCII_STRINGPARAM(
2941 "com/sun/star/uno/DeploymentException")),
2942 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2943 rtl::OString(
2944 RTL_CONSTASCII_STRINGPARAM(
2945 "(Ljava/lang/String;Ljava/lang/Object;)V")));
2946 // stack: ex
2947 code->instrAthrow();
2948 code->setMaxStackAndLocals(4, 1);
2949 cf->addMethod(
2950 static_cast< ClassFile::AccessFlags >(
2951 ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC
2952 | ClassFile::ACC_SYNTHETIC),
2953 rtl::OString(RTL_CONSTASCII_STRINGPARAM("$getFactory")),
2954 rtl::OString(
2955 RTL_CONSTASCII_STRINGPARAM(
2956 "(Lcom/sun/star/uno/XComponentContext;)"
2957 "Lcom/sun/star/lang/XMultiComponentFactory;")),
2958 code.get(), std::vector< rtl::OString >(), rtl::OString());
2960 // Synthetic castInstance method:
2962 std::auto_ptr< ClassFile::Code > code(cf->newCode());
2963 code->instrNew(
2964 rtl::OString(
2965 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")));
2966 // stack: type
2967 code->instrDup();
2968 // stack: type type
2969 code->loadStringConstant(realJavaBaseName);
2970 // stack: type type "..."
2971 code->instrGetstatic(
2972 rtl::OString(
2973 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")),
2974 rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")),
2975 rtl::OString(
2976 RTL_CONSTASCII_STRINGPARAM(
2977 "Lcom/sun/star/uno/TypeClass;")));
2978 // stack: type type "..." INTERFACE
2979 code->instrInvokespecial(
2980 rtl::OString(
2981 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
2982 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
2983 rtl::OString(
2984 RTL_CONSTASCII_STRINGPARAM(
2985 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V")));
2986 // stack: type
2987 code->loadLocalReference(0);
2988 // stack: type instance
2989 code->instrInvokestatic(
2990 rtl::OString(
2991 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/UnoRuntime")),
2992 rtl::OString(RTL_CONSTASCII_STRINGPARAM("queryInterface")),
2993 rtl::OString(
2994 RTL_CONSTASCII_STRINGPARAM(
2995 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
2996 "Ljava/lang/Object;")));
2997 // stack: instance
2998 code->instrDup();
2999 // stack: instance instance
3000 ClassFile::Code::Branch branch = code->instrIfnull();
3001 // stack: instance
3002 code->instrAreturn();
3003 code->branchHere(branch);
3004 code->instrPop();
3005 // stack: -
3006 code->instrNew(
3007 rtl::OString(
3008 RTL_CONSTASCII_STRINGPARAM(
3009 "com/sun/star/uno/DeploymentException")));
3010 // stack: ex
3011 code->instrDup();
3012 // stack: ex ex
3013 rtl::OStringBuffer msg;
3014 msg.append(
3015 RTL_CONSTASCII_STRINGPARAM(
3016 "component context fails to supply service "));
3017 msg.append(unoName);
3018 msg.append(RTL_CONSTASCII_STRINGPARAM(" of type "));
3019 msg.append(realJavaBaseName);
3020 code->loadStringConstant(msg.makeStringAndClear());
3021 // stack: ex ex "..."
3022 code->loadLocalReference(1);
3023 // stack: ex ex "..." context
3024 code->instrInvokespecial(
3025 rtl::OString(
3026 RTL_CONSTASCII_STRINGPARAM(
3027 "com/sun/star/uno/DeploymentException")),
3028 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
3029 rtl::OString(
3030 RTL_CONSTASCII_STRINGPARAM(
3031 "(Ljava/lang/String;Ljava/lang/Object;)V")));
3032 // stack: ex
3033 code->instrAthrow();
3034 code->setMaxStackAndLocals(4, 2);
3035 cf->addMethod(
3036 static_cast< ClassFile::AccessFlags >(
3037 ClassFile::ACC_PRIVATE | ClassFile::ACC_STATIC
3038 | ClassFile::ACC_SYNTHETIC),
3039 rtl::OString(RTL_CONSTASCII_STRINGPARAM("$castInstance")),
3040 rtl::OString(
3041 RTL_CONSTASCII_STRINGPARAM(
3042 "(Ljava/lang/Object;Lcom/sun/star/uno/"
3043 "XComponentContext;)Ljava/lang/Object;")),
3044 code.get(), std::vector< rtl::OString >(), rtl::OString());
3047 writeClassFile(options, className, *cf.get());
3050 void handleSingleton(
3051 TypeManager const & manager, JavaOptions /*TODO const*/ & options,
3052 typereg::Reader const & reader, Dependencies * dependencies)
3054 OSL_ASSERT(dependencies != 0);
3055 if (reader.getSuperTypeCount() != 1 || reader.getFieldCount() != 0
3056 || reader.getMethodCount() != 0 || reader.getReferenceCount() != 0)
3058 throw CannotDumpException(
3059 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
3060 //TODO
3062 rtl::OString base(codemaker::convertString(reader.getSuperTypeName(0)));
3063 rtl::OString realJavaBaseName(base.replace('/', '.'));
3064 switch (manager.getTypeReader(base).getTypeClass()) {
3065 case RT_TYPE_INTERFACE:
3066 break;
3068 case RT_TYPE_SERVICE:
3069 return;
3071 default:
3072 throw CannotDumpException(
3073 rtl::OString(RTL_CONSTASCII_STRINGPARAM("Bad type information")));
3074 //TODO
3076 dependencies->insert(base);
3077 rtl::OString unoName(codemaker::convertString(reader.getTypeName()));
3078 rtl::OString className(
3079 translateUnoTypeToJavaFullyQualifiedName(
3080 unoName, rtl::OString(RTL_CONSTASCII_STRINGPARAM("singleton"))));
3081 unoName = unoName.replace('/', '.');
3082 dependencies->insert(
3083 rtl::OString(
3084 RTL_CONSTASCII_STRINGPARAM(
3085 "com/sun/star/uno/DeploymentException")));
3086 dependencies->insert(
3087 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")));
3088 dependencies->insert(
3089 rtl::OString(
3090 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")));
3091 std::auto_ptr< ClassFile > cf(
3092 new ClassFile(
3093 static_cast< ClassFile::AccessFlags >(
3094 ClassFile::ACC_PUBLIC | ClassFile::ACC_FINAL
3095 | ClassFile::ACC_SUPER),
3096 className,
3097 rtl::OString(RTL_CONSTASCII_STRINGPARAM("java/lang/Object")),
3098 rtl::OString()));
3099 MethodDescriptor desc(manager, dependencies, base, 0, 0);
3100 desc.addParameter(
3101 rtl::OString(
3102 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")),
3103 false, false, 0);
3104 std::auto_ptr< ClassFile::Code > code(cf->newCode());
3105 code->loadLocalReference(0);
3106 // stack: context
3107 code->loadStringConstant(
3108 rtl::OString(RTL_CONSTASCII_STRINGPARAM("/singletons/")) + unoName);
3109 // stack: context "..."
3110 code->instrInvokeinterface(
3111 rtl::OString(
3112 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/XComponentContext")),
3113 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getValueByName")),
3114 rtl::OString(
3115 RTL_CONSTASCII_STRINGPARAM(
3116 "(Ljava/lang/String;)Ljava/lang/Object;")),
3118 // stack: value
3119 code->instrDup();
3120 // stack: value value
3121 code->instrInstanceof(
3122 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")));
3123 // stack: value 0/1
3124 ClassFile::Code::Branch branch1 = code->instrIfeq();
3125 // stack: value
3126 code->instrCheckcast(
3127 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")));
3128 // stack: value
3129 code->instrDup();
3130 // stack: value value
3131 code->instrInvokevirtual(
3132 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
3133 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getType")),
3134 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Lcom/sun/star/uno/Type;")));
3135 // stack: value type
3136 code->instrInvokevirtual(
3137 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
3138 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getTypeClass")),
3139 rtl::OString(
3140 RTL_CONSTASCII_STRINGPARAM("()Lcom/sun/star/uno/TypeClass;")));
3141 // stack: value typeClass
3142 code->instrGetstatic(
3143 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")),
3144 rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")),
3145 rtl::OString(
3146 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;")));
3147 // stack: value typeClass INTERFACE
3148 ClassFile::Code::Branch branch2 = code->instrIfAcmpne();
3149 // stack: value
3150 code->instrInvokevirtual(
3151 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Any")),
3152 rtl::OString(RTL_CONSTASCII_STRINGPARAM("getObject")),
3153 rtl::OString(RTL_CONSTASCII_STRINGPARAM("()Ljava/lang/Object;")));
3154 // stack: value
3155 code->branchHere(branch1);
3156 code->instrNew(
3157 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")));
3158 // stack: value type
3159 code->instrDup();
3160 // stack: value type type
3161 code->loadStringConstant(realJavaBaseName);
3162 // stack: value type type "..."
3163 code->instrGetstatic(
3164 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/TypeClass")),
3165 rtl::OString(RTL_CONSTASCII_STRINGPARAM("INTERFACE")),
3166 rtl::OString(
3167 RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/TypeClass;")));
3168 // stack: value type type "..." INTERFACE
3169 code->instrInvokespecial(
3170 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/Type")),
3171 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
3172 rtl::OString(
3173 RTL_CONSTASCII_STRINGPARAM(
3174 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V")));
3175 // stack: value type
3176 code->instrSwap();
3177 // stack: type value
3178 code->instrInvokestatic(
3179 rtl::OString(RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/UnoRuntime")),
3180 rtl::OString(RTL_CONSTASCII_STRINGPARAM("queryInterface")),
3181 rtl::OString(
3182 RTL_CONSTASCII_STRINGPARAM(
3183 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
3184 "Ljava/lang/Object;")));
3185 // stack: instance
3186 code->instrDup();
3187 // stack: instance instance
3188 ClassFile::Code::Branch branch3 = code->instrIfnull();
3189 // stack: instance
3190 code->instrCheckcast(base);
3191 // stack: instance
3192 code->instrAreturn();
3193 code->branchHere(branch2);
3194 code->branchHere(branch3);
3195 code->instrPop();
3196 // stack: -
3197 code->instrNew(
3198 rtl::OString(
3199 RTL_CONSTASCII_STRINGPARAM(
3200 "com/sun/star/uno/DeploymentException")));
3201 // stack: ex
3202 code->instrDup();
3203 // stack: ex ex
3204 rtl::OStringBuffer msg;
3205 msg.append(
3206 RTL_CONSTASCII_STRINGPARAM(
3207 "component context fails to supply singleton "));
3208 msg.append(unoName);
3209 msg.append(RTL_CONSTASCII_STRINGPARAM(" of type "));
3210 msg.append(realJavaBaseName);
3211 code->loadStringConstant(msg.makeStringAndClear());
3212 // stack: ex ex "..."
3213 code->loadLocalReference(0);
3214 // stack: ex ex "..." context
3215 code->instrInvokespecial(
3216 rtl::OString(
3217 RTL_CONSTASCII_STRINGPARAM("com/sun/star/uno/DeploymentException")),
3218 rtl::OString(RTL_CONSTASCII_STRINGPARAM("<init>")),
3219 rtl::OString(
3220 RTL_CONSTASCII_STRINGPARAM(
3221 "(Ljava/lang/String;Ljava/lang/Object;)V")));
3222 // stack: ex
3223 code->instrAthrow();
3224 code->setMaxStackAndLocals(5, 1);
3225 cf->addMethod(
3226 static_cast< ClassFile::AccessFlags >(
3227 ClassFile::ACC_PUBLIC | ClassFile::ACC_STATIC),
3228 rtl::OString(RTL_CONSTASCII_STRINGPARAM("get")), desc.getDescriptor(),
3229 code.get(), std::vector< rtl::OString >(), desc.getSignature());
3230 writeClassFile(options, className, *cf.get());
3235 bool produceType(
3236 rtl::OString const & type, TypeManager const & manager,
3237 codemaker::GeneratedTypeSet & generated, JavaOptions * options)
3239 OSL_ASSERT(options != 0);
3240 if (type.equals("/")
3241 || type.equals(manager.getBase())
3242 || generated.contains(type))
3244 return true;
3246 sal_Bool extra = sal_False;
3247 typereg::Reader reader(manager.getTypeReader(type, &extra));
3248 if (extra) {
3249 generated.add(type);
3250 return true;
3252 if (!reader.isValid()) {
3253 return false;
3256 handleUnoTypeRegistryEntityFunction handler;
3257 switch (reader.getTypeClass()) {
3258 case RT_TYPE_ENUM:
3259 handler = handleEnumType;
3260 break;
3262 case RT_TYPE_STRUCT:
3263 case RT_TYPE_EXCEPTION:
3264 handler = handleAggregatingType;
3265 break;
3267 case RT_TYPE_INTERFACE:
3268 handler = handleInterfaceType;
3269 break;
3271 case RT_TYPE_TYPEDEF:
3272 handler = handleTypedef;
3273 break;
3275 case RT_TYPE_CONSTANTS:
3276 handler = handleConstantGroup;
3277 break;
3279 case RT_TYPE_MODULE:
3280 handler = handleModule;
3281 break;
3283 case RT_TYPE_SERVICE:
3284 handler = handleService;
3285 break;
3287 case RT_TYPE_SINGLETON:
3288 handler = handleSingleton;
3289 break;
3291 default:
3292 return false;
3294 Dependencies deps;
3295 handler(manager, *options, reader, &deps);
3296 generated.add(type);
3297 if (!options->isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-nD")))) {
3298 for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) {
3299 if (!produceType(*i, manager, generated, options)) {
3300 return false;
3304 return true;
3307 bool produceType(
3308 RegistryKey & rTypeKey, bool bIsExtraType, TypeManager const & manager,
3309 codemaker::GeneratedTypeSet & generated, JavaOptions * options)
3311 ::rtl::OString typeName = manager.getTypeName(rTypeKey);
3313 OSL_ASSERT(options != 0);
3314 if (typeName.equals("/")
3315 || typeName.equals(manager.getBase())
3316 || generated.contains(typeName))
3318 return true;
3320 typereg::Reader reader(manager.getTypeReader(rTypeKey));
3321 if (bIsExtraType) {
3322 generated.add(typeName);
3323 return true;
3325 if (!reader.isValid()) {
3326 return false;
3328 handleUnoTypeRegistryEntityFunction handler;
3329 switch (reader.getTypeClass()) {
3330 case RT_TYPE_ENUM:
3331 handler = handleEnumType;
3332 break;
3334 case RT_TYPE_STRUCT:
3335 case RT_TYPE_EXCEPTION:
3336 handler = handleAggregatingType;
3337 break;
3339 case RT_TYPE_INTERFACE:
3340 handler = handleInterfaceType;
3341 break;
3343 case RT_TYPE_TYPEDEF:
3344 handler = handleTypedef;
3345 break;
3347 case RT_TYPE_CONSTANTS:
3348 handler = handleConstantGroup;
3349 break;
3351 case RT_TYPE_MODULE:
3352 handler = handleModule;
3353 break;
3355 case RT_TYPE_SERVICE:
3356 handler = handleService;
3357 break;
3359 case RT_TYPE_SINGLETON:
3360 handler = handleSingleton;
3361 break;
3363 default:
3364 return false;
3366 Dependencies deps;
3367 handler(manager, *options, reader, &deps);
3368 generated.add(typeName);
3369 if (!options->isValid(rtl::OString(RTL_CONSTASCII_STRINGPARAM("-nD")))) {
3370 for (Dependencies::iterator i(deps.begin()); i != deps.end(); ++i) {
3371 if (!produceType(*i, manager, generated, options)) {
3372 return false;
3376 return true;