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