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