lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / codemaker / source / cppumaker / cpputype.cxx
blob4b3face0c702ac0286f0f06968b05d6270091b86
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include <algorithm>
24 #include <cassert>
25 #include <cstdlib>
26 #include <map>
27 #include <set>
28 #include <memory>
29 #include <vector>
30 #include <iostream>
32 #include <rtl/alloc.h>
33 #include <rtl/ref.hxx>
34 #include <rtl/ustrbuf.hxx>
35 #include <rtl/ustring.hxx>
36 #include <rtl/strbuf.hxx>
37 #include <unoidl/unoidl.hxx>
39 #include <codemaker/commoncpp.hxx>
40 #include <codemaker/exceptiontree.hxx>
41 #include <codemaker/generatedtypeset.hxx>
42 #include <codemaker/typemanager.hxx>
43 #include <codemaker/unotype.hxx>
45 #include "cpputype.hxx"
46 #include "cppuoptions.hxx"
47 #include "dependencies.hxx"
48 #include "dumputils.hxx"
49 #include "includes.hxx"
51 namespace
54 bool isBootstrapType(OUString const & name)
56 static char const * const names[] = {
57 "com.sun.star.beans.Property",
58 "com.sun.star.beans.PropertyAttribute",
59 "com.sun.star.beans.PropertyChangeEvent",
60 "com.sun.star.beans.PropertyState",
61 "com.sun.star.beans.PropertyValue",
62 "com.sun.star.beans.XFastPropertySet",
63 "com.sun.star.beans.XMultiPropertySet",
64 "com.sun.star.beans.XPropertiesChangeListener",
65 "com.sun.star.beans.XPropertyAccess",
66 "com.sun.star.beans.XPropertyChangeListener",
67 "com.sun.star.beans.XPropertySet",
68 "com.sun.star.beans.XPropertySetInfo",
69 "com.sun.star.beans.XPropertySetOption",
70 "com.sun.star.beans.XVetoableChangeListener",
71 "com.sun.star.bridge.UnoUrlResolver",
72 "com.sun.star.bridge.XUnoUrlResolver",
73 "com.sun.star.connection.SocketPermission",
74 "com.sun.star.container.XElementAccess",
75 "com.sun.star.container.XEnumeration",
76 "com.sun.star.container.XEnumerationAccess",
77 "com.sun.star.container.XHierarchicalNameAccess",
78 "com.sun.star.container.XNameAccess",
79 "com.sun.star.container.XNameContainer",
80 "com.sun.star.container.XNameReplace",
81 "com.sun.star.container.XSet",
82 "com.sun.star.io.FilePermission",
83 "com.sun.star.io.IOException",
84 "com.sun.star.lang.DisposedException",
85 "com.sun.star.lang.EventObject",
86 "com.sun.star.lang.WrappedTargetRuntimeException",
87 "com.sun.star.lang.XComponent",
88 "com.sun.star.lang.XEventListener",
89 "com.sun.star.lang.XInitialization",
90 "com.sun.star.lang.XMultiComponentFactory",
91 "com.sun.star.lang.XMultiServiceFactory",
92 "com.sun.star.lang.XServiceInfo",
93 "com.sun.star.lang.XSingleComponentFactory",
94 "com.sun.star.lang.XSingleServiceFactory",
95 "com.sun.star.lang.XTypeProvider",
96 "com.sun.star.loader.XImplementationLoader",
97 "com.sun.star.reflection.FieldAccessMode",
98 "com.sun.star.reflection.MethodMode",
99 "com.sun.star.reflection.ParamInfo",
100 "com.sun.star.reflection.ParamMode",
101 "com.sun.star.reflection.TypeDescriptionSearchDepth",
102 "com.sun.star.reflection.XCompoundTypeDescription",
103 "com.sun.star.reflection.XEnumTypeDescription",
104 "com.sun.star.reflection.XIdlArray",
105 "com.sun.star.reflection.XIdlClass",
106 "com.sun.star.reflection.XIdlField",
107 "com.sun.star.reflection.XIdlField2",
108 "com.sun.star.reflection.XIdlMethod",
109 "com.sun.star.reflection.XIdlReflection",
110 "com.sun.star.reflection.XIndirectTypeDescription",
111 "com.sun.star.reflection.XInterfaceAttributeTypeDescription",
112 "com.sun.star.reflection.XInterfaceAttributeTypeDescription2",
113 "com.sun.star.reflection.XInterfaceMemberTypeDescription",
114 "com.sun.star.reflection.XInterfaceMethodTypeDescription",
115 "com.sun.star.reflection.XInterfaceTypeDescription",
116 "com.sun.star.reflection.XInterfaceTypeDescription2",
117 "com.sun.star.reflection.XMethodParameter",
118 "com.sun.star.reflection.XStructTypeDescription",
119 "com.sun.star.reflection.XTypeDescription",
120 "com.sun.star.reflection.XTypeDescriptionEnumeration",
121 "com.sun.star.reflection.XTypeDescriptionEnumerationAccess",
122 "com.sun.star.registry.RegistryKeyType",
123 "com.sun.star.registry.RegistryValueType",
124 "com.sun.star.registry.XImplementationRegistration",
125 "com.sun.star.registry.XRegistryKey",
126 "com.sun.star.registry.XSimpleRegistry",
127 "com.sun.star.security.RuntimePermission",
128 "com.sun.star.security.XAccessControlContext",
129 "com.sun.star.security.XAccessController",
130 "com.sun.star.security.XAction",
131 "com.sun.star.uno.DeploymentException",
132 "com.sun.star.uno.RuntimeException",
133 "com.sun.star.uno.TypeClass",
134 "com.sun.star.uno.Uik",
135 "com.sun.star.uno.XAdapter",
136 "com.sun.star.uno.XAggregation",
137 "com.sun.star.uno.XComponentContext",
138 "com.sun.star.uno.XCurrentContext",
139 "com.sun.star.uno.XInterface",
140 "com.sun.star.uno.XReference",
141 "com.sun.star.uno.XUnloadingPreference",
142 "com.sun.star.uno.XWeak",
143 "com.sun.star.util.XMacroExpander" };
144 // cf. cppuhelper/unotypes/Makefile UNOTYPES (plus missing dependencies)
145 for (std::size_t i = 0; i < SAL_N_ELEMENTS(names); ++i) {
146 if (name.equalsAscii(names[i])) {
147 return true;
150 return false;
153 class CppuType
155 public:
156 CppuType(
157 OUString const & name, rtl::Reference< TypeManager > const & typeMgr);
159 virtual ~CppuType() {}
161 CppuType(const CppuType&) = delete;
162 const CppuType& operator=(const CppuType&) = delete;
164 void dump(CppuOptions const & options);
166 void dumpFile(
167 OUString const & uri, OUString const & name, bool hpp,
168 CppuOptions const & options);
170 void dumpDependedTypes(
171 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const;
173 virtual void dumpHdlFile(
174 FileStream & out, codemaker::cppumaker::Includes & includes) {
175 dumpHFileContent(out, includes);
178 virtual void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) = 0;
180 OUString dumpHeaderDefine(FileStream& o, OUString const & extension) const;
182 void dumpGetCppuType(FileStream & out);
184 virtual void dumpLightGetCppuType(FileStream & out);
186 virtual void dumpNormalGetCppuType(FileStream &) {
187 assert(false); // this cannot happen
190 virtual void dumpComprehensiveGetCppuType(FileStream &) {
191 assert(false); // this cannot happen
194 void dumpType(
195 FileStream & out, OUString const & name, bool isConst = false,
196 bool isRef = false, bool native = false, bool cppuUnoType = false)
197 const;
199 OUString getTypeClass(OUString const & name, bool cStyle = false);
201 void dumpCppuGetType(
202 FileStream & out, OUString const & name, OUString const * ownName = nullptr) const;
204 sal_uInt32 getInheritedMemberCount();
206 void inc(sal_Int32 num=4);
207 void dec(sal_Int32 num=4);
208 OUString indent() const;
209 protected:
210 virtual sal_uInt32 checkInheritedMemberCount() const {
211 assert(false); // this cannot happen
212 return 0;
215 bool passByReference(OUString const & name) const;
217 bool canBeWarnUnused(OUString const & name) const;
218 bool canBeWarnUnused(OUString const & name, int depth) const;
220 OUString resolveOuterTypedefs(OUString const & name) const;
222 OUString resolveAllTypedefs(OUString const & name) const;
224 codemaker::cpp::IdentifierTranslationMode isGlobal() const;
226 virtual void dumpDeclaration(FileStream &) {
227 assert(false); // this cannot happen
230 virtual void dumpFiles(OUString const & uri, CppuOptions const & options);
232 virtual void addLightGetCppuTypeIncludes(
233 codemaker::cppumaker::Includes & includes) const;
235 virtual void addNormalGetCppuTypeIncludes(
236 codemaker::cppumaker::Includes & includes) const;
238 virtual void addComprehensiveGetCppuTypeIncludes(
239 codemaker::cppumaker::Includes & includes) const;
241 virtual bool isPolymorphic() const;
243 virtual void dumpTemplateHead(FileStream &) const {}
245 virtual void dumpTemplateParameters(FileStream &) const {}
247 void dumpGetCppuTypePreamble(FileStream & out);
249 void dumpGetCppuTypePostamble(FileStream & out);
251 void addDefaultHIncludes(codemaker::cppumaker::Includes & includes) const;
252 void addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) const;
254 void dumpInitializer(
255 FileStream & out, bool parameterized, OUString const & name) const;
257 void dumpHFileContent(
258 FileStream & out, codemaker::cppumaker::Includes & includes);
260 protected:
261 sal_uInt32 m_inheritedMemberCount;
263 bool m_cppuTypeLeak;
264 bool m_cppuTypeDynamic;
265 sal_Int32 m_indentLength;
266 OUString name_;
267 OUString id_;
268 rtl::Reference< TypeManager > m_typeMgr;
269 codemaker::cppumaker::Dependencies m_dependencies;
271 private:
272 void addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
273 const;
276 CppuType::CppuType(
277 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
278 m_inheritedMemberCount(0)
279 , m_cppuTypeLeak(false)
280 , m_cppuTypeDynamic(true)
281 , m_indentLength(0)
282 , name_(name)
283 , id_(name_.copy(name_.lastIndexOf('.') + 1))
284 , m_typeMgr(typeMgr)
285 , m_dependencies(typeMgr, name_)
288 void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
289 const
291 if (name_ == "com.sun.star.uno.XInterface"
292 || name_ == "com.sun.star.uno.Exception") {
293 includes.addType();
294 includes.addCppuUnotypeHxx();
295 includes.addSalTypesH();
296 includes.addTypelibTypeclassH();
297 includes.addTypelibTypedescriptionH();
298 } else if (m_cppuTypeLeak) {
299 addLightGetCppuTypeIncludes(includes);
300 } else if (m_cppuTypeDynamic) {
301 addNormalGetCppuTypeIncludes(includes);
302 } else {
303 addComprehensiveGetCppuTypeIncludes(includes);
307 void CppuType::dumpFiles(OUString const & uri, CppuOptions const & options)
309 dumpFile(uri, name_, false, options);
310 dumpFile(uri, name_, true, options);
313 void CppuType::addLightGetCppuTypeIncludes(
314 codemaker::cppumaker::Includes & includes) const
316 //TODO: Determine what is really needed, instead of relying on
317 // addDefaultHxxIncludes
318 includes.addCppuUnotypeHxx();
321 void CppuType::addNormalGetCppuTypeIncludes(
322 codemaker::cppumaker::Includes & includes) const
324 //TODO: Determine what is really needed, instead of relying on
325 // addDefaultHxxIncludes
326 includes.addCppuUnotypeHxx();
329 void CppuType::addComprehensiveGetCppuTypeIncludes(
330 codemaker::cppumaker::Includes & includes) const
332 //TODO: Determine what is really needed, instead of relying on
333 // addDefaultHxxIncludes
334 includes.addCppuUnotypeHxx();
337 bool CppuType::isPolymorphic() const
339 return false;
342 void CppuType::dumpGetCppuTypePreamble(FileStream & out)
344 if (isPolymorphic()) {
345 out << "namespace cppu {\n\n";
346 dumpTemplateHead(out);
347 out << "class UnoType< ";
348 dumpType(out, name_);
349 dumpTemplateParameters(out);
350 out << " > {\npublic:\n";
351 inc();
352 out << indent()
353 << "static inline ::css::uno::Type const & get() {\n";
354 } else {
355 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
356 out << "\n\n";
358 out << ("inline ::css::uno::Type const &"
359 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
360 dumpType(out, name_, false, false, true);
361 out << " const *) {\n";
363 inc();
366 void CppuType::dumpGetCppuTypePostamble(FileStream & out)
368 dec();
369 if (isPolymorphic()) {
370 out << indent() << "}\n\nprivate:\n"
371 << indent() << "UnoType(UnoType &); // not defined\n"
372 << indent() << "~UnoType(); // not defined\n"
373 << indent()
374 << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
375 } else {
376 out << "}\n\n";
377 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
378 out << "\n\n";
381 dumpTemplateHead(out);
382 out << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
383 " getCppuType(SAL_UNUSED_PARAMETER ");
384 dumpType(out, name_);
385 dumpTemplateParameters(out);
386 out << " const *) {\n";
387 inc();
388 out << indent() << "return ::cppu::UnoType< ";
389 dumpType(out, name_);
390 dumpTemplateParameters(out);
391 out << " >::get();\n";
392 dec();
393 out << indent() << "}\n";
396 void CppuType::dump(CppuOptions const & options)
398 if (isBootstrapType(name_)) {
399 m_cppuTypeDynamic = false;
400 } else {
401 // -CS was used as an undocumented option to generate static getCppuType
402 // functions; since the introduction of cppu::UnoType this no longer is
403 // meaningful (getCppuType is just a forward to cppu::UnoType::get now),
404 // and -CS is handled the same way as -C now:
405 if (options.isValid("-L"))
406 m_cppuTypeLeak = true;
407 if (options.isValid("-C") || options.isValid("-CS"))
408 m_cppuTypeDynamic = false;
410 dumpFiles(
411 options.isValid("-O") ? b2u(options.getOption("-O")) : "", options);
414 void CppuType::dumpFile(
415 OUString const & uri, OUString const & name, bool hpp,
416 CppuOptions const & options)
418 OUString fileUri(
419 b2u(createFileNameFromType(
420 u2b(uri), u2b(name), hpp ? ".hpp" : ".hdl")));
421 if (fileUri.isEmpty()) {
422 throw CannotDumpException("empty target URI for entity " + name);
424 bool exists = fileExists(u2b(fileUri));
425 if (exists && options.isValid("-G")) {
426 return;
428 FileStream out;
429 out.createTempFile(getTempDir(u2b(fileUri)));
430 OUString tmpUri(b2u(out.getName()));
431 if(!out.isValid()) {
432 throw CannotDumpException("cannot open " + tmpUri + " for writing");
434 codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, hpp);
435 try {
436 if (hpp) {
437 addGetCppuTypeIncludes(includes);
438 dumpHppFile(out, includes);
439 } else {
440 dumpHdlFile(out, includes);
442 } catch (...) {
443 out.close();
444 // Remove existing type file if something goes wrong to ensure
445 // consistency:
446 if (fileExists(u2b(fileUri))) {
447 removeTypeFile(u2b(fileUri));
449 removeTypeFile(u2b(tmpUri));
450 throw;
452 out.close();
453 (void)makeValidTypeFile(
454 u2b(fileUri), u2b(tmpUri), exists && options.isValid("-Gc"));
457 void CppuType::dumpDependedTypes(
458 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const
460 if (!options.isValid("-nD")) {
461 codemaker::cppumaker::Dependencies::Map const & map
462 = m_dependencies.getMap();
463 for (const auto& entry : map) {
464 produce(entry.first, m_typeMgr, generated, options);
469 OUString CppuType::dumpHeaderDefine(
470 FileStream & out, OUString const & extension) const
472 OUString def(
473 "INCLUDED_" + name_.replace('.', '_').toAsciiUpperCase() + "_"
474 + extension);
475 out << "#ifndef " << def << "\n#define " << def << "\n";
476 return def;
479 void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes)
480 const
482 //TODO: Only include what is really needed
483 includes.addCppuMacrosHxx();
484 if (m_typeMgr->getSort(name_)
485 == codemaker::UnoType::Sort::Interface) {
486 includes.addReference();
490 void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes)
491 const
493 //TODO: Only include what is really needed
494 includes.addType();
495 if (m_typeMgr->getSort(name_)
496 == codemaker::UnoType::Sort::Interface) {
497 includes.addReference();
501 void CppuType::dumpInitializer(
502 FileStream & out, bool parameterized, OUString const & name) const
504 out << "(";
505 if (!parameterized) {
506 sal_Int32 k;
507 std::vector< OString > args;
508 OUString n(
509 b2u(codemaker::UnoType::decompose(
510 u2b(resolveAllTypedefs(name)), &k, &args)));
511 if (k == 0) {
512 rtl::Reference< unoidl::Entity > ent;
513 switch (m_typeMgr->getSort(n, &ent)) {
514 case codemaker::UnoType::Sort::Boolean:
515 out << "false";
516 break;
517 case codemaker::UnoType::Sort::Byte:
518 case codemaker::UnoType::Sort::Short:
519 case codemaker::UnoType::Sort::UnsignedShort:
520 case codemaker::UnoType::Sort::Long:
521 case codemaker::UnoType::Sort::UnsignedLong:
522 case codemaker::UnoType::Sort::Hyper:
523 case codemaker::UnoType::Sort::UnsignedHyper:
524 case codemaker::UnoType::Sort::Float:
525 case codemaker::UnoType::Sort::Double:
526 case codemaker::UnoType::Sort::Char:
527 out << "0";
528 break;
529 case codemaker::UnoType::Sort::Enum:
530 out << codemaker::cpp::scopedCppName(u2b(n)) << "_"
531 << (dynamic_cast< unoidl::EnumTypeEntity * >(ent.get())->
532 getMembers()[0].name);
533 break;
534 case codemaker::UnoType::Sort::String:
535 case codemaker::UnoType::Sort::Type:
536 case codemaker::UnoType::Sort::Any:
537 case codemaker::UnoType::Sort::PlainStruct:
538 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
539 case codemaker::UnoType::Sort::Interface:
540 break;
541 default:
542 throw CannotDumpException(
543 "unexpected entity \"" + name
544 + "\" in call to CppuType::dumpInitializer");
548 out << ")";
551 void CppuType::dumpHFileContent(
552 FileStream & out, codemaker::cppumaker::Includes & includes)
554 addDefaultHIncludes(includes);
555 dumpHeaderDefine(out, "HDL");
556 out << "\n";
557 includes.dump(out, nullptr, false);
558 // 'exceptions = false' would be wrong for services/singletons, but
559 // those don't dump .hdl files anyway
560 out << ("\nnamespace com { namespace sun { namespace star { namespace uno"
561 " { class Type; } } } }\n\n");
562 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
563 out << "\n";
565 dumpDeclaration(out);
566 if (!(name_ == "com.sun.star.uno.XInterface"
567 || name_ == "com.sun.star.uno.Exception"
568 || isPolymorphic())) {
569 out << "\n" << indent()
570 << ("inline ::css::uno::Type const &"
571 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
572 dumpType(out, name_, false, false, true);
573 out << " const *);\n";
575 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
576 out << "\n";
578 out << "\n";
579 dumpTemplateHead(out);
580 out << "SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL getCppuType(";
581 dumpType(out, name_, true);
582 dumpTemplateParameters(out);
583 out << " *);\n\n#endif\n";
586 void CppuType::dumpGetCppuType(FileStream & out)
588 if (name_ == "com.sun.star.uno.XInterface") {
589 out << indent()
590 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
591 " getCppuType(SAL_UNUSED_PARAMETER ");
592 dumpType(out, name_, true);
593 out << " *) {\n";
594 inc();
595 out << indent()
596 << ("return ::cppu::UnoType< ::css::uno::XInterface"
597 " >::get();\n");
598 dec();
599 out << indent() << "}\n";
600 } else if (name_ == "com.sun.star.uno.Exception") {
601 out << indent()
602 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
603 " getCppuType(SAL_UNUSED_PARAMETER ");
604 dumpType(out, name_, true);
605 out << " *) {\n";
606 inc();
607 out << indent()
608 << ("return ::cppu::UnoType< ::css::uno::Exception"
609 " >::get();\n");
610 dec();
611 out << indent() << "}\n";
612 } else if (m_cppuTypeLeak) {
613 dumpLightGetCppuType(out);
614 } else if (m_cppuTypeDynamic) {
615 dumpNormalGetCppuType(out);
616 } else {
617 dumpComprehensiveGetCppuType(out);
621 void CppuType::dumpLightGetCppuType(FileStream & out)
623 dumpGetCppuTypePreamble(out);
624 out << indent()
625 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
626 << indent() << "if ( !the_type )\n" << indent() << "{\n";
627 inc();
628 out << indent() << "typelib_static_type_init( &the_type, "
629 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
630 dec();
631 out << indent() << "}\n" << indent()
632 << ("return * reinterpret_cast< ::css::uno::Type * >("
633 " &the_type );\n");
634 dumpGetCppuTypePostamble(out);
637 codemaker::cpp::IdentifierTranslationMode CppuType::isGlobal() const
639 return name_.indexOf('.') == -1
640 ? codemaker::cpp::IdentifierTranslationMode::Global : codemaker::cpp::IdentifierTranslationMode::NonGlobal;
643 sal_uInt32 CppuType::getInheritedMemberCount()
645 if (m_inheritedMemberCount == 0) {
646 m_inheritedMemberCount = checkInheritedMemberCount();
649 return m_inheritedMemberCount;
652 OUString CppuType::getTypeClass(OUString const & name, bool cStyle)
654 rtl::Reference< unoidl::Entity > ent;
655 switch (m_typeMgr->getSort(name, &ent)) {
656 case codemaker::UnoType::Sort::Void:
657 return cStyle
658 ? OUString("typelib_TypeClass_VOID")
659 : OUString("::css::uno::TypeClass_VOID");
660 case codemaker::UnoType::Sort::Boolean:
661 return cStyle
662 ? OUString("typelib_TypeClass_BOOLEAN")
663 : OUString("::css::uno::TypeClass_BOOLEAN");
664 case codemaker::UnoType::Sort::Byte:
665 return cStyle
666 ? OUString("typelib_TypeClass_BYTE")
667 : OUString("::css::uno::TypeClass_BYTE");
668 case codemaker::UnoType::Sort::Short:
669 return cStyle
670 ? OUString("typelib_TypeClass_SHORT")
671 : OUString("::css::uno::TypeClass_SHORT");
672 case codemaker::UnoType::Sort::UnsignedShort:
673 return cStyle
674 ? OUString("typelib_TypeClass_UNSIGNED_SHORT")
675 : OUString("::css::uno::TypeClass_UNSIGNED_SHORT");
676 case codemaker::UnoType::Sort::Long:
677 return cStyle
678 ? OUString("typelib_TypeClass_LONG")
679 : OUString("::css::uno::TypeClass_LONG");
680 case codemaker::UnoType::Sort::UnsignedLong:
681 return cStyle
682 ? OUString("typelib_TypeClass_UNSIGNED_LONG")
683 : OUString("::css::uno::TypeClass_UNSIGNED_LONG");
684 case codemaker::UnoType::Sort::Hyper:
685 return cStyle
686 ? OUString("typelib_TypeClass_HYPER")
687 : OUString("::css::uno::TypeClass_HYPER");
688 case codemaker::UnoType::Sort::UnsignedHyper:
689 return cStyle
690 ? OUString("typelib_TypeClass_UNSIGNED_HYPER")
691 : OUString("::css::uno::TypeClass_UNSIGNED_HYPER");
692 case codemaker::UnoType::Sort::Float:
693 return cStyle
694 ? OUString("typelib_TypeClass_FLOAT")
695 : OUString("::css::uno::TypeClass_FLOAT");
696 case codemaker::UnoType::Sort::Double:
697 return cStyle
698 ? OUString("typelib_TypeClass_DOUBLE")
699 : OUString("::css::uno::TypeClass_DOUBLE");
700 case codemaker::UnoType::Sort::Char:
701 return cStyle
702 ? OUString("typelib_TypeClass_CHAR")
703 : OUString("::css::uno::TypeClass_CHAR");
704 case codemaker::UnoType::Sort::String:
705 return cStyle
706 ? OUString("typelib_TypeClass_STRING")
707 : OUString("::css::uno::TypeClass_STRING");
708 case codemaker::UnoType::Sort::Type:
709 return cStyle
710 ? OUString("typelib_TypeClass_TYPE")
711 : OUString("::css::uno::TypeClass_TYPE");
712 case codemaker::UnoType::Sort::Any:
713 return cStyle
714 ? OUString("typelib_TypeClass_ANY")
715 : OUString("::css::uno::TypeClass_ANY");
716 case codemaker::UnoType::Sort::Sequence:
717 return cStyle
718 ? OUString("typelib_TypeClass_SEQUENCE")
719 : OUString("::css::uno::TypeClass_SEQUENCE");
720 case codemaker::UnoType::Sort::Enum:
721 return cStyle
722 ? OUString("typelib_TypeClass_ENUM")
723 : OUString("::css::uno::TypeClass_ENUM");
724 case codemaker::UnoType::Sort::PlainStruct:
725 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
726 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
727 return cStyle
728 ? OUString("typelib_TypeClass_STRUCT")
729 : OUString("::css::uno::TypeClass_STRUCT");
730 case codemaker::UnoType::Sort::Exception:
731 return cStyle
732 ? OUString("typelib_TypeClass_EXCEPTION")
733 : OUString("::css::uno::TypeClass_EXCEPTION");
734 case codemaker::UnoType::Sort::Interface:
735 return cStyle
736 ? OUString("typelib_TypeClass_INTERFACE")
737 : OUString("::css::uno::TypeClass_INTERFACE");
738 case codemaker::UnoType::Sort::Typedef:
739 return getTypeClass(dynamic_cast<unoidl::TypedefEntity&>(*ent).getType(), cStyle);
740 default:
741 for (;;) {
742 std::abort();
747 void CppuType::dumpType(
748 FileStream & out, OUString const & name, bool isConst, bool isRef,
749 bool native, bool cppuUnoType) const
751 sal_Int32 k;
752 std::vector< OString > args;
753 OUString n(
754 b2u(codemaker::UnoType::decompose(
755 u2b(resolveAllTypedefs(name)), &k, &args)));
756 if (isConst) {
757 out << "const ";
759 for (sal_Int32 i = 0; i != k; ++i) {
760 out << (cppuUnoType
761 ? "::cppu::UnoSequenceType" : "::css::uno::Sequence")
762 << "< ";
764 switch (m_typeMgr->getSort(n)) {
765 case codemaker::UnoType::Sort::Void:
766 out << "void";
767 break;
768 case codemaker::UnoType::Sort::Boolean:
769 out << "::sal_Bool";
770 break;
771 case codemaker::UnoType::Sort::Byte:
772 out << "::sal_Int8";
773 break;
774 case codemaker::UnoType::Sort::Short:
775 out << "::sal_Int16";
776 break;
777 case codemaker::UnoType::Sort::UnsignedShort:
778 out << (cppuUnoType ? "::cppu::UnoUnsignedShortType" : "::sal_uInt16");
779 break;
780 case codemaker::UnoType::Sort::Long:
781 out << "::sal_Int32";
782 break;
783 case codemaker::UnoType::Sort::UnsignedLong:
784 out << "::sal_uInt32";
785 break;
786 case codemaker::UnoType::Sort::Hyper:
787 out << "::sal_Int64";
788 break;
789 case codemaker::UnoType::Sort::UnsignedHyper:
790 out << "::sal_uInt64";
791 break;
792 case codemaker::UnoType::Sort::Float:
793 out << "float";
794 break;
795 case codemaker::UnoType::Sort::Double:
796 out << "double";
797 break;
798 case codemaker::UnoType::Sort::Char:
799 out << (cppuUnoType ? "::cppu::UnoCharType" : "::sal_Unicode");
800 break;
801 case codemaker::UnoType::Sort::String:
802 out << "::rtl::OUString";
803 break;
804 case codemaker::UnoType::Sort::Type:
805 out << "::css::uno::Type";
806 break;
807 case codemaker::UnoType::Sort::Any:
808 out << "::css::uno::Any";
809 break;
810 case codemaker::UnoType::Sort::Enum:
811 case codemaker::UnoType::Sort::PlainStruct:
812 case codemaker::UnoType::Sort::Exception:
813 out << codemaker::cpp::scopedCppName(u2b(n));
814 break;
815 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
816 out << codemaker::cpp::scopedCppName(u2b(n));
817 if (!args.empty()) {
818 out << "< ";
819 for (std::vector< OString >::iterator i(args.begin());
820 i != args.end(); ++i) {
821 if (i != args.begin()) {
822 out << ", ";
824 dumpType(out, b2u(*i));
826 out << " >";
828 break;
829 case codemaker::UnoType::Sort::Interface:
830 if (!native) {
831 out << "::css::uno::Reference< ";
833 out << codemaker::cpp::scopedCppName(u2b(n));
834 if (!native) {
835 out << " >";
837 break;
838 default:
839 throw CannotDumpException(
840 "unexpected entity \"" + name + "\" in call to CppuType::dumpType");
842 for (sal_Int32 i = 0; i != k; ++i) {
843 out << " >";
845 if (isRef) {
846 out << "&";
850 void CppuType::dumpCppuGetType(
851 FileStream & out, OUString const & name, OUString const * ownName) const
853 //TODO: What are these calls good for?
854 OUString nucleus;
855 sal_Int32 rank;
856 codemaker::UnoType::Sort sort = m_typeMgr->decompose(
857 name, true, &nucleus, &rank, nullptr, nullptr);
858 switch (rank == 0 ? sort : codemaker::UnoType::Sort::Sequence) {
859 case codemaker::UnoType::Sort::Void:
860 case codemaker::UnoType::Sort::Boolean:
861 case codemaker::UnoType::Sort::Byte:
862 case codemaker::UnoType::Sort::Short:
863 case codemaker::UnoType::Sort::UnsignedShort:
864 case codemaker::UnoType::Sort::Long:
865 case codemaker::UnoType::Sort::UnsignedLong:
866 case codemaker::UnoType::Sort::Hyper:
867 case codemaker::UnoType::Sort::UnsignedHyper:
868 case codemaker::UnoType::Sort::Float:
869 case codemaker::UnoType::Sort::Double:
870 case codemaker::UnoType::Sort::Char:
871 case codemaker::UnoType::Sort::String:
872 case codemaker::UnoType::Sort::Type:
873 case codemaker::UnoType::Sort::Any:
874 break;
875 case codemaker::UnoType::Sort::Sequence:
876 case codemaker::UnoType::Sort::Enum:
877 case codemaker::UnoType::Sort::PlainStruct:
878 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
879 case codemaker::UnoType::Sort::Exception:
880 case codemaker::UnoType::Sort::Interface:
881 // Take care of recursion like struct S { sequence<S> x; }:
882 if (ownName == nullptr || nucleus != *ownName) {
883 out << indent() << "::cppu::UnoType< ";
884 dumpType(out, name, false, false, false, true);
885 out << " >::get();\n";
887 break;
888 case codemaker::UnoType::Sort::Typedef:
889 for (;;) std::abort(); // this cannot happen
890 default:
891 throw CannotDumpException(
892 "unexpected entity \"" + name
893 + "\" in call to CppuType::dumpCppuGetType");
897 bool CppuType::passByReference(OUString const & name) const
899 switch (m_typeMgr->getSort(resolveOuterTypedefs(name))) {
900 case codemaker::UnoType::Sort::Boolean:
901 case codemaker::UnoType::Sort::Byte:
902 case codemaker::UnoType::Sort::Short:
903 case codemaker::UnoType::Sort::UnsignedShort:
904 case codemaker::UnoType::Sort::Long:
905 case codemaker::UnoType::Sort::UnsignedLong:
906 case codemaker::UnoType::Sort::Hyper:
907 case codemaker::UnoType::Sort::UnsignedHyper:
908 case codemaker::UnoType::Sort::Float:
909 case codemaker::UnoType::Sort::Double:
910 case codemaker::UnoType::Sort::Char:
911 case codemaker::UnoType::Sort::Enum:
912 return false;
913 case codemaker::UnoType::Sort::String:
914 case codemaker::UnoType::Sort::Type:
915 case codemaker::UnoType::Sort::Any:
916 case codemaker::UnoType::Sort::Sequence:
917 case codemaker::UnoType::Sort::PlainStruct:
918 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
919 case codemaker::UnoType::Sort::Interface:
920 return true;
921 default:
922 throw CannotDumpException(
923 "unexpected entity \"" + name
924 + "\" in call to CppuType::passByReference");
928 bool CppuType::canBeWarnUnused(OUString const & name) const
930 return canBeWarnUnused(name, 0);
932 bool CppuType::canBeWarnUnused(OUString const & name, int depth) const
934 // prevent infinite recursion and blowing the stack
935 if (depth > 10)
936 return false;
937 OUString aResolvedName = resolveOuterTypedefs(name);
938 switch (m_typeMgr->getSort(aResolvedName)) {
939 case codemaker::UnoType::Sort::Boolean:
940 case codemaker::UnoType::Sort::Byte:
941 case codemaker::UnoType::Sort::Short:
942 case codemaker::UnoType::Sort::UnsignedShort:
943 case codemaker::UnoType::Sort::Long:
944 case codemaker::UnoType::Sort::UnsignedLong:
945 case codemaker::UnoType::Sort::Hyper:
946 case codemaker::UnoType::Sort::UnsignedHyper:
947 case codemaker::UnoType::Sort::Float:
948 case codemaker::UnoType::Sort::Double:
949 case codemaker::UnoType::Sort::Char:
950 case codemaker::UnoType::Sort::Enum:
951 case codemaker::UnoType::Sort::String:
952 case codemaker::UnoType::Sort::Type:
953 return true;
954 case codemaker::UnoType::Sort::PlainStruct: {
955 rtl::Reference< unoidl::Entity > ent;
956 m_typeMgr->getSort(aResolvedName, &ent);
957 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
958 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
959 if (!ent2->getDirectBase().isEmpty() && !canBeWarnUnused(ent2->getDirectBase(), depth+1))
960 return false;
961 for ( const unoidl::PlainStructTypeEntity::Member& rMember : ent2->getDirectMembers()) {
962 if (!canBeWarnUnused(rMember.type, depth+1))
963 return false;
965 return true;
967 case codemaker::UnoType::Sort::Sequence: {
968 OUString aInnerType = aResolvedName.copy(2);
969 return canBeWarnUnused(aInnerType, depth+1);
971 case codemaker::UnoType::Sort::Any:
972 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
973 case codemaker::UnoType::Sort::Interface:
974 return false;
975 default:
976 throw CannotDumpException(
977 "unexpected entity \"" + name
978 + "\" in call to CppuType::canBeWarnUnused");
982 OUString CppuType::resolveOuterTypedefs(OUString const & name) const
984 for (OUString n(name);;) {
985 rtl::Reference< unoidl::Entity > ent;
986 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
987 return n;
989 n = dynamic_cast<unoidl::TypedefEntity&>(*ent).getType();
993 OUString CppuType::resolveAllTypedefs(OUString const & name) const
995 sal_Int32 k1;
996 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k1)));
997 for (;;) {
998 rtl::Reference< unoidl::Entity > ent;
999 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
1000 break;
1002 sal_Int32 k2;
1003 n = b2u(codemaker::UnoType::decompose(
1004 u2b(dynamic_cast<unoidl::TypedefEntity&>(*ent).getType()), &k2));
1005 k1 += k2; //TODO: overflow
1007 OUStringBuffer b;
1008 for (sal_Int32 i = 0; i != k1; ++i) {
1009 b.append("[]");
1011 b.append(n);
1012 return b.makeStringAndClear();
1015 void CppuType::inc(sal_Int32 num)
1017 m_indentLength += num;
1020 void CppuType::dec(sal_Int32 num)
1022 m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0);
1025 OUString CppuType::indent() const
1027 OUStringBuffer buf(m_indentLength);
1028 for (sal_Int32 i = 0; i != m_indentLength; ++i) {
1029 buf.append(' ');
1031 return buf.makeStringAndClear();
1034 bool isDeprecated(std::vector< OUString > const & annotations)
1036 for (const OUString& r : annotations) {
1037 if (r == "deprecated") {
1038 return true;
1041 return false;
1044 void dumpDeprecation(FileStream & out, bool deprecated)
1046 if (deprecated) {
1047 out << "SAL_DEPRECATED_INTERNAL(\"marked @deprecated in UNOIDL\") ";
1051 class BaseOffset
1053 public:
1054 BaseOffset(
1055 rtl::Reference< TypeManager > const & manager,
1056 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity):
1057 manager_(manager), offset_(0) {
1058 calculateBases(entity);
1060 BaseOffset(const BaseOffset&) = delete;
1061 const BaseOffset& operator=(const BaseOffset&) = delete;
1063 sal_Int32 get() const {
1064 return offset_;
1067 private:
1068 void calculateBases(
1069 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity);
1071 rtl::Reference< TypeManager > manager_;
1072 std::set< OUString > set_;
1073 sal_Int32 offset_;
1076 void BaseOffset::calculateBases(
1077 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity)
1079 assert(entity.is());
1080 for (const unoidl::AnnotatedReference& ar : entity->getDirectMandatoryBases()) {
1081 if (set_.insert(ar.name).second) {
1082 rtl::Reference< unoidl::Entity > ent;
1083 codemaker::UnoType::Sort sort = manager_->getSort(ar.name, &ent);
1084 if (sort != codemaker::UnoType::Sort::Interface) {
1085 throw CannotDumpException(
1086 "interface type base " + ar.name
1087 + " is not an interface type");
1089 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
1090 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()));
1091 assert(ent2.is());
1092 calculateBases(ent2);
1093 offset_ += ent2->getDirectAttributes().size()
1094 + ent2->getDirectMethods().size(); //TODO: overflow
1099 class InterfaceType: public CppuType
1101 public:
1102 InterfaceType(
1103 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
1104 OUString const & name, rtl::Reference< TypeManager > const & typeMgr);
1106 virtual void dumpDeclaration(FileStream& o) override;
1107 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1109 void dumpAttributes(FileStream& o) const;
1110 void dumpMethods(FileStream& o) const;
1111 void dumpNormalGetCppuType(FileStream& o) override;
1112 void dumpComprehensiveGetCppuType(FileStream& o) override;
1113 void dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index);
1114 void dumpCppuMethodRefs(FileStream& o, sal_uInt32& index);
1115 void dumpCppuAttributes(FileStream& o, sal_uInt32& index);
1116 void dumpCppuMethods(FileStream& o, sal_uInt32& index);
1117 void dumpAttributesCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1118 void dumpMethodsCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1120 private:
1121 virtual void addComprehensiveGetCppuTypeIncludes(
1122 codemaker::cppumaker::Includes & includes) const override;
1124 virtual sal_uInt32 checkInheritedMemberCount() const override {
1125 return BaseOffset(m_typeMgr, entity_).get();
1128 void dumpExceptionTypeName(
1129 FileStream & out, OUString const & prefix, sal_uInt32 index,
1130 OUString const & name) const;
1132 sal_Int32 dumpExceptionTypeNames(
1133 FileStream & out, OUString const & prefix,
1134 std::vector< OUString > const & exceptions, bool runtimeException) const;
1136 rtl::Reference< unoidl::InterfaceTypeEntity > entity_;
1137 bool m_isDeprecated;
1140 InterfaceType::InterfaceType(
1141 rtl::Reference< unoidl::InterfaceTypeEntity > const & entity,
1142 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1143 CppuType(name, typeMgr), entity_(entity),
1144 m_isDeprecated(isDeprecated(entity->getAnnotations()))
1146 assert(entity.is());
1149 void InterfaceType::dumpDeclaration(FileStream & out)
1151 out << "\nclass SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI " << id_;
1152 for (std::vector< unoidl::AnnotatedReference >::const_iterator i(
1153 entity_->getDirectMandatoryBases().begin());
1154 i != entity_->getDirectMandatoryBases().end(); ++i) {
1155 out << (i == entity_->getDirectMandatoryBases().begin() ? " :" : ",")
1156 << " public " << codemaker::cpp::scopedCppName(u2b(i->name));
1158 out << "\n{\npublic:\n";
1159 inc();
1160 out << "#if defined LIBO_INTERNAL_ONLY\n"
1161 << indent() << id_ << "() = default;\n"
1162 << indent() << id_ << "(" << id_ << " const &) = default;\n"
1163 << indent() << id_ << "(" << id_ << " &&) = default;\n"
1164 << indent() << id_ << " & operator =(" << id_ << " const &) = default;\n"
1165 << indent() << id_ << " & operator =(" << id_ << " &&) = default;\n#endif\n\n";
1166 dumpAttributes(out);
1167 dumpMethods(out);
1168 out << "\n" << indent()
1169 << ("static inline ::css::uno::Type const & SAL_CALL"
1170 " static_type(void * = 0);\n\n");
1171 dec();
1172 out << "protected:\n";
1173 inc();
1174 out << indent() << "~" << id_
1175 << ("() throw () {} // avoid warnings about virtual members and"
1176 " non-virtual dtor\n");
1177 dec();
1178 out << "};\n\n";
1181 void InterfaceType::dumpHppFile(
1182 FileStream & out, codemaker::cppumaker::Includes & includes)
1184 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1185 out << "\n";
1186 addDefaultHxxIncludes(includes);
1187 includes.dump(out, &name_, !(m_cppuTypeLeak || m_cppuTypeDynamic));
1188 out << "\n";
1189 dumpGetCppuType(out);
1190 out << "\n::css::uno::Type const & "
1191 << codemaker::cpp::scopedCppName(u2b(name_))
1192 << "::static_type(SAL_UNUSED_PARAMETER void *) {\n";
1193 inc();
1194 out << indent() << "return ::cppu::UnoType< ";
1195 dumpType(out, name_, false, false, true);
1196 out << " >::get();\n";
1197 dec();
1198 out << "}\n\n#endif // "<< headerDefine << "\n";
1201 void InterfaceType::dumpAttributes(FileStream & out) const
1203 if (!entity_->getDirectAttributes().empty()) {
1204 out << "\n" << indent() << "// Attributes\n";
1206 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1207 bool depr = m_isDeprecated || isDeprecated(attr.annotations);
1208 out << indent();
1209 dumpDeprecation(out, depr);
1210 out << "virtual ";
1211 dumpType(out, attr.type);
1212 out << " SAL_CALL get" << attr.name << "() = 0;\n";
1213 if (!attr.readOnly) {
1214 bool byRef = passByReference(attr.type);
1215 out << indent();
1216 dumpDeprecation(out, depr);
1217 out << "virtual void SAL_CALL set" << attr.name << "( ";
1218 dumpType(out, attr.type, byRef, byRef);
1219 out << " _" << attr.name.toAsciiLowerCase() << " ) = 0;\n";
1224 void InterfaceType::dumpMethods(FileStream & out) const
1226 if (!entity_->getDirectMethods().empty()) {
1227 out << "\n" << indent() << "// Methods\n";
1229 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1230 out << indent();
1231 dumpDeprecation(out, m_isDeprecated || isDeprecated(method.annotations));
1232 out << "virtual ";
1233 dumpType(out, method.returnType);
1234 out << " SAL_CALL " << method.name << "(";
1235 if (!method.parameters.empty()) {
1236 out << " ";
1237 for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1238 const_iterator j(method.parameters.begin());
1239 j != method.parameters.end();) {
1240 bool isConst;
1241 bool isRef;
1242 if (j->direction
1243 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1245 isConst = passByReference(j->type);
1246 isRef = isConst;
1247 } else {
1248 isConst = false;
1249 isRef = true;
1251 dumpType(out, j->type, isConst, isRef);
1252 out << " " << j->name;
1253 ++j;
1254 if (j != method.parameters.end()) {
1255 out << ", ";
1258 out << " ";
1260 out << ") = 0;\n";
1264 void InterfaceType::dumpNormalGetCppuType(FileStream & out)
1266 dumpGetCppuTypePreamble(out);
1267 out << indent()
1268 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
1269 << indent() << "if ( !the_type )\n" << indent() << "{\n";
1270 inc();
1271 std::vector< unoidl::AnnotatedReference >::size_type bases(
1272 entity_->getDirectMandatoryBases().size());
1273 if (bases == 1
1274 && (entity_->getDirectMandatoryBases()[0].name
1275 == "com.sun.star.uno.XInterface")) {
1276 bases = 0;
1278 if (bases != 0) {
1279 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1280 << entity_->getDirectMandatoryBases().size() << "];\n";
1281 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1282 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1283 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1284 dumpType(out, ar.name, true, false, false, true);
1285 out << " >::get().getTypeLibType();\n";
1288 out << indent() << "typelib_static_mi_interface_type_init( &the_type, \""
1289 << name_ << "\", " << bases << ", "
1290 << (bases == 0 ? "0" : "aSuperTypes") << " );\n";
1291 dec();
1292 out << indent() << "}\n" << indent()
1293 << ("return * reinterpret_cast< ::css::uno::Type * >("
1294 " &the_type );\n");
1295 dumpGetCppuTypePostamble(out);
1298 void InterfaceType::dumpComprehensiveGetCppuType(FileStream & out)
1300 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
1301 OUString staticTypeClass("the" + id_ + "Type");
1302 out << " namespace detail {\n\n" << indent() << "struct " << staticTypeClass
1303 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
1304 << staticTypeClass << " >\n" << indent() << "{\n";
1305 inc();
1306 out << indent() << "::css::uno::Type * operator()() const\n"
1307 << indent() << "{\n";
1308 inc();
1309 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
1310 << indent() << "// Start inline typedescription generation\n"
1311 << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n";
1312 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1313 << entity_->getDirectMandatoryBases().size() << "];\n";
1314 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1315 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1316 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1317 dumpType(out, ar.name, false, false, false, true);
1318 out << " >::get().getTypeLibType();\n";
1320 std::size_t count = entity_->getDirectAttributes().size()
1321 + entity_->getDirectMethods().size(); //TODO: overflow
1322 if (count != 0) {
1323 out << indent() << "typelib_TypeDescriptionReference * pMembers["
1324 << count << "] = { ";
1325 for (std::size_t i = 0; i != count; ++i) {
1326 out << "0";
1327 if (i + 1 != count) {
1328 out << ",";
1331 out << " };\n";
1332 sal_uInt32 index = 0;
1333 dumpCppuAttributeRefs(out, index);
1334 dumpCppuMethodRefs(out, index);
1336 out << "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1337 inc();
1338 out << indent() << "&pTD,\n" << indent()
1339 << "sTypeName.pData, 0, 0, 0, 0, 0,\n" << indent()
1340 << entity_->getDirectMandatoryBases().size() << ", aSuperTypes,\n"
1341 << indent() << count << ",\n" << indent()
1342 << (count == 0 ? "0" : "pMembers") << " );\n\n";
1343 dec();
1344 out << indent()
1345 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1346 " );\n");
1347 for (std::size_t i = 0; i != count; ++i) {
1348 out << indent() << "typelib_typedescriptionreference_release( pMembers["
1349 << i << "] );\n";
1351 out << indent()
1352 << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1353 " );\n\n")
1354 << indent() << "return new ::css::uno::Type( "
1355 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
1356 dec();
1357 out << indent() << "}\n";
1358 dec();
1359 out << indent() << "};\n\n";
1360 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
1361 out << " }\n\n";
1362 dumpGetCppuTypePreamble(out);
1363 out << indent() << "const ::css::uno::Type &rRet = *detail::"
1364 << staticTypeClass << "::get();\n" << indent()
1365 << "// End inline typedescription generation\n" << indent()
1366 << "static bool bInitStarted = false;\n" << indent()
1367 << "if (!bInitStarted)\n" << indent() << "{\n";
1368 inc();
1369 out << indent()
1370 << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"
1371 << indent() << "if (!bInitStarted)\n" << indent() << "{\n";
1372 inc();
1373 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"
1374 << indent() << "bInitStarted = true;\n";
1375 std::set< OUString > seen;
1376 // Type for RuntimeException is always needed:
1377 seen.insert("com.sun.star.uno.RuntimeException");
1378 dumpCppuGetType(out, "com.sun.star.uno.RuntimeException");
1379 dumpAttributesCppuDecl(out, &seen);
1380 dumpMethodsCppuDecl(out, &seen);
1381 if (count != 0) {
1382 sal_uInt32 index = getInheritedMemberCount();
1383 dumpCppuAttributes(out, index);
1384 dumpCppuMethods(out, index);
1386 dec();
1387 out << indent() << "}\n";
1388 dec();
1389 out << indent() << "}\n" << indent() << "else\n" << indent() << "{\n";
1390 inc();
1391 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
1392 dec();
1393 out << indent() << "}\n" << indent() << "return rRet;\n";
1394 dumpGetCppuTypePostamble(out);
1397 void InterfaceType::dumpCppuAttributeRefs(FileStream & out, sal_uInt32 & index)
1399 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1400 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1401 out << indent() << "::rtl::OUString sAttributeName" << n << "( \""
1402 << name_ << "::" << attr.name << "\" );\n" << indent()
1403 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1404 << "],\n";
1405 inc(38);
1406 out << indent()
1407 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_ATTRIBUTE,\n"
1408 << indent() << "sAttributeName" << n << ".pData );\n";
1409 dec(38);
1410 ++n;
1414 void InterfaceType::dumpCppuMethodRefs(FileStream & out, sal_uInt32 & index)
1416 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1417 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1418 out << indent() << "::rtl::OUString sMethodName" << n << "( \"" << name_
1419 << "::" << method.name << "\" );\n" << indent()
1420 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1421 << "],\n";
1422 inc(38);
1423 out << indent()
1424 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_METHOD,\n"
1425 << indent() << "sMethodName" << n << ".pData );\n";
1426 dec(38);
1427 ++n;
1431 void InterfaceType::addComprehensiveGetCppuTypeIncludes(
1432 codemaker::cppumaker::Includes & includes) const
1434 // The comprehensive getCppuType method always includes a line
1435 // "getCppuType( (const ::css::uno::RuntimeException*)0 );":
1436 includes.addCppuUnotypeHxx();
1437 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
1438 includes.addOslMutexHxx();
1439 includes.add("com.sun.star.uno.RuntimeException");
1442 void InterfaceType::dumpCppuAttributes(FileStream & out, sal_uInt32 & index)
1444 if (!entity_->getDirectAttributes().empty()) {
1445 out << "\n" << indent()
1446 << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
1447 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1448 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1449 OUString type(resolveAllTypedefs(attr.type));
1450 out << indent() << "{\n";
1451 inc();
1452 out << indent() << "::rtl::OUString sAttributeType" << n << "( \""
1453 << type << "\" );\n" << indent()
1454 << "::rtl::OUString sAttributeName" << n << "( \"" << name_
1455 << "::" << attr.name << "\" );\n";
1456 sal_Int32 getExcn = dumpExceptionTypeNames(
1457 out, "get", attr.getExceptions, false);
1458 sal_Int32 setExcn = dumpExceptionTypeNames(
1459 out, "set", attr.setExceptions, false);
1460 out << indent()
1461 << ("typelib_typedescription_newExtendedInterfaceAttribute("
1462 " &pAttribute,\n");
1463 inc();
1464 out << indent() << index++ << ", sAttributeName" << n
1465 << ".pData,\n" << indent() << "(typelib_TypeClass)"
1466 << getTypeClass(type) << ", sAttributeType" << n << ".pData,\n"
1467 << indent() << "sal_" << (attr.readOnly ? "True" : "False")
1468 << ", " << getExcn << ", "
1469 << (getExcn == 0 ? "0" : "the_getExceptions") << ", " << setExcn
1470 << ", " << (setExcn == 0 ? "0" : "the_setExceptions")
1471 << " );\n";
1472 dec();
1473 out << indent()
1474 << ("typelib_typedescription_register("
1475 " (typelib_TypeDescription**)&pAttribute );\n");
1476 dec();
1477 out << indent() << "}\n";
1478 ++n;
1480 out << indent()
1481 << ("typelib_typedescription_release("
1482 " (typelib_TypeDescription*)pAttribute );\n");
1486 void InterfaceType::dumpCppuMethods(FileStream & out, sal_uInt32 & index)
1488 if (!entity_->getDirectMethods().empty()) {
1489 out << "\n" << indent()
1490 << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
1491 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1492 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1493 OUString returnType(resolveAllTypedefs(method.returnType));
1494 out << indent() << "{\n";
1495 inc();
1496 if (!method.parameters.empty()) {
1497 out << indent() << "typelib_Parameter_Init aParameters["
1498 << method.parameters.size() << "];\n";
1500 std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1501 size_type m = 0;
1502 for (const unoidl::InterfaceTypeEntity::Method::Parameter& param : method.parameters) {
1503 OUString type(resolveAllTypedefs(param.type));
1504 out << indent() << "::rtl::OUString sParamName" << m << "( \""
1505 << param.name << "\" );\n" << indent()
1506 << "::rtl::OUString sParamType" << m << "( \"" << type
1507 << "\" );\n" << indent() << "aParameters[" << m
1508 << "].pParamName = sParamName" << m << ".pData;\n"
1509 << indent() << "aParameters[" << m
1510 << "].eTypeClass = (typelib_TypeClass)"
1511 << getTypeClass(type) << ";\n" << indent() << "aParameters["
1512 << m << "].pTypeName = sParamType" << m << ".pData;\n"
1513 << indent() << "aParameters[" << m << "].bIn = "
1514 << ((param.direction
1515 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT)
1516 ? "sal_False" : "sal_True")
1517 << ";\n" << indent() << "aParameters[" << m << "].bOut = "
1518 << ((param.direction
1519 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
1520 ? "sal_False" : "sal_True")
1521 << ";\n";
1522 ++m;
1524 sal_Int32 excn = dumpExceptionTypeNames(
1525 out, "", method.exceptions,
1526 method.name != "acquire" && method.name != "release");
1527 out << indent() << "::rtl::OUString sReturnType" << n << "( \""
1528 << returnType << "\" );\n" << indent()
1529 << "::rtl::OUString sMethodName" << n << "( \"" << name_ << "::"
1530 << method.name << "\" );\n" << indent()
1531 << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
1532 inc();
1533 out << indent() << index++ << ", sal_False,\n" << indent()
1534 << "sMethodName" << n << ".pData,\n" << indent()
1535 << "(typelib_TypeClass)" << getTypeClass(returnType)
1536 << ", sReturnType" << n << ".pData,\n" << indent()
1537 << method.parameters.size() << ", "
1538 << (method.parameters.empty() ? "0" : "aParameters") << ",\n"
1539 << indent() << excn << ", "
1540 << (excn == 0 ? "0" : "the_Exceptions") << " );\n";
1541 dec();
1542 out << indent()
1543 << ("typelib_typedescription_register("
1544 " (typelib_TypeDescription**)&pMethod );\n");
1545 dec();
1546 out << indent() << "}\n";
1547 ++n;
1549 out << indent()
1550 << ("typelib_typedescription_release("
1551 " (typelib_TypeDescription*)pMethod );\n");
1555 void InterfaceType::dumpAttributesCppuDecl(
1556 FileStream & out, std::set< OUString > * seen) const
1558 assert(seen != nullptr);
1559 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1560 if (seen->insert(attr.type).second) {
1561 dumpCppuGetType(out, attr.type);
1563 for (const OUString& exc : attr.getExceptions) {
1564 if (seen->insert(exc).second) {
1565 dumpCppuGetType(out, exc);
1568 for (const OUString& exc : attr.setExceptions) {
1569 if (seen->insert(exc).second) {
1570 dumpCppuGetType(out, exc);
1576 void InterfaceType::dumpMethodsCppuDecl(
1577 FileStream & out, std::set< OUString > * seen) const
1579 assert(seen != nullptr);
1580 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1581 for (const OUString& ex : method.exceptions) {
1582 if (seen->insert(ex).second) {
1583 dumpCppuGetType(out, ex);
1589 void InterfaceType::dumpExceptionTypeName(
1590 FileStream & out, OUString const & prefix, sal_uInt32 index,
1591 OUString const & name) const
1593 out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName"
1594 << index << "( \"" << name << "\" );\n";
1597 sal_Int32 InterfaceType::dumpExceptionTypeNames(
1598 FileStream & out, OUString const & prefix,
1599 std::vector< OUString > const & exceptions, bool runtimeException) const
1601 sal_Int32 count = 0;
1602 for (const OUString& ex : exceptions) {
1603 if (ex != "com.sun.star.uno.RuntimeException") {
1604 dumpExceptionTypeName(out, prefix, count++, ex);
1607 if (runtimeException) {
1608 dumpExceptionTypeName(
1609 out, prefix, count++, "com.sun.star.uno.RuntimeException");
1611 if (count != 0) {
1612 out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {";
1613 for (sal_Int32 i = 0; i != count; ++i) {
1614 out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName"
1615 << i << ".pData";
1617 out << " };\n";
1619 return count;
1622 class ConstantGroup: public CppuType
1624 public:
1625 ConstantGroup(
1626 rtl::Reference< unoidl::ConstantGroupEntity > const & entity,
1627 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1628 CppuType(name, typeMgr), entity_(entity) {
1629 assert(entity.is());
1632 bool hasConstants() const {
1633 return !entity_->getMembers().empty();
1636 private:
1637 virtual void dumpHdlFile(
1638 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1640 virtual void dumpHppFile(
1641 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1643 virtual void dumpDeclaration(FileStream & out) override;
1645 rtl::Reference< unoidl::ConstantGroupEntity > entity_;
1648 void ConstantGroup::dumpHdlFile(
1649 FileStream & out, codemaker::cppumaker::Includes & includes)
1651 OUString headerDefine(dumpHeaderDefine(out, "HDL"));
1652 out << "\n";
1653 addDefaultHIncludes(includes);
1654 includes.dump(out, nullptr, true);
1655 out << "\n";
1656 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, true)) {
1657 out << "\n";
1659 out << "\n";
1660 dumpDeclaration(out);
1661 out << "\n";
1662 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, true)) {
1663 out << "\n";
1665 out << "\n#endif // "<< headerDefine << "\n";
1668 void ConstantGroup::dumpHppFile(
1669 FileStream & out, codemaker::cppumaker::Includes &)
1671 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1672 out << "\n";
1673 codemaker::cppumaker::Includes::dumpInclude(out, u2b(name_), false);
1674 out << "\n#endif // "<< headerDefine << "\n";
1677 void ConstantGroup::dumpDeclaration(FileStream & out)
1679 for (const unoidl::ConstantGroupEntity::Member& member : entity_->getMembers()) {
1680 out << "static const ";
1681 switch (member.value.type) {
1682 case unoidl::ConstantValue::TYPE_BOOLEAN:
1683 out << "::sal_Bool";
1684 break;
1685 case unoidl::ConstantValue::TYPE_BYTE:
1686 out << "::sal_Int8";
1687 break;
1688 case unoidl::ConstantValue::TYPE_SHORT:
1689 out << "::sal_Int16";
1690 break;
1691 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1692 out << "::sal_uInt16";
1693 break;
1694 case unoidl::ConstantValue::TYPE_LONG:
1695 out << "::sal_Int32";
1696 break;
1697 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1698 out << "::sal_uInt32";
1699 break;
1700 case unoidl::ConstantValue::TYPE_HYPER:
1701 out << "::sal_Int64";
1702 break;
1703 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1704 out << "::sal_uInt64";
1705 break;
1706 case unoidl::ConstantValue::TYPE_FLOAT:
1707 out << "float";
1708 break;
1709 case unoidl::ConstantValue::TYPE_DOUBLE:
1710 out << "double";
1711 break;
1713 out << " " << member.name << " = ";
1714 switch (member.value.type) {
1715 case unoidl::ConstantValue::TYPE_BOOLEAN:
1716 out << (member.value.booleanValue ? "sal_True" : "sal_False");
1717 break;
1718 case unoidl::ConstantValue::TYPE_BYTE:
1719 out << "(sal_Int8)" << OUString::number(member.value.byteValue);
1720 break;
1721 case unoidl::ConstantValue::TYPE_SHORT:
1722 out << "(sal_Int16)" << OUString::number(member.value.shortValue);
1723 break;
1724 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
1725 out << "(sal_uInt16)"
1726 << OUString::number(member.value.unsignedShortValue);
1727 break;
1728 case unoidl::ConstantValue::TYPE_LONG:
1729 // Avoid C++ compiler warnings about (un)signedness of literal
1730 // -2^31:
1731 if (member.value.longValue == SAL_MIN_INT32) {
1732 out << "SAL_MIN_INT32";
1733 } else {
1734 out << "(sal_Int32)" << OUString::number(member.value.longValue);
1736 break;
1737 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
1738 out << "(sal_uInt32)"
1739 << OUString::number(member.value.unsignedLongValue) << "U";
1740 break;
1741 case unoidl::ConstantValue::TYPE_HYPER:
1742 // Avoid C++ compiler warnings about (un)signedness of literal
1743 // -2^63:
1744 if (member.value.hyperValue == SAL_MIN_INT64) {
1745 out << "SAL_MIN_INT64";
1746 } else {
1747 out << "(sal_Int64) SAL_CONST_INT64("
1748 << OUString::number(member.value.hyperValue) << ")";
1750 break;
1751 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
1752 out << "SAL_CONST_UINT64("
1753 << OUString::number(member.value.unsignedHyperValue) << ")";
1754 break;
1755 case unoidl::ConstantValue::TYPE_FLOAT:
1756 out << "(float)" << OUString::number(member.value.floatValue);
1757 break;
1758 case unoidl::ConstantValue::TYPE_DOUBLE:
1759 out << "(double)" << OUString::number(member.value.doubleValue);
1760 break;
1762 out << ";\n";
1766 void dumpTypeParameterName(FileStream & out, OUString const & name)
1768 // Prefix all type parameters with "typeparam_" to avoid problems when a
1769 // struct member has the same name as a type parameter, as in
1770 // struct<T> { T T; };
1771 out << "typeparam_" << name;
1774 class PlainStructType: public CppuType
1776 public:
1777 PlainStructType(
1778 rtl::Reference< unoidl::PlainStructTypeEntity > const & entity,
1779 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1780 CppuType(name, typeMgr), entity_(entity) {
1781 assert(entity.is());
1784 private:
1785 virtual sal_uInt32 checkInheritedMemberCount() const override {
1786 return getTotalMemberCount(entity_->getDirectBase());
1789 virtual void dumpDeclaration(FileStream& o) override;
1791 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1793 virtual void dumpLightGetCppuType(FileStream & out) override;
1795 virtual void dumpNormalGetCppuType(FileStream & out) override;
1797 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
1799 virtual void addLightGetCppuTypeIncludes(
1800 codemaker::cppumaker::Includes & includes) const override;
1802 virtual void addNormalGetCppuTypeIncludes(
1803 codemaker::cppumaker::Includes & includes) const override;
1805 virtual void addComprehensiveGetCppuTypeIncludes(
1806 codemaker::cppumaker::Includes & includes) const override;
1808 bool dumpBaseMembers(
1809 FileStream & out, OUString const & base, bool withType);
1811 sal_uInt32 getTotalMemberCount(OUString const & base) const;
1813 rtl::Reference< unoidl::PlainStructTypeEntity > entity_;
1816 void PlainStructType::dumpDeclaration(FileStream & out)
1818 out << "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
1819 out << "struct SAL_DLLPUBLIC_RTTI ";
1820 if (canBeWarnUnused(name_))
1821 out << "SAL_WARN_UNUSED ";
1822 out << id_;
1823 OUString base(entity_->getDirectBase());
1824 if (!base.isEmpty()) {
1825 out << ": public " << codemaker::cpp::scopedCppName(u2b(base));
1827 out << " {\n";
1828 inc();
1829 out << indent() << "inline " << id_ << "();\n";
1830 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1831 out << "\n" << indent() << "inline " << id_ << "(";
1832 bool bFirst = !dumpBaseMembers(out, base, true);
1833 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1834 if (!bFirst) {
1835 out << ", ";
1837 dumpType(out, member.type, true, true);
1838 out << " " << member.name << "_";
1839 bFirst = false;
1841 out << ");\n";
1843 if (!entity_->getDirectMembers().empty()) {
1844 out << "\n";
1845 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
1846 const_iterator i(entity_->getDirectMembers().begin());
1847 i != entity_->getDirectMembers().end(); ++i) {
1848 out << indent();
1849 dumpType(out, i->type);
1850 out << " " << i->name;
1851 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
1852 && i->type != "hyper" && i->type != "unsigned hyper"
1853 && i->type != "double") {
1854 out << " CPPU_GCC3_ALIGN("
1855 << codemaker::cpp::scopedCppName(u2b(base)) << ")";
1857 out << ";\n";
1860 dec();
1861 out << "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
1864 void PlainStructType::dumpHppFile(
1865 FileStream & out, codemaker::cppumaker::Includes & includes)
1867 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
1868 out << "\n";
1869 includes.dump(out, &name_, true);
1870 out << "\n";
1871 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
1872 out << "\n";
1874 out << "\ninline " << id_ << "::" << id_ << "()\n";
1875 inc();
1876 OUString base(entity_->getDirectBase());
1877 bool bFirst = true;
1878 if (!base.isEmpty()) {
1879 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1880 << "()\n";
1881 bFirst = false;
1883 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1884 out << indent() << (bFirst ? ":" : ",") << " " << member.name;
1885 dumpInitializer(out, false, member.type);
1886 out << "\n";
1887 bFirst = false;
1889 dec();
1890 out << "{\n}\n\n";
1891 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1892 out << "inline " << id_;
1893 out << "::" << id_ << "(";
1894 bFirst = !dumpBaseMembers(out, base, true);
1895 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1896 if (!bFirst) {
1897 out << ", ";
1899 dumpType(out, member.type, true, true);
1900 out << " " << member.name << "_";
1901 bFirst = false;
1903 out << ")\n";
1904 inc();
1905 bFirst = true;
1906 if (!base.isEmpty()) {
1907 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1908 << "(";
1909 dumpBaseMembers(out, base, false);
1910 out << ")\n";
1911 bFirst = false;
1913 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1914 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
1915 << member.name << "_)\n";
1916 bFirst = false;
1918 dec();
1919 out << "{\n}\n\n";
1921 // print the operator==
1922 out << "\ninline bool operator==(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1923 out << "{\n";
1924 inc();
1925 out << indent() << "return ";
1926 bFirst = true;
1927 if (!base.isEmpty()) {
1928 out << "operator==( static_cast< " << codemaker::cpp::scopedCppName(u2b(base))
1929 << ">(the_lhs), static_cast< " << codemaker::cpp::scopedCppName(u2b(base)) << ">(the_rhs) )\n";
1930 bFirst = false;
1932 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1933 if (!bFirst)
1934 out << "\n" << indent() << indent() << "&& ";
1935 out << "the_lhs." << member.name << " == the_rhs." << member.name;
1936 bFirst = false;
1938 out << ";\n";
1939 dec();
1940 out << "}\n";
1941 // print the operator!=
1942 out << "\ninline bool operator!=(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1943 out << "{\n";
1944 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
1945 out << "}\n";
1946 // close namespace
1947 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
1948 out << "\n";
1950 out << "\n";
1951 dumpGetCppuType(out);
1952 out << "\n#endif // "<< headerDefine << "\n";
1955 void PlainStructType::dumpLightGetCppuType(FileStream & out)
1957 dumpGetCppuTypePreamble(out);
1958 out << indent()
1959 << ("//TODO: On certain platforms with weak memory models, the"
1960 " following code can result in some threads observing that the_type"
1961 " points to garbage\n")
1962 << indent()
1963 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1964 << indent() << "if (the_type == 0) {\n";
1965 inc();
1966 out << indent() << "::typelib_static_type_init(&the_type, "
1967 << getTypeClass(name_, true) << ", \"" << name_ << "\");\n";
1968 dec();
1969 out << indent() << "}\n" << indent()
1970 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
1971 dumpGetCppuTypePostamble(out);
1974 void PlainStructType::dumpNormalGetCppuType(FileStream & out)
1976 dumpGetCppuTypePreamble(out);
1977 out << indent()
1978 << ("//TODO: On certain platforms with weak memory models, the"
1979 " following code can result in some threads observing that the_type"
1980 " points to garbage\n")
1981 << indent()
1982 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1983 << indent() << "if (the_type == 0) {\n";
1984 inc();
1985 out << indent()
1986 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
1987 inc();
1988 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
1989 entity_->getDirectMembers().begin());
1990 i != entity_->getDirectMembers().end();) {
1991 out << indent() << "::cppu::UnoType< ";
1992 dumpType(out, i->type, false, false, false, true);
1993 ++i;
1994 out << " >::get().getTypeLibType()"
1995 << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
1997 dec();
1998 out << indent() << "::typelib_static_struct_type_init(&the_type, \""
1999 << name_ << "\", ";
2000 if (entity_->getDirectBase().isEmpty()) {
2001 out << "0";
2002 } else {
2003 out << "::cppu::UnoType< ";
2004 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2005 out << " >::get().getTypeLibType()";
2007 out << ", " << entity_->getDirectMembers().size() << ", the_members, 0);\n";
2008 dec();
2009 out << indent() << "}\n" << indent()
2010 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2011 dumpGetCppuTypePostamble(out);
2014 void PlainStructType::dumpComprehensiveGetCppuType(FileStream & out)
2016 OUString staticTypeClass("the" + id_ + "Type");
2017 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
2018 out << " namespace detail {\n\n" << indent() << "struct "
2019 << staticTypeClass
2020 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2021 << staticTypeClass << " >\n" << indent() << "{\n";
2022 inc();
2023 out << indent() << "::css::uno::Type * operator()() const\n"
2024 << indent() << "{\n";
2025 inc();
2026 out << indent() << "::rtl::OUString the_name( \"" << name_ << "\" );\n";
2027 std::map< OUString, sal_uInt32 > types;
2028 std::vector< unoidl::PlainStructTypeEntity::Member >::size_type n = 0;
2029 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2030 if (types.emplace(
2031 member.type, static_cast< sal_uInt32 >(types.size())).
2032 second) {
2033 dumpCppuGetType(out, member.type, &name_);
2034 // For typedefs, use the resolved type name, as there will be no
2035 // information available about the typedef itself at runtime (the
2036 // above getCppuType call will make available information about the
2037 // resolved type); no extra #include for the resolved type is
2038 // needed, as the header for the typedef includes it already:
2039 out << indent() << "::rtl::OUString the_tname"
2040 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2041 << resolveAllTypedefs(member.type) << "\" );\n";
2043 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2044 << member.name << "\" );\n";
2046 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2047 inc();
2048 n = 0;
2049 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
2050 entity_->getDirectMembers().begin());
2051 i != entity_->getDirectMembers().end();) {
2052 out << indent() << "{ { " << getTypeClass(i->type, true)
2053 << ", the_tname" << types.find(i->type)->second
2054 << ".pData, the_name" << n++ << ".pData }, false }";
2055 ++i;
2056 out << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2058 dec();
2059 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"
2060 << indent()
2061 << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2062 if (entity_->getDirectBase().isEmpty()) {
2063 out << "0";
2064 } else {
2065 out << "::cppu::UnoType< ";
2066 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2067 out << " >::get().getTypeLibType()";
2069 out << ", " << entity_->getDirectMembers().size() << ", the_members);\n"
2070 << indent() << "::typelib_typedescription_register(&the_newType);\n"
2071 << indent() << "::typelib_typedescription_release(the_newType);\n"
2072 << indent() << "return new ::css::uno::Type("
2073 << getTypeClass(name_) << ", the_name); // leaked\n";
2074 dec();
2075 out << indent() << "}\n";
2076 dec();
2077 out << indent() << "};\n";
2078 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
2079 out << " }\n\n";
2080 dumpGetCppuTypePreamble(out);
2081 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
2082 dumpGetCppuTypePostamble(out);
2085 bool PlainStructType::dumpBaseMembers(
2086 FileStream & out, OUString const & base, bool withType)
2088 bool hasMember = false;
2089 if (!base.isEmpty()) {
2090 rtl::Reference< unoidl::Entity > ent;
2091 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2092 if (sort != codemaker::UnoType::Sort::PlainStruct) {
2093 throw CannotDumpException(
2094 "plain struct type base " + base
2095 + " is not a plain struct type");
2097 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
2098 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2099 assert(ent2.is());
2100 if (!ent2.is()) {
2101 return false;
2103 hasMember = dumpBaseMembers(out, ent2->getDirectBase(), withType);
2104 for (const unoidl::PlainStructTypeEntity::Member& member : ent2->getDirectMembers()) {
2105 if (hasMember) {
2106 out << ", ";
2108 if (withType) {
2109 dumpType(out, member.type, true, true);
2110 out << " ";
2112 out << member.name << "_";
2113 hasMember = true;
2116 return hasMember;
2119 void PlainStructType::addLightGetCppuTypeIncludes(
2120 codemaker::cppumaker::Includes & includes) const
2122 includes.addType();
2123 includes.addCppuUnotypeHxx();
2124 includes.addSalTypesH();
2125 includes.addTypelibTypeclassH();
2126 includes.addTypelibTypedescriptionH();
2129 void PlainStructType::addNormalGetCppuTypeIncludes(
2130 codemaker::cppumaker::Includes & includes) const
2132 includes.addType();
2133 includes.addCppuUnotypeHxx();
2134 includes.addSalTypesH();
2135 includes.addTypelibTypeclassH();
2136 includes.addTypelibTypedescriptionH();
2139 void PlainStructType::addComprehensiveGetCppuTypeIncludes(
2140 codemaker::cppumaker::Includes & includes) const
2142 includes.addType();
2143 includes.addCppuUnotypeHxx();
2144 includes.addRtlInstanceHxx();
2145 includes.addRtlUstringH();
2146 includes.addRtlUstringHxx();
2147 includes.addSalTypesH();
2148 includes.addTypelibTypeclassH();
2149 includes.addTypelibTypedescriptionH();
2152 sal_uInt32 PlainStructType::getTotalMemberCount(OUString const & base) const
2154 if (base.isEmpty()) {
2155 return 0;
2157 rtl::Reference< unoidl::Entity > ent;
2158 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2159 if (sort != codemaker::UnoType::Sort::PlainStruct) {
2160 throw CannotDumpException(
2161 "plain struct type base " + base + " is not a plain struct type");
2163 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
2164 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2165 assert(ent2.is());
2166 if (!ent2.is()) {
2167 return 0;
2169 return getTotalMemberCount(ent2->getDirectBase())
2170 + ent2->getDirectMembers().size(); //TODO: overflow
2173 class PolyStructType: public CppuType
2175 public:
2176 PolyStructType(
2177 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > const &
2178 entity,
2179 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2180 CppuType(name, typeMgr), entity_(entity) {
2181 assert(entity.is());
2184 private:
2185 virtual void dumpDeclaration(FileStream& o) override;
2187 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
2189 virtual void dumpLightGetCppuType(FileStream & out) override;
2191 virtual void dumpNormalGetCppuType(FileStream & out) override;
2193 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2195 virtual void addLightGetCppuTypeIncludes(
2196 codemaker::cppumaker::Includes & includes) const override;
2198 virtual void addNormalGetCppuTypeIncludes(
2199 codemaker::cppumaker::Includes & includes) const override;
2201 virtual void addComprehensiveGetCppuTypeIncludes(
2202 codemaker::cppumaker::Includes & includes) const override;
2204 virtual bool isPolymorphic() const override {
2205 return true;
2208 virtual void dumpTemplateHead(FileStream & out) const override;
2210 virtual void dumpTemplateParameters(FileStream & out) const override;
2212 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > entity_;
2215 void PolyStructType::dumpDeclaration(FileStream & out)
2217 out << "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
2218 dumpTemplateHead(out);
2219 out << "struct SAL_DLLPUBLIC_RTTI " << id_ << " {\n";
2220 inc();
2221 out << indent() << "inline " << id_ << "();\n";
2222 if (!entity_->getMembers().empty()) {
2223 out << "\n" << indent() << "inline " << id_ << "(";
2224 for (std::vector<
2225 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2226 const_iterator i(entity_->getMembers().begin());
2227 i != entity_->getMembers().end(); ++i) {
2228 if (i != entity_->getMembers().begin()) {
2229 out << ", ";
2231 if (i->parameterized) {
2232 dumpTypeParameterName(out, i->type);
2233 out << " const &";
2234 } else {
2235 dumpType(out, i->type, true, true);
2237 out << " " << i->name << "_";
2239 out << ");\n\n";
2240 // print the member fields
2241 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member :
2242 entity_->getMembers()) {
2243 out << indent();
2244 if (member.parameterized) {
2245 dumpTypeParameterName(out, member.type);
2246 } else {
2247 dumpType(out, member.type);
2249 out << " " << member.name << ";\n";
2252 dec();
2253 out << "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
2256 void PolyStructType::dumpHppFile(
2257 FileStream & out, codemaker::cppumaker::Includes & includes)
2259 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
2260 out << "\n";
2261 includes.dump(out, &name_, true);
2262 out << "\n";
2263 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2264 out << "\n";
2266 out << "\n";
2267 // dump default (no-arg) constructor
2268 dumpTemplateHead(out);
2269 out << "inline " << id_;
2270 dumpTemplateParameters(out);
2271 out << "::" << id_ << "()\n";
2272 inc();
2273 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2274 const_iterator i(entity_->getMembers().begin());
2275 i != entity_->getMembers().end(); ++i) {
2276 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2277 << " " << i->name;
2278 dumpInitializer(out, i->parameterized, i->type);
2279 out << "\n";
2281 dec();
2282 out << "{\n}\n\n";
2283 if (!entity_->getMembers().empty()) {
2284 // dump takes-all-fields constructor
2285 dumpTemplateHead(out);
2286 out << "inline " << id_;
2287 dumpTemplateParameters(out);
2288 out << "::" << id_ << "(";
2289 for (std::vector<
2290 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2291 const_iterator i(entity_->getMembers().begin());
2292 i != entity_->getMembers().end(); ++i) {
2293 if (i != entity_->getMembers().begin()) {
2294 out << ", ";
2296 if (i->parameterized) {
2297 dumpTypeParameterName(out, i->type);
2298 out << " const &";
2299 } else {
2300 dumpType(out, i->type, true, true);
2302 out << " " << i->name << "_";
2304 out << ")\n";
2305 inc();
2306 for (std::vector<
2307 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2308 const_iterator i(entity_->getMembers().begin());
2309 i != entity_->getMembers().end(); ++i) {
2310 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2311 << " " << i->name << "(" << i->name << "_)\n";
2313 dec();
2314 out << "{\n}\n\n" << indent();
2315 // dump make_T method
2316 dumpTemplateHead(out);
2317 out << "\n" << indent() << "inline " << id_;
2318 dumpTemplateParameters(out);
2319 out << "\n" << indent() << "make_" << id_ << "(";
2320 for (std::vector<
2321 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2322 const_iterator i(entity_->getMembers().begin());
2323 i != entity_->getMembers().end(); ++i) {
2324 if (i != entity_->getMembers().begin()) {
2325 out << ", ";
2327 if (i->parameterized) {
2328 dumpTypeParameterName(out, i->type);
2329 out << " const &";
2330 } else {
2331 dumpType(out, i->type, true, true);
2333 out << " " << i->name << "_";
2335 out << ")\n" << indent() << "{\n";
2336 inc();
2337 out << indent() << "return " << id_;
2338 dumpTemplateParameters(out);
2339 out << "(";
2340 for (std::vector<
2341 unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2342 const_iterator i(entity_->getMembers().begin());
2343 i != entity_->getMembers().end(); ++i) {
2344 if (i != entity_->getMembers().begin()) {
2345 out << ", ";
2347 out << i->name << "_";
2349 out << ");\n";
2350 dec();
2351 out << indent() << "}\n\n";
2353 // print the operator==
2354 dumpTemplateHead(out);
2355 out << " inline bool operator==(const " << id_;
2356 dumpTemplateParameters(out);
2357 out << "& the_lhs, const " << id_;
2358 dumpTemplateParameters(out);
2359 out << "& the_rhs)\n";
2360 out << "{\n";
2361 inc();
2362 out << indent() << "return ";
2363 bool bFirst = true;
2364 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2365 if (!bFirst)
2366 out << "\n" << indent() << indent() << "&& ";
2367 out << "the_lhs." << member.name << " == the_rhs." << member.name;
2368 bFirst = false;
2370 out << ";\n";
2371 dec();
2372 out << "}\n";
2373 // print the operator!=
2374 dumpTemplateHead(out);
2375 out << " inline bool operator!=(const " << id_;
2376 dumpTemplateParameters(out);
2377 out << "& the_lhs, const " << id_;
2378 dumpTemplateParameters(out);
2379 out << "& the_rhs)\n";
2380 out << "{\n";
2381 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
2382 out << "}\n";
2383 // close namespace
2384 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2385 out << "\n";
2387 out << "\n";
2388 dumpGetCppuType(out);
2389 out << "\n#endif // "<< headerDefine << "\n";
2392 void PolyStructType::dumpLightGetCppuType(FileStream & out)
2394 dumpGetCppuTypePreamble(out);
2395 out << indent()
2396 << ("//TODO: On certain platforms with weak memory models, the"
2397 " following code can result in some threads observing that the_type"
2398 " points to garbage\n")
2399 << indent()
2400 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2401 << indent() << "if (the_type == 0) {\n";
2402 inc();
2403 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2404 << "<\");\n";
2405 for (std::vector< OUString >::const_iterator i(
2406 entity_->getTypeParameters().begin());
2407 i != entity_->getTypeParameters().end();) {
2408 out << indent()
2409 << ("the_buffer.append(::rtl::OUStringToOString("
2410 "::cppu::getTypeFavourChar(static_cast< ");
2411 dumpTypeParameterName(out, *i);
2412 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2413 ++i;
2414 if (i != entity_->getTypeParameters().end()) {
2415 out << indent() << "the_buffer.append(',');\n";
2418 out << indent() << "the_buffer.append('>');\n" << indent()
2419 << "::typelib_static_type_init(&the_type, " << getTypeClass(name_, true)
2420 << ", the_buffer.getStr());\n";
2421 dec();
2422 out << indent() << "}\n" << indent()
2423 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2424 dumpGetCppuTypePostamble(out);
2427 void PolyStructType::dumpNormalGetCppuType(FileStream & out)
2429 dumpGetCppuTypePreamble(out);
2430 out << indent()
2431 << ("//TODO: On certain platforms with weak memory models, the"
2432 " following code can result in some threads observing that the_type"
2433 " points to garbage\n")
2434 << indent()
2435 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2436 << indent() << "if (the_type == 0) {\n";
2437 inc();
2438 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2439 << "<\");\n";
2440 for (std::vector< OUString >::const_iterator i(
2441 entity_->getTypeParameters().begin());
2442 i != entity_->getTypeParameters().end();) {
2443 out << indent()
2444 << ("the_buffer.append(::rtl::OUStringToOString("
2445 "::cppu::getTypeFavourChar(static_cast< ");
2446 dumpTypeParameterName(out, *i);
2447 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2448 ++i;
2449 if (i != entity_->getTypeParameters().end()) {
2450 out << indent() << "the_buffer.append(',');\n";
2453 out << indent() << "the_buffer.append('>');\n" << indent()
2454 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2455 inc();
2456 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2457 const_iterator i(entity_->getMembers().begin());
2458 i != entity_->getMembers().end();) {
2459 out << indent();
2460 if (i->parameterized) {
2461 out << "::cppu::getTypeFavourChar(static_cast< ";
2462 dumpTypeParameterName(out, i->type);
2463 out << " * >(0))";
2464 } else {
2465 out << "::cppu::UnoType< ";
2466 dumpType(out, i->type, false, false, false, true);
2467 out << " >::get()";
2469 ++i;
2470 out << ".getTypeLibType()"
2471 << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2473 dec();
2474 out << indent() << "static ::sal_Bool const the_parameterizedTypes[] = { ";
2475 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2476 const_iterator i(entity_->getMembers().begin());
2477 i != entity_->getMembers().end(); ++i) {
2478 if (i != entity_->getMembers().begin()) {
2479 out << ", ";
2481 out << (i->parameterized ? "true" : "false");
2483 out << " };\n" << indent()
2484 << ("::typelib_static_struct_type_init(&the_type, the_buffer.getStr(),"
2485 " 0, ")
2486 << entity_->getMembers().size()
2487 << ", the_members, the_parameterizedTypes);\n";
2488 dec();
2489 out << indent() << "}\n" << indent()
2490 << ("return *reinterpret_cast< ::css::uno::Type * >("
2491 "&the_type);\n");
2492 dumpGetCppuTypePostamble(out);
2495 void PolyStructType::dumpComprehensiveGetCppuType(FileStream & out)
2497 out << "namespace cppu { namespace detail {\n\n" << indent();
2498 dumpTemplateHead(out);
2499 OUString staticTypeClass("the" + id_ + "Type");
2500 out << "struct " << staticTypeClass
2501 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2502 << staticTypeClass;
2503 dumpTemplateParameters(out);
2504 out << " >\n" << indent() << "{\n";
2505 inc();
2506 out << indent() << "::css::uno::Type * operator()() const\n"
2507 << indent() << "{\n";
2508 inc();
2509 out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent()
2510 << "the_buffer.append(\"" << name_ << "<\");\n";
2511 for (std::vector< OUString >::const_iterator i(
2512 entity_->getTypeParameters().begin());
2513 i != entity_->getTypeParameters().end();) {
2514 out << indent()
2515 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2516 dumpTypeParameterName(out, *i);
2517 out << " * >(0)).getTypeName());\n";
2518 ++i;
2519 if (i != entity_->getTypeParameters().end()) {
2520 out << indent()
2521 << ("the_buffer.append("
2522 "static_cast< ::sal_Unicode >(','));\n");
2525 out << indent() << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n"
2526 << indent()
2527 << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2528 std::map< OUString, sal_uInt32 > parameters;
2529 std::map< OUString, sal_uInt32 > types;
2530 std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2531 size_type n = 0;
2532 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2533 if (member.parameterized) {
2534 if (parameters.emplace(
2535 member.type, static_cast< sal_uInt32 >(parameters.size())).
2536 second) {
2537 sal_uInt32 k = static_cast< sal_uInt32 >(parameters.size() - 1);
2538 out << indent()
2539 << "::css::uno::Type const & the_ptype" << k
2540 << " = ::cppu::getTypeFavourChar(static_cast< ";
2541 dumpTypeParameterName(out, member.type);
2542 out << " * >(0));\n" << indent()
2543 << "::typelib_TypeClass the_pclass" << k
2544 << " = (::typelib_TypeClass) the_ptype" << k
2545 << ".getTypeClass();\n" << indent()
2546 << "::rtl::OUString the_pname" << k << "(the_ptype" << k
2547 << ".getTypeName());\n";
2549 } else if (types.emplace(member.type, static_cast< sal_uInt32 >(types.size())).
2550 second) {
2551 dumpCppuGetType(out, member.type, &name_);
2552 // For typedefs, use the resolved type name, as there will be no
2553 // information available about the typedef itself at runtime (the
2554 // above getCppuType call will make available information about the
2555 // resolved type); no extra #include for the resolved type is
2556 // needed, as the header for the typedef includes it already:
2557 out << indent() << "::rtl::OUString the_tname"
2558 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2559 << resolveAllTypedefs(member.type) << "\" );\n";
2561 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2562 << member.name << "\" );\n";
2564 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2565 inc();
2566 n = 0;
2567 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2568 const_iterator i(entity_->getMembers().begin());
2569 i != entity_->getMembers().end();) {
2570 out << indent() << "{ { ";
2571 if (i->parameterized) {
2572 sal_uInt32 k = parameters.find(i->type)->second;
2573 out << "the_pclass" << k << ", the_pname" << k << ".pData";
2574 } else {
2575 out << getTypeClass(i->type, true) << ", the_tname"
2576 << types.find(i->type)->second << ".pData";
2578 out << ", the_name" << n++ << ".pData }, "
2579 << (i->parameterized ? "true" : "false") << " }";
2580 ++i;
2581 out << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2583 dec();
2584 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2585 out << indent()
2586 << ("::typelib_typedescription_newStruct(&the_newType, the_name.pData,"
2587 " 0, ")
2588 << entity_->getMembers().size() << ", the_members);\n" << indent()
2589 << "::typelib_typedescription_register(&the_newType);\n" << indent()
2590 << "::typelib_typedescription_release(the_newType);\n" << indent()
2591 << "return new ::css::uno::Type(" << getTypeClass(name_)
2592 << ", the_name); // leaked\n";
2593 dec();
2594 out << indent() << "}\n";
2595 dec();
2596 out << indent() << "};\n } }\n\n";
2597 dumpGetCppuTypePreamble(out);
2598 out << indent() << "return *detail::" << staticTypeClass;
2599 dumpTemplateParameters(out);
2600 out << "::get();\n";
2601 dumpGetCppuTypePostamble(out);
2604 void PolyStructType::addLightGetCppuTypeIncludes(
2605 codemaker::cppumaker::Includes & includes) const
2607 includes.addType();
2608 includes.addCppuUnotypeHxx();
2609 includes.addSalTypesH();
2610 includes.addTypelibTypeclassH();
2611 includes.addTypelibTypedescriptionH();
2612 includes.addRtlStrbufHxx();
2613 includes.addRtlTextencH();
2614 includes.addRtlUstringHxx();
2617 void PolyStructType::addNormalGetCppuTypeIncludes(
2618 codemaker::cppumaker::Includes & includes) const
2620 includes.addType();
2621 includes.addCppuUnotypeHxx();
2622 includes.addSalTypesH();
2623 includes.addTypelibTypeclassH();
2624 includes.addTypelibTypedescriptionH();
2625 includes.addRtlStrbufHxx();
2626 includes.addRtlTextencH();
2627 includes.addRtlUstringHxx();
2630 void PolyStructType::addComprehensiveGetCppuTypeIncludes(
2631 codemaker::cppumaker::Includes & includes) const
2633 includes.addType();
2634 includes.addCppuUnotypeHxx();
2635 includes.addRtlInstanceHxx();
2636 includes.addRtlUstringH();
2637 includes.addRtlUstringHxx();
2638 includes.addSalTypesH();
2639 includes.addTypelibTypeclassH();
2640 includes.addTypelibTypedescriptionH();
2641 includes.addRtlStringH();
2642 includes.addRtlUstrbufHxx();
2645 void PolyStructType::dumpTemplateHead(FileStream & out) const
2647 out << "template< ";
2648 for (std::vector< OUString >::const_iterator i(
2649 entity_->getTypeParameters().begin());
2650 i != entity_->getTypeParameters().end(); ++i) {
2651 if (i != entity_->getTypeParameters().begin()) {
2652 out << ", ";
2654 out << "typename ";
2655 dumpTypeParameterName(out, *i);
2657 out << " > ";
2660 void PolyStructType::dumpTemplateParameters(FileStream & out) const
2662 out << "< ";
2663 for (std::vector< OUString >::const_iterator i(
2664 entity_->getTypeParameters().begin());
2665 i != entity_->getTypeParameters().end(); ++i) {
2666 if (i != entity_->getTypeParameters().begin()) {
2667 out << ", ";
2669 dumpTypeParameterName(out, *i);
2671 out << " >";
2674 OUString typeToIdentifier(OUString const & name)
2676 sal_Int32 k;
2677 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k)));
2678 OUStringBuffer b;
2679 for (sal_Int32 i = 0; i != k; ++i) {
2680 b.append("seq_");
2682 b.append(n);
2683 b.replace(' ', '_');
2684 b.replace(',', '_');
2685 b.replace('.', '_');
2686 b.replace('<', '_');
2687 b.replace('>', '_');
2688 return b.makeStringAndClear();
2691 class ExceptionType: public CppuType
2693 public:
2694 ExceptionType(
2695 rtl::Reference< unoidl::ExceptionTypeEntity > const & entity,
2696 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2697 CppuType(name, typeMgr), entity_(entity) {
2698 assert(entity.is());
2701 private:
2702 virtual void dumpHppFile(
2703 FileStream & out, codemaker::cppumaker::Includes & includes) override;
2705 virtual void addComprehensiveGetCppuTypeIncludes(
2706 codemaker::cppumaker::Includes & includes) const override;
2708 virtual void dumpLightGetCppuType(FileStream & out) override;
2710 virtual void dumpNormalGetCppuType(FileStream & out) override;
2712 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2714 virtual sal_uInt32 checkInheritedMemberCount() const override {
2715 return getTotalMemberCount(entity_->getDirectBase());
2718 virtual void dumpDeclaration(FileStream & out) override;
2720 bool dumpBaseMembers(
2721 FileStream & out, OUString const & base, bool withType,
2722 bool eligibleForDefaults);
2724 sal_uInt32 getTotalMemberCount(OUString const & base) const;
2726 rtl::Reference< unoidl::ExceptionTypeEntity > entity_;
2729 void ExceptionType::addComprehensiveGetCppuTypeIncludes(
2730 codemaker::cppumaker::Includes & includes) const
2732 includes.addCppuUnotypeHxx();
2733 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
2736 void ExceptionType::dumpHppFile(
2737 FileStream & out, codemaker::cppumaker::Includes & includes)
2739 OUString headerDefine(dumpHeaderDefine(out, "HPP"));
2740 out << "\n";
2741 addDefaultHxxIncludes(includes);
2742 includes.dump(out, &name_, true);
2744 // for the output operator below
2745 if (name_ == "com.sun.star.uno.Exception")
2747 out << "#if defined LIBO_INTERNAL_ONLY\n";
2748 out << "#include <ostream>\n";
2749 out << "#include <typeinfo>\n";
2750 out << "#endif\n";
2753 out << "\n";
2755 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2756 out << "\n";
2758 out << "\ninline " << id_ << "::" << id_ << "()\n";
2759 inc();
2760 OUString base(entity_->getDirectBase());
2761 bool bFirst = true;
2762 if (!base.isEmpty()) {
2763 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2764 << "()\n";
2765 bFirst = false;
2767 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2768 out << indent() << (bFirst ? ":" : ",") << " ";
2769 out << member.name;
2770 dumpInitializer(out, false, member.type);
2771 out << "\n";
2772 bFirst = false;
2774 dec();
2775 out << "{";
2776 if (!m_cppuTypeDynamic) {
2777 out << "\n";
2778 inc();
2779 dumpCppuGetType(out, name_);
2780 dec();
2781 } else {
2782 out << " ";
2784 out << "}\n\n";
2785 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
2786 out << indent() << "inline " << id_ << "::" << id_ << "(";
2787 bFirst = !dumpBaseMembers(out, base, true, false);
2788 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2789 if (!bFirst) {
2790 out << ", ";
2792 dumpType(out, member.type, true, true);
2793 out << " " << member.name << "_";
2794 bFirst = false;
2796 out << ")\n";
2797 inc();
2798 bFirst = true;
2799 if (!base.isEmpty()) {
2800 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2801 << "(";
2802 dumpBaseMembers(out, base, false, false);
2803 out << ")\n";
2804 bFirst = false;
2806 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2807 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
2808 << member.name << "_)\n";
2809 bFirst = false;
2811 dec();
2812 out << "{";
2813 if (!m_cppuTypeDynamic) {
2814 out << "\n";
2815 inc();
2816 dumpCppuGetType(out, name_);
2817 dec();
2818 } else {
2819 out << " ";
2821 out << "}\n\n";
2823 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent() << id_ << "::" << id_
2824 << "(" << id_ << " const & the_other)";
2825 bFirst = true;
2826 if (!base.isEmpty()) {
2827 out << ": " << codemaker::cpp::scopedCppName(u2b(base))
2828 << "(the_other)";
2829 bFirst = false;
2831 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2832 out << (bFirst ? ":" : ",") << " " << member.name << "(the_other." << member.name
2833 << ")";
2834 bFirst = false;
2836 out << indent() << " {}\n\n" << indent() << id_ << "::~" << id_
2837 << "() {}\n\n" << indent() << id_ << " & " << id_ << "::operator =("
2838 << id_ << " const & the_other) {\n";
2839 inc();
2840 out << indent()
2841 << ("//TODO: Just like its implicitly-defined counterpart, this"
2842 " function definition is not exception-safe\n");
2843 if (!base.isEmpty()) {
2844 out << indent() << codemaker::cpp::scopedCppName(u2b(base))
2845 << "::operator =(the_other);\n";
2847 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2848 out << indent() << member.name << " = the_other." << member.name << ";\n";
2850 out << indent() << "return *this;\n";
2851 dec();
2852 out << indent() << "}\n#endif\n\n";
2854 // Provide an output operator for printing Exception information to SAL_WARN/SAL_INFO.
2855 if (name_ == "com.sun.star.uno.Exception")
2857 out << "#if defined LIBO_INTERNAL_ONLY\n";
2858 out << "template< typename charT, typename traits >\n";
2859 out << "inline ::std::basic_ostream<charT, traits> & operator<<(\n";
2860 out << " ::std::basic_ostream<charT, traits> & os, ::com::sun::star::uno::Exception const & exception)\n";
2861 out << "{\n";
2862 out << " // the class name is useful because exception throwing code does not always pass in a useful message\n";
2863 out << " os << typeid(exception).name();\n";
2864 out << " if (!exception.Message.isEmpty())\n";
2865 out << " os << \" msg: \" << exception.Message;\n";
2866 out << " return os;\n";
2867 out << "}\n";
2868 out << "#endif\n";
2869 out << "\n";
2872 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2873 out << "\n";
2875 out << "\n";
2877 dumpGetCppuType(out);
2878 out << "\n#endif // "<< headerDefine << "\n";
2881 void ExceptionType::dumpLightGetCppuType(FileStream & out)
2883 dumpGetCppuTypePreamble(out);
2884 out << indent()
2885 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
2886 << indent() << "if ( !the_type )\n" << indent() << "{\n";
2887 inc();
2888 out << indent() << "typelib_static_type_init( &the_type, "
2889 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
2890 dec();
2891 out << indent() << "}\n" << indent()
2892 << ("return * reinterpret_cast< ::css::uno::Type * >("
2893 " &the_type );\n");
2894 dumpGetCppuTypePostamble(out);
2897 void ExceptionType::dumpNormalGetCppuType(FileStream & out)
2899 dumpGetCppuTypePreamble(out);
2900 out << indent()
2901 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
2902 << indent() << "if ( !the_type )\n" << indent() << "{\n";
2903 inc();
2904 OUString base(entity_->getDirectBase());
2905 bool baseException = false;
2906 if (!base.isEmpty()) {
2907 if (base == "com.sun.star.uno.Exception") {
2908 baseException = true;
2909 } else {
2910 out << indent()
2911 << ("const ::css::uno::Type& rBaseType ="
2912 " ::cppu::UnoType< ");
2913 dumpType(out, base, true, false, false, true);
2914 out << " >::get();\n\n";
2917 if (!entity_->getDirectMembers().empty()) {
2918 out << indent() << "typelib_TypeDescriptionReference * aMemberRefs["
2919 << entity_->getDirectMembers().size() << "];\n";
2920 std::set< OUString > seen;
2921 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
2922 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2923 OUString type(resolveAllTypedefs(member.type));
2924 OUString modType(typeToIdentifier(type));
2925 if (seen.insert(type).second) {
2926 out << indent()
2927 << "const ::css::uno::Type& rMemberType_"
2928 << modType << " = ::cppu::UnoType< ";
2929 dumpType(out, type, false, false, false, true);
2930 out << " >::get();\n";
2932 out << indent() << "aMemberRefs[" << n++ << "] = rMemberType_"
2933 << modType << ".getTypeLibType();\n";
2935 out << "\n";
2937 out << indent() << "typelib_static_compound_type_init( &the_type, "
2938 << getTypeClass(name_, true) << ", \"" << name_ << "\", ";
2939 if (baseException) {
2940 out << ("* ::typelib_static_type_getByTypeClass("
2941 " typelib_TypeClass_EXCEPTION )");
2942 } else if (base.isEmpty()) {
2943 out << "0";
2944 } else {
2945 out << "rBaseType.getTypeLibType()";
2947 out << ", " << entity_->getDirectMembers().size() << ", "
2948 << (entity_->getDirectMembers().empty() ? "0" : "aMemberRefs")
2949 << " );\n";
2950 dec();
2951 out << indent() << "}\n" << indent()
2952 << ("return * reinterpret_cast< const ::css::uno::Type * >("
2953 " &the_type );\n");
2954 dumpGetCppuTypePostamble(out);
2957 void ExceptionType::dumpComprehensiveGetCppuType(FileStream & out)
2959 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
2960 out << " namespace detail {\n\n";
2961 OUString staticTypeClass("the" + id_ + "Type");
2962 out << indent() << "struct " << staticTypeClass
2963 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2964 << staticTypeClass << " >\n" << indent() << "{\n";
2965 inc();
2966 out << indent() << "::css::uno::Type * operator()() const\n"
2967 << indent() << "{\n";
2968 inc();
2969 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
2970 << indent() << "// Start inline typedescription generation\n"
2971 << indent() << "typelib_TypeDescription * pTD = 0;\n";
2972 OUString base(entity_->getDirectBase());
2973 if (!base.isEmpty()) {
2974 out << indent()
2975 << ("const ::css::uno::Type& rSuperType ="
2976 " ::cppu::UnoType< ");
2977 dumpType(out, base, false, false, false, true);
2978 out << " >::get();\n";
2980 std::set< OUString > seen;
2981 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2982 if (seen.insert(member.type).second) {
2983 dumpCppuGetType(out, member.type);
2986 if (!entity_->getDirectMembers().empty()) {
2987 out << "\n" << indent() << "typelib_CompoundMember_Init aMembers["
2988 << entity_->getDirectMembers().size() << "];\n";
2989 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
2990 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2991 OUString type(resolveAllTypedefs(member.type));
2992 out << indent() << "::rtl::OUString sMemberType" << n << "( \""
2993 << type << "\" );\n" << indent()
2994 << "::rtl::OUString sMemberName" << n << "( \"" << member.name
2995 << "\" );\n" << indent() << "aMembers[" << n
2996 << "].eTypeClass = (typelib_TypeClass)" << getTypeClass(type)
2997 << ";\n" << indent() << "aMembers[" << n
2998 << "].pTypeName = sMemberType" << n << ".pData;\n" << indent()
2999 << "aMembers[" << n << "].pMemberName = sMemberName" << n
3000 << ".pData;\n";
3001 ++n;
3004 out << "\n" << indent() << "typelib_typedescription_new(\n";
3005 inc();
3006 out << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)"
3007 << getTypeClass(name_) << ", sTypeName.pData,\n" << indent()
3008 << (base.isEmpty() ? "0" : "rSuperType.getTypeLibType()") << ",\n"
3009 << indent() << entity_->getDirectMembers().size() << ",\n" << indent()
3010 << (entity_->getDirectMembers().empty() ? "0" : "aMembers")
3011 << " );\n\n";
3012 dec();
3013 out << indent()
3014 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3015 " );\n\n")
3016 << indent() << "typelib_typedescription_release( pTD );\n" << indent()
3017 << "// End inline typedescription generation\n\n" << indent()
3018 << "return new ::css::uno::Type( " << getTypeClass(name_)
3019 << ", sTypeName ); // leaked\n";
3020 dec();
3021 out << indent() << "}\n";
3022 dec();
3023 out << indent() << "};\n\n";
3024 codemaker::cppumaker::dumpNamespaceClose(out, name_, false);
3025 out << " }\n\n";
3026 dumpGetCppuTypePreamble(out);
3027 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
3028 dumpGetCppuTypePostamble(out);
3031 void ExceptionType::dumpDeclaration(FileStream & out)
3033 out << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT SAL_WARN_UNUSED " << id_;
3034 OUString base(entity_->getDirectBase());
3035 if (!base.isEmpty()) {
3036 out << " : public " << codemaker::cpp::scopedCppName(u2b(base));
3038 out << "\n{\npublic:\n";
3039 inc();
3040 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3041 << "();\n\n";
3042 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
3043 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(";
3044 bool eligibleForDefaults = entity_->getDirectMembers().empty();
3045 bool bFirst = !dumpBaseMembers(out, base, true, eligibleForDefaults);
3046 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3047 if (!bFirst) {
3048 out << ", ";
3050 dumpType(out, member.type, true, true);
3051 out << " " << member.name << "_";
3052 bFirst = false;
3054 out << ");\n\n";
3056 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent()
3057 << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(" << id_
3058 << " const &);\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE ~"
3059 << id_ << "();\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3060 << " & operator =(" << id_ << " const &);\n#endif\n\n";
3061 for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
3062 entity_->getDirectMembers().begin());
3063 i != entity_->getDirectMembers().end(); ++i) {
3064 out << indent();
3065 dumpType(out, i->type);
3066 out << " " << i->name;
3067 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
3068 && i->type != "hyper" && i->type != "unsigned hyper"
3069 && i->type != "double") {
3070 out << " CPPU_GCC3_ALIGN( "
3071 << codemaker::cpp::scopedCppName(u2b(base)) << " )";
3073 out << ";\n";
3075 dec();
3076 out << "};\n\n";
3079 bool ExceptionType::dumpBaseMembers(
3080 FileStream & out, OUString const & base, bool withType, bool eligibleForDefaults)
3082 bool hasMember = false;
3083 if (!base.isEmpty()) {
3084 rtl::Reference< unoidl::Entity > ent;
3085 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3086 if (sort != codemaker::UnoType::Sort::Exception) {
3087 throw CannotDumpException(
3088 "exception type base " + base + " is not an exception type");
3090 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
3091 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()));
3092 assert(ent2.is());
3093 if (!ent2.is()) {
3094 return false;
3096 hasMember = dumpBaseMembers( out, ent2->getDirectBase(), withType,
3097 eligibleForDefaults && ent2->getDirectMembers().empty() );
3098 int memberCount = 0;
3099 for (const unoidl::ExceptionTypeEntity::Member& member : ent2->getDirectMembers()) {
3100 if (hasMember) {
3101 out << ", ";
3103 if (withType) {
3104 dumpType(out, member.type, true, true);
3105 out << " ";
3107 out << member.name << "_";
3108 // We want to provide a default parameter value for uno::Exception subtype
3109 // constructors, since most of the time we don't pass a Context object in to the exception
3110 // throw sites.
3111 if (eligibleForDefaults
3112 && base == "com.sun.star.uno.Exception"
3113 && memberCount == 1
3114 && member.name == "Context"
3115 && member.type == "com.sun.star.uno.XInterface") {
3116 out << " = ::css::uno::Reference< ::css::uno::XInterface >()";
3118 hasMember = true;
3119 ++memberCount;
3122 return hasMember;
3125 sal_uInt32 ExceptionType::getTotalMemberCount(OUString const & base) const
3127 if (base.isEmpty()) {
3128 return 0;
3130 rtl::Reference< unoidl::Entity > ent;
3131 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3132 if (sort != codemaker::UnoType::Sort::Exception) {
3133 throw CannotDumpException(
3134 "exception type base " + base + " is not an exception type");
3136 unoidl::ExceptionTypeEntity& ent2(dynamic_cast<unoidl::ExceptionTypeEntity&>(*ent));
3137 return getTotalMemberCount(ent2.getDirectBase())
3138 + ent2.getDirectMembers().size(); //TODO: overflow
3141 class EnumType: public CppuType
3143 public:
3144 EnumType(
3145 rtl::Reference< unoidl::EnumTypeEntity > const & entity,
3146 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3147 CppuType(name, typeMgr), entity_(entity) {
3148 assert(entity.is());
3151 private:
3152 virtual void dumpDeclaration(FileStream& o) override;
3154 virtual void addComprehensiveGetCppuTypeIncludes(
3155 codemaker::cppumaker::Includes & includes) const override;
3157 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3159 void dumpNormalGetCppuType(FileStream& o) override;
3160 void dumpComprehensiveGetCppuType(FileStream& o) override;
3162 rtl::Reference< unoidl::EnumTypeEntity > entity_;
3165 void EnumType::addComprehensiveGetCppuTypeIncludes(
3166 codemaker::cppumaker::Includes & includes) const
3168 includes.addCppuUnotypeHxx();
3169 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
3172 void EnumType::dumpDeclaration(FileStream& o)
3174 o << "\n#if defined LIBO_INTERNAL_ONLY\n";
3175 o << "\nenum class SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3176 o << "\n#else\n";
3177 o << "\nenum SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3178 o << "\n#endif\n";
3179 inc();
3181 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3182 o << indent() << id_ << "_" << u2b(member.name) << " = " << member.value
3183 << ",\n";
3186 o << indent() << id_ << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3188 dec();
3189 o << "};\n\n";
3191 // use constexpr to create a kind of type-alias so we don't have to modify existing code
3192 o << "#if defined LIBO_INTERNAL_ONLY\n";
3193 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3194 o << "constexpr auto " << id_ << "_" << u2b(member.name)
3195 << " = "
3196 << id_ << "::" << id_ << "_" << u2b(member.name)
3197 << ";\n";
3199 o << "#endif\n";
3202 void EnumType::dumpHppFile(
3203 FileStream& o, codemaker::cppumaker::Includes & includes)
3205 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3206 o << "\n";
3208 addDefaultHxxIncludes(includes);
3209 includes.dump(o, &name_, true);
3210 o << "\n";
3212 dumpGetCppuType(o);
3214 o << "\n#endif // "<< headerDefine << "\n";
3217 void EnumType::dumpNormalGetCppuType(FileStream& o)
3219 dumpGetCppuTypePreamble(o);
3221 o << indent()
3222 << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3224 o << indent() << "if ( !the_type )\n" << indent() << "{\n";
3225 inc();
3227 o << indent() << "typelib_static_enum_type_init( &the_type,\n";
3228 inc(31);
3229 o << indent() << "\"" << name_ << "\",\n"
3230 << indent() << codemaker::cpp::scopedCppName(u2b(name_)) << "_"
3231 << u2b(entity_->getMembers()[0].name) << " );\n";
3232 dec(31);
3233 dec();
3234 o << indent() << "}\n";
3235 o << indent()
3236 << ("return * reinterpret_cast< ::css::uno::Type * >("
3237 " &the_type );\n");
3238 dumpGetCppuTypePostamble(o);
3241 void EnumType::dumpComprehensiveGetCppuType(FileStream& o)
3243 if (!isPolymorphic())
3244 codemaker::cppumaker::dumpNamespaceOpen(o, name_, false);
3245 else
3246 o << "namespace cppu { ";
3247 o << " namespace detail {\n\n";
3249 OUString sStaticTypeClass("the" + id_ + "Type");
3250 o << indent() << "struct " << sStaticTypeClass << " : public rtl::StaticWithInit< ::css::uno::Type *, " << sStaticTypeClass << " >\n";
3251 o << indent() << "{\n";
3252 inc();
3253 o << indent() << "::css::uno::Type * operator()() const\n";
3254 o << indent() << "{\n";
3256 inc();
3257 o << indent() << "::rtl::OUString sTypeName( \"" << name_
3258 << "\" );\n\n";
3260 o << indent() << "// Start inline typedescription generation\n"
3261 << indent() << "typelib_TypeDescription * pTD = 0;\n\n";
3263 o << indent() << "rtl_uString* enumValueNames["
3264 << entity_->getMembers().size() << "];\n";
3265 std::vector< unoidl::EnumTypeEntity::Member >::size_type n = 0;
3266 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3267 o << indent() << "::rtl::OUString sEnumValue" << n << "( \""
3268 << u2b(member.name) << "\" );\n";
3269 o << indent() << "enumValueNames[" << n << "] = sEnumValue" << n
3270 << ".pData;\n";
3271 ++n;
3274 o << "\n" << indent() << "sal_Int32 enumValues["
3275 << entity_->getMembers().size() << "];\n";
3276 n = 0;
3277 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3278 o << indent() << "enumValues[" << n++ << "] = " << member.value << ";\n";
3281 o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3282 inc();
3283 o << indent() << "sTypeName.pData,\n"
3284 << indent() << "(sal_Int32)"
3285 << codemaker::cpp::scopedCppName(u2b(name_), false) << "_"
3286 << u2b(entity_->getMembers()[0].name) << ",\n"
3287 << indent() << entity_->getMembers().size()
3288 << ", enumValueNames, enumValues );\n\n";
3289 dec();
3291 o << indent()
3292 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3293 " );\n");
3294 o << indent() << "typelib_typedescription_release( pTD );\n"
3295 << indent() << "// End inline typedescription generation\n\n";
3297 o << indent() << "return new ::css::uno::Type( "
3298 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
3300 dec();
3301 o << indent() << "}\n";
3302 dec();
3303 o << indent() << "};\n\n";
3305 if (!isPolymorphic())
3306 codemaker::cppumaker::dumpNamespaceClose(o, name_, false);
3307 else
3308 o << " }";
3309 o << " }\n\n";
3311 dumpGetCppuTypePreamble(o);
3312 o << indent() << "return *detail::" << sStaticTypeClass << "::get();\n";
3313 dumpGetCppuTypePostamble(o);
3316 class Typedef: public CppuType
3318 public:
3319 Typedef(
3320 rtl::Reference< unoidl::TypedefEntity > const & entity,
3321 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3322 CppuType(name, typeMgr), entity_(entity) {
3323 assert(entity.is());
3326 private:
3327 virtual void dumpDeclaration(FileStream& o) override;
3329 void dumpHdlFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3331 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3333 rtl::Reference< unoidl::TypedefEntity > entity_;
3336 void Typedef::dumpHdlFile(
3337 FileStream& o, codemaker::cppumaker::Includes & includes)
3339 OUString headerDefine(dumpHeaderDefine(o, "HDL"));
3340 o << "\n";
3342 addDefaultHIncludes(includes);
3343 includes.dump(o, nullptr, true);
3344 o << "\n";
3346 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3347 o << "\n";
3350 dumpDeclaration(o);
3352 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3353 o << "\n";
3356 o << "#endif // "<< headerDefine << "\n";
3359 void Typedef::dumpDeclaration(FileStream& o)
3361 o << "\ntypedef ";
3362 dumpType(o, entity_->getType());
3363 o << " " << id_ << ";\n\n";
3366 void Typedef::dumpHppFile(
3367 FileStream& o, codemaker::cppumaker::Includes & includes)
3369 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3370 o << "\n";
3372 addDefaultHxxIncludes(includes);
3373 includes.dump(o, &name_, true);
3374 o << "\n";
3376 o << "\n#endif // "<< headerDefine << "\n";
3379 class ConstructiveType: public CppuType
3381 public:
3382 ConstructiveType(
3383 OUString const & name, rtl::Reference< TypeManager > const & manager):
3384 CppuType(name, manager) {}
3386 private:
3387 virtual void dumpHdlFile(FileStream &, codemaker::cppumaker::Includes &) override {
3388 assert(false); // this cannot happen
3391 virtual void dumpFiles(OUString const & uri, CppuOptions const & options) override {
3392 dumpFile(uri, name_, true, options);
3396 bool hasRestParameter(
3397 unoidl::SingleInterfaceBasedServiceEntity::Constructor const & constructor)
3399 return !constructor.parameters.empty()
3400 && constructor.parameters.back().rest;
3403 void includeExceptions(
3404 codemaker::cppumaker::Includes & includes,
3405 codemaker::ExceptionTreeNode const * node)
3407 if (node->present) {
3408 includes.add(node->name);
3409 } else {
3410 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3411 includeExceptions(includes, pChild.get());
3416 class ServiceType: public ConstructiveType
3418 public:
3419 ServiceType(
3420 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > const &
3421 entity,
3422 OUString const & name, rtl::Reference< TypeManager > const & manager):
3423 ConstructiveType(name, manager), entity_(entity) {
3424 assert(entity.is());
3427 private:
3428 virtual void dumpHppFile(
3429 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3431 void dumpCatchClauses(
3432 FileStream & out, codemaker::ExceptionTreeNode const * node);
3434 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > entity_;
3437 void failsToSupply(
3438 FileStream & o, OUString const & service, OString const & type)
3440 o << "::rtl::OUString(\"component context fails to supply service \") + \""
3441 << service << "\" + \" of type \" + \"" << type << "\"";
3444 void ServiceType::dumpHppFile(
3445 FileStream & o, codemaker::cppumaker::Includes & includes)
3447 if (!entity_->getConstructors().empty()) {
3448 //TODO: Decide whether the types added to includes should rather be
3449 // added to m_dependencies (and thus be generated during
3450 // dumpDependedTypes):
3451 includes.addCassert();
3452 includes.addReference();
3453 includes.addRtlUstringH();
3454 includes.addRtlUstringHxx();
3455 includes.add("com.sun.star.uno.DeploymentException");
3456 includes.add("com.sun.star.uno.XComponentContext");
3457 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor& cons : entity_->getConstructors()) {
3458 if (cons.defaultConstructor) {
3459 includes.add("com.sun.star.uno.Exception");
3460 includes.add("com.sun.star.uno.RuntimeException");
3461 } else {
3462 if (!hasRestParameter(cons)) {
3463 includes.addAny();
3464 includes.addSequence();
3465 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3466 cons.parameters) {
3467 if (m_typeMgr->getSort(
3468 b2u(codemaker::UnoType::decompose(
3469 u2b(param.type))))
3470 == codemaker::UnoType::Sort::Char) {
3471 includes.addCppuUnotypeHxx();
3472 break;
3476 codemaker::ExceptionTree tree;
3477 for (const OUString& ex : cons.exceptions) {
3478 tree.add(u2b(ex), m_typeMgr);
3480 if (!tree.getRoot().present) {
3481 includes.add("com.sun.star.uno.Exception");
3482 includes.add("com.sun.star.uno.RuntimeException");
3483 includeExceptions(includes, &tree.getRoot());
3488 OString cppName(
3489 codemaker::cpp::translateUnoToCppIdentifier(
3490 u2b(id_), "service", isGlobal()));
3491 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3492 o << "\n";
3493 includes.dump(o, nullptr, true);
3494 if (!entity_->getConstructors().empty()) {
3495 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3496 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3497 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3498 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3499 << name_.replaceAll(".", "_dot_")
3500 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3501 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3502 << name_.replaceAll(".", "_dot_")
3503 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3504 << name_.replaceAll(".", "_dot_")
3505 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3506 "::css::uno::Any > const &);\n#endif\n";
3508 o << "\n";
3509 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3510 o << "\n";
3512 o << "\nclass " << cppName << " {\n";
3513 inc();
3514 if (!entity_->getConstructors().empty()) {
3515 OString baseName(u2b(entity_->getBase()));
3516 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3517 o << "public:\n";
3518 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor& cons :
3519 entity_->getConstructors()) {
3520 if (cons.defaultConstructor) {
3521 o << indent() << "static ::css::uno::Reference< "
3522 << scopedBaseName << " > "
3523 << codemaker::cpp::translateUnoToCppIdentifier(
3524 "create", "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal,
3525 &cppName)
3526 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3527 " the_context) {\n");
3528 inc();
3529 o << indent() << "assert(the_context.is());\n" << indent()
3530 << "::css::uno::Reference< " << scopedBaseName
3531 << " > the_instance;\n" << indent() << "try {\n";
3532 inc();
3533 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3534 "LO_URE_CTOR_ENV_")
3535 << name_.replaceAll(".", "_dot_")
3536 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3537 << name_.replaceAll(".", "_dot_")
3538 << ") && defined LO_URE_CTOR_FUN_"
3539 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3540 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3541 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3542 "static_cast< ::css::uno::XInterface * >((*"
3543 "LO_URE_CTOR_FUN_")
3544 << name_.replaceAll(".", "_dot_")
3545 << (")(the_context.get(), ::css::uno::Sequence<"
3546 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3547 " ::css::uno::UNO_QUERY);\n#else\n")
3548 << indent() << "the_instance = ::css::uno::Reference< "
3549 << scopedBaseName
3550 << (" >(the_context->getServiceManager()->"
3551 "createInstanceWithContext("
3552 " \"")
3553 << name_
3554 << "\", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3555 dec();
3556 o << indent()
3557 << "} catch (const ::css::uno::RuntimeException &) {\n";
3558 inc();
3559 o << indent() << "throw;\n";
3560 dec();
3561 o << indent()
3562 << "} catch (const ::css::uno::Exception & the_exception) {\n";
3563 inc();
3564 o << indent() << "throw ::css::uno::DeploymentException(";
3565 failsToSupply(o, name_, baseName);
3566 o << " + \": \" + the_exception.Message, the_context);\n";
3567 dec();
3568 o << indent() << "}\n" << indent()
3569 << "if (!the_instance.is()) {\n";
3570 inc();
3571 o << indent() << "throw ::css::uno::DeploymentException(";
3572 failsToSupply(o, name_, baseName);
3573 o << ", the_context);\n";
3574 dec();
3575 o << indent() << "}\n" << indent() << "return the_instance;\n";
3576 dec();
3577 o << indent() << "}\n\n";
3578 } else {
3579 o << indent() << "static ::css::uno::Reference< "
3580 << scopedBaseName << " > "
3581 << codemaker::cpp::translateUnoToCppIdentifier(
3582 u2b(cons.name), "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal,
3583 &cppName)
3584 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3585 " the_context");
3586 bool rest = hasRestParameter(cons);
3587 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& param :
3588 cons.parameters) {
3589 o << ", ";
3590 OUStringBuffer buf;
3591 if (param.rest) {
3592 buf.append("[]");
3594 buf.append(param.type);
3595 OUString type(buf.makeStringAndClear());
3596 bool byRef = passByReference(type);
3597 dumpType(o, type, byRef, byRef);
3598 o << " "
3599 << codemaker::cpp::translateUnoToCppIdentifier(
3600 u2b(param.name), "param", codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3602 o << ") {\n";
3603 inc();
3604 o << indent() << "assert(the_context.is());\n";
3605 if (!rest && !cons.parameters.empty()) {
3606 o << indent()
3607 << "::css::uno::Sequence< ::css::uno::Any > the_arguments("
3608 << cons.parameters.size() << ");\n";
3609 std::vector<
3610 unoidl::SingleInterfaceBasedServiceEntity::Constructor::
3611 Parameter >::size_type n = 0;
3612 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter& j :
3613 cons.parameters) {
3614 o << indent() << "the_arguments[" << n++ << "] ";
3615 OString param(
3616 codemaker::cpp::translateUnoToCppIdentifier(
3617 u2b(j.name), "param",
3618 codemaker::cpp::IdentifierTranslationMode::NonGlobal));
3619 sal_Int32 rank;
3620 if (resolveOuterTypedefs(j.type) == "any") {
3621 o << "= " << param;
3622 } else if (m_typeMgr->getSort(
3623 b2u(codemaker::UnoType::decompose(
3624 u2b(j.type), &rank)))
3625 == codemaker::UnoType::Sort::Char) {
3626 o << "= ::css::uno::Any(&" << param
3627 << ", ::cppu::UnoType< ";
3628 for (sal_Int32 k = 0; k < rank; ++k) {
3629 o << "::cppu::UnoSequenceType< ";
3631 o << "::cppu::UnoCharType";
3632 for (sal_Int32 k = 0; k < rank; ++k) {
3633 o << " >";
3635 o << " >::get())";
3636 } else {
3637 o << "<<= " << param;
3639 o << ";\n";
3642 o << indent() << "::css::uno::Reference< "
3643 << scopedBaseName << " > the_instance;\n";
3644 codemaker::ExceptionTree tree;
3645 for (const OUString& ex : cons.exceptions) {
3646 tree.add(u2b(ex), m_typeMgr);
3648 if (!tree.getRoot().present) {
3649 o << indent() << "try {\n";
3650 inc();
3652 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3653 "LO_URE_CTOR_ENV_")
3654 << name_.replaceAll(".", "_dot_")
3655 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3656 << name_.replaceAll(".", "_dot_")
3657 << ") && defined LO_URE_CTOR_FUN_"
3658 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3659 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3660 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3661 "static_cast< ::css::uno::XInterface * >((*"
3662 "LO_URE_CTOR_FUN_")
3663 << name_.replaceAll(".", "_dot_")
3664 << ")(the_context.get(), ";
3665 if (rest) {
3666 o << codemaker::cpp::translateUnoToCppIdentifier(
3667 u2b(cons.parameters.back().name), "param",
3668 codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3669 } else if (cons.parameters.empty()) {
3670 o << "::css::uno::Sequence< ::css::uno::Any >()";
3671 } else {
3672 o << "the_arguments";
3674 o << ")), ::SAL_NO_ACQUIRE), ::css::uno::UNO_QUERY);\n" << indent()
3675 << ("::css::uno::Reference< ::css::lang::XInitialization > "
3676 "init(the_instance, ::css::uno::UNO_QUERY);\n")
3677 << indent() << "if (init.is()) {\n"
3678 << indent() << " init->initialize(";
3679 if (cons.parameters.empty()) {
3680 o << "::css::uno::Sequence< ::css::uno::Any >()";
3681 } else {
3682 o << "the_arguments";
3684 o << ");\n" << indent() << "}\n";
3685 o << "#else\n"
3686 << indent() << "the_instance = ::css::uno::Reference< "
3687 << scopedBaseName
3688 << (" >(the_context->getServiceManager()->"
3689 "createInstanceWithArgumentsAndContext("
3690 " \"")
3691 << name_ << "\", ";
3692 if (rest) {
3693 o << codemaker::cpp::translateUnoToCppIdentifier(
3694 u2b(cons.parameters.back().name), "param",
3695 codemaker::cpp::IdentifierTranslationMode::NonGlobal);
3696 } else if (cons.parameters.empty()) {
3697 o << "::css::uno::Sequence< ::css::uno::Any >()";
3698 } else {
3699 o << "the_arguments";
3701 o << ", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3702 if (!tree.getRoot().present) {
3703 dec();
3704 o << indent()
3705 << "} catch (const ::css::uno::RuntimeException &) {\n";
3706 inc();
3707 o << indent() << "throw;\n";
3708 dec();
3709 dumpCatchClauses(o, &tree.getRoot());
3710 o << indent()
3711 << ("} catch (const ::css::uno::Exception &"
3712 " the_exception) {\n");
3713 inc();
3714 o << indent() << "throw ::css::uno::DeploymentException(";
3715 failsToSupply(o, name_, baseName);
3716 o << " + \": \" + the_exception.Message, the_context);\n";
3717 dec();
3718 o << indent() << "}\n";
3720 o << indent() << "if (!the_instance.is()) {\n";
3721 inc();
3722 o << indent() << "throw ::css::uno::DeploymentException(";
3723 failsToSupply(o, name_, baseName);
3724 o << ", the_context);\n";
3725 dec();
3726 o << indent() << "}\n" << indent() << "return the_instance;\n";
3727 dec();
3728 o << indent() << "}\n\n";
3732 o << "private:\n";
3733 o << indent() << cppName << "(); // not implemented\n"
3734 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3735 << indent() << "~" << cppName << "(); // not implemented\n"
3736 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3737 dec();
3738 o << "};\n\n";
3739 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3740 o << "\n";
3742 o << "\n#endif // "<< headerDefine << "\n";
3745 void ServiceType::dumpCatchClauses(
3746 FileStream & out, codemaker::ExceptionTreeNode const * node)
3748 if (node->present) {
3749 out << indent() << "} catch (const ";
3750 dumpType(out, b2u(node->name));
3751 out << " &) {\n";
3752 inc();
3753 out << indent() << "throw;\n";
3754 dec();
3755 } else {
3756 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3757 dumpCatchClauses(out, pChild.get());
3762 class SingletonType: public ConstructiveType
3764 public:
3765 SingletonType(
3766 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > const & entity,
3767 OUString const & name, rtl::Reference< TypeManager > const & manager):
3768 ConstructiveType(name, manager), entity_(entity) {
3769 assert(entity.is());
3772 private:
3773 virtual void dumpHppFile(
3774 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3776 rtl::Reference< unoidl::InterfaceBasedSingletonEntity > entity_;
3779 void SingletonType::dumpHppFile(
3780 FileStream & o, codemaker::cppumaker::Includes & includes)
3782 OString cppName(
3783 codemaker::cpp::translateUnoToCppIdentifier(
3784 u2b(id_), "singleton", isGlobal()));
3785 OString baseName(u2b(entity_->getBase()));
3786 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3787 OUString headerDefine(dumpHeaderDefine(o, "HPP"));
3788 o << "\n";
3789 //TODO: Decide whether the types added to includes should rather be added to
3790 // m_dependencies (and thus be generated during dumpDependedTypes):
3791 includes.add("com.sun.star.uno.DeploymentException");
3792 includes.add("com.sun.star.uno.XComponentContext");
3793 includes.addCassert();
3794 includes.addAny();
3795 includes.addReference();
3796 includes.addRtlUstringH();
3797 includes.addRtlUstringHxx();
3798 includes.dump(o, nullptr, true);
3799 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3800 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3801 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3802 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3803 << name_.replaceAll(".", "_dot_")
3804 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3805 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3806 << name_.replaceAll(".", "_dot_")
3807 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3808 << name_.replaceAll(".", "_dot_")
3809 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3810 "::css::uno::Any > const &);\n#endif\n";
3811 o << "\n";
3812 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3813 o << "\n";
3815 o << "\nclass " << cppName << " {\npublic:\n";
3816 inc();
3817 o << indent() << "static ::css::uno::Reference< "
3818 << scopedBaseName << " > "
3819 << codemaker::cpp::translateUnoToCppIdentifier(
3820 "get", "method", codemaker::cpp::IdentifierTranslationMode::NonGlobal, &cppName)
3821 << ("(::css::uno::Reference<"
3822 " ::css::uno::XComponentContext > const & the_context)"
3823 " {\n");
3824 inc();
3825 o << indent() << "assert(the_context.is());\n" << indent()
3826 << "::css::uno::Reference< " << scopedBaseName
3827 << (" > instance;\n#if defined LO_URE_CURRENT_ENV && defined "
3828 "LO_URE_CTOR_ENV_")
3829 << name_.replaceAll(".", "_dot_")
3830 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3831 << name_.replaceAll(".", "_dot_")
3832 << ") && defined LO_URE_CTOR_FUN_"
3833 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3834 << "instance = ::css::uno::Reference< " << scopedBaseName
3835 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3836 "static_cast< ::css::uno::XInterface * >((*"
3837 "LO_URE_CTOR_FUN_")
3838 << name_.replaceAll(".", "_dot_")
3839 << (")(the_context.get(), ::css::uno::Sequence<"
3840 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3841 " ::css::uno::UNO_QUERY);\n#else\n")
3842 << indent() << ("the_context->getValueByName("
3843 "::rtl::OUString( \"/singletons/")
3844 << name_ << "\" )) >>= instance;\n#endif\n"
3845 << indent() << "if (!instance.is()) {\n";
3846 inc();
3847 o << indent()
3848 << ("throw ::css::uno::DeploymentException("
3849 "::rtl::OUString( \"component context"
3850 " fails to supply singleton ")
3851 << name_ << " of type " << baseName << "\" ), the_context);\n";
3852 dec();
3853 o << indent() << "}\n" << indent() << "return instance;\n";
3854 dec();
3855 o << indent() << "}\n\n";
3856 o << "private:\n";
3857 o << indent() << cppName << "(); // not implemented\n"
3858 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3859 << indent() << "~" << cppName << "(); // not implemented\n"
3860 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3861 dec();
3862 o << "};\n\n";
3863 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3864 o << "\n";
3866 o << "\n#endif // "<< headerDefine << "\n";
3871 void produce(
3872 OUString const & name, rtl::Reference< TypeManager > const & manager,
3873 codemaker::GeneratedTypeSet & generated, CppuOptions const & options)
3875 if (generated.contains(u2b(name))) {
3876 return;
3878 generated.add(u2b(name));
3879 if (!manager->foundAtPrimaryProvider(name)) {
3880 return;
3882 rtl::Reference< unoidl::Entity > ent;
3883 rtl::Reference< unoidl::MapCursor > cur;
3884 switch (manager->getSort(name, &ent, &cur)) {
3885 case codemaker::UnoType::Sort::Module: {
3886 OUString prefix;
3887 if (!name.isEmpty()) {
3888 prefix = name + ".";
3890 for (;;) {
3891 OUString mem;
3892 if (!cur->getNext(&mem).is()) {
3893 break;
3895 produce(prefix + mem, manager, generated, options);
3897 break;
3899 case codemaker::UnoType::Sort::Enum: {
3900 EnumType t(
3901 dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), name,
3902 manager);
3903 t.dump(options);
3904 t.dumpDependedTypes(generated, options);
3905 break;
3907 case codemaker::UnoType::Sort::PlainStruct: {
3908 PlainStructType t(
3909 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
3910 name, manager);
3911 t.dump(options);
3912 t.dumpDependedTypes(generated, options);
3913 break;
3915 case codemaker::UnoType::Sort::PolymorphicStructTemplate: {
3916 PolyStructType t(
3917 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
3918 ent.get()),
3919 name, manager);
3920 t.dump(options);
3921 t.dumpDependedTypes(generated, options);
3922 break;
3924 case codemaker::UnoType::Sort::Exception: {
3925 ExceptionType t(
3926 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()), name,
3927 manager);
3928 t.dump(options);
3929 t.dumpDependedTypes(generated, options);
3930 break;
3932 case codemaker::UnoType::Sort::Interface: {
3933 InterfaceType t(
3934 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()), name,
3935 manager);
3936 t.dump(options);
3937 t.dumpDependedTypes(generated, options);
3938 break;
3940 case codemaker::UnoType::Sort::Typedef: {
3941 Typedef t(
3942 dynamic_cast< unoidl::TypedefEntity * >(ent.get()), name,
3943 manager);
3944 t.dump(options);
3945 t.dumpDependedTypes(generated, options);
3946 break;
3948 case codemaker::UnoType::Sort::ConstantGroup: {
3949 ConstantGroup t(
3950 dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()), name,
3951 manager);
3952 if (t.hasConstants()) {
3953 t.dump(options);
3955 break;
3957 case codemaker::UnoType::Sort::SingleInterfaceBasedService: {
3958 ServiceType t(
3959 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(
3960 ent.get()),
3961 name, manager);
3962 t.dump(options);
3963 t.dumpDependedTypes(generated, options);
3964 break;
3966 case codemaker::UnoType::Sort::InterfaceBasedSingleton: {
3967 SingletonType t(
3968 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
3969 ent.get()),
3970 name, manager);
3971 t.dump(options);
3972 t.dumpDependedTypes(generated, options);
3973 break;
3975 case codemaker::UnoType::Sort::AccumulationBasedService:
3976 case codemaker::UnoType::Sort::ServiceBasedSingleton:
3977 break;
3978 default:
3979 throw CannotDumpException(
3980 "unexpected entity \"" + name + "\" in call to produce");
3984 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */