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