Bump version to 6.0-36
[LibreOffice.git] / codemaker / source / cppumaker / cpputype.cxx
blob36014c13460b8b0ad6e87c0229775ed0f21a8e0a
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>
22 #include <algorithm>
23 #include <cassert>
24 #include <cstdlib>
25 #include <map>
26 #include <set>
27 #include <memory>
28 #include <vector>
29 #include <iostream>
31 #include <rtl/alloc.h>
32 #include <rtl/ref.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/ustring.hxx>
35 #include <rtl/strbuf.hxx>
36 #include <unoidl/unoidl.hxx>
38 #include <codemaker/commoncpp.hxx>
39 #include <codemaker/exceptiontree.hxx>
40 #include <codemaker/generatedtypeset.hxx>
41 #include <codemaker/typemanager.hxx>
42 #include <codemaker/unotype.hxx>
44 #include "cpputype.hxx"
45 #include "cppuoptions.hxx"
46 #include "dependencies.hxx"
47 #include "dumputils.hxx"
48 #include "includes.hxx"
50 namespace
53 bool isBootstrapType(OUString const & name)
55 static char const * const names[] = {
56 "com.sun.star.beans.Property",
57 "com.sun.star.beans.PropertyAttribute",
58 "com.sun.star.beans.PropertyChangeEvent",
59 "com.sun.star.beans.PropertyState",
60 "com.sun.star.beans.PropertyValue",
61 "com.sun.star.beans.XFastPropertySet",
62 "com.sun.star.beans.XMultiPropertySet",
63 "com.sun.star.beans.XPropertiesChangeListener",
64 "com.sun.star.beans.XPropertyAccess",
65 "com.sun.star.beans.XPropertyChangeListener",
66 "com.sun.star.beans.XPropertySet",
67 "com.sun.star.beans.XPropertySetInfo",
68 "com.sun.star.beans.XPropertySetOption",
69 "com.sun.star.beans.XVetoableChangeListener",
70 "com.sun.star.bridge.UnoUrlResolver",
71 "com.sun.star.bridge.XUnoUrlResolver",
72 "com.sun.star.connection.SocketPermission",
73 "com.sun.star.container.XElementAccess",
74 "com.sun.star.container.XEnumeration",
75 "com.sun.star.container.XEnumerationAccess",
76 "com.sun.star.container.XHierarchicalNameAccess",
77 "com.sun.star.container.XNameAccess",
78 "com.sun.star.container.XNameContainer",
79 "com.sun.star.container.XNameReplace",
80 "com.sun.star.container.XSet",
81 "com.sun.star.io.FilePermission",
82 "com.sun.star.io.IOException",
83 "com.sun.star.lang.DisposedException",
84 "com.sun.star.lang.EventObject",
85 "com.sun.star.lang.WrappedTargetRuntimeException",
86 "com.sun.star.lang.XComponent",
87 "com.sun.star.lang.XEventListener",
88 "com.sun.star.lang.XInitialization",
89 "com.sun.star.lang.XMultiComponentFactory",
90 "com.sun.star.lang.XMultiServiceFactory",
91 "com.sun.star.lang.XServiceInfo",
92 "com.sun.star.lang.XSingleComponentFactory",
93 "com.sun.star.lang.XSingleServiceFactory",
94 "com.sun.star.lang.XTypeProvider",
95 "com.sun.star.loader.XImplementationLoader",
96 "com.sun.star.reflection.FieldAccessMode",
97 "com.sun.star.reflection.MethodMode",
98 "com.sun.star.reflection.ParamInfo",
99 "com.sun.star.reflection.ParamMode",
100 "com.sun.star.reflection.TypeDescriptionSearchDepth",
101 "com.sun.star.reflection.XCompoundTypeDescription",
102 "com.sun.star.reflection.XEnumTypeDescription",
103 "com.sun.star.reflection.XIdlArray",
104 "com.sun.star.reflection.XIdlClass",
105 "com.sun.star.reflection.XIdlField",
106 "com.sun.star.reflection.XIdlField2",
107 "com.sun.star.reflection.XIdlMethod",
108 "com.sun.star.reflection.XIdlReflection",
109 "com.sun.star.reflection.XIndirectTypeDescription",
110 "com.sun.star.reflection.XInterfaceAttributeTypeDescription",
111 "com.sun.star.reflection.XInterfaceAttributeTypeDescription2",
112 "com.sun.star.reflection.XInterfaceMemberTypeDescription",
113 "com.sun.star.reflection.XInterfaceMethodTypeDescription",
114 "com.sun.star.reflection.XInterfaceTypeDescription",
115 "com.sun.star.reflection.XInterfaceTypeDescription2",
116 "com.sun.star.reflection.XMethodParameter",
117 "com.sun.star.reflection.XStructTypeDescription",
118 "com.sun.star.reflection.XTypeDescription",
119 "com.sun.star.reflection.XTypeDescriptionEnumeration",
120 "com.sun.star.reflection.XTypeDescriptionEnumerationAccess",
121 "com.sun.star.registry.RegistryKeyType",
122 "com.sun.star.registry.RegistryValueType",
123 "com.sun.star.registry.XImplementationRegistration",
124 "com.sun.star.registry.XRegistryKey",
125 "com.sun.star.registry.XSimpleRegistry",
126 "com.sun.star.security.RuntimePermission",
127 "com.sun.star.security.XAccessControlContext",
128 "com.sun.star.security.XAccessController",
129 "com.sun.star.security.XAction",
130 "com.sun.star.uno.DeploymentException",
131 "com.sun.star.uno.RuntimeException",
132 "com.sun.star.uno.TypeClass",
133 "com.sun.star.uno.Uik",
134 "com.sun.star.uno.XAdapter",
135 "com.sun.star.uno.XAggregation",
136 "com.sun.star.uno.XComponentContext",
137 "com.sun.star.uno.XCurrentContext",
138 "com.sun.star.uno.XInterface",
139 "com.sun.star.uno.XReference",
140 "com.sun.star.uno.XUnloadingPreference",
141 "com.sun.star.uno.XWeak",
142 "com.sun.star.util.XMacroExpander" };
143 // cf. cppuhelper/unotypes/Makefile UNOTYPES (plus missing dependencies)
144 for (std::size_t i = 0; i < SAL_N_ELEMENTS(names); ++i) {
145 if (name.equalsAscii(names[i])) {
146 return true;
149 return false;
152 class CppuType
154 public:
155 CppuType(
156 OUString const & name, rtl::Reference< TypeManager > const & typeMgr);
158 virtual ~CppuType() {}
160 CppuType(const CppuType&) = delete;
161 const CppuType& operator=(const CppuType&) = delete;
163 void dump(CppuOptions const & options);
165 bool dumpFile(
166 OUString const & uri, OUString const & name, bool hpp,
167 CppuOptions const & options);
169 void dumpDependedTypes(
170 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const;
172 virtual void dumpHdlFile(
173 FileStream & out, codemaker::cppumaker::Includes & includes) {
174 dumpHFileContent(out, includes);
177 virtual void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) = 0;
179 OUString dumpHeaderDefine(FileStream& o, OUString const & extension) const;
181 void dumpGetCppuType(FileStream & out);
183 virtual void dumpLightGetCppuType(FileStream & out);
185 virtual void dumpNormalGetCppuType(FileStream &) {
186 assert(false); // this cannot happen
189 virtual void dumpComprehensiveGetCppuType(FileStream &) {
190 assert(false); // this cannot happen
193 void dumpType(
194 FileStream & out, OUString const & name, bool isConst = false,
195 bool isRef = false, bool native = false, bool cppuUnoType = false)
196 const;
198 OUString getTypeClass(OUString const & name, bool cStyle = false);
200 void dumpCppuGetType(
201 FileStream & out, OUString const & name, OUString const * ownName = nullptr) const;
203 sal_uInt32 getInheritedMemberCount();
205 void inc(sal_Int32 num=4);
206 void dec(sal_Int32 num=4);
207 OUString indent() const;
208 protected:
209 virtual sal_uInt32 checkInheritedMemberCount() const {
210 assert(false); // this cannot happen
211 return 0;
214 bool passByReference(OUString const & name) const;
216 bool canBeWarnUnused(OUString const & name) const;
217 bool canBeWarnUnused(OUString const & name, int depth) const;
219 OUString resolveOuterTypedefs(OUString const & name) const;
221 OUString resolveAllTypedefs(OUString const & name) const;
223 codemaker::cpp::IdentifierTranslationMode isGlobal() const;
225 virtual void dumpDeclaration(FileStream &) {
226 assert(false); // this cannot happen
229 virtual void dumpFiles(OUString const & uri, CppuOptions const & options);
231 virtual void addLightGetCppuTypeIncludes(
232 codemaker::cppumaker::Includes & includes) const;
234 virtual void addNormalGetCppuTypeIncludes(
235 codemaker::cppumaker::Includes & includes) const;
237 virtual void addComprehensiveGetCppuTypeIncludes(
238 codemaker::cppumaker::Includes & includes) const;
240 virtual bool isPolymorphic() const;
242 virtual void dumpTemplateHead(FileStream &) const {}
244 virtual void dumpTemplateParameters(FileStream &) const {}
246 void dumpGetCppuTypePreamble(FileStream & out);
248 void dumpGetCppuTypePostamble(FileStream & out);
250 void addDefaultHIncludes(codemaker::cppumaker::Includes & includes) const;
251 void addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) const;
253 void dumpInitializer(
254 FileStream & out, bool parameterized, OUString const & name) const;
256 void dumpHFileContent(
257 FileStream & out, codemaker::cppumaker::Includes & includes);
259 protected:
260 sal_uInt32 m_inheritedMemberCount;
262 bool m_cppuTypeLeak;
263 bool m_cppuTypeDynamic;
264 sal_Int32 m_indentLength;
265 OUString name_;
266 OUString id_;
267 rtl::Reference< TypeManager > m_typeMgr;
268 codemaker::cppumaker::Dependencies m_dependencies;
270 private:
271 void addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
272 const;
275 CppuType::CppuType(
276 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
277 m_inheritedMemberCount(0)
278 , m_cppuTypeLeak(false)
279 , m_cppuTypeDynamic(true)
280 , m_indentLength(0)
281 , name_(name)
282 , id_(name_.copy(name_.lastIndexOf('.') + 1))
283 , m_typeMgr(typeMgr)
284 , m_dependencies(typeMgr, name_)
287 void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
288 const
290 if (name_ == "com.sun.star.uno.XInterface"
291 || name_ == "com.sun.star.uno.Exception") {
292 includes.addType();
293 includes.addCppuUnotypeHxx();
294 includes.addSalTypesH();
295 includes.addTypelibTypeclassH();
296 includes.addTypelibTypedescriptionH();
297 } else if (m_cppuTypeLeak) {
298 addLightGetCppuTypeIncludes(includes);
299 } else if (m_cppuTypeDynamic) {
300 addNormalGetCppuTypeIncludes(includes);
301 } else {
302 addComprehensiveGetCppuTypeIncludes(includes);
306 void CppuType::dumpFiles(OUString const & uri, CppuOptions const & options)
308 dumpFile(uri, name_, false, options);
309 dumpFile(uri, name_, true, options);
312 void CppuType::addLightGetCppuTypeIncludes(
313 codemaker::cppumaker::Includes & includes) const
315 //TODO: Determine what is really needed, instead of relying on
316 // addDefaultHxxIncludes
317 includes.addCppuUnotypeHxx();
320 void CppuType::addNormalGetCppuTypeIncludes(
321 codemaker::cppumaker::Includes & includes) const
323 //TODO: Determine what is really needed, instead of relying on
324 // addDefaultHxxIncludes
325 includes.addCppuUnotypeHxx();
328 void CppuType::addComprehensiveGetCppuTypeIncludes(
329 codemaker::cppumaker::Includes & includes) const
331 //TODO: Determine what is really needed, instead of relying on
332 // addDefaultHxxIncludes
333 includes.addCppuUnotypeHxx();
336 bool CppuType::isPolymorphic() const
338 return false;
341 void CppuType::dumpGetCppuTypePreamble(FileStream & out)
343 if (isPolymorphic()) {
344 out << "namespace cppu {\n\n";
345 dumpTemplateHead(out);
346 out << "class UnoType< ";
347 dumpType(out, name_);
348 dumpTemplateParameters(out);
349 out << " > {\npublic:\n";
350 inc();
351 out << indent()
352 << "static inline ::css::uno::Type const & get() {\n";
353 } else {
354 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
355 out << "\n\n";
357 out << ("inline ::css::uno::Type const &"
358 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
359 dumpType(out, name_, false, false, true);
360 out << " const *) {\n";
362 inc();
365 void CppuType::dumpGetCppuTypePostamble(FileStream & out)
367 dec();
368 if (isPolymorphic()) {
369 out << indent() << "}\n\nprivate:\n"
370 << indent() << "UnoType(UnoType &); // not defined\n"
371 << indent() << "~UnoType(); // not defined\n"
372 << indent()
373 << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
374 } else {
375 out << "}\n\n";
376 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
377 out << "\n\n";
380 dumpTemplateHead(out);
381 out << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
382 " getCppuType(SAL_UNUSED_PARAMETER ");
383 dumpType(out, name_);
384 dumpTemplateParameters(out);
385 out << " const *) {\n";
386 inc();
387 out << indent() << "return ::cppu::UnoType< ";
388 dumpType(out, name_);
389 dumpTemplateParameters(out);
390 out << " >::get();\n";
391 dec();
392 out << indent() << "}\n";
395 void CppuType::dump(CppuOptions const & options)
397 if (isBootstrapType(name_)) {
398 m_cppuTypeDynamic = false;
399 } else {
400 // -CS was used as an undocumented option to generate static getCppuType
401 // functions; since the introduction of cppu::UnoType this no longer is
402 // meaningful (getCppuType is just a forward to cppu::UnoType::get now),
403 // and -CS is handled the same way as -C now:
404 if (options.isValid("-L"))
405 m_cppuTypeLeak = true;
406 if (options.isValid("-C") || options.isValid("-CS"))
407 m_cppuTypeDynamic = false;
409 dumpFiles(
410 options.isValid("-O") ? b2u(options.getOption("-O")) : "", options);
413 bool CppuType::dumpFile(
414 OUString const & uri, OUString const & name, bool hpp,
415 CppuOptions const & options)
417 OUString fileUri(
418 b2u(createFileNameFromType(
419 u2b(uri), u2b(name), hpp ? ".hpp" : ".hdl")));
420 if (fileUri.isEmpty()) {
421 throw CannotDumpException("empty target URI for entity " + name);
423 bool exists = fileExists(u2b(fileUri));
424 if (exists && options.isValid("-G")) {
425 return false;
427 FileStream out;
428 out.createTempFile(getTempDir(u2b(fileUri)));
429 OUString tmpUri(b2u(out.getName()));
430 if(!out.isValid()) {
431 throw CannotDumpException("cannot open " + tmpUri + " for writing");
433 codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, hpp);
434 try {
435 if (hpp) {
436 addGetCppuTypeIncludes(includes);
437 dumpHppFile(out, includes);
438 } else {
439 dumpHdlFile(out, includes);
441 } catch (...) {
442 out.close();
443 // Remove existing type file if something goes wrong to ensure
444 // consistency:
445 if (fileExists(u2b(fileUri))) {
446 removeTypeFile(u2b(fileUri));
448 removeTypeFile(u2b(tmpUri));
449 throw;
451 out.close();
452 return makeValidTypeFile(
453 u2b(fileUri), u2b(tmpUri), exists && options.isValid("-Gc"));
456 void CppuType::dumpDependedTypes(
457 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const
459 if (!options.isValid("-nD")) {
460 codemaker::cppumaker::Dependencies::Map const & map
461 = m_dependencies.getMap();
462 for (const auto& entry : map) {
463 produce(entry.first, m_typeMgr, generated, options);
468 OUString CppuType::dumpHeaderDefine(
469 FileStream & out, OUString const & extension) const
471 OUString def(
472 "INCLUDED_" + name_.replace('.', '_').toAsciiUpperCase() + "_"
473 + extension);
474 out << "#ifndef " << def << "\n#define " << def << "\n";
475 return def;
478 void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes)
479 const
481 //TODO: Only include what is really needed
482 includes.addCppuMacrosHxx();
483 if (m_typeMgr->getSort(name_)
484 == codemaker::UnoType::Sort::Interface) {
485 includes.addReference();
489 void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes)
490 const
492 //TODO: Only include what is really needed
493 includes.addType();
494 if (m_typeMgr->getSort(name_)
495 == codemaker::UnoType::Sort::Interface) {
496 includes.addReference();
500 void CppuType::dumpInitializer(
501 FileStream & out, bool parameterized, OUString const & name) const
503 out << "(";
504 if (!parameterized) {
505 sal_Int32 k;
506 std::vector< OString > args;
507 OUString n(
508 b2u(codemaker::UnoType::decompose(
509 u2b(resolveAllTypedefs(name)), &k, &args)));
510 if (k == 0) {
511 rtl::Reference< unoidl::Entity > ent;
512 switch (m_typeMgr->getSort(n, &ent)) {
513 case codemaker::UnoType::Sort::Boolean:
514 out << "false";
515 break;
516 case codemaker::UnoType::Sort::Byte:
517 case codemaker::UnoType::Sort::Short:
518 case codemaker::UnoType::Sort::UnsignedShort:
519 case codemaker::UnoType::Sort::Long:
520 case codemaker::UnoType::Sort::UnsignedLong:
521 case codemaker::UnoType::Sort::Hyper:
522 case codemaker::UnoType::Sort::UnsignedHyper:
523 case codemaker::UnoType::Sort::Float:
524 case codemaker::UnoType::Sort::Double:
525 case codemaker::UnoType::Sort::Char:
526 out << "0";
527 break;
528 case codemaker::UnoType::Sort::Enum:
529 out << codemaker::cpp::scopedCppName(u2b(n)) << "_"
530 << (dynamic_cast< unoidl::EnumTypeEntity * >(ent.get())->
531 getMembers()[0].name);
532 break;
533 case codemaker::UnoType::Sort::String:
534 case codemaker::UnoType::Sort::Type:
535 case codemaker::UnoType::Sort::Any:
536 case codemaker::UnoType::Sort::PlainStruct:
537 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
538 case codemaker::UnoType::Sort::Interface:
539 break;
540 default:
541 throw CannotDumpException(
542 "unexpected entity \"" + name
543 + "\" in call to CppuType::dumpInitializer");
547 out << ")";
550 void CppuType::dumpHFileContent(
551 FileStream & out, codemaker::cppumaker::Includes & includes)
553 addDefaultHIncludes(includes);
554 dumpHeaderDefine(out, "HDL");
555 out << "\n";
556 includes.dump(out, nullptr, false);
557 // 'exceptions = false' would be wrong for services/singletons, but
558 // those don't dump .hdl files anyway
559 out << ("\nnamespace com { namespace sun { namespace star { namespace uno"
560 " { class Type; } } } }\n\n");
561 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
562 out << "\n";
564 dumpDeclaration(out);
565 if (!(name_ == "com.sun.star.uno.XInterface"
566 || name_ == "com.sun.star.uno.Exception"
567 || isPolymorphic())) {
568 out << "\n" << indent()
569 << ("inline ::css::uno::Type const &"
570 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
571 dumpType(out, name_, false, false, true);
572 out << " const *);\n";
574 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
575 out << "\n";
577 out << "\n";
578 dumpTemplateHead(out);
579 out << "SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL getCppuType(";
580 dumpType(out, name_, true);
581 dumpTemplateParameters(out);
582 out << " *);\n\n#endif\n";
585 void CppuType::dumpGetCppuType(FileStream & out)
587 if (name_ == "com.sun.star.uno.XInterface") {
588 out << indent()
589 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
590 " getCppuType(SAL_UNUSED_PARAMETER ");
591 dumpType(out, name_, true);
592 out << " *) {\n";
593 inc();
594 out << indent()
595 << ("return ::cppu::UnoType< ::css::uno::XInterface"
596 " >::get();\n");
597 dec();
598 out << indent() << "}\n";
599 } else if (name_ == "com.sun.star.uno.Exception") {
600 out << indent()
601 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
602 " getCppuType(SAL_UNUSED_PARAMETER ");
603 dumpType(out, name_, true);
604 out << " *) {\n";
605 inc();
606 out << indent()
607 << ("return ::cppu::UnoType< ::css::uno::Exception"
608 " >::get();\n");
609 dec();
610 out << indent() << "}\n";
611 } else if (m_cppuTypeLeak) {
612 dumpLightGetCppuType(out);
613 } else if (m_cppuTypeDynamic) {
614 dumpNormalGetCppuType(out);
615 } else {
616 dumpComprehensiveGetCppuType(out);
620 void CppuType::dumpLightGetCppuType(FileStream & out)
622 dumpGetCppuTypePreamble(out);
623 out << indent()
624 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
625 << indent() << "if ( !the_type )\n" << indent() << "{\n";
626 inc();
627 out << indent() << "typelib_static_type_init( &the_type, "
628 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
629 dec();
630 out << indent() << "}\n" << indent()
631 << ("return * reinterpret_cast< ::css::uno::Type * >("
632 " &the_type );\n");
633 dumpGetCppuTypePostamble(out);
636 codemaker::cpp::IdentifierTranslationMode CppuType::isGlobal() const
638 return name_.indexOf('.') == -1
639 ? codemaker::cpp::IdentifierTranslationMode::Global : codemaker::cpp::IdentifierTranslationMode::NonGlobal;
642 sal_uInt32 CppuType::getInheritedMemberCount()
644 if (m_inheritedMemberCount == 0) {
645 m_inheritedMemberCount = checkInheritedMemberCount();
648 return m_inheritedMemberCount;
651 OUString CppuType::getTypeClass(OUString const & name, bool cStyle)
653 rtl::Reference< unoidl::Entity > ent;
654 switch (m_typeMgr->getSort(name, &ent)) {
655 case codemaker::UnoType::Sort::Void:
656 return cStyle
657 ? OUString("typelib_TypeClass_VOID")
658 : OUString("::css::uno::TypeClass_VOID");
659 case codemaker::UnoType::Sort::Boolean:
660 return cStyle
661 ? OUString("typelib_TypeClass_BOOLEAN")
662 : OUString("::css::uno::TypeClass_BOOLEAN");
663 case codemaker::UnoType::Sort::Byte:
664 return cStyle
665 ? OUString("typelib_TypeClass_BYTE")
666 : OUString("::css::uno::TypeClass_BYTE");
667 case codemaker::UnoType::Sort::Short:
668 return cStyle
669 ? OUString("typelib_TypeClass_SHORT")
670 : OUString("::css::uno::TypeClass_SHORT");
671 case codemaker::UnoType::Sort::UnsignedShort:
672 return cStyle
673 ? OUString("typelib_TypeClass_UNSIGNED_SHORT")
674 : OUString("::css::uno::TypeClass_UNSIGNED_SHORT");
675 case codemaker::UnoType::Sort::Long:
676 return cStyle
677 ? OUString("typelib_TypeClass_LONG")
678 : OUString("::css::uno::TypeClass_LONG");
679 case codemaker::UnoType::Sort::UnsignedLong:
680 return cStyle
681 ? OUString("typelib_TypeClass_UNSIGNED_LONG")
682 : OUString("::css::uno::TypeClass_UNSIGNED_LONG");
683 case codemaker::UnoType::Sort::Hyper:
684 return cStyle
685 ? OUString("typelib_TypeClass_HYPER")
686 : OUString("::css::uno::TypeClass_HYPER");
687 case codemaker::UnoType::Sort::UnsignedHyper:
688 return cStyle
689 ? OUString("typelib_TypeClass_UNSIGNED_HYPER")
690 : OUString("::css::uno::TypeClass_UNSIGNED_HYPER");
691 case codemaker::UnoType::Sort::Float:
692 return cStyle
693 ? OUString("typelib_TypeClass_FLOAT")
694 : OUString("::css::uno::TypeClass_FLOAT");
695 case codemaker::UnoType::Sort::Double:
696 return cStyle
697 ? OUString("typelib_TypeClass_DOUBLE")
698 : OUString("::css::uno::TypeClass_DOUBLE");
699 case codemaker::UnoType::Sort::Char:
700 return cStyle
701 ? OUString("typelib_TypeClass_CHAR")
702 : OUString("::css::uno::TypeClass_CHAR");
703 case codemaker::UnoType::Sort::String:
704 return cStyle
705 ? OUString("typelib_TypeClass_STRING")
706 : OUString("::css::uno::TypeClass_STRING");
707 case codemaker::UnoType::Sort::Type:
708 return cStyle
709 ? OUString("typelib_TypeClass_TYPE")
710 : OUString("::css::uno::TypeClass_TYPE");
711 case codemaker::UnoType::Sort::Any:
712 return cStyle
713 ? OUString("typelib_TypeClass_ANY")
714 : OUString("::css::uno::TypeClass_ANY");
715 case codemaker::UnoType::Sort::Sequence:
716 return cStyle
717 ? OUString("typelib_TypeClass_SEQUENCE")
718 : OUString("::css::uno::TypeClass_SEQUENCE");
719 case codemaker::UnoType::Sort::Enum:
720 return cStyle
721 ? OUString("typelib_TypeClass_ENUM")
722 : OUString("::css::uno::TypeClass_ENUM");
723 case codemaker::UnoType::Sort::PlainStruct:
724 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
725 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
726 return cStyle
727 ? OUString("typelib_TypeClass_STRUCT")
728 : OUString("::css::uno::TypeClass_STRUCT");
729 case codemaker::UnoType::Sort::Exception:
730 return cStyle
731 ? OUString("typelib_TypeClass_EXCEPTION")
732 : OUString("::css::uno::TypeClass_EXCEPTION");
733 case codemaker::UnoType::Sort::Interface:
734 return cStyle
735 ? OUString("typelib_TypeClass_INTERFACE")
736 : OUString("::css::uno::TypeClass_INTERFACE");
737 case codemaker::UnoType::Sort::Typedef:
738 return getTypeClass(
739 dynamic_cast<unoidl::TypedefEntity&>(*ent.get()).getType(),
740 cStyle);
741 default:
742 for (;;) {
743 std::abort();
748 void CppuType::dumpType(
749 FileStream & out, OUString const & name, bool isConst, bool isRef,
750 bool native, bool cppuUnoType) const
752 sal_Int32 k;
753 std::vector< OString > args;
754 OUString n(
755 b2u(codemaker::UnoType::decompose(
756 u2b(resolveAllTypedefs(name)), &k, &args)));
757 if (isConst) {
758 out << "const ";
760 for (sal_Int32 i = 0; i != k; ++i) {
761 out << (cppuUnoType
762 ? "::cppu::UnoSequenceType" : "::css::uno::Sequence")
763 << "< ";
765 switch (m_typeMgr->getSort(n)) {
766 case codemaker::UnoType::Sort::Void:
767 out << "void";
768 break;
769 case codemaker::UnoType::Sort::Boolean:
770 out << "::sal_Bool";
771 break;
772 case codemaker::UnoType::Sort::Byte:
773 out << "::sal_Int8";
774 break;
775 case codemaker::UnoType::Sort::Short:
776 out << "::sal_Int16";
777 break;
778 case codemaker::UnoType::Sort::UnsignedShort:
779 out << (cppuUnoType ? "::cppu::UnoUnsignedShortType" : "::sal_uInt16");
780 break;
781 case codemaker::UnoType::Sort::Long:
782 out << "::sal_Int32";
783 break;
784 case codemaker::UnoType::Sort::UnsignedLong:
785 out << "::sal_uInt32";
786 break;
787 case codemaker::UnoType::Sort::Hyper:
788 out << "::sal_Int64";
789 break;
790 case codemaker::UnoType::Sort::UnsignedHyper:
791 out << "::sal_uInt64";
792 break;
793 case codemaker::UnoType::Sort::Float:
794 out << "float";
795 break;
796 case codemaker::UnoType::Sort::Double:
797 out << "double";
798 break;
799 case codemaker::UnoType::Sort::Char:
800 out << (cppuUnoType ? "::cppu::UnoCharType" : "::sal_Unicode");
801 break;
802 case codemaker::UnoType::Sort::String:
803 out << "::rtl::OUString";
804 break;
805 case codemaker::UnoType::Sort::Type:
806 out << "::css::uno::Type";
807 break;
808 case codemaker::UnoType::Sort::Any:
809 out << "::css::uno::Any";
810 break;
811 case codemaker::UnoType::Sort::Enum:
812 case codemaker::UnoType::Sort::PlainStruct:
813 case codemaker::UnoType::Sort::Exception:
814 out << codemaker::cpp::scopedCppName(u2b(n));
815 break;
816 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
817 out << codemaker::cpp::scopedCppName(u2b(n));
818 if (!args.empty()) {
819 out << "< ";
820 for (std::vector< OString >::iterator i(args.begin());
821 i != args.end(); ++i) {
822 if (i != args.begin()) {
823 out << ", ";
825 dumpType(out, b2u(*i));
827 out << " >";
829 break;
830 case codemaker::UnoType::Sort::Interface:
831 if (!native) {
832 out << "::css::uno::Reference< ";
834 out << codemaker::cpp::scopedCppName(u2b(n));
835 if (!native) {
836 out << " >";
838 break;
839 default:
840 throw CannotDumpException(
841 "unexpected entity \"" + name + "\" in call to CppuType::dumpType");
843 for (sal_Int32 i = 0; i != k; ++i) {
844 out << " >";
846 if (isRef) {
847 out << "&";
851 void CppuType::dumpCppuGetType(
852 FileStream & out, OUString const & name, OUString const * ownName) const
854 //TODO: What are these calls good for?
855 OUString nucleus;
856 sal_Int32 rank;
857 codemaker::UnoType::Sort sort = m_typeMgr->decompose(
858 name, true, &nucleus, &rank, nullptr, nullptr);
859 switch (rank == 0 ? sort : codemaker::UnoType::Sort::Sequence) {
860 case codemaker::UnoType::Sort::Void:
861 case codemaker::UnoType::Sort::Boolean:
862 case codemaker::UnoType::Sort::Byte:
863 case codemaker::UnoType::Sort::Short:
864 case codemaker::UnoType::Sort::UnsignedShort:
865 case codemaker::UnoType::Sort::Long:
866 case codemaker::UnoType::Sort::UnsignedLong:
867 case codemaker::UnoType::Sort::Hyper:
868 case codemaker::UnoType::Sort::UnsignedHyper:
869 case codemaker::UnoType::Sort::Float:
870 case codemaker::UnoType::Sort::Double:
871 case codemaker::UnoType::Sort::Char:
872 case codemaker::UnoType::Sort::String:
873 case codemaker::UnoType::Sort::Type:
874 case codemaker::UnoType::Sort::Any:
875 break;
876 case codemaker::UnoType::Sort::Sequence:
877 case codemaker::UnoType::Sort::Enum:
878 case codemaker::UnoType::Sort::PlainStruct:
879 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
880 case codemaker::UnoType::Sort::Exception:
881 case codemaker::UnoType::Sort::Interface:
882 // Take care of recursion like struct S { sequence<S> x; }:
883 if (ownName == nullptr || nucleus != *ownName) {
884 out << indent() << "::cppu::UnoType< ";
885 dumpType(out, name, false, false, false, true);
886 out << " >::get();\n";
888 break;
889 case codemaker::UnoType::Sort::Typedef:
890 for (;;) std::abort(); // this cannot happen
891 default:
892 throw CannotDumpException(
893 "unexpected entity \"" + name
894 + "\" in call to CppuType::dumpCppuGetType");
898 bool CppuType::passByReference(OUString const & name) const
900 switch (m_typeMgr->getSort(resolveOuterTypedefs(name))) {
901 case codemaker::UnoType::Sort::Boolean:
902 case codemaker::UnoType::Sort::Byte:
903 case codemaker::UnoType::Sort::Short:
904 case codemaker::UnoType::Sort::UnsignedShort:
905 case codemaker::UnoType::Sort::Long:
906 case codemaker::UnoType::Sort::UnsignedLong:
907 case codemaker::UnoType::Sort::Hyper:
908 case codemaker::UnoType::Sort::UnsignedHyper:
909 case codemaker::UnoType::Sort::Float:
910 case codemaker::UnoType::Sort::Double:
911 case codemaker::UnoType::Sort::Char:
912 case codemaker::UnoType::Sort::Enum:
913 return false;
914 case codemaker::UnoType::Sort::String:
915 case codemaker::UnoType::Sort::Type:
916 case codemaker::UnoType::Sort::Any:
917 case codemaker::UnoType::Sort::Sequence:
918 case codemaker::UnoType::Sort::PlainStruct:
919 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
920 case codemaker::UnoType::Sort::Interface:
921 return true;
922 default:
923 throw CannotDumpException(
924 "unexpected entity \"" + name
925 + "\" in call to CppuType::passByReference");
929 bool CppuType::canBeWarnUnused(OUString const & name) const
931 return canBeWarnUnused(name, 0);
933 bool CppuType::canBeWarnUnused(OUString const & name, int depth) const
935 // prevent infinite recursion and blowing the stack
936 if (depth > 10)
937 return false;
938 OUString aResolvedName = resolveOuterTypedefs(name);
939 switch (m_typeMgr->getSort(aResolvedName)) {
940 case codemaker::UnoType::Sort::Boolean:
941 case codemaker::UnoType::Sort::Byte:
942 case codemaker::UnoType::Sort::Short:
943 case codemaker::UnoType::Sort::UnsignedShort:
944 case codemaker::UnoType::Sort::Long:
945 case codemaker::UnoType::Sort::UnsignedLong:
946 case codemaker::UnoType::Sort::Hyper:
947 case codemaker::UnoType::Sort::UnsignedHyper:
948 case codemaker::UnoType::Sort::Float:
949 case codemaker::UnoType::Sort::Double:
950 case codemaker::UnoType::Sort::Char:
951 case codemaker::UnoType::Sort::Enum:
952 case codemaker::UnoType::Sort::String:
953 case codemaker::UnoType::Sort::Type:
954 return true;
955 case codemaker::UnoType::Sort::PlainStruct: {
956 rtl::Reference< unoidl::Entity > ent;
957 m_typeMgr->getSort(aResolvedName, &ent);
958 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
959 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
960 if (!ent2->getDirectBase().isEmpty() && !canBeWarnUnused(ent2->getDirectBase(), depth+1))
961 return false;
962 for ( const unoidl::PlainStructTypeEntity::Member& rMember : ent2->getDirectMembers()) {
963 if (!canBeWarnUnused(rMember.type, depth+1))
964 return false;
966 return true;
968 case codemaker::UnoType::Sort::Sequence: {
969 OUString aInnerType = aResolvedName.copy(2);
970 return canBeWarnUnused(aInnerType, depth+1);
972 case codemaker::UnoType::Sort::Any:
973 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
974 case codemaker::UnoType::Sort::Interface:
975 return false;
976 default:
977 throw CannotDumpException(
978 "unexpected entity \"" + name
979 + "\" in call to CppuType::canBeWarnUnused");
983 OUString CppuType::resolveOuterTypedefs(OUString const & name) const
985 for (OUString n(name);;) {
986 rtl::Reference< unoidl::Entity > ent;
987 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
988 return n;
990 n = dynamic_cast<unoidl::TypedefEntity&>(*ent.get()).getType();
994 OUString CppuType::resolveAllTypedefs(OUString const & name) const
996 sal_Int32 k1;
997 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k1)));
998 for (;;) {
999 rtl::Reference< unoidl::Entity > ent;
1000 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
1001 break;
1003 sal_Int32 k2;
1004 n = b2u(
1005 codemaker::UnoType::decompose(
1006 u2b(dynamic_cast<unoidl::TypedefEntity&>(*ent.get()).
1007 getType()),
1008 &k2));
1009 k1 += k2; //TODO: overflow
1011 OUStringBuffer b;
1012 for (sal_Int32 i = 0; i != k1; ++i) {
1013 b.append("[]");
1015 b.append(n);
1016 return b.makeStringAndClear();
1019 void CppuType::inc(sal_Int32 num)
1021 m_indentLength += num;
1024 void CppuType::dec(sal_Int32 num)
1026 m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0);
1029 OUString CppuType::indent() const
1031 OUStringBuffer buf(m_indentLength);
1032 for (sal_Int32 i = 0; i != m_indentLength; ++i) {
1033 buf.append(' ');
1035 return buf.makeStringAndClear();
1038 bool isDeprecated(std::vector< OUString > const & annotations)
1040 for (const OUString& r : annotations) {
1041 if (r == "deprecated") {
1042 return true;
1045 return false;
1048 void dumpDeprecation(FileStream & out, bool deprecated)
1050 if (deprecated) {
1051 out << "SAL_DEPRECATED_INTERNAL(\"marked @deprecated in UNOIDL\") ";
1055 class BaseOffset
1057 public:
1058 BaseOffset(
1059 rtl::Reference< TypeManager > const & manager,
1060 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity):
1061 manager_(manager), offset_(0) {
1062 calculateBases(entity);
1064 BaseOffset(const BaseOffset&) = delete;
1065 const BaseOffset& operator=(const BaseOffset&) = delete;
1067 sal_Int32 get() const {
1068 return offset_;
1071 private:
1072 void calculateBases(
1073 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity);
1075 rtl::Reference< TypeManager > manager_;
1076 std::set< OUString > set_;
1077 sal_Int32 offset_;
1080 void BaseOffset::calculateBases(
1081 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity)
1083 assert(entity.is());
1084 for (const unoidl::AnnotatedReference& ar : entity->getDirectMandatoryBases()) {
1085 if (set_.insert(ar.name).second) {
1086 rtl::Reference< unoidl::Entity > ent;
1087 codemaker::UnoType::Sort sort = manager_->getSort(ar.name, &ent);
1088 if (sort != codemaker::UnoType::Sort::Interface) {
1089 throw CannotDumpException(
1090 "interface type base " + ar.name
1091 + " is not an interface type");
1093 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
1094 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()));
1095 assert(ent2.is());
1096 calculateBases(ent2);
1097 offset_ += ent2->getDirectAttributes().size()
1098 + ent2->getDirectMethods().size(); //TODO: overflow
1103 class InterfaceType: public CppuType
1105 public:
1106 InterfaceType(
1107 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
1108 OUString const & name, rtl::Reference< TypeManager > const & typeMgr);
1110 virtual void dumpDeclaration(FileStream& o) override;
1111 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1113 void dumpAttributes(FileStream& o) const;
1114 void dumpMethods(FileStream& o) const;
1115 void dumpNormalGetCppuType(FileStream& o) override;
1116 void dumpComprehensiveGetCppuType(FileStream& o) override;
1117 void dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index);
1118 void dumpCppuMethodRefs(FileStream& o, sal_uInt32& index);
1119 void dumpCppuAttributes(FileStream& o, sal_uInt32& index);
1120 void dumpCppuMethods(FileStream& o, sal_uInt32& index);
1121 void dumpAttributesCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1122 void dumpMethodsCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1124 private:
1125 virtual void addComprehensiveGetCppuTypeIncludes(
1126 codemaker::cppumaker::Includes & includes) const override;
1128 virtual sal_uInt32 checkInheritedMemberCount() const override {
1129 return BaseOffset(m_typeMgr, entity_).get();
1132 void dumpExceptionTypeName(
1133 FileStream & out, OUString const & prefix, sal_uInt32 index,
1134 OUString const & name) const;
1136 sal_Int32 dumpExceptionTypeNames(
1137 FileStream & out, OUString const & prefix,
1138 std::vector< OUString > const & exceptions, bool runtimeException) const;
1140 rtl::Reference< unoidl::InterfaceTypeEntity > entity_;
1141 bool m_isDeprecated;
1144 InterfaceType::InterfaceType(
1145 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
1146 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1147 CppuType(name, typeMgr), entity_(entity),
1148 m_isDeprecated(isDeprecated(entity->getAnnotations()))
1150 assert(entity.is());
1153 void InterfaceType::dumpDeclaration(FileStream & out)
1155 out << "\nclass SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI " << id_;
1156 for (std::vector< unoidl::AnnotatedReference >::const_iterator i(
1157 entity_->getDirectMandatoryBases().begin());
1158 i != entity_->getDirectMandatoryBases().end(); ++i) {
1159 out << (i == entity_->getDirectMandatoryBases().begin() ? " :" : ",")
1160 << " public " << codemaker::cpp::scopedCppName(u2b(i->name));
1162 out << "\n{\npublic:\n";
1163 inc();
1164 dumpAttributes(out);
1165 dumpMethods(out);
1166 out << "\n" << indent()
1167 << ("static inline ::css::uno::Type const & SAL_CALL"
1168 " static_type(void * = 0);\n\n");
1169 dec();
1170 out << "protected:\n";
1171 inc();
1172 out << indent() << "~" << id_
1173 << ("() throw () {} // avoid warnings about virtual members and"
1174 " non-virtual dtor\n");
1175 dec();
1176 out << "};\n\n";
1179 void InterfaceType::dumpHppFile(
1180 FileStream & out, codemaker::cppumaker::Includes & includes)
1182 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1183 out << "\n";
1184 addDefaultHxxIncludes(includes);
1185 includes.dump(out, &name_, !(m_cppuTypeLeak || m_cppuTypeDynamic));
1186 out << "\n";
1187 dumpGetCppuType(out);
1188 out << "\n::css::uno::Type const & "
1189 << codemaker::cpp::scopedCppName(u2b(name_))
1190 << "::static_type(SAL_UNUSED_PARAMETER void *) {\n";
1191 inc();
1192 out << indent() << "return ::cppu::UnoType< ";
1193 dumpType(out, name_, false, false, true);
1194 out << " >::get();\n";
1195 dec();
1196 out << "}\n\n#endif // "<< headerDefine << "\n";
1199 void InterfaceType::dumpAttributes(FileStream & out) const
1201 if (!entity_->getDirectAttributes().empty()) {
1202 out << "\n" << indent() << "// Attributes\n";
1204 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1205 bool depr = m_isDeprecated || isDeprecated(attr.annotations);
1206 out << indent();
1207 dumpDeprecation(out, depr);
1208 out << "virtual ";
1209 dumpType(out, attr.type);
1210 out << " SAL_CALL get" << attr.name << "() = 0;\n";
1211 if (!attr.readOnly) {
1212 bool byRef = passByReference(attr.type);
1213 out << indent();
1214 dumpDeprecation(out, depr);
1215 out << "virtual void SAL_CALL set" << attr.name << "( ";
1216 dumpType(out, attr.type, byRef, byRef);
1217 out << " _" << attr.name.toAsciiLowerCase() << " ) = 0;\n";
1222 void InterfaceType::dumpMethods(FileStream & out) const
1224 if (!entity_->getDirectMethods().empty()) {
1225 out << "\n" << indent() << "// Methods\n";
1227 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1228 out << indent();
1229 dumpDeprecation(out, m_isDeprecated || isDeprecated(method.annotations));
1230 out << "virtual ";
1231 dumpType(out, method.returnType);
1232 out << " SAL_CALL " << method.name << "(";
1233 if (!method.parameters.empty()) {
1234 out << " ";
1235 for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1236 const_iterator j(method.parameters.begin());
1237 j != method.parameters.end();) {
1238 bool isConst;
1239 bool isRef;
1240 if (j->direction
1241 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1243 isConst = passByReference(j->type);
1244 isRef = isConst;
1245 } else {
1246 isConst = false;
1247 isRef = true;
1249 dumpType(out, j->type, isConst, isRef);
1250 out << " " << j->name;
1251 ++j;
1252 if (j != method.parameters.end()) {
1253 out << ", ";
1256 out << " ";
1258 out << ") = 0;\n";
1262 void InterfaceType::dumpNormalGetCppuType(FileStream & out)
1264 dumpGetCppuTypePreamble(out);
1265 out << indent()
1266 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
1267 << indent() << "if ( !the_type )\n" << indent() << "{\n";
1268 inc();
1269 std::vector< unoidl::AnnotatedReference >::size_type bases(
1270 entity_->getDirectMandatoryBases().size());
1271 if (bases == 1
1272 && (entity_->getDirectMandatoryBases()[0].name
1273 == "com.sun.star.uno.XInterface")) {
1274 bases = 0;
1276 if (bases != 0) {
1277 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1278 << entity_->getDirectMandatoryBases().size() << "];\n";
1279 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1280 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1281 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1282 dumpType(out, ar.name, true, false, false, true);
1283 out << " >::get().getTypeLibType();\n";
1286 out << indent() << "typelib_static_mi_interface_type_init( &the_type, \""
1287 << name_ << "\", " << bases << ", "
1288 << (bases == 0 ? "0" : "aSuperTypes") << " );\n";
1289 dec();
1290 out << indent() << "}\n" << indent()
1291 << ("return * reinterpret_cast< ::css::uno::Type * >("
1292 " &the_type );\n");
1293 dumpGetCppuTypePostamble(out);
1296 void InterfaceType::dumpComprehensiveGetCppuType(FileStream & out)
1298 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
1299 OUString staticTypeClass("the" + id_ + "Type");
1300 out << " namespace detail {\n\n" << indent() << "struct " << staticTypeClass
1301 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
1302 << staticTypeClass << " >\n" << indent() << "{\n";
1303 inc();
1304 out << indent() << "::css::uno::Type * operator()() const\n"
1305 << indent() << "{\n";
1306 inc();
1307 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
1308 << indent() << "// Start inline typedescription generation\n"
1309 << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n";
1310 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1311 << entity_->getDirectMandatoryBases().size() << "];\n";
1312 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1313 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1314 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1315 dumpType(out, ar.name, false, false, false, true);
1316 out << " >::get().getTypeLibType();\n";
1318 std::size_t count = entity_->getDirectAttributes().size()
1319 + entity_->getDirectMethods().size(); //TODO: overflow
1320 if (count != 0) {
1321 out << indent() << "typelib_TypeDescriptionReference * pMembers["
1322 << count << "] = { ";
1323 for (std::size_t i = 0; i != count; ++i) {
1324 out << "0";
1325 if (i + 1 != count) {
1326 out << ",";
1329 out << " };\n";
1330 sal_uInt32 index = 0;
1331 dumpCppuAttributeRefs(out, index);
1332 dumpCppuMethodRefs(out, index);
1334 out << "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1335 inc();
1336 out << indent() << "&pTD,\n" << indent()
1337 << "sTypeName.pData, 0, 0, 0, 0, 0,\n" << indent()
1338 << entity_->getDirectMandatoryBases().size() << ", aSuperTypes,\n"
1339 << indent() << count << ",\n" << indent()
1340 << (count == 0 ? "0" : "pMembers") << " );\n\n";
1341 dec();
1342 out << indent()
1343 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1344 " );\n");
1345 for (std::size_t i = 0; i != count; ++i) {
1346 out << indent() << "typelib_typedescriptionreference_release( pMembers["
1347 << i << "] );\n";
1349 out << indent()
1350 << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1351 " );\n\n")
1352 << indent() << "return new ::css::uno::Type( "
1353 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
1354 dec();
1355 out << indent() << "}\n";
1356 dec();
1357 out << indent() << "};\n\n";
1358 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
1359 out << " }\n\n";
1360 dumpGetCppuTypePreamble(out);
1361 out << indent() << "const ::css::uno::Type &rRet = *detail::"
1362 << staticTypeClass << "::get();\n" << indent()
1363 << "// End inline typedescription generation\n" << indent()
1364 << "static bool bInitStarted = false;\n" << indent()
1365 << "if (!bInitStarted)\n" << indent() << "{\n";
1366 inc();
1367 out << indent()
1368 << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"
1369 << indent() << "if (!bInitStarted)\n" << indent() << "{\n";
1370 inc();
1371 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"
1372 << indent() << "bInitStarted = true;\n";
1373 std::set< OUString > seen;
1374 // Type for RuntimeException is always needed:
1375 seen.insert("com.sun.star.uno.RuntimeException");
1376 dumpCppuGetType(out, "com.sun.star.uno.RuntimeException");
1377 dumpAttributesCppuDecl(out, &seen);
1378 dumpMethodsCppuDecl(out, &seen);
1379 if (count != 0) {
1380 sal_uInt32 index = getInheritedMemberCount();
1381 dumpCppuAttributes(out, index);
1382 dumpCppuMethods(out, index);
1384 dec();
1385 out << indent() << "}\n";
1386 dec();
1387 out << indent() << "}\n" << indent() << "else\n" << indent() << "{\n";
1388 inc();
1389 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
1390 dec();
1391 out << indent() << "}\n" << indent() << "return rRet;\n";
1392 dumpGetCppuTypePostamble(out);
1395 void InterfaceType::dumpCppuAttributeRefs(FileStream & out, sal_uInt32 & index)
1397 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1398 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1399 out << indent() << "::rtl::OUString sAttributeName" << n << "( \""
1400 << name_ << "::" << attr.name << "\" );\n" << indent()
1401 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1402 << "],\n";
1403 inc(38);
1404 out << indent()
1405 << ("(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_ATTRIBUTE,\n")
1406 << indent() << "sAttributeName" << n << ".pData );\n";
1407 dec(38);
1408 ++n;
1412 void InterfaceType::dumpCppuMethodRefs(FileStream & out, sal_uInt32 & index)
1414 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1415 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1416 out << indent() << "::rtl::OUString sMethodName" << n << "( \"" << name_
1417 << "::" << method.name << "\" );\n" << indent()
1418 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1419 << "],\n";
1420 inc(38);
1421 out << indent()
1422 << ("(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_METHOD,\n")
1423 << indent() << "sMethodName" << n << ".pData );\n";
1424 dec(38);
1425 ++n;
1429 void InterfaceType::addComprehensiveGetCppuTypeIncludes(
1430 codemaker::cppumaker::Includes & includes) const
1432 // The comprehensive getCppuType method always includes a line
1433 // "getCppuType( (const ::css::uno::RuntimeException*)0 );":
1434 includes.addCppuUnotypeHxx();
1435 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
1436 includes.addOslMutexHxx();
1437 includes.add("com.sun.star.uno.RuntimeException");
1440 void InterfaceType::dumpCppuAttributes(FileStream & out, sal_uInt32 & index)
1442 if (!entity_->getDirectAttributes().empty()) {
1443 out << "\n" << indent()
1444 << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
1445 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1446 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1447 OUString type(resolveAllTypedefs(attr.type));
1448 out << indent() << "{\n";
1449 inc();
1450 out << indent() << "::rtl::OUString sAttributeType" << n << "( \""
1451 << type << "\" );\n" << indent()
1452 << "::rtl::OUString sAttributeName" << n << "( \"" << name_
1453 << "::" << attr.name << "\" );\n";
1454 sal_Int32 getExcn = dumpExceptionTypeNames(
1455 out, "get", attr.getExceptions, false);
1456 sal_Int32 setExcn = dumpExceptionTypeNames(
1457 out, "set", attr.setExceptions, false);
1458 out << indent()
1459 << ("typelib_typedescription_newExtendedInterfaceAttribute("
1460 " &pAttribute,\n");
1461 inc();
1462 out << indent() << index++ << ", sAttributeName" << n
1463 << ".pData,\n" << indent() << "(typelib_TypeClass)"
1464 << getTypeClass(type) << ", sAttributeType" << n << ".pData,\n"
1465 << indent() << "sal_" << (attr.readOnly ? "True" : "False")
1466 << ", " << getExcn << ", "
1467 << (getExcn == 0 ? "0" : "the_getExceptions") << ", " << setExcn
1468 << ", " << (setExcn == 0 ? "0" : "the_setExceptions")
1469 << " );\n";
1470 dec();
1471 out << indent()
1472 << ("typelib_typedescription_register("
1473 " (typelib_TypeDescription**)&pAttribute );\n");
1474 dec();
1475 out << indent() << "}\n";
1476 ++n;
1478 out << indent()
1479 << ("typelib_typedescription_release("
1480 " (typelib_TypeDescription*)pAttribute );\n");
1484 void InterfaceType::dumpCppuMethods(FileStream & out, sal_uInt32 & index)
1486 if (!entity_->getDirectMethods().empty()) {
1487 out << "\n" << indent()
1488 << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
1489 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1490 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1491 OUString returnType(resolveAllTypedefs(method.returnType));
1492 out << indent() << "{\n";
1493 inc();
1494 if (!method.parameters.empty()) {
1495 out << indent() << "typelib_Parameter_Init aParameters["
1496 << method.parameters.size() << "];\n";
1498 std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1499 size_type m = 0;
1500 for (const unoidl::InterfaceTypeEntity::Method::Parameter& param : method.parameters) {
1501 OUString type(resolveAllTypedefs(param.type));
1502 out << indent() << "::rtl::OUString sParamName" << m << "( \""
1503 << param.name << "\" );\n" << indent()
1504 << "::rtl::OUString sParamType" << m << "( \"" << type
1505 << "\" );\n" << indent() << "aParameters[" << m
1506 << "].pParamName = sParamName" << m << ".pData;\n"
1507 << indent() << "aParameters[" << m
1508 << "].eTypeClass = (typelib_TypeClass)"
1509 << getTypeClass(type) << ";\n" << indent() << "aParameters["
1510 << m << "].pTypeName = sParamType" << m << ".pData;\n"
1511 << indent() << "aParameters[" << m << "].bIn = "
1512 << ((param.direction
1513 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT)
1514 ? "sal_False" : "sal_True")
1515 << ";\n" << indent() << "aParameters[" << m << "].bOut = "
1516 << ((param.direction
1517 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1518 ? "sal_False" : "sal_True")
1519 << ";\n";
1520 ++m;
1522 sal_Int32 excn = dumpExceptionTypeNames(
1523 out, "", method.exceptions,
1524 method.name != "acquire" && method.name != "release");
1525 out << indent() << "::rtl::OUString sReturnType" << n << "( \""
1526 << returnType << "\" );\n" << indent()
1527 << "::rtl::OUString sMethodName" << n << "( \"" << name_ << "::"
1528 << method.name << "\" );\n" << indent()
1529 << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
1530 inc();
1531 out << indent() << index++ << ", sal_False,\n" << indent()
1532 << "sMethodName" << n << ".pData,\n" << indent()
1533 << "(typelib_TypeClass)" << getTypeClass(returnType)
1534 << ", sReturnType" << n << ".pData,\n" << indent()
1535 << method.parameters.size() << ", "
1536 << (method.parameters.empty() ? "0" : "aParameters") << ",\n"
1537 << indent() << excn << ", "
1538 << (excn == 0 ? "0" : "the_Exceptions") << " );\n";
1539 dec();
1540 out << indent()
1541 << ("typelib_typedescription_register("
1542 " (typelib_TypeDescription**)&pMethod );\n");
1543 dec();
1544 out << indent() << "}\n";
1545 ++n;
1547 out << indent()
1548 << ("typelib_typedescription_release("
1549 " (typelib_TypeDescription*)pMethod );\n");
1553 void InterfaceType::dumpAttributesCppuDecl(
1554 FileStream & out, std::set< OUString > * seen) const
1556 assert(seen != nullptr);
1557 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1558 if (seen->insert(attr.type).second) {
1559 dumpCppuGetType(out, attr.type);
1561 for (const OUString& exc : attr.getExceptions) {
1562 if (seen->insert(exc).second) {
1563 dumpCppuGetType(out, exc);
1566 for (const OUString& exc : attr.setExceptions) {
1567 if (seen->insert(exc).second) {
1568 dumpCppuGetType(out, exc);
1574 void InterfaceType::dumpMethodsCppuDecl(
1575 FileStream & out, std::set< OUString > * seen) const
1577 assert(seen != nullptr);
1578 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1579 for (const OUString& ex : method.exceptions) {
1580 if (seen->insert(ex).second) {
1581 dumpCppuGetType(out, ex);
1587 void InterfaceType::dumpExceptionTypeName(
1588 FileStream & out, OUString const & prefix, sal_uInt32 index,
1589 OUString const & name) const
1591 out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName"
1592 << index << "( \"" << name << "\" );\n";
1595 sal_Int32 InterfaceType::dumpExceptionTypeNames(
1596 FileStream & out, OUString const & prefix,
1597 std::vector< OUString > const & exceptions, bool runtimeException) const
1599 sal_Int32 count = 0;
1600 for (const OUString& ex : exceptions) {
1601 if (ex != "com.sun.star.uno.RuntimeException") {
1602 dumpExceptionTypeName(out, prefix, count++, ex);
1605 if (runtimeException) {
1606 dumpExceptionTypeName(
1607 out, prefix, count++, "com.sun.star.uno.RuntimeException");
1609 if (count != 0) {
1610 out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {";
1611 for (sal_Int32 i = 0; i != count; ++i) {
1612 out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName"
1613 << i << ".pData";
1615 out << " };\n";
1617 return count;
1620 class ConstantGroup: public CppuType
1622 public:
1623 ConstantGroup(
1624 rtl::Reference< unoidl::ConstantGroupEntity > const & entity,
1625 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1626 CppuType(name, typeMgr), entity_(entity) {
1627 assert(entity.is());
1630 bool hasConstants() const {
1631 return !entity_->getMembers().empty();
1634 private:
1635 virtual void dumpHdlFile(
1636 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1638 virtual void dumpHppFile(
1639 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1641 virtual void dumpDeclaration(FileStream & out) override;
1643 rtl::Reference< unoidl::ConstantGroupEntity > entity_;
1646 void ConstantGroup::dumpHdlFile(
1647 FileStream & out, codemaker::cppumaker::Includes & includes)
1649 OUString headerDefine(dumpHeaderDefine(out, "HDL"));
1650 out << "\n";
1651 addDefaultHIncludes(includes);
1652 includes.dump(out, nullptr, true);
1653 out << "\n";
1654 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, true)) {
1655 out << "\n";
1657 out << "\n";
1658 dumpDeclaration(out);
1659 out << "\n";
1660 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, true)) {
1661 out << "\n";
1663 out << "\n#endif // "<< headerDefine << "\n";
1666 void ConstantGroup::dumpHppFile(
1667 FileStream & out, codemaker::cppumaker::Includes &)
1669 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1670 out << "\n";
1671 codemaker::cppumaker::Includes::dumpInclude(out, u2b(name_), false);
1672 out << "\n#endif // "<< headerDefine << "\n";
1675 void ConstantGroup::dumpDeclaration(FileStream & out)
1677 for (const unoidl::ConstantGroupEntity::Member& member : entity_->getMembers()) {
1678 out << "static const ";
1679 switch (member.value.type) {
1680 case unoidl::ConstantValue::TYPE_BOOLEAN:
1681 out << "::sal_Bool";
1682 break;
1683 case unoidl::ConstantValue::TYPE_BYTE:
1684 out << "::sal_Int8";
1685 break;
1686 case unoidl::ConstantValue::TYPE_SHORT:
1687 out << "::sal_Int16";
1688 break;
1689 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1690 out << "::sal_uInt16";
1691 break;
1692 case unoidl::ConstantValue::TYPE_LONG:
1693 out << "::sal_Int32";
1694 break;
1695 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1696 out << "::sal_uInt32";
1697 break;
1698 case unoidl::ConstantValue::TYPE_HYPER:
1699 out << "::sal_Int64";
1700 break;
1701 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1702 out << "::sal_uInt64";
1703 break;
1704 case unoidl::ConstantValue::TYPE_FLOAT:
1705 out << "float";
1706 break;
1707 case unoidl::ConstantValue::TYPE_DOUBLE:
1708 out << "double";
1709 break;
1711 out << " " << member.name << " = ";
1712 switch (member.value.type) {
1713 case unoidl::ConstantValue::TYPE_BOOLEAN:
1714 out << (member.value.booleanValue ? "sal_True" : "sal_False");
1715 break;
1716 case unoidl::ConstantValue::TYPE_BYTE:
1717 out << "(sal_Int8)" << OUString::number(member.value.byteValue);
1718 break;
1719 case unoidl::ConstantValue::TYPE_SHORT:
1720 out << "(sal_Int16)" << OUString::number(member.value.shortValue);
1721 break;
1722 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1723 out << "(sal_uInt16)"
1724 << OUString::number(member.value.unsignedShortValue);
1725 break;
1726 case unoidl::ConstantValue::TYPE_LONG:
1727 // Avoid C++ compiler warnings about (un)signedness of literal
1728 // -2^31:
1729 if (member.value.longValue == SAL_MIN_INT32) {
1730 out << "SAL_MIN_INT32";
1731 } else {
1732 out << "(sal_Int32)" << OUString::number(member.value.longValue);
1734 break;
1735 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1736 out << "(sal_uInt32)"
1737 << OUString::number(member.value.unsignedLongValue) << "U";
1738 break;
1739 case unoidl::ConstantValue::TYPE_HYPER:
1740 // Avoid C++ compiler warnings about (un)signedness of literal
1741 // -2^63:
1742 if (member.value.hyperValue == SAL_MIN_INT64) {
1743 out << "SAL_MIN_INT64";
1744 } else {
1745 out << "(sal_Int64) SAL_CONST_INT64("
1746 << OUString::number(member.value.hyperValue) << ")";
1748 break;
1749 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1750 out << "SAL_CONST_UINT64("
1751 << OUString::number(member.value.unsignedHyperValue) << ")";
1752 break;
1753 case unoidl::ConstantValue::TYPE_FLOAT:
1754 out << "(float)" << OUString::number(member.value.floatValue);
1755 break;
1756 case unoidl::ConstantValue::TYPE_DOUBLE:
1757 out << "(double)" << OUString::number(member.value.doubleValue);
1758 break;
1760 out << ";\n";
1764 void dumpTypeParameterName(FileStream & out, OUString const & name)
1766 // Prefix all type parameters with "typeparam_" to avoid problems when a
1767 // struct member has the same name as a type parameter, as in
1768 // struct<T> { T T; };
1769 out << "typeparam_" << name;
1772 class PlainStructType: public CppuType
1774 public:
1775 PlainStructType(
1776 rtl::Reference< unoidl::PlainStructTypeEntity > const & entity,
1777 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1778 CppuType(name, typeMgr), entity_(entity) {
1779 assert(entity.is());
1782 private:
1783 virtual sal_uInt32 checkInheritedMemberCount() const override {
1784 return getTotalMemberCount(entity_->getDirectBase());
1787 virtual void dumpDeclaration(FileStream& o) override;
1789 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1791 virtual void dumpLightGetCppuType(FileStream & out) override;
1793 virtual void dumpNormalGetCppuType(FileStream & out) override;
1795 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
1797 virtual void addLightGetCppuTypeIncludes(
1798 codemaker::cppumaker::Includes & includes) const override;
1800 virtual void addNormalGetCppuTypeIncludes(
1801 codemaker::cppumaker::Includes & includes) const override;
1803 virtual void addComprehensiveGetCppuTypeIncludes(
1804 codemaker::cppumaker::Includes & includes) const override;
1806 bool dumpBaseMembers(
1807 FileStream & out, OUString const & base, bool withType);
1809 sal_uInt32 getTotalMemberCount(OUString const & base) const;
1811 rtl::Reference< unoidl::PlainStructTypeEntity > entity_;
1814 void PlainStructType::dumpDeclaration(FileStream & out)
1816 out << "\n#ifdef SAL_W32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
1817 out << "struct SAL_DLLPUBLIC_RTTI ";
1818 if (canBeWarnUnused(name_))
1819 out << "SAL_WARN_UNUSED ";
1820 out << id_;
1821 OUString base(entity_->getDirectBase());
1822 if (!base.isEmpty()) {
1823 out << ": public " << codemaker::cpp::scopedCppName(u2b(base));
1825 out << " {\n";
1826 inc();
1827 out << indent() << "inline " << id_ << "();\n";
1828 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1829 out << "\n" << indent() << "inline " << id_ << "(";
1830 bool bFirst = !dumpBaseMembers(out, base, true);
1831 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1832 if (!bFirst) {
1833 out << ", ";
1835 dumpType(out, member.type, true, true);
1836 out << " " << member.name << "_";
1837 bFirst = false;
1839 out << ");\n";
1841 if (!entity_->getDirectMembers().empty()) {
1842 out << "\n";
1843 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
1844 const_iterator i(entity_->getDirectMembers().begin());
1845 i != entity_->getDirectMembers().end(); ++i) {
1846 out << indent();
1847 dumpType(out, i->type);
1848 out << " " << i->name;
1849 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
1850 && i->type != "hyper" && i->type != "unsigned hyper"
1851 && i->type != "double") {
1852 out << " CPPU_GCC3_ALIGN("
1853 << codemaker::cpp::scopedCppName(u2b(base)) << ")";
1855 out << ";\n";
1858 dec();
1859 out << "};\n\n#ifdef SAL_W32\n# pragma pack(pop)\n#endif\n\n";
1862 void PlainStructType::dumpHppFile(
1863 FileStream & out, codemaker::cppumaker::Includes & includes)
1865 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1866 out << "\n";
1867 includes.dump(out, &name_, true);
1868 out << "\n";
1869 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
1870 out << "\n";
1872 out << "\ninline " << id_ << "::" << id_ << "()\n";
1873 inc();
1874 OUString base(entity_->getDirectBase());
1875 bool bFirst = true;
1876 if (!base.isEmpty()) {
1877 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1878 << "()\n";
1879 bFirst = false;
1881 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1882 out << indent() << (bFirst ? ":" : ",") << " " << member.name;
1883 dumpInitializer(out, false, member.type);
1884 out << "\n";
1885 bFirst = false;
1887 dec();
1888 out << "{\n}\n\n";
1889 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1890 out << "inline " << id_;
1891 out << "::" << id_ << "(";
1892 bFirst = !dumpBaseMembers(out, base, true);
1893 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1894 if (!bFirst) {
1895 out << ", ";
1897 dumpType(out, member.type, true, true);
1898 out << " " << member.name << "_";
1899 bFirst = false;
1901 out << ")\n";
1902 inc();
1903 bFirst = true;
1904 if (!base.isEmpty()) {
1905 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1906 << "(";
1907 dumpBaseMembers(out, base, false);
1908 out << ")\n";
1909 bFirst = false;
1911 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1912 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
1913 << member.name << "_)\n";
1914 bFirst = false;
1916 dec();
1917 out << "{\n}\n\n";
1919 // print the operator==
1920 out << "\ninline bool operator==(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1921 out << "{\n";
1922 inc();
1923 out << indent() << "return ";
1924 bFirst = true;
1925 if (!base.isEmpty()) {
1926 out << "operator==( static_cast< " << codemaker::cpp::scopedCppName(u2b(base))
1927 << ">(the_lhs), static_cast< " << codemaker::cpp::scopedCppName(u2b(base)) << ">(the_rhs) )\n";
1928 bFirst = false;
1930 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1931 if (!bFirst)
1932 out << "\n" << indent() << indent() << "&& ";
1933 out << "the_lhs." << member.name << " == the_rhs." << member.name;
1934 bFirst = false;
1936 out << ";\n";
1937 dec();
1938 out << "}\n";
1939 // print the operator!=
1940 out << "\ninline bool operator!=(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1941 out << "{\n";
1942 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
1943 out << "}\n";
1944 // close namespace
1945 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
1946 out << "\n";
1948 out << "\n";
1949 dumpGetCppuType(out);
1950 out << "\n#endif // "<< headerDefine << "\n";
1953 void PlainStructType::dumpLightGetCppuType(FileStream & out)
1955 dumpGetCppuTypePreamble(out);
1956 out << indent()
1957 << ("//TODO: On certain platforms with weak memory models, the"
1958 " following code can result in some threads observing that the_type"
1959 " points to garbage\n")
1960 << indent()
1961 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1962 << indent() << "if (the_type == 0) {\n";
1963 inc();
1964 out << indent() << "::typelib_static_type_init(&the_type, "
1965 << getTypeClass(name_, true) << ", \"" << name_ << "\");\n";
1966 dec();
1967 out << indent() << "}\n" << indent()
1968 << ("return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n");
1969 dumpGetCppuTypePostamble(out);
1972 void PlainStructType::dumpNormalGetCppuType(FileStream & out)
1974 dumpGetCppuTypePreamble(out);
1975 out << indent()
1976 << ("//TODO: On certain platforms with weak memory models, the"
1977 " following code can result in some threads observing that the_type"
1978 " points to garbage\n")
1979 << indent()
1980 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1981 << indent() << "if (the_type == 0) {\n";
1982 inc();
1983 out << indent()
1984 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
1985 inc();
1986 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
1987 entity_->getDirectMembers().begin());
1988 i != entity_->getDirectMembers().end();) {
1989 out << indent() << "::cppu::UnoType< ";
1990 dumpType(out, i->type, false, false, false, true);
1991 ++i;
1992 out << " >::get().getTypeLibType()"
1993 << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
1995 dec();
1996 out << indent() << "::typelib_static_struct_type_init(&the_type, \""
1997 << name_ << "\", ";
1998 if (entity_->getDirectBase().isEmpty()) {
1999 out << "0";
2000 } else {
2001 out << "::cppu::UnoType< ";
2002 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2003 out << " >::get().getTypeLibType()";
2005 out << ", " << entity_->getDirectMembers().size() << ", the_members, 0);\n";
2006 dec();
2007 out << indent() << "}\n" << indent()
2008 << ("return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n");
2009 dumpGetCppuTypePostamble(out);
2012 void PlainStructType::dumpComprehensiveGetCppuType(FileStream & out)
2014 OUString staticTypeClass("the" + id_ + "Type");
2015 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
2016 out << " namespace detail {\n\n" << indent() << "struct "
2017 << staticTypeClass
2018 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2019 << staticTypeClass << " >\n" << indent() << "{\n";
2020 inc();
2021 out << indent() << "::css::uno::Type * operator()() const\n"
2022 << indent() << "{\n";
2023 inc();
2024 out << indent() << "::rtl::OUString the_name( \"" << name_ << "\" );\n";
2025 std::map< OUString, sal_uInt32 > types;
2026 std::vector< unoidl::PlainStructTypeEntity::Member >::size_type n = 0;
2027 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2028 if (types.emplace(
2029 member.type, static_cast< sal_uInt32 >(types.size())).
2030 second) {
2031 dumpCppuGetType(out, member.type, &name_);
2032 // For typedefs, use the resolved type name, as there will be no
2033 // information available about the typedef itself at runtime (the
2034 // above getCppuType call will make available information about the
2035 // resolved type); no extra #include for the resolved type is
2036 // needed, as the header for the typedef includes it already:
2037 out << indent() << "::rtl::OUString the_tname"
2038 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2039 << resolveAllTypedefs(member.type) << "\" );\n";
2041 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2042 << member.name << "\" );\n";
2044 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2045 inc();
2046 n = 0;
2047 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
2048 entity_->getDirectMembers().begin());
2049 i != entity_->getDirectMembers().end();) {
2050 out << indent() << "{ { " << getTypeClass(i->type, true)
2051 << ", the_tname" << types.find(i->type)->second
2052 << ".pData, the_name" << n++ << ".pData }, false }";
2053 ++i;
2054 out << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2056 dec();
2057 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"
2058 << indent()
2059 << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2060 if (entity_->getDirectBase().isEmpty()) {
2061 out << "0";
2062 } else {
2063 out << "::cppu::UnoType< ";
2064 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2065 out << " >::get().getTypeLibType()";
2067 out << ", " << entity_->getDirectMembers().size() << ", the_members);\n"
2068 << indent() << "::typelib_typedescription_register(&the_newType);\n"
2069 << indent() << "::typelib_typedescription_release(the_newType);\n"
2070 << indent() << "return new ::css::uno::Type("
2071 << getTypeClass(name_) << ", the_name); // leaked\n";
2072 dec();
2073 out << indent() << "}\n";
2074 dec();
2075 out << indent() << "};\n";
2076 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
2077 out << " }\n\n";
2078 dumpGetCppuTypePreamble(out);
2079 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
2080 dumpGetCppuTypePostamble(out);
2083 bool PlainStructType::dumpBaseMembers(
2084 FileStream & out, OUString const & base, bool withType)
2086 bool hasMember = false;
2087 if (!base.isEmpty()) {
2088 rtl::Reference< unoidl::Entity > ent;
2089 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2090 if (sort != codemaker::UnoType::Sort::PlainStruct) {
2091 throw CannotDumpException(
2092 "plain struct type base " + base
2093 + " is not a plain struct type");
2095 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
2096 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2097 assert(ent2.is());
2098 if (!ent2.is()) {
2099 return false;
2101 hasMember = dumpBaseMembers(out, ent2->getDirectBase(), withType);
2102 for (const unoidl::PlainStructTypeEntity::Member& member : ent2->getDirectMembers()) {
2103 if (hasMember) {
2104 out << ", ";
2106 if (withType) {
2107 dumpType(out, member.type, true, true);
2108 out << " ";
2110 out << member.name << "_";
2111 hasMember = true;
2114 return hasMember;
2117 void PlainStructType::addLightGetCppuTypeIncludes(
2118 codemaker::cppumaker::Includes & includes) const
2120 includes.addType();
2121 includes.addCppuUnotypeHxx();
2122 includes.addSalTypesH();
2123 includes.addTypelibTypeclassH();
2124 includes.addTypelibTypedescriptionH();
2127 void PlainStructType::addNormalGetCppuTypeIncludes(
2128 codemaker::cppumaker::Includes & includes) const
2130 includes.addType();
2131 includes.addCppuUnotypeHxx();
2132 includes.addSalTypesH();
2133 includes.addTypelibTypeclassH();
2134 includes.addTypelibTypedescriptionH();
2137 void PlainStructType::addComprehensiveGetCppuTypeIncludes(
2138 codemaker::cppumaker::Includes & includes) const
2140 includes.addType();
2141 includes.addCppuUnotypeHxx();
2142 includes.addRtlInstanceHxx();
2143 includes.addRtlUstringH();
2144 includes.addRtlUstringHxx();
2145 includes.addSalTypesH();
2146 includes.addTypelibTypeclassH();
2147 includes.addTypelibTypedescriptionH();
2150 sal_uInt32 PlainStructType::getTotalMemberCount(OUString const & base) const
2152 if (base.isEmpty()) {
2153 return 0;
2155 rtl::Reference< unoidl::Entity > ent;
2156 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2157 if (sort != codemaker::UnoType::Sort::PlainStruct) {
2158 throw CannotDumpException(
2159 "plain struct type base " + base + " is not a plain struct type");
2161 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
2162 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2163 assert(ent2.is());
2164 if (!ent2.is()) {
2165 return 0;
2167 return getTotalMemberCount(ent2->getDirectBase())
2168 + ent2->getDirectMembers().size(); //TODO: overflow
2171 class PolyStructType: public CppuType
2173 public:
2174 PolyStructType(
2175 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const &
2176 entity,
2177 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2178 CppuType(name, typeMgr), entity_(entity) {
2179 assert(entity.is());
2182 private:
2183 virtual void dumpDeclaration(FileStream& o) override;
2185 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
2187 virtual void dumpLightGetCppuType(FileStream & out) override;
2189 virtual void dumpNormalGetCppuType(FileStream & out) override;
2191 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2193 virtual void addLightGetCppuTypeIncludes(
2194 codemaker::cppumaker::Includes & includes) const override;
2196 virtual void addNormalGetCppuTypeIncludes(
2197 codemaker::cppumaker::Includes & includes) const override;
2199 virtual void addComprehensiveGetCppuTypeIncludes(
2200 codemaker::cppumaker::Includes & includes) const override;
2202 virtual bool isPolymorphic() const override {
2203 return true;
2206 virtual void dumpTemplateHead(FileStream & out) const override;
2208 virtual void dumpTemplateParameters(FileStream & out) const override;
2210 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > entity_;
2213 void PolyStructType::dumpDeclaration(FileStream & out)
2215 out << "\n#ifdef SAL_W32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
2216 dumpTemplateHead(out);
2217 out << "struct SAL_DLLPUBLIC_RTTI " << id_ << " {\n";
2218 inc();
2219 out << indent() << "inline " << id_ << "();\n";
2220 if (!entity_->getMembers().empty()) {
2221 out << "\n" << indent() << "inline " << id_ << "(";
2222 for (std::vector<
2223 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2224 const_iterator i(entity_->getMembers().begin());
2225 i != entity_->getMembers().end(); ++i) {
2226 if (i != entity_->getMembers().begin()) {
2227 out << ", ";
2229 if (i->parameterized) {
2230 dumpTypeParameterName(out, i->type);
2231 out << " const &";
2232 } else {
2233 dumpType(out, i->type, true, true);
2235 out << " " << i->name << "_";
2237 out << ");\n\n";
2238 // print the member fields
2239 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member :
2240 entity_->getMembers()) {
2241 out << indent();
2242 if (member.parameterized) {
2243 dumpTypeParameterName(out, member.type);
2244 } else {
2245 dumpType(out, member.type);
2247 out << " " << member.name << ";\n";
2250 dec();
2251 out << "};\n\n#ifdef SAL_W32\n# pragma pack(pop)\n#endif\n\n";
2254 void PolyStructType::dumpHppFile(
2255 FileStream & out, codemaker::cppumaker::Includes & includes)
2257 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
2258 out << "\n";
2259 includes.dump(out, &name_, true);
2260 out << "\n";
2261 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2262 out << "\n";
2264 out << "\n";
2265 // dump default (no-arg) constructor
2266 dumpTemplateHead(out);
2267 out << "inline " << id_;
2268 dumpTemplateParameters(out);
2269 out << "::" << id_ << "()\n";
2270 inc();
2271 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2272 const_iterator i(entity_->getMembers().begin());
2273 i != entity_->getMembers().end(); ++i) {
2274 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2275 << " " << i->name;
2276 dumpInitializer(out, i->parameterized, i->type);
2277 out << "\n";
2279 dec();
2280 out << "{\n}\n\n";
2281 if (!entity_->getMembers().empty()) {
2282 // dump takes-all-fields constructor
2283 dumpTemplateHead(out);
2284 out << "inline " << id_;
2285 dumpTemplateParameters(out);
2286 out << "::" << id_ << "(";
2287 for (std::vector<
2288 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2289 const_iterator i(entity_->getMembers().begin());
2290 i != entity_->getMembers().end(); ++i) {
2291 if (i != entity_->getMembers().begin()) {
2292 out << ", ";
2294 if (i->parameterized) {
2295 dumpTypeParameterName(out, i->type);
2296 out << " const &";
2297 } else {
2298 dumpType(out, i->type, true, true);
2300 out << " " << i->name << "_";
2302 out << ")\n";
2303 inc();
2304 for (std::vector<
2305 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2306 const_iterator i(entity_->getMembers().begin());
2307 i != entity_->getMembers().end(); ++i) {
2308 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2309 << " " << i->name << "(" << i->name << "_)\n";
2311 dec();
2312 out << "{\n}\n\n" << indent();
2313 // dump make_T method
2314 dumpTemplateHead(out);
2315 out << "\n" << indent() << "inline " << id_;
2316 dumpTemplateParameters(out);
2317 out << "\n" << indent() << "make_" << id_ << "(";
2318 for (std::vector<
2319 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2320 const_iterator i(entity_->getMembers().begin());
2321 i != entity_->getMembers().end(); ++i) {
2322 if (i != entity_->getMembers().begin()) {
2323 out << ", ";
2325 if (i->parameterized) {
2326 dumpTypeParameterName(out, i->type);
2327 out << " const &";
2328 } else {
2329 dumpType(out, i->type, true, true);
2331 out << " " << i->name << "_";
2333 out << ")\n" << indent() << "{\n";
2334 inc();
2335 out << indent() << "return " << id_;
2336 dumpTemplateParameters(out);
2337 out << "(";
2338 for (std::vector<
2339 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2340 const_iterator i(entity_->getMembers().begin());
2341 i != entity_->getMembers().end(); ++i) {
2342 if (i != entity_->getMembers().begin()) {
2343 out << ", ";
2345 out << i->name << "_";
2347 out << ");\n";
2348 dec();
2349 out << indent() << "}\n\n";
2351 // print the operator==
2352 dumpTemplateHead(out);
2353 out << " inline bool operator==(const " << id_;
2354 dumpTemplateParameters(out);
2355 out << "& the_lhs, const " << id_;
2356 dumpTemplateParameters(out);
2357 out << "& the_rhs)\n";
2358 out << "{\n";
2359 inc();
2360 out << indent() << "return ";
2361 bool bFirst = true;
2362 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2363 if (!bFirst)
2364 out << "\n" << indent() << indent() << "&& ";
2365 out << "the_lhs." << member.name << " == the_rhs." << member.name;
2366 bFirst = false;
2368 out << ";\n";
2369 dec();
2370 out << "}\n";
2371 // print the operator!=
2372 dumpTemplateHead(out);
2373 out << " inline bool operator!=(const " << id_;
2374 dumpTemplateParameters(out);
2375 out << "& the_lhs, const " << id_;
2376 dumpTemplateParameters(out);
2377 out << "& the_rhs)\n";
2378 out << "{\n";
2379 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
2380 out << "}\n";
2381 // close namespace
2382 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2383 out << "\n";
2385 out << "\n";
2386 dumpGetCppuType(out);
2387 out << "\n#endif // "<< headerDefine << "\n";
2390 void PolyStructType::dumpLightGetCppuType(FileStream & out)
2392 dumpGetCppuTypePreamble(out);
2393 out << indent()
2394 << ("//TODO: On certain platforms with weak memory models, the"
2395 " following code can result in some threads observing that the_type"
2396 " points to garbage\n")
2397 << indent()
2398 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2399 << indent() << "if (the_type == 0) {\n";
2400 inc();
2401 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2402 << "<\");\n";
2403 for (std::vector< OUString >::const_iterator i(
2404 entity_->getTypeParameters().begin());
2405 i != entity_->getTypeParameters().end();) {
2406 out << indent()
2407 << ("the_buffer.append(::rtl::OUStringToOString("
2408 "::cppu::getTypeFavourChar(static_cast< ");
2409 dumpTypeParameterName(out, *i);
2410 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2411 ++i;
2412 if (i != entity_->getTypeParameters().end()) {
2413 out << indent() << "the_buffer.append(',');\n";
2416 out << indent() << "the_buffer.append('>');\n" << indent()
2417 << "::typelib_static_type_init(&the_type, " << getTypeClass(name_, true)
2418 << ", the_buffer.getStr());\n";
2419 dec();
2420 out << indent() << "}\n" << indent()
2421 << ("return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n");
2422 dumpGetCppuTypePostamble(out);
2425 void PolyStructType::dumpNormalGetCppuType(FileStream & out)
2427 dumpGetCppuTypePreamble(out);
2428 out << indent()
2429 << ("//TODO: On certain platforms with weak memory models, the"
2430 " following code can result in some threads observing that the_type"
2431 " points to garbage\n")
2432 << indent()
2433 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2434 << indent() << "if (the_type == 0) {\n";
2435 inc();
2436 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2437 << "<\");\n";
2438 for (std::vector< OUString >::const_iterator i(
2439 entity_->getTypeParameters().begin());
2440 i != entity_->getTypeParameters().end();) {
2441 out << indent()
2442 << ("the_buffer.append(::rtl::OUStringToOString("
2443 "::cppu::getTypeFavourChar(static_cast< ");
2444 dumpTypeParameterName(out, *i);
2445 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2446 ++i;
2447 if (i != entity_->getTypeParameters().end()) {
2448 out << indent() << "the_buffer.append(',');\n";
2451 out << indent() << "the_buffer.append('>');\n" << indent()
2452 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2453 inc();
2454 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2455 const_iterator i(entity_->getMembers().begin());
2456 i != entity_->getMembers().end();) {
2457 out << indent();
2458 if (i->parameterized) {
2459 out << "::cppu::getTypeFavourChar(static_cast< ";
2460 dumpTypeParameterName(out, i->type);
2461 out << " * >(0))";
2462 } else {
2463 out << "::cppu::UnoType< ";
2464 dumpType(out, i->type, false, false, false, true);
2465 out << " >::get()";
2467 ++i;
2468 out << ".getTypeLibType()"
2469 << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2471 dec();
2472 out << indent() << "static ::sal_Bool const the_parameterizedTypes[] = { ";
2473 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2474 const_iterator i(entity_->getMembers().begin());
2475 i != entity_->getMembers().end(); ++i) {
2476 if (i != entity_->getMembers().begin()) {
2477 out << ", ";
2479 out << (i->parameterized ? "true" : "false");
2481 out << " };\n" << indent()
2482 << ("::typelib_static_struct_type_init(&the_type, the_buffer.getStr(),"
2483 " 0, ")
2484 << entity_->getMembers().size()
2485 << ", the_members, the_parameterizedTypes);\n";
2486 dec();
2487 out << indent() << "}\n" << indent()
2488 << ("return *reinterpret_cast< ::css::uno::Type * >("
2489 "&the_type);\n");
2490 dumpGetCppuTypePostamble(out);
2493 void PolyStructType::dumpComprehensiveGetCppuType(FileStream & out)
2495 out << "namespace cppu { namespace detail {\n\n" << indent();
2496 dumpTemplateHead(out);
2497 OUString staticTypeClass("the" + id_ + "Type");
2498 out << "struct " << staticTypeClass
2499 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2500 << staticTypeClass;
2501 dumpTemplateParameters(out);
2502 out << " >\n" << indent() << "{\n";
2503 inc();
2504 out << indent() << "::css::uno::Type * operator()() const\n"
2505 << indent() << "{\n";
2506 inc();
2507 out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent()
2508 << "the_buffer.append(\"" << name_ << "<\");\n";
2509 for (std::vector< OUString >::const_iterator i(
2510 entity_->getTypeParameters().begin());
2511 i != entity_->getTypeParameters().end();) {
2512 out << indent()
2513 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2514 dumpTypeParameterName(out, *i);
2515 out << " * >(0)).getTypeName());\n";
2516 ++i;
2517 if (i != entity_->getTypeParameters().end()) {
2518 out << indent()
2519 << ("the_buffer.append("
2520 "static_cast< ::sal_Unicode >(','));\n");
2523 out << indent() << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n"
2524 << indent()
2525 << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2526 std::map< OUString, sal_uInt32 > parameters;
2527 std::map< OUString, sal_uInt32 > types;
2528 std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2529 size_type n = 0;
2530 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2531 if (member.parameterized) {
2532 if (parameters.emplace(
2533 member.type, static_cast< sal_uInt32 >(parameters.size())).
2534 second) {
2535 sal_uInt32 k = static_cast< sal_uInt32 >(parameters.size() - 1);
2536 out << indent()
2537 << "::css::uno::Type const & the_ptype" << k
2538 << " = ::cppu::getTypeFavourChar(static_cast< ";
2539 dumpTypeParameterName(out, member.type);
2540 out << " * >(0));\n" << indent()
2541 << "::typelib_TypeClass the_pclass" << k
2542 << " = (::typelib_TypeClass) the_ptype" << k
2543 << ".getTypeClass();\n" << indent()
2544 << "::rtl::OUString the_pname" << k << "(the_ptype" << k
2545 << ".getTypeName());\n";
2547 } else if (types.emplace(member.type, static_cast< sal_uInt32 >(types.size())).
2548 second) {
2549 dumpCppuGetType(out, member.type, &name_);
2550 // For typedefs, use the resolved type name, as there will be no
2551 // information available about the typedef itself at runtime (the
2552 // above getCppuType call will make available information about the
2553 // resolved type); no extra #include for the resolved type is
2554 // needed, as the header for the typedef includes it already:
2555 out << indent() << "::rtl::OUString the_tname"
2556 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2557 << resolveAllTypedefs(member.type) << "\" );\n";
2559 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2560 << member.name << "\" );\n";
2562 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2563 inc();
2564 n = 0;
2565 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2566 const_iterator i(entity_->getMembers().begin());
2567 i != entity_->getMembers().end();) {
2568 out << indent() << "{ { ";
2569 if (i->parameterized) {
2570 sal_uInt32 k = parameters.find(i->type)->second;
2571 out << "the_pclass" << k << ", the_pname" << k << ".pData";
2572 } else {
2573 out << getTypeClass(i->type, true) << ", the_tname"
2574 << types.find(i->type)->second << ".pData";
2576 out << ", the_name" << n++ << ".pData }, "
2577 << (i->parameterized ? "true" : "false") << " }";
2578 ++i;
2579 out << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2581 dec();
2582 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2583 out << indent()
2584 << ("::typelib_typedescription_newStruct(&the_newType, the_name.pData,"
2585 " 0, ")
2586 << entity_->getMembers().size() << ", the_members);\n" << indent()
2587 << "::typelib_typedescription_register(&the_newType);\n" << indent()
2588 << "::typelib_typedescription_release(the_newType);\n" << indent()
2589 << "return new ::css::uno::Type(" << getTypeClass(name_)
2590 << ", the_name); // leaked\n";
2591 dec();
2592 out << indent() << "}\n";
2593 dec();
2594 out << indent() << "};\n } }\n\n";
2595 dumpGetCppuTypePreamble(out);
2596 out << indent() << "return *detail::" << staticTypeClass;
2597 dumpTemplateParameters(out);
2598 out << "::get();\n";
2599 dumpGetCppuTypePostamble(out);
2602 void PolyStructType::addLightGetCppuTypeIncludes(
2603 codemaker::cppumaker::Includes & includes) const
2605 includes.addType();
2606 includes.addCppuUnotypeHxx();
2607 includes.addSalTypesH();
2608 includes.addTypelibTypeclassH();
2609 includes.addTypelibTypedescriptionH();
2610 includes.addRtlStrbufHxx();
2611 includes.addRtlTextencH();
2612 includes.addRtlUstringHxx();
2615 void PolyStructType::addNormalGetCppuTypeIncludes(
2616 codemaker::cppumaker::Includes & includes) const
2618 includes.addType();
2619 includes.addCppuUnotypeHxx();
2620 includes.addSalTypesH();
2621 includes.addTypelibTypeclassH();
2622 includes.addTypelibTypedescriptionH();
2623 includes.addRtlStrbufHxx();
2624 includes.addRtlTextencH();
2625 includes.addRtlUstringHxx();
2628 void PolyStructType::addComprehensiveGetCppuTypeIncludes(
2629 codemaker::cppumaker::Includes & includes) const
2631 includes.addType();
2632 includes.addCppuUnotypeHxx();
2633 includes.addRtlInstanceHxx();
2634 includes.addRtlUstringH();
2635 includes.addRtlUstringHxx();
2636 includes.addSalTypesH();
2637 includes.addTypelibTypeclassH();
2638 includes.addTypelibTypedescriptionH();
2639 includes.addRtlStringH();
2640 includes.addRtlUstrbufHxx();
2643 void PolyStructType::dumpTemplateHead(FileStream & out) const
2645 out << "template< ";
2646 for (std::vector< OUString >::const_iterator i(
2647 entity_->getTypeParameters().begin());
2648 i != entity_->getTypeParameters().end(); ++i) {
2649 if (i != entity_->getTypeParameters().begin()) {
2650 out << ", ";
2652 out << "typename ";
2653 dumpTypeParameterName(out, *i);
2655 out << " > ";
2658 void PolyStructType::dumpTemplateParameters(FileStream & out) const
2660 out << "< ";
2661 for (std::vector< OUString >::const_iterator i(
2662 entity_->getTypeParameters().begin());
2663 i != entity_->getTypeParameters().end(); ++i) {
2664 if (i != entity_->getTypeParameters().begin()) {
2665 out << ", ";
2667 dumpTypeParameterName(out, *i);
2669 out << " >";
2672 OUString typeToIdentifier(OUString const & name)
2674 sal_Int32 k;
2675 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k)));
2676 OUStringBuffer b;
2677 for (sal_Int32 i = 0; i != k; ++i) {
2678 b.append("seq_");
2680 b.append(n);
2681 b.replace(' ', '_');
2682 b.replace(',', '_');
2683 b.replace('.', '_');
2684 b.replace('<', '_');
2685 b.replace('>', '_');
2686 return b.makeStringAndClear();
2689 class ExceptionType: public CppuType
2691 public:
2692 ExceptionType(
2693 rtl::Reference< unoidl::ExceptionTypeEntity > const & entity,
2694 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2695 CppuType(name, typeMgr), entity_(entity) {
2696 assert(entity.is());
2699 private:
2700 virtual void dumpHppFile(
2701 FileStream & out, codemaker::cppumaker::Includes & includes) override;
2703 virtual void addComprehensiveGetCppuTypeIncludes(
2704 codemaker::cppumaker::Includes & includes) const override;
2706 virtual void dumpLightGetCppuType(FileStream & out) override;
2708 virtual void dumpNormalGetCppuType(FileStream & out) override;
2710 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2712 virtual sal_uInt32 checkInheritedMemberCount() const override {
2713 return getTotalMemberCount(entity_->getDirectBase());
2716 virtual void dumpDeclaration(FileStream & out) override;
2718 bool dumpBaseMembers(
2719 FileStream & out, OUString const & base, bool withType,
2720 bool eligibleForDefaults);
2722 sal_uInt32 getTotalMemberCount(OUString const & base) const;
2724 rtl::Reference< unoidl::ExceptionTypeEntity > entity_;
2727 void ExceptionType::addComprehensiveGetCppuTypeIncludes(
2728 codemaker::cppumaker::Includes & includes) const
2730 includes.addCppuUnotypeHxx();
2731 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
2734 void ExceptionType::dumpHppFile(
2735 FileStream & out, codemaker::cppumaker::Includes & includes)
2737 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
2738 out << "\n";
2739 addDefaultHxxIncludes(includes);
2740 includes.dump(out, &name_, true);
2742 // for the output operator below
2743 if (name_ == "com.sun.star.uno.Exception")
2745 out << "#if defined LIBO_INTERNAL_ONLY\n";
2746 out << "#include <ostream>\n";
2747 out << "#include <typeinfo>\n";
2748 out << "#endif\n";
2751 out << "\n";
2753 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2754 out << "\n";
2756 out << "\ninline " << id_ << "::" << id_ << "()\n";
2757 inc();
2758 OUString base(entity_->getDirectBase());
2759 bool bFirst = true;
2760 if (!base.isEmpty()) {
2761 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2762 << "()\n";
2763 bFirst = false;
2765 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2766 out << indent() << (bFirst ? ":" : ",") << " ";
2767 out << member.name;
2768 dumpInitializer(out, false, member.type);
2769 out << "\n";
2770 bFirst = false;
2772 dec();
2773 out << "{";
2774 if (!m_cppuTypeDynamic) {
2775 out << "\n";
2776 inc();
2777 dumpCppuGetType(out, name_);
2778 dec();
2779 } else {
2780 out << " ";
2782 out << "}\n\n";
2783 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
2784 out << indent() << "inline " << id_ << "::" << id_ << "(";
2785 bFirst = !dumpBaseMembers(out, base, true, false);
2786 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2787 if (!bFirst) {
2788 out << ", ";
2790 dumpType(out, member.type, true, true);
2791 out << " " << member.name << "_";
2792 bFirst = false;
2794 out << ")\n";
2795 inc();
2796 bFirst = true;
2797 if (!base.isEmpty()) {
2798 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2799 << "(";
2800 dumpBaseMembers(out, base, false, false);
2801 out << ")\n";
2802 bFirst = false;
2804 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2805 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
2806 << member.name << "_)\n";
2807 bFirst = false;
2809 dec();
2810 out << "{";
2811 if (!m_cppuTypeDynamic) {
2812 out << "\n";
2813 inc();
2814 dumpCppuGetType(out, name_);
2815 dec();
2816 } else {
2817 out << " ";
2819 out << "}\n\n";
2821 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent() << id_ << "::" << id_
2822 << "(" << id_ << " const & the_other)";
2823 bFirst = true;
2824 if (!base.isEmpty()) {
2825 out << ": " << codemaker::cpp::scopedCppName(u2b(base))
2826 << "(the_other)";
2827 bFirst = false;
2829 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2830 out << (bFirst ? ":" : ",") << " " << member.name << "(the_other." << member.name
2831 << ")";
2832 bFirst = false;
2834 out << indent() << " {}\n\n" << indent() << id_ << "::~" << id_
2835 << "() {}\n\n" << indent() << id_ << " & " << id_ << "::operator =("
2836 << id_ << " const & the_other) {\n";
2837 inc();
2838 out << indent()
2839 << ("//TODO: Just like its implicitly-defined counterpart, this"
2840 " function definition is not exception-safe\n");
2841 if (!base.isEmpty()) {
2842 out << indent() << codemaker::cpp::scopedCppName(u2b(base))
2843 << "::operator =(the_other);\n";
2845 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2846 out << indent() << member.name << " = the_other." << member.name << ";\n";
2848 out << indent() << "return *this;\n";
2849 dec();
2850 out << indent() << "}\n#endif\n\n";
2852 // Provide an output operator for printing Exception information to SAL_WARN/SAL_INFO.
2853 if (name_ == "com.sun.star.uno.Exception")
2855 out << "#if defined LIBO_INTERNAL_ONLY\n";
2856 out << "template< typename charT, typename traits >\n";
2857 out << "inline ::std::basic_ostream<charT, traits> & operator<<(\n";
2858 out << " ::std::basic_ostream<charT, traits> & os, ::com::sun::star::uno::Exception const & exception)\n";
2859 out << "{\n";
2860 out << " // the class name is useful because exception throwing code does not always pass in a useful message\n";
2861 out << " os << typeid(exception).name();\n";
2862 out << " if (!exception.Message.isEmpty())\n";
2863 out << " os << \" msg: \" << exception.Message;\n";
2864 out << " return os;\n";
2865 out << "}\n";
2866 out << "#endif\n";
2867 out << "\n";
2870 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2871 out << "\n";
2873 out << "\n";
2875 dumpGetCppuType(out);
2876 out << "\n#endif // "<< headerDefine << "\n";
2879 void ExceptionType::dumpLightGetCppuType(FileStream & out)
2881 dumpGetCppuTypePreamble(out);
2882 out << indent()
2883 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
2884 << indent() << "if ( !the_type )\n" << indent() << "{\n";
2885 inc();
2886 out << indent() << "typelib_static_type_init( &the_type, "
2887 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
2888 dec();
2889 out << indent() << "}\n" << indent()
2890 << ("return * reinterpret_cast< ::css::uno::Type * >("
2891 " &the_type );\n");
2892 dumpGetCppuTypePostamble(out);
2895 void ExceptionType::dumpNormalGetCppuType(FileStream & out)
2897 dumpGetCppuTypePreamble(out);
2898 out << indent()
2899 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
2900 << indent() << "if ( !the_type )\n" << indent() << "{\n";
2901 inc();
2902 OUString base(entity_->getDirectBase());
2903 bool baseException = false;
2904 if (!base.isEmpty()) {
2905 if (base == "com.sun.star.uno.Exception") {
2906 baseException = true;
2907 } else {
2908 out << indent()
2909 << ("const ::css::uno::Type& rBaseType ="
2910 " ::cppu::UnoType< ");
2911 dumpType(out, base, true, false, false, true);
2912 out << " >::get();\n\n";
2915 if (!entity_->getDirectMembers().empty()) {
2916 out << indent() << "typelib_TypeDescriptionReference * aMemberRefs["
2917 << entity_->getDirectMembers().size() << "];\n";
2918 std::set< OUString > seen;
2919 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
2920 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2921 OUString type(resolveAllTypedefs(member.type));
2922 OUString modType(typeToIdentifier(type));
2923 if (seen.insert(type).second) {
2924 out << indent()
2925 << "const ::css::uno::Type& rMemberType_"
2926 << modType << " = ::cppu::UnoType< ";
2927 dumpType(out, type, false, false, false, true);
2928 out << " >::get();\n";
2930 out << indent() << "aMemberRefs[" << n++ << "] = rMemberType_"
2931 << modType << ".getTypeLibType();\n";
2933 out << "\n";
2935 out << indent() << "typelib_static_compound_type_init( &the_type, "
2936 << getTypeClass(name_, true) << ", \"" << name_ << "\", ";
2937 if (baseException) {
2938 out << ("* ::typelib_static_type_getByTypeClass("
2939 " typelib_TypeClass_EXCEPTION )");
2940 } else if (base.isEmpty()) {
2941 out << "0";
2942 } else {
2943 out << "rBaseType.getTypeLibType()";
2945 out << ", " << entity_->getDirectMembers().size() << ", "
2946 << (entity_->getDirectMembers().empty() ? "0" : "aMemberRefs")
2947 << " );\n";
2948 dec();
2949 out << indent() << "}\n" << indent()
2950 << ("return * reinterpret_cast< const ::css::uno::Type * >("
2951 " &the_type );\n");
2952 dumpGetCppuTypePostamble(out);
2955 void ExceptionType::dumpComprehensiveGetCppuType(FileStream & out)
2957 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
2958 out << " namespace detail {\n\n";
2959 OUString staticTypeClass("the" + id_ + "Type");
2960 out << indent() << "struct " << staticTypeClass
2961 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2962 << staticTypeClass << " >\n" << indent() << "{\n";
2963 inc();
2964 out << indent() << "::css::uno::Type * operator()() const\n"
2965 << indent() << "{\n";
2966 inc();
2967 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
2968 << indent() << "// Start inline typedescription generation\n"
2969 << indent() << "typelib_TypeDescription * pTD = 0;\n";
2970 OUString base(entity_->getDirectBase());
2971 if (!base.isEmpty()) {
2972 out << indent()
2973 << ("const ::css::uno::Type& rSuperType ="
2974 " ::cppu::UnoType< ");
2975 dumpType(out, base, false, false, false, true);
2976 out << " >::get();\n";
2978 std::set< OUString > seen;
2979 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2980 if (seen.insert(member.type).second) {
2981 dumpCppuGetType(out, member.type);
2984 if (!entity_->getDirectMembers().empty()) {
2985 out << "\n" << indent() << "typelib_CompoundMember_Init aMembers["
2986 << entity_->getDirectMembers().size() << "];\n";
2987 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
2988 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2989 OUString type(resolveAllTypedefs(member.type));
2990 out << indent() << "::rtl::OUString sMemberType" << n << "( \""
2991 << type << "\" );\n" << indent()
2992 << "::rtl::OUString sMemberName" << n << "( \"" << member.name
2993 << "\" );\n" << indent() << "aMembers[" << n
2994 << "].eTypeClass = (typelib_TypeClass)" << getTypeClass(type)
2995 << ";\n" << indent() << "aMembers[" << n
2996 << "].pTypeName = sMemberType" << n << ".pData;\n" << indent()
2997 << "aMembers[" << n << "].pMemberName = sMemberName" << n
2998 << ".pData;\n";
2999 ++n;
3002 out << "\n" << indent() << "typelib_typedescription_new(\n";
3003 inc();
3004 out << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)"
3005 << getTypeClass(name_) << ", sTypeName.pData,\n" << indent()
3006 << (base.isEmpty() ? "0" : "rSuperType.getTypeLibType()") << ",\n"
3007 << indent() << entity_->getDirectMembers().size() << ",\n" << indent()
3008 << (entity_->getDirectMembers().empty() ? "0" : "aMembers")
3009 << " );\n\n";
3010 dec();
3011 out << indent()
3012 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3013 " );\n\n")
3014 << indent() << "typelib_typedescription_release( pTD );\n" << indent()
3015 << "// End inline typedescription generation\n\n" << indent()
3016 << "return new ::css::uno::Type( " << getTypeClass(name_)
3017 << ", sTypeName ); // leaked\n";
3018 dec();
3019 out << indent() << "}\n";
3020 dec();
3021 out << indent() << "};\n\n";
3022 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
3023 out << " }\n\n";
3024 dumpGetCppuTypePreamble(out);
3025 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
3026 dumpGetCppuTypePostamble(out);
3029 void ExceptionType::dumpDeclaration(FileStream & out)
3031 out << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT " << id_;
3032 OUString base(entity_->getDirectBase());
3033 if (!base.isEmpty()) {
3034 out << " : public " << codemaker::cpp::scopedCppName(u2b(base));
3036 out << "\n{\npublic:\n";
3037 inc();
3038 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3039 << "();\n\n";
3040 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
3041 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(";
3042 bool eligibleForDefaults = entity_->getDirectMembers().empty();
3043 bool bFirst = !dumpBaseMembers(out, base, true, eligibleForDefaults);
3044 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3045 if (!bFirst) {
3046 out << ", ";
3048 dumpType(out, member.type, true, true);
3049 out << " " << member.name << "_";
3050 bFirst = false;
3052 out << ");\n\n";
3054 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent()
3055 << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(" << id_
3056 << " const &);\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE ~"
3057 << id_ << "();\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3058 << " & operator =(" << id_ << " const &);\n#endif\n\n";
3059 for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
3060 entity_->getDirectMembers().begin());
3061 i != entity_->getDirectMembers().end(); ++i) {
3062 out << indent();
3063 dumpType(out, i->type);
3064 out << " " << i->name;
3065 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
3066 && i->type != "hyper" && i->type != "unsigned hyper"
3067 && i->type != "double") {
3068 out << " CPPU_GCC3_ALIGN( "
3069 << codemaker::cpp::scopedCppName(u2b(base)) << " )";
3071 out << ";\n";
3073 dec();
3074 out << "};\n\n";
3077 bool ExceptionType::dumpBaseMembers(
3078 FileStream & out, OUString const & base, bool withType, bool eligibleForDefaults)
3080 bool hasMember = false;
3081 if (!base.isEmpty()) {
3082 rtl::Reference< unoidl::Entity > ent;
3083 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3084 if (sort != codemaker::UnoType::Sort::Exception) {
3085 throw CannotDumpException(
3086 "exception type base " + base + " is not an exception type");
3088 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
3089 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()));
3090 assert(ent2.is());
3091 if (!ent2.is()) {
3092 return false;
3094 hasMember = dumpBaseMembers( out, ent2->getDirectBase(), withType,
3095 eligibleForDefaults && ent2->getDirectMembers().empty() );
3096 int memberCount = 0;
3097 for (const unoidl::ExceptionTypeEntity::Member& member : ent2->getDirectMembers()) {
3098 if (hasMember) {
3099 out << ", ";
3101 if (withType) {
3102 dumpType(out, member.type, true, true);
3103 out << " ";
3105 out << member.name << "_";
3106 // We want to provide a default parameter value for uno::Exception subtype
3107 // constructors, since most of the time we don't pass a Context object in to the exception
3108 // throw sites.
3109 if (eligibleForDefaults
3110 && base == "com.sun.star.uno.Exception"
3111 && memberCount == 1
3112 && member.name == "Context"
3113 && member.type == "com.sun.star.uno.XInterface") {
3114 out << " = ::css::uno::Reference< ::css::uno::XInterface >()";
3116 hasMember = true;
3117 ++memberCount;
3120 return hasMember;
3123 sal_uInt32 ExceptionType::getTotalMemberCount(OUString const & base) const
3125 if (base.isEmpty()) {
3126 return 0;
3128 rtl::Reference< unoidl::Entity > ent;
3129 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3130 if (sort != codemaker::UnoType::Sort::Exception) {
3131 throw CannotDumpException(
3132 "exception type base " + base + " is not an exception type");
3134 unoidl::ExceptionTypeEntity& ent2(
3135 dynamic_cast< unoidl::ExceptionTypeEntity&>(*ent.get()));
3136 return getTotalMemberCount(ent2.getDirectBase())
3137 + ent2.getDirectMembers().size(); //TODO: overflow
3140 class EnumType: public CppuType
3142 public:
3143 EnumType(
3144 rtl::Reference< unoidl::EnumTypeEntity > const & entity,
3145 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3146 CppuType(name, typeMgr), entity_(entity) {
3147 assert(entity.is());
3150 private:
3151 virtual void dumpDeclaration(FileStream& o) override;
3153 virtual void addComprehensiveGetCppuTypeIncludes(
3154 codemaker::cppumaker::Includes & includes) const override;
3156 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3158 void dumpNormalGetCppuType(FileStream& o) override;
3159 void dumpComprehensiveGetCppuType(FileStream& o) override;
3161 rtl::Reference< unoidl::EnumTypeEntity > entity_;
3164 void EnumType::addComprehensiveGetCppuTypeIncludes(
3165 codemaker::cppumaker::Includes & includes) const
3167 includes.addCppuUnotypeHxx();
3168 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
3171 void EnumType::dumpDeclaration(FileStream& o)
3173 o << "\n#if defined LIBO_INTERNAL_ONLY\n";
3174 o << "\nenum class SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3175 o << "\n#else\n";
3176 o << "\nenum SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3177 o << "\n#endif\n";
3178 inc();
3180 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3181 o << indent() << id_ << "_" << u2b(member.name) << " = " << member.value
3182 << ",\n";
3185 o << indent() << id_ << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3187 dec();
3188 o << "};\n\n";
3190 // use constexpr to create a kind of type-alias so we don't have to modify existing code
3191 o << "#if defined LIBO_INTERNAL_ONLY\n";
3192 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3193 o << "constexpr auto " << id_ << "_" << u2b(member.name)
3194 << " = "
3195 << id_ << "::" << id_ << "_" << u2b(member.name)
3196 << ";\n";
3198 o << "#endif\n";
3201 void EnumType::dumpHppFile(
3202 FileStream& o, codemaker::cppumaker::Includes & includes)
3204 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3205 o << "\n";
3207 addDefaultHxxIncludes(includes);
3208 includes.dump(o, &name_, true);
3209 o << "\n";
3211 dumpGetCppuType(o);
3213 o << "\n#endif // "<< headerDefine << "\n";
3216 void EnumType::dumpNormalGetCppuType(FileStream& o)
3218 dumpGetCppuTypePreamble(o);
3220 o << indent()
3221 << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3223 o << indent() << "if ( !the_type )\n" << indent() << "{\n";
3224 inc();
3226 o << indent() << "typelib_static_enum_type_init( &the_type,\n";
3227 inc(31);
3228 o << indent() << "\"" << name_ << "\",\n"
3229 << indent() << codemaker::cpp::scopedCppName(u2b(name_)) << "_"
3230 << u2b(entity_->getMembers()[0].name) << " );\n";
3231 dec(31);
3232 dec();
3233 o << indent() << "}\n";
3234 o << indent()
3235 << ("return * reinterpret_cast< ::css::uno::Type * >("
3236 " &the_type );\n");
3237 dumpGetCppuTypePostamble(o);
3240 void EnumType::dumpComprehensiveGetCppuType(FileStream& o)
3242 if (!isPolymorphic())
3243 codemaker::cppumaker::dumpNamespaceOpen(o, name_, false);
3244 else
3245 o << "namespace cppu { ";
3246 o << " namespace detail {\n\n";
3248 OUString sStaticTypeClass("the" + id_ + "Type");
3249 o << indent() << "struct " << sStaticTypeClass << " : public rtl::StaticWithInit< ::css::uno::Type *, " << sStaticTypeClass << " >\n";
3250 o << indent() << "{\n";
3251 inc();
3252 o << indent() << "::css::uno::Type * operator()() const\n";
3253 o << indent() << "{\n";
3255 inc();
3256 o << indent() << "::rtl::OUString sTypeName( \"" << name_
3257 << "\" );\n\n";
3259 o << indent() << "// Start inline typedescription generation\n"
3260 << indent() << "typelib_TypeDescription * pTD = 0;\n\n";
3262 o << indent() << "rtl_uString* enumValueNames["
3263 << entity_->getMembers().size() << "];\n";
3264 std::vector< unoidl::EnumTypeEntity::Member >::size_type n = 0;
3265 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3266 o << indent() << "::rtl::OUString sEnumValue" << n << "( \""
3267 << u2b(member.name) << "\" );\n";
3268 o << indent() << "enumValueNames[" << n << "] = sEnumValue" << n
3269 << ".pData;\n";
3270 ++n;
3273 o << "\n" << indent() << "sal_Int32 enumValues["
3274 << entity_->getMembers().size() << "];\n";
3275 n = 0;
3276 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3277 o << indent() << "enumValues[" << n++ << "] = " << member.value << ";\n";
3280 o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3281 inc();
3282 o << indent() << "sTypeName.pData,\n"
3283 << indent() << "(sal_Int32)"
3284 << codemaker::cpp::scopedCppName(u2b(name_), false) << "_"
3285 << u2b(entity_->getMembers()[0].name) << ",\n"
3286 << indent() << entity_->getMembers().size()
3287 << ", enumValueNames, enumValues );\n\n";
3288 dec();
3290 o << indent()
3291 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3292 " );\n");
3293 o << indent() << "typelib_typedescription_release( pTD );\n"
3294 << indent() << "// End inline typedescription generation\n\n";
3296 o << indent() << "return new ::css::uno::Type( "
3297 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
3299 dec();
3300 o << indent() << "}\n";
3301 dec();
3302 o << indent() << "};\n\n";
3304 if (!isPolymorphic())
3305 codemaker::cppumaker::dumpNamespaceClose(o, name_, false);
3306 else
3307 o << " }";
3308 o << " }\n\n";
3310 dumpGetCppuTypePreamble(o);
3311 o << indent() << "return *detail::" << sStaticTypeClass << "::get();\n";
3312 dumpGetCppuTypePostamble(o);
3315 class Typedef: public CppuType
3317 public:
3318 Typedef(
3319 rtl::Reference< unoidl::TypedefEntity > const & entity,
3320 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3321 CppuType(name, typeMgr), entity_(entity) {
3322 assert(entity.is());
3325 private:
3326 virtual void dumpDeclaration(FileStream& o) override;
3328 void dumpHdlFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3330 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3332 rtl::Reference< unoidl::TypedefEntity > entity_;
3335 void Typedef::dumpHdlFile(
3336 FileStream& o, codemaker::cppumaker::Includes & includes)
3338 OUString headerDefine(dumpHeaderDefine(o, "HDL"));
3339 o << "\n";
3341 addDefaultHIncludes(includes);
3342 includes.dump(o, nullptr, true);
3343 o << "\n";
3345 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3346 o << "\n";
3349 dumpDeclaration(o);
3351 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3352 o << "\n";
3355 o << "#endif // "<< headerDefine << "\n";
3358 void Typedef::dumpDeclaration(FileStream& o)
3360 o << "\ntypedef ";
3361 dumpType(o, entity_->getType());
3362 o << " " << id_ << ";\n\n";
3365 void Typedef::dumpHppFile(
3366 FileStream& o, codemaker::cppumaker::Includes & includes)
3368 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3369 o << "\n";
3371 addDefaultHxxIncludes(includes);
3372 includes.dump(o, &name_, true);
3373 o << "\n";
3375 o << "\n#endif // "<< headerDefine << "\n";
3378 class ConstructiveType: public CppuType
3380 public:
3381 ConstructiveType(
3382 OUString const & name, rtl::Reference< TypeManager > const & manager):
3383 CppuType(name, manager) {}
3385 private:
3386 virtual void dumpHdlFile(FileStream &, codemaker::cppumaker::Includes &) override {
3387 assert(false); // this cannot happen
3390 virtual void dumpFiles(OUString const & uri, CppuOptions const & options) override {
3391 dumpFile(uri, name_, true, options);
3395 bool hasRestParameter(
3396 unoidl::SingleInterfaceBasedServiceEntity::Constructor const & constructor)
3398 return !constructor.parameters.empty()
3399 && constructor.parameters.back().rest;
3402 void includeExceptions(
3403 codemaker::cppumaker::Includes & includes,
3404 codemaker::ExceptionTreeNode const * node)
3406 if (node->present) {
3407 includes.add(node->name);
3408 } else {
3409 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3410 includeExceptions(includes, pChild.get());
3415 class ServiceType: public ConstructiveType
3417 public:
3418 ServiceType(
3419 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const &
3420 entity,
3421 OUString const & name, rtl::Reference< TypeManager > const & manager):
3422 ConstructiveType(name, manager), entity_(entity) {
3423 assert(entity.is());
3426 private:
3427 virtual void dumpHppFile(
3428 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3430 void dumpCatchClauses(
3431 FileStream & out, codemaker::ExceptionTreeNode const * node);
3433 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > entity_;
3436 void failsToSupply(
3437 FileStream & o, OUString const & service, OString const & type)
3439 o << "::rtl::OUString(\"component context fails to supply service \") + \""
3440 << service << "\" + \" of type \" + \"" << type << "\"";
3443 void ServiceType::dumpHppFile(
3444 FileStream & o, codemaker::cppumaker::Includes & includes)
3446 if (!entity_->getConstructors().empty()) {
3447 //TODO: Decide whether the types added to includes should rather be
3448 // added to m_dependencies (and thus be generated during
3449 // dumpDependedTypes):
3450 includes.addCassert();
3451 includes.addReference();
3452 includes.addRtlUstringH();
3453 includes.addRtlUstringHxx();
3454 includes.add("com.sun.star.uno.DeploymentException");
3455 includes.add("com.sun.star.uno.XComponentContext");
3456 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor& cons : entity_->getConstructors()) {
3457 if (cons.defaultConstructor) {
3458 includes.add("com.sun.star.uno.Exception");
3459 includes.add("com.sun.star.uno.RuntimeException");
3460 } else {
3461 if (!hasRestParameter(cons)) {
3462 includes.addAny();
3463 includes.addSequence();
3464 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3465 cons.parameters) {
3466 if (m_typeMgr->getSort(
3467 b2u(codemaker::UnoType::decompose(
3468 u2b(param.type))))
3469 == codemaker::UnoType::Sort::Char) {
3470 includes.addCppuUnotypeHxx();
3471 break;
3475 codemaker::ExceptionTree tree;
3476 for (const OUString& ex : cons.exceptions) {
3477 tree.add(u2b(ex), m_typeMgr);
3479 if (!tree.getRoot().present) {
3480 includes.add("com.sun.star.uno.Exception");
3481 includes.add("com.sun.star.uno.RuntimeException");
3482 includeExceptions(includes, &tree.getRoot());
3487 OString cppName(
3488 codemaker::cpp::translateUnoToCppIdentifier(
3489 u2b(id_), "service", isGlobal()));
3490 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3491 o << "\n";
3492 includes.dump(o, nullptr, true);
3493 if (!entity_->getConstructors().empty()) {
3494 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3495 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3496 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3497 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3498 << name_.replaceAll(".", "_dot_")
3499 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3500 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3501 << name_.replaceAll(".", "_dot_")
3502 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3503 << name_.replaceAll(".", "_dot_")
3504 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3505 "::css::uno::Any > const &);\n#endif\n";
3507 o << "\n";
3508 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3509 o << "\n";
3511 o << "\nclass " << cppName << " {\n";
3512 inc();
3513 if (!entity_->getConstructors().empty()) {
3514 OString baseName(u2b(entity_->getBase()));
3515 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3516 o << "public:\n";
3517 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor& cons :
3518 entity_->getConstructors()) {
3519 if (cons.defaultConstructor) {
3520 o << indent() << "static ::css::uno::Reference< "
3521 << scopedBaseName << " > "
3522 << codemaker::cpp::translateUnoToCppIdentifier(
3523 "create", "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal,
3524 &cppName)
3525 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3526 " the_context) {\n");
3527 inc();
3528 o << indent() << "assert(the_context.is());\n" << indent()
3529 << "::css::uno::Reference< " << scopedBaseName
3530 << " > the_instance;\n" << indent() << "try {\n";
3531 inc();
3532 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3533 "LO_URE_CTOR_ENV_")
3534 << name_.replaceAll(".", "_dot_")
3535 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3536 << name_.replaceAll(".", "_dot_")
3537 << ") && defined LO_URE_CTOR_FUN_"
3538 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3539 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3540 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3541 "static_cast< ::css::uno::XInterface * >((*"
3542 "LO_URE_CTOR_FUN_")
3543 << name_.replaceAll(".", "_dot_")
3544 << (")(the_context.get(), ::css::uno::Sequence<"
3545 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3546 " ::css::uno::UNO_QUERY);\n#else\n")
3547 << indent() << "the_instance = ::css::uno::Reference< "
3548 << scopedBaseName
3549 << (" >(the_context->getServiceManager()->"
3550 "createInstanceWithContext("
3551 " \"")
3552 << name_
3553 << "\", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3554 dec();
3555 o << indent()
3556 << "} catch (const ::css::uno::RuntimeException &) {\n";
3557 inc();
3558 o << indent() << "throw;\n";
3559 dec();
3560 o << indent()
3561 << ("} catch (const ::css::uno::Exception & the_exception) {\n");
3562 inc();
3563 o << indent() << "throw ::css::uno::DeploymentException(";
3564 failsToSupply(o, name_, baseName);
3565 o << " + \": \" + the_exception.Message, the_context);\n";
3566 dec();
3567 o << indent() << "}\n" << indent()
3568 << "if (!the_instance.is()) {\n";
3569 inc();
3570 o << indent() << "throw ::css::uno::DeploymentException(";
3571 failsToSupply(o, name_, baseName);
3572 o << ", the_context);\n";
3573 dec();
3574 o << indent() << "}\n" << indent() << "return the_instance;\n";
3575 dec();
3576 o << indent() << "}\n\n";
3577 } else {
3578 o << indent() << "static ::css::uno::Reference< "
3579 << scopedBaseName << " > "
3580 << codemaker::cpp::translateUnoToCppIdentifier(
3581 u2b(cons.name), "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal,
3582 &cppName)
3583 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3584 " the_context");
3585 bool rest = hasRestParameter(cons);
3586 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3587 cons.parameters) {
3588 o << ", ";
3589 OUStringBuffer buf;
3590 if (param.rest) {
3591 buf.append("[]");
3593 buf.append(param.type);
3594 OUString type(buf.makeStringAndClear());
3595 bool byRef = passByReference(type);
3596 dumpType(o, type, byRef, byRef);
3597 o << " "
3598 << codemaker::cpp::translateUnoToCppIdentifier(
3599 u2b(param.name), "param", codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3601 o << ") {\n";
3602 inc();
3603 o << indent() << "assert(the_context.is());\n";
3604 if (!rest && !cons.parameters.empty()) {
3605 o << indent()
3606 << ("::css::uno::Sequence< ::css::uno::Any > the_arguments(")
3607 << cons.parameters.size() << ");\n";
3608 std::vector<
3609 unoidl::SingleInterfaceBasedServiceEntity::Constructor::
3610 Parameter >::size_type n = 0;
3611 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& j :
3612 cons.parameters) {
3613 o << indent() << "the_arguments[" << n++ << "] ";
3614 OString param(
3615 codemaker::cpp::translateUnoToCppIdentifier(
3616 u2b(j.name), "param",
3617 codemaker::cpp::IdentifierTranslationMode::NonGlobal));
3618 sal_Int32 rank;
3619 if (resolveOuterTypedefs(j.type) == "any") {
3620 o << "= " << param;
3621 } else if (m_typeMgr->getSort(
3622 b2u(codemaker::UnoType::decompose(
3623 u2b(j.type), &rank)))
3624 == codemaker::UnoType::Sort::Char) {
3625 o << "= ::css::uno::Any(&" << param
3626 << ", ::cppu::UnoType< ";
3627 for (sal_Int32 k = 0; k < rank; ++k) {
3628 o << "::cppu::UnoSequenceType< ";
3630 o << "::cppu::UnoCharType";
3631 for (sal_Int32 k = 0; k < rank; ++k) {
3632 o << " >";
3634 o << " >::get())";
3635 } else {
3636 o << "<<= " << param;
3638 o << ";\n";
3641 o << indent() << "::css::uno::Reference< "
3642 << scopedBaseName << " > the_instance;\n";
3643 codemaker::ExceptionTree tree;
3644 for (const OUString& ex : cons.exceptions) {
3645 tree.add(u2b(ex), m_typeMgr);
3647 if (!tree.getRoot().present) {
3648 o << indent() << "try {\n";
3649 inc();
3651 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3652 "LO_URE_CTOR_ENV_")
3653 << name_.replaceAll(".", "_dot_")
3654 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3655 << name_.replaceAll(".", "_dot_")
3656 << ") && defined LO_URE_CTOR_FUN_"
3657 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3658 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3659 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3660 "static_cast< ::css::uno::XInterface * >((*"
3661 "LO_URE_CTOR_FUN_")
3662 << name_.replaceAll(".", "_dot_")
3663 << ")(the_context.get(), ";
3664 if (rest) {
3665 o << codemaker::cpp::translateUnoToCppIdentifier(
3666 u2b(cons.parameters.back().name), "param",
3667 codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3668 } else if (cons.parameters.empty()) {
3669 o << "::css::uno::Sequence< ::css::uno::Any >()";
3670 } else {
3671 o << "the_arguments";
3673 o << ")), ::SAL_NO_ACQUIRE), ::css::uno::UNO_QUERY);\n" << indent()
3674 << ("::css::uno::Reference< ::css::lang::XInitialization > "
3675 "init(the_instance, ::css::uno::UNO_QUERY);\n")
3676 << indent() << "if (init.is()) {\n"
3677 << indent() << " init->initialize(";
3678 if (cons.parameters.empty()) {
3679 o << "::css::uno::Sequence< ::css::uno::Any >()";
3680 } else {
3681 o << "the_arguments";
3683 o << ");\n" << indent() << "}\n";
3684 o << ("#else\n")
3685 << indent() << "the_instance = ::css::uno::Reference< "
3686 << scopedBaseName
3687 << (" >(the_context->getServiceManager()->"
3688 "createInstanceWithArgumentsAndContext("
3689 " \"")
3690 << name_ << "\", ";
3691 if (rest) {
3692 o << codemaker::cpp::translateUnoToCppIdentifier(
3693 u2b(cons.parameters.back().name), "param",
3694 codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3695 } else if (cons.parameters.empty()) {
3696 o << ("::css::uno::Sequence< ::css::uno::Any >()");
3697 } else {
3698 o << "the_arguments";
3700 o << ", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3701 if (!tree.getRoot().present) {
3702 dec();
3703 o << indent()
3704 << ("} catch (const ::css::uno::RuntimeException &) {\n");
3705 inc();
3706 o << indent() << "throw;\n";
3707 dec();
3708 dumpCatchClauses(o, &tree.getRoot());
3709 o << indent()
3710 << ("} catch (const ::css::uno::Exception &"
3711 " the_exception) {\n");
3712 inc();
3713 o << indent() << "throw ::css::uno::DeploymentException(";
3714 failsToSupply(o, name_, baseName);
3715 o << " + \": \" + the_exception.Message, the_context);\n";
3716 dec();
3717 o << indent() << "}\n";
3719 o << indent() << "if (!the_instance.is()) {\n";
3720 inc();
3721 o << indent() << "throw ::css::uno::DeploymentException(";
3722 failsToSupply(o, name_, baseName);
3723 o << ", the_context);\n";
3724 dec();
3725 o << indent() << "}\n" << indent() << "return the_instance;\n";
3726 dec();
3727 o << indent() << "}\n\n";
3731 o << "private:\n";
3732 o << indent() << cppName << "(); // not implemented\n"
3733 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3734 << indent() << "~" << cppName << "(); // not implemented\n"
3735 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3736 dec();
3737 o << "};\n\n";
3738 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3739 o << "\n";
3741 o << "\n#endif // "<< headerDefine << "\n";
3744 void ServiceType::dumpCatchClauses(
3745 FileStream & out, codemaker::ExceptionTreeNode const * node)
3747 if (node->present) {
3748 out << indent() << "} catch (const ";
3749 dumpType(out, b2u(node->name));
3750 out << " &) {\n";
3751 inc();
3752 out << indent() << "throw;\n";
3753 dec();
3754 } else {
3755 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3756 dumpCatchClauses(out, pChild.get());
3761 class SingletonType: public ConstructiveType
3763 public:
3764 SingletonType(
3765 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > const & entity,
3766 OUString const & name, rtl::Reference< TypeManager > const & manager):
3767 ConstructiveType(name, manager), entity_(entity) {
3768 assert(entity.is());
3771 private:
3772 virtual void dumpHppFile(
3773 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3775 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > entity_;
3778 void SingletonType::dumpHppFile(
3779 FileStream & o, codemaker::cppumaker::Includes & includes)
3781 OString cppName(
3782 codemaker::cpp::translateUnoToCppIdentifier(
3783 u2b(id_), "singleton", isGlobal()));
3784 OString baseName(u2b(entity_->getBase()));
3785 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3786 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3787 o << "\n";
3788 //TODO: Decide whether the types added to includes should rather be added to
3789 // m_dependencies (and thus be generated during dumpDependedTypes):
3790 includes.add("com.sun.star.uno.DeploymentException");
3791 includes.add("com.sun.star.uno.XComponentContext");
3792 includes.addCassert();
3793 includes.addAny();
3794 includes.addReference();
3795 includes.addRtlUstringH();
3796 includes.addRtlUstringHxx();
3797 includes.dump(o, nullptr, true);
3798 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3799 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3800 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3801 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3802 << name_.replaceAll(".", "_dot_")
3803 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3804 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3805 << name_.replaceAll(".", "_dot_")
3806 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3807 << name_.replaceAll(".", "_dot_")
3808 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3809 "::css::uno::Any > const &);\n#endif\n";
3810 o << "\n";
3811 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3812 o << "\n";
3814 o << "\nclass " << cppName << " {\npublic:\n";
3815 inc();
3816 o << indent() << "static ::css::uno::Reference< "
3817 << scopedBaseName << " > "
3818 << codemaker::cpp::translateUnoToCppIdentifier(
3819 "get", "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal, &cppName)
3820 << ("(::css::uno::Reference<"
3821 " ::css::uno::XComponentContext > const & the_context)"
3822 " {\n");
3823 inc();
3824 o << indent() << "assert(the_context.is());\n" << indent()
3825 << "::css::uno::Reference< " << scopedBaseName
3826 << (" > instance;\n#if defined LO_URE_CURRENT_ENV && defined "
3827 "LO_URE_CTOR_ENV_")
3828 << name_.replaceAll(".", "_dot_")
3829 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3830 << name_.replaceAll(".", "_dot_")
3831 << ") && defined LO_URE_CTOR_FUN_"
3832 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3833 << "instance = ::css::uno::Reference< " << scopedBaseName
3834 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3835 "static_cast< ::css::uno::XInterface * >((*"
3836 "LO_URE_CTOR_FUN_")
3837 << name_.replaceAll(".", "_dot_")
3838 << (")(the_context.get(), ::css::uno::Sequence<"
3839 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3840 " ::css::uno::UNO_QUERY);\n#else\n")
3841 << indent() << ("the_context->getValueByName("
3842 "::rtl::OUString( \"/singletons/")
3843 << name_ << "\" )) >>= instance;\n#endif\n"
3844 << indent() << "if (!instance.is()) {\n";
3845 inc();
3846 o << indent()
3847 << ("throw ::css::uno::DeploymentException("
3848 "::rtl::OUString( \"component context"
3849 " fails to supply singleton ")
3850 << name_ << " of type " << baseName << "\" ), the_context);\n";
3851 dec();
3852 o << indent() << "}\n" << indent() << "return instance;\n";
3853 dec();
3854 o << indent() << "}\n\n";
3855 o << "private:\n";
3856 o << indent() << cppName << "(); // not implemented\n"
3857 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3858 << indent() << "~" << cppName << "(); // not implemented\n"
3859 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3860 dec();
3861 o << "};\n\n";
3862 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3863 o << "\n";
3865 o << "\n#endif // "<< headerDefine << "\n";
3870 void produce(
3871 OUString const & name, rtl::Reference< TypeManager > const & manager,
3872 codemaker::GeneratedTypeSet & generated, CppuOptions const & options)
3874 if (generated.contains(u2b(name))) {
3875 return;
3877 generated.add(u2b(name));
3878 if (!manager->foundAtPrimaryProvider(name)) {
3879 return;
3881 rtl::Reference< unoidl::Entity > ent;
3882 rtl::Reference< unoidl::MapCursor > cur;
3883 switch (manager->getSort(name, &ent, &cur)) {
3884 case codemaker::UnoType::Sort::Module: {
3885 OUString prefix;
3886 if (!name.isEmpty()) {
3887 prefix = name + ".";
3889 for (;;) {
3890 OUString mem;
3891 if (!cur->getNext(&mem).is()) {
3892 break;
3894 produce(prefix + mem, manager, generated, options);
3896 break;
3898 case codemaker::UnoType::Sort::Enum: {
3899 EnumType t(
3900 dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), name,
3901 manager);
3902 t.dump(options);
3903 t.dumpDependedTypes(generated, options);
3904 break;
3906 case codemaker::UnoType::Sort::PlainStruct: {
3907 PlainStructType t(
3908 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
3909 name, manager);
3910 t.dump(options);
3911 t.dumpDependedTypes(generated, options);
3912 break;
3914 case codemaker::UnoType::Sort::PolymorphicStructTemplate: {
3915 PolyStructType t(
3916 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
3917 ent.get()),
3918 name, manager);
3919 t.dump(options);
3920 t.dumpDependedTypes(generated, options);
3921 break;
3923 case codemaker::UnoType::Sort::Exception: {
3924 ExceptionType t(
3925 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()), name,
3926 manager);
3927 t.dump(options);
3928 t.dumpDependedTypes(generated, options);
3929 break;
3931 case codemaker::UnoType::Sort::Interface: {
3932 InterfaceType t(
3933 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()), name,
3934 manager);
3935 t.dump(options);
3936 t.dumpDependedTypes(generated, options);
3937 break;
3939 case codemaker::UnoType::Sort::Typedef: {
3940 Typedef t(
3941 dynamic_cast< unoidl::TypedefEntity * >(ent.get()), name,
3942 manager);
3943 t.dump(options);
3944 t.dumpDependedTypes(generated, options);
3945 break;
3947 case codemaker::UnoType::Sort::ConstantGroup: {
3948 ConstantGroup t(
3949 dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()), name,
3950 manager);
3951 if (t.hasConstants()) {
3952 t.dump(options);
3954 break;
3956 case codemaker::UnoType::Sort::SingleInterfaceBasedService: {
3957 ServiceType t(
3958 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
3959 ent.get()),
3960 name, manager);
3961 t.dump(options);
3962 t.dumpDependedTypes(generated, options);
3963 break;
3965 case codemaker::UnoType::Sort::InterfaceBasedSingleton: {
3966 SingletonType t(
3967 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
3968 ent.get()),
3969 name, manager);
3970 t.dump(options);
3971 t.dumpDependedTypes(generated, options);
3972 break;
3974 case codemaker::UnoType::Sort::AccumulationBasedService:
3975 case codemaker::UnoType::Sort::ServiceBasedSingleton:
3976 break;
3977 default:
3978 throw CannotDumpException(
3979 "unexpected entity \"" + name + "\" in call to produce");
3983 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */