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