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