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