1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
28 #include <string_view>
32 #include <codemaker/codemaker.hxx>
33 #include <codemaker/exceptiontree.hxx>
34 #include <codemaker/generatedtypeset.hxx>
35 #include <codemaker/global.hxx>
36 #include <codemaker/options.hxx>
37 #include <codemaker/typemanager.hxx>
38 #include <codemaker/unotype.hxx>
39 #include <codemaker/commonjava.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>
49 #include "classfile.hxx"
50 #include "javaoptions.hxx"
51 #include "javatype.hxx"
53 using codemaker::javamaker::ClassFile
;
58 rtl::Reference
< TypeManager
> const & manager
, std::u16string_view nucleus
,
59 sal_Int32 rank
, std::vector
< OUString
> const & arguments
,
60 OUStringBuffer
* buffer
)
64 assert(buffer
!= nullptr);
65 for (sal_Int32 i
= 0; i
!= rank
; ++i
) {
68 buffer
->append(nucleus
);
69 if (arguments
.empty())
73 for (std::vector
< OUString
>::const_iterator
i(arguments
.begin());
74 i
!= arguments
.end(); ++i
)
76 if (i
!= arguments
.begin()) {
81 std::vector
< OUString
> args
;
82 manager
->decompose(*i
, false, &n
, &k
, &args
, nullptr);
83 appendUnoName(manager
, n
, k
, args
, buffer
);
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:
91 OUString
createUnoName(
92 rtl::Reference
< TypeManager
> const & manager
, std::u16string_view nucleus
,
93 sal_Int32 rank
, std::vector
< OUString
> const & arguments
)
95 OUStringBuffer
buf(256);
96 appendUnoName(manager
, nucleus
, rank
, arguments
, &buf
);
97 return buf
.makeStringAndClear();
103 SPECIAL_TYPE_UNSIGNED
,
104 SPECIAL_TYPE_INTERFACE
107 bool isSpecialType(SpecialType special
) {
108 return special
>= SPECIAL_TYPE_UNSIGNED
;
111 OString
translateUnoidlEntityNameToJavaFullyQualifiedName(
112 std::u16string_view name
, std::string_view prefix
)
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
)
121 return codemaker::convertString(OUString(name
.substr(0, i
))).replace('.', '/')
122 + codemaker::java::translateUnoToJavaIdentifier(
123 codemaker::convertString(OUString(name
.substr(i
))), prefix
);
126 struct PolymorphicUnoType
{
127 PolymorphicUnoType(): kind(KIND_NONE
) {}
129 enum Kind
{ KIND_NONE
, KIND_STRUCT
, KIND_SEQUENCE
};
134 SpecialType
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
);
140 SpecialType
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
)
149 assert((signature
== nullptr) == (needsSignature
== nullptr));
153 != codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
));
154 if (rank
> 0xFF - (array
? 1 : 0)) {
155 throw CannotDumpException(
156 u
"Too many array dimensions for Java class file format"_ustr
);
161 for (sal_Int32 i
= 0; i
!= rank
; ++i
) {
162 if (descriptor
!= nullptr) {
163 descriptor
->append('[');
165 if (signature
!= nullptr) {
166 signature
->append('[');
169 if (polymorphicUnoType
!= nullptr) {
171 == codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
)
173 polymorphicUnoType
->kind
= rank
== 0
174 ? PolymorphicUnoType::KIND_STRUCT
175 : PolymorphicUnoType::KIND_SEQUENCE
;
176 polymorphicUnoType
->name
= createUnoName(
177 manager
, nucleus
, rank
, arguments
);
179 polymorphicUnoType
->kind
= PolymorphicUnoType::KIND_NONE
;
183 case codemaker::UnoType::Sort::Void
:
184 case codemaker::UnoType::Sort::Boolean
:
185 case codemaker::UnoType::Sort::Byte
:
186 case codemaker::UnoType::Sort::Short
:
187 case codemaker::UnoType::Sort::UnsignedShort
:
188 case codemaker::UnoType::Sort::Long
:
189 case codemaker::UnoType::Sort::UnsignedLong
:
190 case codemaker::UnoType::Sort::Hyper
:
191 case codemaker::UnoType::Sort::UnsignedHyper
:
192 case codemaker::UnoType::Sort::Float
:
193 case codemaker::UnoType::Sort::Double
:
194 case codemaker::UnoType::Sort::Char
:
195 case codemaker::UnoType::Sort::String
:
196 case codemaker::UnoType::Sort::Type
:
197 case codemaker::UnoType::Sort::Any
:
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;" } };
217 = simpleTypeDescriptors
[static_cast<int>(sort
)][rank
== 0 && classType
];
218 if (descriptor
!= nullptr) {
219 descriptor
->append(s
);
221 if (signature
!= nullptr) {
222 signature
->append(s
);
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
)];
233 case codemaker::UnoType::Sort::Interface
:
234 if (nucleus
== "com.sun.star.uno.XInterface") {
235 if (descriptor
!= nullptr) {
236 descriptor
->append("Ljava/lang/Object;");
238 if (signature
!= nullptr) {
239 signature
->append("Ljava/lang/Object;");
241 return SPECIAL_TYPE_INTERFACE
;
244 case codemaker::UnoType::Sort::Sequence
:
245 case codemaker::UnoType::Sort::Enum
:
246 case codemaker::UnoType::Sort::PlainStruct
:
247 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
248 if (dependencies
!= nullptr) {
249 dependencies
->insert(nucleus
);
251 if (descriptor
!= nullptr) {
253 "L" + codemaker::convertString(nucleus
).replace('.', '/')
256 if (signature
!= nullptr) {
258 "L" + codemaker::convertString(nucleus
).replace('.', '/'));
259 if (!arguments
.empty()) {
260 signature
->append('<');
261 for (const OUString
& arg
: arguments
)
263 translateUnoTypeToDescriptor(
264 manager
, arg
, false, true, dependencies
, nullptr, signature
,
265 needsSignature
, nullptr);
267 signature
->append('>');
268 *needsSignature
= true;
270 signature
->append(';');
272 return SPECIAL_TYPE_NONE
;
274 throw CannotDumpException(
275 "unexpected nucleus \"" + nucleus
276 + "\" in call to translateUnoTypeToDescriptor");
280 SpecialType
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
)
286 assert(manager
.is());
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
);
297 SpecialType
getFieldDescriptor(
298 rtl::Reference
< TypeManager
> const & manager
, std::set
<OUString
> * dependencies
,
299 std::u16string_view type
, OString
* descriptor
, OString
* signature
,
300 PolymorphicUnoType
* polymorphicUnoType
)
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
,
309 *descriptor
= desc
.makeStringAndClear();
310 if (signature
!= nullptr) {
312 *signature
= sig
.makeStringAndClear();
320 class MethodDescriptor
{
323 rtl::Reference
< TypeManager
> manager
,
324 std::set
<OUString
> * dependencies
, std::u16string_view returnType
,
325 SpecialType
* specialReturnType
,
326 PolymorphicUnoType
* polymorphicUnoType
);
328 SpecialType
addParameter(
329 std::u16string_view type
, bool array
, bool dependency
,
330 PolymorphicUnoType
* polymorphicUnoType
);
332 void addTypeParameter(OUString
const & name
);
334 OString
getDescriptor() const;
336 OString
getSignature() const { return m_needsSignature
? m_signatureStart
+ m_signatureEnd
: OString();}
339 rtl::Reference
< TypeManager
> m_manager
;
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
;
348 MethodDescriptor::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)
354 assert(dependencies
!= nullptr);
355 m_descriptorStart
.append('(');
356 m_signatureStart
.append('(');
357 OStringBuffer
descEnd(128);
359 OStringBuffer
sigEnd(128);
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
;
371 SpecialType
MethodDescriptor::addParameter(
372 std::u16string_view type
, bool array
, bool dependency
,
373 PolymorphicUnoType
* polymorphicUnoType
)
375 return translateUnoTypeToDescriptor(
376 m_manager
, type
, array
, false, dependency
? m_dependencies
: nullptr,
377 &m_descriptorStart
, &m_signatureStart
, &m_needsSignature
,
381 void MethodDescriptor::addTypeParameter(OUString
const & name
) {
382 m_descriptorStart
.append("Ljava/lang/Object;");
383 m_signatureStart
.append("T" + codemaker::convertString(name
) + ";");
384 m_needsSignature
= true;
387 OString
MethodDescriptor::getDescriptor() const {
388 return m_descriptorStart
+ m_descriptorEnd
;
394 enum Kind
{ KIND_MEMBER
, KIND_ATTRIBUTE
, KIND_METHOD
, KIND_PARAMETER
};
396 // Same values as in com/sun/star/lib/uno/typeinfo/TypeInfo.java:
398 FLAG_READONLY
= 0x008, FLAG_BOUND
= 0x100
403 OString name
, SpecialType specialType
, sal_Int32 index
,
404 PolymorphicUnoType
const & polymorphicUnoType
,
405 sal_Int32 typeParameterIndex
);
407 // KIND_ATTRIBUTE/METHOD:
409 Kind kind
, OString name
, SpecialType specialType
, Flags flags
,
410 sal_Int32 index
, PolymorphicUnoType polymorphicUnoType
);
414 OString parameterName
, SpecialType specialType
,
415 bool inParameter
, bool outParameter
, OString methodName
,
416 sal_Int32 index
, PolymorphicUnoType polymorphicUnoType
);
418 sal_uInt16
generateCode(ClassFile::Code
& code
, std::set
<OUString
> * dependencies
)
421 void generatePolymorphicUnoTypeCode(
422 ClassFile::Code
& code
, std::set
<OUString
> * dependencies
) const;
429 OString m_methodName
;
430 PolymorphicUnoType m_polymorphicUnoType
;
431 sal_Int32 m_typeParameterIndex
;
434 sal_Int32
translateSpecialTypeFlags(
435 SpecialType specialType
, bool inParameter
, bool outParameter
)
437 static sal_Int32
const specialTypeFlags
[SPECIAL_TYPE_INTERFACE
+ 1] = {
438 0, 0x0040 /* ANY */, 0x0004 /* UNSIGNED */, 0x0080 /* INTERFACE */ };
439 sal_Int32 flags
= specialTypeFlags
[specialType
];
441 flags
|= 0x0001; /* IN */
444 flags
|= 0x0002; /* OUT */
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
)
459 polymorphicUnoType
.kind
== PolymorphicUnoType::KIND_NONE
460 ? typeParameterIndex
>= -1 : typeParameterIndex
== -1);
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)
471 assert(kind
== KIND_ATTRIBUTE
|| kind
== KIND_METHOD
);
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)
485 sal_uInt16
TypeInfo::generateCode(
486 ClassFile::Code
& code
, std::set
<OUString
> * dependencies
) const
490 code
.instrNew("com/sun/star/lib/uno/typeinfo/MemberTypeInfo"_ostr
);
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"_ostr
, "<init>"_ostr
,
500 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V"_ostr
);
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"_ostr
, "<init>"_ostr
,
507 "(Ljava/lang/String;IILcom/sun/star/uno/Type;I)V"_ostr
);
510 code
.instrInvokespecial(
511 "com/sun/star/lib/uno/typeinfo/MemberTypeInfo"_ostr
, "<init>"_ostr
,
512 "(Ljava/lang/String;II)V"_ostr
);
516 code
.instrNew("com/sun/star/lib/uno/typeinfo/AttributeTypeInfo"_ostr
);
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"_ostr
, "<init>"_ostr
,
525 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V"_ostr
);
528 code
.instrInvokespecial(
529 "com/sun/star/lib/uno/typeinfo/AttributeTypeInfo"_ostr
, "<init>"_ostr
,
530 "(Ljava/lang/String;II)V"_ostr
);
534 code
.instrNew("com/sun/star/lib/uno/typeinfo/MethodTypeInfo"_ostr
);
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"_ostr
, "<init>"_ostr
,
543 "(Ljava/lang/String;IILcom/sun/star/uno/Type;)V"_ostr
);
546 code
.instrInvokespecial(
547 "com/sun/star/lib/uno/typeinfo/MethodTypeInfo"_ostr
, "<init>"_ostr
,
548 "(Ljava/lang/String;II)V"_ostr
);
552 code
.instrNew("com/sun/star/lib/uno/typeinfo/ParameterTypeInfo"_ostr
);
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"_ostr
, "<init>"_ostr
,
562 ("(Ljava/lang/String;Ljava/lang/String;II"
563 "Lcom/sun/star/uno/Type;)V"_ostr
));
566 code
.instrInvokespecial(
567 "com/sun/star/lib/uno/typeinfo/ParameterTypeInfo"_ostr
, "<init>"_ostr
,
568 "(Ljava/lang/String;Ljava/lang/String;II)V"_ostr
);
577 void TypeInfo::generatePolymorphicUnoTypeCode(
578 ClassFile::Code
& code
, std::set
<OUString
> * dependencies
) const
580 assert(dependencies
!= nullptr);
581 assert(m_polymorphicUnoType
.kind
!= PolymorphicUnoType::KIND_NONE
);
582 code
.instrNew("com/sun/star/uno/Type"_ostr
);
584 code
.loadStringConstant(
585 codemaker::convertString(m_polymorphicUnoType
.name
));
586 if (m_polymorphicUnoType
.kind
== PolymorphicUnoType::KIND_STRUCT
) {
588 "com/sun/star/uno/TypeClass"_ostr
, "STRUCT"_ostr
,
589 "Lcom/sun/star/uno/TypeClass;"_ostr
);
592 "com/sun/star/uno/TypeClass"_ostr
, "SEQUENCE"_ostr
,
593 "Lcom/sun/star/uno/TypeClass;"_ostr
);
595 dependencies
->insert(u
"com.sun.star.uno.TypeClass"_ustr
);
596 code
.instrInvokespecial(
597 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
,
598 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"_ostr
);
602 JavaOptions
const & options
, OString
const & type
,
603 ClassFile
const & classFile
)
606 if (options
.isValid("-O"_ostr
)) {
607 path
= options
.getOption("-O"_ostr
);
609 OString
filename(createFileNameFromType(path
, type
, ".class"_ostr
));
611 if (fileExists(filename
)) {
612 if (options
.isValid("-G"_ostr
)) {
615 bCheck
= options
.isValid("-Gc"_ostr
);
618 tempfile
.createTempFile(getTempDir(filename
));
619 if (!tempfile
.isValid()) {
620 throw CannotDumpException(
621 "Cannot create temporary file for " + b2u(filename
));
623 OString
tempname(tempfile
.getName());
625 classFile
.write(tempfile
);
627 // Remove existing file for consistency:
628 if (fileExists(filename
)) {
629 removeTypeFile(filename
);
632 removeTypeFile(tempname
);
636 if (!makeValidTypeFile(filename
, tempname
, bCheck
)) {
637 throw CannotDumpException(
638 "Cannot create " + b2u(filename
) + " from temporary file "
644 OString
const & className
, std::vector
< TypeInfo
> const & typeInfo
,
645 std::set
<OUString
> * dependencies
, ClassFile
* classFile
)
647 assert(classFile
!= nullptr);
648 std::vector
< TypeInfo
>::size_type typeInfos
= typeInfo
.size();
649 if (typeInfos
> SAL_MAX_INT32
) {
650 throw CannotDumpException(
651 u
"UNOTYPEINFO array too big for Java class file format"_ustr
);
657 static_cast< ClassFile::AccessFlags
>(
658 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
659 | ClassFile::ACC_FINAL
),
660 "UNOTYPEINFO"_ostr
, "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;"_ostr
,
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"_ostr
);
666 sal_uInt16 stack
= 0;
667 for (const TypeInfo
& ti
: typeInfo
)
670 code
->loadIntegerConstant(index
++);
671 stack
= std::max(stack
, ti
.generateCode(*code
, dependencies
));
672 code
->instrAastore();
674 code
->instrPutstatic(
675 className
, "UNOTYPEINFO"_ostr
,
676 "[Lcom/sun/star/lib/uno/typeinfo/TypeInfo;"_ostr
);
678 if (stack
> SAL_MAX_UINT16
- 4) {
679 throw CannotDumpException(
680 u
"Stack too big for Java class file format"_ustr
);
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>"_ostr
, "()V"_ostr
, code
.get(), std::vector
< OString
>(), ""_ostr
);
690 const OUString
& name
, rtl::Reference
< unoidl::EnumTypeEntity
> const & entity
,
691 JavaOptions
const & options
)
694 OString
className(codemaker::convertString(name
).replace('.', '/'));
695 std::unique_ptr
< ClassFile
> cf(
697 static_cast< ClassFile::AccessFlags
>(
698 ClassFile::ACC_PUBLIC
| ClassFile::ACC_FINAL
699 | ClassFile::ACC_SUPER
),
700 className
, "com/sun/star/uno/Enum"_ostr
, ""_ostr
));
701 OString
classDescriptor("L" + className
+ ";");
702 for (const unoidl::EnumTypeEntity::Member
& member
: entity
->getMembers())
704 OString
fieldName(codemaker::convertString(member
.name
));
706 static_cast< ClassFile::AccessFlags
>(
707 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
708 | ClassFile::ACC_FINAL
),
709 fieldName
, classDescriptor
, 0, OString());
711 static_cast< ClassFile::AccessFlags
>(
712 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
713 | ClassFile::ACC_FINAL
),
714 fieldName
+ "_value", "I"_ostr
,
715 cf
->addIntegerInfo(member
.value
), ""_ostr
);
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"_ostr
, "<init>"_ostr
, "(I)V"_ostr
);
722 code
->setMaxStackAndLocals(2, 2);
724 ClassFile::ACC_PRIVATE
,
725 "<init>"_ostr
, "(I)V"_ostr
, code
.get(),
726 std::vector
< OString
>(), ""_ostr
);
727 code
= cf
->newCode();
728 code
->instrGetstatic(
730 codemaker::convertString(entity
->getMembers()[0].name
),
732 code
->instrAreturn();
733 code
->setMaxStackAndLocals(1, 0);
735 static_cast< ClassFile::AccessFlags
>(
736 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
),
737 "getDefault"_ostr
, "()" + classDescriptor
,
738 code
.get(), std::vector
< OString
>(), ""_ostr
);
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())
746 min
= std::min(min
, member
.value
);
747 max
= std::max(max
, member
.value
);
748 map
.emplace(member
.value
, codemaker::convertString(member
.name
));
750 sal_uInt64 size
= static_cast< sal_uInt64
>(map
.size());
751 if ((static_cast< sal_uInt64
>(max
) - static_cast< sal_uInt64
>(min
)
753 || size
> SAL_MAX_INT32
)
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
)
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);
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
));
775 code
->instrTableswitch(defCode
.get(), min
, blocks
);
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
)
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());
789 code
->instrLookupswitch(defCode
.get(), blocks
);
790 for (const std::pair
< sal_Int32
, ClassFile::Code
* >& pair
: blocks
)
795 code
->setMaxStackAndLocals(1, 1);
797 static_cast< ClassFile::AccessFlags
>(
798 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
),
799 "fromInt"_ostr
, "(I)" + classDescriptor
, code
.get(),
800 std::vector
< OString
>(), ""_ostr
);
801 code
= cf
->newCode();
802 for (const unoidl::EnumTypeEntity::Member
& member
: entity
->getMembers())
804 code
->instrNew(className
);
806 code
->loadIntegerConstant(member
.value
);
807 code
->instrInvokespecial(className
, "<init>"_ostr
, "(I)V"_ostr
);
808 code
->instrPutstatic(
809 className
, codemaker::convertString(member
.name
), classDescriptor
);
812 code
->setMaxStackAndLocals(3, 0);
814 static_cast< ClassFile::AccessFlags
>(
815 ClassFile::ACC_PRIVATE
| ClassFile::ACC_STATIC
),
816 "<clinit>"_ostr
, "()V"_ostr
, code
.get(), std::vector
< OString
>(), ""_ostr
);
817 writeClassFile(options
, className
, *cf
);
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
,
826 assert(classFile
!= nullptr);
827 assert(typeInfo
!= nullptr);
830 SpecialType specialType
;
831 PolymorphicUnoType polymorphicUnoType
;
832 if (typeParameterIndex
>= 0) {
833 descriptor
= "Ljava/lang/Object;"_ostr
;
834 signature
= "T" + codemaker::convertString(type
).replace('.', '/')
836 specialType
= SPECIAL_TYPE_NONE
; //TODO: SPECIAL_TYPE_TYPE_PARAMETER?
838 specialType
= getFieldDescriptor(
839 manager
, dependencies
, type
, &descriptor
, &signature
,
840 &polymorphicUnoType
);
843 ClassFile::ACC_PUBLIC
, codemaker::convertString(name
), descriptor
, 0,
847 codemaker::convertString(name
), specialType
, index
,
848 polymorphicUnoType
, typeParameterIndex
));
851 sal_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
)
856 assert(manager
.is());
857 assert(code
!= nullptr);
861 OString
name(codemaker::convertString(fieldName
));
864 std::vector
< OUString
> args
;
865 rtl::Reference
< unoidl::Entity
> ent
;
866 codemaker::UnoType::Sort sort
= manager
->decompose(
867 fieldType
, true, &nucleus
, &rank
, &args
, &ent
);
870 case codemaker::UnoType::Sort::Boolean
:
871 case codemaker::UnoType::Sort::Byte
:
872 case codemaker::UnoType::Sort::Short
:
873 case codemaker::UnoType::Sort::UnsignedShort
:
874 case codemaker::UnoType::Sort::Long
:
875 case codemaker::UnoType::Sort::UnsignedLong
:
876 case codemaker::UnoType::Sort::Hyper
:
877 case codemaker::UnoType::Sort::UnsignedHyper
:
878 case codemaker::UnoType::Sort::Float
:
879 case codemaker::UnoType::Sort::Double
:
880 case codemaker::UnoType::Sort::Char
:
881 case codemaker::UnoType::Sort::Interface
:
883 case codemaker::UnoType::Sort::String
:
884 code
->loadLocalReference(0);
885 code
->loadStringConstant(OString());
886 code
->instrPutfield(className
, name
, "Ljava/lang/String;"_ostr
);
888 case codemaker::UnoType::Sort::Type
:
889 code
->loadLocalReference(0);
890 code
->instrGetstatic(
891 "com/sun/star/uno/Type"_ostr
, "VOID"_ostr
, "Lcom/sun/star/uno/Type;"_ostr
);
892 code
->instrPutfield(className
, name
, "Lcom/sun/star/uno/Type;"_ostr
);
894 case codemaker::UnoType::Sort::Any
:
895 code
->loadLocalReference(0);
896 code
->instrGetstatic(
897 "com/sun/star/uno/Any"_ostr
, "VOID"_ostr
, "Lcom/sun/star/uno/Any;"_ostr
);
898 code
->instrPutfield(className
, name
, "Ljava/lang/Object;"_ostr
);
900 case codemaker::UnoType::Sort::Enum
:
902 rtl::Reference
< unoidl::EnumTypeEntity
> ent2(
903 dynamic_cast< unoidl::EnumTypeEntity
* >(ent
.get()));
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
);
917 case codemaker::UnoType::Sort::PlainStruct
:
918 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
920 code
->loadLocalReference(0);
922 codemaker::convertString(nucleus
).replace('.', '/'));
924 code
->instrInvokespecial(
925 codemaker::convertString(nucleus
).replace('.', '/'),
926 "<init>"_ostr
, "()V"_ostr
);
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());
934 case codemaker::UnoType::Sort::Sequence
:
935 case codemaker::UnoType::Sort::Typedef
:
936 for (;;) std::abort(); // this cannot happen
938 throw CannotDumpException(
939 OUString::Concat("unexpected entity \"") + fieldType
940 + "\" in call to addFieldInit");
943 code
->loadLocalReference(0);
944 code
->loadIntegerConstant(0);
946 if (sort
>= codemaker::UnoType::Sort::Boolean
947 && sort
<= codemaker::UnoType::Sort::Char
)
949 code
->instrNewarray(sort
);
951 code
->instrAnewarray(
952 codemaker::java::translateUnoToJavaType(
953 sort
, codemaker::convertString(nucleus
).replace('.', '/'),
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());
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());
971 sal_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
)
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;
984 code
->loadLocalReference(*index
);
989 std::vector
< OUString
> args
;
990 codemaker::UnoType::Sort sort
= manager
->decompose(
991 type
, true, &nucleus
, &rank
, &args
, nullptr);
994 case codemaker::UnoType::Sort::Boolean
:
996 code
->instrNew("java/lang/Boolean"_ostr
);
998 code
->loadLocalInteger(*index
);
999 code
->instrInvokespecial(
1000 "java/lang/Boolean"_ostr
, "<init>"_ostr
, "(Z)V"_ostr
);
1003 code
->loadLocalInteger(*index
);
1008 case codemaker::UnoType::Sort::Byte
:
1010 code
->instrNew("java/lang/Byte"_ostr
);
1012 code
->loadLocalInteger(*index
);
1013 code
->instrInvokespecial(
1014 "java/lang/Byte"_ostr
, "<init>"_ostr
, "(B)V"_ostr
);
1017 code
->loadLocalInteger(*index
);
1022 case codemaker::UnoType::Sort::Short
:
1024 code
->instrNew("java/lang/Short"_ostr
);
1026 code
->loadLocalInteger(*index
);
1027 code
->instrInvokespecial(
1028 "java/lang/Short"_ostr
, "<init>"_ostr
, "(S)V"_ostr
);
1031 code
->loadLocalInteger(*index
);
1036 case codemaker::UnoType::Sort::UnsignedShort
:
1038 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1040 code
->instrGetstatic(
1041 "com/sun/star/uno/Type"_ostr
, "UNSIGNED_SHORT"_ostr
,
1042 "Lcom/sun/star/uno/Type;"_ostr
);
1043 code
->instrNew("java/lang/Short"_ostr
);
1045 code
->loadLocalInteger(*index
);
1046 code
->instrInvokespecial(
1047 "java/lang/Short"_ostr
, "<init>"_ostr
, "(S)V"_ostr
);
1048 code
->instrInvokespecial(
1049 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1050 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1053 code
->loadLocalInteger(*index
);
1058 case codemaker::UnoType::Sort::Long
:
1060 code
->instrNew("java/lang/Integer"_ostr
);
1062 code
->loadLocalInteger(*index
);
1063 code
->instrInvokespecial(
1064 "java/lang/Integer"_ostr
, "<init>"_ostr
, "(I)V"_ostr
);
1067 code
->loadLocalInteger(*index
);
1072 case codemaker::UnoType::Sort::UnsignedLong
:
1074 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1076 code
->instrGetstatic(
1077 "com/sun/star/uno/Type"_ostr
, "UNSIGNED_LONG"_ostr
,
1078 "Lcom/sun/star/uno/Type;"_ostr
);
1079 code
->instrNew("java/lang/Integer"_ostr
);
1081 code
->loadLocalInteger(*index
);
1082 code
->instrInvokespecial(
1083 "java/lang/Integer"_ostr
, "<init>"_ostr
, "(I)V"_ostr
);
1084 code
->instrInvokespecial(
1085 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1086 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1089 code
->loadLocalInteger(*index
);
1094 case codemaker::UnoType::Sort::Hyper
:
1096 code
->instrNew("java/lang/Long"_ostr
);
1098 code
->loadLocalLong(*index
);
1099 code
->instrInvokespecial(
1100 "java/lang/Long"_ostr
, "<init>"_ostr
, "(J)V"_ostr
);
1103 code
->loadLocalLong(*index
);
1108 case codemaker::UnoType::Sort::UnsignedHyper
:
1110 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1112 code
->instrGetstatic(
1113 "com/sun/star/uno/Type"_ostr
, "UNSIGNED_HYPER"_ostr
,
1114 "Lcom/sun/star/uno/Type;"_ostr
);
1115 code
->instrNew("java/lang/Long"_ostr
);
1117 code
->loadLocalLong(*index
);
1118 code
->instrInvokespecial(
1119 "java/lang/Long"_ostr
, "<init>"_ostr
, "(J)V"_ostr
);
1120 code
->instrInvokespecial(
1121 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1122 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1125 code
->loadLocalLong(*index
);
1130 case codemaker::UnoType::Sort::Float
:
1132 code
->instrNew("java/lang/Float"_ostr
);
1134 code
->loadLocalFloat(*index
);
1135 code
->instrInvokespecial(
1136 "java/lang/Float"_ostr
, "<init>"_ostr
, "(F)V"_ostr
);
1139 code
->loadLocalFloat(*index
);
1144 case codemaker::UnoType::Sort::Double
:
1146 code
->instrNew("java/lang/Double"_ostr
);
1148 code
->loadLocalDouble(*index
);
1149 code
->instrInvokespecial(
1150 "java/lang/Double"_ostr
, "<init>"_ostr
, "(D)V"_ostr
);
1153 code
->loadLocalDouble(*index
);
1158 case codemaker::UnoType::Sort::Char
:
1160 code
->instrNew("java/lang/Character"_ostr
);
1162 code
->loadLocalInteger(*index
);
1163 code
->instrInvokespecial(
1164 "java/lang/Character"_ostr
, "<init>"_ostr
, "(C)V"_ostr
);
1167 code
->loadLocalInteger(*index
);
1172 case codemaker::UnoType::Sort::String
:
1173 case codemaker::UnoType::Sort::Type
:
1174 case codemaker::UnoType::Sort::Any
:
1175 code
->loadLocalReference(*index
);
1178 case codemaker::UnoType::Sort::Enum
:
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
);
1184 case codemaker::UnoType::Sort::PlainStruct
:
1185 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
1187 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1189 code
->instrNew("com/sun/star/uno/Type"_ostr
);
1191 code
->loadStringConstant(
1192 codemaker::convertString(
1193 createUnoName(manager
, nucleus
, rank
, args
)));
1194 code
->instrGetstatic(
1195 "com/sun/star/uno/TypeClass"_ostr
, "STRUCT"_ostr
,
1196 "Lcom/sun/star/uno/TypeClass;"_ostr
);
1197 dependencies
->insert(u
"com.sun.star.uno.TypeClass"_ustr
);
1198 code
->instrInvokespecial(
1199 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
,
1200 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"_ostr
);
1201 code
->loadLocalReference(*index
);
1202 code
->instrInvokespecial(
1203 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1204 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1207 code
->loadLocalReference(*index
);
1212 case codemaker::UnoType::Sort::Interface
:
1213 if (any
&& nucleus
!= "com.sun.star.uno.XInterface") {
1214 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1216 code
->instrNew("com/sun/star/uno/Type"_ostr
);
1218 code
->loadStringConstant(codemaker::convertString(nucleus
));
1219 code
->instrGetstatic(
1220 "com/sun/star/uno/TypeClass"_ostr
, "INTERFACE"_ostr
,
1221 "Lcom/sun/star/uno/TypeClass;"_ostr
);
1222 dependencies
->insert(u
"com.sun.star.uno.TypeClass"_ustr
);
1223 code
->instrInvokespecial(
1224 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
,
1225 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"_ostr
);
1226 code
->loadLocalReference(*index
);
1227 code
->instrInvokespecial(
1228 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1229 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1232 code
->loadLocalReference(*index
);
1237 case codemaker::UnoType::Sort::Sequence
:
1238 case codemaker::UnoType::Sort::Typedef
:
1239 for (;;) std::abort(); // this cannot happen
1241 throw CannotDumpException(
1242 OUString::Concat("unexpected entity \"") + type
1243 + "\" in call to addLoadLocal");
1249 case codemaker::UnoType::Sort::Boolean
:
1250 case codemaker::UnoType::Sort::Byte
:
1251 case codemaker::UnoType::Sort::Short
:
1252 case codemaker::UnoType::Sort::Long
:
1253 case codemaker::UnoType::Sort::Hyper
:
1254 case codemaker::UnoType::Sort::Float
:
1255 case codemaker::UnoType::Sort::Double
:
1256 case codemaker::UnoType::Sort::Char
:
1257 case codemaker::UnoType::Sort::String
:
1258 case codemaker::UnoType::Sort::Type
:
1259 // assuming that no Java types are derived from
1260 // com.sun.star.uno.Type
1261 case codemaker::UnoType::Sort::Enum
:
1262 // assuming that no Java types are derived from Java
1263 // types that are directly derived from
1264 // com.sun.star.uno.Enum
1266 case codemaker::UnoType::Sort::UnsignedShort
:
1267 case codemaker::UnoType::Sort::UnsignedLong
:
1268 case codemaker::UnoType::Sort::UnsignedHyper
:
1269 case codemaker::UnoType::Sort::Any
:
1270 case codemaker::UnoType::Sort::PlainStruct
:
1271 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
1272 case codemaker::UnoType::Sort::Interface
:
1275 case codemaker::UnoType::Sort::Sequence
:
1276 case codemaker::UnoType::Sort::Typedef
:
1277 for (;;) std::abort(); // this cannot happen
1279 throw CannotDumpException(
1280 OUString::Concat("unexpected entity \"") + type
1281 + "\" in call to addLoadLocal");
1285 code
->instrNew("com/sun/star/uno/Any"_ostr
);
1287 code
->instrNew("com/sun/star/uno/Type"_ostr
);
1289 code
->loadStringConstant(
1290 codemaker::convertString(
1291 createUnoName(manager
, nucleus
, rank
, args
)));
1292 code
->instrInvokespecial(
1293 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
, "(Ljava/lang/String;)V"_ostr
);
1294 code
->loadLocalReference(*index
);
1295 code
->instrInvokespecial(
1296 "com/sun/star/uno/Any"_ostr
, "<init>"_ostr
,
1297 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V"_ostr
);
1300 code
->loadLocalReference(*index
);
1306 if (*index
> SAL_MAX_UINT16
- size
) {
1307 throw CannotDumpException(
1308 u
"Too many local variables for Java class file format"_ustr
);
1310 *index
= *index
+ size
;
1314 sal_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
)
1320 assert(methodDescriptor
!= nullptr);
1321 assert(code
!= nullptr);
1323 if (typeParameter
) {
1324 methodDescriptor
->addTypeParameter(fieldType
);
1325 desc
= "Ljava/lang/Object;"_ostr
;
1327 methodDescriptor
->addParameter(fieldType
, false, true, nullptr);
1328 getFieldDescriptor(manager
, dependencies
, fieldType
, &desc
, nullptr, nullptr);
1330 code
->loadLocalReference(0);
1331 sal_uInt16 stack
= addLoadLocal(
1332 manager
, code
, index
, typeParameter
, fieldType
, false, dependencies
);
1333 code
->instrPutfield(className
, fieldName
, desc
);
1337 void addPlainStructBaseArguments(
1338 rtl::Reference
< TypeManager
> const & manager
, std::set
<OUString
> * dependencies
,
1339 MethodDescriptor
* methodDescriptor
, ClassFile::Code
* code
,
1340 OUString
const & base
, sal_uInt16
* index
)
1342 assert(manager
.is());
1343 assert(methodDescriptor
!= nullptr);
1344 rtl::Reference
< unoidl::Entity
> ent
;
1345 if (manager
->getSort(base
, &ent
)
1346 != codemaker::UnoType::Sort::PlainStruct
)
1348 throw CannotDumpException(
1349 "unexpected entity \"" + base
1350 + "\" in call to addPlainStructBaseArguments");
1352 unoidl::PlainStructTypeEntity
& ent2(dynamic_cast<unoidl::PlainStructTypeEntity
&>(*ent
));
1353 if (!ent2
.getDirectBase().isEmpty()) {
1354 addPlainStructBaseArguments(
1355 manager
, dependencies
, methodDescriptor
, code
,
1356 ent2
.getDirectBase(), index
);
1358 for (const unoidl::PlainStructTypeEntity::Member
& member
: ent2
.getDirectMembers())
1360 methodDescriptor
->addParameter(member
.type
, false, true, nullptr);
1361 addLoadLocal(manager
, code
, index
, false, member
.type
, false, dependencies
);
1365 void handlePlainStructType(
1366 const OUString
& name
,
1367 rtl::Reference
< unoidl::PlainStructTypeEntity
> const & entity
,
1368 rtl::Reference
< TypeManager
> const & manager
, JavaOptions
const & options
,
1369 std::set
<OUString
> * dependencies
)
1371 assert(entity
.is());
1372 assert(dependencies
!= nullptr);
1373 OString
className(codemaker::convertString(name
).replace('.', '/'));
1375 if (entity
->getDirectBase().isEmpty()) {
1376 superClass
= "java/lang/Object"_ostr
;
1378 superClass
= codemaker::convertString(entity
->getDirectBase()).
1380 dependencies
->insert(entity
->getDirectBase());
1382 std::unique_ptr
< ClassFile
> cf(
1384 static_cast< ClassFile::AccessFlags
>(
1385 ClassFile::ACC_PUBLIC
| ClassFile::ACC_SUPER
),
1386 className
, superClass
, ""_ostr
));
1387 std::vector
< TypeInfo
> typeInfo
;
1388 sal_Int32 index
= 0;
1389 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity
->getDirectMembers())
1392 manager
, dependencies
, cf
.get(), &typeInfo
, -1, member
.type
, member
.name
,
1395 std::unique_ptr
< ClassFile::Code
> code(cf
->newCode());
1396 code
->loadLocalReference(0);
1397 code
->instrInvokespecial(superClass
, "<init>"_ostr
, "()V"_ostr
);
1398 sal_uInt16 stack
= 0;
1399 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity
->getDirectMembers())
1404 manager
, className
, member
.name
, false, member
.type
, dependencies
,
1407 code
->instrReturn();
1408 code
->setMaxStackAndLocals(stack
+ 1, 1);
1410 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "()V"_ostr
, code
.get(),
1411 std::vector
< OString
>(), ""_ostr
);
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(),
1421 code
->instrInvokespecial(superClass
, "<init>"_ostr
, desc
.getDescriptor());
1422 sal_uInt16 maxSize
= index2
;
1423 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity
->getDirectMembers())
1428 manager
, dependencies
, &desc
, code
.get(), &index2
, className
,
1429 codemaker::convertString(member
.name
), false, member
.type
));
1431 code
->instrReturn();
1432 code
->setMaxStackAndLocals(maxSize
, index2
);
1434 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, desc
.getDescriptor(), code
.get(),
1435 std::vector
< OString
>(), desc
.getSignature());
1436 addTypeInfo(className
, typeInfo
, dependencies
, cf
.get());
1437 writeClassFile(options
, className
, *cf
);
1440 void handlePolyStructType(
1441 const OUString
& name
,
1442 rtl::Reference
< unoidl::PolymorphicStructTypeTemplateEntity
> const &
1444 rtl::Reference
< TypeManager
> const & manager
, JavaOptions
const & options
,
1445 std::set
<OUString
> * dependencies
)
1447 assert(entity
.is());
1448 OString
className(codemaker::convertString(name
).replace('.', '/'));
1449 std::map
< OUString
, sal_Int32
> typeParameters
;
1450 OStringBuffer
sig(128);
1452 sal_Int32 index
= 0;
1453 for (const OUString
& param
: entity
->getTypeParameters())
1455 sig
.append(codemaker::convertString(param
) + ":Ljava/lang/Object;");
1456 if (!typeParameters
.emplace(param
, index
++).second
)
1458 throw CannotDumpException(u
"Bad type information"_ustr
); //TODO
1461 sig
.append(">Ljava/lang/Object;");
1462 std::unique_ptr
< ClassFile
> cf(
1464 static_cast< ClassFile::AccessFlags
>(
1465 ClassFile::ACC_PUBLIC
| ClassFile::ACC_SUPER
),
1466 className
, "java/lang/Object"_ostr
, sig
.makeStringAndClear()));
1467 std::vector
< TypeInfo
> typeInfo
;
1469 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
: entity
->getMembers())
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(u
"Bad type information"_ustr
); //TODO
1478 typeParameterIndex
= it
->second
;
1480 typeParameterIndex
= -1;
1483 manager
, dependencies
, cf
.get(), &typeInfo
, typeParameterIndex
,
1484 member
.type
, member
.name
, index
++);
1486 std::unique_ptr
< ClassFile::Code
> code(cf
->newCode());
1487 code
->loadLocalReference(0);
1488 code
->instrInvokespecial("java/lang/Object"_ostr
, "<init>"_ostr
, "()V"_ostr
);
1489 sal_uInt16 stack
= 0;
1490 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
: entity
->getMembers())
1495 manager
, className
, member
.name
, member
.parameterized
, member
.type
,
1496 dependencies
, code
.get()));
1498 code
->instrReturn();
1499 code
->setMaxStackAndLocals(stack
+ 1, 1);
1501 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "()V"_ostr
, code
.get(),
1502 std::vector
< OString
>(), ""_ostr
);
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"_ostr
, "<init>"_ostr
, desc
.getDescriptor());
1509 sal_uInt16 maxSize
= index2
;
1510 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
: entity
->getMembers())
1515 manager
, dependencies
, &desc
, code
.get(), &index2
, className
,
1516 codemaker::convertString(member
.name
), member
.parameterized
, member
.type
));
1518 code
->instrReturn();
1519 code
->setMaxStackAndLocals(maxSize
, index2
);
1521 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, desc
.getDescriptor(), code
.get(),
1522 std::vector
< OString
>(), desc
.getSignature());
1523 addTypeInfo(className
, typeInfo
, dependencies
, cf
.get());
1524 writeClassFile(options
, className
, *cf
);
1527 void addExceptionBaseArguments(
1528 rtl::Reference
< TypeManager
> const & manager
, std::set
<OUString
> * dependencies
,
1529 MethodDescriptor
* methodDescriptor
, ClassFile::Code
* code
,
1530 OUString
const & base
, sal_uInt16
* index
)
1532 assert(manager
.is());
1533 assert(methodDescriptor
!= nullptr);
1534 rtl::Reference
< unoidl::Entity
> ent
;
1535 if (manager
->getSort(base
, &ent
) != codemaker::UnoType::Sort::Exception
)
1537 throw CannotDumpException(
1538 "unexpected entity \"" + base
1539 + "\" in call to addExceptionBaseArguments");
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
);
1548 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1549 ent2
.getDirectMembers().begin());
1550 i
!= ent2
.getDirectMembers().end(); ++i
)
1552 if (!baseException
|| i
!= ent2
.getDirectMembers().begin()) {
1553 methodDescriptor
->addParameter(i
->type
, false, true, nullptr);
1555 manager
, code
, index
, false, i
->type
, false, dependencies
);
1560 void 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
)
1565 assert(entity
.is());
1566 assert(dependencies
!= nullptr);
1567 OString
className(codemaker::convertString(name
).replace('.', '/'));
1568 bool baseException
= false;
1569 bool baseRuntimeException
= false;
1571 if (className
== "com/sun/star/uno/Exception") {
1572 baseException
= true;
1573 superClass
= "java/lang/Exception"_ostr
;
1574 } else if (className
== "com/sun/star/uno/RuntimeException") {
1575 baseRuntimeException
= true;
1576 superClass
= "java/lang/RuntimeException"_ostr
;
1578 if (entity
->getDirectBase().isEmpty()) {
1579 throw CannotDumpException(
1580 "Exception type \"" + name
+ "\" lacks base");
1582 superClass
= codemaker::convertString(entity
->getDirectBase()).
1584 dependencies
->insert(entity
->getDirectBase());
1586 std::unique_ptr
< ClassFile
> cf(
1588 static_cast< ClassFile::AccessFlags
>(
1589 ClassFile::ACC_PUBLIC
| ClassFile::ACC_SUPER
),
1590 className
, superClass
, ""_ostr
));
1591 std::vector
< TypeInfo
> typeInfo
;
1592 sal_Int32 index
= 0;
1593 if (baseRuntimeException
) {
1595 manager
, dependencies
, cf
.get(), &typeInfo
, -1,
1596 u
"com.sun.star.uno.XInterface"_ustr
, u
"Context"_ustr
, index
++);
1598 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1599 entity
->getDirectMembers().begin());
1600 i
!= entity
->getDirectMembers().end(); ++i
)
1602 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1604 manager
, dependencies
, cf
.get(), &typeInfo
, -1, i
->type
,
1609 // create default constructor
1610 std::unique_ptr
< ClassFile::Code
> code(cf
->newCode());
1611 code
->loadLocalReference(0);
1612 code
->instrInvokespecial(superClass
, "<init>"_ostr
, "()V"_ostr
);
1613 sal_uInt16 stack
= 0;
1614 if (baseRuntimeException
) {
1618 manager
, className
, u
"Context"_ustr
, false,
1619 u
"com.sun.star.uno.XInterface", dependencies
, code
.get()));
1621 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1622 entity
->getDirectMembers().begin());
1623 i
!= entity
->getDirectMembers().end(); ++i
)
1625 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1629 manager
, className
, i
->name
, false, i
->type
, dependencies
,
1633 code
->instrReturn();
1634 code
->setMaxStackAndLocals(stack
+ 1, 1);
1636 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "()V"_ostr
, code
.get(),
1637 std::vector
< OString
>(), ""_ostr
);
1640 // create (Throwable Cause) constructor
1641 code
= cf
->newCode();
1642 code
->loadLocalReference(0);
1643 code
->loadLocalReference(1);
1644 code
->instrInvokespecial(superClass
, "<init>"_ostr
, "(Ljava/lang/Throwable;)V"_ostr
);
1646 if (baseRuntimeException
) {
1650 manager
, className
, u
"Context"_ustr
, false,
1651 u
"com.sun.star.uno.XInterface", dependencies
, code
.get()));
1653 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1654 entity
->getDirectMembers().begin());
1655 i
!= entity
->getDirectMembers().end(); ++i
)
1657 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1661 manager
, className
, i
->name
, false, i
->type
, dependencies
,
1665 code
->instrReturn();
1666 code
->setMaxStackAndLocals(stack
+ 2, 2);
1668 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "(Ljava/lang/Throwable;)V"_ostr
, code
.get(),
1669 std::vector
< OString
>(), ""_ostr
);
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>"_ostr
, "(Ljava/lang/String;Ljava/lang/Throwable;)V"_ostr
);
1679 code
->loadLocalReference(1);
1680 code
->loadLocalReference(2);
1681 code
->instrInvokespecial(superClass
, "<init>"_ostr
, "(Ljava/lang/Throwable;Ljava/lang/String;)V"_ostr
);
1684 if (baseRuntimeException
) {
1688 manager
, className
, u
"Context"_ustr
, false,
1689 u
"com.sun.star.uno.XInterface", dependencies
, code
.get()));
1691 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1692 entity
->getDirectMembers().begin());
1693 i
!= entity
->getDirectMembers().end(); ++i
)
1695 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1699 manager
, className
, i
->name
, false, i
->type
, dependencies
,
1703 code
->instrReturn();
1704 code
->setMaxStackAndLocals(stack
+ 3, 3);
1706 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "(Ljava/lang/Throwable;Ljava/lang/String;)V"_ostr
, code
.get(),
1707 std::vector
< OString
>(), ""_ostr
);
1709 // create (String Message) constructor
1710 code
= cf
->newCode();
1711 code
->loadLocalReference(0);
1712 code
->loadLocalReference(1);
1713 code
->instrInvokespecial(superClass
, "<init>"_ostr
, "(Ljava/lang/String;)V"_ostr
);
1715 if (baseRuntimeException
) {
1719 manager
, className
, u
"Context"_ustr
, false,
1720 u
"com.sun.star.uno.XInterface", dependencies
, code
.get()));
1722 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1723 entity
->getDirectMembers().begin());
1724 i
!= entity
->getDirectMembers().end(); ++i
)
1726 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1730 manager
, className
, i
->name
, false, i
->type
, dependencies
,
1734 code
->instrReturn();
1735 code
->setMaxStackAndLocals(stack
+ 2, 2);
1737 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, "(Ljava/lang/String;)V"_ostr
, code
.get(),
1738 std::vector
< OString
>(), ""_ostr
);
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(),
1753 code
->instrInvokespecial(superClass
, "<init>"_ostr
, desc1
.getDescriptor());
1754 sal_uInt16 maxSize
= index2
;
1755 if (baseRuntimeException
) {
1759 manager
, dependencies
, &desc1
, code
.get(), &index2
, className
,
1760 "Context"_ostr
, false, u
"com.sun.star.uno.XInterface"_ustr
));
1762 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1763 entity
->getDirectMembers().begin());
1764 i
!= entity
->getDirectMembers().end(); ++i
)
1766 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1770 manager
, dependencies
, &desc1
, code
.get(), &index2
,
1771 className
, codemaker::convertString(i
->name
), false,
1775 code
->instrReturn();
1776 code
->setMaxStackAndLocals(maxSize
, index2
);
1778 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, desc1
.getDescriptor(), code
.get(),
1779 std::vector
< OString
>(), desc1
.getSignature());
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>"_ostr
, "(Ljava/lang/String;Ljava/lang/Throwable;)V"_ostr
);
1794 code
->loadLocalReference(1);
1795 code
->loadLocalReference(2);
1796 addExceptionBaseArguments(
1797 manager
, dependencies
, &desc2
, code
.get(), entity
->getDirectBase(),
1799 code
->instrInvokespecial(superClass
, "<init>"_ostr
, OString::Concat("(Ljava/lang/Throwable;") + desc2
.getDescriptor().subView(1));
1801 sal_uInt16 maxSize2
= index3
;
1802 if (baseRuntimeException
) {
1803 maxSize2
= std::max(
1806 manager
, dependencies
, &desc2
, code
.get(), &index3
, className
,
1807 "Context"_ostr
, false, u
"com.sun.star.uno.XInterface"_ustr
));
1809 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
1810 entity
->getDirectMembers().begin());
1811 i
!= entity
->getDirectMembers().end(); ++i
)
1813 if (!baseException
|| i
!= entity
->getDirectMembers().begin()) {
1814 maxSize2
= std::max(
1817 manager
, dependencies
, &desc2
, code
.get(), &index3
,
1818 className
, codemaker::convertString(i
->name
), false,
1822 code
->instrReturn();
1823 code
->setMaxStackAndLocals(maxSize2
, index3
);
1825 ClassFile::ACC_PUBLIC
, "<init>"_ostr
, OString::Concat("(Ljava/lang/Throwable;") + desc2
.getDescriptor().subView(1), code
.get(),
1826 std::vector
< OString
>(), desc2
.getSignature());
1828 addTypeInfo(className
, typeInfo
, dependencies
, cf
.get());
1829 writeClassFile(options
, className
, *cf
);
1832 void createExceptionsAttribute(
1833 rtl::Reference
< TypeManager
> const & manager
,
1834 std::vector
< OUString
> const & exceptionTypes
,
1835 std::set
<OUString
> * dependencies
, std::vector
< OString
> * exceptions
,
1836 codemaker::ExceptionTree
* tree
)
1838 assert(dependencies
!= nullptr);
1839 assert(exceptions
!= nullptr);
1840 for (const OUString
& ex
: exceptionTypes
)
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
);
1851 void 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
)
1856 assert(entity
.is());
1857 assert(dependencies
!= nullptr);
1858 OString
className(codemaker::convertString(name
).replace('.', '/'));
1859 std::unique_ptr
< ClassFile
> cf(
1861 static_cast< ClassFile::AccessFlags
>(
1862 ClassFile::ACC_PUBLIC
| ClassFile::ACC_INTERFACE
1863 | ClassFile::ACC_ABSTRACT
),
1864 className
, "java/lang/Object"_ostr
, ""_ostr
));
1865 for (const unoidl::AnnotatedReference
& ar
: entity
->getDirectMandatoryBases())
1867 dependencies
->insert(ar
.name
);
1868 cf
->addInterface(codemaker::convertString(ar
.name
).replace('.', '/'));
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"_ostr
);
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())
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
));
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);
1902 static_cast< ClassFile::AccessFlags
>(
1903 ClassFile::ACC_PUBLIC
| ClassFile::ACC_ABSTRACT
),
1904 "set" + attrName
, sdesc
.getDescriptor(), nullptr, exc2
,
1905 sdesc
.getSignature());
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);
1915 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity
->getDirectMethods())
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
)
1930 bool in
= param
.direction
1931 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
;
1932 bool out
= param
.direction
1933 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
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
)
1940 typeInfo
.emplace_back(
1941 codemaker::convertString(param
.name
), specialType
, in
,
1942 out
, methodName
, paramIndex
, polymorphicUnoType
);
1946 std::vector
< OString
> exc2
;
1947 createExceptionsAttribute(
1948 manager
, method
.exceptions
, dependencies
, &exc2
, nullptr);
1950 static_cast< ClassFile::AccessFlags
>(
1951 ClassFile::ACC_PUBLIC
| ClassFile::ACC_ABSTRACT
),
1952 methodName
, desc
.getDescriptor(), nullptr, exc2
, desc
.getSignature());
1955 addTypeInfo(className
, typeInfo
, dependencies
, cf
.get());
1956 writeClassFile(options
, className
, *cf
);
1960 rtl::Reference
< unoidl::TypedefEntity
> const & entity
,
1961 rtl::Reference
< TypeManager
> const & manager
, std::set
<OUString
> * dependencies
)
1963 assert(entity
.is());
1964 assert(manager
.is());
1965 assert(dependencies
!= nullptr);
1967 switch (manager
->decompose(entity
->getType(), false, &nucleus
, nullptr, nullptr, nullptr))
1969 case codemaker::UnoType::Sort::Boolean
:
1970 case codemaker::UnoType::Sort::Byte
:
1971 case codemaker::UnoType::Sort::Short
:
1972 case codemaker::UnoType::Sort::UnsignedShort
:
1973 case codemaker::UnoType::Sort::Long
:
1974 case codemaker::UnoType::Sort::UnsignedLong
:
1975 case codemaker::UnoType::Sort::Hyper
:
1976 case codemaker::UnoType::Sort::UnsignedHyper
:
1977 case codemaker::UnoType::Sort::Float
:
1978 case codemaker::UnoType::Sort::Double
:
1979 case codemaker::UnoType::Sort::Char
:
1980 case codemaker::UnoType::Sort::String
:
1981 case codemaker::UnoType::Sort::Type
:
1982 case codemaker::UnoType::Sort::Any
:
1984 case codemaker::UnoType::Sort::Enum
:
1985 case codemaker::UnoType::Sort::PlainStruct
:
1986 case codemaker::UnoType::Sort::Interface
:
1987 case codemaker::UnoType::Sort::Typedef
:
1988 dependencies
->insert(nucleus
);
1991 assert(false); // this cannot happen
1995 void 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
)
2000 assert(entity
.is());
2001 OString
className(codemaker::convertString(name
).replace('.', '/'));
2002 std::unique_ptr
< ClassFile
> cf(
2004 static_cast< ClassFile::AccessFlags
>(
2005 ClassFile::ACC_PUBLIC
| ClassFile::ACC_INTERFACE
2006 | ClassFile::ACC_ABSTRACT
),
2007 className
, "java/lang/Object"_ostr
, ""_ostr
));
2008 for (const unoidl::ConstantGroupEntity::Member
& member
: entity
->getMembers())
2011 sal_uInt16 valueIndex
= sal_uInt16(); // avoid false warnings
2012 switch (member
.value
.type
) {
2013 case unoidl::ConstantValue::TYPE_BOOLEAN
:
2015 valueIndex
= cf
->addIntegerInfo(sal_Int32(member
.value
.booleanValue
));
2017 case unoidl::ConstantValue::TYPE_BYTE
:
2019 valueIndex
= cf
->addIntegerInfo(member
.value
.byteValue
);
2021 case unoidl::ConstantValue::TYPE_SHORT
:
2023 valueIndex
= cf
->addIntegerInfo(member
.value
.shortValue
);
2025 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
2026 type
= "unsigned short";
2027 valueIndex
= cf
->addIntegerInfo(member
.value
.unsignedShortValue
);
2029 case unoidl::ConstantValue::TYPE_LONG
:
2031 valueIndex
= cf
->addIntegerInfo(member
.value
.longValue
);
2033 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
2034 type
= "unsigned long";
2035 valueIndex
= cf
->addIntegerInfo(
2036 static_cast< sal_Int32
>(member
.value
.unsignedLongValue
));
2038 case unoidl::ConstantValue::TYPE_HYPER
:
2040 valueIndex
= cf
->addLongInfo(member
.value
.hyperValue
);
2042 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
2043 type
= "unsigned hyper";
2044 valueIndex
= cf
->addLongInfo(
2045 static_cast< sal_Int64
>(member
.value
.unsignedHyperValue
));
2047 case unoidl::ConstantValue::TYPE_FLOAT
:
2049 valueIndex
= cf
->addFloatInfo(member
.value
.floatValue
);
2051 case unoidl::ConstantValue::TYPE_DOUBLE
:
2053 valueIndex
= cf
->addDoubleInfo(member
.value
.doubleValue
);
2058 getFieldDescriptor(manager
, dependencies
, type
, &desc
, &sig
, nullptr);
2060 static_cast< ClassFile::AccessFlags
>(
2061 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
2062 | ClassFile::ACC_FINAL
),
2063 codemaker::convertString(member
.name
), desc
, valueIndex
, sig
);
2065 writeClassFile(options
, className
, *cf
);
2068 void addExceptionHandlers(
2069 codemaker::ExceptionTreeNode
const * node
,
2070 ClassFile::Code::Position start
, ClassFile::Code::Position end
,
2071 ClassFile::Code::Position handler
, ClassFile::Code
* code
)
2073 assert(node
!= nullptr);
2074 assert(code
!= nullptr);
2075 if (node
->present
) {
2076 code
->addException(start
, end
, handler
, node
->name
.replace('.', '/'));
2078 for (std::unique_ptr
<codemaker::ExceptionTreeNode
> const & p
: node
->children
)
2080 addExceptionHandlers(p
.get(), start
, end
, handler
, code
);
2085 void addConstructor(
2086 rtl::Reference
< TypeManager
> const & manager
,
2087 std::string_view realJavaBaseName
, OString
const & unoName
,
2088 OString
const & className
,
2089 unoidl::SingleInterfaceBasedServiceEntity::Constructor
const & constructor
,
2090 OUString
const & returnType
, std::set
<OUString
> * dependencies
,
2091 ClassFile
* classFile
)
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);
2100 code
->instrInvokeinterface(
2101 "com/sun/star/uno/XComponentContext"_ostr
, "getServiceManager"_ostr
,
2102 "()Lcom/sun/star/lang/XMultiComponentFactory;"_ostr
, 1);
2104 code
->loadStringConstant(unoName
);
2105 // stack: factory serviceName
2106 codemaker::ExceptionTree tree
;
2107 ClassFile::Code::Position tryStart
;
2108 ClassFile::Code::Position tryEnd
;
2109 std::vector
< OString
> exc
;
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"_ostr
,
2120 "createInstanceWithContext"_ostr
,
2121 ("(Ljava/lang/String;Lcom/sun/star/uno/XComponentContext;)"
2122 "Ljava/lang/Object;"_ostr
),
2124 tryEnd
= code
->getPosition();
2128 if (constructor
.parameters
.size() == 1
2129 && constructor
.parameters
[0].rest
)
2131 desc
.addParameter(u
"any", true, true, nullptr);
2132 code
->loadLocalReference(localIndex
++);
2133 // stack: factory serviceName args
2135 access
= static_cast< ClassFile::AccessFlags
>(
2136 access
| ClassFile::ACC_VARARGS
);
2138 code
->loadIntegerConstant(constructor
.parameters
.size());
2139 // stack: factory serviceName N
2140 code
->instrAnewarray("java/lang/Object"_ostr
);
2141 // stack: factory serviceName args
2144 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter
& param
:
2145 constructor
.parameters
)
2147 desc
.addParameter(param
.type
, false, true, nullptr);
2149 // stack: factory serviceName args args
2150 code
->loadIntegerConstant(n
++);
2151 // stack: factory serviceName args args i
2155 manager
, code
.get(), &localIndex
, false, param
.type
, true,
2157 // stack: factory serviceName args args i any
2158 code
->instrAastore();
2159 // stack: factory serviceName args
2163 code
->loadLocalReference(0);
2164 // stack: factory serviceName args context
2165 tryStart
= code
->getPosition();
2166 code
->instrInvokeinterface(
2167 "com/sun/star/lang/XMultiComponentFactory"_ostr
,
2168 "createInstanceWithArgumentsAndContext"_ostr
,
2169 ("(Ljava/lang/String;[Ljava/lang/Object;"
2170 "Lcom/sun/star/uno/XComponentContext;)Ljava/lang/Object;"_ostr
),
2172 tryEnd
= code
->getPosition();
2174 createExceptionsAttribute(
2175 manager
, constructor
.exceptions
, dependencies
, &exc
, &tree
);
2177 code
->loadLocalReference(0);
2178 // stack: instance context
2179 code
->instrInvokestatic(
2180 className
, "$castInstance"_ostr
,
2181 ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
2182 "Ljava/lang/Object;"_ostr
));
2184 code
->instrCheckcast(
2185 codemaker::convertString(returnType
).replace('.', '/'));
2187 code
->instrAreturn();
2188 if (!tree
.getRoot().present
) {
2189 ClassFile::Code::Position pos1
= code
->getPosition();
2191 code
->instrInvokevirtual(
2192 "java/lang/Throwable"_ostr
, "toString"_ostr
, "()Ljava/lang/String;"_ostr
);
2194 localIndex
= std::max
< sal_uInt16
>(localIndex
, 2);
2195 code
->storeLocalReference(1);
2197 code
->instrNew("com/sun/star/uno/DeploymentException"_ostr
);
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"_ostr
, "concat"_ostr
,
2209 "(Ljava/lang/String;)Ljava/lang/String;"_ostr
);
2210 // stack: ex ex "..."
2211 code
->loadLocalReference(0);
2212 // stack: ex ex "..." context
2213 code
->instrInvokespecial(
2214 "com/sun/star/uno/DeploymentException"_ostr
, "<init>"_ostr
,
2215 "(Ljava/lang/String;Ljava/lang/Object;)V"_ostr
);
2217 ClassFile::Code::Position pos2
= code
->getPosition();
2218 code
->instrAthrow();
2219 addExceptionHandlers(
2220 &tree
.getRoot(), tryStart
, tryEnd
, pos2
, code
.get());
2222 tryStart
, tryEnd
, pos1
, "com/sun/star/uno/Exception"_ostr
);
2223 dependencies
->insert(u
"com.sun.star.uno.Exception"_ustr
);
2224 stack
= std::max
< sal_uInt16
>(stack
, 4);
2226 code
->setMaxStackAndLocals(stack
, localIndex
);
2227 classFile
->addMethod(
2229 codemaker::java::translateUnoToJavaIdentifier(
2230 (constructor
.defaultConstructor
2231 ? "create"_ostr
: codemaker::convertString(constructor
.name
)),
2233 desc
.getDescriptor(), code
.get(), exc
, desc
.getSignature());
2237 const OUString
& name
,
2238 rtl::Reference
< unoidl::SingleInterfaceBasedServiceEntity
> const & entity
,
2239 rtl::Reference
< TypeManager
> const & manager
, JavaOptions
const & options
,
2240 std::set
<OUString
> * dependencies
)
2242 assert(entity
.is());
2243 assert(dependencies
!= nullptr);
2244 OString
unoName(codemaker::convertString(name
));
2246 translateUnoidlEntityNameToJavaFullyQualifiedName(name
, "service"));
2247 std::unique_ptr
< ClassFile
> cf(
2249 static_cast< ClassFile::AccessFlags
>(
2250 ClassFile::ACC_PUBLIC
| ClassFile::ACC_FINAL
2251 | ClassFile::ACC_SUPER
),
2252 className
, "java/lang/Object"_ostr
, ""_ostr
));
2253 if (!entity
->getConstructors().empty()) {
2254 OString
realJavaBaseName(
2255 codemaker::convertString(entity
->getBase()));
2256 dependencies
->insert(entity
->getBase());
2257 dependencies
->insert(u
"com.sun.star.lang.XMultiComponentFactory"_ustr
);
2258 dependencies
->insert(u
"com.sun.star.uno.DeploymentException"_ustr
);
2259 dependencies
->insert(u
"com.sun.star.uno.TypeClass"_ustr
);
2260 dependencies
->insert(u
"com.sun.star.uno.XComponentContext"_ustr
);
2261 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor
& cons
:
2262 entity
->getConstructors())
2265 manager
, realJavaBaseName
, unoName
, className
, cons
,
2266 entity
->getBase(), dependencies
, cf
.get());
2268 // Synthetic castInstance method:
2270 std::unique_ptr
< ClassFile::Code
> code(cf
->newCode());
2271 code
->instrNew("com/sun/star/uno/Type"_ostr
);
2275 code
->loadStringConstant(realJavaBaseName
);
2276 // stack: type type "..."
2277 code
->instrGetstatic(
2278 "com/sun/star/uno/TypeClass"_ostr
, "INTERFACE"_ostr
,
2279 "Lcom/sun/star/uno/TypeClass;"_ostr
);
2280 // stack: type type "..." INTERFACE
2281 code
->instrInvokespecial(
2282 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
,
2283 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"_ostr
);
2285 code
->loadLocalReference(0);
2286 // stack: type instance
2287 code
->instrInvokestatic(
2288 "com/sun/star/uno/UnoRuntime"_ostr
, "queryInterface"_ostr
,
2289 ("(Lcom/sun/star/uno/Type;Ljava/lang/Object;)"
2290 "Ljava/lang/Object;"_ostr
));
2293 // stack: instance instance
2294 ClassFile::Code::Branch branch
= code
->instrIfnull();
2296 code
->instrAreturn();
2297 code
->branchHere(branch
);
2300 code
->instrNew("com/sun/star/uno/DeploymentException"_ostr
);
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"_ostr
, "<init>"_ostr
,
2312 "(Ljava/lang/String;Ljava/lang/Object;)V"_ostr
);
2314 code
->instrAthrow();
2315 code
->setMaxStackAndLocals(4, 2);
2317 static_cast< ClassFile::AccessFlags
>(
2318 ClassFile::ACC_PRIVATE
| ClassFile::ACC_STATIC
2319 | ClassFile::ACC_SYNTHETIC
),
2320 "$castInstance"_ostr
,
2321 ("(Ljava/lang/Object;Lcom/sun/star/uno/XComponentContext;)"
2322 "Ljava/lang/Object;"_ostr
),
2323 code
.get(), std::vector
< OString
>(), ""_ostr
);
2326 writeClassFile(options
, className
, *cf
);
2329 void handleSingleton(
2330 const OUString
& name
,
2331 rtl::Reference
< unoidl::InterfaceBasedSingletonEntity
> const & entity
,
2332 rtl::Reference
< TypeManager
> const & manager
, JavaOptions
const & options
,
2333 std::set
<OUString
> * dependencies
)
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
));
2342 translateUnoidlEntityNameToJavaFullyQualifiedName(name
, "singleton"));
2343 dependencies
->insert(u
"com.sun.star.uno.DeploymentException"_ustr
);
2344 dependencies
->insert(u
"com.sun.star.uno.TypeClass"_ustr
);
2345 dependencies
->insert(u
"com.sun.star.uno.XComponentContext"_ustr
);
2346 std::unique_ptr
< ClassFile
> cf(
2348 static_cast< ClassFile::AccessFlags
>(
2349 ClassFile::ACC_PUBLIC
| ClassFile::ACC_FINAL
2350 | ClassFile::ACC_SUPER
),
2351 className
, "java/lang/Object"_ostr
, ""_ostr
));
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);
2357 code
->loadStringConstant("/singletons/" + unoName
);
2358 // stack: context "..."
2359 code
->instrInvokeinterface(
2360 "com/sun/star/uno/XComponentContext"_ostr
, "getValueByName"_ostr
,
2361 "(Ljava/lang/String;)Ljava/lang/Object;"_ostr
, 2);
2364 // stack: value value
2365 code
->instrInstanceof("com/sun/star/uno/Any"_ostr
);
2367 ClassFile::Code::Branch branch1
= code
->instrIfeq();
2369 code
->instrCheckcast("com/sun/star/uno/Any"_ostr
);
2372 // stack: value value
2373 code
->instrInvokevirtual(
2374 "com/sun/star/uno/Any"_ostr
, "getType"_ostr
, "()Lcom/sun/star/uno/Type;"_ostr
);
2375 // stack: value type
2376 code
->instrInvokevirtual(
2377 "com/sun/star/uno/Type"_ostr
, "getTypeClass"_ostr
,
2378 "()Lcom/sun/star/uno/TypeClass;"_ostr
);
2379 // stack: value typeClass
2380 code
->instrGetstatic(
2381 "com/sun/star/uno/TypeClass"_ostr
, "INTERFACE"_ostr
,
2382 "Lcom/sun/star/uno/TypeClass;"_ostr
);
2383 // stack: value typeClass INTERFACE
2384 ClassFile::Code::Branch branch2
= code
->instrIfAcmpne();
2386 code
->instrInvokevirtual(
2387 "com/sun/star/uno/Any"_ostr
, "getObject"_ostr
, "()Ljava/lang/Object;"_ostr
);
2389 code
->branchHere(branch1
);
2390 code
->instrNew("com/sun/star/uno/Type"_ostr
);
2391 // stack: value type
2393 // stack: value type type
2394 code
->loadStringConstant(realJavaBaseName
);
2395 // stack: value type type "..."
2396 code
->instrGetstatic(
2397 "com/sun/star/uno/TypeClass"_ostr
, "INTERFACE"_ostr
,
2398 "Lcom/sun/star/uno/TypeClass;"_ostr
);
2399 // stack: value type type "..." INTERFACE
2400 code
->instrInvokespecial(
2401 "com/sun/star/uno/Type"_ostr
, "<init>"_ostr
,
2402 "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V"_ostr
);
2403 // stack: value type
2405 // stack: type value
2406 code
->instrInvokestatic(
2407 "com/sun/star/uno/UnoRuntime"_ostr
, "queryInterface"_ostr
,
2408 "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;"_ostr
);
2411 // stack: instance instance
2412 ClassFile::Code::Branch branch3
= code
->instrIfnull();
2414 code
->instrCheckcast(base
);
2416 code
->instrAreturn();
2417 code
->branchHere(branch2
);
2418 code
->branchHere(branch3
);
2421 code
->instrNew("com/sun/star/uno/DeploymentException"_ostr
);
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"_ostr
, "<init>"_ostr
,
2433 "(Ljava/lang/String;Ljava/lang/Object;)V"_ostr
);
2435 code
->instrAthrow();
2436 code
->setMaxStackAndLocals(5, 1);
2438 static_cast< ClassFile::AccessFlags
>(
2439 ClassFile::ACC_PUBLIC
| ClassFile::ACC_STATIC
),
2440 "get"_ostr
, desc
.getDescriptor(), code
.get(), std::vector
< OString
>(),
2441 desc
.getSignature());
2442 writeClassFile(options
, className
, *cf
);
2448 OUString
const & name
, rtl::Reference
< TypeManager
> const & manager
,
2449 codemaker::GeneratedTypeSet
& generated
, JavaOptions
const & options
)
2451 if (generated
.contains(u2b(name
))) {
2454 generated
.add(u2b(name
));
2455 if (!manager
->foundAtPrimaryProvider(name
)) {
2458 std::set
<OUString
> deps
;
2459 rtl::Reference
< unoidl::Entity
> ent
;
2460 rtl::Reference
< unoidl::MapCursor
> cur
;
2461 switch (manager
->getSort(name
, &ent
, &cur
)) {
2462 case codemaker::UnoType::Sort::Module
:
2465 if (!name
.isEmpty()) {
2466 prefix
= name
+ ".";
2470 if (!cur
->getNext(&mem
).is()) {
2473 produce(prefix
+ mem
, manager
, generated
, options
);
2477 case codemaker::UnoType::Sort::Enum
:
2479 name
, dynamic_cast< unoidl::EnumTypeEntity
* >(ent
.get()), options
);
2481 case codemaker::UnoType::Sort::PlainStruct
:
2482 handlePlainStructType(
2483 name
, dynamic_cast< unoidl::PlainStructTypeEntity
* >(ent
.get()),
2484 manager
, options
, &deps
);
2486 case codemaker::UnoType::Sort::PolymorphicStructTemplate
:
2487 handlePolyStructType(
2489 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity
* >(
2491 manager
, options
, &deps
);
2493 case codemaker::UnoType::Sort::Exception
:
2494 handleExceptionType(
2495 name
, dynamic_cast< unoidl::ExceptionTypeEntity
* >(ent
.get()),
2496 manager
, options
, &deps
);
2498 case codemaker::UnoType::Sort::Interface
:
2499 handleInterfaceType(
2500 name
, dynamic_cast< unoidl::InterfaceTypeEntity
* >(ent
.get()),
2501 manager
, options
, &deps
);
2503 case codemaker::UnoType::Sort::Typedef
:
2505 dynamic_cast< unoidl::TypedefEntity
* >(ent
.get()), manager
, &deps
);
2507 case codemaker::UnoType::Sort::ConstantGroup
:
2508 handleConstantGroup(
2509 name
, dynamic_cast< unoidl::ConstantGroupEntity
* >(ent
.get()),
2510 manager
, options
, &deps
);
2512 case codemaker::UnoType::Sort::SingleInterfaceBasedService
:
2515 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity
* >(
2517 manager
, options
, &deps
);
2519 case codemaker::UnoType::Sort::InterfaceBasedSingleton
:
2522 dynamic_cast< unoidl::InterfaceBasedSingletonEntity
* >(ent
.get()),
2523 manager
, options
, &deps
);
2525 case codemaker::UnoType::Sort::AccumulationBasedService
:
2526 case codemaker::UnoType::Sort::ServiceBasedSingleton
:
2529 throw CannotDumpException(
2530 "unexpected entity \"" + name
+ "\" in call to produce");
2532 if (!options
.isValid("-nD"_ostr
)) {
2533 for (const OUString
& d
: deps
) {
2534 produce(d
, manager
, generated
, options
);
2539 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */