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>
21 #include <sal/log.hxx>
28 #include <string_view>
34 #include <rtl/alloc.h>
35 #include <rtl/ref.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <rtl/ustring.hxx>
38 #include <rtl/strbuf.hxx>
39 #include <unoidl/unoidl.hxx>
41 #include <codemaker/commoncpp.hxx>
42 #include <codemaker/exceptiontree.hxx>
43 #include <codemaker/generatedtypeset.hxx>
44 #include <codemaker/typemanager.hxx>
45 #include <codemaker/unotype.hxx>
47 #include "cpputype.hxx"
48 #include "cppuoptions.hxx"
49 #include "dependencies.hxx"
50 #include "dumputils.hxx"
51 #include "includes.hxx"
56 using FileType
= codemaker::cppumaker::FileType
;
58 bool isBootstrapType(OUString
const & name
)
60 static char const * const names
[] = {
61 "com.sun.star.beans.Property",
62 "com.sun.star.beans.PropertyAttribute",
63 "com.sun.star.beans.PropertyChangeEvent",
64 "com.sun.star.beans.PropertyState",
65 "com.sun.star.beans.PropertyValue",
66 "com.sun.star.beans.XFastPropertySet",
67 "com.sun.star.beans.XMultiPropertySet",
68 "com.sun.star.beans.XPropertiesChangeListener",
69 "com.sun.star.beans.XPropertyAccess",
70 "com.sun.star.beans.XPropertyChangeListener",
71 "com.sun.star.beans.XPropertySet",
72 "com.sun.star.beans.XPropertySetInfo",
73 "com.sun.star.beans.XPropertySetOption",
74 "com.sun.star.beans.XVetoableChangeListener",
75 "com.sun.star.bridge.UnoUrlResolver",
76 "com.sun.star.bridge.XUnoUrlResolver",
77 "com.sun.star.connection.SocketPermission",
78 "com.sun.star.container.XElementAccess",
79 "com.sun.star.container.XEnumeration",
80 "com.sun.star.container.XEnumerationAccess",
81 "com.sun.star.container.XHierarchicalNameAccess",
82 "com.sun.star.container.XNameAccess",
83 "com.sun.star.container.XNameContainer",
84 "com.sun.star.container.XNameReplace",
85 "com.sun.star.container.XSet",
86 "com.sun.star.io.FilePermission",
87 "com.sun.star.io.IOException",
88 "com.sun.star.lang.DisposedException",
89 "com.sun.star.lang.EventObject",
90 "com.sun.star.lang.WrappedTargetRuntimeException",
91 "com.sun.star.lang.XComponent",
92 "com.sun.star.lang.XEventListener",
93 "com.sun.star.lang.XInitialization",
94 "com.sun.star.lang.XMultiComponentFactory",
95 "com.sun.star.lang.XMultiServiceFactory",
96 "com.sun.star.lang.XServiceInfo",
97 "com.sun.star.lang.XSingleComponentFactory",
98 "com.sun.star.lang.XSingleServiceFactory",
99 "com.sun.star.lang.XTypeProvider",
100 "com.sun.star.loader.XImplementationLoader",
101 "com.sun.star.reflection.FieldAccessMode",
102 "com.sun.star.reflection.MethodMode",
103 "com.sun.star.reflection.ParamInfo",
104 "com.sun.star.reflection.ParamMode",
105 "com.sun.star.reflection.TypeDescriptionSearchDepth",
106 "com.sun.star.reflection.XCompoundTypeDescription",
107 "com.sun.star.reflection.XEnumTypeDescription",
108 "com.sun.star.reflection.XIdlArray",
109 "com.sun.star.reflection.XIdlClass",
110 "com.sun.star.reflection.XIdlField",
111 "com.sun.star.reflection.XIdlField2",
112 "com.sun.star.reflection.XIdlMethod",
113 "com.sun.star.reflection.XIdlReflection",
114 "com.sun.star.reflection.XIndirectTypeDescription",
115 "com.sun.star.reflection.XInterfaceAttributeTypeDescription",
116 "com.sun.star.reflection.XInterfaceAttributeTypeDescription2",
117 "com.sun.star.reflection.XInterfaceMemberTypeDescription",
118 "com.sun.star.reflection.XInterfaceMethodTypeDescription",
119 "com.sun.star.reflection.XInterfaceTypeDescription",
120 "com.sun.star.reflection.XInterfaceTypeDescription2",
121 "com.sun.star.reflection.XMethodParameter",
122 "com.sun.star.reflection.XStructTypeDescription",
123 "com.sun.star.reflection.XTypeDescription",
124 "com.sun.star.reflection.XTypeDescriptionEnumeration",
125 "com.sun.star.reflection.XTypeDescriptionEnumerationAccess",
126 "com.sun.star.registry.RegistryKeyType",
127 "com.sun.star.registry.RegistryValueType",
128 "com.sun.star.registry.XImplementationRegistration",
129 "com.sun.star.registry.XRegistryKey",
130 "com.sun.star.registry.XSimpleRegistry",
131 "com.sun.star.security.RuntimePermission",
132 "com.sun.star.security.XAccessControlContext",
133 "com.sun.star.security.XAccessController",
134 "com.sun.star.security.XAction",
135 "com.sun.star.uno.DeploymentException",
136 "com.sun.star.uno.RuntimeException",
137 "com.sun.star.uno.TypeClass",
138 "com.sun.star.uno.Uik",
139 "com.sun.star.uno.XAdapter",
140 "com.sun.star.uno.XAggregation",
141 "com.sun.star.uno.XComponentContext",
142 "com.sun.star.uno.XCurrentContext",
143 "com.sun.star.uno.XInterface",
144 "com.sun.star.uno.XReference",
145 "com.sun.star.uno.XUnloadingPreference",
146 "com.sun.star.uno.XWeak",
147 "com.sun.star.util.XMacroExpander" };
148 // cf. cppuhelper/unotypes/Makefile UNOTYPES (plus missing dependencies)
149 auto const pred
= [&name
](const char* aName
) {
150 return name
.equalsAscii(aName
);
152 return std::any_of(std::begin(names
), std::end(names
), pred
);
155 OString
getFileExtension(FileType eFileType
)
160 case FileType::HDL
: return ".hdl"_ostr
;
161 case FileType::HPP
: return ".hpp"_ostr
;
162 case FileType::EMBIND_CXX
: return "_embind.cxx"_ostr
;
169 CppuType(OUString name
, rtl::Reference
< TypeManager
> const & typeMgr
);
171 virtual ~CppuType() {}
173 CppuType(const CppuType
&) = delete;
174 const CppuType
& operator=(const CppuType
&) = delete;
176 void dump(CppuOptions
const & options
);
179 std::u16string_view uri
, std::u16string_view name
, FileType eFileType
,
180 CppuOptions
const & options
);
182 void dumpDependedTypes(
183 codemaker::GeneratedTypeSet
& generated
, CppuOptions
const & options
) const;
185 virtual void dumpHdlFile(
186 FileStream
& out
, codemaker::cppumaker::Includes
& includes
) {
187 dumpHFileContent(out
, includes
);
190 virtual void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) = 0;
192 virtual void dumpEmbindCppFile(FileStream
& o
);
194 OUString
dumpHeaderDefine(FileStream
& o
, std::u16string_view extension
) const;
196 void dumpGetCppuType(FileStream
& out
);
198 virtual void dumpLightGetCppuType(FileStream
& out
);
200 virtual void dumpNormalGetCppuType(FileStream
&) {
201 assert(false); // this cannot happen
204 virtual void dumpComprehensiveGetCppuType(FileStream
&) {
205 assert(false); // this cannot happen
209 FileStream
& out
, std::u16string_view name
, bool isConst
= false,
210 bool isRef
= false, bool native
= false, bool cppuUnoType
= false)
213 OUString
getTypeClass(OUString
const & name
, bool cStyle
= false);
215 void dumpCppuGetType(
216 FileStream
& out
, std::u16string_view name
, OUString
const * ownName
= nullptr) const;
218 sal_uInt32
getInheritedMemberCount();
220 void inc(sal_Int32 num
=4);
221 void dec(sal_Int32 num
=4);
222 OUString
indent() const;
224 virtual sal_uInt32
checkInheritedMemberCount() const {
225 assert(false); // this cannot happen
229 bool passByReference(OUString
const & name
) const;
231 bool canBeWarnUnused(OUString
const & name
) const;
232 bool canBeWarnUnused(OUString
const & name
, int depth
) const;
234 OUString
resolveOuterTypedefs(OUString
const & name
) const;
236 OUString
resolveAllTypedefs(std::u16string_view name
) const;
238 codemaker::cpp::IdentifierTranslationMode
isGlobal() const;
240 virtual void dumpDeclaration(FileStream
&) {
241 assert(false); // this cannot happen
244 virtual void dumpEmbindDeclaration(FileStream
&) {};
246 virtual void dumpFiles(OUString
const & uri
, CppuOptions
const & options
);
248 virtual void addLightGetCppuTypeIncludes(
249 codemaker::cppumaker::Includes
& includes
) const;
251 virtual void addNormalGetCppuTypeIncludes(
252 codemaker::cppumaker::Includes
& includes
) const;
254 virtual void addComprehensiveGetCppuTypeIncludes(
255 codemaker::cppumaker::Includes
& includes
) const;
257 virtual bool isPolymorphic() const;
259 virtual void dumpTemplateHead(FileStream
&) const {}
261 virtual void dumpTemplateParameters(FileStream
&) const {}
263 void dumpGetCppuTypePreamble(FileStream
& out
);
265 void dumpGetCppuTypePostamble(FileStream
& out
);
267 void addDefaultHIncludes(codemaker::cppumaker::Includes
& includes
) const;
268 void addDefaultHxxIncludes(codemaker::cppumaker::Includes
& includes
) const;
270 void dumpInitializer(
271 FileStream
& out
, bool parameterized
, std::u16string_view name
) const;
273 void dumpHFileContent(
274 FileStream
& out
, codemaker::cppumaker::Includes
& includes
);
277 sal_uInt32 m_inheritedMemberCount
;
280 bool m_cppuTypeDynamic
;
281 sal_Int32 m_indentLength
;
284 rtl::Reference
< TypeManager
> m_typeMgr
;
285 codemaker::cppumaker::Dependencies m_dependencies
;
288 void addGetCppuTypeIncludes(codemaker::cppumaker::Includes
& includes
)
293 OUString name
, rtl::Reference
< TypeManager
> const & typeMgr
):
294 m_inheritedMemberCount(0)
295 , m_cppuTypeLeak(false)
296 , m_cppuTypeDynamic(true)
298 , name_(std::move(name
))
299 , id_(name_
.copy(name_
.lastIndexOf('.') + 1))
301 , m_dependencies(typeMgr
, name_
)
304 void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes
& includes
)
307 if (name_
== "com.sun.star.uno.XInterface"
308 || name_
== "com.sun.star.uno.Exception") {
310 includes
.addCppuUnotypeHxx();
311 includes
.addSalTypesH();
312 includes
.addTypelibTypeclassH();
313 includes
.addTypelibTypedescriptionH();
314 } else if (m_cppuTypeLeak
) {
315 addLightGetCppuTypeIncludes(includes
);
316 } else if (m_cppuTypeDynamic
) {
317 addNormalGetCppuTypeIncludes(includes
);
319 addComprehensiveGetCppuTypeIncludes(includes
);
323 void CppuType::dumpFiles(OUString
const & uri
, CppuOptions
const & options
)
325 dumpFile(uri
, name_
, FileType::HDL
, options
);
326 dumpFile(uri
, name_
, FileType::HPP
, options
);
327 if(options
.isValid("-W"_ostr
))
328 dumpFile(uri
, name_
, FileType::EMBIND_CXX
, options
);
331 void CppuType::addLightGetCppuTypeIncludes(
332 codemaker::cppumaker::Includes
& includes
) const
334 //TODO: Determine what is really needed, instead of relying on
335 // addDefaultHxxIncludes
336 includes
.addCppuUnotypeHxx();
339 void CppuType::addNormalGetCppuTypeIncludes(
340 codemaker::cppumaker::Includes
& includes
) const
342 //TODO: Determine what is really needed, instead of relying on
343 // addDefaultHxxIncludes
344 includes
.addCppuUnotypeHxx();
347 void CppuType::addComprehensiveGetCppuTypeIncludes(
348 codemaker::cppumaker::Includes
& includes
) const
350 //TODO: Determine what is really needed, instead of relying on
351 // addDefaultHxxIncludes
352 includes
.addCppuUnotypeHxx();
355 bool CppuType::isPolymorphic() const
360 void CppuType::dumpGetCppuTypePreamble(FileStream
& out
)
362 if (isPolymorphic()) {
363 out
<< "namespace cppu {\n\n";
364 dumpTemplateHead(out
);
365 out
<< "class UnoType< ";
366 dumpType(out
, name_
);
367 dumpTemplateParameters(out
);
368 out
<< " > {\npublic:\n";
371 << "static inline ::css::uno::Type const & get() {\n";
373 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false)) {
376 out
<< ("inline ::css::uno::Type const &"
377 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
378 dumpType(out
, name_
, false, false, true);
379 out
<< " const *) {\n";
384 void CppuType::dumpGetCppuTypePostamble(FileStream
& out
)
387 if (isPolymorphic()) {
388 out
<< indent() << "}\n\nprivate:\n"
389 << indent() << "UnoType(UnoType &); // not defined\n"
390 << indent() << "~UnoType(); // not defined\n"
392 << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
395 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false)) {
399 dumpTemplateHead(out
);
400 out
<< ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
401 " getCppuType(SAL_UNUSED_PARAMETER ");
402 dumpType(out
, name_
);
403 dumpTemplateParameters(out
);
404 out
<< " const *) {\n";
406 out
<< indent() << "return ::cppu::UnoType< ";
407 dumpType(out
, name_
);
408 dumpTemplateParameters(out
);
409 out
<< " >::get();\n";
411 out
<< indent() << "}\n";
414 void CppuType::dump(CppuOptions
const & options
)
416 if (isBootstrapType(name_
)) {
417 m_cppuTypeDynamic
= false;
419 // -CS was used as an undocumented option to generate static getCppuType
420 // functions; since the introduction of cppu::UnoType this no longer is
421 // meaningful (getCppuType is just a forward to cppu::UnoType::get now),
422 // and -CS is handled the same way as -C now:
423 if (options
.isValid("-L"_ostr
))
424 m_cppuTypeLeak
= true;
425 if (options
.isValid("-C"_ostr
) || options
.isValid("-CS"_ostr
))
426 m_cppuTypeDynamic
= false;
429 options
.isValid("-O"_ostr
) ? b2u(options
.getOption("-O"_ostr
)) : "", options
);
432 void CppuType::dumpFile(
433 std::u16string_view uri
, std::u16string_view name
, FileType eFileType
,
434 CppuOptions
const & options
)
437 b2u(createFileNameFromType(
438 u2b(uri
), u2b(name
), getFileExtension(eFileType
))));
439 if (fileUri
.isEmpty()) {
440 throw CannotDumpException(OUString::Concat("empty target URI for entity ") + name
);
442 bool exists
= fileExists(u2b(fileUri
));
443 if (exists
&& options
.isValid("-G"_ostr
)) {
447 out
.createTempFile(getTempDir(u2b(fileUri
)));
448 OUString
tmpUri(b2u(out
.getName()));
450 throw CannotDumpException("cannot open " + tmpUri
+ " for writing");
452 codemaker::cppumaker::Includes
includes(m_typeMgr
, m_dependencies
, eFileType
);
457 addGetCppuTypeIncludes(includes
);
458 dumpHppFile(out
, includes
);
461 dumpHdlFile(out
, includes
);
463 case FileType::EMBIND_CXX
:
464 dumpEmbindCppFile(out
);
469 // Remove existing type file if something goes wrong to ensure
471 if (fileExists(u2b(fileUri
))) {
472 removeTypeFile(u2b(fileUri
));
474 removeTypeFile(u2b(tmpUri
));
478 (void)makeValidTypeFile(
479 u2b(fileUri
), u2b(tmpUri
), exists
&& options
.isValid("-Gc"_ostr
));
482 void CppuType::dumpDependedTypes(
483 codemaker::GeneratedTypeSet
& generated
, CppuOptions
const & options
) const
485 if (!options
.isValid("-nD"_ostr
)) {
486 codemaker::cppumaker::Dependencies::Map
const & map
487 = m_dependencies
.getMap();
488 for (const auto& entry
: map
) {
489 produce(entry
.first
, m_typeMgr
, generated
, options
);
494 OUString
CppuType::dumpHeaderDefine(
495 FileStream
& out
, std::u16string_view extension
) const
498 "INCLUDED_" + name_
.replace('.', '_').toAsciiUpperCase() + "_"
500 out
<< "#ifndef " << def
<< "\n#define " << def
<< "\n";
504 void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes
& includes
)
507 //TODO: Only include what is really needed
508 includes
.addCppuMacrosHxx();
509 if (m_typeMgr
->getSort(name_
)
510 == codemaker::UnoType::Sort::Interface
) {
511 includes
.addReference();
515 void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes
& includes
)
518 //TODO: Only include what is really needed
520 if (m_typeMgr
->getSort(name_
)
521 == codemaker::UnoType::Sort::Interface
) {
522 includes
.addReference();
526 void CppuType::dumpInitializer(
527 FileStream
& out
, bool parameterized
, std::u16string_view name
) const
530 if (!parameterized
) {
532 std::vector
< OString
> args
;
534 b2u(codemaker::UnoType::decompose(
535 u2b(resolveAllTypedefs(name
)), &k
, &args
)));
537 rtl::Reference
< unoidl::Entity
> ent
;
538 switch (m_typeMgr
->getSort(n
, &ent
)) {
539 case codemaker::UnoType::Sort::Boolean
:
542 case codemaker::UnoType::Sort::Byte
:
543 case codemaker::UnoType::Sort::Short
:
544 case codemaker::UnoType::Sort::UnsignedShort
:
545 case codemaker::UnoType::Sort::Long
:
546 case codemaker::UnoType::Sort::UnsignedLong
:
547 case codemaker::UnoType::Sort::Hyper
:
548 case codemaker::UnoType::Sort::UnsignedHyper
:
549 case codemaker::UnoType::Sort::Float
:
550 case codemaker::UnoType::Sort::Double
:
551 case codemaker::UnoType::Sort::Char
:
554 case codemaker::UnoType::Sort::Enum
:
555 out
<< codemaker::cpp::scopedCppName(u2b(n
)) << "_"
556 << (dynamic_cast<unoidl::EnumTypeEntity
&>(*ent
).
557 getMembers()[0].name
);
559 case codemaker::UnoType::Sort::String
:
560 case codemaker::UnoType::Sort::Type
:
561 case codemaker::UnoType::Sort::Any
:
562 case codemaker::UnoType::Sort::PlainStruct
:
563 case codemaker::UnoType::Sort::PolymorphicStructTemplate
:
564 case codemaker::UnoType::Sort::Interface
:
567 throw CannotDumpException(
568 OUString::Concat("unexpected entity \"") + name
569 + "\" in call to CppuType::dumpInitializer");
576 void CppuType::dumpHFileContent(
577 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
579 addDefaultHIncludes(includes
);
580 dumpHeaderDefine(out
, u
"HDL");
582 includes
.dump(out
, nullptr, false);
583 // 'exceptions = false' would be wrong for services/singletons, but
584 // those don't dump .hdl files anyway
585 out
<< ("\nnamespace com { namespace sun { namespace star { namespace uno"
586 " { class Type; } } } }\n\n");
587 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false)) {
590 dumpDeclaration(out
);
591 if (!(name_
== "com.sun.star.uno.XInterface"
592 || name_
== "com.sun.star.uno.Exception"
593 || isPolymorphic())) {
594 out
<< "\n" << indent()
595 << ("inline ::css::uno::Type const &"
596 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
597 dumpType(out
, name_
, false, false, true);
598 out
<< " const *);\n";
600 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false)) {
604 dumpTemplateHead(out
);
605 out
<< "SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL getCppuType(";
606 dumpType(out
, name_
, true);
607 dumpTemplateParameters(out
);
608 out
<< " *);\n\n#endif\n";
611 void CppuType::dumpEmbindCppFile(FileStream
&out
)
613 out
<< "#ifdef EMSCRIPTEN\n";
614 out
<< "#include <emscripten/bind.h>\n"
615 "#include <" << name_
.replace('.', '/') << ".hpp>\n";
616 out
<< "using namespace emscripten;\n\n";
617 dumpEmbindDeclaration(out
);
621 void CppuType::dumpGetCppuType(FileStream
& out
)
623 if (name_
== "com.sun.star.uno.XInterface") {
625 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
626 " getCppuType(SAL_UNUSED_PARAMETER ");
627 dumpType(out
, name_
, true);
631 << ("return ::cppu::UnoType< ::css::uno::XInterface"
634 out
<< indent() << "}\n";
635 } else if (name_
== "com.sun.star.uno.Exception") {
637 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
638 " getCppuType(SAL_UNUSED_PARAMETER ");
639 dumpType(out
, name_
, true);
643 << ("return ::cppu::UnoType< ::css::uno::Exception"
646 out
<< indent() << "}\n";
647 } else if (m_cppuTypeLeak
) {
648 dumpLightGetCppuType(out
);
649 } else if (m_cppuTypeDynamic
) {
650 dumpNormalGetCppuType(out
);
652 dumpComprehensiveGetCppuType(out
);
656 void CppuType::dumpLightGetCppuType(FileStream
& out
)
658 dumpGetCppuTypePreamble(out
);
660 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
661 << indent() << "if ( !the_type )\n" << indent() << "{\n";
663 out
<< indent() << "typelib_static_type_init( &the_type, "
664 << getTypeClass(name_
, true) << ", \"" << name_
<< "\" );\n";
666 out
<< indent() << "}\n" << indent()
667 << ("return * reinterpret_cast< ::css::uno::Type * >("
669 dumpGetCppuTypePostamble(out
);
672 codemaker::cpp::IdentifierTranslationMode
CppuType::isGlobal() const
674 return name_
.indexOf('.') == -1
675 ? codemaker::cpp::IdentifierTranslationMode::Global
: codemaker::cpp::IdentifierTranslationMode::NonGlobal
;
678 sal_uInt32
CppuType::getInheritedMemberCount()
680 if (m_inheritedMemberCount
== 0) {
681 m_inheritedMemberCount
= checkInheritedMemberCount();
684 return m_inheritedMemberCount
;
687 OUString
CppuType::getTypeClass(OUString
const & name
, bool cStyle
)
689 rtl::Reference
< unoidl::Entity
> ent
;
690 switch (m_typeMgr
->getSort(name
, &ent
)) {
691 case codemaker::UnoType::Sort::Void
:
693 ? OUString("typelib_TypeClass_VOID")
694 : OUString("::css::uno::TypeClass_VOID");
695 case codemaker::UnoType::Sort::Boolean
:
697 ? OUString("typelib_TypeClass_BOOLEAN")
698 : OUString("::css::uno::TypeClass_BOOLEAN");
699 case codemaker::UnoType::Sort::Byte
:
701 ? OUString("typelib_TypeClass_BYTE")
702 : OUString("::css::uno::TypeClass_BYTE");
703 case codemaker::UnoType::Sort::Short
:
705 ? OUString("typelib_TypeClass_SHORT")
706 : OUString("::css::uno::TypeClass_SHORT");
707 case codemaker::UnoType::Sort::UnsignedShort
:
709 ? OUString("typelib_TypeClass_UNSIGNED_SHORT")
710 : OUString("::css::uno::TypeClass_UNSIGNED_SHORT");
711 case codemaker::UnoType::Sort::Long
:
713 ? OUString("typelib_TypeClass_LONG")
714 : OUString("::css::uno::TypeClass_LONG");
715 case codemaker::UnoType::Sort::UnsignedLong
:
717 ? OUString("typelib_TypeClass_UNSIGNED_LONG")
718 : OUString("::css::uno::TypeClass_UNSIGNED_LONG");
719 case codemaker::UnoType::Sort::Hyper
:
721 ? OUString("typelib_TypeClass_HYPER")
722 : OUString("::css::uno::TypeClass_HYPER");
723 case codemaker::UnoType::Sort::UnsignedHyper
:
725 ? OUString("typelib_TypeClass_UNSIGNED_HYPER")
726 : OUString("::css::uno::TypeClass_UNSIGNED_HYPER");
727 case codemaker::UnoType::Sort::Float
:
729 ? OUString("typelib_TypeClass_FLOAT")
730 : OUString("::css::uno::TypeClass_FLOAT");
731 case codemaker::UnoType::Sort::Double
:
733 ? OUString("typelib_TypeClass_DOUBLE")
734 : OUString("::css::uno::TypeClass_DOUBLE");
735 case codemaker::UnoType::Sort::Char
:
737 ? OUString("typelib_TypeClass_CHAR")
738 : OUString("::css::uno::TypeClass_CHAR");
739 case codemaker::UnoType::Sort::String
:
741 ? OUString("typelib_TypeClass_STRING")
742 : OUString("::css::uno::TypeClass_STRING");
743 case codemaker::UnoType::Sort::Type
:
745 ? OUString("typelib_TypeClass_TYPE")
746 : OUString("::css::uno::TypeClass_TYPE");
747 case codemaker::UnoType::Sort::Any
:
749 ? OUString("typelib_TypeClass_ANY")
750 : OUString("::css::uno::TypeClass_ANY");
751 case codemaker::UnoType::Sort::Sequence
:
753 ? OUString("typelib_TypeClass_SEQUENCE")
754 : OUString("::css::uno::TypeClass_SEQUENCE");
755 case codemaker::UnoType::Sort::Enum
:
757 ? OUString("typelib_TypeClass_ENUM")
758 : OUString("::css::uno::TypeClass_ENUM");
759 case codemaker::UnoType::Sort::PlainStruct
:
760 case codemaker::UnoType::Sort::PolymorphicStructTemplate
:
761 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
763 ? OUString("typelib_TypeClass_STRUCT")
764 : OUString("::css::uno::TypeClass_STRUCT");
765 case codemaker::UnoType::Sort::Exception
:
767 ? OUString("typelib_TypeClass_EXCEPTION")
768 : OUString("::css::uno::TypeClass_EXCEPTION");
769 case codemaker::UnoType::Sort::Interface
:
771 ? OUString("typelib_TypeClass_INTERFACE")
772 : OUString("::css::uno::TypeClass_INTERFACE");
773 case codemaker::UnoType::Sort::Typedef
:
774 return getTypeClass(dynamic_cast<unoidl::TypedefEntity
&>(*ent
).getType(), cStyle
);
782 void CppuType::dumpType(
783 FileStream
& out
, std::u16string_view name
, bool isConst
, bool isRef
,
784 bool native
, bool cppuUnoType
) const
787 std::vector
< OString
> args
;
789 b2u(codemaker::UnoType::decompose(
790 u2b(resolveAllTypedefs(name
)), &k
, &args
)));
794 for (sal_Int32 i
= 0; i
!= k
; ++i
) {
796 ? "::cppu::UnoSequenceType" : "::css::uno::Sequence")
799 switch (m_typeMgr
->getSort(n
)) {
800 case codemaker::UnoType::Sort::Void
:
803 case codemaker::UnoType::Sort::Boolean
:
806 case codemaker::UnoType::Sort::Byte
:
809 case codemaker::UnoType::Sort::Short
:
810 out
<< "::sal_Int16";
812 case codemaker::UnoType::Sort::UnsignedShort
:
813 out
<< (cppuUnoType
? "::cppu::UnoUnsignedShortType" : "::sal_uInt16");
815 case codemaker::UnoType::Sort::Long
:
816 out
<< "::sal_Int32";
818 case codemaker::UnoType::Sort::UnsignedLong
:
819 out
<< "::sal_uInt32";
821 case codemaker::UnoType::Sort::Hyper
:
822 out
<< "::sal_Int64";
824 case codemaker::UnoType::Sort::UnsignedHyper
:
825 out
<< "::sal_uInt64";
827 case codemaker::UnoType::Sort::Float
:
830 case codemaker::UnoType::Sort::Double
:
833 case codemaker::UnoType::Sort::Char
:
834 out
<< (cppuUnoType
? "::cppu::UnoCharType" : "::sal_Unicode");
836 case codemaker::UnoType::Sort::String
:
837 out
<< "::rtl::OUString";
839 case codemaker::UnoType::Sort::Type
:
840 out
<< "::css::uno::Type";
842 case codemaker::UnoType::Sort::Any
:
843 out
<< "::css::uno::Any";
845 case codemaker::UnoType::Sort::Enum
:
846 case codemaker::UnoType::Sort::PlainStruct
:
847 case codemaker::UnoType::Sort::Exception
:
848 out
<< codemaker::cpp::scopedCppName(u2b(n
));
850 case codemaker::UnoType::Sort::PolymorphicStructTemplate
:
851 out
<< codemaker::cpp::scopedCppName(u2b(n
));
854 for (std::vector
< OString
>::iterator
i(args
.begin());
855 i
!= args
.end(); ++i
) {
856 if (i
!= args
.begin()) {
859 dumpType(out
, b2u(*i
));
864 case codemaker::UnoType::Sort::Interface
:
866 out
<< "::css::uno::Reference< ";
868 out
<< codemaker::cpp::scopedCppName(u2b(n
));
874 throw CannotDumpException(
875 OUString::Concat("unexpected entity \"") + name
+ "\" in call to CppuType::dumpType");
877 for (sal_Int32 i
= 0; i
!= k
; ++i
) {
885 void CppuType::dumpCppuGetType(
886 FileStream
& out
, std::u16string_view name
, OUString
const * ownName
) const
888 //TODO: What are these calls good for?
891 codemaker::UnoType::Sort sort
= m_typeMgr
->decompose(
892 name
, true, &nucleus
, &rank
, nullptr, nullptr);
893 switch (rank
== 0 ? sort
: codemaker::UnoType::Sort::Sequence
) {
894 case codemaker::UnoType::Sort::Void
:
895 case codemaker::UnoType::Sort::Boolean
:
896 case codemaker::UnoType::Sort::Byte
:
897 case codemaker::UnoType::Sort::Short
:
898 case codemaker::UnoType::Sort::UnsignedShort
:
899 case codemaker::UnoType::Sort::Long
:
900 case codemaker::UnoType::Sort::UnsignedLong
:
901 case codemaker::UnoType::Sort::Hyper
:
902 case codemaker::UnoType::Sort::UnsignedHyper
:
903 case codemaker::UnoType::Sort::Float
:
904 case codemaker::UnoType::Sort::Double
:
905 case codemaker::UnoType::Sort::Char
:
906 case codemaker::UnoType::Sort::String
:
907 case codemaker::UnoType::Sort::Type
:
908 case codemaker::UnoType::Sort::Any
:
910 case codemaker::UnoType::Sort::Sequence
:
911 case codemaker::UnoType::Sort::Enum
:
912 case codemaker::UnoType::Sort::PlainStruct
:
913 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
914 case codemaker::UnoType::Sort::Exception
:
915 case codemaker::UnoType::Sort::Interface
:
916 // Take care of recursion like struct S { sequence<S> x; }:
917 if (ownName
== nullptr || nucleus
!= *ownName
) {
918 out
<< indent() << "::cppu::UnoType< ";
919 dumpType(out
, name
, false, false, false, true);
920 out
<< " >::get();\n";
923 case codemaker::UnoType::Sort::Typedef
:
924 for (;;) std::abort(); // this cannot happen
926 throw CannotDumpException(
927 OUString::Concat("unexpected entity \"") + name
928 + "\" in call to CppuType::dumpCppuGetType");
932 bool CppuType::passByReference(OUString
const & name
) const
934 switch (m_typeMgr
->getSort(resolveOuterTypedefs(name
))) {
935 case codemaker::UnoType::Sort::Boolean
:
936 case codemaker::UnoType::Sort::Byte
:
937 case codemaker::UnoType::Sort::Short
:
938 case codemaker::UnoType::Sort::UnsignedShort
:
939 case codemaker::UnoType::Sort::Long
:
940 case codemaker::UnoType::Sort::UnsignedLong
:
941 case codemaker::UnoType::Sort::Hyper
:
942 case codemaker::UnoType::Sort::UnsignedHyper
:
943 case codemaker::UnoType::Sort::Float
:
944 case codemaker::UnoType::Sort::Double
:
945 case codemaker::UnoType::Sort::Char
:
946 case codemaker::UnoType::Sort::Enum
:
948 case codemaker::UnoType::Sort::String
:
949 case codemaker::UnoType::Sort::Type
:
950 case codemaker::UnoType::Sort::Any
:
951 case codemaker::UnoType::Sort::Sequence
:
952 case codemaker::UnoType::Sort::PlainStruct
:
953 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
954 case codemaker::UnoType::Sort::Interface
:
957 throw CannotDumpException(
958 "unexpected entity \"" + name
959 + "\" in call to CppuType::passByReference");
963 bool CppuType::canBeWarnUnused(OUString
const & name
) const
965 return canBeWarnUnused(name
, 0);
967 bool CppuType::canBeWarnUnused(OUString
const & name
, int depth
) const
969 // prevent infinite recursion and blowing the stack
972 OUString aResolvedName
= resolveOuterTypedefs(name
);
973 switch (m_typeMgr
->getSort(aResolvedName
)) {
974 case codemaker::UnoType::Sort::Boolean
:
975 case codemaker::UnoType::Sort::Byte
:
976 case codemaker::UnoType::Sort::Short
:
977 case codemaker::UnoType::Sort::UnsignedShort
:
978 case codemaker::UnoType::Sort::Long
:
979 case codemaker::UnoType::Sort::UnsignedLong
:
980 case codemaker::UnoType::Sort::Hyper
:
981 case codemaker::UnoType::Sort::UnsignedHyper
:
982 case codemaker::UnoType::Sort::Float
:
983 case codemaker::UnoType::Sort::Double
:
984 case codemaker::UnoType::Sort::Char
:
985 case codemaker::UnoType::Sort::Enum
:
986 case codemaker::UnoType::Sort::String
:
987 case codemaker::UnoType::Sort::Type
:
989 case codemaker::UnoType::Sort::PlainStruct
: {
990 rtl::Reference
< unoidl::Entity
> ent
;
991 m_typeMgr
->getSort(aResolvedName
, &ent
);
992 rtl::Reference
< unoidl::PlainStructTypeEntity
> ent2(
993 dynamic_cast< unoidl::PlainStructTypeEntity
* >(ent
.get()));
994 if (!ent2
->getDirectBase().isEmpty() && !canBeWarnUnused(ent2
->getDirectBase(), depth
+1))
996 for ( const unoidl::PlainStructTypeEntity::Member
& rMember
: ent2
->getDirectMembers()) {
997 if (!canBeWarnUnused(rMember
.type
, depth
+1))
1002 case codemaker::UnoType::Sort::Sequence
: {
1003 OUString aInnerType
= aResolvedName
.copy(2);
1004 return canBeWarnUnused(aInnerType
, depth
+1);
1006 case codemaker::UnoType::Sort::Any
:
1007 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct
:
1008 case codemaker::UnoType::Sort::Interface
:
1011 throw CannotDumpException(
1012 "unexpected entity \"" + name
1013 + "\" in call to CppuType::canBeWarnUnused");
1017 OUString
CppuType::resolveOuterTypedefs(OUString
const & name
) const
1019 for (OUString
n(name
);;) {
1020 rtl::Reference
< unoidl::Entity
> ent
;
1021 if (m_typeMgr
->getSort(n
, &ent
) != codemaker::UnoType::Sort::Typedef
) {
1024 n
= dynamic_cast<unoidl::TypedefEntity
&>(*ent
).getType();
1028 OUString
CppuType::resolveAllTypedefs(std::u16string_view name
) const
1031 OUString
n(b2u(codemaker::UnoType::decompose(u2b(name
), &k1
)));
1033 rtl::Reference
< unoidl::Entity
> ent
;
1034 if (m_typeMgr
->getSort(n
, &ent
) != codemaker::UnoType::Sort::Typedef
) {
1038 n
= b2u(codemaker::UnoType::decompose(
1039 u2b(dynamic_cast<unoidl::TypedefEntity
&>(*ent
).getType()), &k2
));
1040 k1
+= k2
; //TODO: overflow
1042 OUStringBuffer
b(k1
*2 + n
.getLength());
1043 for (sal_Int32 i
= 0; i
!= k1
; ++i
) {
1047 return b
.makeStringAndClear();
1050 void CppuType::inc(sal_Int32 num
)
1052 m_indentLength
+= num
;
1055 void CppuType::dec(sal_Int32 num
)
1057 m_indentLength
= std::max
< sal_Int32
>(m_indentLength
- num
, 0);
1060 OUString
CppuType::indent() const
1062 OUStringBuffer
buf(m_indentLength
);
1063 for (sal_Int32 i
= 0; i
!= m_indentLength
; ++i
) {
1066 return buf
.makeStringAndClear();
1069 bool isDeprecated(std::vector
< OUString
> const & annotations
)
1071 for (const OUString
& r
: annotations
) {
1072 if (r
== "deprecated") {
1079 void dumpDeprecation(FileStream
& out
, bool deprecated
)
1082 out
<< "SAL_DEPRECATED_INTERNAL(\"marked @deprecated in UNOIDL\") ";
1090 rtl::Reference
< TypeManager
> manager
,
1091 rtl::Reference
< unoidl::InterfaceTypeEntity
> const & entity
):
1092 manager_(std::move(manager
)), offset_(0) {
1093 calculateBases(entity
);
1095 BaseOffset(const BaseOffset
&) = delete;
1096 const BaseOffset
& operator=(const BaseOffset
&) = delete;
1098 sal_Int32
get() const {
1103 void calculateBases(
1104 rtl::Reference
< unoidl::InterfaceTypeEntity
> const & entity
);
1106 rtl::Reference
< TypeManager
> manager_
;
1107 std::set
< OUString
> set_
;
1111 void BaseOffset::calculateBases(
1112 rtl::Reference
< unoidl::InterfaceTypeEntity
> const & entity
)
1114 assert(entity
.is());
1115 for (const unoidl::AnnotatedReference
& ar
: entity
->getDirectMandatoryBases()) {
1116 if (set_
.insert(ar
.name
).second
) {
1117 rtl::Reference
< unoidl::Entity
> ent
;
1118 codemaker::UnoType::Sort sort
= manager_
->getSort(ar
.name
, &ent
);
1119 if (sort
!= codemaker::UnoType::Sort::Interface
) {
1120 throw CannotDumpException(
1121 "interface type base " + ar
.name
1122 + " is not an interface type");
1124 rtl::Reference
< unoidl::InterfaceTypeEntity
> ent2(
1125 dynamic_cast< unoidl::InterfaceTypeEntity
* >(ent
.get()));
1127 calculateBases(ent2
);
1128 offset_
+= ent2
->getDirectAttributes().size()
1129 + ent2
->getDirectMethods().size(); //TODO: overflow
1134 class InterfaceType
: public CppuType
1138 rtl::Reference
< unoidl::InterfaceTypeEntity
> const & entity
,
1139 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
);
1141 virtual void dumpDeclaration(FileStream
& o
) override
;
1142 virtual void dumpEmbindDeclaration(FileStream
& o
) override
;
1143 void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
1145 void dumpAttributes(FileStream
& o
) const;
1146 void dumpEmbindAttributeBindings(FileStream
& o
) const;
1147 void dumpMethods(FileStream
& o
) const;
1148 void dumpEmbindMethodBindings(FileStream
& o
, bool bDumpForReference
=false) const;
1149 void dumpEmbindWrapperFunc(FileStream
& o
, const unoidl::InterfaceTypeEntity::Method
& method
, bool bDumpForReference
=false) const;
1150 void dumpNormalGetCppuType(FileStream
& o
) override
;
1151 void dumpComprehensiveGetCppuType(FileStream
& o
) override
;
1152 void dumpCppuAttributeRefs(FileStream
& o
, sal_uInt32
& index
);
1153 void dumpCppuMethodRefs(FileStream
& o
, sal_uInt32
& index
);
1154 void dumpCppuAttributes(FileStream
& o
, sal_uInt32
& index
);
1155 void dumpCppuMethods(FileStream
& o
, sal_uInt32
& index
);
1156 void dumpAttributesCppuDecl(FileStream
& out
, std::set
< OUString
> * seen
) const;
1157 void dumpMethodsCppuDecl(FileStream
& out
, std::set
< OUString
> * seen
) const;
1160 virtual void addComprehensiveGetCppuTypeIncludes(
1161 codemaker::cppumaker::Includes
& includes
) const override
;
1163 virtual sal_uInt32
checkInheritedMemberCount() const override
{
1164 return BaseOffset(m_typeMgr
, entity_
).get();
1167 void dumpExceptionTypeName(
1168 FileStream
& out
, std::u16string_view prefix
, sal_uInt32 index
,
1169 std::u16string_view name
) const;
1171 sal_Int32
dumpExceptionTypeNames(
1172 FileStream
& out
, std::u16string_view prefix
,
1173 std::vector
< OUString
> const & exceptions
, bool runtimeException
) const;
1175 rtl::Reference
< unoidl::InterfaceTypeEntity
> entity_
;
1176 bool m_isDeprecated
;
1179 InterfaceType::InterfaceType(
1180 rtl::Reference
< unoidl::InterfaceTypeEntity
> const & entity
,
1181 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
1182 CppuType(name
, typeMgr
), entity_(entity
),
1183 m_isDeprecated(isDeprecated(entity
->getAnnotations()))
1185 assert(entity
.is());
1188 void InterfaceType::dumpDeclaration(FileStream
& out
)
1190 out
<< "\nclass SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI " << id_
;
1191 for (std::vector
< unoidl::AnnotatedReference
>::const_iterator
i(
1192 entity_
->getDirectMandatoryBases().begin());
1193 i
!= entity_
->getDirectMandatoryBases().end(); ++i
) {
1194 out
<< (i
== entity_
->getDirectMandatoryBases().begin() ? " :" : ",")
1195 << " public " << codemaker::cpp::scopedCppName(u2b(i
->name
));
1197 out
<< "\n{\npublic:\n";
1199 out
<< "#if defined LIBO_INTERNAL_ONLY\n"
1200 << indent() << id_
<< "() = default;\n"
1201 << indent() << id_
<< "(" << id_
<< " const &) = default;\n"
1202 << indent() << id_
<< "(" << id_
<< " &&) = default;\n"
1203 << indent() << id_
<< " & operator =(" << id_
<< " const &) = default;\n"
1204 << indent() << id_
<< " & operator =(" << id_
<< " &&) = default;\n#endif\n\n";
1205 dumpAttributes(out
);
1207 out
<< "\n" << indent()
1208 << ("static inline ::css::uno::Type const & SAL_CALL"
1209 " static_type(void * = 0);\n\n");
1211 out
<< "protected:\n";
1213 out
<< indent() << "~" << id_
1214 << ("() SAL_NOEXCEPT {} // avoid warnings about virtual members and"
1215 " non-virtual dtor\n");
1220 void InterfaceType::dumpEmbindDeclaration(FileStream
& out
)
1222 // TODO: This is a temporary workaround that likely causes the Embind UNO
1223 // bindings to leak memory. Reference counting and cloning mechanisms of
1224 // Embind should be investigated to figure out what exactly we need here.
1225 out
<< "namespace emscripten { namespace internal { \n"
1226 "template<> void raw_destructor<" << codemaker::cpp::scopedCppName(u2b(name_
))
1227 << ">(" << codemaker::cpp::scopedCppName(u2b(name_
)) << "*){}\n"
1230 out
<< "EMSCRIPTEN_BINDINGS(uno_bindings_";
1231 codemaker::cppumaker::dumpTypeFullWithDecorator(out
, name_
, u
"_");
1232 codemaker::cppumaker::dumpTypeIdentifier(out
, name_
);
1235 out
<< "\nclass_<" << codemaker::cpp::scopedCppName(u2b(name_
)) << ">(\"";
1236 codemaker::cppumaker::dumpTypeFullWithDecorator(out
, name_
, u
"$");
1237 codemaker::cppumaker::dumpTypeIdentifier(out
, name_
);
1241 // dump bindings for attributes and methods.
1242 dumpEmbindAttributeBindings(out
);
1243 dumpEmbindMethodBindings(out
);
1244 out
<< indent() << ";\n";
1247 // dump reference bindings.
1248 out
<< "\nclass_<::css::uno::Reference<" << codemaker::cpp::scopedCppName(u2b(name_
)) << ">, base<::css::uno::BaseReference>>(\"";
1249 codemaker::cppumaker::dumpTypeFullWithDecorator(out
, name_
, u
"$");
1250 codemaker::cppumaker::dumpTypeIdentifier(out
, name_
);
1253 out
<< indent() << ".constructor<>()\n"
1254 << indent() << ".constructor<::css::uno::BaseReference, ::css::uno::UnoReference_Query>()\n"
1255 << indent() << ".function(\"is\", &::css::uno::Reference<" << codemaker::cpp::scopedCppName(u2b(name_
)) << ">::is)\n"
1256 << indent() << ".function(\"get\", &::css::uno::Reference<" << codemaker::cpp::scopedCppName(u2b(name_
)) << ">::get, allow_raw_pointers())\n"
1257 << indent() << ".function(\"set\", emscripten::select_overload<bool(const ::css::uno::Any&, com::sun::star::uno::UnoReference_Query)>(&::css::uno::Reference<" << codemaker::cpp::scopedCppName(u2b(name_
)) << ">::set))\n";
1258 dumpEmbindAttributeBindings(out
);
1259 dumpEmbindMethodBindings(out
, true);
1260 out
<< indent() << ";\n";
1267 void InterfaceType::dumpHppFile(
1268 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
1270 OUString
headerDefine(dumpHeaderDefine(out
, u
"HPP"));
1272 addDefaultHxxIncludes(includes
);
1273 includes
.dump(out
, &name_
, !(m_cppuTypeLeak
|| m_cppuTypeDynamic
));
1274 out
<< "\n#if defined LIBO_INTERNAL_ONLY\n#include <type_traits>\n#endif\n\n";
1275 dumpGetCppuType(out
);
1276 out
<< "\n::css::uno::Type const & "
1277 << codemaker::cpp::scopedCppName(u2b(name_
))
1278 << "::static_type(SAL_UNUSED_PARAMETER void *) {\n";
1280 out
<< indent() << "return ::cppu::UnoType< ";
1281 dumpType(out
, name_
, false, false, true);
1282 out
<< " >::get();\n";
1284 out
<< "}\n\n#if defined LIBO_INTERNAL_ONLY\nnamespace cppu::detail {\n";
1285 if (name_
== "com.sun.star.uno.XInterface") {
1286 out
<< "template<typename> struct IsUnoInterfaceType: ::std::false_type {};\n"
1287 "template<typename T> inline constexpr auto isUnoInterfaceType ="
1288 " sizeof (T) && IsUnoInterfaceType<T>::value;\n";
1290 out
<< "template<> struct IsUnoInterfaceType<";
1291 dumpType(out
, name_
, false, false, true);
1292 out
<< ">: ::std::true_type {};\n}\n#endif\n\n#endif // "<< headerDefine
<< "\n";
1295 void InterfaceType::dumpAttributes(FileStream
& out
) const
1297 if (!entity_
->getDirectAttributes().empty()) {
1298 out
<< "\n" << indent() << "// Attributes\n";
1300 for (const unoidl::InterfaceTypeEntity::Attribute
& attr
: entity_
->getDirectAttributes()) {
1301 bool depr
= m_isDeprecated
|| isDeprecated(attr
.annotations
);
1303 dumpDeprecation(out
, depr
);
1305 dumpType(out
, attr
.type
);
1306 out
<< " SAL_CALL get" << attr
.name
<< "() = 0;\n";
1307 if (!attr
.readOnly
) {
1308 bool byRef
= passByReference(attr
.type
);
1310 dumpDeprecation(out
, depr
);
1311 out
<< "virtual void SAL_CALL set" << attr
.name
<< "( ";
1312 dumpType(out
, attr
.type
, byRef
, byRef
);
1313 out
<< " _" << attr
.name
.toAsciiLowerCase() << " ) = 0;\n";
1318 void InterfaceType::dumpEmbindAttributeBindings(FileStream
& out
) const
1320 if (!entity_
->getDirectAttributes().empty())
1322 out
<< indent() << "// Bindings for attributes\n";
1324 for (const unoidl::InterfaceTypeEntity::Attribute
& attr
: entity_
->getDirectAttributes())
1326 if (m_isDeprecated
|| isDeprecated(attr
.annotations
))
1330 out
<< ".function(\"";
1331 out
<< "get" << attr
.name
<< "\", &" << codemaker::cpp::scopedCppName(u2b(name_
)) << "::get"
1332 << attr
.name
<< ")\n";
1336 out
<< ".function(\"";
1337 out
<< "set" << attr
.name
<< "\", &" << codemaker::cpp::scopedCppName(u2b(name_
))
1338 << "::set" << attr
.name
<< ")\n";
1343 void InterfaceType::dumpMethods(FileStream
& out
) const
1345 if (!entity_
->getDirectMethods().empty()) {
1346 out
<< "\n" << indent() << "// Methods\n";
1348 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity_
->getDirectMethods()) {
1350 dumpDeprecation(out
, m_isDeprecated
|| isDeprecated(method
.annotations
));
1352 dumpType(out
, method
.returnType
);
1353 out
<< " SAL_CALL " << method
.name
<< "(";
1354 if (!method
.parameters
.empty()) {
1356 for (std::vector
< unoidl::InterfaceTypeEntity::Method::Parameter
>::
1357 const_iterator
j(method
.parameters
.begin());
1358 j
!= method
.parameters
.end();) {
1362 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
)
1364 isConst
= passByReference(j
->type
);
1370 dumpType(out
, j
->type
, isConst
, isRef
);
1371 out
<< " " << j
->name
;
1373 if (j
!= method
.parameters
.end()) {
1383 void InterfaceType::dumpEmbindWrapperFunc(FileStream
& out
,
1384 const unoidl::InterfaceTypeEntity::Method
& method
,
1385 bool bDumpForReference
) const
1388 out
<< ".function(\"" << method
.name
<< "\", ";
1389 out
<< indent() << "+[](";
1390 if (bDumpForReference
)
1391 out
<< "::css::uno::Reference<";
1392 out
<< codemaker::cpp::scopedCppName(u2b(name_
));
1393 if (bDumpForReference
)
1396 if(!method
.parameters
.empty())
1399 auto dumpParameters
= [&](bool bDumpType
)
1401 // dumpParams with references as pointers
1402 if (!method
.parameters
.empty())
1405 for (std::vector
<unoidl::InterfaceTypeEntity::Method::Parameter
>::const_iterator
1406 parameter(method
.parameters
.begin());
1407 parameter
!= method
.parameters
.end();)
1411 if (parameter
->direction
1412 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
)
1414 isConst
= passByReference(parameter
->type
);
1422 // for the embind wrapper, we define a pointer instead of a reference.
1424 dumpType(out
, parameter
->type
, isConst
, /*isRef=*/false);
1428 out
<< " " << parameter
->name
;
1430 if (parameter
!= method
.parameters
.end())
1438 dumpParameters(/*bDumpType=*/true);
1440 if (bDumpForReference
)
1442 out
<< ") { return self->get()->" << method
.name
<< "(";
1446 out
<< ") { return self->" << method
.name
<< "(";
1449 dumpParameters(/*bDumpType=*/false);
1450 out
<< "); }, allow_raw_pointers() )\n";
1453 void InterfaceType::dumpEmbindMethodBindings(FileStream
& out
, bool bDumpForReference
) const
1455 if (!entity_
->getDirectMethods().empty()) {
1456 out
<< indent() << "// Bindings for methods\n";
1458 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity_
->getDirectMethods()) {
1459 if( m_isDeprecated
|| isDeprecated(method
.annotations
) )
1462 // if dumping the method binding for a reference implementation
1464 if(bDumpForReference
)
1466 dumpEmbindWrapperFunc(out
, method
, true);
1470 bool bHasOutParams
= std::any_of(
1471 method
.parameters
.begin(), method
.parameters
.end(),
1472 [](const auto& parameter
) {
1473 return parameter
.direction
1474 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
;
1479 dumpEmbindWrapperFunc(out
, method
, false);
1484 out
<< ".function(\"" << method
.name
<< "\", &"
1485 << codemaker::cpp::scopedCppName(u2b(name_
))
1486 << "::" << method
.name
<< ")\n";
1492 void InterfaceType::dumpNormalGetCppuType(FileStream
& out
)
1494 dumpGetCppuTypePreamble(out
);
1496 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
1497 << indent() << "if ( !the_type )\n" << indent() << "{\n";
1499 std::vector
< unoidl::AnnotatedReference
>::size_type
bases(
1500 entity_
->getDirectMandatoryBases().size());
1502 && (entity_
->getDirectMandatoryBases()[0].name
1503 == "com.sun.star.uno.XInterface")) {
1507 out
<< indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1508 << entity_
->getDirectMandatoryBases().size() << "];\n";
1509 std::vector
< unoidl::AnnotatedReference
>::size_type n
= 0;
1510 for (const unoidl::AnnotatedReference
& ar
: entity_
->getDirectMandatoryBases()) {
1511 out
<< indent() << "aSuperTypes[" << n
++ << "] = ::cppu::UnoType< ";
1512 dumpType(out
, ar
.name
, true, false, false, true);
1513 out
<< " >::get().getTypeLibType();\n";
1516 out
<< indent() << "typelib_static_mi_interface_type_init( &the_type, \""
1517 << name_
<< "\", " << bases
<< ", "
1518 << (bases
== 0 ? "0" : "aSuperTypes") << " );\n";
1520 out
<< indent() << "}\n" << indent()
1521 << ("return * reinterpret_cast< ::css::uno::Type * >("
1523 dumpGetCppuTypePostamble(out
);
1526 void InterfaceType::dumpComprehensiveGetCppuType(FileStream
& out
)
1528 codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false);
1529 OUString
staticTypeClass("the" + id_
+ "Type");
1530 out
<< " namespace detail {\n\n" << indent() << "struct " << staticTypeClass
1531 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
1532 << staticTypeClass
<< " >\n" << indent() << "{\n";
1534 out
<< indent() << "::css::uno::Type * operator()() const\n"
1535 << indent() << "{\n";
1537 out
<< indent() << "::rtl::OUString sTypeName( \"" << name_
<< "\" );\n\n"
1538 << indent() << "// Start inline typedescription generation\n"
1539 << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n";
1540 out
<< indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1541 << entity_
->getDirectMandatoryBases().size() << "];\n";
1542 std::vector
< unoidl::AnnotatedReference
>::size_type n
= 0;
1543 for (const unoidl::AnnotatedReference
& ar
: entity_
->getDirectMandatoryBases()) {
1544 out
<< indent() << "aSuperTypes[" << n
++ << "] = ::cppu::UnoType< ";
1545 dumpType(out
, ar
.name
, false, false, false, true);
1546 out
<< " >::get().getTypeLibType();\n";
1548 std::size_t count
= entity_
->getDirectAttributes().size()
1549 + entity_
->getDirectMethods().size(); //TODO: overflow
1551 out
<< indent() << "typelib_TypeDescriptionReference * pMembers["
1552 << count
<< "] = { ";
1553 for (std::size_t i
= 0; i
!= count
; ++i
) {
1555 if (i
+ 1 != count
) {
1560 sal_uInt32 index
= 0;
1561 dumpCppuAttributeRefs(out
, index
);
1562 dumpCppuMethodRefs(out
, index
);
1564 out
<< "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1566 out
<< indent() << "&pTD,\n" << indent()
1567 << "sTypeName.pData, 0, 0, 0, 0, 0,\n" << indent()
1568 << entity_
->getDirectMandatoryBases().size() << ", aSuperTypes,\n"
1569 << indent() << count
<< ",\n" << indent()
1570 << (count
== 0 ? "0" : "pMembers") << " );\n\n";
1573 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1575 for (std::size_t i
= 0; i
!= count
; ++i
) {
1576 out
<< indent() << "typelib_typedescriptionreference_release( pMembers["
1580 << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1582 << indent() << "return new ::css::uno::Type( "
1583 << getTypeClass(name_
) << ", sTypeName ); // leaked\n";
1585 out
<< indent() << "}\n";
1587 out
<< indent() << "};\n\n";
1588 codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false);
1590 dumpGetCppuTypePreamble(out
);
1591 out
<< indent() << "const ::css::uno::Type &rRet = *detail::"
1592 << staticTypeClass
<< "::get();\n" << indent()
1593 << "// End inline typedescription generation\n" << indent()
1594 << "static bool bInitStarted = false;\n" << indent()
1595 << "if (!bInitStarted)\n" << indent() << "{\n";
1598 << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"
1599 << indent() << "if (!bInitStarted)\n" << indent() << "{\n";
1601 out
<< indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"
1602 << indent() << "bInitStarted = true;\n";
1603 std::set
< OUString
> seen
;
1604 // Type for RuntimeException is always needed:
1605 seen
.insert("com.sun.star.uno.RuntimeException");
1606 dumpCppuGetType(out
, u
"com.sun.star.uno.RuntimeException");
1607 dumpAttributesCppuDecl(out
, &seen
);
1608 dumpMethodsCppuDecl(out
, &seen
);
1610 sal_uInt32 index
= getInheritedMemberCount();
1611 dumpCppuAttributes(out
, index
);
1612 dumpCppuMethods(out
, index
);
1615 out
<< indent() << "}\n";
1617 out
<< indent() << "}\n" << indent() << "else\n" << indent() << "{\n";
1619 out
<< indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
1621 out
<< indent() << "}\n" << indent() << "return rRet;\n";
1622 dumpGetCppuTypePostamble(out
);
1625 void InterfaceType::dumpCppuAttributeRefs(FileStream
& out
, sal_uInt32
& index
)
1627 std::vector
< unoidl::InterfaceTypeEntity::Attribute
>::size_type n
= 0;
1628 for (const unoidl::InterfaceTypeEntity::Attribute
& attr
: entity_
->getDirectAttributes()) {
1629 out
<< indent() << "::rtl::OUString sAttributeName" << n
<< "( \""
1630 << name_
<< "::" << attr
.name
<< "\" );\n" << indent()
1631 << "typelib_typedescriptionreference_new( &pMembers[" << index
++
1635 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_ATTRIBUTE,\n"
1636 << indent() << "sAttributeName" << n
<< ".pData );\n";
1642 void InterfaceType::dumpCppuMethodRefs(FileStream
& out
, sal_uInt32
& index
)
1644 std::vector
< unoidl::InterfaceTypeEntity::Method
>::size_type n
= 0;
1645 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity_
->getDirectMethods()) {
1646 out
<< indent() << "::rtl::OUString sMethodName" << n
<< "( \"" << name_
1647 << "::" << method
.name
<< "\" );\n" << indent()
1648 << "typelib_typedescriptionreference_new( &pMembers[" << index
++
1652 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_METHOD,\n"
1653 << indent() << "sMethodName" << n
<< ".pData );\n";
1659 void InterfaceType::addComprehensiveGetCppuTypeIncludes(
1660 codemaker::cppumaker::Includes
& includes
) const
1662 // The comprehensive getCppuType method always includes a line
1663 // "getCppuType( (const ::css::uno::RuntimeException*)0 );":
1664 includes
.addCppuUnotypeHxx();
1665 includes
.addRtlInstanceHxx(); // using rtl::StaticWithInit
1666 includes
.addOslMutexHxx();
1667 includes
.add("com.sun.star.uno.RuntimeException"_ostr
);
1670 void InterfaceType::dumpCppuAttributes(FileStream
& out
, sal_uInt32
& index
)
1672 if (entity_
->getDirectAttributes().empty())
1675 out
<< "\n" << indent()
1676 << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
1677 std::vector
< unoidl::InterfaceTypeEntity::Attribute
>::size_type n
= 0;
1678 for (const unoidl::InterfaceTypeEntity::Attribute
& attr
: entity_
->getDirectAttributes()) {
1679 OUString
type(resolveAllTypedefs(attr
.type
));
1680 out
<< indent() << "{\n";
1682 out
<< indent() << "::rtl::OUString sAttributeType" << n
<< "( \""
1683 << type
<< "\" );\n" << indent()
1684 << "::rtl::OUString sAttributeName" << n
<< "( \"" << name_
1685 << "::" << attr
.name
<< "\" );\n";
1686 sal_Int32 getExcn
= dumpExceptionTypeNames(
1687 out
, u
"get", attr
.getExceptions
, false);
1688 sal_Int32 setExcn
= dumpExceptionTypeNames(
1689 out
, u
"set", attr
.setExceptions
, false);
1691 << ("typelib_typedescription_newExtendedInterfaceAttribute("
1694 out
<< indent() << index
++ << ", sAttributeName" << n
1695 << ".pData,\n" << indent() << "(typelib_TypeClass)"
1696 << getTypeClass(type
) << ", sAttributeType" << n
<< ".pData,\n"
1697 << indent() << "sal_" << (attr
.readOnly
? "True" : "False")
1698 << ", " << getExcn
<< ", "
1699 << (getExcn
== 0 ? "0" : "the_getExceptions") << ", " << setExcn
1700 << ", " << (setExcn
== 0 ? "0" : "the_setExceptions")
1704 << ("typelib_typedescription_register("
1705 " (typelib_TypeDescription**)&pAttribute );\n");
1707 out
<< indent() << "}\n";
1711 << ("typelib_typedescription_release("
1712 " (typelib_TypeDescription*)pAttribute );\n");
1715 void InterfaceType::dumpCppuMethods(FileStream
& out
, sal_uInt32
& index
)
1717 if (entity_
->getDirectMethods().empty())
1720 out
<< "\n" << indent()
1721 << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
1722 std::vector
< unoidl::InterfaceTypeEntity::Method
>::size_type n
= 0;
1723 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity_
->getDirectMethods()) {
1724 OUString
returnType(resolveAllTypedefs(method
.returnType
));
1725 out
<< indent() << "{\n";
1727 if (!method
.parameters
.empty()) {
1728 out
<< indent() << "typelib_Parameter_Init aParameters["
1729 << method
.parameters
.size() << "];\n";
1731 std::vector
< unoidl::InterfaceTypeEntity::Method::Parameter
>::
1733 for (const unoidl::InterfaceTypeEntity::Method::Parameter
& param
: method
.parameters
) {
1734 OUString
type(resolveAllTypedefs(param
.type
));
1735 out
<< indent() << "::rtl::OUString sParamName" << m
<< "( \""
1736 << param
.name
<< "\" );\n" << indent()
1737 << "::rtl::OUString sParamType" << m
<< "( \"" << type
1738 << "\" );\n" << indent() << "aParameters[" << m
1739 << "].pParamName = sParamName" << m
<< ".pData;\n"
1740 << indent() << "aParameters[" << m
1741 << "].eTypeClass = (typelib_TypeClass)"
1742 << getTypeClass(type
) << ";\n" << indent() << "aParameters["
1743 << m
<< "].pTypeName = sParamType" << m
<< ".pData;\n"
1744 << indent() << "aParameters[" << m
<< "].bIn = "
1745 << ((param
.direction
1746 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
)
1747 ? "sal_False" : "sal_True")
1748 << ";\n" << indent() << "aParameters[" << m
<< "].bOut = "
1749 << ((param
.direction
1750 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
)
1751 ? "sal_False" : "sal_True")
1755 sal_Int32 excn
= dumpExceptionTypeNames(
1756 out
, u
"", method
.exceptions
,
1757 method
.name
!= "acquire" && method
.name
!= "release");
1758 out
<< indent() << "::rtl::OUString sReturnType" << n
<< "( \""
1759 << returnType
<< "\" );\n" << indent()
1760 << "::rtl::OUString sMethodName" << n
<< "( \"" << name_
<< "::"
1761 << method
.name
<< "\" );\n" << indent()
1762 << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
1764 out
<< indent() << index
++ << ", sal_False,\n" << indent()
1765 << "sMethodName" << n
<< ".pData,\n" << indent()
1766 << "(typelib_TypeClass)" << getTypeClass(returnType
)
1767 << ", sReturnType" << n
<< ".pData,\n" << indent()
1768 << method
.parameters
.size() << ", "
1769 << (method
.parameters
.empty() ? "0" : "aParameters") << ",\n"
1770 << indent() << excn
<< ", "
1771 << (excn
== 0 ? "0" : "the_Exceptions") << " );\n";
1774 << ("typelib_typedescription_register("
1775 " (typelib_TypeDescription**)&pMethod );\n");
1777 out
<< indent() << "}\n";
1781 << ("typelib_typedescription_release("
1782 " (typelib_TypeDescription*)pMethod );\n");
1785 void InterfaceType::dumpAttributesCppuDecl(
1786 FileStream
& out
, std::set
< OUString
> * seen
) const
1788 assert(seen
!= nullptr);
1789 for (const unoidl::InterfaceTypeEntity::Attribute
& attr
: entity_
->getDirectAttributes()) {
1790 if (seen
->insert(attr
.type
).second
) {
1791 dumpCppuGetType(out
, attr
.type
);
1793 for (const OUString
& exc
: attr
.getExceptions
) {
1794 if (seen
->insert(exc
).second
) {
1795 dumpCppuGetType(out
, exc
);
1798 for (const OUString
& exc
: attr
.setExceptions
) {
1799 if (seen
->insert(exc
).second
) {
1800 dumpCppuGetType(out
, exc
);
1806 void InterfaceType::dumpMethodsCppuDecl(
1807 FileStream
& out
, std::set
< OUString
> * seen
) const
1809 assert(seen
!= nullptr);
1810 for (const unoidl::InterfaceTypeEntity::Method
& method
: entity_
->getDirectMethods()) {
1811 for (const OUString
& ex
: method
.exceptions
) {
1812 if (seen
->insert(ex
).second
) {
1813 dumpCppuGetType(out
, ex
);
1819 void InterfaceType::dumpExceptionTypeName(
1820 FileStream
& out
, std::u16string_view prefix
, sal_uInt32 index
,
1821 std::u16string_view name
) const
1823 out
<< indent() << "::rtl::OUString the_" << prefix
<< "ExceptionName"
1824 << index
<< "( \"" << name
<< "\" );\n";
1827 sal_Int32
InterfaceType::dumpExceptionTypeNames(
1828 FileStream
& out
, std::u16string_view prefix
,
1829 std::vector
< OUString
> const & exceptions
, bool runtimeException
) const
1831 sal_Int32 count
= 0;
1832 for (const OUString
& ex
: exceptions
) {
1833 if (ex
!= "com.sun.star.uno.RuntimeException") {
1834 dumpExceptionTypeName(out
, prefix
, count
++, ex
);
1837 if (runtimeException
) {
1838 dumpExceptionTypeName(
1839 out
, prefix
, count
++, u
"com.sun.star.uno.RuntimeException");
1842 out
<< indent() << "rtl_uString * the_" << prefix
<< "Exceptions[] = {";
1843 for (sal_Int32 i
= 0; i
!= count
; ++i
) {
1844 out
<< (i
== 0 ? " " : ", ") << "the_" << prefix
<< "ExceptionName"
1852 class ConstantGroup
: public CppuType
1856 rtl::Reference
< unoidl::ConstantGroupEntity
> const & entity
,
1857 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
1858 CppuType(name
, typeMgr
), entity_(entity
) {
1859 assert(entity
.is());
1862 bool hasConstants() const {
1863 return !entity_
->getMembers().empty();
1867 virtual void dumpHdlFile(
1868 FileStream
& out
, codemaker::cppumaker::Includes
& includes
) override
;
1870 virtual void dumpHppFile(
1871 FileStream
& out
, codemaker::cppumaker::Includes
& includes
) override
;
1873 virtual void dumpDeclaration(FileStream
& out
) override
;
1875 rtl::Reference
< unoidl::ConstantGroupEntity
> entity_
;
1878 void ConstantGroup::dumpHdlFile(
1879 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
1881 OUString
headerDefine(dumpHeaderDefine(out
, u
"HDL"));
1883 addDefaultHIncludes(includes
);
1884 includes
.dump(out
, nullptr, true);
1886 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, true)) {
1890 dumpDeclaration(out
);
1892 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, true)) {
1895 out
<< "\n#endif // "<< headerDefine
<< "\n";
1898 void ConstantGroup::dumpHppFile(
1899 FileStream
& out
, codemaker::cppumaker::Includes
&)
1901 OUString
headerDefine(dumpHeaderDefine(out
, u
"HPP"));
1903 codemaker::cppumaker::Includes::dumpInclude(out
, u2b(name_
), false);
1904 out
<< "\n#endif // "<< headerDefine
<< "\n";
1907 void ConstantGroup::dumpDeclaration(FileStream
& out
)
1909 for (const unoidl::ConstantGroupEntity::Member
& member
: entity_
->getMembers()) {
1910 out
<< "static const ";
1911 switch (member
.value
.type
) {
1912 case unoidl::ConstantValue::TYPE_BOOLEAN
:
1913 out
<< "::sal_Bool";
1915 case unoidl::ConstantValue::TYPE_BYTE
:
1916 out
<< "::sal_Int8";
1918 case unoidl::ConstantValue::TYPE_SHORT
:
1919 out
<< "::sal_Int16";
1921 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
1922 out
<< "::sal_uInt16";
1924 case unoidl::ConstantValue::TYPE_LONG
:
1925 out
<< "::sal_Int32";
1927 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
1928 out
<< "::sal_uInt32";
1930 case unoidl::ConstantValue::TYPE_HYPER
:
1931 out
<< "::sal_Int64";
1933 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
1934 out
<< "::sal_uInt64";
1936 case unoidl::ConstantValue::TYPE_FLOAT
:
1939 case unoidl::ConstantValue::TYPE_DOUBLE
:
1943 out
<< " " << member
.name
<< " = ";
1944 switch (member
.value
.type
) {
1945 case unoidl::ConstantValue::TYPE_BOOLEAN
:
1946 out
<< (member
.value
.booleanValue
? "sal_True" : "sal_False");
1948 case unoidl::ConstantValue::TYPE_BYTE
:
1949 out
<< "(sal_Int8)" << OUString::number(member
.value
.byteValue
);
1951 case unoidl::ConstantValue::TYPE_SHORT
:
1952 out
<< "(sal_Int16)" << OUString::number(member
.value
.shortValue
);
1954 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
1955 out
<< "(sal_uInt16)"
1956 << OUString::number(member
.value
.unsignedShortValue
);
1958 case unoidl::ConstantValue::TYPE_LONG
:
1959 // Avoid C++ compiler warnings about (un)signedness of literal
1961 if (member
.value
.longValue
== SAL_MIN_INT32
) {
1962 out
<< "SAL_MIN_INT32";
1964 out
<< "(sal_Int32)" << OUString::number(member
.value
.longValue
);
1967 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
1968 out
<< "(sal_uInt32)"
1969 << OUString::number(member
.value
.unsignedLongValue
) << "U";
1971 case unoidl::ConstantValue::TYPE_HYPER
:
1972 // Avoid C++ compiler warnings about (un)signedness of literal
1974 if (member
.value
.hyperValue
== SAL_MIN_INT64
) {
1975 out
<< "SAL_MIN_INT64";
1977 out
<< "(sal_Int64) SAL_CONST_INT64("
1978 << OUString::number(member
.value
.hyperValue
) << ")";
1981 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
1982 out
<< "SAL_CONST_UINT64("
1983 << OUString::number(member
.value
.unsignedHyperValue
) << ")";
1985 case unoidl::ConstantValue::TYPE_FLOAT
:
1986 out
<< "(float)" << OUString::number(member
.value
.floatValue
);
1988 case unoidl::ConstantValue::TYPE_DOUBLE
:
1989 out
<< "(double)" << OUString::number(member
.value
.doubleValue
);
1996 void dumpTypeParameterName(FileStream
& out
, std::u16string_view name
)
1998 // Prefix all type parameters with "typeparam_" to avoid problems when a
1999 // struct member has the same name as a type parameter, as in
2000 // struct<T> { T T; };
2001 out
<< "typeparam_" << name
;
2004 class PlainStructType
: public CppuType
2008 rtl::Reference
< unoidl::PlainStructTypeEntity
> const & entity
,
2009 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
2010 CppuType(name
, typeMgr
), entity_(entity
) {
2011 assert(entity
.is());
2015 virtual sal_uInt32
checkInheritedMemberCount() const override
{
2016 return getTotalMemberCount(entity_
->getDirectBase());
2019 virtual void dumpDeclaration(FileStream
& o
) override
;
2021 void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
2023 virtual void dumpLightGetCppuType(FileStream
& out
) override
;
2025 virtual void dumpNormalGetCppuType(FileStream
& out
) override
;
2027 virtual void dumpComprehensiveGetCppuType(FileStream
& out
) override
;
2029 virtual void addLightGetCppuTypeIncludes(
2030 codemaker::cppumaker::Includes
& includes
) const override
;
2032 virtual void addNormalGetCppuTypeIncludes(
2033 codemaker::cppumaker::Includes
& includes
) const override
;
2035 virtual void addComprehensiveGetCppuTypeIncludes(
2036 codemaker::cppumaker::Includes
& includes
) const override
;
2038 bool dumpBaseMembers(
2039 FileStream
& out
, OUString
const & base
, bool withType
);
2041 sal_uInt32
getTotalMemberCount(OUString
const & base
) const;
2043 rtl::Reference
< unoidl::PlainStructTypeEntity
> entity_
;
2046 void PlainStructType::dumpDeclaration(FileStream
& out
)
2048 out
<< "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
2049 out
<< "struct SAL_DLLPUBLIC_RTTI ";
2050 if (canBeWarnUnused(name_
))
2051 out
<< "SAL_WARN_UNUSED ";
2053 OUString
base(entity_
->getDirectBase());
2054 if (!base
.isEmpty()) {
2055 out
<< ": public " << codemaker::cpp::scopedCppName(u2b(base
));
2059 out
<< indent() << "inline " << id_
<< "();\n";
2060 if (!entity_
->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
2061 out
<< "\n" << indent() << "inline " << id_
<< "(";
2062 bool bFirst
= !dumpBaseMembers(out
, base
, true);
2063 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2067 dumpType(out
, member
.type
, true, true);
2068 out
<< " " << member
.name
<< "_";
2073 if (!entity_
->getDirectMembers().empty()) {
2075 for (std::vector
< unoidl::PlainStructTypeEntity::Member
>::
2076 const_iterator
i(entity_
->getDirectMembers().begin());
2077 i
!= entity_
->getDirectMembers().end(); ++i
) {
2079 dumpType(out
, i
->type
);
2080 out
<< " " << i
->name
;
2081 if (i
== entity_
->getDirectMembers().begin() && !base
.isEmpty()
2082 && i
->type
!= "hyper" && i
->type
!= "unsigned hyper"
2083 && i
->type
!= "double") {
2084 out
<< " CPPU_GCC3_ALIGN("
2085 << codemaker::cpp::scopedCppName(u2b(base
)) << ")";
2091 out
<< "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
2094 void PlainStructType::dumpHppFile(
2095 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
2097 OUString
headerDefine(dumpHeaderDefine(out
, u
"HPP"));
2099 includes
.dump(out
, &name_
, true);
2101 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false)) {
2104 out
<< "\ninline " << id_
<< "::" << id_
<< "()\n";
2106 OUString
base(entity_
->getDirectBase());
2108 if (!base
.isEmpty()) {
2109 out
<< indent() << ": " << codemaker::cpp::scopedCppName(u2b(base
))
2113 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2114 out
<< indent() << (bFirst
? ":" : ",") << " " << member
.name
;
2115 dumpInitializer(out
, false, member
.type
);
2121 if (!entity_
->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
2122 out
<< "inline " << id_
;
2123 out
<< "::" << id_
<< "(";
2124 bFirst
= !dumpBaseMembers(out
, base
, true);
2125 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2129 dumpType(out
, member
.type
, true, true);
2130 out
<< " " << member
.name
<< "_";
2136 if (!base
.isEmpty()) {
2137 out
<< indent() << ": " << codemaker::cpp::scopedCppName(u2b(base
))
2139 dumpBaseMembers(out
, base
, false);
2143 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2144 out
<< indent() << (bFirst
? ":" : ",") << " " << member
.name
<< "("
2145 << member
.name
<< "_)\n";
2151 // print the operator==
2152 out
<< "\ninline bool operator==(const " << id_
<< "& the_lhs, const " << id_
<< "& the_rhs)\n";
2155 out
<< indent() << "return ";
2157 if (!base
.isEmpty()) {
2158 out
<< "operator==( static_cast< " << codemaker::cpp::scopedCppName(u2b(base
))
2159 << ">(the_lhs), static_cast< " << codemaker::cpp::scopedCppName(u2b(base
)) << ">(the_rhs) )\n";
2162 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2164 out
<< "\n" << indent() << indent() << "&& ";
2165 out
<< "the_lhs." << member
.name
<< " == the_rhs." << member
.name
;
2171 // print the operator!=
2172 out
<< "\ninline bool operator!=(const " << id_
<< "& the_lhs, const " << id_
<< "& the_rhs)\n";
2174 out
<< indent() << "return !operator==(the_lhs, the_rhs);\n";
2177 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false)) {
2181 dumpGetCppuType(out
);
2182 out
<< "\n#endif // "<< headerDefine
<< "\n";
2185 void PlainStructType::dumpLightGetCppuType(FileStream
& out
)
2187 dumpGetCppuTypePreamble(out
);
2189 << ("//TODO: On certain platforms with weak memory models, the"
2190 " following code can result in some threads observing that the_type"
2191 " points to garbage\n")
2193 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2194 << indent() << "if (the_type == 0) {\n";
2196 out
<< indent() << "::typelib_static_type_init(&the_type, "
2197 << getTypeClass(name_
, true) << ", \"" << name_
<< "\");\n";
2199 out
<< indent() << "}\n" << indent()
2200 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2201 dumpGetCppuTypePostamble(out
);
2204 void PlainStructType::dumpNormalGetCppuType(FileStream
& out
)
2206 dumpGetCppuTypePreamble(out
);
2208 << ("//TODO: On certain platforms with weak memory models, the"
2209 " following code can result in some threads observing that the_type"
2210 " points to garbage\n")
2212 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2213 << indent() << "if (the_type == 0) {\n";
2216 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2218 for (std::vector
< unoidl::PlainStructTypeEntity::Member
>::const_iterator
i(
2219 entity_
->getDirectMembers().begin());
2220 i
!= entity_
->getDirectMembers().end();) {
2221 out
<< indent() << "::cppu::UnoType< ";
2222 dumpType(out
, i
->type
, false, false, false, true);
2224 out
<< " >::get().getTypeLibType()"
2225 << (i
== entity_
->getDirectMembers().end() ? " };" : ",") << "\n";
2228 out
<< indent() << "::typelib_static_struct_type_init(&the_type, \""
2230 if (entity_
->getDirectBase().isEmpty()) {
2233 out
<< "::cppu::UnoType< ";
2234 dumpType(out
, entity_
->getDirectBase(), false, false, false, true);
2235 out
<< " >::get().getTypeLibType()";
2237 out
<< ", " << entity_
->getDirectMembers().size() << ", the_members, 0);\n";
2239 out
<< indent() << "}\n" << indent()
2240 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2241 dumpGetCppuTypePostamble(out
);
2244 void PlainStructType::dumpComprehensiveGetCppuType(FileStream
& out
)
2246 OUString
staticTypeClass("the" + id_
+ "Type");
2247 codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false);
2248 out
<< " namespace detail {\n\n" << indent() << "struct "
2250 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2251 << staticTypeClass
<< " >\n" << indent() << "{\n";
2253 out
<< indent() << "::css::uno::Type * operator()() const\n"
2254 << indent() << "{\n";
2256 out
<< indent() << "::rtl::OUString the_name( \"" << name_
<< "\" );\n";
2257 std::map
< OUString
, sal_uInt32
> types
;
2258 std::vector
< unoidl::PlainStructTypeEntity::Member
>::size_type n
= 0;
2259 for (const unoidl::PlainStructTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
2261 member
.type
, static_cast< sal_uInt32
>(types
.size())).
2263 dumpCppuGetType(out
, member
.type
, &name_
);
2264 // For typedefs, use the resolved type name, as there will be no
2265 // information available about the typedef itself at runtime (the
2266 // above getCppuType call will make available information about the
2267 // resolved type); no extra #include for the resolved type is
2268 // needed, as the header for the typedef includes it already:
2269 out
<< indent() << "::rtl::OUString the_tname"
2270 << static_cast< sal_uInt32
>(types
.size() - 1) << "( \""
2271 << resolveAllTypedefs(member
.type
) << "\" );\n";
2273 out
<< indent() << "::rtl::OUString the_name" << n
++ << "( \""
2274 << member
.name
<< "\" );\n";
2276 out
<< indent() << "::typelib_StructMember_Init the_members[] = {\n";
2279 for (std::vector
< unoidl::PlainStructTypeEntity::Member
>::const_iterator
i(
2280 entity_
->getDirectMembers().begin());
2281 i
!= entity_
->getDirectMembers().end();) {
2282 const auto iter
= types
.find(i
->type
);
2283 assert(iter
!= types
.end());
2284 out
<< indent() << "{ { " << getTypeClass(i
->type
, true)
2285 << ", the_tname" << iter
->second
2286 << ".pData, the_name" << n
++ << ".pData }, false }";
2288 out
<< (i
== entity_
->getDirectMembers().end() ? " };" : ",") << "\n";
2291 out
<< indent() << "::typelib_TypeDescription * the_newType = 0;\n"
2293 << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2294 if (entity_
->getDirectBase().isEmpty()) {
2297 out
<< "::cppu::UnoType< ";
2298 dumpType(out
, entity_
->getDirectBase(), false, false, false, true);
2299 out
<< " >::get().getTypeLibType()";
2301 out
<< ", " << entity_
->getDirectMembers().size() << ", the_members);\n"
2302 << indent() << "::typelib_typedescription_register(&the_newType);\n"
2303 << indent() << "::typelib_typedescription_release(the_newType);\n"
2304 << indent() << "return new ::css::uno::Type("
2305 << getTypeClass(name_
) << ", the_name); // leaked\n";
2307 out
<< indent() << "}\n";
2309 out
<< indent() << "};\n";
2310 codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false);
2312 dumpGetCppuTypePreamble(out
);
2313 out
<< indent() << "return *detail::" << staticTypeClass
<< "::get();\n";
2314 dumpGetCppuTypePostamble(out
);
2317 bool PlainStructType::dumpBaseMembers(
2318 FileStream
& out
, OUString
const & base
, bool withType
)
2323 rtl::Reference
< unoidl::Entity
> ent
;
2324 codemaker::UnoType::Sort sort
= m_typeMgr
->getSort(base
, &ent
);
2325 if (sort
!= codemaker::UnoType::Sort::PlainStruct
) {
2326 throw CannotDumpException(
2327 "plain struct type base " + base
2328 + " is not a plain struct type");
2330 rtl::Reference
< unoidl::PlainStructTypeEntity
> ent2(
2331 dynamic_cast< unoidl::PlainStructTypeEntity
* >(ent
.get()));
2336 bool hasMember
= dumpBaseMembers(out
, ent2
->getDirectBase(), withType
);
2337 for (const unoidl::PlainStructTypeEntity::Member
& member
: ent2
->getDirectMembers()) {
2342 dumpType(out
, member
.type
, true, true);
2345 out
<< member
.name
<< "_";
2351 void PlainStructType::addLightGetCppuTypeIncludes(
2352 codemaker::cppumaker::Includes
& includes
) const
2355 includes
.addCppuUnotypeHxx();
2356 includes
.addSalTypesH();
2357 includes
.addTypelibTypeclassH();
2358 includes
.addTypelibTypedescriptionH();
2361 void PlainStructType::addNormalGetCppuTypeIncludes(
2362 codemaker::cppumaker::Includes
& includes
) const
2365 includes
.addCppuUnotypeHxx();
2366 includes
.addSalTypesH();
2367 includes
.addTypelibTypeclassH();
2368 includes
.addTypelibTypedescriptionH();
2371 void PlainStructType::addComprehensiveGetCppuTypeIncludes(
2372 codemaker::cppumaker::Includes
& includes
) const
2375 includes
.addCppuUnotypeHxx();
2376 includes
.addRtlInstanceHxx();
2377 includes
.addRtlUstringH();
2378 includes
.addRtlUstringHxx();
2379 includes
.addSalTypesH();
2380 includes
.addTypelibTypeclassH();
2381 includes
.addTypelibTypedescriptionH();
2384 sal_uInt32
PlainStructType::getTotalMemberCount(OUString
const & base
) const
2386 if (base
.isEmpty()) {
2389 rtl::Reference
< unoidl::Entity
> ent
;
2390 codemaker::UnoType::Sort sort
= m_typeMgr
->getSort(base
, &ent
);
2391 if (sort
!= codemaker::UnoType::Sort::PlainStruct
) {
2392 throw CannotDumpException(
2393 "plain struct type base " + base
+ " is not a plain struct type");
2395 rtl::Reference
< unoidl::PlainStructTypeEntity
> ent2(
2396 dynamic_cast< unoidl::PlainStructTypeEntity
* >(ent
.get()));
2401 return getTotalMemberCount(ent2
->getDirectBase())
2402 + ent2
->getDirectMembers().size(); //TODO: overflow
2405 class PolyStructType
: public CppuType
2409 rtl::Reference
< unoidl::PolymorphicStructTypeTemplateEntity
> const &
2411 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
2412 CppuType(name
, typeMgr
), entity_(entity
) {
2413 assert(entity
.is());
2417 virtual void dumpDeclaration(FileStream
& o
) override
;
2419 void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
2421 virtual void dumpLightGetCppuType(FileStream
& out
) override
;
2423 virtual void dumpNormalGetCppuType(FileStream
& out
) override
;
2425 virtual void dumpComprehensiveGetCppuType(FileStream
& out
) override
;
2427 virtual void addLightGetCppuTypeIncludes(
2428 codemaker::cppumaker::Includes
& includes
) const override
;
2430 virtual void addNormalGetCppuTypeIncludes(
2431 codemaker::cppumaker::Includes
& includes
) const override
;
2433 virtual void addComprehensiveGetCppuTypeIncludes(
2434 codemaker::cppumaker::Includes
& includes
) const override
;
2436 virtual bool isPolymorphic() const override
{
2440 virtual void dumpTemplateHead(FileStream
& out
) const override
;
2442 virtual void dumpTemplateParameters(FileStream
& out
) const override
;
2444 rtl::Reference
< unoidl::PolymorphicStructTypeTemplateEntity
> entity_
;
2447 void PolyStructType::dumpDeclaration(FileStream
& out
)
2449 out
<< "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
2450 dumpTemplateHead(out
);
2451 out
<< "struct SAL_DLLPUBLIC_RTTI " << id_
<< " {\n";
2453 out
<< indent() << "inline " << id_
<< "();\n";
2454 if (!entity_
->getMembers().empty()) {
2455 out
<< "\n" << indent() << "inline " << id_
<< "(";
2457 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2458 const_iterator
i(entity_
->getMembers().begin());
2459 i
!= entity_
->getMembers().end(); ++i
) {
2460 if (i
!= entity_
->getMembers().begin()) {
2463 if (i
->parameterized
) {
2464 dumpTypeParameterName(out
, i
->type
);
2467 dumpType(out
, i
->type
, true, true);
2469 out
<< " " << i
->name
<< "_";
2472 // print the member fields
2473 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
:
2474 entity_
->getMembers()) {
2476 if (member
.parameterized
) {
2477 dumpTypeParameterName(out
, member
.type
);
2479 dumpType(out
, member
.type
);
2481 out
<< " " << member
.name
<< ";\n";
2485 out
<< "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
2488 void PolyStructType::dumpHppFile(
2489 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
2491 OUString
headerDefine(dumpHeaderDefine(out
, u
"HPP"));
2493 includes
.dump(out
, &name_
, true);
2495 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false)) {
2499 // dump default (no-arg) constructor
2500 dumpTemplateHead(out
);
2501 out
<< "inline " << id_
;
2502 dumpTemplateParameters(out
);
2503 out
<< "::" << id_
<< "()\n";
2505 for (std::vector
< unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2506 const_iterator
i(entity_
->getMembers().begin());
2507 i
!= entity_
->getMembers().end(); ++i
) {
2508 out
<< indent() << (i
== entity_
->getMembers().begin() ? ":" : ",")
2510 dumpInitializer(out
, i
->parameterized
, i
->type
);
2515 if (!entity_
->getMembers().empty()) {
2516 // dump takes-all-fields constructor
2517 dumpTemplateHead(out
);
2518 out
<< "inline " << id_
;
2519 dumpTemplateParameters(out
);
2520 out
<< "::" << id_
<< "(";
2522 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2523 const_iterator
i(entity_
->getMembers().begin());
2524 i
!= entity_
->getMembers().end(); ++i
) {
2525 if (i
!= entity_
->getMembers().begin()) {
2528 if (i
->parameterized
) {
2529 dumpTypeParameterName(out
, i
->type
);
2532 dumpType(out
, i
->type
, true, true);
2534 out
<< " " << i
->name
<< "_";
2539 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2540 const_iterator
i(entity_
->getMembers().begin());
2541 i
!= entity_
->getMembers().end(); ++i
) {
2542 out
<< indent() << (i
== entity_
->getMembers().begin() ? ":" : ",")
2543 << " " << i
->name
<< "(" << i
->name
<< "_)\n";
2546 out
<< "{\n}\n\n" << indent();
2547 // dump make_T method
2548 dumpTemplateHead(out
);
2549 out
<< "\n" << indent() << "inline " << id_
;
2550 dumpTemplateParameters(out
);
2551 out
<< "\n" << indent() << "make_" << id_
<< "(";
2553 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2554 const_iterator
i(entity_
->getMembers().begin());
2555 i
!= entity_
->getMembers().end(); ++i
) {
2556 if (i
!= entity_
->getMembers().begin()) {
2559 if (i
->parameterized
) {
2560 dumpTypeParameterName(out
, i
->type
);
2563 dumpType(out
, i
->type
, true, true);
2565 out
<< " " << i
->name
<< "_";
2567 out
<< ")\n" << indent() << "{\n";
2569 out
<< indent() << "return " << id_
;
2570 dumpTemplateParameters(out
);
2573 unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2574 const_iterator
i(entity_
->getMembers().begin());
2575 i
!= entity_
->getMembers().end(); ++i
) {
2576 if (i
!= entity_
->getMembers().begin()) {
2579 out
<< i
->name
<< "_";
2583 out
<< indent() << "}\n\n";
2585 // print the operator==
2586 dumpTemplateHead(out
);
2587 out
<< " inline bool operator==(const " << id_
;
2588 dumpTemplateParameters(out
);
2589 out
<< "& the_lhs, const " << id_
;
2590 dumpTemplateParameters(out
);
2591 out
<< "& the_rhs)\n";
2594 out
<< indent() << "return ";
2596 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
: entity_
->getMembers()) {
2598 out
<< "\n" << indent() << indent() << "&& ";
2599 out
<< "the_lhs." << member
.name
<< " == the_rhs." << member
.name
;
2605 // print the operator!=
2606 dumpTemplateHead(out
);
2607 out
<< " inline bool operator!=(const " << id_
;
2608 dumpTemplateParameters(out
);
2609 out
<< "& the_lhs, const " << id_
;
2610 dumpTemplateParameters(out
);
2611 out
<< "& the_rhs)\n";
2613 out
<< indent() << "return !operator==(the_lhs, the_rhs);\n";
2616 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false)) {
2620 dumpGetCppuType(out
);
2621 out
<< "\n#endif // "<< headerDefine
<< "\n";
2624 void PolyStructType::dumpLightGetCppuType(FileStream
& out
)
2626 dumpGetCppuTypePreamble(out
);
2628 << ("//TODO: On certain platforms with weak memory models, the"
2629 " following code can result in some threads observing that the_type"
2630 " points to garbage\n")
2632 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2633 << indent() << "if (the_type == 0) {\n";
2636 out
<< "#ifdef LIBO_INTERNAL_ONLY\n";
2638 out
<< indent() << "::rtl::OString the_buffer = \"" << name_
2640 for (std::vector
< OUString
>::const_iterator
i(
2641 entity_
->getTypeParameters().begin());
2642 i
!= entity_
->getTypeParameters().end();) {
2644 << ("::rtl::OUStringToOString("
2645 "::cppu::getTypeFavourChar(static_cast< ");
2646 dumpTypeParameterName(out
, *i
);
2647 out
<< " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8) +\n";
2649 if (i
!= entity_
->getTypeParameters().end()) {
2650 out
<< indent() << "\",\" +\n";
2653 out
<< indent() << "\">\";\n";
2657 out
<< indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2659 for (std::vector
< OUString
>::const_iterator
i(
2660 entity_
->getTypeParameters().begin());
2661 i
!= entity_
->getTypeParameters().end();) {
2663 << ("the_buffer.append(::rtl::OUStringToOString("
2664 "::cppu::getTypeFavourChar(static_cast< ");
2665 dumpTypeParameterName(out
, *i
);
2666 out
<< " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2668 if (i
!= entity_
->getTypeParameters().end()) {
2669 out
<< indent() << "the_buffer.append(',');\n";
2672 out
<< indent() << "the_buffer.append('>');\n";
2677 << "::typelib_static_type_init(&the_type, " << getTypeClass(name_
, true)
2678 << ", the_buffer.getStr());\n";
2681 out
<< indent() << "}\n" << indent()
2682 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2683 dumpGetCppuTypePostamble(out
);
2686 void PolyStructType::dumpNormalGetCppuType(FileStream
& out
)
2688 dumpGetCppuTypePreamble(out
);
2690 << ("//TODO: On certain platforms with weak memory models, the"
2691 " following code can result in some threads observing that the_type"
2692 " points to garbage\n")
2694 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2695 << indent() << "if (the_type == 0) {\n";
2697 out
<< indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2699 for (std::vector
< OUString
>::const_iterator
i(
2700 entity_
->getTypeParameters().begin());
2701 i
!= entity_
->getTypeParameters().end();) {
2703 << ("the_buffer.append(::rtl::OUStringToOString("
2704 "::cppu::getTypeFavourChar(static_cast< ");
2705 dumpTypeParameterName(out
, *i
);
2706 out
<< " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2708 if (i
!= entity_
->getTypeParameters().end()) {
2709 out
<< indent() << "the_buffer.append(',');\n";
2712 out
<< indent() << "the_buffer.append('>');\n" << indent()
2713 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2715 for (std::vector
< unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2716 const_iterator
i(entity_
->getMembers().begin());
2717 i
!= entity_
->getMembers().end();) {
2719 if (i
->parameterized
) {
2720 out
<< "::cppu::getTypeFavourChar(static_cast< ";
2721 dumpTypeParameterName(out
, i
->type
);
2724 out
<< "::cppu::UnoType< ";
2725 dumpType(out
, i
->type
, false, false, false, true);
2729 out
<< ".getTypeLibType()"
2730 << (i
== entity_
->getMembers().end() ? " };" : ",") << "\n";
2733 out
<< indent() << "static ::sal_Bool const the_parameterizedTypes[] = { ";
2734 for (std::vector
< unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2735 const_iterator
i(entity_
->getMembers().begin());
2736 i
!= entity_
->getMembers().end(); ++i
) {
2737 if (i
!= entity_
->getMembers().begin()) {
2740 out
<< (i
->parameterized
? "true" : "false");
2742 out
<< " };\n" << indent()
2743 << ("::typelib_static_struct_type_init(&the_type, the_buffer.getStr(),"
2745 << entity_
->getMembers().size()
2746 << ", the_members, the_parameterizedTypes);\n";
2748 out
<< indent() << "}\n" << indent()
2749 << ("return *reinterpret_cast< ::css::uno::Type * >("
2751 dumpGetCppuTypePostamble(out
);
2754 void PolyStructType::dumpComprehensiveGetCppuType(FileStream
& out
)
2756 out
<< "namespace cppu { namespace detail {\n\n" << indent();
2757 dumpTemplateHead(out
);
2758 OUString
staticTypeClass("the" + id_
+ "Type");
2759 out
<< "struct " << staticTypeClass
2760 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2762 dumpTemplateParameters(out
);
2763 out
<< " >\n" << indent() << "{\n";
2765 out
<< indent() << "::css::uno::Type * operator()() const\n"
2766 << indent() << "{\n";
2769 out
<< "#ifdef LIBO_INTERNAL_ONLY\n";
2771 << "::rtl::OUString the_name =\n";
2772 out
<< indent() << "\"" << name_
<< "<\" +\n";
2773 for (std::vector
< OUString
>::const_iterator
i(
2774 entity_
->getTypeParameters().begin());
2775 i
!= entity_
->getTypeParameters().end();) {
2777 << "::cppu::getTypeFavourChar(static_cast< ";
2778 dumpTypeParameterName(out
, *i
);
2779 out
<< " * >(0)).getTypeName() +\n";
2781 if (i
!= entity_
->getTypeParameters().end()) {
2789 out
<< indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent()
2790 << "the_buffer.append(\"" << name_
<< "<\");\n";
2791 for (std::vector
< OUString
>::const_iterator
i(
2792 entity_
->getTypeParameters().begin());
2793 i
!= entity_
->getTypeParameters().end();) {
2795 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2796 dumpTypeParameterName(out
, *i
);
2797 out
<< " * >(0)).getTypeName());\n";
2799 if (i
!= entity_
->getTypeParameters().end()) {
2801 << ("the_buffer.append("
2802 "static_cast< ::sal_Unicode >(','));\n");
2805 out
<< indent() << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n";
2807 << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2809 std::map
< OUString
, sal_uInt32
> parameters
;
2810 std::map
< OUString
, sal_uInt32
> types
;
2811 std::vector
< unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2813 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member
& member
: entity_
->getMembers()) {
2814 if (member
.parameterized
) {
2815 if (parameters
.emplace(
2816 member
.type
, static_cast< sal_uInt32
>(parameters
.size())).
2818 sal_uInt32 k
= static_cast< sal_uInt32
>(parameters
.size() - 1);
2820 << "::css::uno::Type const & the_ptype" << k
2821 << " = ::cppu::getTypeFavourChar(static_cast< ";
2822 dumpTypeParameterName(out
, member
.type
);
2823 out
<< " * >(0));\n" << indent()
2824 << "::typelib_TypeClass the_pclass" << k
2825 << " = (::typelib_TypeClass) the_ptype" << k
2826 << ".getTypeClass();\n" << indent()
2827 << "::rtl::OUString the_pname" << k
<< "(the_ptype" << k
2828 << ".getTypeName());\n";
2830 } else if (types
.emplace(member
.type
, static_cast< sal_uInt32
>(types
.size())).
2832 dumpCppuGetType(out
, member
.type
, &name_
);
2833 // For typedefs, use the resolved type name, as there will be no
2834 // information available about the typedef itself at runtime (the
2835 // above getCppuType call will make available information about the
2836 // resolved type); no extra #include for the resolved type is
2837 // needed, as the header for the typedef includes it already:
2838 out
<< indent() << "::rtl::OUString the_tname"
2839 << static_cast< sal_uInt32
>(types
.size() - 1) << "( \""
2840 << resolveAllTypedefs(member
.type
) << "\" );\n";
2842 out
<< indent() << "::rtl::OUString the_name" << n
++ << "( \""
2843 << member
.name
<< "\" );\n";
2845 out
<< indent() << "::typelib_StructMember_Init the_members[] = {\n";
2848 for (std::vector
< unoidl::PolymorphicStructTypeTemplateEntity::Member
>::
2849 const_iterator
i(entity_
->getMembers().begin());
2850 i
!= entity_
->getMembers().end();) {
2851 out
<< indent() << "{ { ";
2852 if (i
->parameterized
) {
2853 const auto iter
= parameters
.find(i
->type
);
2854 assert(iter
!= parameters
.end());
2855 sal_uInt32 k
= iter
->second
;
2856 out
<< "the_pclass" << k
<< ", the_pname" << k
<< ".pData";
2858 const auto iter
= types
.find(i
->type
);
2859 assert(iter
!= types
.end());
2860 out
<< getTypeClass(i
->type
, true) << ", the_tname"
2861 << iter
->second
<< ".pData";
2863 out
<< ", the_name" << n
++ << ".pData }, "
2864 << (i
->parameterized
? "true" : "false") << " }";
2866 out
<< (i
== entity_
->getMembers().end() ? " };" : ",") << "\n";
2869 out
<< indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2871 << ("::typelib_typedescription_newStruct(&the_newType, the_name.pData,"
2873 << entity_
->getMembers().size() << ", the_members);\n" << indent()
2874 << "::typelib_typedescription_register(&the_newType);\n" << indent()
2875 << "::typelib_typedescription_release(the_newType);\n" << indent()
2876 << "return new ::css::uno::Type(" << getTypeClass(name_
)
2877 << ", the_name); // leaked\n";
2879 out
<< indent() << "}\n";
2881 out
<< indent() << "};\n } }\n\n";
2882 dumpGetCppuTypePreamble(out
);
2883 out
<< indent() << "return *detail::" << staticTypeClass
;
2884 dumpTemplateParameters(out
);
2885 out
<< "::get();\n";
2886 dumpGetCppuTypePostamble(out
);
2889 void PolyStructType::addLightGetCppuTypeIncludes(
2890 codemaker::cppumaker::Includes
& includes
) const
2893 includes
.addCppuUnotypeHxx();
2894 includes
.addSalTypesH();
2895 includes
.addTypelibTypeclassH();
2896 includes
.addTypelibTypedescriptionH();
2897 includes
.addRtlStrbufHxx();
2898 includes
.addRtlTextencH();
2899 includes
.addRtlUstringHxx();
2902 void PolyStructType::addNormalGetCppuTypeIncludes(
2903 codemaker::cppumaker::Includes
& includes
) const
2906 includes
.addCppuUnotypeHxx();
2907 includes
.addSalTypesH();
2908 includes
.addTypelibTypeclassH();
2909 includes
.addTypelibTypedescriptionH();
2910 includes
.addRtlStrbufHxx();
2911 includes
.addRtlTextencH();
2912 includes
.addRtlUstringHxx();
2915 void PolyStructType::addComprehensiveGetCppuTypeIncludes(
2916 codemaker::cppumaker::Includes
& includes
) const
2919 includes
.addCppuUnotypeHxx();
2920 includes
.addRtlInstanceHxx();
2921 includes
.addRtlUstringH();
2922 includes
.addRtlUstringHxx();
2923 includes
.addSalTypesH();
2924 includes
.addTypelibTypeclassH();
2925 includes
.addTypelibTypedescriptionH();
2926 includes
.addRtlStringH();
2927 includes
.addRtlUstrbufHxx();
2930 void PolyStructType::dumpTemplateHead(FileStream
& out
) const
2932 out
<< "template< ";
2933 for (std::vector
< OUString
>::const_iterator
i(
2934 entity_
->getTypeParameters().begin());
2935 i
!= entity_
->getTypeParameters().end(); ++i
) {
2936 if (i
!= entity_
->getTypeParameters().begin()) {
2940 dumpTypeParameterName(out
, *i
);
2945 void PolyStructType::dumpTemplateParameters(FileStream
& out
) const
2948 for (std::vector
< OUString
>::const_iterator
i(
2949 entity_
->getTypeParameters().begin());
2950 i
!= entity_
->getTypeParameters().end(); ++i
) {
2951 if (i
!= entity_
->getTypeParameters().begin()) {
2954 dumpTypeParameterName(out
, *i
);
2959 OUString
typeToIdentifier(std::u16string_view name
)
2962 OUString
n(b2u(codemaker::UnoType::decompose(u2b(name
), &k
)));
2963 OUStringBuffer
b(4*k
+ n
.getLength());
2964 for (sal_Int32 i
= 0; i
!= k
; ++i
) {
2968 b
.replace(' ', '_');
2969 b
.replace(',', '_');
2970 b
.replace('.', '_');
2971 b
.replace('<', '_');
2972 b
.replace('>', '_');
2973 return b
.makeStringAndClear();
2976 class ExceptionType
: public CppuType
2980 rtl::Reference
< unoidl::ExceptionTypeEntity
> const & entity
,
2981 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
2982 CppuType(name
, typeMgr
), entity_(entity
) {
2983 assert(entity
.is());
2987 virtual void dumpHdlFile(
2988 FileStream
& out
, codemaker::cppumaker::Includes
& includes
) override
;
2990 virtual void dumpHppFile(
2991 FileStream
& out
, codemaker::cppumaker::Includes
& includes
) override
;
2993 virtual void addComprehensiveGetCppuTypeIncludes(
2994 codemaker::cppumaker::Includes
& includes
) const override
;
2996 virtual void dumpLightGetCppuType(FileStream
& out
) override
;
2998 virtual void dumpNormalGetCppuType(FileStream
& out
) override
;
3000 virtual void dumpComprehensiveGetCppuType(FileStream
& out
) override
;
3002 virtual sal_uInt32
checkInheritedMemberCount() const override
{
3003 return getTotalMemberCount(entity_
->getDirectBase());
3006 virtual void dumpDeclaration(FileStream
& out
) override
;
3008 bool dumpBaseMembers(
3009 FileStream
& out
, OUString
const & base
, bool withType
,
3010 bool eligibleForDefaults
);
3012 sal_uInt32
getTotalMemberCount(OUString
const & base
) const;
3014 rtl::Reference
< unoidl::ExceptionTypeEntity
> entity_
;
3017 void ExceptionType::dumpHdlFile(
3018 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
3020 if (name_
== "com.sun.star.uno.Exception")
3022 includes
.addCustom("#if defined(LIBO_INTERNAL_ONLY)");
3023 includes
.addCustom("#if __has_include(<version>)");
3024 includes
.addCustom("#include <version>");
3025 includes
.addCustom("#endif");
3026 includes
.addCustom("#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907");
3027 includes
.addCustom("#include <source_location>");
3028 includes
.addCustom("#define LIBO_USE_SOURCE_LOCATION std");
3029 includes
.addCustom("#elif __has_include(<experimental/source_location>)");
3030 includes
.addCustom("#include <experimental/source_location>");
3031 includes
.addCustom("#define LIBO_USE_SOURCE_LOCATION std::experimental");
3032 includes
.addCustom("#endif");
3033 includes
.addCustom("#endif");
3034 includes
.addCustom("#if defined LIBO_USE_SOURCE_LOCATION");
3035 includes
.addCustom("#include <o3tl/runtimetooustring.hxx>");
3036 includes
.addCustom("#endif");
3038 dumpHFileContent(out
, includes
);
3041 void ExceptionType::addComprehensiveGetCppuTypeIncludes(
3042 codemaker::cppumaker::Includes
& includes
) const
3044 includes
.addCppuUnotypeHxx();
3045 includes
.addRtlInstanceHxx(); // using rtl::StaticWithInit
3048 void ExceptionType::dumpHppFile(
3049 FileStream
& out
, codemaker::cppumaker::Includes
& includes
)
3051 OUString
headerDefine(dumpHeaderDefine(out
, u
"HPP"));
3053 addDefaultHxxIncludes(includes
);
3054 includes
.dump(out
, &name_
, true);
3056 // for the output operator below
3057 if (name_
== "com.sun.star.uno.Exception")
3059 out
<< "#if defined LIBO_INTERNAL_ONLY\n";
3060 out
<< "#include <ostream>\n";
3061 out
<< "#include <typeinfo>\n";
3067 if (codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false)) {
3071 // default constructor
3072 out
<< "\ninline " << id_
<< "::" << id_
<< "(\n";
3073 out
<< "#if defined LIBO_USE_SOURCE_LOCATION\n";
3074 out
<< " LIBO_USE_SOURCE_LOCATION::source_location location\n";
3078 OUString
base(entity_
->getDirectBase());
3080 if (!base
.isEmpty()) {
3081 out
<< indent() << ": " << codemaker::cpp::scopedCppName(u2b(base
))
3083 out
<< "#if defined LIBO_USE_SOURCE_LOCATION\n";
3084 out
<< " location\n";
3089 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3090 out
<< indent() << (bFirst
? ":" : ",") << " ";
3092 dumpInitializer(out
, false, member
.type
);
3098 if (!m_cppuTypeDynamic
) {
3101 dumpCppuGetType(out
, name_
);
3106 if (name_
== "com.sun.star.uno.Exception")
3108 out
<< "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3109 out
<< " if (!Message.isEmpty())\n";
3110 out
<< " Message += \" \";\n";
3111 out
<< " Message += \"at \" + o3tl::runtimeToOUString(location.file_name()) + \":\" + OUString::number(location.line());\n";
3116 // fields constructor
3117 if (!entity_
->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
3118 out
<< indent() << "inline " << id_
<< "::" << id_
<< "(";
3119 bFirst
= !dumpBaseMembers(out
, base
, true, false);
3120 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3124 dumpType(out
, member
.type
, true, true);
3125 out
<< " " << member
.name
<< "_";
3128 out
<< "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3129 out
<< " " << (bFirst
? "" : ", ") << "LIBO_USE_SOURCE_LOCATION::source_location location\n";
3134 if (!base
.isEmpty()) {
3135 out
<< indent() << ": " << codemaker::cpp::scopedCppName(u2b(base
))
3137 dumpBaseMembers(out
, base
, false, false);
3138 out
<< "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3139 out
<< " , location\n";
3144 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3145 out
<< indent() << (bFirst
? ":" : ",") << " " << member
.name
<< "("
3146 << member
.name
<< "_)\n";
3151 if (!m_cppuTypeDynamic
) {
3154 dumpCppuGetType(out
, name_
);
3159 if (name_
== "com.sun.star.uno.Exception")
3161 out
<< "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3162 out
<< " if (!Message.isEmpty())\n";
3163 out
<< " Message += \" \";\n";
3164 out
<< " Message += \"at \" + o3tl::runtimeToOUString(location.file_name()) + \":\" + OUString::number(location.line());\n";
3169 out
<< "#if !defined LIBO_INTERNAL_ONLY\n" << indent() << id_
<< "::" << id_
3170 << "(" << id_
<< " const & the_other)";
3172 if (!base
.isEmpty()) {
3173 out
<< ": " << codemaker::cpp::scopedCppName(u2b(base
))
3177 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3178 out
<< (bFirst
? ":" : ",") << " " << member
.name
<< "(the_other." << member
.name
3182 out
<< indent() << " {}\n\n" << indent() << id_
<< "::~" << id_
3183 << "() {}\n\n" << indent() << id_
<< " & " << id_
<< "::operator =("
3184 << id_
<< " const & the_other) {\n";
3187 << ("//TODO: Just like its implicitly-defined counterpart, this"
3188 " function definition is not exception-safe\n");
3189 if (!base
.isEmpty()) {
3190 out
<< indent() << codemaker::cpp::scopedCppName(u2b(base
))
3191 << "::operator =(the_other);\n";
3193 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3194 out
<< indent() << member
.name
<< " = the_other." << member
.name
<< ";\n";
3196 out
<< indent() << "return *this;\n";
3198 out
<< indent() << "}\n#endif\n\n";
3200 // Provide an output operator for printing Exception information to SAL_WARN/SAL_INFO.
3201 if (name_
== "com.sun.star.uno.Exception")
3203 out
<< "#if defined LIBO_INTERNAL_ONLY\n";
3204 out
<< "template< typename charT, typename traits >\n";
3205 out
<< "inline ::std::basic_ostream<charT, traits> & operator<<(\n";
3206 out
<< " ::std::basic_ostream<charT, traits> & os, ::com::sun::star::uno::Exception const & exception)\n";
3208 out
<< " // the class name is useful because exception throwing code does not always pass in a useful message\n";
3209 out
<< " os << typeid(exception).name();\n";
3210 out
<< " if (!exception.Message.isEmpty())\n";
3211 out
<< " os << \" msg: \" << exception.Message;\n";
3212 out
<< " return os;\n";
3218 if (codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false)) {
3223 dumpGetCppuType(out
);
3224 out
<< "\n#endif // "<< headerDefine
<< "\n";
3227 void ExceptionType::dumpLightGetCppuType(FileStream
& out
)
3229 dumpGetCppuTypePreamble(out
);
3231 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3232 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3234 out
<< indent() << "typelib_static_type_init( &the_type, "
3235 << getTypeClass(name_
, true) << ", \"" << name_
<< "\" );\n";
3237 out
<< indent() << "}\n" << indent()
3238 << ("return * reinterpret_cast< ::css::uno::Type * >("
3240 dumpGetCppuTypePostamble(out
);
3243 void ExceptionType::dumpNormalGetCppuType(FileStream
& out
)
3245 dumpGetCppuTypePreamble(out
);
3247 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3248 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3250 OUString
base(entity_
->getDirectBase());
3251 bool baseException
= false;
3252 if (!base
.isEmpty()) {
3253 if (base
== "com.sun.star.uno.Exception") {
3254 baseException
= true;
3257 << ("const ::css::uno::Type& rBaseType ="
3258 " ::cppu::UnoType< ");
3259 dumpType(out
, base
, true, false, false, true);
3260 out
<< " >::get();\n\n";
3263 if (!entity_
->getDirectMembers().empty()) {
3264 out
<< indent() << "typelib_TypeDescriptionReference * aMemberRefs["
3265 << entity_
->getDirectMembers().size() << "];\n";
3266 std::set
< OUString
> seen
;
3267 std::vector
< unoidl::ExceptionTypeEntity::Member
>::size_type n
= 0;
3268 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3269 OUString
type(resolveAllTypedefs(member
.type
));
3270 OUString
modType(typeToIdentifier(type
));
3271 if (seen
.insert(type
).second
) {
3273 << "const ::css::uno::Type& rMemberType_"
3274 << modType
<< " = ::cppu::UnoType< ";
3275 dumpType(out
, type
, false, false, false, true);
3276 out
<< " >::get();\n";
3278 out
<< indent() << "aMemberRefs[" << n
++ << "] = rMemberType_"
3279 << modType
<< ".getTypeLibType();\n";
3283 out
<< indent() << "typelib_static_compound_type_init( &the_type, "
3284 << getTypeClass(name_
, true) << ", \"" << name_
<< "\", ";
3285 if (baseException
) {
3286 out
<< ("* ::typelib_static_type_getByTypeClass("
3287 " typelib_TypeClass_EXCEPTION )");
3288 } else if (base
.isEmpty()) {
3291 out
<< "rBaseType.getTypeLibType()";
3293 out
<< ", " << entity_
->getDirectMembers().size() << ", "
3294 << (entity_
->getDirectMembers().empty() ? "0" : "aMemberRefs")
3297 out
<< indent() << "}\n" << indent()
3298 << ("return * reinterpret_cast< const ::css::uno::Type * >("
3300 dumpGetCppuTypePostamble(out
);
3303 void ExceptionType::dumpComprehensiveGetCppuType(FileStream
& out
)
3305 codemaker::cppumaker::dumpNamespaceOpen(out
, name_
, false);
3306 out
<< " namespace detail {\n\n";
3307 OUString
staticTypeClass("the" + id_
+ "Type");
3308 out
<< indent() << "struct " << staticTypeClass
3309 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
3310 << staticTypeClass
<< " >\n" << indent() << "{\n";
3312 out
<< indent() << "::css::uno::Type * operator()() const\n"
3313 << indent() << "{\n";
3315 out
<< indent() << "::rtl::OUString sTypeName( \"" << name_
<< "\" );\n\n"
3316 << indent() << "// Start inline typedescription generation\n"
3317 << indent() << "typelib_TypeDescription * pTD = 0;\n";
3318 OUString
base(entity_
->getDirectBase());
3319 if (!base
.isEmpty()) {
3321 << ("const ::css::uno::Type& rSuperType ="
3322 " ::cppu::UnoType< ");
3323 dumpType(out
, base
, false, false, false, true);
3324 out
<< " >::get();\n";
3326 std::set
< OUString
> seen
;
3327 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3328 if (seen
.insert(member
.type
).second
) {
3329 dumpCppuGetType(out
, member
.type
);
3332 if (!entity_
->getDirectMembers().empty()) {
3333 out
<< "\n" << indent() << "typelib_CompoundMember_Init aMembers["
3334 << entity_
->getDirectMembers().size() << "];\n";
3335 std::vector
< unoidl::ExceptionTypeEntity::Member
>::size_type n
= 0;
3336 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3337 OUString
type(resolveAllTypedefs(member
.type
));
3338 out
<< indent() << "::rtl::OUString sMemberType" << n
<< "( \""
3339 << type
<< "\" );\n" << indent()
3340 << "::rtl::OUString sMemberName" << n
<< "( \"" << member
.name
3341 << "\" );\n" << indent() << "aMembers[" << n
3342 << "].eTypeClass = (typelib_TypeClass)" << getTypeClass(type
)
3343 << ";\n" << indent() << "aMembers[" << n
3344 << "].pTypeName = sMemberType" << n
<< ".pData;\n" << indent()
3345 << "aMembers[" << n
<< "].pMemberName = sMemberName" << n
3350 out
<< "\n" << indent() << "typelib_typedescription_new(\n";
3352 out
<< indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)"
3353 << getTypeClass(name_
) << ", sTypeName.pData,\n" << indent()
3354 << (base
.isEmpty() ? "0" : "rSuperType.getTypeLibType()") << ",\n"
3355 << indent() << entity_
->getDirectMembers().size() << ",\n" << indent()
3356 << (entity_
->getDirectMembers().empty() ? "0" : "aMembers")
3360 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3362 << indent() << "typelib_typedescription_release( pTD );\n" << indent()
3363 << "// End inline typedescription generation\n\n" << indent()
3364 << "return new ::css::uno::Type( " << getTypeClass(name_
)
3365 << ", sTypeName ); // leaked\n";
3367 out
<< indent() << "}\n";
3369 out
<< indent() << "};\n\n";
3370 codemaker::cppumaker::dumpNamespaceClose(out
, name_
, false);
3372 dumpGetCppuTypePreamble(out
);
3373 out
<< indent() << "return *detail::" << staticTypeClass
<< "::get();\n";
3374 dumpGetCppuTypePostamble(out
);
3377 void ExceptionType::dumpDeclaration(FileStream
& out
)
3379 out
<< "\nclass CPPU_GCC_DLLPUBLIC_EXPORT SAL_WARN_UNUSED " << id_
;
3380 OUString
base(entity_
->getDirectBase());
3381 if (!base
.isEmpty()) {
3382 out
<< " : public " << codemaker::cpp::scopedCppName(u2b(base
));
3384 out
<< "\n{\npublic:\n";
3387 // default constructor
3388 out
<< indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
<< "(\n";
3389 out
<< "#if defined LIBO_USE_SOURCE_LOCATION\n";
3390 out
<< " LIBO_USE_SOURCE_LOCATION::source_location location = LIBO_USE_SOURCE_LOCATION::source_location::current()\n";
3391 out
<< "#endif\n\n";
3394 // constructor that initializes data members
3395 if (!entity_
->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
3396 out
<< indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
<< "(";
3397 bool eligibleForDefaults
= entity_
->getDirectMembers().empty();
3398 bool bFirst
= !dumpBaseMembers(out
, base
, true, eligibleForDefaults
);
3399 for (const unoidl::ExceptionTypeEntity::Member
& member
: entity_
->getDirectMembers()) {
3403 dumpType(out
, member
.type
, true, true);
3404 out
<< " " << member
.name
<< "_";
3407 out
<< "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3408 out
<< ", LIBO_USE_SOURCE_LOCATION::source_location location = LIBO_USE_SOURCE_LOCATION::source_location::current()\n";
3412 out
<< "#if !defined LIBO_INTERNAL_ONLY\n" << indent()
3413 << "inline CPPU_GCC_DLLPRIVATE " << id_
<< "(" << id_
3414 << " const &);\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE ~"
3415 << id_
<< "();\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3416 << " & operator =(" << id_
<< " const &);\n#endif\n\n";
3417 for (std::vector
< unoidl::ExceptionTypeEntity::Member
>::const_iterator
i(
3418 entity_
->getDirectMembers().begin());
3419 i
!= entity_
->getDirectMembers().end(); ++i
) {
3421 dumpType(out
, i
->type
);
3422 out
<< " " << i
->name
;
3423 if (i
== entity_
->getDirectMembers().begin() && !base
.isEmpty()
3424 && i
->type
!= "hyper" && i
->type
!= "unsigned hyper"
3425 && i
->type
!= "double") {
3426 out
<< " CPPU_GCC3_ALIGN( "
3427 << codemaker::cpp::scopedCppName(u2b(base
)) << " )";
3435 bool ExceptionType::dumpBaseMembers(
3436 FileStream
& out
, OUString
const & base
, bool withType
, bool eligibleForDefaults
)
3441 bool hasMember
= false;
3442 rtl::Reference
< unoidl::Entity
> ent
;
3443 codemaker::UnoType::Sort sort
= m_typeMgr
->getSort(base
, &ent
);
3444 if (sort
!= codemaker::UnoType::Sort::Exception
) {
3445 throw CannotDumpException(
3446 "exception type base " + base
+ " is not an exception type");
3448 rtl::Reference
< unoidl::ExceptionTypeEntity
> ent2(
3449 dynamic_cast< unoidl::ExceptionTypeEntity
* >(ent
.get()));
3454 hasMember
= dumpBaseMembers( out
, ent2
->getDirectBase(), withType
,
3455 eligibleForDefaults
&& ent2
->getDirectMembers().empty() );
3456 int memberCount
= 0;
3457 for (const unoidl::ExceptionTypeEntity::Member
& member
: ent2
->getDirectMembers()) {
3462 dumpType(out
, member
.type
, true, true);
3465 out
<< member
.name
<< "_";
3466 // We want to provide a default parameter value for uno::Exception subtype
3467 // constructors, since most of the time we don't pass a Context object in to the exception
3469 if (eligibleForDefaults
3470 && base
== "com.sun.star.uno.Exception"
3472 && member
.name
== "Context"
3473 && member
.type
== "com.sun.star.uno.XInterface") {
3474 out
<< " = ::css::uno::Reference< ::css::uno::XInterface >()";
3482 sal_uInt32
ExceptionType::getTotalMemberCount(OUString
const & base
) const
3484 if (base
.isEmpty()) {
3487 rtl::Reference
< unoidl::Entity
> ent
;
3488 codemaker::UnoType::Sort sort
= m_typeMgr
->getSort(base
, &ent
);
3489 if (sort
!= codemaker::UnoType::Sort::Exception
) {
3490 throw CannotDumpException(
3491 "exception type base " + base
+ " is not an exception type");
3493 unoidl::ExceptionTypeEntity
& ent2(dynamic_cast<unoidl::ExceptionTypeEntity
&>(*ent
));
3494 return getTotalMemberCount(ent2
.getDirectBase())
3495 + ent2
.getDirectMembers().size(); //TODO: overflow
3498 class EnumType
: public CppuType
3502 rtl::Reference
< unoidl::EnumTypeEntity
> const & entity
,
3503 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
3504 CppuType(name
, typeMgr
), entity_(entity
) {
3505 assert(entity
.is());
3509 virtual void dumpDeclaration(FileStream
& o
) override
;
3511 virtual void addComprehensiveGetCppuTypeIncludes(
3512 codemaker::cppumaker::Includes
& includes
) const override
;
3514 void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
3516 void dumpNormalGetCppuType(FileStream
& o
) override
;
3517 void dumpComprehensiveGetCppuType(FileStream
& o
) override
;
3519 rtl::Reference
< unoidl::EnumTypeEntity
> entity_
;
3522 void EnumType::addComprehensiveGetCppuTypeIncludes(
3523 codemaker::cppumaker::Includes
& includes
) const
3525 includes
.addCppuUnotypeHxx();
3526 includes
.addRtlInstanceHxx(); // using rtl::StaticWithInit
3529 void EnumType::dumpDeclaration(FileStream
& o
)
3531 o
<< "\n#if defined LIBO_INTERNAL_ONLY\n";
3532 o
<< "\nenum class SAL_DLLPUBLIC_RTTI " << id_
<< "\n{\n";
3534 o
<< "\nenum SAL_DLLPUBLIC_RTTI " << id_
<< "\n{\n";
3538 for (const unoidl::EnumTypeEntity::Member
& member
: entity_
->getMembers()) {
3539 o
<< indent() << id_
<< "_" << u2b(member
.name
) << " = " << member
.value
3543 o
<< indent() << id_
<< "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3548 // use constexpr to create a kind of type-alias so we don't have to modify existing code
3549 o
<< "#if defined LIBO_INTERNAL_ONLY\n";
3550 for (const unoidl::EnumTypeEntity::Member
& member
: entity_
->getMembers()) {
3551 o
<< "constexpr auto " << id_
<< "_" << u2b(member
.name
)
3553 << id_
<< "::" << id_
<< "_" << u2b(member
.name
)
3559 void EnumType::dumpHppFile(
3560 FileStream
& o
, codemaker::cppumaker::Includes
& includes
)
3562 OUString
headerDefine(dumpHeaderDefine(o
, u
"HPP"));
3565 addDefaultHxxIncludes(includes
);
3566 includes
.dump(o
, &name_
, true);
3571 o
<< "\n#endif // "<< headerDefine
<< "\n";
3574 void EnumType::dumpNormalGetCppuType(FileStream
& o
)
3576 dumpGetCppuTypePreamble(o
);
3579 << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3581 o
<< indent() << "if ( !the_type )\n" << indent() << "{\n";
3584 o
<< indent() << "typelib_static_enum_type_init( &the_type,\n";
3586 o
<< indent() << "\"" << name_
<< "\",\n"
3587 << indent() << codemaker::cpp::scopedCppName(u2b(name_
)) << "_"
3588 << u2b(entity_
->getMembers()[0].name
) << " );\n";
3591 o
<< indent() << "}\n";
3593 << ("return * reinterpret_cast< ::css::uno::Type * >("
3595 dumpGetCppuTypePostamble(o
);
3598 void EnumType::dumpComprehensiveGetCppuType(FileStream
& o
)
3600 if (!isPolymorphic())
3601 codemaker::cppumaker::dumpNamespaceOpen(o
, name_
, false);
3603 o
<< "namespace cppu { ";
3604 o
<< " namespace detail {\n\n";
3606 OUString
sStaticTypeClass("the" + id_
+ "Type");
3607 o
<< indent() << "struct " << sStaticTypeClass
<< " : public rtl::StaticWithInit< ::css::uno::Type *, " << sStaticTypeClass
<< " >\n";
3608 o
<< indent() << "{\n";
3610 o
<< indent() << "::css::uno::Type * operator()() const\n";
3611 o
<< indent() << "{\n";
3614 o
<< indent() << "::rtl::OUString sTypeName( \"" << name_
3617 o
<< indent() << "// Start inline typedescription generation\n"
3618 << indent() << "typelib_TypeDescription * pTD = 0;\n\n";
3620 o
<< indent() << "rtl_uString* enumValueNames["
3621 << entity_
->getMembers().size() << "];\n";
3622 std::vector
< unoidl::EnumTypeEntity::Member
>::size_type n
= 0;
3623 for (const unoidl::EnumTypeEntity::Member
& member
: entity_
->getMembers()) {
3624 o
<< indent() << "::rtl::OUString sEnumValue" << n
<< "( \""
3625 << u2b(member
.name
) << "\" );\n";
3626 o
<< indent() << "enumValueNames[" << n
<< "] = sEnumValue" << n
3631 o
<< "\n" << indent() << "sal_Int32 enumValues["
3632 << entity_
->getMembers().size() << "];\n";
3634 for (const unoidl::EnumTypeEntity::Member
& member
: entity_
->getMembers()) {
3635 o
<< indent() << "enumValues[" << n
++ << "] = " << member
.value
<< ";\n";
3638 o
<< "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3640 o
<< indent() << "sTypeName.pData,\n"
3641 << indent() << "(sal_Int32)"
3642 << codemaker::cpp::scopedCppName(u2b(name_
), false) << "_"
3643 << u2b(entity_
->getMembers()[0].name
) << ",\n"
3644 << indent() << entity_
->getMembers().size()
3645 << ", enumValueNames, enumValues );\n\n";
3649 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3651 o
<< indent() << "typelib_typedescription_release( pTD );\n"
3652 << indent() << "// End inline typedescription generation\n\n";
3654 o
<< indent() << "return new ::css::uno::Type( "
3655 << getTypeClass(name_
) << ", sTypeName ); // leaked\n";
3658 o
<< indent() << "}\n";
3660 o
<< indent() << "};\n\n";
3662 if (!isPolymorphic())
3663 codemaker::cppumaker::dumpNamespaceClose(o
, name_
, false);
3668 dumpGetCppuTypePreamble(o
);
3669 o
<< indent() << "return *detail::" << sStaticTypeClass
<< "::get();\n";
3670 dumpGetCppuTypePostamble(o
);
3673 class Typedef
: public CppuType
3677 rtl::Reference
< unoidl::TypedefEntity
> const & entity
,
3678 OUString
const & name
, rtl::Reference
< TypeManager
> const & typeMgr
):
3679 CppuType(name
, typeMgr
), entity_(entity
) {
3680 assert(entity
.is());
3684 virtual void dumpDeclaration(FileStream
& o
) override
;
3686 void dumpHdlFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
3688 void dumpHppFile(FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
3690 rtl::Reference
< unoidl::TypedefEntity
> entity_
;
3693 void Typedef::dumpHdlFile(
3694 FileStream
& o
, codemaker::cppumaker::Includes
& includes
)
3696 OUString
headerDefine(dumpHeaderDefine(o
, u
"HDL"));
3699 addDefaultHIncludes(includes
);
3700 includes
.dump(o
, nullptr, true);
3703 if (codemaker::cppumaker::dumpNamespaceOpen(o
, name_
, false)) {
3709 if (codemaker::cppumaker::dumpNamespaceClose(o
, name_
, false)) {
3713 o
<< "#endif // "<< headerDefine
<< "\n";
3716 void Typedef::dumpDeclaration(FileStream
& o
)
3719 dumpType(o
, entity_
->getType());
3720 o
<< " " << id_
<< ";\n\n";
3723 void Typedef::dumpHppFile(
3724 FileStream
& o
, codemaker::cppumaker::Includes
& includes
)
3726 OUString
headerDefine(dumpHeaderDefine(o
, u
"HPP"));
3729 addDefaultHxxIncludes(includes
);
3730 includes
.dump(o
, &name_
, true);
3733 o
<< "\n#endif // "<< headerDefine
<< "\n";
3736 class ConstructiveType
: public CppuType
3740 OUString
const & name
, rtl::Reference
< TypeManager
> const & manager
):
3741 CppuType(name
, manager
) {}
3744 virtual void dumpHdlFile(FileStream
&, codemaker::cppumaker::Includes
&) override
{
3745 assert(false); // this cannot happen
3748 virtual void dumpFiles(OUString
const & uri
, CppuOptions
const & options
) override
{
3749 dumpFile(uri
, name_
, FileType::HPP
, options
);
3750 if(options
.isValid("-W"_ostr
))
3751 dumpFile(uri
, name_
, FileType::EMBIND_CXX
, options
);
3755 bool hasRestParameter(
3756 unoidl::SingleInterfaceBasedServiceEntity::Constructor
const & constructor
)
3758 return !constructor
.parameters
.empty()
3759 && constructor
.parameters
.back().rest
;
3762 void includeExceptions(
3763 codemaker::cppumaker::Includes
& includes
,
3764 codemaker::ExceptionTreeNode
const * node
)
3766 if (node
->present
) {
3767 includes
.add(node
->name
);
3769 for (std::unique_ptr
<codemaker::ExceptionTreeNode
> const & pChild
: node
->children
) {
3770 includeExceptions(includes
, pChild
.get());
3775 class ServiceType
: public ConstructiveType
3779 rtl::Reference
< unoidl::SingleInterfaceBasedServiceEntity
> const &
3781 OUString
const & name
, rtl::Reference
< TypeManager
> const & manager
):
3782 ConstructiveType(name
, manager
), entity_(entity
) {
3783 assert(entity
.is());
3787 virtual void dumpHppFile(
3788 FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
3790 void dumpCatchClauses(
3791 FileStream
& out
, codemaker::ExceptionTreeNode
const * node
);
3793 rtl::Reference
< unoidl::SingleInterfaceBasedServiceEntity
> entity_
;
3797 FileStream
& o
, std::u16string_view service
, OString
const & type
)
3799 o
<< "::rtl::OUString(\"component context fails to supply service \") + \""
3800 << service
<< "\" + \" of type \" + \"" << type
<< "\"";
3803 void ServiceType::dumpHppFile(
3804 FileStream
& o
, codemaker::cppumaker::Includes
& includes
)
3806 if (!entity_
->getConstructors().empty()) {
3807 //TODO: Decide whether the types added to includes should rather be
3808 // added to m_dependencies (and thus be generated during
3809 // dumpDependedTypes):
3810 includes
.addCassert();
3811 includes
.addReference();
3812 includes
.addRtlUstringH();
3813 includes
.addRtlUstringHxx();
3814 includes
.add("com.sun.star.uno.DeploymentException"_ostr
);
3815 includes
.add("com.sun.star.uno.XComponentContext"_ostr
);
3816 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor
& cons
: entity_
->getConstructors()) {
3817 if (cons
.defaultConstructor
) {
3818 includes
.add("com.sun.star.uno.Exception"_ostr
);
3819 includes
.add("com.sun.star.uno.RuntimeException"_ostr
);
3821 if (!hasRestParameter(cons
)) {
3823 includes
.addSequence();
3824 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter
& param
:
3826 if (m_typeMgr
->getSort(
3827 b2u(codemaker::UnoType::decompose(
3829 == codemaker::UnoType::Sort::Char
) {
3830 includes
.addCppuUnotypeHxx();
3835 codemaker::ExceptionTree tree
;
3836 for (const OUString
& ex
: cons
.exceptions
) {
3837 tree
.add(u2b(ex
), m_typeMgr
);
3839 if (!tree
.getRoot().present
) {
3840 includes
.add("com.sun.star.uno.Exception"_ostr
);
3841 includes
.add("com.sun.star.uno.RuntimeException"_ostr
);
3842 includeExceptions(includes
, &tree
.getRoot());
3848 codemaker::cpp::translateUnoToCppIdentifier(
3849 u2b(id_
), "service", isGlobal()));
3850 OUString
headerDefine(dumpHeaderDefine(o
, u
"HPP"));
3852 includes
.dump(o
, nullptr, true);
3853 if (!entity_
->getConstructors().empty()) {
3854 o
<< ("\n#if defined ANDROID || defined IOS //TODO\n"
3855 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3856 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3857 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3858 << name_
.replaceAll(".", "_dot_")
3859 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3860 << name_
.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3861 << name_
.replaceAll(".", "_dot_")
3862 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3863 << name_
.replaceAll(".", "_dot_")
3864 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3865 "::css::uno::Any > const &);\n#endif\n";
3868 if (codemaker::cppumaker::dumpNamespaceOpen(o
, name_
, false)) {
3871 o
<< "\nclass " << cppName
<< " {\n";
3873 if (!entity_
->getConstructors().empty()) {
3874 OString
baseName(u2b(entity_
->getBase()));
3875 OString
scopedBaseName(codemaker::cpp::scopedCppName(baseName
));
3877 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor
& cons
:
3878 entity_
->getConstructors()) {
3879 if (cons
.defaultConstructor
) {
3880 o
<< indent() << "static ::css::uno::Reference< "
3881 << scopedBaseName
<< " > "
3882 << codemaker::cpp::translateUnoToCppIdentifier(
3883 "create"_ostr
, "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal
,
3885 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3886 " the_context) {\n");
3888 o
<< indent() << "assert(the_context.is());\n" << indent()
3889 << "::css::uno::Reference< " << scopedBaseName
3890 << " > the_instance;\n" << indent() << "try {\n";
3892 o
<< ("#if defined LO_URE_CURRENT_ENV && defined "
3894 << name_
.replaceAll(".", "_dot_")
3895 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3896 << name_
.replaceAll(".", "_dot_")
3897 << ") && defined LO_URE_CTOR_FUN_"
3898 << name_
.replaceAll(".", "_dot_") << "\n" << indent()
3899 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3900 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3901 "static_cast< ::css::uno::XInterface * >((*"
3903 << name_
.replaceAll(".", "_dot_")
3904 << (")(the_context.get(), ::css::uno::Sequence<"
3905 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3906 " ::css::uno::UNO_QUERY);\n#else\n")
3907 << indent() << "the_instance = ::css::uno::Reference< "
3909 << (" >(the_context->getServiceManager()->"
3910 "createInstanceWithContext("
3913 << "\", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3916 << "} catch (const ::css::uno::RuntimeException &) {\n";
3918 o
<< indent() << "throw;\n";
3921 << "} catch (const ::css::uno::Exception & the_exception) {\n";
3923 o
<< indent() << "throw ::css::uno::DeploymentException(";
3924 failsToSupply(o
, name_
, baseName
);
3925 o
<< " + \": \" + the_exception.Message, the_context);\n";
3927 o
<< indent() << "}\n" << indent()
3928 << "if (!the_instance.is()) {\n";
3930 o
<< indent() << "throw ::css::uno::DeploymentException(";
3931 failsToSupply(o
, name_
, baseName
);
3932 o
<< ", the_context);\n";
3934 o
<< indent() << "}\n" << indent() << "return the_instance;\n";
3936 o
<< indent() << "}\n\n";
3938 o
<< indent() << "static ::css::uno::Reference< "
3939 << scopedBaseName
<< " > "
3940 << codemaker::cpp::translateUnoToCppIdentifier(
3941 u2b(cons
.name
), "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal
,
3943 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3945 bool rest
= hasRestParameter(cons
);
3946 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter
& param
:
3949 OUStringBuffer
buf(2 + param
.type
.getLength());
3953 buf
.append(param
.type
);
3954 OUString
type(buf
.makeStringAndClear());
3955 bool byRef
= passByReference(type
);
3956 dumpType(o
, type
, byRef
, byRef
);
3958 << codemaker::cpp::translateUnoToCppIdentifier(
3959 u2b(param
.name
), "param", codemaker::cpp::IdentifierTranslationMode::NonGlobal
);
3963 o
<< indent() << "assert(the_context.is());\n";
3964 if (!rest
&& !cons
.parameters
.empty()) {
3966 << "::css::uno::Sequence< ::css::uno::Any > the_arguments("
3967 << cons
.parameters
.size() << ");\n";
3969 << "::css::uno::Any* the_arguments_array = the_arguments.getArray();\n";
3972 unoidl::SingleInterfaceBasedServiceEntity::Constructor::
3973 Parameter
>::size_type n
= 0;
3974 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter
& j
:
3976 o
<< indent() << "the_arguments_array[" << n
++ << "] ";
3978 codemaker::cpp::translateUnoToCppIdentifier(
3979 u2b(j
.name
), "param",
3980 codemaker::cpp::IdentifierTranslationMode::NonGlobal
));
3982 if (resolveOuterTypedefs(j
.type
) == "any") {
3984 } else if (m_typeMgr
->getSort(
3985 b2u(codemaker::UnoType::decompose(
3986 u2b(j
.type
), &rank
)))
3987 == codemaker::UnoType::Sort::Char
) {
3988 o
<< "= ::css::uno::Any(&" << param
3989 << ", ::cppu::UnoType< ";
3990 for (sal_Int32 k
= 0; k
< rank
; ++k
) {
3991 o
<< "::cppu::UnoSequenceType< ";
3993 o
<< "::cppu::UnoCharType";
3994 for (sal_Int32 k
= 0; k
< rank
; ++k
) {
3999 o
<< "<<= " << param
;
4004 o
<< indent() << "::css::uno::Reference< "
4005 << scopedBaseName
<< " > the_instance;\n";
4006 codemaker::ExceptionTree tree
;
4007 for (const OUString
& ex
: cons
.exceptions
) {
4008 tree
.add(u2b(ex
), m_typeMgr
);
4010 if (!tree
.getRoot().present
) {
4011 o
<< indent() << "try {\n";
4014 o
<< ("#if defined LO_URE_CURRENT_ENV && defined "
4016 << name_
.replaceAll(".", "_dot_")
4017 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
4018 << name_
.replaceAll(".", "_dot_")
4019 << ") && defined LO_URE_CTOR_FUN_"
4020 << name_
.replaceAll(".", "_dot_") << "\n" << indent()
4021 << "the_instance = ::css::uno::Reference< " << scopedBaseName
4022 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
4023 "static_cast< ::css::uno::XInterface * >((*"
4025 << name_
.replaceAll(".", "_dot_")
4026 << ")(the_context.get(), ";
4028 o
<< codemaker::cpp::translateUnoToCppIdentifier(
4029 u2b(cons
.parameters
.back().name
), "param",
4030 codemaker::cpp::IdentifierTranslationMode::NonGlobal
);
4031 } else if (cons
.parameters
.empty()) {
4032 o
<< "::css::uno::Sequence< ::css::uno::Any >()";
4034 o
<< "the_arguments";
4036 o
<< ")), ::SAL_NO_ACQUIRE), ::css::uno::UNO_QUERY);\n" << indent()
4037 << ("::css::uno::Reference< ::css::lang::XInitialization > "
4038 "init(the_instance, ::css::uno::UNO_QUERY);\n")
4039 << indent() << "if (init.is()) {\n"
4040 << indent() << " init->initialize(";
4041 if (cons
.parameters
.empty()) {
4042 o
<< "::css::uno::Sequence< ::css::uno::Any >()";
4044 o
<< "the_arguments";
4046 o
<< ");\n" << indent() << "}\n";
4048 << indent() << "the_instance = ::css::uno::Reference< "
4050 << (" >(the_context->getServiceManager()->"
4051 "createInstanceWithArgumentsAndContext("
4055 o
<< codemaker::cpp::translateUnoToCppIdentifier(
4056 u2b(cons
.parameters
.back().name
), "param",
4057 codemaker::cpp::IdentifierTranslationMode::NonGlobal
);
4058 } else if (cons
.parameters
.empty()) {
4059 o
<< "::css::uno::Sequence< ::css::uno::Any >()";
4061 o
<< "the_arguments";
4063 o
<< ", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
4064 if (!tree
.getRoot().present
) {
4067 << "} catch (const ::css::uno::RuntimeException &) {\n";
4069 o
<< indent() << "throw;\n";
4071 dumpCatchClauses(o
, &tree
.getRoot());
4073 << ("} catch (const ::css::uno::Exception &"
4074 " the_exception) {\n");
4076 o
<< indent() << "throw ::css::uno::DeploymentException(";
4077 failsToSupply(o
, name_
, baseName
);
4078 o
<< " + \": \" + the_exception.Message, the_context);\n";
4080 o
<< indent() << "}\n";
4082 o
<< indent() << "if (!the_instance.is()) {\n";
4084 o
<< indent() << "throw ::css::uno::DeploymentException(";
4085 failsToSupply(o
, name_
, baseName
);
4086 o
<< ", the_context);\n";
4088 o
<< indent() << "}\n" << indent() << "return the_instance;\n";
4090 o
<< indent() << "}\n\n";
4095 o
<< indent() << cppName
<< "(); // not implemented\n"
4096 << indent() << cppName
<< "(" << cppName
<< " &); // not implemented\n"
4097 << indent() << "~" << cppName
<< "(); // not implemented\n"
4098 << indent() << "void operator =(" << cppName
<< "); // not implemented\n";
4101 if (codemaker::cppumaker::dumpNamespaceClose(o
, name_
, false)) {
4104 o
<< "\n#endif // "<< headerDefine
<< "\n";
4107 void ServiceType::dumpCatchClauses(
4108 FileStream
& out
, codemaker::ExceptionTreeNode
const * node
)
4110 if (node
->present
) {
4111 out
<< indent() << "} catch (const ";
4112 dumpType(out
, b2u(node
->name
));
4115 out
<< indent() << "throw;\n";
4118 for (std::unique_ptr
<codemaker::ExceptionTreeNode
> const & pChild
: node
->children
) {
4119 dumpCatchClauses(out
, pChild
.get());
4124 class SingletonType
: public ConstructiveType
4128 rtl::Reference
< unoidl::InterfaceBasedSingletonEntity
> const & entity
,
4129 OUString
const & name
, rtl::Reference
< TypeManager
> const & manager
):
4130 ConstructiveType(name
, manager
), entity_(entity
) {
4131 assert(entity
.is());
4135 virtual void dumpHppFile(
4136 FileStream
& o
, codemaker::cppumaker::Includes
& includes
) override
;
4138 rtl::Reference
< unoidl::InterfaceBasedSingletonEntity
> entity_
;
4141 void SingletonType::dumpHppFile(
4142 FileStream
& o
, codemaker::cppumaker::Includes
& includes
)
4145 codemaker::cpp::translateUnoToCppIdentifier(
4146 u2b(id_
), "singleton", isGlobal()));
4147 OString
baseName(u2b(entity_
->getBase()));
4148 OString
scopedBaseName(codemaker::cpp::scopedCppName(baseName
));
4149 OUString
headerDefine(dumpHeaderDefine(o
, u
"HPP"));
4151 //TODO: Decide whether the types added to includes should rather be added to
4152 // m_dependencies (and thus be generated during dumpDependedTypes):
4153 includes
.add("com.sun.star.uno.DeploymentException"_ostr
);
4154 includes
.add("com.sun.star.uno.XComponentContext"_ostr
);
4155 includes
.addCassert();
4157 includes
.addReference();
4158 includes
.addRtlUstringH();
4159 includes
.addRtlUstringHxx();
4160 includes
.dump(o
, nullptr, true);
4161 o
<< ("\n#if defined ANDROID || defined IOS //TODO\n"
4162 "#include <com/sun/star/lang/XInitialization.hpp>\n"
4163 "#include <osl/detail/component-defines.h>\n#endif\n\n"
4164 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
4165 << name_
.replaceAll(".", "_dot_")
4166 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
4167 << name_
.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
4168 << name_
.replaceAll(".", "_dot_")
4169 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
4170 << name_
.replaceAll(".", "_dot_")
4171 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
4172 "::css::uno::Any > const &);\n#endif\n";
4174 if (codemaker::cppumaker::dumpNamespaceOpen(o
, name_
, false)) {
4177 o
<< "\nclass " << cppName
<< " {\npublic:\n";
4179 o
<< indent() << "static ::css::uno::Reference< "
4180 << scopedBaseName
<< " > "
4181 << codemaker::cpp::translateUnoToCppIdentifier(
4182 "get"_ostr
, "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal
, &cppName
)
4183 << ("(::css::uno::Reference<"
4184 " ::css::uno::XComponentContext > const & the_context)"
4187 o
<< indent() << "assert(the_context.is());\n" << indent()
4188 << "::css::uno::Reference< " << scopedBaseName
4189 << (" > instance;\n#if defined LO_URE_CURRENT_ENV && defined "
4191 << name_
.replaceAll(".", "_dot_")
4192 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
4193 << name_
.replaceAll(".", "_dot_")
4194 << ") && defined LO_URE_CTOR_FUN_"
4195 << name_
.replaceAll(".", "_dot_") << "\n" << indent()
4196 << "instance = ::css::uno::Reference< " << scopedBaseName
4197 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
4198 "static_cast< ::css::uno::XInterface * >((*"
4200 << name_
.replaceAll(".", "_dot_")
4201 << (")(the_context.get(), ::css::uno::Sequence<"
4202 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
4203 " ::css::uno::UNO_QUERY);\n#else\n")
4204 << indent() << ("the_context->getValueByName("
4205 "::rtl::OUString( \"/singletons/")
4206 << name_
<< "\" )) >>= instance;\n#endif\n"
4207 << indent() << "if (!instance.is()) {\n";
4210 << ("throw ::css::uno::DeploymentException("
4211 "::rtl::OUString( \"component context"
4212 " fails to supply singleton ")
4213 << name_
<< " of type " << baseName
<< "\" ), the_context);\n";
4215 o
<< indent() << "}\n" << indent() << "return instance;\n";
4217 o
<< indent() << "}\n\n";
4219 o
<< indent() << cppName
<< "(); // not implemented\n"
4220 << indent() << cppName
<< "(" << cppName
<< " &); // not implemented\n"
4221 << indent() << "~" << cppName
<< "(); // not implemented\n"
4222 << indent() << "void operator =(" << cppName
<< "); // not implemented\n";
4225 if (codemaker::cppumaker::dumpNamespaceClose(o
, name_
, false)) {
4228 o
<< "\n#endif // "<< headerDefine
<< "\n";
4234 OUString
const & name
, rtl::Reference
< TypeManager
> const & manager
,
4235 codemaker::GeneratedTypeSet
& generated
, CppuOptions
const & options
)
4237 if (generated
.contains(u2b(name
))) {
4240 generated
.add(u2b(name
));
4241 if (!manager
->foundAtPrimaryProvider(name
)) {
4244 rtl::Reference
< unoidl::Entity
> ent
;
4245 rtl::Reference
< unoidl::MapCursor
> cur
;
4246 switch (manager
->getSort(name
, &ent
, &cur
)) {
4247 case codemaker::UnoType::Sort::Module
: {
4249 if (!name
.isEmpty()) {
4250 prefix
= name
+ ".";
4254 if (!cur
->getNext(&mem
).is()) {
4257 produce(prefix
+ mem
, manager
, generated
, options
);
4261 case codemaker::UnoType::Sort::Enum
: {
4263 dynamic_cast< unoidl::EnumTypeEntity
* >(ent
.get()), name
,
4266 t
.dumpDependedTypes(generated
, options
);
4269 case codemaker::UnoType::Sort::PlainStruct
: {
4271 dynamic_cast< unoidl::PlainStructTypeEntity
* >(ent
.get()),
4274 t
.dumpDependedTypes(generated
, options
);
4277 case codemaker::UnoType::Sort::PolymorphicStructTemplate
: {
4279 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity
* >(
4283 t
.dumpDependedTypes(generated
, options
);
4286 case codemaker::UnoType::Sort::Exception
: {
4288 dynamic_cast< unoidl::ExceptionTypeEntity
* >(ent
.get()), name
,
4291 t
.dumpDependedTypes(generated
, options
);
4294 case codemaker::UnoType::Sort::Interface
: {
4296 dynamic_cast< unoidl::InterfaceTypeEntity
* >(ent
.get()), name
,
4299 t
.dumpDependedTypes(generated
, options
);
4302 case codemaker::UnoType::Sort::Typedef
: {
4304 dynamic_cast< unoidl::TypedefEntity
* >(ent
.get()), name
,
4307 t
.dumpDependedTypes(generated
, options
);
4310 case codemaker::UnoType::Sort::ConstantGroup
: {
4312 dynamic_cast< unoidl::ConstantGroupEntity
* >(ent
.get()), name
,
4314 if (t
.hasConstants()) {
4319 case codemaker::UnoType::Sort::SingleInterfaceBasedService
: {
4321 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity
* >(
4325 t
.dumpDependedTypes(generated
, options
);
4328 case codemaker::UnoType::Sort::InterfaceBasedSingleton
: {
4330 dynamic_cast< unoidl::InterfaceBasedSingletonEntity
* >(
4334 t
.dumpDependedTypes(generated
, options
);
4337 case codemaker::UnoType::Sort::AccumulationBasedService
:
4338 case codemaker::UnoType::Sort::ServiceBasedSingleton
:
4341 throw CannotDumpException(
4342 "unexpected entity \"" + name
+ "\" in call to produce");
4346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */