Bump version to 24.04.3.4
[LibreOffice.git] / codemaker / source / cppumaker / cpputype.cxx
blobc67772eb2e887db9071a5fac2cd9df6dec46dd71
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
23 #include <algorithm>
24 #include <cassert>
25 #include <cstdlib>
26 #include <map>
27 #include <set>
28 #include <string_view>
29 #include <memory>
30 #include <utility>
31 #include <vector>
32 #include <iostream>
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"
53 namespace
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)
157 switch(eFileType)
159 default:
160 case FileType::HDL: return ".hdl"_ostr;
161 case FileType::HPP: return ".hpp"_ostr;
162 case FileType::EMBIND_CXX: return "_embind.cxx"_ostr;
166 class CppuType
168 public:
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);
178 void dumpFile(
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
208 void dumpType(
209 FileStream & out, std::u16string_view name, bool isConst = false,
210 bool isRef = false, bool native = false, bool cppuUnoType = false)
211 const;
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;
223 protected:
224 virtual sal_uInt32 checkInheritedMemberCount() const {
225 assert(false); // this cannot happen
226 return 0;
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);
276 protected:
277 sal_uInt32 m_inheritedMemberCount;
279 bool m_cppuTypeLeak;
280 bool m_cppuTypeDynamic;
281 sal_Int32 m_indentLength;
282 OUString name_;
283 OUString id_;
284 rtl::Reference< TypeManager > m_typeMgr;
285 codemaker::cppumaker::Dependencies m_dependencies;
287 private:
288 void addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
289 const;
292 CppuType::CppuType(
293 OUString name, rtl::Reference< TypeManager > const & typeMgr):
294 m_inheritedMemberCount(0)
295 , m_cppuTypeLeak(false)
296 , m_cppuTypeDynamic(true)
297 , m_indentLength(0)
298 , name_(std::move(name))
299 , id_(name_.copy(name_.lastIndexOf('.') + 1))
300 , m_typeMgr(typeMgr)
301 , m_dependencies(typeMgr, name_)
304 void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
305 const
307 if (name_ == "com.sun.star.uno.XInterface"
308 || name_ == "com.sun.star.uno.Exception") {
309 includes.addType();
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);
318 } else {
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
357 return false;
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";
369 inc();
370 out << indent()
371 << "static inline ::css::uno::Type const & get() {\n";
372 } else {
373 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
374 out << "\n\n";
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";
381 inc();
384 void CppuType::dumpGetCppuTypePostamble(FileStream & out)
386 dec();
387 if (isPolymorphic()) {
388 out << indent() << "}\n\nprivate:\n"
389 << indent() << "UnoType(UnoType &); // not defined\n"
390 << indent() << "~UnoType(); // not defined\n"
391 << indent()
392 << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
393 } else {
394 out << "}\n\n";
395 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
396 out << "\n\n";
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";
405 inc();
406 out << indent() << "return ::cppu::UnoType< ";
407 dumpType(out, name_);
408 dumpTemplateParameters(out);
409 out << " >::get();\n";
410 dec();
411 out << indent() << "}\n";
414 void CppuType::dump(CppuOptions const & options)
416 if (isBootstrapType(name_)) {
417 m_cppuTypeDynamic = false;
418 } else {
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;
428 dumpFiles(
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)
436 OUString fileUri(
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)) {
444 return;
446 FileStream out;
447 out.createTempFile(getTempDir(u2b(fileUri)));
448 OUString tmpUri(b2u(out.getName()));
449 if(!out.isValid()) {
450 throw CannotDumpException("cannot open " + tmpUri + " for writing");
452 codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, eFileType);
453 try {
454 switch(eFileType)
456 case FileType::HPP:
457 addGetCppuTypeIncludes(includes);
458 dumpHppFile(out, includes);
459 break;
460 case FileType::HDL:
461 dumpHdlFile(out, includes);
462 break;
463 case FileType::EMBIND_CXX:
464 dumpEmbindCppFile(out);
465 break;
467 } catch (...) {
468 out.close();
469 // Remove existing type file if something goes wrong to ensure
470 // consistency:
471 if (fileExists(u2b(fileUri))) {
472 removeTypeFile(u2b(fileUri));
474 removeTypeFile(u2b(tmpUri));
475 throw;
477 out.close();
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
497 OUString def(
498 "INCLUDED_" + name_.replace('.', '_').toAsciiUpperCase() + "_"
499 + extension);
500 out << "#ifndef " << def << "\n#define " << def << "\n";
501 return def;
504 void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes)
505 const
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)
516 const
518 //TODO: Only include what is really needed
519 includes.addType();
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
529 out << "(";
530 if (!parameterized) {
531 sal_Int32 k;
532 std::vector< OString > args;
533 OUString n(
534 b2u(codemaker::UnoType::decompose(
535 u2b(resolveAllTypedefs(name)), &k, &args)));
536 if (k == 0) {
537 rtl::Reference< unoidl::Entity > ent;
538 switch (m_typeMgr->getSort(n, &ent)) {
539 case codemaker::UnoType::Sort::Boolean:
540 out << "false";
541 break;
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:
552 out << "0";
553 break;
554 case codemaker::UnoType::Sort::Enum:
555 out << codemaker::cpp::scopedCppName(u2b(n)) << "_"
556 << (dynamic_cast<unoidl::EnumTypeEntity&>(*ent).
557 getMembers()[0].name);
558 break;
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:
565 break;
566 default:
567 throw CannotDumpException(
568 OUString::Concat("unexpected entity \"") + name
569 + "\" in call to CppuType::dumpInitializer");
573 out << ")";
576 void CppuType::dumpHFileContent(
577 FileStream & out, codemaker::cppumaker::Includes & includes)
579 addDefaultHIncludes(includes);
580 dumpHeaderDefine(out, u"HDL");
581 out << "\n";
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)) {
588 out << "\n";
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)) {
601 out << "\n";
603 out << "\n";
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);
618 out << "#endif\n";
621 void CppuType::dumpGetCppuType(FileStream & out)
623 if (name_ == "com.sun.star.uno.XInterface") {
624 out << indent()
625 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
626 " getCppuType(SAL_UNUSED_PARAMETER ");
627 dumpType(out, name_, true);
628 out << " *) {\n";
629 inc();
630 out << indent()
631 << ("return ::cppu::UnoType< ::css::uno::XInterface"
632 " >::get();\n");
633 dec();
634 out << indent() << "}\n";
635 } else if (name_ == "com.sun.star.uno.Exception") {
636 out << indent()
637 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
638 " getCppuType(SAL_UNUSED_PARAMETER ");
639 dumpType(out, name_, true);
640 out << " *) {\n";
641 inc();
642 out << indent()
643 << ("return ::cppu::UnoType< ::css::uno::Exception"
644 " >::get();\n");
645 dec();
646 out << indent() << "}\n";
647 } else if (m_cppuTypeLeak) {
648 dumpLightGetCppuType(out);
649 } else if (m_cppuTypeDynamic) {
650 dumpNormalGetCppuType(out);
651 } else {
652 dumpComprehensiveGetCppuType(out);
656 void CppuType::dumpLightGetCppuType(FileStream & out)
658 dumpGetCppuTypePreamble(out);
659 out << indent()
660 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
661 << indent() << "if ( !the_type )\n" << indent() << "{\n";
662 inc();
663 out << indent() << "typelib_static_type_init( &the_type, "
664 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
665 dec();
666 out << indent() << "}\n" << indent()
667 << ("return * reinterpret_cast< ::css::uno::Type * >("
668 " &the_type );\n");
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:
692 return cStyle
693 ? OUString("typelib_TypeClass_VOID")
694 : OUString("::css::uno::TypeClass_VOID");
695 case codemaker::UnoType::Sort::Boolean:
696 return cStyle
697 ? OUString("typelib_TypeClass_BOOLEAN")
698 : OUString("::css::uno::TypeClass_BOOLEAN");
699 case codemaker::UnoType::Sort::Byte:
700 return cStyle
701 ? OUString("typelib_TypeClass_BYTE")
702 : OUString("::css::uno::TypeClass_BYTE");
703 case codemaker::UnoType::Sort::Short:
704 return cStyle
705 ? OUString("typelib_TypeClass_SHORT")
706 : OUString("::css::uno::TypeClass_SHORT");
707 case codemaker::UnoType::Sort::UnsignedShort:
708 return cStyle
709 ? OUString("typelib_TypeClass_UNSIGNED_SHORT")
710 : OUString("::css::uno::TypeClass_UNSIGNED_SHORT");
711 case codemaker::UnoType::Sort::Long:
712 return cStyle
713 ? OUString("typelib_TypeClass_LONG")
714 : OUString("::css::uno::TypeClass_LONG");
715 case codemaker::UnoType::Sort::UnsignedLong:
716 return cStyle
717 ? OUString("typelib_TypeClass_UNSIGNED_LONG")
718 : OUString("::css::uno::TypeClass_UNSIGNED_LONG");
719 case codemaker::UnoType::Sort::Hyper:
720 return cStyle
721 ? OUString("typelib_TypeClass_HYPER")
722 : OUString("::css::uno::TypeClass_HYPER");
723 case codemaker::UnoType::Sort::UnsignedHyper:
724 return cStyle
725 ? OUString("typelib_TypeClass_UNSIGNED_HYPER")
726 : OUString("::css::uno::TypeClass_UNSIGNED_HYPER");
727 case codemaker::UnoType::Sort::Float:
728 return cStyle
729 ? OUString("typelib_TypeClass_FLOAT")
730 : OUString("::css::uno::TypeClass_FLOAT");
731 case codemaker::UnoType::Sort::Double:
732 return cStyle
733 ? OUString("typelib_TypeClass_DOUBLE")
734 : OUString("::css::uno::TypeClass_DOUBLE");
735 case codemaker::UnoType::Sort::Char:
736 return cStyle
737 ? OUString("typelib_TypeClass_CHAR")
738 : OUString("::css::uno::TypeClass_CHAR");
739 case codemaker::UnoType::Sort::String:
740 return cStyle
741 ? OUString("typelib_TypeClass_STRING")
742 : OUString("::css::uno::TypeClass_STRING");
743 case codemaker::UnoType::Sort::Type:
744 return cStyle
745 ? OUString("typelib_TypeClass_TYPE")
746 : OUString("::css::uno::TypeClass_TYPE");
747 case codemaker::UnoType::Sort::Any:
748 return cStyle
749 ? OUString("typelib_TypeClass_ANY")
750 : OUString("::css::uno::TypeClass_ANY");
751 case codemaker::UnoType::Sort::Sequence:
752 return cStyle
753 ? OUString("typelib_TypeClass_SEQUENCE")
754 : OUString("::css::uno::TypeClass_SEQUENCE");
755 case codemaker::UnoType::Sort::Enum:
756 return cStyle
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:
762 return cStyle
763 ? OUString("typelib_TypeClass_STRUCT")
764 : OUString("::css::uno::TypeClass_STRUCT");
765 case codemaker::UnoType::Sort::Exception:
766 return cStyle
767 ? OUString("typelib_TypeClass_EXCEPTION")
768 : OUString("::css::uno::TypeClass_EXCEPTION");
769 case codemaker::UnoType::Sort::Interface:
770 return cStyle
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);
775 default:
776 for (;;) {
777 std::abort();
782 void CppuType::dumpType(
783 FileStream & out, std::u16string_view name, bool isConst, bool isRef,
784 bool native, bool cppuUnoType) const
786 sal_Int32 k;
787 std::vector< OString > args;
788 OUString n(
789 b2u(codemaker::UnoType::decompose(
790 u2b(resolveAllTypedefs(name)), &k, &args)));
791 if (isConst) {
792 out << "const ";
794 for (sal_Int32 i = 0; i != k; ++i) {
795 out << (cppuUnoType
796 ? "::cppu::UnoSequenceType" : "::css::uno::Sequence")
797 << "< ";
799 switch (m_typeMgr->getSort(n)) {
800 case codemaker::UnoType::Sort::Void:
801 out << "void";
802 break;
803 case codemaker::UnoType::Sort::Boolean:
804 out << "::sal_Bool";
805 break;
806 case codemaker::UnoType::Sort::Byte:
807 out << "::sal_Int8";
808 break;
809 case codemaker::UnoType::Sort::Short:
810 out << "::sal_Int16";
811 break;
812 case codemaker::UnoType::Sort::UnsignedShort:
813 out << (cppuUnoType ? "::cppu::UnoUnsignedShortType" : "::sal_uInt16");
814 break;
815 case codemaker::UnoType::Sort::Long:
816 out << "::sal_Int32";
817 break;
818 case codemaker::UnoType::Sort::UnsignedLong:
819 out << "::sal_uInt32";
820 break;
821 case codemaker::UnoType::Sort::Hyper:
822 out << "::sal_Int64";
823 break;
824 case codemaker::UnoType::Sort::UnsignedHyper:
825 out << "::sal_uInt64";
826 break;
827 case codemaker::UnoType::Sort::Float:
828 out << "float";
829 break;
830 case codemaker::UnoType::Sort::Double:
831 out << "double";
832 break;
833 case codemaker::UnoType::Sort::Char:
834 out << (cppuUnoType ? "::cppu::UnoCharType" : "::sal_Unicode");
835 break;
836 case codemaker::UnoType::Sort::String:
837 out << "::rtl::OUString";
838 break;
839 case codemaker::UnoType::Sort::Type:
840 out << "::css::uno::Type";
841 break;
842 case codemaker::UnoType::Sort::Any:
843 out << "::css::uno::Any";
844 break;
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));
849 break;
850 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
851 out << codemaker::cpp::scopedCppName(u2b(n));
852 if (!args.empty()) {
853 out << "< ";
854 for (std::vector< OString >::iterator i(args.begin());
855 i != args.end(); ++i) {
856 if (i != args.begin()) {
857 out << ", ";
859 dumpType(out, b2u(*i));
861 out << " >";
863 break;
864 case codemaker::UnoType::Sort::Interface:
865 if (!native) {
866 out << "::css::uno::Reference< ";
868 out << codemaker::cpp::scopedCppName(u2b(n));
869 if (!native) {
870 out << " >";
872 break;
873 default:
874 throw CannotDumpException(
875 OUString::Concat("unexpected entity \"") + name + "\" in call to CppuType::dumpType");
877 for (sal_Int32 i = 0; i != k; ++i) {
878 out << " >";
880 if (isRef) {
881 out << "&";
885 void CppuType::dumpCppuGetType(
886 FileStream & out, std::u16string_view name, OUString const * ownName) const
888 //TODO: What are these calls good for?
889 OUString nucleus;
890 sal_Int32 rank;
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:
909 break;
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";
922 break;
923 case codemaker::UnoType::Sort::Typedef:
924 for (;;) std::abort(); // this cannot happen
925 default:
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:
947 return false;
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:
955 return true;
956 default:
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
970 if (depth > 10)
971 return false;
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:
988 return true;
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))
995 return false;
996 for ( const unoidl::PlainStructTypeEntity::Member& rMember : ent2->getDirectMembers()) {
997 if (!canBeWarnUnused(rMember.type, depth+1))
998 return false;
1000 return true;
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:
1009 return false;
1010 default:
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) {
1022 return n;
1024 n = dynamic_cast<unoidl::TypedefEntity&>(*ent).getType();
1028 OUString CppuType::resolveAllTypedefs(std::u16string_view name) const
1030 sal_Int32 k1;
1031 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k1)));
1032 for (;;) {
1033 rtl::Reference< unoidl::Entity > ent;
1034 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
1035 break;
1037 sal_Int32 k2;
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) {
1044 b.append("[]");
1046 b.append(n);
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) {
1064 buf.append(' ');
1066 return buf.makeStringAndClear();
1069 bool isDeprecated(std::vector< OUString > const & annotations)
1071 for (const OUString& r : annotations) {
1072 if (r == "deprecated") {
1073 return true;
1076 return false;
1079 void dumpDeprecation(FileStream & out, bool deprecated)
1081 if (deprecated) {
1082 out << "SAL_DEPRECATED_INTERNAL(\"marked @deprecated in UNOIDL\") ";
1086 class BaseOffset
1088 public:
1089 BaseOffset(
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 {
1099 return offset_;
1102 private:
1103 void calculateBases(
1104 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity);
1106 rtl::Reference< TypeManager > manager_;
1107 std::set< OUString > set_;
1108 sal_Int32 offset_;
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()));
1126 assert(ent2.is());
1127 calculateBases(ent2);
1128 offset_ += ent2->getDirectAttributes().size()
1129 + ent2->getDirectMethods().size(); //TODO: overflow
1134 class InterfaceType: public CppuType
1136 public:
1137 InterfaceType(
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;
1159 private:
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";
1198 inc();
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);
1206 dumpMethods(out);
1207 out << "\n" << indent()
1208 << ("static inline ::css::uno::Type const & SAL_CALL"
1209 " static_type(void * = 0);\n\n");
1210 dec();
1211 out << "protected:\n";
1212 inc();
1213 out << indent() << "~" << id_
1214 << ("() SAL_NOEXCEPT {} // avoid warnings about virtual members and"
1215 " non-virtual dtor\n");
1216 dec();
1217 out << "};\n\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"
1228 "}}\n";
1230 out << "EMSCRIPTEN_BINDINGS(uno_bindings_";
1231 codemaker::cppumaker::dumpTypeFullWithDecorator(out, name_, u"_");
1232 codemaker::cppumaker::dumpTypeIdentifier(out, name_);
1233 out << ") {\n";
1235 out << "\nclass_<" << codemaker::cpp::scopedCppName(u2b(name_)) << ">(\"";
1236 codemaker::cppumaker::dumpTypeFullWithDecorator(out, name_, u"$");
1237 codemaker::cppumaker::dumpTypeIdentifier(out, name_);
1238 out << "\")\n";
1240 inc();
1241 // dump bindings for attributes and methods.
1242 dumpEmbindAttributeBindings(out);
1243 dumpEmbindMethodBindings(out);
1244 out << indent() << ";\n";
1245 dec();
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_);
1251 out << "Ref\")\n";
1252 inc();
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";
1261 dec();
1263 out << "}\n";
1267 void InterfaceType::dumpHppFile(
1268 FileStream & out, codemaker::cppumaker::Includes & includes)
1270 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
1271 out << "\n";
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";
1279 inc();
1280 out << indent() << "return ::cppu::UnoType< ";
1281 dumpType(out, name_, false, false, true);
1282 out << " >::get();\n";
1283 dec();
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);
1302 out << indent();
1303 dumpDeprecation(out, depr);
1304 out << "virtual ";
1305 dumpType(out, attr.type);
1306 out << " SAL_CALL get" << attr.name << "() = 0;\n";
1307 if (!attr.readOnly) {
1308 bool byRef = passByReference(attr.type);
1309 out << indent();
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))
1327 continue;
1329 out << indent();
1330 out << ".function(\"";
1331 out << "get" << attr.name << "\", &" << codemaker::cpp::scopedCppName(u2b(name_)) << "::get"
1332 << attr.name << ")\n";
1333 if (!attr.readOnly)
1335 out << indent();
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()) {
1349 out << indent();
1350 dumpDeprecation(out, m_isDeprecated || isDeprecated(method.annotations));
1351 out << "virtual ";
1352 dumpType(out, method.returnType);
1353 out << " SAL_CALL " << method.name << "(";
1354 if (!method.parameters.empty()) {
1355 out << " ";
1356 for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1357 const_iterator j(method.parameters.begin());
1358 j != method.parameters.end();) {
1359 bool isConst;
1360 bool isRef;
1361 if (j->direction
1362 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1364 isConst = passByReference(j->type);
1365 isRef = isConst;
1366 } else {
1367 isConst = false;
1368 isRef = true;
1370 dumpType(out, j->type, isConst, isRef);
1371 out << " " << j->name;
1372 ++j;
1373 if (j != method.parameters.end()) {
1374 out << ", ";
1377 out << " ";
1379 out << ") = 0;\n";
1383 void InterfaceType::dumpEmbindWrapperFunc(FileStream& out,
1384 const unoidl::InterfaceTypeEntity::Method& method,
1385 bool bDumpForReference) const
1387 out << indent();
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)
1394 out << ">";
1395 out << "* self";
1396 if(!method.parameters.empty())
1397 out << ",";
1399 auto dumpParameters = [&](bool bDumpType)
1401 // dumpParams with references as pointers
1402 if (!method.parameters.empty())
1404 out << " ";
1405 for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
1406 parameter(method.parameters.begin());
1407 parameter != method.parameters.end();)
1409 bool isConst;
1410 bool isRef;
1411 if (parameter->direction
1412 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1414 isConst = passByReference(parameter->type);
1415 isRef = isConst;
1417 else
1419 isConst = false;
1420 isRef = true;
1422 // for the embind wrapper, we define a pointer instead of a reference.
1423 if (bDumpType)
1424 dumpType(out, parameter->type, isConst, /*isRef=*/false);
1425 if (isRef)
1426 out << "*";
1428 out << " " << parameter->name;
1429 ++parameter;
1430 if (parameter != method.parameters.end())
1432 out << ", ";
1435 out << " ";
1438 dumpParameters(/*bDumpType=*/true);
1440 if (bDumpForReference)
1442 out << ") { return self->get()->" << method.name << "(";
1444 else
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) )
1460 continue;
1462 // if dumping the method binding for a reference implementation
1463 // dump wrapper.
1464 if(bDumpForReference)
1466 dumpEmbindWrapperFunc(out, method, true);
1467 continue;
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;
1477 if (bHasOutParams)
1479 dumpEmbindWrapperFunc(out, method, false);
1480 continue;
1483 out << indent();
1484 out << ".function(\"" << method.name << "\", &"
1485 << codemaker::cpp::scopedCppName(u2b(name_))
1486 << "::" << method.name << ")\n";
1492 void InterfaceType::dumpNormalGetCppuType(FileStream & out)
1494 dumpGetCppuTypePreamble(out);
1495 out << indent()
1496 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
1497 << indent() << "if ( !the_type )\n" << indent() << "{\n";
1498 inc();
1499 std::vector< unoidl::AnnotatedReference >::size_type bases(
1500 entity_->getDirectMandatoryBases().size());
1501 if (bases == 1
1502 && (entity_->getDirectMandatoryBases()[0].name
1503 == "com.sun.star.uno.XInterface")) {
1504 bases = 0;
1506 if (bases != 0) {
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";
1519 dec();
1520 out << indent() << "}\n" << indent()
1521 << ("return * reinterpret_cast< ::css::uno::Type * >("
1522 " &the_type );\n");
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";
1533 inc();
1534 out << indent() << "::css::uno::Type * operator()() const\n"
1535 << indent() << "{\n";
1536 inc();
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
1550 if (count != 0) {
1551 out << indent() << "typelib_TypeDescriptionReference * pMembers["
1552 << count << "] = { ";
1553 for (std::size_t i = 0; i != count; ++i) {
1554 out << "0";
1555 if (i + 1 != count) {
1556 out << ",";
1559 out << " };\n";
1560 sal_uInt32 index = 0;
1561 dumpCppuAttributeRefs(out, index);
1562 dumpCppuMethodRefs(out, index);
1564 out << "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1565 inc();
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";
1571 dec();
1572 out << indent()
1573 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1574 " );\n");
1575 for (std::size_t i = 0; i != count; ++i) {
1576 out << indent() << "typelib_typedescriptionreference_release( pMembers["
1577 << i << "] );\n";
1579 out << indent()
1580 << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1581 " );\n\n")
1582 << indent() << "return new ::css::uno::Type( "
1583 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
1584 dec();
1585 out << indent() << "}\n";
1586 dec();
1587 out << indent() << "};\n\n";
1588 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
1589 out << " }\n\n";
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";
1596 inc();
1597 out << indent()
1598 << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"
1599 << indent() << "if (!bInitStarted)\n" << indent() << "{\n";
1600 inc();
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);
1609 if (count != 0) {
1610 sal_uInt32 index = getInheritedMemberCount();
1611 dumpCppuAttributes(out, index);
1612 dumpCppuMethods(out, index);
1614 dec();
1615 out << indent() << "}\n";
1616 dec();
1617 out << indent() << "}\n" << indent() << "else\n" << indent() << "{\n";
1618 inc();
1619 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
1620 dec();
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++
1632 << "],\n";
1633 inc(38);
1634 out << indent()
1635 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_ATTRIBUTE,\n"
1636 << indent() << "sAttributeName" << n << ".pData );\n";
1637 dec(38);
1638 ++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++
1649 << "],\n";
1650 inc(38);
1651 out << indent()
1652 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_METHOD,\n"
1653 << indent() << "sMethodName" << n << ".pData );\n";
1654 dec(38);
1655 ++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())
1673 return;
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";
1681 inc();
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);
1690 out << indent()
1691 << ("typelib_typedescription_newExtendedInterfaceAttribute("
1692 " &pAttribute,\n");
1693 inc();
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")
1701 << " );\n";
1702 dec();
1703 out << indent()
1704 << ("typelib_typedescription_register("
1705 " (typelib_TypeDescription**)&pAttribute );\n");
1706 dec();
1707 out << indent() << "}\n";
1708 ++n;
1710 out << indent()
1711 << ("typelib_typedescription_release("
1712 " (typelib_TypeDescription*)pAttribute );\n");
1715 void InterfaceType::dumpCppuMethods(FileStream & out, sal_uInt32 & index)
1717 if (entity_->getDirectMethods().empty())
1718 return;
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";
1726 inc();
1727 if (!method.parameters.empty()) {
1728 out << indent() << "typelib_Parameter_Init aParameters["
1729 << method.parameters.size() << "];\n";
1731 std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1732 size_type m = 0;
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")
1752 << ";\n";
1753 ++m;
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";
1763 inc();
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";
1772 dec();
1773 out << indent()
1774 << ("typelib_typedescription_register("
1775 " (typelib_TypeDescription**)&pMethod );\n");
1776 dec();
1777 out << indent() << "}\n";
1778 ++n;
1780 out << indent()
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");
1841 if (count != 0) {
1842 out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {";
1843 for (sal_Int32 i = 0; i != count; ++i) {
1844 out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName"
1845 << i << ".pData";
1847 out << " };\n";
1849 return count;
1852 class ConstantGroup: public CppuType
1854 public:
1855 ConstantGroup(
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();
1866 private:
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"));
1882 out << "\n";
1883 addDefaultHIncludes(includes);
1884 includes.dump(out, nullptr, true);
1885 out << "\n";
1886 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, true)) {
1887 out << "\n";
1889 out << "\n";
1890 dumpDeclaration(out);
1891 out << "\n";
1892 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, true)) {
1893 out << "\n";
1895 out << "\n#endif // "<< headerDefine << "\n";
1898 void ConstantGroup::dumpHppFile(
1899 FileStream & out, codemaker::cppumaker::Includes &)
1901 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
1902 out << "\n";
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";
1914 break;
1915 case unoidl::ConstantValue::TYPE_BYTE:
1916 out << "::sal_Int8";
1917 break;
1918 case unoidl::ConstantValue::TYPE_SHORT:
1919 out << "::sal_Int16";
1920 break;
1921 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1922 out << "::sal_uInt16";
1923 break;
1924 case unoidl::ConstantValue::TYPE_LONG:
1925 out << "::sal_Int32";
1926 break;
1927 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1928 out << "::sal_uInt32";
1929 break;
1930 case unoidl::ConstantValue::TYPE_HYPER:
1931 out << "::sal_Int64";
1932 break;
1933 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1934 out << "::sal_uInt64";
1935 break;
1936 case unoidl::ConstantValue::TYPE_FLOAT:
1937 out << "float";
1938 break;
1939 case unoidl::ConstantValue::TYPE_DOUBLE:
1940 out << "double";
1941 break;
1943 out << " " << member.name << " = ";
1944 switch (member.value.type) {
1945 case unoidl::ConstantValue::TYPE_BOOLEAN:
1946 out << (member.value.booleanValue ? "sal_True" : "sal_False");
1947 break;
1948 case unoidl::ConstantValue::TYPE_BYTE:
1949 out << "(sal_Int8)" << OUString::number(member.value.byteValue);
1950 break;
1951 case unoidl::ConstantValue::TYPE_SHORT:
1952 out << "(sal_Int16)" << OUString::number(member.value.shortValue);
1953 break;
1954 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1955 out << "(sal_uInt16)"
1956 << OUString::number(member.value.unsignedShortValue);
1957 break;
1958 case unoidl::ConstantValue::TYPE_LONG:
1959 // Avoid C++ compiler warnings about (un)signedness of literal
1960 // -2^31:
1961 if (member.value.longValue == SAL_MIN_INT32) {
1962 out << "SAL_MIN_INT32";
1963 } else {
1964 out << "(sal_Int32)" << OUString::number(member.value.longValue);
1966 break;
1967 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1968 out << "(sal_uInt32)"
1969 << OUString::number(member.value.unsignedLongValue) << "U";
1970 break;
1971 case unoidl::ConstantValue::TYPE_HYPER:
1972 // Avoid C++ compiler warnings about (un)signedness of literal
1973 // -2^63:
1974 if (member.value.hyperValue == SAL_MIN_INT64) {
1975 out << "SAL_MIN_INT64";
1976 } else {
1977 out << "(sal_Int64) SAL_CONST_INT64("
1978 << OUString::number(member.value.hyperValue) << ")";
1980 break;
1981 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1982 out << "SAL_CONST_UINT64("
1983 << OUString::number(member.value.unsignedHyperValue) << ")";
1984 break;
1985 case unoidl::ConstantValue::TYPE_FLOAT:
1986 out << "(float)" << OUString::number(member.value.floatValue);
1987 break;
1988 case unoidl::ConstantValue::TYPE_DOUBLE:
1989 out << "(double)" << OUString::number(member.value.doubleValue);
1990 break;
1992 out << ";\n";
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
2006 public:
2007 PlainStructType(
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());
2014 private:
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 ";
2052 out << id_;
2053 OUString base(entity_->getDirectBase());
2054 if (!base.isEmpty()) {
2055 out << ": public " << codemaker::cpp::scopedCppName(u2b(base));
2057 out << " {\n";
2058 inc();
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()) {
2064 if (!bFirst) {
2065 out << ", ";
2067 dumpType(out, member.type, true, true);
2068 out << " " << member.name << "_";
2069 bFirst = false;
2071 out << ");\n";
2073 if (!entity_->getDirectMembers().empty()) {
2074 out << "\n";
2075 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
2076 const_iterator i(entity_->getDirectMembers().begin());
2077 i != entity_->getDirectMembers().end(); ++i) {
2078 out << indent();
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)) << ")";
2087 out << ";\n";
2090 dec();
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"));
2098 out << "\n";
2099 includes.dump(out, &name_, true);
2100 out << "\n";
2101 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2102 out << "\n";
2104 out << "\ninline " << id_ << "::" << id_ << "()\n";
2105 inc();
2106 OUString base(entity_->getDirectBase());
2107 bool bFirst = true;
2108 if (!base.isEmpty()) {
2109 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2110 << "()\n";
2111 bFirst = false;
2113 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2114 out << indent() << (bFirst ? ":" : ",") << " " << member.name;
2115 dumpInitializer(out, false, member.type);
2116 out << "\n";
2117 bFirst = false;
2119 dec();
2120 out << "{\n}\n\n";
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()) {
2126 if (!bFirst) {
2127 out << ", ";
2129 dumpType(out, member.type, true, true);
2130 out << " " << member.name << "_";
2131 bFirst = false;
2133 out << ")\n";
2134 inc();
2135 bFirst = true;
2136 if (!base.isEmpty()) {
2137 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2138 << "(";
2139 dumpBaseMembers(out, base, false);
2140 out << ")\n";
2141 bFirst = false;
2143 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2144 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
2145 << member.name << "_)\n";
2146 bFirst = false;
2148 dec();
2149 out << "{\n}\n\n";
2151 // print the operator==
2152 out << "\ninline bool operator==(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
2153 out << "{\n";
2154 inc();
2155 out << indent() << "return ";
2156 bFirst = true;
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";
2160 bFirst = false;
2162 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2163 if (!bFirst)
2164 out << "\n" << indent() << indent() << "&& ";
2165 out << "the_lhs." << member.name << " == the_rhs." << member.name;
2166 bFirst = false;
2168 out << ";\n";
2169 dec();
2170 out << "}\n";
2171 // print the operator!=
2172 out << "\ninline bool operator!=(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
2173 out << "{\n";
2174 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
2175 out << "}\n";
2176 // close namespace
2177 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2178 out << "\n";
2180 out << "\n";
2181 dumpGetCppuType(out);
2182 out << "\n#endif // "<< headerDefine << "\n";
2185 void PlainStructType::dumpLightGetCppuType(FileStream & out)
2187 dumpGetCppuTypePreamble(out);
2188 out << indent()
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")
2192 << indent()
2193 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2194 << indent() << "if (the_type == 0) {\n";
2195 inc();
2196 out << indent() << "::typelib_static_type_init(&the_type, "
2197 << getTypeClass(name_, true) << ", \"" << name_ << "\");\n";
2198 dec();
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);
2207 out << indent()
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")
2211 << indent()
2212 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2213 << indent() << "if (the_type == 0) {\n";
2214 inc();
2215 out << indent()
2216 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2217 inc();
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);
2223 ++i;
2224 out << " >::get().getTypeLibType()"
2225 << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2227 dec();
2228 out << indent() << "::typelib_static_struct_type_init(&the_type, \""
2229 << name_ << "\", ";
2230 if (entity_->getDirectBase().isEmpty()) {
2231 out << "0";
2232 } else {
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";
2238 dec();
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 "
2249 << staticTypeClass
2250 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2251 << staticTypeClass << " >\n" << indent() << "{\n";
2252 inc();
2253 out << indent() << "::css::uno::Type * operator()() const\n"
2254 << indent() << "{\n";
2255 inc();
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()) {
2260 if (types.emplace(
2261 member.type, static_cast< sal_uInt32 >(types.size())).
2262 second) {
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";
2277 inc();
2278 n = 0;
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 }";
2287 ++i;
2288 out << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2290 dec();
2291 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"
2292 << indent()
2293 << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2294 if (entity_->getDirectBase().isEmpty()) {
2295 out << "0";
2296 } else {
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";
2306 dec();
2307 out << indent() << "}\n";
2308 dec();
2309 out << indent() << "};\n";
2310 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
2311 out << " }\n\n";
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)
2320 if (base.isEmpty())
2321 return false;
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()));
2332 assert(ent2.is());
2333 if (!ent2.is()) {
2334 return false;
2336 bool hasMember = dumpBaseMembers(out, ent2->getDirectBase(), withType);
2337 for (const unoidl::PlainStructTypeEntity::Member& member : ent2->getDirectMembers()) {
2338 if (hasMember) {
2339 out << ", ";
2341 if (withType) {
2342 dumpType(out, member.type, true, true);
2343 out << " ";
2345 out << member.name << "_";
2346 hasMember = true;
2348 return hasMember;
2351 void PlainStructType::addLightGetCppuTypeIncludes(
2352 codemaker::cppumaker::Includes & includes) const
2354 includes.addType();
2355 includes.addCppuUnotypeHxx();
2356 includes.addSalTypesH();
2357 includes.addTypelibTypeclassH();
2358 includes.addTypelibTypedescriptionH();
2361 void PlainStructType::addNormalGetCppuTypeIncludes(
2362 codemaker::cppumaker::Includes & includes) const
2364 includes.addType();
2365 includes.addCppuUnotypeHxx();
2366 includes.addSalTypesH();
2367 includes.addTypelibTypeclassH();
2368 includes.addTypelibTypedescriptionH();
2371 void PlainStructType::addComprehensiveGetCppuTypeIncludes(
2372 codemaker::cppumaker::Includes & includes) const
2374 includes.addType();
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()) {
2387 return 0;
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()));
2397 assert(ent2.is());
2398 if (!ent2.is()) {
2399 return 0;
2401 return getTotalMemberCount(ent2->getDirectBase())
2402 + ent2->getDirectMembers().size(); //TODO: overflow
2405 class PolyStructType: public CppuType
2407 public:
2408 PolyStructType(
2409 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const &
2410 entity,
2411 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2412 CppuType(name, typeMgr), entity_(entity) {
2413 assert(entity.is());
2416 private:
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 {
2437 return true;
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";
2452 inc();
2453 out << indent() << "inline " << id_ << "();\n";
2454 if (!entity_->getMembers().empty()) {
2455 out << "\n" << indent() << "inline " << id_ << "(";
2456 for (std::vector<
2457 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2458 const_iterator i(entity_->getMembers().begin());
2459 i != entity_->getMembers().end(); ++i) {
2460 if (i != entity_->getMembers().begin()) {
2461 out << ", ";
2463 if (i->parameterized) {
2464 dumpTypeParameterName(out, i->type);
2465 out << " const &";
2466 } else {
2467 dumpType(out, i->type, true, true);
2469 out << " " << i->name << "_";
2471 out << ");\n\n";
2472 // print the member fields
2473 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member :
2474 entity_->getMembers()) {
2475 out << indent();
2476 if (member.parameterized) {
2477 dumpTypeParameterName(out, member.type);
2478 } else {
2479 dumpType(out, member.type);
2481 out << " " << member.name << ";\n";
2484 dec();
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"));
2492 out << "\n";
2493 includes.dump(out, &name_, true);
2494 out << "\n";
2495 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2496 out << "\n";
2498 out << "\n";
2499 // dump default (no-arg) constructor
2500 dumpTemplateHead(out);
2501 out << "inline " << id_;
2502 dumpTemplateParameters(out);
2503 out << "::" << id_ << "()\n";
2504 inc();
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() ? ":" : ",")
2509 << " " << i->name;
2510 dumpInitializer(out, i->parameterized, i->type);
2511 out << "\n";
2513 dec();
2514 out << "{\n}\n\n";
2515 if (!entity_->getMembers().empty()) {
2516 // dump takes-all-fields constructor
2517 dumpTemplateHead(out);
2518 out << "inline " << id_;
2519 dumpTemplateParameters(out);
2520 out << "::" << id_ << "(";
2521 for (std::vector<
2522 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2523 const_iterator i(entity_->getMembers().begin());
2524 i != entity_->getMembers().end(); ++i) {
2525 if (i != entity_->getMembers().begin()) {
2526 out << ", ";
2528 if (i->parameterized) {
2529 dumpTypeParameterName(out, i->type);
2530 out << " const &";
2531 } else {
2532 dumpType(out, i->type, true, true);
2534 out << " " << i->name << "_";
2536 out << ")\n";
2537 inc();
2538 for (std::vector<
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";
2545 dec();
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_ << "(";
2552 for (std::vector<
2553 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2554 const_iterator i(entity_->getMembers().begin());
2555 i != entity_->getMembers().end(); ++i) {
2556 if (i != entity_->getMembers().begin()) {
2557 out << ", ";
2559 if (i->parameterized) {
2560 dumpTypeParameterName(out, i->type);
2561 out << " const &";
2562 } else {
2563 dumpType(out, i->type, true, true);
2565 out << " " << i->name << "_";
2567 out << ")\n" << indent() << "{\n";
2568 inc();
2569 out << indent() << "return " << id_;
2570 dumpTemplateParameters(out);
2571 out << "(";
2572 for (std::vector<
2573 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2574 const_iterator i(entity_->getMembers().begin());
2575 i != entity_->getMembers().end(); ++i) {
2576 if (i != entity_->getMembers().begin()) {
2577 out << ", ";
2579 out << i->name << "_";
2581 out << ");\n";
2582 dec();
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";
2592 out << "{\n";
2593 inc();
2594 out << indent() << "return ";
2595 bool bFirst = true;
2596 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2597 if (!bFirst)
2598 out << "\n" << indent() << indent() << "&& ";
2599 out << "the_lhs." << member.name << " == the_rhs." << member.name;
2600 bFirst = false;
2602 out << ";\n";
2603 dec();
2604 out << "}\n";
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";
2612 out << "{\n";
2613 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
2614 out << "}\n";
2615 // close namespace
2616 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2617 out << "\n";
2619 out << "\n";
2620 dumpGetCppuType(out);
2621 out << "\n#endif // "<< headerDefine << "\n";
2624 void PolyStructType::dumpLightGetCppuType(FileStream & out)
2626 dumpGetCppuTypePreamble(out);
2627 out << indent()
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")
2631 << indent()
2632 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2633 << indent() << "if (the_type == 0) {\n";
2634 inc();
2636 out << "#ifdef LIBO_INTERNAL_ONLY\n";
2638 out << indent() << "::rtl::OString the_buffer = \"" << name_
2639 << "<\" +\n";
2640 for (std::vector< OUString >::const_iterator i(
2641 entity_->getTypeParameters().begin());
2642 i != entity_->getTypeParameters().end();) {
2643 out << indent()
2644 << ("::rtl::OUStringToOString("
2645 "::cppu::getTypeFavourChar(static_cast< ");
2646 dumpTypeParameterName(out, *i);
2647 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8) +\n";
2648 ++i;
2649 if (i != entity_->getTypeParameters().end()) {
2650 out << indent() << "\",\" +\n";
2653 out << indent() << "\">\";\n";
2655 out << "#else\n";
2657 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2658 << "<\");\n";
2659 for (std::vector< OUString >::const_iterator i(
2660 entity_->getTypeParameters().begin());
2661 i != entity_->getTypeParameters().end();) {
2662 out << indent()
2663 << ("the_buffer.append(::rtl::OUStringToOString("
2664 "::cppu::getTypeFavourChar(static_cast< ");
2665 dumpTypeParameterName(out, *i);
2666 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2667 ++i;
2668 if (i != entity_->getTypeParameters().end()) {
2669 out << indent() << "the_buffer.append(',');\n";
2672 out << indent() << "the_buffer.append('>');\n";
2674 out << "#endif\n";
2676 out << indent()
2677 << "::typelib_static_type_init(&the_type, " << getTypeClass(name_, true)
2678 << ", the_buffer.getStr());\n";
2680 dec();
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);
2689 out << indent()
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")
2693 << indent()
2694 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2695 << indent() << "if (the_type == 0) {\n";
2696 inc();
2697 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2698 << "<\");\n";
2699 for (std::vector< OUString >::const_iterator i(
2700 entity_->getTypeParameters().begin());
2701 i != entity_->getTypeParameters().end();) {
2702 out << indent()
2703 << ("the_buffer.append(::rtl::OUStringToOString("
2704 "::cppu::getTypeFavourChar(static_cast< ");
2705 dumpTypeParameterName(out, *i);
2706 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2707 ++i;
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";
2714 inc();
2715 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2716 const_iterator i(entity_->getMembers().begin());
2717 i != entity_->getMembers().end();) {
2718 out << indent();
2719 if (i->parameterized) {
2720 out << "::cppu::getTypeFavourChar(static_cast< ";
2721 dumpTypeParameterName(out, i->type);
2722 out << " * >(0))";
2723 } else {
2724 out << "::cppu::UnoType< ";
2725 dumpType(out, i->type, false, false, false, true);
2726 out << " >::get()";
2728 ++i;
2729 out << ".getTypeLibType()"
2730 << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2732 dec();
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()) {
2738 out << ", ";
2740 out << (i->parameterized ? "true" : "false");
2742 out << " };\n" << indent()
2743 << ("::typelib_static_struct_type_init(&the_type, the_buffer.getStr(),"
2744 " 0, ")
2745 << entity_->getMembers().size()
2746 << ", the_members, the_parameterizedTypes);\n";
2747 dec();
2748 out << indent() << "}\n" << indent()
2749 << ("return *reinterpret_cast< ::css::uno::Type * >("
2750 "&the_type);\n");
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 *, "
2761 << staticTypeClass;
2762 dumpTemplateParameters(out);
2763 out << " >\n" << indent() << "{\n";
2764 inc();
2765 out << indent() << "::css::uno::Type * operator()() const\n"
2766 << indent() << "{\n";
2767 inc();
2769 out << "#ifdef LIBO_INTERNAL_ONLY\n";
2770 out << indent()
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();) {
2776 out << indent()
2777 << "::cppu::getTypeFavourChar(static_cast< ";
2778 dumpTypeParameterName(out, *i);
2779 out << " * >(0)).getTypeName() +\n";
2780 ++i;
2781 if (i != entity_->getTypeParameters().end()) {
2782 out << indent()
2783 << "\",\" +\n";
2786 out << indent()
2787 << "\">\";\n";
2788 out << "#else\n";
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();) {
2794 out << indent()
2795 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2796 dumpTypeParameterName(out, *i);
2797 out << " * >(0)).getTypeName());\n";
2798 ++i;
2799 if (i != entity_->getTypeParameters().end()) {
2800 out << indent()
2801 << ("the_buffer.append("
2802 "static_cast< ::sal_Unicode >(','));\n");
2805 out << indent() << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n";
2806 out << indent()
2807 << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2808 out << "#endif\n";
2809 std::map< OUString, sal_uInt32 > parameters;
2810 std::map< OUString, sal_uInt32 > types;
2811 std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2812 size_type n = 0;
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())).
2817 second) {
2818 sal_uInt32 k = static_cast< sal_uInt32 >(parameters.size() - 1);
2819 out << indent()
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())).
2831 second) {
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";
2846 inc();
2847 n = 0;
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";
2857 } else {
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") << " }";
2865 ++i;
2866 out << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2868 dec();
2869 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2870 out << indent()
2871 << ("::typelib_typedescription_newStruct(&the_newType, the_name.pData,"
2872 " 0, ")
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";
2878 dec();
2879 out << indent() << "}\n";
2880 dec();
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
2892 includes.addType();
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
2905 includes.addType();
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
2918 includes.addType();
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()) {
2937 out << ", ";
2939 out << "typename ";
2940 dumpTypeParameterName(out, *i);
2942 out << " > ";
2945 void PolyStructType::dumpTemplateParameters(FileStream & out) const
2947 out << "< ";
2948 for (std::vector< OUString >::const_iterator i(
2949 entity_->getTypeParameters().begin());
2950 i != entity_->getTypeParameters().end(); ++i) {
2951 if (i != entity_->getTypeParameters().begin()) {
2952 out << ", ";
2954 dumpTypeParameterName(out, *i);
2956 out << " >";
2959 OUString typeToIdentifier(std::u16string_view name)
2961 sal_Int32 k;
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) {
2965 b.append("seq_");
2967 b.append(n);
2968 b.replace(' ', '_');
2969 b.replace(',', '_');
2970 b.replace('.', '_');
2971 b.replace('<', '_');
2972 b.replace('>', '_');
2973 return b.makeStringAndClear();
2976 class ExceptionType: public CppuType
2978 public:
2979 ExceptionType(
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());
2986 private:
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"));
3052 out << "\n";
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";
3062 out << "#endif\n";
3065 out << "\n";
3067 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
3068 out << "\n";
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";
3075 out << "#endif\n";
3076 out << " )\n";
3077 inc();
3078 OUString base(entity_->getDirectBase());
3079 bool bFirst = true;
3080 if (!base.isEmpty()) {
3081 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
3082 << "(\n";
3083 out << "#if defined LIBO_USE_SOURCE_LOCATION\n";
3084 out << " location\n";
3085 out << "#endif\n";
3086 out << ")\n";
3087 bFirst = false;
3089 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3090 out << indent() << (bFirst ? ":" : ",") << " ";
3091 out << member.name;
3092 dumpInitializer(out, false, member.type);
3093 out << "\n";
3094 bFirst = false;
3096 dec();
3097 out << "{";
3098 if (!m_cppuTypeDynamic) {
3099 out << "\n";
3100 inc();
3101 dumpCppuGetType(out, name_);
3102 dec();
3103 } else {
3104 out << " ";
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";
3112 out << "#endif\n";
3114 out << "}\n\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()) {
3121 if (!bFirst) {
3122 out << ", ";
3124 dumpType(out, member.type, true, true);
3125 out << " " << member.name << "_";
3126 bFirst = false;
3128 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3129 out << " " << (bFirst ? "" : ", ") << "LIBO_USE_SOURCE_LOCATION::source_location location\n";
3130 out << "#endif\n";
3131 out << ")\n";
3132 inc();
3133 bFirst = true;
3134 if (!base.isEmpty()) {
3135 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
3136 << "(";
3137 dumpBaseMembers(out, base, false, false);
3138 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3139 out << " , location\n";
3140 out << "#endif\n";
3141 out << ")\n";
3142 bFirst = false;
3144 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3145 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
3146 << member.name << "_)\n";
3147 bFirst = false;
3149 dec();
3150 out << "{";
3151 if (!m_cppuTypeDynamic) {
3152 out << "\n";
3153 inc();
3154 dumpCppuGetType(out, name_);
3155 dec();
3156 } else {
3157 out << " ";
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";
3165 out << "#endif\n";
3167 out << "}\n\n";
3169 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent() << id_ << "::" << id_
3170 << "(" << id_ << " const & the_other)";
3171 bFirst = true;
3172 if (!base.isEmpty()) {
3173 out << ": " << codemaker::cpp::scopedCppName(u2b(base))
3174 << "(the_other)";
3175 bFirst = false;
3177 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3178 out << (bFirst ? ":" : ",") << " " << member.name << "(the_other." << member.name
3179 << ")";
3180 bFirst = false;
3182 out << indent() << " {}\n\n" << indent() << id_ << "::~" << id_
3183 << "() {}\n\n" << indent() << id_ << " & " << id_ << "::operator =("
3184 << id_ << " const & the_other) {\n";
3185 inc();
3186 out << indent()
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";
3197 dec();
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";
3207 out << "{\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";
3213 out << "}\n";
3214 out << "#endif\n";
3215 out << "\n";
3218 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
3219 out << "\n";
3221 out << "\n";
3223 dumpGetCppuType(out);
3224 out << "\n#endif // "<< headerDefine << "\n";
3227 void ExceptionType::dumpLightGetCppuType(FileStream & out)
3229 dumpGetCppuTypePreamble(out);
3230 out << indent()
3231 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3232 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3233 inc();
3234 out << indent() << "typelib_static_type_init( &the_type, "
3235 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
3236 dec();
3237 out << indent() << "}\n" << indent()
3238 << ("return * reinterpret_cast< ::css::uno::Type * >("
3239 " &the_type );\n");
3240 dumpGetCppuTypePostamble(out);
3243 void ExceptionType::dumpNormalGetCppuType(FileStream & out)
3245 dumpGetCppuTypePreamble(out);
3246 out << indent()
3247 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3248 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3249 inc();
3250 OUString base(entity_->getDirectBase());
3251 bool baseException = false;
3252 if (!base.isEmpty()) {
3253 if (base == "com.sun.star.uno.Exception") {
3254 baseException = true;
3255 } else {
3256 out << indent()
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) {
3272 out << indent()
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";
3281 out << "\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()) {
3289 out << "0";
3290 } else {
3291 out << "rBaseType.getTypeLibType()";
3293 out << ", " << entity_->getDirectMembers().size() << ", "
3294 << (entity_->getDirectMembers().empty() ? "0" : "aMemberRefs")
3295 << " );\n";
3296 dec();
3297 out << indent() << "}\n" << indent()
3298 << ("return * reinterpret_cast< const ::css::uno::Type * >("
3299 " &the_type );\n");
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";
3311 inc();
3312 out << indent() << "::css::uno::Type * operator()() const\n"
3313 << indent() << "{\n";
3314 inc();
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()) {
3320 out << indent()
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
3346 << ".pData;\n";
3347 ++n;
3350 out << "\n" << indent() << "typelib_typedescription_new(\n";
3351 inc();
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")
3357 << " );\n\n";
3358 dec();
3359 out << indent()
3360 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3361 " );\n\n")
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";
3366 dec();
3367 out << indent() << "}\n";
3368 dec();
3369 out << indent() << "};\n\n";
3370 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
3371 out << " }\n\n";
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";
3385 inc();
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";
3392 out << " );\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()) {
3400 if (!bFirst) {
3401 out << ", ";
3403 dumpType(out, member.type, true, true);
3404 out << " " << member.name << "_";
3405 bFirst = false;
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";
3409 out << "#endif\n";
3410 out << " );\n\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) {
3420 out << indent();
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)) << " )";
3429 out << ";\n";
3431 dec();
3432 out << "};\n\n";
3435 bool ExceptionType::dumpBaseMembers(
3436 FileStream & out, OUString const & base, bool withType, bool eligibleForDefaults)
3438 if (base.isEmpty())
3439 return false;
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()));
3450 assert(ent2.is());
3451 if (!ent2.is()) {
3452 return false;
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()) {
3458 if (hasMember) {
3459 out << ", ";
3461 if (withType) {
3462 dumpType(out, member.type, true, true);
3463 out << " ";
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
3468 // throw sites.
3469 if (eligibleForDefaults
3470 && base == "com.sun.star.uno.Exception"
3471 && memberCount == 1
3472 && member.name == "Context"
3473 && member.type == "com.sun.star.uno.XInterface") {
3474 out << " = ::css::uno::Reference< ::css::uno::XInterface >()";
3476 hasMember = true;
3477 ++memberCount;
3479 return hasMember;
3482 sal_uInt32 ExceptionType::getTotalMemberCount(OUString const & base) const
3484 if (base.isEmpty()) {
3485 return 0;
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
3500 public:
3501 EnumType(
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());
3508 private:
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";
3533 o << "\n#else\n";
3534 o << "\nenum SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3535 o << "\n#endif\n";
3536 inc();
3538 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3539 o << indent() << id_ << "_" << u2b(member.name) << " = " << member.value
3540 << ",\n";
3543 o << indent() << id_ << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3545 dec();
3546 o << "};\n\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)
3552 << " = "
3553 << id_ << "::" << id_ << "_" << u2b(member.name)
3554 << ";\n";
3556 o << "#endif\n";
3559 void EnumType::dumpHppFile(
3560 FileStream& o, codemaker::cppumaker::Includes & includes)
3562 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3563 o << "\n";
3565 addDefaultHxxIncludes(includes);
3566 includes.dump(o, &name_, true);
3567 o << "\n";
3569 dumpGetCppuType(o);
3571 o << "\n#endif // "<< headerDefine << "\n";
3574 void EnumType::dumpNormalGetCppuType(FileStream& o)
3576 dumpGetCppuTypePreamble(o);
3578 o << indent()
3579 << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3581 o << indent() << "if ( !the_type )\n" << indent() << "{\n";
3582 inc();
3584 o << indent() << "typelib_static_enum_type_init( &the_type,\n";
3585 inc(31);
3586 o << indent() << "\"" << name_ << "\",\n"
3587 << indent() << codemaker::cpp::scopedCppName(u2b(name_)) << "_"
3588 << u2b(entity_->getMembers()[0].name) << " );\n";
3589 dec(31);
3590 dec();
3591 o << indent() << "}\n";
3592 o << indent()
3593 << ("return * reinterpret_cast< ::css::uno::Type * >("
3594 " &the_type );\n");
3595 dumpGetCppuTypePostamble(o);
3598 void EnumType::dumpComprehensiveGetCppuType(FileStream& o)
3600 if (!isPolymorphic())
3601 codemaker::cppumaker::dumpNamespaceOpen(o, name_, false);
3602 else
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";
3609 inc();
3610 o << indent() << "::css::uno::Type * operator()() const\n";
3611 o << indent() << "{\n";
3613 inc();
3614 o << indent() << "::rtl::OUString sTypeName( \"" << name_
3615 << "\" );\n\n";
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
3627 << ".pData;\n";
3628 ++n;
3631 o << "\n" << indent() << "sal_Int32 enumValues["
3632 << entity_->getMembers().size() << "];\n";
3633 n = 0;
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";
3639 inc();
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";
3646 dec();
3648 o << indent()
3649 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3650 " );\n");
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";
3657 dec();
3658 o << indent() << "}\n";
3659 dec();
3660 o << indent() << "};\n\n";
3662 if (!isPolymorphic())
3663 codemaker::cppumaker::dumpNamespaceClose(o, name_, false);
3664 else
3665 o << " }";
3666 o << " }\n\n";
3668 dumpGetCppuTypePreamble(o);
3669 o << indent() << "return *detail::" << sStaticTypeClass << "::get();\n";
3670 dumpGetCppuTypePostamble(o);
3673 class Typedef: public CppuType
3675 public:
3676 Typedef(
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());
3683 private:
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"));
3697 o << "\n";
3699 addDefaultHIncludes(includes);
3700 includes.dump(o, nullptr, true);
3701 o << "\n";
3703 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3704 o << "\n";
3707 dumpDeclaration(o);
3709 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3710 o << "\n";
3713 o << "#endif // "<< headerDefine << "\n";
3716 void Typedef::dumpDeclaration(FileStream& o)
3718 o << "\ntypedef ";
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"));
3727 o << "\n";
3729 addDefaultHxxIncludes(includes);
3730 includes.dump(o, &name_, true);
3731 o << "\n";
3733 o << "\n#endif // "<< headerDefine << "\n";
3736 class ConstructiveType: public CppuType
3738 public:
3739 ConstructiveType(
3740 OUString const & name, rtl::Reference< TypeManager > const & manager):
3741 CppuType(name, manager) {}
3743 private:
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);
3768 } else {
3769 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3770 includeExceptions(includes, pChild.get());
3775 class ServiceType: public ConstructiveType
3777 public:
3778 ServiceType(
3779 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const &
3780 entity,
3781 OUString const & name, rtl::Reference< TypeManager > const & manager):
3782 ConstructiveType(name, manager), entity_(entity) {
3783 assert(entity.is());
3786 private:
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_;
3796 void failsToSupply(
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);
3820 } else {
3821 if (!hasRestParameter(cons)) {
3822 includes.addAny();
3823 includes.addSequence();
3824 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3825 cons.parameters) {
3826 if (m_typeMgr->getSort(
3827 b2u(codemaker::UnoType::decompose(
3828 u2b(param.type))))
3829 == codemaker::UnoType::Sort::Char) {
3830 includes.addCppuUnotypeHxx();
3831 break;
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());
3847 OString cppName(
3848 codemaker::cpp::translateUnoToCppIdentifier(
3849 u2b(id_), "service", isGlobal()));
3850 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3851 o << "\n";
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";
3867 o << "\n";
3868 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3869 o << "\n";
3871 o << "\nclass " << cppName << " {\n";
3872 inc();
3873 if (!entity_->getConstructors().empty()) {
3874 OString baseName(u2b(entity_->getBase()));
3875 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3876 o << "public:\n";
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,
3884 &cppName)
3885 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3886 " the_context) {\n");
3887 inc();
3888 o << indent() << "assert(the_context.is());\n" << indent()
3889 << "::css::uno::Reference< " << scopedBaseName
3890 << " > the_instance;\n" << indent() << "try {\n";
3891 inc();
3892 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3893 "LO_URE_CTOR_ENV_")
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 * >((*"
3902 "LO_URE_CTOR_FUN_")
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< "
3908 << scopedBaseName
3909 << (" >(the_context->getServiceManager()->"
3910 "createInstanceWithContext("
3911 " \"")
3912 << name_
3913 << "\", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3914 dec();
3915 o << indent()
3916 << "} catch (const ::css::uno::RuntimeException &) {\n";
3917 inc();
3918 o << indent() << "throw;\n";
3919 dec();
3920 o << indent()
3921 << "} catch (const ::css::uno::Exception & the_exception) {\n";
3922 inc();
3923 o << indent() << "throw ::css::uno::DeploymentException(";
3924 failsToSupply(o, name_, baseName);
3925 o << " + \": \" + the_exception.Message, the_context);\n";
3926 dec();
3927 o << indent() << "}\n" << indent()
3928 << "if (!the_instance.is()) {\n";
3929 inc();
3930 o << indent() << "throw ::css::uno::DeploymentException(";
3931 failsToSupply(o, name_, baseName);
3932 o << ", the_context);\n";
3933 dec();
3934 o << indent() << "}\n" << indent() << "return the_instance;\n";
3935 dec();
3936 o << indent() << "}\n\n";
3937 } else {
3938 o << indent() << "static ::css::uno::Reference< "
3939 << scopedBaseName << " > "
3940 << codemaker::cpp::translateUnoToCppIdentifier(
3941 u2b(cons.name), "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal,
3942 &cppName)
3943 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3944 " the_context");
3945 bool rest = hasRestParameter(cons);
3946 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3947 cons.parameters) {
3948 o << ", ";
3949 OUStringBuffer buf(2 + param.type.getLength());
3950 if (param.rest) {
3951 buf.append("[]");
3953 buf.append(param.type);
3954 OUString type(buf.makeStringAndClear());
3955 bool byRef = passByReference(type);
3956 dumpType(o, type, byRef, byRef);
3957 o << " "
3958 << codemaker::cpp::translateUnoToCppIdentifier(
3959 u2b(param.name), "param", codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3961 o << ") {\n";
3962 inc();
3963 o << indent() << "assert(the_context.is());\n";
3964 if (!rest && !cons.parameters.empty()) {
3965 o << indent()
3966 << "::css::uno::Sequence< ::css::uno::Any > the_arguments("
3967 << cons.parameters.size() << ");\n";
3968 o << indent()
3969 << "::css::uno::Any* the_arguments_array = the_arguments.getArray();\n";
3971 std::vector<
3972 unoidl::SingleInterfaceBasedServiceEntity::Constructor::
3973 Parameter >::size_type n = 0;
3974 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& j :
3975 cons.parameters) {
3976 o << indent() << "the_arguments_array[" << n++ << "] ";
3977 OString param(
3978 codemaker::cpp::translateUnoToCppIdentifier(
3979 u2b(j.name), "param",
3980 codemaker::cpp::IdentifierTranslationMode::NonGlobal));
3981 sal_Int32 rank;
3982 if (resolveOuterTypedefs(j.type) == "any") {
3983 o << "= " << param;
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) {
3995 o << " >";
3997 o << " >::get())";
3998 } else {
3999 o << "<<= " << param;
4001 o << ";\n";
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";
4012 inc();
4014 o << ("#if defined LO_URE_CURRENT_ENV && defined "
4015 "LO_URE_CTOR_ENV_")
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 * >((*"
4024 "LO_URE_CTOR_FUN_")
4025 << name_.replaceAll(".", "_dot_")
4026 << ")(the_context.get(), ";
4027 if (rest) {
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 >()";
4033 } else {
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 >()";
4043 } else {
4044 o << "the_arguments";
4046 o << ");\n" << indent() << "}\n";
4047 o << "#else\n"
4048 << indent() << "the_instance = ::css::uno::Reference< "
4049 << scopedBaseName
4050 << (" >(the_context->getServiceManager()->"
4051 "createInstanceWithArgumentsAndContext("
4052 " \"")
4053 << name_ << "\", ";
4054 if (rest) {
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 >()";
4060 } else {
4061 o << "the_arguments";
4063 o << ", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
4064 if (!tree.getRoot().present) {
4065 dec();
4066 o << indent()
4067 << "} catch (const ::css::uno::RuntimeException &) {\n";
4068 inc();
4069 o << indent() << "throw;\n";
4070 dec();
4071 dumpCatchClauses(o, &tree.getRoot());
4072 o << indent()
4073 << ("} catch (const ::css::uno::Exception &"
4074 " the_exception) {\n");
4075 inc();
4076 o << indent() << "throw ::css::uno::DeploymentException(";
4077 failsToSupply(o, name_, baseName);
4078 o << " + \": \" + the_exception.Message, the_context);\n";
4079 dec();
4080 o << indent() << "}\n";
4082 o << indent() << "if (!the_instance.is()) {\n";
4083 inc();
4084 o << indent() << "throw ::css::uno::DeploymentException(";
4085 failsToSupply(o, name_, baseName);
4086 o << ", the_context);\n";
4087 dec();
4088 o << indent() << "}\n" << indent() << "return the_instance;\n";
4089 dec();
4090 o << indent() << "}\n\n";
4094 o << "private:\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";
4099 dec();
4100 o << "};\n\n";
4101 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
4102 o << "\n";
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));
4113 out << " &) {\n";
4114 inc();
4115 out << indent() << "throw;\n";
4116 dec();
4117 } else {
4118 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
4119 dumpCatchClauses(out, pChild.get());
4124 class SingletonType: public ConstructiveType
4126 public:
4127 SingletonType(
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());
4134 private:
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)
4144 OString cppName(
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"));
4150 o << "\n";
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();
4156 includes.addAny();
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";
4173 o << "\n";
4174 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
4175 o << "\n";
4177 o << "\nclass " << cppName << " {\npublic:\n";
4178 inc();
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)"
4185 " {\n");
4186 inc();
4187 o << indent() << "assert(the_context.is());\n" << indent()
4188 << "::css::uno::Reference< " << scopedBaseName
4189 << (" > instance;\n#if defined LO_URE_CURRENT_ENV && defined "
4190 "LO_URE_CTOR_ENV_")
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 * >((*"
4199 "LO_URE_CTOR_FUN_")
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";
4208 inc();
4209 o << indent()
4210 << ("throw ::css::uno::DeploymentException("
4211 "::rtl::OUString( \"component context"
4212 " fails to supply singleton ")
4213 << name_ << " of type " << baseName << "\" ), the_context);\n";
4214 dec();
4215 o << indent() << "}\n" << indent() << "return instance;\n";
4216 dec();
4217 o << indent() << "}\n\n";
4218 o << "private:\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";
4223 dec();
4224 o << "};\n\n";
4225 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
4226 o << "\n";
4228 o << "\n#endif // "<< headerDefine << "\n";
4233 void produce(
4234 OUString const & name, rtl::Reference< TypeManager > const & manager,
4235 codemaker::GeneratedTypeSet & generated, CppuOptions const & options)
4237 if (generated.contains(u2b(name))) {
4238 return;
4240 generated.add(u2b(name));
4241 if (!manager->foundAtPrimaryProvider(name)) {
4242 return;
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: {
4248 OUString prefix;
4249 if (!name.isEmpty()) {
4250 prefix = name + ".";
4252 for (;;) {
4253 OUString mem;
4254 if (!cur->getNext(&mem).is()) {
4255 break;
4257 produce(prefix + mem, manager, generated, options);
4259 break;
4261 case codemaker::UnoType::Sort::Enum: {
4262 EnumType t(
4263 dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), name,
4264 manager);
4265 t.dump(options);
4266 t.dumpDependedTypes(generated, options);
4267 break;
4269 case codemaker::UnoType::Sort::PlainStruct: {
4270 PlainStructType t(
4271 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
4272 name, manager);
4273 t.dump(options);
4274 t.dumpDependedTypes(generated, options);
4275 break;
4277 case codemaker::UnoType::Sort::PolymorphicStructTemplate: {
4278 PolyStructType t(
4279 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
4280 ent.get()),
4281 name, manager);
4282 t.dump(options);
4283 t.dumpDependedTypes(generated, options);
4284 break;
4286 case codemaker::UnoType::Sort::Exception: {
4287 ExceptionType t(
4288 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()), name,
4289 manager);
4290 t.dump(options);
4291 t.dumpDependedTypes(generated, options);
4292 break;
4294 case codemaker::UnoType::Sort::Interface: {
4295 InterfaceType t(
4296 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()), name,
4297 manager);
4298 t.dump(options);
4299 t.dumpDependedTypes(generated, options);
4300 break;
4302 case codemaker::UnoType::Sort::Typedef: {
4303 Typedef t(
4304 dynamic_cast< unoidl::TypedefEntity * >(ent.get()), name,
4305 manager);
4306 t.dump(options);
4307 t.dumpDependedTypes(generated, options);
4308 break;
4310 case codemaker::UnoType::Sort::ConstantGroup: {
4311 ConstantGroup t(
4312 dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()), name,
4313 manager);
4314 if (t.hasConstants()) {
4315 t.dump(options);
4317 break;
4319 case codemaker::UnoType::Sort::SingleInterfaceBasedService: {
4320 ServiceType t(
4321 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
4322 ent.get()),
4323 name, manager);
4324 t.dump(options);
4325 t.dumpDependedTypes(generated, options);
4326 break;
4328 case codemaker::UnoType::Sort::InterfaceBasedSingleton: {
4329 SingletonType t(
4330 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
4331 ent.get()),
4332 name, manager);
4333 t.dump(options);
4334 t.dumpDependedTypes(generated, options);
4335 break;
4337 case codemaker::UnoType::Sort::AccumulationBasedService:
4338 case codemaker::UnoType::Sort::ServiceBasedSingleton:
4339 break;
4340 default:
4341 throw CannotDumpException(
4342 "unexpected entity \"" + name + "\" in call to produce");
4346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */