LibreOffice Module codemaker (master) 1
cpputype.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8*
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21#include <sal/log.hxx>
22
23#include <algorithm>
24#include <cassert>
25#include <cstdlib>
26#include <map>
27#include <set>
28#include <string_view>
29#include <memory>
30#include <utility>
31#include <vector>
32#include <iostream>
33
34#include <rtl/alloc.h>
35#include <rtl/ref.hxx>
36#include <rtl/ustrbuf.hxx>
37#include <rtl/ustring.hxx>
38#include <rtl/strbuf.hxx>
39#include <unoidl/unoidl.hxx>
40
45#include <codemaker/unotype.hxx>
46
47#include "cpputype.hxx"
48#include "cppuoptions.hxx"
49#include "dependencies.hxx"
50#include "dumputils.hxx"
51#include "includes.hxx"
52
53namespace
54{
55
56bool isBootstrapType(OUString const & name)
57{
58 static char const * const names[] = {
59 "com.sun.star.beans.Property",
60 "com.sun.star.beans.PropertyAttribute",
61 "com.sun.star.beans.PropertyChangeEvent",
62 "com.sun.star.beans.PropertyState",
63 "com.sun.star.beans.PropertyValue",
64 "com.sun.star.beans.XFastPropertySet",
65 "com.sun.star.beans.XMultiPropertySet",
66 "com.sun.star.beans.XPropertiesChangeListener",
67 "com.sun.star.beans.XPropertyAccess",
68 "com.sun.star.beans.XPropertyChangeListener",
69 "com.sun.star.beans.XPropertySet",
70 "com.sun.star.beans.XPropertySetInfo",
71 "com.sun.star.beans.XPropertySetOption",
72 "com.sun.star.beans.XVetoableChangeListener",
73 "com.sun.star.bridge.UnoUrlResolver",
74 "com.sun.star.bridge.XUnoUrlResolver",
75 "com.sun.star.connection.SocketPermission",
76 "com.sun.star.container.XElementAccess",
77 "com.sun.star.container.XEnumeration",
78 "com.sun.star.container.XEnumerationAccess",
79 "com.sun.star.container.XHierarchicalNameAccess",
80 "com.sun.star.container.XNameAccess",
81 "com.sun.star.container.XNameContainer",
82 "com.sun.star.container.XNameReplace",
83 "com.sun.star.container.XSet",
84 "com.sun.star.io.FilePermission",
85 "com.sun.star.io.IOException",
86 "com.sun.star.lang.DisposedException",
87 "com.sun.star.lang.EventObject",
88 "com.sun.star.lang.WrappedTargetRuntimeException",
89 "com.sun.star.lang.XComponent",
90 "com.sun.star.lang.XEventListener",
91 "com.sun.star.lang.XInitialization",
92 "com.sun.star.lang.XMultiComponentFactory",
93 "com.sun.star.lang.XMultiServiceFactory",
94 "com.sun.star.lang.XServiceInfo",
95 "com.sun.star.lang.XSingleComponentFactory",
96 "com.sun.star.lang.XSingleServiceFactory",
97 "com.sun.star.lang.XTypeProvider",
98 "com.sun.star.loader.XImplementationLoader",
99 "com.sun.star.reflection.FieldAccessMode",
100 "com.sun.star.reflection.MethodMode",
101 "com.sun.star.reflection.ParamInfo",
102 "com.sun.star.reflection.ParamMode",
103 "com.sun.star.reflection.TypeDescriptionSearchDepth",
104 "com.sun.star.reflection.XCompoundTypeDescription",
105 "com.sun.star.reflection.XEnumTypeDescription",
106 "com.sun.star.reflection.XIdlArray",
107 "com.sun.star.reflection.XIdlClass",
108 "com.sun.star.reflection.XIdlField",
109 "com.sun.star.reflection.XIdlField2",
110 "com.sun.star.reflection.XIdlMethod",
111 "com.sun.star.reflection.XIdlReflection",
112 "com.sun.star.reflection.XIndirectTypeDescription",
113 "com.sun.star.reflection.XInterfaceAttributeTypeDescription",
114 "com.sun.star.reflection.XInterfaceAttributeTypeDescription2",
115 "com.sun.star.reflection.XInterfaceMemberTypeDescription",
116 "com.sun.star.reflection.XInterfaceMethodTypeDescription",
117 "com.sun.star.reflection.XInterfaceTypeDescription",
118 "com.sun.star.reflection.XInterfaceTypeDescription2",
119 "com.sun.star.reflection.XMethodParameter",
120 "com.sun.star.reflection.XStructTypeDescription",
121 "com.sun.star.reflection.XTypeDescription",
122 "com.sun.star.reflection.XTypeDescriptionEnumeration",
123 "com.sun.star.reflection.XTypeDescriptionEnumerationAccess",
124 "com.sun.star.registry.RegistryKeyType",
125 "com.sun.star.registry.RegistryValueType",
126 "com.sun.star.registry.XImplementationRegistration",
127 "com.sun.star.registry.XRegistryKey",
128 "com.sun.star.registry.XSimpleRegistry",
129 "com.sun.star.security.RuntimePermission",
130 "com.sun.star.security.XAccessControlContext",
131 "com.sun.star.security.XAccessController",
132 "com.sun.star.security.XAction",
133 "com.sun.star.uno.DeploymentException",
134 "com.sun.star.uno.RuntimeException",
135 "com.sun.star.uno.TypeClass",
136 "com.sun.star.uno.Uik",
137 "com.sun.star.uno.XAdapter",
138 "com.sun.star.uno.XAggregation",
139 "com.sun.star.uno.XComponentContext",
140 "com.sun.star.uno.XCurrentContext",
141 "com.sun.star.uno.XInterface",
142 "com.sun.star.uno.XReference",
143 "com.sun.star.uno.XUnloadingPreference",
144 "com.sun.star.uno.XWeak",
145 "com.sun.star.util.XMacroExpander" };
146 // cf. cppuhelper/unotypes/Makefile UNOTYPES (plus missing dependencies)
147 auto const pred = [&name](const char* aName) {
148 return name.equalsAscii(aName);
149 };
150 return std::any_of(std::begin(names), std::end(names), pred);
151}
152
153class CppuType
154{
155public:
156 CppuType(OUString name, rtl::Reference< TypeManager > const & typeMgr);
157
158 virtual ~CppuType() {}
159
160 CppuType(const CppuType&) = delete;
161 const CppuType& operator=(const CppuType&) = delete;
162
163 void dump(CppuOptions const & options);
164
165 void dumpFile(
166 std::u16string_view uri, std::u16string_view name, bool hpp,
167 CppuOptions const & options);
168
169 void dumpDependedTypes(
170 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const;
171
172 virtual void dumpHdlFile(
173 FileStream & out, codemaker::cppumaker::Includes & includes) {
174 dumpHFileContent(out, includes);
175 }
176
177 virtual void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) = 0;
178
179 OUString dumpHeaderDefine(FileStream& o, std::u16string_view extension) const;
180
181 void dumpGetCppuType(FileStream & out);
182
183 virtual void dumpLightGetCppuType(FileStream & out);
184
185 virtual void dumpNormalGetCppuType(FileStream &) {
186 assert(false); // this cannot happen
187 }
188
189 virtual void dumpComprehensiveGetCppuType(FileStream &) {
190 assert(false); // this cannot happen
191 }
192
193 void dumpType(
194 FileStream & out, std::u16string_view name, bool isConst = false,
195 bool isRef = false, bool native = false, bool cppuUnoType = false)
196 const;
197
198 OUString getTypeClass(OUString const & name, bool cStyle = false);
199
200 void dumpCppuGetType(
201 FileStream & out, std::u16string_view name, OUString const * ownName = nullptr) const;
202
203 sal_uInt32 getInheritedMemberCount();
204
205 void inc(sal_Int32 num=4);
206 void dec(sal_Int32 num=4);
207 OUString indent() const;
208protected:
209 virtual sal_uInt32 checkInheritedMemberCount() const {
210 assert(false); // this cannot happen
211 return 0;
212 }
213
214 bool passByReference(OUString const & name) const;
215
216 bool canBeWarnUnused(OUString const & name) const;
217 bool canBeWarnUnused(OUString const & name, int depth) const;
218
219 OUString resolveOuterTypedefs(OUString const & name) const;
220
221 OUString resolveAllTypedefs(std::u16string_view name) const;
222
224
225 virtual void dumpDeclaration(FileStream &) {
226 assert(false); // this cannot happen
227 }
228
229 virtual void dumpFiles(OUString const & uri, CppuOptions const & options);
230
231 virtual void addLightGetCppuTypeIncludes(
232 codemaker::cppumaker::Includes & includes) const;
233
234 virtual void addNormalGetCppuTypeIncludes(
235 codemaker::cppumaker::Includes & includes) const;
236
237 virtual void addComprehensiveGetCppuTypeIncludes(
238 codemaker::cppumaker::Includes & includes) const;
239
240 virtual bool isPolymorphic() const;
241
242 virtual void dumpTemplateHead(FileStream &) const {}
243
244 virtual void dumpTemplateParameters(FileStream &) const {}
245
246 void dumpGetCppuTypePreamble(FileStream & out);
247
248 void dumpGetCppuTypePostamble(FileStream & out);
249
250 void addDefaultHIncludes(codemaker::cppumaker::Includes & includes) const;
251 void addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes) const;
252
253 void dumpInitializer(
254 FileStream & out, bool parameterized, std::u16string_view name) const;
255
256 void dumpHFileContent(
258
259protected:
260 sal_uInt32 m_inheritedMemberCount;
261
262 bool m_cppuTypeLeak;
263 bool m_cppuTypeDynamic;
264 sal_Int32 m_indentLength;
265 OUString name_;
266 OUString id_;
269
270private:
271 void addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
272 const;
273};
274
275CppuType::CppuType(
276 OUString name, rtl::Reference< TypeManager > const & typeMgr):
277 m_inheritedMemberCount(0)
278 , m_cppuTypeLeak(false)
279 , m_cppuTypeDynamic(true)
280 , m_indentLength(0)
281 , name_(std::move(name))
282 , id_(name_.copy(name_.lastIndexOf('.') + 1))
283 , m_typeMgr(typeMgr)
284 , m_dependencies(typeMgr, name_)
285{}
286
287void CppuType::addGetCppuTypeIncludes(codemaker::cppumaker::Includes & includes)
288const
289{
290 if (name_ == "com.sun.star.uno.XInterface"
291 || name_ == "com.sun.star.uno.Exception") {
292 includes.addType();
293 includes.addCppuUnotypeHxx();
294 includes.addSalTypesH();
295 includes.addTypelibTypeclassH();
297 } else if (m_cppuTypeLeak) {
298 addLightGetCppuTypeIncludes(includes);
299 } else if (m_cppuTypeDynamic) {
300 addNormalGetCppuTypeIncludes(includes);
301 } else {
302 addComprehensiveGetCppuTypeIncludes(includes);
303 }
304}
305
306void CppuType::dumpFiles(OUString const & uri, CppuOptions const & options)
307{
308 dumpFile(uri, name_, false, options);
309 dumpFile(uri, name_, true, options);
310}
311
312void CppuType::addLightGetCppuTypeIncludes(
313 codemaker::cppumaker::Includes & includes) const
314{
315 //TODO: Determine what is really needed, instead of relying on
316 // addDefaultHxxIncludes
317 includes.addCppuUnotypeHxx();
318}
319
320void CppuType::addNormalGetCppuTypeIncludes(
321 codemaker::cppumaker::Includes & includes) const
322{
323 //TODO: Determine what is really needed, instead of relying on
324 // addDefaultHxxIncludes
325 includes.addCppuUnotypeHxx();
326}
327
328void CppuType::addComprehensiveGetCppuTypeIncludes(
329 codemaker::cppumaker::Includes & includes) const
330{
331 //TODO: Determine what is really needed, instead of relying on
332 // addDefaultHxxIncludes
333 includes.addCppuUnotypeHxx();
334}
335
336bool CppuType::isPolymorphic() const
337{
338 return false;
339}
340
341void CppuType::dumpGetCppuTypePreamble(FileStream & out)
342{
343 if (isPolymorphic()) {
344 out << "namespace cppu {\n\n";
345 dumpTemplateHead(out);
346 out << "class UnoType< ";
347 dumpType(out, name_);
348 dumpTemplateParameters(out);
349 out << " > {\npublic:\n";
350 inc();
351 out << indent()
352 << "static inline ::css::uno::Type const & get() {\n";
353 } else {
354 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
355 out << "\n\n";
356 }
357 out << ("inline ::css::uno::Type const &"
358 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
359 dumpType(out, name_, false, false, true);
360 out << " const *) {\n";
361 }
362 inc();
363}
364
365void CppuType::dumpGetCppuTypePostamble(FileStream & out)
366{
367 dec();
368 if (isPolymorphic()) {
369 out << indent() << "}\n\nprivate:\n"
370 << indent() << "UnoType(UnoType &); // not defined\n"
371 << indent() << "~UnoType(); // not defined\n"
372 << indent()
373 << "void operator =(UnoType); // not defined\n};\n\n}\n\n";
374 } else {
375 out << "}\n\n";
376 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
377 out << "\n\n";
378 }
379 }
380 dumpTemplateHead(out);
381 out << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
382 " getCppuType(SAL_UNUSED_PARAMETER ");
383 dumpType(out, name_);
384 dumpTemplateParameters(out);
385 out << " const *) {\n";
386 inc();
387 out << indent() << "return ::cppu::UnoType< ";
388 dumpType(out, name_);
389 dumpTemplateParameters(out);
390 out << " >::get();\n";
391 dec();
392 out << indent() << "}\n";
393}
394
395void CppuType::dump(CppuOptions const & options)
396{
397 if (isBootstrapType(name_)) {
398 m_cppuTypeDynamic = false;
399 } else {
400 // -CS was used as an undocumented option to generate static getCppuType
401 // functions; since the introduction of cppu::UnoType this no longer is
402 // meaningful (getCppuType is just a forward to cppu::UnoType::get now),
403 // and -CS is handled the same way as -C now:
404 if (options.isValid("-L"))
405 m_cppuTypeLeak = true;
406 if (options.isValid("-C") || options.isValid("-CS"))
407 m_cppuTypeDynamic = false;
408 }
409 dumpFiles(
410 options.isValid("-O") ? b2u(options.getOption("-O")) : "", options);
411}
412
413void CppuType::dumpFile(
414 std::u16string_view uri, std::u16string_view name, bool hpp,
415 CppuOptions const & options)
416{
417 OUString fileUri(
419 u2b(uri), u2b(name), hpp ? ".hpp" : ".hdl")));
420 if (fileUri.isEmpty()) {
421 throw CannotDumpException(OUString::Concat("empty target URI for entity ") + name);
422 }
423 bool exists = fileExists(u2b(fileUri));
424 if (exists && options.isValid("-G")) {
425 return;
426 }
427 FileStream out;
428 out.createTempFile(getTempDir(u2b(fileUri)));
429 OUString tmpUri(b2u(out.getName()));
430 if(!out.isValid()) {
431 throw CannotDumpException("cannot open " + tmpUri + " for writing");
432 }
433 codemaker::cppumaker::Includes includes(m_typeMgr, m_dependencies, hpp);
434 try {
435 if (hpp) {
436 addGetCppuTypeIncludes(includes);
437 dumpHppFile(out, includes);
438 } else {
439 dumpHdlFile(out, includes);
440 }
441 } catch (...) {
442 out.close();
443 // Remove existing type file if something goes wrong to ensure
444 // consistency:
445 if (fileExists(u2b(fileUri))) {
446 removeTypeFile(u2b(fileUri));
447 }
448 removeTypeFile(u2b(tmpUri));
449 throw;
450 }
451 out.close();
452 (void)makeValidTypeFile(
453 u2b(fileUri), u2b(tmpUri), exists && options.isValid("-Gc"));
454}
455
456void CppuType::dumpDependedTypes(
457 codemaker::GeneratedTypeSet & generated, CppuOptions const & options) const
458{
459 if (!options.isValid("-nD")) {
461 = m_dependencies.getMap();
462 for (const auto& entry : map) {
463 produce(entry.first, m_typeMgr, generated, options);
464 }
465 }
466}
467
468OUString CppuType::dumpHeaderDefine(
469 FileStream & out, std::u16string_view extension) const
470{
471 OUString def(
472 "INCLUDED_" + name_.replace('.', '_').toAsciiUpperCase() + "_"
473 + extension);
474 out << "#ifndef " << def << "\n#define " << def << "\n";
475 return def;
476}
477
478void CppuType::addDefaultHIncludes(codemaker::cppumaker::Includes & includes)
479const
480{
481 //TODO: Only include what is really needed
482 includes.addCppuMacrosHxx();
483 if (m_typeMgr->getSort(name_)
485 includes.addReference();
486 }
487}
488
489void CppuType::addDefaultHxxIncludes(codemaker::cppumaker::Includes & includes)
490const
491{
492 //TODO: Only include what is really needed
493 includes.addType();
494 if (m_typeMgr->getSort(name_)
496 includes.addReference();
497 }
498}
499
500void CppuType::dumpInitializer(
501 FileStream & out, bool parameterized, std::u16string_view name) const
502{
503 out << "(";
504 if (!parameterized) {
505 sal_Int32 k;
506 std::vector< OString > args;
507 OUString n(
509 u2b(resolveAllTypedefs(name)), &k, &args)));
510 if (k == 0) {
512 switch (m_typeMgr->getSort(n, &ent)) {
514 out << "false";
515 break;
526 out << "0";
527 break;
529 out << codemaker::cpp::scopedCppName(u2b(n)) << "_"
530 << (dynamic_cast<unoidl::EnumTypeEntity&>(*ent).
531 getMembers()[0].name);
532 break;
539 break;
540 default:
542 OUString::Concat("unexpected entity \"") + name
543 + "\" in call to CppuType::dumpInitializer");
544 }
545 }
546 }
547 out << ")";
548}
549
550void CppuType::dumpHFileContent(
552{
553 addDefaultHIncludes(includes);
554 dumpHeaderDefine(out, u"HDL");
555 out << "\n";
556 includes.dump(out, nullptr, false);
557 // 'exceptions = false' would be wrong for services/singletons, but
558 // those don't dump .hdl files anyway
559 out << ("\nnamespace com { namespace sun { namespace star { namespace uno"
560 " { class Type; } } } }\n\n");
561 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
562 out << "\n";
563 }
564 dumpDeclaration(out);
565 if (!(name_ == "com.sun.star.uno.XInterface"
566 || name_ == "com.sun.star.uno.Exception"
567 || isPolymorphic())) {
568 out << "\n" << indent()
569 << ("inline ::css::uno::Type const &"
570 " cppu_detail_getUnoType(SAL_UNUSED_PARAMETER ");
571 dumpType(out, name_, false, false, true);
572 out << " const *);\n";
573 }
574 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
575 out << "\n";
576 }
577 out << "\n";
578 dumpTemplateHead(out);
579 out << "SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL getCppuType(";
580 dumpType(out, name_, true);
581 dumpTemplateParameters(out);
582 out << " *);\n\n#endif\n";
583}
584
585void CppuType::dumpGetCppuType(FileStream & out)
586{
587 if (name_ == "com.sun.star.uno.XInterface") {
588 out << indent()
589 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
590 " getCppuType(SAL_UNUSED_PARAMETER ");
591 dumpType(out, name_, true);
592 out << " *) {\n";
593 inc();
594 out << indent()
595 << ("return ::cppu::UnoType< ::css::uno::XInterface"
596 " >::get();\n");
597 dec();
598 out << indent() << "}\n";
599 } else if (name_ == "com.sun.star.uno.Exception") {
600 out << indent()
601 << ("SAL_DEPRECATED(\"use cppu::UnoType\") inline ::css::uno::Type const & SAL_CALL"
602 " getCppuType(SAL_UNUSED_PARAMETER ");
603 dumpType(out, name_, true);
604 out << " *) {\n";
605 inc();
606 out << indent()
607 << ("return ::cppu::UnoType< ::css::uno::Exception"
608 " >::get();\n");
609 dec();
610 out << indent() << "}\n";
611 } else if (m_cppuTypeLeak) {
612 dumpLightGetCppuType(out);
613 } else if (m_cppuTypeDynamic) {
614 dumpNormalGetCppuType(out);
615 } else {
616 dumpComprehensiveGetCppuType(out);
617 }
618}
619
620void CppuType::dumpLightGetCppuType(FileStream & out)
621{
622 dumpGetCppuTypePreamble(out);
623 out << indent()
624 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
625 << indent() << "if ( !the_type )\n" << indent() << "{\n";
626 inc();
627 out << indent() << "typelib_static_type_init( &the_type, "
628 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
629 dec();
630 out << indent() << "}\n" << indent()
631 << ("return * reinterpret_cast< ::css::uno::Type * >("
632 " &the_type );\n");
633 dumpGetCppuTypePostamble(out);
634}
635
636codemaker::cpp::IdentifierTranslationMode CppuType::isGlobal() const
637{
638 return name_.indexOf('.') == -1
640}
641
642sal_uInt32 CppuType::getInheritedMemberCount()
643{
644 if (m_inheritedMemberCount == 0) {
645 m_inheritedMemberCount = checkInheritedMemberCount();
646 }
647
648 return m_inheritedMemberCount;
649}
650
651OUString CppuType::getTypeClass(OUString const & name, bool cStyle)
652{
654 switch (m_typeMgr->getSort(name, &ent)) {
656 return cStyle
657 ? OUString("typelib_TypeClass_VOID")
658 : OUString("::css::uno::TypeClass_VOID");
660 return cStyle
661 ? OUString("typelib_TypeClass_BOOLEAN")
662 : OUString("::css::uno::TypeClass_BOOLEAN");
664 return cStyle
665 ? OUString("typelib_TypeClass_BYTE")
666 : OUString("::css::uno::TypeClass_BYTE");
668 return cStyle
669 ? OUString("typelib_TypeClass_SHORT")
670 : OUString("::css::uno::TypeClass_SHORT");
672 return cStyle
673 ? OUString("typelib_TypeClass_UNSIGNED_SHORT")
674 : OUString("::css::uno::TypeClass_UNSIGNED_SHORT");
676 return cStyle
677 ? OUString("typelib_TypeClass_LONG")
678 : OUString("::css::uno::TypeClass_LONG");
680 return cStyle
681 ? OUString("typelib_TypeClass_UNSIGNED_LONG")
682 : OUString("::css::uno::TypeClass_UNSIGNED_LONG");
684 return cStyle
685 ? OUString("typelib_TypeClass_HYPER")
686 : OUString("::css::uno::TypeClass_HYPER");
688 return cStyle
689 ? OUString("typelib_TypeClass_UNSIGNED_HYPER")
690 : OUString("::css::uno::TypeClass_UNSIGNED_HYPER");
692 return cStyle
693 ? OUString("typelib_TypeClass_FLOAT")
694 : OUString("::css::uno::TypeClass_FLOAT");
696 return cStyle
697 ? OUString("typelib_TypeClass_DOUBLE")
698 : OUString("::css::uno::TypeClass_DOUBLE");
700 return cStyle
701 ? OUString("typelib_TypeClass_CHAR")
702 : OUString("::css::uno::TypeClass_CHAR");
704 return cStyle
705 ? OUString("typelib_TypeClass_STRING")
706 : OUString("::css::uno::TypeClass_STRING");
708 return cStyle
709 ? OUString("typelib_TypeClass_TYPE")
710 : OUString("::css::uno::TypeClass_TYPE");
712 return cStyle
713 ? OUString("typelib_TypeClass_ANY")
714 : OUString("::css::uno::TypeClass_ANY");
716 return cStyle
717 ? OUString("typelib_TypeClass_SEQUENCE")
718 : OUString("::css::uno::TypeClass_SEQUENCE");
720 return cStyle
721 ? OUString("typelib_TypeClass_ENUM")
722 : OUString("::css::uno::TypeClass_ENUM");
726 return cStyle
727 ? OUString("typelib_TypeClass_STRUCT")
728 : OUString("::css::uno::TypeClass_STRUCT");
730 return cStyle
731 ? OUString("typelib_TypeClass_EXCEPTION")
732 : OUString("::css::uno::TypeClass_EXCEPTION");
734 return cStyle
735 ? OUString("typelib_TypeClass_INTERFACE")
736 : OUString("::css::uno::TypeClass_INTERFACE");
738 return getTypeClass(dynamic_cast<unoidl::TypedefEntity&>(*ent).getType(), cStyle);
739 default:
740 for (;;) {
741 std::abort();
742 }
743 }
744}
745
746void CppuType::dumpType(
747 FileStream & out, std::u16string_view name, bool isConst, bool isRef,
748 bool native, bool cppuUnoType) const
749{
750 sal_Int32 k;
751 std::vector< OString > args;
752 OUString n(
754 u2b(resolveAllTypedefs(name)), &k, &args)));
755 if (isConst) {
756 out << "const ";
757 }
758 for (sal_Int32 i = 0; i != k; ++i) {
759 out << (cppuUnoType
760 ? "::cppu::UnoSequenceType" : "::css::uno::Sequence")
761 << "< ";
762 }
763 switch (m_typeMgr->getSort(n)) {
765 out << "void";
766 break;
768 out << "::sal_Bool";
769 break;
771 out << "::sal_Int8";
772 break;
774 out << "::sal_Int16";
775 break;
777 out << (cppuUnoType ? "::cppu::UnoUnsignedShortType" : "::sal_uInt16");
778 break;
780 out << "::sal_Int32";
781 break;
783 out << "::sal_uInt32";
784 break;
786 out << "::sal_Int64";
787 break;
789 out << "::sal_uInt64";
790 break;
792 out << "float";
793 break;
795 out << "double";
796 break;
798 out << (cppuUnoType ? "::cppu::UnoCharType" : "::sal_Unicode");
799 break;
801 out << "::rtl::OUString";
802 break;
804 out << "::css::uno::Type";
805 break;
807 out << "::css::uno::Any";
808 break;
813 break;
816 if (!args.empty()) {
817 out << "< ";
818 for (std::vector< OString >::iterator i(args.begin());
819 i != args.end(); ++i) {
820 if (i != args.begin()) {
821 out << ", ";
822 }
823 dumpType(out, b2u(*i));
824 }
825 out << " >";
826 }
827 break;
829 if (!native) {
830 out << "::css::uno::Reference< ";
831 }
833 if (!native) {
834 out << " >";
835 }
836 break;
837 default:
839 OUString::Concat("unexpected entity \"") + name + "\" in call to CppuType::dumpType");
840 }
841 for (sal_Int32 i = 0; i != k; ++i) {
842 out << " >";
843 }
844 if (isRef) {
845 out << "&";
846 }
847}
848
849void CppuType::dumpCppuGetType(
850 FileStream & out, std::u16string_view name, OUString const * ownName) const
851{
852 //TODO: What are these calls good for?
853 OUString nucleus;
854 sal_Int32 rank;
855 codemaker::UnoType::Sort sort = m_typeMgr->decompose(
856 name, true, &nucleus, &rank, nullptr, nullptr);
857 switch (rank == 0 ? sort : codemaker::UnoType::Sort::Sequence) {
873 break;
880 // Take care of recursion like struct S { sequence<S> x; }:
881 if (ownName == nullptr || nucleus != *ownName) {
882 out << indent() << "::cppu::UnoType< ";
883 dumpType(out, name, false, false, false, true);
884 out << " >::get();\n";
885 }
886 break;
888 for (;;) std::abort(); // this cannot happen
889 default:
891 OUString::Concat("unexpected entity \"") + name
892 + "\" in call to CppuType::dumpCppuGetType");
893 }
894}
895
896bool CppuType::passByReference(OUString const & name) const
897{
898 switch (m_typeMgr->getSort(resolveOuterTypedefs(name))) {
911 return false;
919 return true;
920 default:
922 "unexpected entity \"" + name
923 + "\" in call to CppuType::passByReference");
924 }
925}
926
927bool CppuType::canBeWarnUnused(OUString const & name) const
928{
929 return canBeWarnUnused(name, 0);
930}
931bool CppuType::canBeWarnUnused(OUString const & name, int depth) const
932{
933 // prevent infinite recursion and blowing the stack
934 if (depth > 10)
935 return false;
936 OUString aResolvedName = resolveOuterTypedefs(name);
937 switch (m_typeMgr->getSort(aResolvedName)) {
952 return true;
955 m_typeMgr->getSort(aResolvedName, &ent);
957 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
958 if (!ent2->getDirectBase().isEmpty() && !canBeWarnUnused(ent2->getDirectBase(), depth+1))
959 return false;
960 for ( const unoidl::PlainStructTypeEntity::Member& rMember : ent2->getDirectMembers()) {
961 if (!canBeWarnUnused(rMember.type, depth+1))
962 return false;
963 }
964 return true;
965 }
967 OUString aInnerType = aResolvedName.copy(2);
968 return canBeWarnUnused(aInnerType, depth+1);
969 }
973 return false;
974 default:
976 "unexpected entity \"" + name
977 + "\" in call to CppuType::canBeWarnUnused");
978 }
979}
980
981OUString CppuType::resolveOuterTypedefs(OUString const & name) const
982{
983 for (OUString n(name);;) {
985 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
986 return n;
987 }
988 n = dynamic_cast<unoidl::TypedefEntity&>(*ent).getType();
989 }
990}
991
992OUString CppuType::resolveAllTypedefs(std::u16string_view name) const
993{
994 sal_Int32 k1;
995 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k1)));
996 for (;;) {
998 if (m_typeMgr->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef) {
999 break;
1000 }
1001 sal_Int32 k2;
1003 u2b(dynamic_cast<unoidl::TypedefEntity&>(*ent).getType()), &k2));
1004 k1 += k2; //TODO: overflow
1005 }
1006 OUStringBuffer b(k1*2 + n.getLength());
1007 for (sal_Int32 i = 0; i != k1; ++i) {
1008 b.append("[]");
1009 }
1010 b.append(n);
1011 return b.makeStringAndClear();
1012}
1013
1014void CppuType::inc(sal_Int32 num)
1015{
1016 m_indentLength += num;
1017}
1018
1019void CppuType::dec(sal_Int32 num)
1020{
1021 m_indentLength = std::max< sal_Int32 >(m_indentLength - num, 0);
1022}
1023
1024OUString CppuType::indent() const
1025{
1026 OUStringBuffer buf(m_indentLength);
1027 for (sal_Int32 i = 0; i != m_indentLength; ++i) {
1028 buf.append(' ');
1029 }
1030 return buf.makeStringAndClear();
1031}
1032
1033bool isDeprecated(std::vector< OUString > const & annotations)
1034{
1035 for (const OUString& r : annotations) {
1036 if (r == "deprecated") {
1037 return true;
1038 }
1039 }
1040 return false;
1041}
1042
1043void dumpDeprecation(FileStream & out, bool deprecated)
1044{
1045 if (deprecated) {
1046 out << "SAL_DEPRECATED_INTERNAL(\"marked @deprecated in UNOIDL\") ";
1047 }
1048}
1049
1050class BaseOffset
1051{
1052public:
1053 BaseOffset(
1056 manager_(std::move(manager)), offset_(0) {
1057 calculateBases(entity);
1058 }
1059 BaseOffset(const BaseOffset&) = delete;
1060 const BaseOffset& operator=(const BaseOffset&) = delete;
1061
1062 sal_Int32 get() const {
1063 return offset_;
1064 }
1065
1066private:
1067 void calculateBases(
1069
1071 std::set< OUString > set_;
1072 sal_Int32 offset_;
1073};
1074
1075void BaseOffset::calculateBases(
1077{
1078 assert(entity.is());
1079 for (const unoidl::AnnotatedReference& ar : entity->getDirectMandatoryBases()) {
1080 if (set_.insert(ar.name).second) {
1082 codemaker::UnoType::Sort sort = manager_->getSort(ar.name, &ent);
1084 throw CannotDumpException(
1085 "interface type base " + ar.name
1086 + " is not an interface type");
1087 }
1089 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()));
1090 assert(ent2.is());
1091 calculateBases(ent2);
1092 offset_ += ent2->getDirectAttributes().size()
1093 + ent2->getDirectMethods().size(); //TODO: overflow
1094 }
1095 }
1096}
1097
1098class InterfaceType: public CppuType
1099{
1100public:
1101 InterfaceType(
1103 OUString const & name, rtl::Reference< TypeManager > const & typeMgr);
1104
1105 virtual void dumpDeclaration(FileStream& o) override;
1106 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1107
1108 void dumpAttributes(FileStream& o) const;
1109 void dumpMethods(FileStream& o) const;
1110 void dumpNormalGetCppuType(FileStream& o) override;
1111 void dumpComprehensiveGetCppuType(FileStream& o) override;
1112 void dumpCppuAttributeRefs(FileStream& o, sal_uInt32& index);
1113 void dumpCppuMethodRefs(FileStream& o, sal_uInt32& index);
1114 void dumpCppuAttributes(FileStream& o, sal_uInt32& index);
1115 void dumpCppuMethods(FileStream& o, sal_uInt32& index);
1116 void dumpAttributesCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1117 void dumpMethodsCppuDecl(FileStream & out, std::set< OUString > * seen) const;
1118
1119private:
1120 virtual void addComprehensiveGetCppuTypeIncludes(
1121 codemaker::cppumaker::Includes & includes) const override;
1122
1123 virtual sal_uInt32 checkInheritedMemberCount() const override {
1124 return BaseOffset(m_typeMgr, entity_).get();
1125 }
1126
1127 void dumpExceptionTypeName(
1128 FileStream & out, std::u16string_view prefix, sal_uInt32 index,
1129 std::u16string_view name) const;
1130
1131 sal_Int32 dumpExceptionTypeNames(
1132 FileStream & out, std::u16string_view prefix,
1133 std::vector< OUString > const & exceptions, bool runtimeException) const;
1134
1136 bool m_isDeprecated;
1137};
1138
1139InterfaceType::InterfaceType(
1141 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1142 CppuType(name, typeMgr), entity_(entity),
1143 m_isDeprecated(isDeprecated(entity->getAnnotations()))
1144{
1145 assert(entity.is());
1146}
1147
1148void InterfaceType::dumpDeclaration(FileStream & out)
1149{
1150 out << "\nclass SAL_NO_VTABLE SAL_DLLPUBLIC_RTTI " << id_;
1151 for (std::vector< unoidl::AnnotatedReference >::const_iterator i(
1152 entity_->getDirectMandatoryBases().begin());
1153 i != entity_->getDirectMandatoryBases().end(); ++i) {
1154 out << (i == entity_->getDirectMandatoryBases().begin() ? " :" : ",")
1155 << " public " << codemaker::cpp::scopedCppName(u2b(i->name));
1156 }
1157 out << "\n{\npublic:\n";
1158 inc();
1159 out << "#if defined LIBO_INTERNAL_ONLY\n"
1160 << indent() << id_ << "() = default;\n"
1161 << indent() << id_ << "(" << id_ << " const &) = default;\n"
1162 << indent() << id_ << "(" << id_ << " &&) = default;\n"
1163 << indent() << id_ << " & operator =(" << id_ << " const &) = default;\n"
1164 << indent() << id_ << " & operator =(" << id_ << " &&) = default;\n#endif\n\n";
1165 dumpAttributes(out);
1166 dumpMethods(out);
1167 out << "\n" << indent()
1168 << ("static inline ::css::uno::Type const & SAL_CALL"
1169 " static_type(void * = 0);\n\n");
1170 dec();
1171 out << "protected:\n";
1172 inc();
1173 out << indent() << "~" << id_
1174 << ("() SAL_NOEXCEPT {} // avoid warnings about virtual members and"
1175 " non-virtual dtor\n");
1176 dec();
1177 out << "};\n\n";
1178}
1179
1180void InterfaceType::dumpHppFile(
1182{
1183 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
1184 out << "\n";
1185 addDefaultHxxIncludes(includes);
1186 includes.dump(out, &name_, !(m_cppuTypeLeak || m_cppuTypeDynamic));
1187 out << "\n#if defined LIBO_INTERNAL_ONLY\n#include <type_traits>\n#endif\n\n";
1188 dumpGetCppuType(out);
1189 out << "\n::css::uno::Type const & "
1191 << "::static_type(SAL_UNUSED_PARAMETER void *) {\n";
1192 inc();
1193 out << indent() << "return ::cppu::UnoType< ";
1194 dumpType(out, name_, false, false, true);
1195 out << " >::get();\n";
1196 dec();
1197 out << "}\n\n#if defined LIBO_INTERNAL_ONLY\nnamespace cppu::detail {\n";
1198 if (name_ == "com.sun.star.uno.XInterface") {
1199 out << "template<typename> struct IsUnoInterfaceType: ::std::false_type {};\n"
1200 "template<typename T> inline constexpr auto isUnoInterfaceType ="
1201 " sizeof (T) && IsUnoInterfaceType<T>::value;\n";
1202 }
1203 out << "template<> struct IsUnoInterfaceType<";
1204 dumpType(out, name_, false, false, true);
1205 out << ">: ::std::true_type {};\n}\n#endif\n\n#endif // "<< headerDefine << "\n";
1206}
1207
1208void InterfaceType::dumpAttributes(FileStream & out) const
1209{
1210 if (!entity_->getDirectAttributes().empty()) {
1211 out << "\n" << indent() << "// Attributes\n";
1212 }
1213 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1214 bool depr = m_isDeprecated || isDeprecated(attr.annotations);
1215 out << indent();
1216 dumpDeprecation(out, depr);
1217 out << "virtual ";
1218 dumpType(out, attr.type);
1219 out << " SAL_CALL get" << attr.name << "() = 0;\n";
1220 if (!attr.readOnly) {
1221 bool byRef = passByReference(attr.type);
1222 out << indent();
1223 dumpDeprecation(out, depr);
1224 out << "virtual void SAL_CALL set" << attr.name << "( ";
1225 dumpType(out, attr.type, byRef, byRef);
1226 out << " _" << attr.name.toAsciiLowerCase() << " ) = 0;\n";
1227 }
1228 }
1229}
1230
1231void InterfaceType::dumpMethods(FileStream & out) const
1232{
1233 if (!entity_->getDirectMethods().empty()) {
1234 out << "\n" << indent() << "// Methods\n";
1235 }
1236 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1237 out << indent();
1238 dumpDeprecation(out, m_isDeprecated || isDeprecated(method.annotations));
1239 out << "virtual ";
1240 dumpType(out, method.returnType);
1241 out << " SAL_CALL " << method.name << "(";
1242 if (!method.parameters.empty()) {
1243 out << " ";
1244 for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1245 const_iterator j(method.parameters.begin());
1246 j != method.parameters.end();) {
1247 bool isConst;
1248 bool isRef;
1249 if (j->direction
1251 {
1252 isConst = passByReference(j->type);
1253 isRef = isConst;
1254 } else {
1255 isConst = false;
1256 isRef = true;
1257 }
1258 dumpType(out, j->type, isConst, isRef);
1259 out << " " << j->name;
1260 ++j;
1261 if (j != method.parameters.end()) {
1262 out << ", ";
1263 }
1264 }
1265 out << " ";
1266 }
1267 out << ") = 0;\n";
1268 }
1269}
1270
1271void InterfaceType::dumpNormalGetCppuType(FileStream & out)
1272{
1273 dumpGetCppuTypePreamble(out);
1274 out << indent()
1275 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
1276 << indent() << "if ( !the_type )\n" << indent() << "{\n";
1277 inc();
1278 std::vector< unoidl::AnnotatedReference >::size_type bases(
1279 entity_->getDirectMandatoryBases().size());
1280 if (bases == 1
1281 && (entity_->getDirectMandatoryBases()[0].name
1282 == "com.sun.star.uno.XInterface")) {
1283 bases = 0;
1284 }
1285 if (bases != 0) {
1286 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1287 << entity_->getDirectMandatoryBases().size() << "];\n";
1288 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1289 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1290 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1291 dumpType(out, ar.name, true, false, false, true);
1292 out << " >::get().getTypeLibType();\n";
1293 }
1294 }
1295 out << indent() << "typelib_static_mi_interface_type_init( &the_type, \""
1296 << name_ << "\", " << bases << ", "
1297 << (bases == 0 ? "0" : "aSuperTypes") << " );\n";
1298 dec();
1299 out << indent() << "}\n" << indent()
1300 << ("return * reinterpret_cast< ::css::uno::Type * >("
1301 " &the_type );\n");
1302 dumpGetCppuTypePostamble(out);
1303}
1304
1305void InterfaceType::dumpComprehensiveGetCppuType(FileStream & out)
1306{
1307 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
1308 OUString staticTypeClass("the" + id_ + "Type");
1309 out << " namespace detail {\n\n" << indent() << "struct " << staticTypeClass
1310 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
1311 << staticTypeClass << " >\n" << indent() << "{\n";
1312 inc();
1313 out << indent() << "::css::uno::Type * operator()() const\n"
1314 << indent() << "{\n";
1315 inc();
1316 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
1317 << indent() << "// Start inline typedescription generation\n"
1318 << indent() << "typelib_InterfaceTypeDescription * pTD = 0;\n\n";
1319 out << indent() << "typelib_TypeDescriptionReference * aSuperTypes["
1320 << entity_->getDirectMandatoryBases().size() << "];\n";
1321 std::vector< unoidl::AnnotatedReference >::size_type n = 0;
1322 for (const unoidl::AnnotatedReference& ar : entity_->getDirectMandatoryBases()) {
1323 out << indent() << "aSuperTypes[" << n++ << "] = ::cppu::UnoType< ";
1324 dumpType(out, ar.name, false, false, false, true);
1325 out << " >::get().getTypeLibType();\n";
1326 }
1327 std::size_t count = entity_->getDirectAttributes().size()
1328 + entity_->getDirectMethods().size(); //TODO: overflow
1329 if (count != 0) {
1330 out << indent() << "typelib_TypeDescriptionReference * pMembers["
1331 << count << "] = { ";
1332 for (std::size_t i = 0; i != count; ++i) {
1333 out << "0";
1334 if (i + 1 != count) {
1335 out << ",";
1336 }
1337 }
1338 out << " };\n";
1339 sal_uInt32 index = 0;
1340 dumpCppuAttributeRefs(out, index);
1341 dumpCppuMethodRefs(out, index);
1342 }
1343 out << "\n" << indent() << "typelib_typedescription_newMIInterface(\n";
1344 inc();
1345 out << indent() << "&pTD,\n" << indent()
1346 << "sTypeName.pData, 0, 0, 0, 0, 0,\n" << indent()
1347 << entity_->getDirectMandatoryBases().size() << ", aSuperTypes,\n"
1348 << indent() << count << ",\n" << indent()
1349 << (count == 0 ? "0" : "pMembers") << " );\n\n";
1350 dec();
1351 out << indent()
1352 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
1353 " );\n");
1354 for (std::size_t i = 0; i != count; ++i) {
1355 out << indent() << "typelib_typedescriptionreference_release( pMembers["
1356 << i << "] );\n";
1357 }
1358 out << indent()
1359 << ("typelib_typedescription_release( (typelib_TypeDescription*)pTD"
1360 " );\n\n")
1361 << indent() << "return new ::css::uno::Type( "
1362 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
1363 dec();
1364 out << indent() << "}\n";
1365 dec();
1366 out << indent() << "};\n\n";
1368 out << " }\n\n";
1369 dumpGetCppuTypePreamble(out);
1370 out << indent() << "const ::css::uno::Type &rRet = *detail::"
1371 << staticTypeClass << "::get();\n" << indent()
1372 << "// End inline typedescription generation\n" << indent()
1373 << "static bool bInitStarted = false;\n" << indent()
1374 << "if (!bInitStarted)\n" << indent() << "{\n";
1375 inc();
1376 out << indent()
1377 << "::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );\n"
1378 << indent() << "if (!bInitStarted)\n" << indent() << "{\n";
1379 inc();
1380 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n"
1381 << indent() << "bInitStarted = true;\n";
1382 std::set< OUString > seen;
1383 // Type for RuntimeException is always needed:
1384 seen.insert("com.sun.star.uno.RuntimeException");
1385 dumpCppuGetType(out, u"com.sun.star.uno.RuntimeException");
1386 dumpAttributesCppuDecl(out, &seen);
1387 dumpMethodsCppuDecl(out, &seen);
1388 if (count != 0) {
1389 sal_uInt32 index = getInheritedMemberCount();
1390 dumpCppuAttributes(out, index);
1391 dumpCppuMethods(out, index);
1392 }
1393 dec();
1394 out << indent() << "}\n";
1395 dec();
1396 out << indent() << "}\n" << indent() << "else\n" << indent() << "{\n";
1397 inc();
1398 out << indent() << "OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();\n";
1399 dec();
1400 out << indent() << "}\n" << indent() << "return rRet;\n";
1401 dumpGetCppuTypePostamble(out);
1402}
1403
1404void InterfaceType::dumpCppuAttributeRefs(FileStream & out, sal_uInt32 & index)
1405{
1406 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1407 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1408 out << indent() << "::rtl::OUString sAttributeName" << n << "( \""
1409 << name_ << "::" << attr.name << "\" );\n" << indent()
1410 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1411 << "],\n";
1412 inc(38);
1413 out << indent()
1414 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_ATTRIBUTE,\n"
1415 << indent() << "sAttributeName" << n << ".pData );\n";
1416 dec(38);
1417 ++n;
1418 }
1419}
1420
1421void InterfaceType::dumpCppuMethodRefs(FileStream & out, sal_uInt32 & index)
1422{
1423 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1424 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1425 out << indent() << "::rtl::OUString sMethodName" << n << "( \"" << name_
1426 << "::" << method.name << "\" );\n" << indent()
1427 << "typelib_typedescriptionreference_new( &pMembers[" << index++
1428 << "],\n";
1429 inc(38);
1430 out << indent()
1431 << "(typelib_TypeClass)::css::uno::TypeClass_INTERFACE_METHOD,\n"
1432 << indent() << "sMethodName" << n << ".pData );\n";
1433 dec(38);
1434 ++n;
1435 }
1436}
1437
1438void InterfaceType::addComprehensiveGetCppuTypeIncludes(
1439 codemaker::cppumaker::Includes & includes) const
1440{
1441 // The comprehensive getCppuType method always includes a line
1442 // "getCppuType( (const ::css::uno::RuntimeException*)0 );":
1443 includes.addCppuUnotypeHxx();
1444 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
1445 includes.addOslMutexHxx();
1446 includes.add("com.sun.star.uno.RuntimeException");
1447}
1448
1449void InterfaceType::dumpCppuAttributes(FileStream & out, sal_uInt32 & index)
1450{
1451 if (entity_->getDirectAttributes().empty())
1452 return;
1453
1454 out << "\n" << indent()
1455 << "typelib_InterfaceAttributeTypeDescription * pAttribute = 0;\n";
1456 std::vector< unoidl::InterfaceTypeEntity::Attribute >::size_type n = 0;
1457 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1458 OUString type(resolveAllTypedefs(attr.type));
1459 out << indent() << "{\n";
1460 inc();
1461 out << indent() << "::rtl::OUString sAttributeType" << n << "( \""
1462 << type << "\" );\n" << indent()
1463 << "::rtl::OUString sAttributeName" << n << "( \"" << name_
1464 << "::" << attr.name << "\" );\n";
1465 sal_Int32 getExcn = dumpExceptionTypeNames(
1466 out, u"get", attr.getExceptions, false);
1467 sal_Int32 setExcn = dumpExceptionTypeNames(
1468 out, u"set", attr.setExceptions, false);
1469 out << indent()
1470 << ("typelib_typedescription_newExtendedInterfaceAttribute("
1471 " &pAttribute,\n");
1472 inc();
1473 out << indent() << index++ << ", sAttributeName" << n
1474 << ".pData,\n" << indent() << "(typelib_TypeClass)"
1475 << getTypeClass(type) << ", sAttributeType" << n << ".pData,\n"
1476 << indent() << "sal_" << (attr.readOnly ? "True" : "False")
1477 << ", " << getExcn << ", "
1478 << (getExcn == 0 ? "0" : "the_getExceptions") << ", " << setExcn
1479 << ", " << (setExcn == 0 ? "0" : "the_setExceptions")
1480 << " );\n";
1481 dec();
1482 out << indent()
1483 << ("typelib_typedescription_register("
1484 " (typelib_TypeDescription**)&pAttribute );\n");
1485 dec();
1486 out << indent() << "}\n";
1487 ++n;
1488 }
1489 out << indent()
1490 << ("typelib_typedescription_release("
1491 " (typelib_TypeDescription*)pAttribute );\n");
1492}
1493
1494void InterfaceType::dumpCppuMethods(FileStream & out, sal_uInt32 & index)
1495{
1496 if (entity_->getDirectMethods().empty())
1497 return;
1498
1499 out << "\n" << indent()
1500 << "typelib_InterfaceMethodTypeDescription * pMethod = 0;\n";
1501 std::vector< unoidl::InterfaceTypeEntity::Method >::size_type n = 0;
1502 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1503 OUString returnType(resolveAllTypedefs(method.returnType));
1504 out << indent() << "{\n";
1505 inc();
1506 if (!method.parameters.empty()) {
1507 out << indent() << "typelib_Parameter_Init aParameters["
1508 << method.parameters.size() << "];\n";
1509 }
1510 std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
1511 size_type m = 0;
1512 for (const unoidl::InterfaceTypeEntity::Method::Parameter& param : method.parameters) {
1513 OUString type(resolveAllTypedefs(param.type));
1514 out << indent() << "::rtl::OUString sParamName" << m << "( \""
1515 << param.name << "\" );\n" << indent()
1516 << "::rtl::OUString sParamType" << m << "( \"" << type
1517 << "\" );\n" << indent() << "aParameters[" << m
1518 << "].pParamName = sParamName" << m << ".pData;\n"
1519 << indent() << "aParameters[" << m
1520 << "].eTypeClass = (typelib_TypeClass)"
1521 << getTypeClass(type) << ";\n" << indent() << "aParameters["
1522 << m << "].pTypeName = sParamType" << m << ".pData;\n"
1523 << indent() << "aParameters[" << m << "].bIn = "
1524 << ((param.direction
1526 ? "sal_False" : "sal_True")
1527 << ";\n" << indent() << "aParameters[" << m << "].bOut = "
1528 << ((param.direction
1530 ? "sal_False" : "sal_True")
1531 << ";\n";
1532 ++m;
1533 }
1534 sal_Int32 excn = dumpExceptionTypeNames(
1535 out, u"", method.exceptions,
1536 method.name != "acquire" && method.name != "release");
1537 out << indent() << "::rtl::OUString sReturnType" << n << "( \""
1538 << returnType << "\" );\n" << indent()
1539 << "::rtl::OUString sMethodName" << n << "( \"" << name_ << "::"
1540 << method.name << "\" );\n" << indent()
1541 << "typelib_typedescription_newInterfaceMethod( &pMethod,\n";
1542 inc();
1543 out << indent() << index++ << ", sal_False,\n" << indent()
1544 << "sMethodName" << n << ".pData,\n" << indent()
1545 << "(typelib_TypeClass)" << getTypeClass(returnType)
1546 << ", sReturnType" << n << ".pData,\n" << indent()
1547 << method.parameters.size() << ", "
1548 << (method.parameters.empty() ? "0" : "aParameters") << ",\n"
1549 << indent() << excn << ", "
1550 << (excn == 0 ? "0" : "the_Exceptions") << " );\n";
1551 dec();
1552 out << indent()
1553 << ("typelib_typedescription_register("
1554 " (typelib_TypeDescription**)&pMethod );\n");
1555 dec();
1556 out << indent() << "}\n";
1557 ++n;
1558 }
1559 out << indent()
1560 << ("typelib_typedescription_release("
1561 " (typelib_TypeDescription*)pMethod );\n");
1562}
1563
1564void InterfaceType::dumpAttributesCppuDecl(
1565 FileStream & out, std::set< OUString > * seen) const
1566{
1567 assert(seen != nullptr);
1568 for (const unoidl::InterfaceTypeEntity::Attribute& attr : entity_->getDirectAttributes()) {
1569 if (seen->insert(attr.type).second) {
1570 dumpCppuGetType(out, attr.type);
1571 }
1572 for (const OUString& exc : attr.getExceptions) {
1573 if (seen->insert(exc).second) {
1574 dumpCppuGetType(out, exc);
1575 }
1576 }
1577 for (const OUString& exc : attr.setExceptions) {
1578 if (seen->insert(exc).second) {
1579 dumpCppuGetType(out, exc);
1580 }
1581 }
1582 }
1583}
1584
1585void InterfaceType::dumpMethodsCppuDecl(
1586 FileStream & out, std::set< OUString > * seen) const
1587{
1588 assert(seen != nullptr);
1589 for (const unoidl::InterfaceTypeEntity::Method& method : entity_->getDirectMethods()) {
1590 for (const OUString& ex : method.exceptions) {
1591 if (seen->insert(ex).second) {
1592 dumpCppuGetType(out, ex);
1593 }
1594 }
1595 }
1596}
1597
1598void InterfaceType::dumpExceptionTypeName(
1599 FileStream & out, std::u16string_view prefix, sal_uInt32 index,
1600 std::u16string_view name) const
1601{
1602 out << indent() << "::rtl::OUString the_" << prefix << "ExceptionName"
1603 << index << "( \"" << name << "\" );\n";
1604}
1605
1606sal_Int32 InterfaceType::dumpExceptionTypeNames(
1607 FileStream & out, std::u16string_view prefix,
1608 std::vector< OUString > const & exceptions, bool runtimeException) const
1609{
1610 sal_Int32 count = 0;
1611 for (const OUString& ex : exceptions) {
1612 if (ex != "com.sun.star.uno.RuntimeException") {
1613 dumpExceptionTypeName(out, prefix, count++, ex);
1614 }
1615 }
1616 if (runtimeException) {
1617 dumpExceptionTypeName(
1618 out, prefix, count++, u"com.sun.star.uno.RuntimeException");
1619 }
1620 if (count != 0) {
1621 out << indent() << "rtl_uString * the_" << prefix << "Exceptions[] = {";
1622 for (sal_Int32 i = 0; i != count; ++i) {
1623 out << (i == 0 ? " " : ", ") << "the_" << prefix << "ExceptionName"
1624 << i << ".pData";
1625 }
1626 out << " };\n";
1627 }
1628 return count;
1629}
1630
1631class ConstantGroup: public CppuType
1632{
1633public:
1636 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1637 CppuType(name, typeMgr), entity_(entity) {
1638 assert(entity.is());
1639 }
1640
1641 bool hasConstants() const {
1642 return !entity_->getMembers().empty();
1643 }
1644
1645private:
1646 virtual void dumpHdlFile(
1647 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1648
1649 virtual void dumpHppFile(
1650 FileStream & out, codemaker::cppumaker::Includes & includes) override;
1651
1652 virtual void dumpDeclaration(FileStream & out) override;
1653
1655};
1656
1657void ConstantGroup::dumpHdlFile(
1659{
1660 OUString headerDefine(dumpHeaderDefine(out, u"HDL"));
1661 out << "\n";
1662 addDefaultHIncludes(includes);
1663 includes.dump(out, nullptr, true);
1664 out << "\n";
1665 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, true)) {
1666 out << "\n";
1667 }
1668 out << "\n";
1669 dumpDeclaration(out);
1670 out << "\n";
1671 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, true)) {
1672 out << "\n";
1673 }
1674 out << "\n#endif // "<< headerDefine << "\n";
1675}
1676
1677void ConstantGroup::dumpHppFile(
1679{
1680 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
1681 out << "\n";
1683 out << "\n#endif // "<< headerDefine << "\n";
1684}
1685
1686void ConstantGroup::dumpDeclaration(FileStream & out)
1687{
1688 for (const unoidl::ConstantGroupEntity::Member& member : entity_->getMembers()) {
1689 out << "static const ";
1690 switch (member.value.type) {
1692 out << "::sal_Bool";
1693 break;
1695 out << "::sal_Int8";
1696 break;
1698 out << "::sal_Int16";
1699 break;
1701 out << "::sal_uInt16";
1702 break;
1704 out << "::sal_Int32";
1705 break;
1707 out << "::sal_uInt32";
1708 break;
1710 out << "::sal_Int64";
1711 break;
1713 out << "::sal_uInt64";
1714 break;
1716 out << "float";
1717 break;
1719 out << "double";
1720 break;
1721 }
1722 out << " " << member.name << " = ";
1723 switch (member.value.type) {
1725 out << (member.value.booleanValue ? "sal_True" : "sal_False");
1726 break;
1728 out << "(sal_Int8)" << OUString::number(member.value.byteValue);
1729 break;
1731 out << "(sal_Int16)" << OUString::number(member.value.shortValue);
1732 break;
1734 out << "(sal_uInt16)"
1735 << OUString::number(member.value.unsignedShortValue);
1736 break;
1738 // Avoid C++ compiler warnings about (un)signedness of literal
1739 // -2^31:
1740 if (member.value.longValue == SAL_MIN_INT32) {
1741 out << "SAL_MIN_INT32";
1742 } else {
1743 out << "(sal_Int32)" << OUString::number(member.value.longValue);
1744 }
1745 break;
1747 out << "(sal_uInt32)"
1748 << OUString::number(member.value.unsignedLongValue) << "U";
1749 break;
1751 // Avoid C++ compiler warnings about (un)signedness of literal
1752 // -2^63:
1753 if (member.value.hyperValue == SAL_MIN_INT64) {
1754 out << "SAL_MIN_INT64";
1755 } else {
1756 out << "(sal_Int64) SAL_CONST_INT64("
1757 << OUString::number(member.value.hyperValue) << ")";
1758 }
1759 break;
1761 out << "SAL_CONST_UINT64("
1762 << OUString::number(member.value.unsignedHyperValue) << ")";
1763 break;
1765 out << "(float)" << OUString::number(member.value.floatValue);
1766 break;
1768 out << "(double)" << OUString::number(member.value.doubleValue);
1769 break;
1770 }
1771 out << ";\n";
1772 }
1773}
1774
1775void dumpTypeParameterName(FileStream & out, std::u16string_view name)
1776{
1777 // Prefix all type parameters with "typeparam_" to avoid problems when a
1778 // struct member has the same name as a type parameter, as in
1779 // struct<T> { T T; };
1780 out << "typeparam_" << name;
1781}
1782
1783class PlainStructType: public CppuType
1784{
1785public:
1786 PlainStructType(
1788 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
1789 CppuType(name, typeMgr), entity_(entity) {
1790 assert(entity.is());
1791 }
1792
1793private:
1794 virtual sal_uInt32 checkInheritedMemberCount() const override {
1795 return getTotalMemberCount(entity_->getDirectBase());
1796 }
1797
1798 virtual void dumpDeclaration(FileStream& o) override;
1799
1800 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
1801
1802 virtual void dumpLightGetCppuType(FileStream & out) override;
1803
1804 virtual void dumpNormalGetCppuType(FileStream & out) override;
1805
1806 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
1807
1808 virtual void addLightGetCppuTypeIncludes(
1809 codemaker::cppumaker::Includes & includes) const override;
1810
1811 virtual void addNormalGetCppuTypeIncludes(
1812 codemaker::cppumaker::Includes & includes) const override;
1813
1814 virtual void addComprehensiveGetCppuTypeIncludes(
1815 codemaker::cppumaker::Includes & includes) const override;
1816
1817 bool dumpBaseMembers(
1818 FileStream & out, OUString const & base, bool withType);
1819
1820 sal_uInt32 getTotalMemberCount(OUString const & base) const;
1821
1823};
1824
1825void PlainStructType::dumpDeclaration(FileStream & out)
1826{
1827 out << "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
1828 out << "struct SAL_DLLPUBLIC_RTTI ";
1829 if (canBeWarnUnused(name_))
1830 out << "SAL_WARN_UNUSED ";
1831 out << id_;
1832 OUString base(entity_->getDirectBase());
1833 if (!base.isEmpty()) {
1834 out << ": public " << codemaker::cpp::scopedCppName(u2b(base));
1835 }
1836 out << " {\n";
1837 inc();
1838 out << indent() << "inline " << id_ << "();\n";
1839 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1840 out << "\n" << indent() << "inline " << id_ << "(";
1841 bool bFirst = !dumpBaseMembers(out, base, true);
1842 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1843 if (!bFirst) {
1844 out << ", ";
1845 }
1846 dumpType(out, member.type, true, true);
1847 out << " " << member.name << "_";
1848 bFirst = false;
1849 }
1850 out << ");\n";
1851 }
1852 if (!entity_->getDirectMembers().empty()) {
1853 out << "\n";
1854 for (std::vector< unoidl::PlainStructTypeEntity::Member >::
1855 const_iterator i(entity_->getDirectMembers().begin());
1856 i != entity_->getDirectMembers().end(); ++i) {
1857 out << indent();
1858 dumpType(out, i->type);
1859 out << " " << i->name;
1860 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
1861 && i->type != "hyper" && i->type != "unsigned hyper"
1862 && i->type != "double") {
1863 out << " CPPU_GCC3_ALIGN("
1864 << codemaker::cpp::scopedCppName(u2b(base)) << ")";
1865 }
1866 out << ";\n";
1867 }
1868 }
1869 dec();
1870 out << "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
1871}
1872
1873void PlainStructType::dumpHppFile(
1875{
1876 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
1877 out << "\n";
1878 includes.dump(out, &name_, true);
1879 out << "\n";
1880 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
1881 out << "\n";
1882 }
1883 out << "\ninline " << id_ << "::" << id_ << "()\n";
1884 inc();
1885 OUString base(entity_->getDirectBase());
1886 bool bFirst = true;
1887 if (!base.isEmpty()) {
1888 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1889 << "()\n";
1890 bFirst = false;
1891 }
1892 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1893 out << indent() << (bFirst ? ":" : ",") << " " << member.name;
1894 dumpInitializer(out, false, member.type);
1895 out << "\n";
1896 bFirst = false;
1897 }
1898 dec();
1899 out << "{\n}\n\n";
1900 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
1901 out << "inline " << id_;
1902 out << "::" << id_ << "(";
1903 bFirst = !dumpBaseMembers(out, base, true);
1904 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1905 if (!bFirst) {
1906 out << ", ";
1907 }
1908 dumpType(out, member.type, true, true);
1909 out << " " << member.name << "_";
1910 bFirst = false;
1911 }
1912 out << ")\n";
1913 inc();
1914 bFirst = true;
1915 if (!base.isEmpty()) {
1916 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
1917 << "(";
1918 dumpBaseMembers(out, base, false);
1919 out << ")\n";
1920 bFirst = false;
1921 }
1922 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1923 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
1924 << member.name << "_)\n";
1925 bFirst = false;
1926 }
1927 dec();
1928 out << "{\n}\n\n";
1929 }
1930 // print the operator==
1931 out << "\ninline bool operator==(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1932 out << "{\n";
1933 inc();
1934 out << indent() << "return ";
1935 bFirst = true;
1936 if (!base.isEmpty()) {
1937 out << "operator==( static_cast< " << codemaker::cpp::scopedCppName(u2b(base))
1938 << ">(the_lhs), static_cast< " << codemaker::cpp::scopedCppName(u2b(base)) << ">(the_rhs) )\n";
1939 bFirst = false;
1940 }
1941 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
1942 if (!bFirst)
1943 out << "\n" << indent() << indent() << "&& ";
1944 out << "the_lhs." << member.name << " == the_rhs." << member.name;
1945 bFirst = false;
1946 }
1947 out << ";\n";
1948 dec();
1949 out << "}\n";
1950 // print the operator!=
1951 out << "\ninline bool operator!=(const " << id_ << "& the_lhs, const " << id_ << "& the_rhs)\n";
1952 out << "{\n";
1953 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
1954 out << "}\n";
1955 // close namespace
1956 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
1957 out << "\n";
1958 }
1959 out << "\n";
1960 dumpGetCppuType(out);
1961 out << "\n#endif // "<< headerDefine << "\n";
1962}
1963
1964void PlainStructType::dumpLightGetCppuType(FileStream & out)
1965{
1966 dumpGetCppuTypePreamble(out);
1967 out << indent()
1968 << ("//TODO: On certain platforms with weak memory models, the"
1969 " following code can result in some threads observing that the_type"
1970 " points to garbage\n")
1971 << indent()
1972 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1973 << indent() << "if (the_type == 0) {\n";
1974 inc();
1975 out << indent() << "::typelib_static_type_init(&the_type, "
1976 << getTypeClass(name_, true) << ", \"" << name_ << "\");\n";
1977 dec();
1978 out << indent() << "}\n" << indent()
1979 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
1980 dumpGetCppuTypePostamble(out);
1981}
1982
1983void PlainStructType::dumpNormalGetCppuType(FileStream & out)
1984{
1985 dumpGetCppuTypePreamble(out);
1986 out << indent()
1987 << ("//TODO: On certain platforms with weak memory models, the"
1988 " following code can result in some threads observing that the_type"
1989 " points to garbage\n")
1990 << indent()
1991 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
1992 << indent() << "if (the_type == 0) {\n";
1993 inc();
1994 out << indent()
1995 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
1996 inc();
1997 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
1998 entity_->getDirectMembers().begin());
1999 i != entity_->getDirectMembers().end();) {
2000 out << indent() << "::cppu::UnoType< ";
2001 dumpType(out, i->type, false, false, false, true);
2002 ++i;
2003 out << " >::get().getTypeLibType()"
2004 << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2005 }
2006 dec();
2007 out << indent() << "::typelib_static_struct_type_init(&the_type, \""
2008 << name_ << "\", ";
2009 if (entity_->getDirectBase().isEmpty()) {
2010 out << "0";
2011 } else {
2012 out << "::cppu::UnoType< ";
2013 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2014 out << " >::get().getTypeLibType()";
2015 }
2016 out << ", " << entity_->getDirectMembers().size() << ", the_members, 0);\n";
2017 dec();
2018 out << indent() << "}\n" << indent()
2019 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2020 dumpGetCppuTypePostamble(out);
2021}
2022
2023void PlainStructType::dumpComprehensiveGetCppuType(FileStream & out)
2024{
2025 OUString staticTypeClass("the" + id_ + "Type");
2026 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
2027 out << " namespace detail {\n\n" << indent() << "struct "
2028 << staticTypeClass
2029 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2030 << staticTypeClass << " >\n" << indent() << "{\n";
2031 inc();
2032 out << indent() << "::css::uno::Type * operator()() const\n"
2033 << indent() << "{\n";
2034 inc();
2035 out << indent() << "::rtl::OUString the_name( \"" << name_ << "\" );\n";
2036 std::map< OUString, sal_uInt32 > types;
2037 std::vector< unoidl::PlainStructTypeEntity::Member >::size_type n = 0;
2038 for (const unoidl::PlainStructTypeEntity::Member& member : entity_->getDirectMembers()) {
2039 if (types.emplace(
2040 member.type, static_cast< sal_uInt32 >(types.size())).
2041 second) {
2042 dumpCppuGetType(out, member.type, &name_);
2043 // For typedefs, use the resolved type name, as there will be no
2044 // information available about the typedef itself at runtime (the
2045 // above getCppuType call will make available information about the
2046 // resolved type); no extra #include for the resolved type is
2047 // needed, as the header for the typedef includes it already:
2048 out << indent() << "::rtl::OUString the_tname"
2049 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2050 << resolveAllTypedefs(member.type) << "\" );\n";
2051 }
2052 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2053 << member.name << "\" );\n";
2054 }
2055 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2056 inc();
2057 n = 0;
2058 for (std::vector< unoidl::PlainStructTypeEntity::Member >::const_iterator i(
2059 entity_->getDirectMembers().begin());
2060 i != entity_->getDirectMembers().end();) {
2061 out << indent() << "{ { " << getTypeClass(i->type, true)
2062 << ", the_tname" << types.find(i->type)->second
2063 << ".pData, the_name" << n++ << ".pData }, false }";
2064 ++i;
2065 out << (i == entity_->getDirectMembers().end() ? " };" : ",") << "\n";
2066 }
2067 dec();
2068 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n"
2069 << indent()
2070 << "::typelib_typedescription_newStruct(&the_newType, the_name.pData, ";
2071 if (entity_->getDirectBase().isEmpty()) {
2072 out << "0";
2073 } else {
2074 out << "::cppu::UnoType< ";
2075 dumpType(out, entity_->getDirectBase(), false, false, false, true);
2076 out << " >::get().getTypeLibType()";
2077 }
2078 out << ", " << entity_->getDirectMembers().size() << ", the_members);\n"
2079 << indent() << "::typelib_typedescription_register(&the_newType);\n"
2080 << indent() << "::typelib_typedescription_release(the_newType);\n"
2081 << indent() << "return new ::css::uno::Type("
2082 << getTypeClass(name_) << ", the_name); // leaked\n";
2083 dec();
2084 out << indent() << "}\n";
2085 dec();
2086 out << indent() << "};\n";
2088 out << " }\n\n";
2089 dumpGetCppuTypePreamble(out);
2090 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
2091 dumpGetCppuTypePostamble(out);
2092}
2093
2094bool PlainStructType::dumpBaseMembers(
2095 FileStream & out, OUString const & base, bool withType)
2096{
2097 if (base.isEmpty())
2098 return false;
2099
2101 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2103 throw CannotDumpException(
2104 "plain struct type base " + base
2105 + " is not a plain struct type");
2106 }
2108 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2109 assert(ent2.is());
2110 if (!ent2.is()) {
2111 return false;
2112 }
2113 bool hasMember = dumpBaseMembers(out, ent2->getDirectBase(), withType);
2114 for (const unoidl::PlainStructTypeEntity::Member& member : ent2->getDirectMembers()) {
2115 if (hasMember) {
2116 out << ", ";
2117 }
2118 if (withType) {
2119 dumpType(out, member.type, true, true);
2120 out << " ";
2121 }
2122 out << member.name << "_";
2123 hasMember = true;
2124 }
2125 return hasMember;
2126}
2127
2128void PlainStructType::addLightGetCppuTypeIncludes(
2129 codemaker::cppumaker::Includes & includes) const
2130{
2131 includes.addType();
2132 includes.addCppuUnotypeHxx();
2133 includes.addSalTypesH();
2134 includes.addTypelibTypeclassH();
2135 includes.addTypelibTypedescriptionH();
2136}
2137
2138void PlainStructType::addNormalGetCppuTypeIncludes(
2139 codemaker::cppumaker::Includes & includes) const
2140{
2141 includes.addType();
2142 includes.addCppuUnotypeHxx();
2143 includes.addSalTypesH();
2144 includes.addTypelibTypeclassH();
2145 includes.addTypelibTypedescriptionH();
2146}
2147
2148void PlainStructType::addComprehensiveGetCppuTypeIncludes(
2149 codemaker::cppumaker::Includes & includes) const
2150{
2151 includes.addType();
2152 includes.addCppuUnotypeHxx();
2153 includes.addRtlInstanceHxx();
2154 includes.addRtlUstringH();
2155 includes.addRtlUstringHxx();
2156 includes.addSalTypesH();
2157 includes.addTypelibTypeclassH();
2158 includes.addTypelibTypedescriptionH();
2159}
2160
2161sal_uInt32 PlainStructType::getTotalMemberCount(OUString const & base) const
2162{
2163 if (base.isEmpty()) {
2164 return 0;
2165 }
2167 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
2169 throw CannotDumpException(
2170 "plain struct type base " + base + " is not a plain struct type");
2171 }
2173 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()));
2174 assert(ent2.is());
2175 if (!ent2.is()) {
2176 return 0;
2177 }
2178 return getTotalMemberCount(ent2->getDirectBase())
2179 + ent2->getDirectMembers().size(); //TODO: overflow
2180}
2181
2182class PolyStructType: public CppuType
2183{
2184public:
2185 PolyStructType(
2187 entity,
2188 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2189 CppuType(name, typeMgr), entity_(entity) {
2190 assert(entity.is());
2191 }
2192
2193private:
2194 virtual void dumpDeclaration(FileStream& o) override;
2195
2196 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
2197
2198 virtual void dumpLightGetCppuType(FileStream & out) override;
2199
2200 virtual void dumpNormalGetCppuType(FileStream & out) override;
2201
2202 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2203
2204 virtual void addLightGetCppuTypeIncludes(
2205 codemaker::cppumaker::Includes & includes) const override;
2206
2207 virtual void addNormalGetCppuTypeIncludes(
2208 codemaker::cppumaker::Includes & includes) const override;
2209
2210 virtual void addComprehensiveGetCppuTypeIncludes(
2211 codemaker::cppumaker::Includes & includes) const override;
2212
2213 virtual bool isPolymorphic() const override {
2214 return true;
2215 }
2216
2217 virtual void dumpTemplateHead(FileStream & out) const override;
2218
2219 virtual void dumpTemplateParameters(FileStream & out) const override;
2220
2222};
2223
2224void PolyStructType::dumpDeclaration(FileStream & out)
2225{
2226 out << "\n#ifdef _WIN32\n# pragma pack(push, 8)\n#endif\n\n" << indent();
2227 dumpTemplateHead(out);
2228 out << "struct SAL_DLLPUBLIC_RTTI " << id_ << " {\n";
2229 inc();
2230 out << indent() << "inline " << id_ << "();\n";
2231 if (!entity_->getMembers().empty()) {
2232 out << "\n" << indent() << "inline " << id_ << "(";
2233 for (std::vector<
2235 const_iterator i(entity_->getMembers().begin());
2236 i != entity_->getMembers().end(); ++i) {
2237 if (i != entity_->getMembers().begin()) {
2238 out << ", ";
2239 }
2240 if (i->parameterized) {
2241 dumpTypeParameterName(out, i->type);
2242 out << " const &";
2243 } else {
2244 dumpType(out, i->type, true, true);
2245 }
2246 out << " " << i->name << "_";
2247 }
2248 out << ");\n\n";
2249 // print the member fields
2251 entity_->getMembers()) {
2252 out << indent();
2253 if (member.parameterized) {
2254 dumpTypeParameterName(out, member.type);
2255 } else {
2256 dumpType(out, member.type);
2257 }
2258 out << " " << member.name << ";\n";
2259 }
2260 }
2261 dec();
2262 out << "};\n\n#ifdef _WIN32\n# pragma pack(pop)\n#endif\n\n";
2263}
2264
2265void PolyStructType::dumpHppFile(
2267{
2268 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
2269 out << "\n";
2270 includes.dump(out, &name_, true);
2271 out << "\n";
2272 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2273 out << "\n";
2274 }
2275 out << "\n";
2276 // dump default (no-arg) constructor
2277 dumpTemplateHead(out);
2278 out << "inline " << id_;
2279 dumpTemplateParameters(out);
2280 out << "::" << id_ << "()\n";
2281 inc();
2282 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2283 const_iterator i(entity_->getMembers().begin());
2284 i != entity_->getMembers().end(); ++i) {
2285 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2286 << " " << i->name;
2287 dumpInitializer(out, i->parameterized, i->type);
2288 out << "\n";
2289 }
2290 dec();
2291 out << "{\n}\n\n";
2292 if (!entity_->getMembers().empty()) {
2293 // dump takes-all-fields constructor
2294 dumpTemplateHead(out);
2295 out << "inline " << id_;
2296 dumpTemplateParameters(out);
2297 out << "::" << id_ << "(";
2298 for (std::vector<
2300 const_iterator i(entity_->getMembers().begin());
2301 i != entity_->getMembers().end(); ++i) {
2302 if (i != entity_->getMembers().begin()) {
2303 out << ", ";
2304 }
2305 if (i->parameterized) {
2306 dumpTypeParameterName(out, i->type);
2307 out << " const &";
2308 } else {
2309 dumpType(out, i->type, true, true);
2310 }
2311 out << " " << i->name << "_";
2312 }
2313 out << ")\n";
2314 inc();
2315 for (std::vector<
2317 const_iterator i(entity_->getMembers().begin());
2318 i != entity_->getMembers().end(); ++i) {
2319 out << indent() << (i == entity_->getMembers().begin() ? ":" : ",")
2320 << " " << i->name << "(" << i->name << "_)\n";
2321 }
2322 dec();
2323 out << "{\n}\n\n" << indent();
2324 // dump make_T method
2325 dumpTemplateHead(out);
2326 out << "\n" << indent() << "inline " << id_;
2327 dumpTemplateParameters(out);
2328 out << "\n" << indent() << "make_" << id_ << "(";
2329 for (std::vector<
2331 const_iterator i(entity_->getMembers().begin());
2332 i != entity_->getMembers().end(); ++i) {
2333 if (i != entity_->getMembers().begin()) {
2334 out << ", ";
2335 }
2336 if (i->parameterized) {
2337 dumpTypeParameterName(out, i->type);
2338 out << " const &";
2339 } else {
2340 dumpType(out, i->type, true, true);
2341 }
2342 out << " " << i->name << "_";
2343 }
2344 out << ")\n" << indent() << "{\n";
2345 inc();
2346 out << indent() << "return " << id_;
2347 dumpTemplateParameters(out);
2348 out << "(";
2349 for (std::vector<
2351 const_iterator i(entity_->getMembers().begin());
2352 i != entity_->getMembers().end(); ++i) {
2353 if (i != entity_->getMembers().begin()) {
2354 out << ", ";
2355 }
2356 out << i->name << "_";
2357 }
2358 out << ");\n";
2359 dec();
2360 out << indent() << "}\n\n";
2361 }
2362 // print the operator==
2363 dumpTemplateHead(out);
2364 out << " inline bool operator==(const " << id_;
2365 dumpTemplateParameters(out);
2366 out << "& the_lhs, const " << id_;
2367 dumpTemplateParameters(out);
2368 out << "& the_rhs)\n";
2369 out << "{\n";
2370 inc();
2371 out << indent() << "return ";
2372 bool bFirst = true;
2373 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2374 if (!bFirst)
2375 out << "\n" << indent() << indent() << "&& ";
2376 out << "the_lhs." << member.name << " == the_rhs." << member.name;
2377 bFirst = false;
2378 }
2379 out << ";\n";
2380 dec();
2381 out << "}\n";
2382 // print the operator!=
2383 dumpTemplateHead(out);
2384 out << " inline bool operator!=(const " << id_;
2385 dumpTemplateParameters(out);
2386 out << "& the_lhs, const " << id_;
2387 dumpTemplateParameters(out);
2388 out << "& the_rhs)\n";
2389 out << "{\n";
2390 out << indent() << "return !operator==(the_lhs, the_rhs);\n";
2391 out << "}\n";
2392 // close namespace
2393 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2394 out << "\n";
2395 }
2396 out << "\n";
2397 dumpGetCppuType(out);
2398 out << "\n#endif // "<< headerDefine << "\n";
2399}
2400
2401void PolyStructType::dumpLightGetCppuType(FileStream & out)
2402{
2403 dumpGetCppuTypePreamble(out);
2404 out << indent()
2405 << ("//TODO: On certain platforms with weak memory models, the"
2406 " following code can result in some threads observing that the_type"
2407 " points to garbage\n")
2408 << indent()
2409 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2410 << indent() << "if (the_type == 0) {\n";
2411 inc();
2412
2413 out << "#ifdef LIBO_INTERNAL_ONLY\n";
2414
2415 out << indent() << "::rtl::OString the_buffer = \"" << name_
2416 << "<\" +\n";
2417 for (std::vector< OUString >::const_iterator i(
2418 entity_->getTypeParameters().begin());
2419 i != entity_->getTypeParameters().end();) {
2420 out << indent()
2421 << ("::rtl::OUStringToOString("
2422 "::cppu::getTypeFavourChar(static_cast< ");
2423 dumpTypeParameterName(out, *i);
2424 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8) +\n";
2425 ++i;
2426 if (i != entity_->getTypeParameters().end()) {
2427 out << indent() << "\",\" +\n";
2428 }
2429 }
2430 out << indent() << "\">\";\n";
2431
2432 out << "#else\n";
2433
2434 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2435 << "<\");\n";
2436 for (std::vector< OUString >::const_iterator i(
2437 entity_->getTypeParameters().begin());
2438 i != entity_->getTypeParameters().end();) {
2439 out << indent()
2440 << ("the_buffer.append(::rtl::OUStringToOString("
2441 "::cppu::getTypeFavourChar(static_cast< ");
2442 dumpTypeParameterName(out, *i);
2443 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2444 ++i;
2445 if (i != entity_->getTypeParameters().end()) {
2446 out << indent() << "the_buffer.append(',');\n";
2447 }
2448 }
2449 out << indent() << "the_buffer.append('>');\n";
2450
2451 out << "#endif\n";
2452
2453 out << indent()
2454 << "::typelib_static_type_init(&the_type, " << getTypeClass(name_, true)
2455 << ", the_buffer.getStr());\n";
2456
2457 dec();
2458 out << indent() << "}\n" << indent()
2459 << "return *reinterpret_cast< ::css::uno::Type * >(&the_type);\n";
2460 dumpGetCppuTypePostamble(out);
2461}
2462
2463void PolyStructType::dumpNormalGetCppuType(FileStream & out)
2464{
2465 dumpGetCppuTypePreamble(out);
2466 out << indent()
2467 << ("//TODO: On certain platforms with weak memory models, the"
2468 " following code can result in some threads observing that the_type"
2469 " points to garbage\n")
2470 << indent()
2471 << "static ::typelib_TypeDescriptionReference * the_type = 0;\n"
2472 << indent() << "if (the_type == 0) {\n";
2473 inc();
2474 out << indent() << "::rtl::OStringBuffer the_buffer(\"" << name_
2475 << "<\");\n";
2476 for (std::vector< OUString >::const_iterator i(
2477 entity_->getTypeParameters().begin());
2478 i != entity_->getTypeParameters().end();) {
2479 out << indent()
2480 << ("the_buffer.append(::rtl::OUStringToOString("
2481 "::cppu::getTypeFavourChar(static_cast< ");
2482 dumpTypeParameterName(out, *i);
2483 out << " * >(0)).getTypeName(), RTL_TEXTENCODING_UTF8));\n";
2484 ++i;
2485 if (i != entity_->getTypeParameters().end()) {
2486 out << indent() << "the_buffer.append(',');\n";
2487 }
2488 }
2489 out << indent() << "the_buffer.append('>');\n" << indent()
2490 << "::typelib_TypeDescriptionReference * the_members[] = {\n";
2491 inc();
2492 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2493 const_iterator i(entity_->getMembers().begin());
2494 i != entity_->getMembers().end();) {
2495 out << indent();
2496 if (i->parameterized) {
2497 out << "::cppu::getTypeFavourChar(static_cast< ";
2498 dumpTypeParameterName(out, i->type);
2499 out << " * >(0))";
2500 } else {
2501 out << "::cppu::UnoType< ";
2502 dumpType(out, i->type, false, false, false, true);
2503 out << " >::get()";
2504 }
2505 ++i;
2506 out << ".getTypeLibType()"
2507 << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2508 }
2509 dec();
2510 out << indent() << "static ::sal_Bool const the_parameterizedTypes[] = { ";
2511 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2512 const_iterator i(entity_->getMembers().begin());
2513 i != entity_->getMembers().end(); ++i) {
2514 if (i != entity_->getMembers().begin()) {
2515 out << ", ";
2516 }
2517 out << (i->parameterized ? "true" : "false");
2518 }
2519 out << " };\n" << indent()
2520 << ("::typelib_static_struct_type_init(&the_type, the_buffer.getStr(),"
2521 " 0, ")
2522 << entity_->getMembers().size()
2523 << ", the_members, the_parameterizedTypes);\n";
2524 dec();
2525 out << indent() << "}\n" << indent()
2526 << ("return *reinterpret_cast< ::css::uno::Type * >("
2527 "&the_type);\n");
2528 dumpGetCppuTypePostamble(out);
2529}
2530
2531void PolyStructType::dumpComprehensiveGetCppuType(FileStream & out)
2532{
2533 out << "namespace cppu { namespace detail {\n\n" << indent();
2534 dumpTemplateHead(out);
2535 OUString staticTypeClass("the" + id_ + "Type");
2536 out << "struct " << staticTypeClass
2537 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
2538 << staticTypeClass;
2539 dumpTemplateParameters(out);
2540 out << " >\n" << indent() << "{\n";
2541 inc();
2542 out << indent() << "::css::uno::Type * operator()() const\n"
2543 << indent() << "{\n";
2544 inc();
2545
2546 out << "#ifdef LIBO_INTERNAL_ONLY\n";
2547 out << indent()
2548 << "::rtl::OUString the_name =\n";
2549 out << indent() << "\"" << name_ << "<\" +\n";
2550 for (std::vector< OUString >::const_iterator i(
2551 entity_->getTypeParameters().begin());
2552 i != entity_->getTypeParameters().end();) {
2553 out << indent()
2554 << "::cppu::getTypeFavourChar(static_cast< ";
2555 dumpTypeParameterName(out, *i);
2556 out << " * >(0)).getTypeName() +\n";
2557 ++i;
2558 if (i != entity_->getTypeParameters().end()) {
2559 out << indent()
2560 << "\",\" +\n";
2561 }
2562 }
2563 out << indent()
2564 << "\">\";\n";
2565 out << "#else\n";
2566 out << indent() << "::rtl::OUStringBuffer the_buffer;\n" << indent()
2567 << "the_buffer.append(\"" << name_ << "<\");\n";
2568 for (std::vector< OUString >::const_iterator i(
2569 entity_->getTypeParameters().begin());
2570 i != entity_->getTypeParameters().end();) {
2571 out << indent()
2572 << "the_buffer.append(::cppu::getTypeFavourChar(static_cast< ";
2573 dumpTypeParameterName(out, *i);
2574 out << " * >(0)).getTypeName());\n";
2575 ++i;
2576 if (i != entity_->getTypeParameters().end()) {
2577 out << indent()
2578 << ("the_buffer.append("
2579 "static_cast< ::sal_Unicode >(','));\n");
2580 }
2581 }
2582 out << indent() << "the_buffer.append(static_cast< ::sal_Unicode >('>'));\n";
2583 out << indent()
2584 << "::rtl::OUString the_name(the_buffer.makeStringAndClear());\n";
2585 out << "#endif\n";
2586 std::map< OUString, sal_uInt32 > parameters;
2587 std::map< OUString, sal_uInt32 > types;
2588 std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2589 size_type n = 0;
2590 for (const unoidl::PolymorphicStructTypeTemplateEntity::Member& member : entity_->getMembers()) {
2591 if (member.parameterized) {
2592 if (parameters.emplace(
2593 member.type, static_cast< sal_uInt32 >(parameters.size())).
2594 second) {
2595 sal_uInt32 k = static_cast< sal_uInt32 >(parameters.size() - 1);
2596 out << indent()
2597 << "::css::uno::Type const & the_ptype" << k
2598 << " = ::cppu::getTypeFavourChar(static_cast< ";
2599 dumpTypeParameterName(out, member.type);
2600 out << " * >(0));\n" << indent()
2601 << "::typelib_TypeClass the_pclass" << k
2602 << " = (::typelib_TypeClass) the_ptype" << k
2603 << ".getTypeClass();\n" << indent()
2604 << "::rtl::OUString the_pname" << k << "(the_ptype" << k
2605 << ".getTypeName());\n";
2606 }
2607 } else if (types.emplace(member.type, static_cast< sal_uInt32 >(types.size())).
2608 second) {
2609 dumpCppuGetType(out, member.type, &name_);
2610 // For typedefs, use the resolved type name, as there will be no
2611 // information available about the typedef itself at runtime (the
2612 // above getCppuType call will make available information about the
2613 // resolved type); no extra #include for the resolved type is
2614 // needed, as the header for the typedef includes it already:
2615 out << indent() << "::rtl::OUString the_tname"
2616 << static_cast< sal_uInt32 >(types.size() - 1) << "( \""
2617 << resolveAllTypedefs(member.type) << "\" );\n";
2618 }
2619 out << indent() << "::rtl::OUString the_name" << n++ << "( \""
2620 << member.name << "\" );\n";
2621 }
2622 out << indent() << "::typelib_StructMember_Init the_members[] = {\n";
2623 inc();
2624 n = 0;
2625 for (std::vector< unoidl::PolymorphicStructTypeTemplateEntity::Member >::
2626 const_iterator i(entity_->getMembers().begin());
2627 i != entity_->getMembers().end();) {
2628 out << indent() << "{ { ";
2629 if (i->parameterized) {
2630 sal_uInt32 k = parameters.find(i->type)->second;
2631 out << "the_pclass" << k << ", the_pname" << k << ".pData";
2632 } else {
2633 out << getTypeClass(i->type, true) << ", the_tname"
2634 << types.find(i->type)->second << ".pData";
2635 }
2636 out << ", the_name" << n++ << ".pData }, "
2637 << (i->parameterized ? "true" : "false") << " }";
2638 ++i;
2639 out << (i == entity_->getMembers().end() ? " };" : ",") << "\n";
2640 }
2641 dec();
2642 out << indent() << "::typelib_TypeDescription * the_newType = 0;\n";
2643 out << indent()
2644 << ("::typelib_typedescription_newStruct(&the_newType, the_name.pData,"
2645 " 0, ")
2646 << entity_->getMembers().size() << ", the_members);\n" << indent()
2647 << "::typelib_typedescription_register(&the_newType);\n" << indent()
2648 << "::typelib_typedescription_release(the_newType);\n" << indent()
2649 << "return new ::css::uno::Type(" << getTypeClass(name_)
2650 << ", the_name); // leaked\n";
2651 dec();
2652 out << indent() << "}\n";
2653 dec();
2654 out << indent() << "};\n } }\n\n";
2655 dumpGetCppuTypePreamble(out);
2656 out << indent() << "return *detail::" << staticTypeClass;
2657 dumpTemplateParameters(out);
2658 out << "::get();\n";
2659 dumpGetCppuTypePostamble(out);
2660}
2661
2662void PolyStructType::addLightGetCppuTypeIncludes(
2663 codemaker::cppumaker::Includes & includes) const
2664{
2665 includes.addType();
2666 includes.addCppuUnotypeHxx();
2667 includes.addSalTypesH();
2668 includes.addTypelibTypeclassH();
2669 includes.addTypelibTypedescriptionH();
2670 includes.addRtlStrbufHxx();
2671 includes.addRtlTextencH();
2672 includes.addRtlUstringHxx();
2673}
2674
2675void PolyStructType::addNormalGetCppuTypeIncludes(
2676 codemaker::cppumaker::Includes & includes) const
2677{
2678 includes.addType();
2679 includes.addCppuUnotypeHxx();
2680 includes.addSalTypesH();
2681 includes.addTypelibTypeclassH();
2682 includes.addTypelibTypedescriptionH();
2683 includes.addRtlStrbufHxx();
2684 includes.addRtlTextencH();
2685 includes.addRtlUstringHxx();
2686}
2687
2688void PolyStructType::addComprehensiveGetCppuTypeIncludes(
2689 codemaker::cppumaker::Includes & includes) const
2690{
2691 includes.addType();
2692 includes.addCppuUnotypeHxx();
2693 includes.addRtlInstanceHxx();
2694 includes.addRtlUstringH();
2695 includes.addRtlUstringHxx();
2696 includes.addSalTypesH();
2697 includes.addTypelibTypeclassH();
2698 includes.addTypelibTypedescriptionH();
2699 includes.addRtlStringH();
2700 includes.addRtlUstrbufHxx();
2701}
2702
2703void PolyStructType::dumpTemplateHead(FileStream & out) const
2704{
2705 out << "template< ";
2706 for (std::vector< OUString >::const_iterator i(
2707 entity_->getTypeParameters().begin());
2708 i != entity_->getTypeParameters().end(); ++i) {
2709 if (i != entity_->getTypeParameters().begin()) {
2710 out << ", ";
2711 }
2712 out << "typename ";
2713 dumpTypeParameterName(out, *i);
2714 }
2715 out << " > ";
2716}
2717
2718void PolyStructType::dumpTemplateParameters(FileStream & out) const
2719{
2720 out << "< ";
2721 for (std::vector< OUString >::const_iterator i(
2722 entity_->getTypeParameters().begin());
2723 i != entity_->getTypeParameters().end(); ++i) {
2724 if (i != entity_->getTypeParameters().begin()) {
2725 out << ", ";
2726 }
2727 dumpTypeParameterName(out, *i);
2728 }
2729 out << " >";
2730}
2731
2732OUString typeToIdentifier(std::u16string_view name)
2733{
2734 sal_Int32 k;
2735 OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k)));
2736 OUStringBuffer b(4*k + n.getLength());
2737 for (sal_Int32 i = 0; i != k; ++i) {
2738 b.append("seq_");
2739 }
2740 b.append(n);
2741 b.replace(' ', '_');
2742 b.replace(',', '_');
2743 b.replace('.', '_');
2744 b.replace('<', '_');
2745 b.replace('>', '_');
2746 return b.makeStringAndClear();
2747}
2748
2749class ExceptionType: public CppuType
2750{
2751public:
2754 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
2755 CppuType(name, typeMgr), entity_(entity) {
2756 assert(entity.is());
2757 }
2758
2759private:
2760 virtual void dumpHdlFile(
2761 FileStream & out, codemaker::cppumaker::Includes & includes) override;
2762
2763 virtual void dumpHppFile(
2764 FileStream & out, codemaker::cppumaker::Includes & includes) override;
2765
2766 virtual void addComprehensiveGetCppuTypeIncludes(
2767 codemaker::cppumaker::Includes & includes) const override;
2768
2769 virtual void dumpLightGetCppuType(FileStream & out) override;
2770
2771 virtual void dumpNormalGetCppuType(FileStream & out) override;
2772
2773 virtual void dumpComprehensiveGetCppuType(FileStream & out) override;
2774
2775 virtual sal_uInt32 checkInheritedMemberCount() const override {
2776 return getTotalMemberCount(entity_->getDirectBase());
2777 }
2778
2779 virtual void dumpDeclaration(FileStream & out) override;
2780
2781 bool dumpBaseMembers(
2782 FileStream & out, OUString const & base, bool withType,
2783 bool eligibleForDefaults);
2784
2785 sal_uInt32 getTotalMemberCount(OUString const & base) const;
2786
2788};
2789
2790void ExceptionType::dumpHdlFile(
2792{
2793 if (name_ == "com.sun.star.uno.Exception")
2794 {
2795 // LIBO_INTERNAL_ONLY implies GCC >= 7, which we need for this
2796 // Merely checking __has_include is not enough because some systems have the header,
2797 // but do not have a new enough Clang 9 supporting __builtin_FILE/LINE/FUNCTION as used by
2798 // that libstdc++ header.
2799 includes.addCustom("#if defined LIBO_INTERNAL_ONLY && ((defined __GNUC__ && !defined __clang__) || (defined __clang__ && __clang_major__ >= 9)) && __has_include(<experimental/source_location>)");
2800 includes.addCustom("#define LIBO_USE_SOURCE_LOCATION");
2801 includes.addCustom("#endif");
2802 includes.addCustom("#if defined LIBO_USE_SOURCE_LOCATION");
2803 includes.addCustom("#include <experimental/source_location>");
2804 includes.addCustom("#include <o3tl/runtimetooustring.hxx>");
2805 includes.addCustom("#endif");
2806 }
2807 dumpHFileContent(out, includes);
2808}
2809
2810void ExceptionType::addComprehensiveGetCppuTypeIncludes(
2811 codemaker::cppumaker::Includes & includes) const
2812{
2813 includes.addCppuUnotypeHxx();
2814 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
2815}
2816
2817void ExceptionType::dumpHppFile(
2819{
2820 OUString headerDefine(dumpHeaderDefine(out, u"HPP"));
2821 out << "\n";
2822 addDefaultHxxIncludes(includes);
2823 includes.dump(out, &name_, true);
2824
2825 // for the output operator below
2826 if (name_ == "com.sun.star.uno.Exception")
2827 {
2828 out << "#if defined LIBO_INTERNAL_ONLY\n";
2829 out << "#include <ostream>\n";
2830 out << "#include <typeinfo>\n";
2831 out << "#endif\n";
2832 }
2833
2834 out << "\n";
2835
2836 if (codemaker::cppumaker::dumpNamespaceOpen(out, name_, false)) {
2837 out << "\n";
2838 }
2839
2840 // default constructor
2841 out << "\ninline " << id_ << "::" << id_ << "(\n";
2842 out << "#if defined LIBO_USE_SOURCE_LOCATION\n";
2843 out << " std::experimental::source_location location\n";
2844 out << "#endif\n";
2845 out << " )\n";
2846 inc();
2847 OUString base(entity_->getDirectBase());
2848 bool bFirst = true;
2849 if (!base.isEmpty()) {
2850 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2851 << "(\n";
2852 out << "#if defined LIBO_USE_SOURCE_LOCATION\n";
2853 out << " location\n";
2854 out << "#endif\n";
2855 out << ")\n";
2856 bFirst = false;
2857 }
2858 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2859 out << indent() << (bFirst ? ":" : ",") << " ";
2860 out << member.name;
2861 dumpInitializer(out, false, member.type);
2862 out << "\n";
2863 bFirst = false;
2864 }
2865 dec();
2866 out << "{";
2867 if (!m_cppuTypeDynamic) {
2868 out << "\n";
2869 inc();
2870 dumpCppuGetType(out, name_);
2871 dec();
2872 } else {
2873 out << " ";
2874 }
2875 if (name_ == "com.sun.star.uno.Exception")
2876 {
2877 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
2878 out << " if (!Message.isEmpty())\n";
2879 out << " Message += \" \";\n";
2880 out << " Message += \"at \" + o3tl::runtimeToOUString(location.file_name()) + \":\" + OUString::number(location.line());\n";
2881 out << "#endif\n";
2882 }
2883 out << "}\n\n";
2884
2885 // fields constructor
2886 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
2887 out << indent() << "inline " << id_ << "::" << id_ << "(";
2888 bFirst = !dumpBaseMembers(out, base, true, false);
2889 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2890 if (!bFirst) {
2891 out << ", ";
2892 }
2893 dumpType(out, member.type, true, true);
2894 out << " " << member.name << "_";
2895 bFirst = false;
2896 }
2897 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
2898 out << " " << (bFirst ? "" : ", ") << "std::experimental::source_location location\n";
2899 out << "#endif\n";
2900 out << ")\n";
2901 inc();
2902 bFirst = true;
2903 if (!base.isEmpty()) {
2904 out << indent() << ": " << codemaker::cpp::scopedCppName(u2b(base))
2905 << "(";
2906 dumpBaseMembers(out, base, false, false);
2907 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
2908 out << " , location\n";
2909 out << "#endif\n";
2910 out << ")\n";
2911 bFirst = false;
2912 }
2913 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2914 out << indent() << (bFirst ? ":" : ",") << " " << member.name << "("
2915 << member.name << "_)\n";
2916 bFirst = false;
2917 }
2918 dec();
2919 out << "{";
2920 if (!m_cppuTypeDynamic) {
2921 out << "\n";
2922 inc();
2923 dumpCppuGetType(out, name_);
2924 dec();
2925 } else {
2926 out << " ";
2927 }
2928 if (name_ == "com.sun.star.uno.Exception")
2929 {
2930 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
2931 out << " if (!Message.isEmpty())\n";
2932 out << " Message += \" \";\n";
2933 out << " Message += \"at \" + o3tl::runtimeToOUString(location.file_name()) + \":\" + OUString::number(location.line());\n";
2934 out << "#endif\n";
2935 }
2936 out << "}\n\n";
2937 }
2938 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent() << id_ << "::" << id_
2939 << "(" << id_ << " const & the_other)";
2940 bFirst = true;
2941 if (!base.isEmpty()) {
2942 out << ": " << codemaker::cpp::scopedCppName(u2b(base))
2943 << "(the_other)";
2944 bFirst = false;
2945 }
2946 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2947 out << (bFirst ? ":" : ",") << " " << member.name << "(the_other." << member.name
2948 << ")";
2949 bFirst = false;
2950 }
2951 out << indent() << " {}\n\n" << indent() << id_ << "::~" << id_
2952 << "() {}\n\n" << indent() << id_ << " & " << id_ << "::operator =("
2953 << id_ << " const & the_other) {\n";
2954 inc();
2955 out << indent()
2956 << ("//TODO: Just like its implicitly-defined counterpart, this"
2957 " function definition is not exception-safe\n");
2958 if (!base.isEmpty()) {
2959 out << indent() << codemaker::cpp::scopedCppName(u2b(base))
2960 << "::operator =(the_other);\n";
2961 }
2962 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
2963 out << indent() << member.name << " = the_other." << member.name << ";\n";
2964 }
2965 out << indent() << "return *this;\n";
2966 dec();
2967 out << indent() << "}\n#endif\n\n";
2968
2969 // Provide an output operator for printing Exception information to SAL_WARN/SAL_INFO.
2970 if (name_ == "com.sun.star.uno.Exception")
2971 {
2972 out << "#if defined LIBO_INTERNAL_ONLY\n";
2973 out << "template< typename charT, typename traits >\n";
2974 out << "inline ::std::basic_ostream<charT, traits> & operator<<(\n";
2975 out << " ::std::basic_ostream<charT, traits> & os, ::com::sun::star::uno::Exception const & exception)\n";
2976 out << "{\n";
2977 out << " // the class name is useful because exception throwing code does not always pass in a useful message\n";
2978 out << " os << typeid(exception).name();\n";
2979 out << " if (!exception.Message.isEmpty())\n";
2980 out << " os << \" msg: \" << exception.Message;\n";
2981 out << " return os;\n";
2982 out << "}\n";
2983 out << "#endif\n";
2984 out << "\n";
2985 }
2986
2987 if (codemaker::cppumaker::dumpNamespaceClose(out, name_, false)) {
2988 out << "\n";
2989 }
2990 out << "\n";
2991
2992 dumpGetCppuType(out);
2993 out << "\n#endif // "<< headerDefine << "\n";
2994}
2995
2996void ExceptionType::dumpLightGetCppuType(FileStream & out)
2997{
2998 dumpGetCppuTypePreamble(out);
2999 out << indent()
3000 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3001 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3002 inc();
3003 out << indent() << "typelib_static_type_init( &the_type, "
3004 << getTypeClass(name_, true) << ", \"" << name_ << "\" );\n";
3005 dec();
3006 out << indent() << "}\n" << indent()
3007 << ("return * reinterpret_cast< ::css::uno::Type * >("
3008 " &the_type );\n");
3009 dumpGetCppuTypePostamble(out);
3010}
3011
3012void ExceptionType::dumpNormalGetCppuType(FileStream & out)
3013{
3014 dumpGetCppuTypePreamble(out);
3015 out << indent()
3016 << "static typelib_TypeDescriptionReference * the_type = 0;\n"
3017 << indent() << "if ( !the_type )\n" << indent() << "{\n";
3018 inc();
3019 OUString base(entity_->getDirectBase());
3020 bool baseException = false;
3021 if (!base.isEmpty()) {
3022 if (base == "com.sun.star.uno.Exception") {
3023 baseException = true;
3024 } else {
3025 out << indent()
3026 << ("const ::css::uno::Type& rBaseType ="
3027 " ::cppu::UnoType< ");
3028 dumpType(out, base, true, false, false, true);
3029 out << " >::get();\n\n";
3030 }
3031 }
3032 if (!entity_->getDirectMembers().empty()) {
3033 out << indent() << "typelib_TypeDescriptionReference * aMemberRefs["
3034 << entity_->getDirectMembers().size() << "];\n";
3035 std::set< OUString > seen;
3036 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
3037 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3038 OUString type(resolveAllTypedefs(member.type));
3039 OUString modType(typeToIdentifier(type));
3040 if (seen.insert(type).second) {
3041 out << indent()
3042 << "const ::css::uno::Type& rMemberType_"
3043 << modType << " = ::cppu::UnoType< ";
3044 dumpType(out, type, false, false, false, true);
3045 out << " >::get();\n";
3046 }
3047 out << indent() << "aMemberRefs[" << n++ << "] = rMemberType_"
3048 << modType << ".getTypeLibType();\n";
3049 }
3050 out << "\n";
3051 }
3052 out << indent() << "typelib_static_compound_type_init( &the_type, "
3053 << getTypeClass(name_, true) << ", \"" << name_ << "\", ";
3054 if (baseException) {
3055 out << ("* ::typelib_static_type_getByTypeClass("
3056 " typelib_TypeClass_EXCEPTION )");
3057 } else if (base.isEmpty()) {
3058 out << "0";
3059 } else {
3060 out << "rBaseType.getTypeLibType()";
3061 }
3062 out << ", " << entity_->getDirectMembers().size() << ", "
3063 << (entity_->getDirectMembers().empty() ? "0" : "aMemberRefs")
3064 << " );\n";
3065 dec();
3066 out << indent() << "}\n" << indent()
3067 << ("return * reinterpret_cast< const ::css::uno::Type * >("
3068 " &the_type );\n");
3069 dumpGetCppuTypePostamble(out);
3070}
3071
3072void ExceptionType::dumpComprehensiveGetCppuType(FileStream & out)
3073{
3074 codemaker::cppumaker::dumpNamespaceOpen(out, name_, false);
3075 out << " namespace detail {\n\n";
3076 OUString staticTypeClass("the" + id_ + "Type");
3077 out << indent() << "struct " << staticTypeClass
3078 << " : public rtl::StaticWithInit< ::css::uno::Type *, "
3079 << staticTypeClass << " >\n" << indent() << "{\n";
3080 inc();
3081 out << indent() << "::css::uno::Type * operator()() const\n"
3082 << indent() << "{\n";
3083 inc();
3084 out << indent() << "::rtl::OUString sTypeName( \"" << name_ << "\" );\n\n"
3085 << indent() << "// Start inline typedescription generation\n"
3086 << indent() << "typelib_TypeDescription * pTD = 0;\n";
3087 OUString base(entity_->getDirectBase());
3088 if (!base.isEmpty()) {
3089 out << indent()
3090 << ("const ::css::uno::Type& rSuperType ="
3091 " ::cppu::UnoType< ");
3092 dumpType(out, base, false, false, false, true);
3093 out << " >::get();\n";
3094 }
3095 std::set< OUString > seen;
3096 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3097 if (seen.insert(member.type).second) {
3098 dumpCppuGetType(out, member.type);
3099 }
3100 }
3101 if (!entity_->getDirectMembers().empty()) {
3102 out << "\n" << indent() << "typelib_CompoundMember_Init aMembers["
3103 << entity_->getDirectMembers().size() << "];\n";
3104 std::vector< unoidl::ExceptionTypeEntity::Member >::size_type n = 0;
3105 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3106 OUString type(resolveAllTypedefs(member.type));
3107 out << indent() << "::rtl::OUString sMemberType" << n << "( \""
3108 << type << "\" );\n" << indent()
3109 << "::rtl::OUString sMemberName" << n << "( \"" << member.name
3110 << "\" );\n" << indent() << "aMembers[" << n
3111 << "].eTypeClass = (typelib_TypeClass)" << getTypeClass(type)
3112 << ";\n" << indent() << "aMembers[" << n
3113 << "].pTypeName = sMemberType" << n << ".pData;\n" << indent()
3114 << "aMembers[" << n << "].pMemberName = sMemberName" << n
3115 << ".pData;\n";
3116 ++n;
3117 }
3118 }
3119 out << "\n" << indent() << "typelib_typedescription_new(\n";
3120 inc();
3121 out << indent() << "&pTD,\n" << indent() << "(typelib_TypeClass)"
3122 << getTypeClass(name_) << ", sTypeName.pData,\n" << indent()
3123 << (base.isEmpty() ? "0" : "rSuperType.getTypeLibType()") << ",\n"
3124 << indent() << entity_->getDirectMembers().size() << ",\n" << indent()
3125 << (entity_->getDirectMembers().empty() ? "0" : "aMembers")
3126 << " );\n\n";
3127 dec();
3128 out << indent()
3129 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3130 " );\n\n")
3131 << indent() << "typelib_typedescription_release( pTD );\n" << indent()
3132 << "// End inline typedescription generation\n\n" << indent()
3133 << "return new ::css::uno::Type( " << getTypeClass(name_)
3134 << ", sTypeName ); // leaked\n";
3135 dec();
3136 out << indent() << "}\n";
3137 dec();
3138 out << indent() << "};\n\n";
3140 out << " }\n\n";
3141 dumpGetCppuTypePreamble(out);
3142 out << indent() << "return *detail::" << staticTypeClass << "::get();\n";
3143 dumpGetCppuTypePostamble(out);
3144}
3145
3146void ExceptionType::dumpDeclaration(FileStream & out)
3147{
3148 out << "\nclass CPPU_GCC_DLLPUBLIC_EXPORT SAL_WARN_UNUSED " << id_;
3149 OUString base(entity_->getDirectBase());
3150 if (!base.isEmpty()) {
3151 out << " : public " << codemaker::cpp::scopedCppName(u2b(base));
3152 }
3153 out << "\n{\npublic:\n";
3154 inc();
3155
3156 // default constructor
3157 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(\n";
3158 out << "#if defined LIBO_USE_SOURCE_LOCATION\n";
3159 out << " std::experimental::source_location location = std::experimental::source_location::current()\n";
3160 out << "#endif\n\n";
3161 out << " );\n";
3162
3163 // constructor that initializes data members
3164 if (!entity_->getDirectMembers().empty() || getInheritedMemberCount() > 0) {
3165 out << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(";
3166 bool eligibleForDefaults = entity_->getDirectMembers().empty();
3167 bool bFirst = !dumpBaseMembers(out, base, true, eligibleForDefaults);
3168 for (const unoidl::ExceptionTypeEntity::Member& member : entity_->getDirectMembers()) {
3169 if (!bFirst) {
3170 out << ", ";
3171 }
3172 dumpType(out, member.type, true, true);
3173 out << " " << member.name << "_";
3174 bFirst = false;
3175 }
3176 out << "\n#if defined LIBO_USE_SOURCE_LOCATION\n";
3177 out << ", std::experimental::source_location location = std::experimental::source_location::current()\n";
3178 out << "#endif\n";
3179 out << " );\n\n";
3180 }
3181 out << "#if !defined LIBO_INTERNAL_ONLY\n" << indent()
3182 << "inline CPPU_GCC_DLLPRIVATE " << id_ << "(" << id_
3183 << " const &);\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE ~"
3184 << id_ << "();\n\n" << indent() << "inline CPPU_GCC_DLLPRIVATE " << id_
3185 << " & operator =(" << id_ << " const &);\n#endif\n\n";
3186 for (std::vector< unoidl::ExceptionTypeEntity::Member >::const_iterator i(
3187 entity_->getDirectMembers().begin());
3188 i != entity_->getDirectMembers().end(); ++i) {
3189 out << indent();
3190 dumpType(out, i->type);
3191 out << " " << i->name;
3192 if (i == entity_->getDirectMembers().begin() && !base.isEmpty()
3193 && i->type != "hyper" && i->type != "unsigned hyper"
3194 && i->type != "double") {
3195 out << " CPPU_GCC3_ALIGN( "
3196 << codemaker::cpp::scopedCppName(u2b(base)) << " )";
3197 }
3198 out << ";\n";
3199 }
3200 dec();
3201 out << "};\n\n";
3202}
3203
3204bool ExceptionType::dumpBaseMembers(
3205 FileStream & out, OUString const & base, bool withType, bool eligibleForDefaults)
3206{
3207 if (base.isEmpty())
3208 return false;
3209
3210 bool hasMember = false;
3212 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3214 throw CannotDumpException(
3215 "exception type base " + base + " is not an exception type");
3216 }
3218 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()));
3219 assert(ent2.is());
3220 if (!ent2.is()) {
3221 return false;
3222 }
3223 hasMember = dumpBaseMembers( out, ent2->getDirectBase(), withType,
3224 eligibleForDefaults && ent2->getDirectMembers().empty() );
3225 int memberCount = 0;
3226 for (const unoidl::ExceptionTypeEntity::Member& member : ent2->getDirectMembers()) {
3227 if (hasMember) {
3228 out << ", ";
3229 }
3230 if (withType) {
3231 dumpType(out, member.type, true, true);
3232 out << " ";
3233 }
3234 out << member.name << "_";
3235 // We want to provide a default parameter value for uno::Exception subtype
3236 // constructors, since most of the time we don't pass a Context object in to the exception
3237 // throw sites.
3238 if (eligibleForDefaults
3239 && base == "com.sun.star.uno.Exception"
3240 && memberCount == 1
3241 && member.name == "Context"
3242 && member.type == "com.sun.star.uno.XInterface") {
3243 out << " = ::css::uno::Reference< ::css::uno::XInterface >()";
3244 }
3245 hasMember = true;
3246 ++memberCount;
3247 }
3248 return hasMember;
3249}
3250
3251sal_uInt32 ExceptionType::getTotalMemberCount(OUString const & base) const
3252{
3253 if (base.isEmpty()) {
3254 return 0;
3255 }
3257 codemaker::UnoType::Sort sort = m_typeMgr->getSort(base, &ent);
3259 throw CannotDumpException(
3260 "exception type base " + base + " is not an exception type");
3261 }
3262 unoidl::ExceptionTypeEntity& ent2(dynamic_cast<unoidl::ExceptionTypeEntity&>(*ent));
3263 return getTotalMemberCount(ent2.getDirectBase())
3264 + ent2.getDirectMembers().size(); //TODO: overflow
3265}
3266
3267class EnumType: public CppuType
3268{
3269public:
3270 EnumType(
3272 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3273 CppuType(name, typeMgr), entity_(entity) {
3274 assert(entity.is());
3275 }
3276
3277private:
3278 virtual void dumpDeclaration(FileStream& o) override;
3279
3280 virtual void addComprehensiveGetCppuTypeIncludes(
3281 codemaker::cppumaker::Includes & includes) const override;
3282
3283 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3284
3285 void dumpNormalGetCppuType(FileStream& o) override;
3286 void dumpComprehensiveGetCppuType(FileStream& o) override;
3287
3289};
3290
3291void EnumType::addComprehensiveGetCppuTypeIncludes(
3292 codemaker::cppumaker::Includes & includes) const
3293{
3294 includes.addCppuUnotypeHxx();
3295 includes.addRtlInstanceHxx(); // using rtl::StaticWithInit
3296}
3297
3298void EnumType::dumpDeclaration(FileStream& o)
3299{
3300 o << "\n#if defined LIBO_INTERNAL_ONLY\n";
3301 o << "\nenum class SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3302 o << "\n#else\n";
3303 o << "\nenum SAL_DLLPUBLIC_RTTI " << id_ << "\n{\n";
3304 o << "\n#endif\n";
3305 inc();
3306
3307 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3308 o << indent() << id_ << "_" << u2b(member.name) << " = " << member.value
3309 << ",\n";
3310 }
3311
3312 o << indent() << id_ << "_MAKE_FIXED_SIZE = SAL_MAX_ENUM\n";
3313
3314 dec();
3315 o << "};\n\n";
3316
3317 // use constexpr to create a kind of type-alias so we don't have to modify existing code
3318 o << "#if defined LIBO_INTERNAL_ONLY\n";
3319 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3320 o << "constexpr auto " << id_ << "_" << u2b(member.name)
3321 << " = "
3322 << id_ << "::" << id_ << "_" << u2b(member.name)
3323 << ";\n";
3324 }
3325 o << "#endif\n";
3326}
3327
3328void EnumType::dumpHppFile(
3330{
3331 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3332 o << "\n";
3333
3334 addDefaultHxxIncludes(includes);
3335 includes.dump(o, &name_, true);
3336 o << "\n";
3337
3338 dumpGetCppuType(o);
3339
3340 o << "\n#endif // "<< headerDefine << "\n";
3341}
3342
3343void EnumType::dumpNormalGetCppuType(FileStream& o)
3344{
3345 dumpGetCppuTypePreamble(o);
3346
3347 o << indent()
3348 << "static typelib_TypeDescriptionReference * the_type = 0;\n";
3349
3350 o << indent() << "if ( !the_type )\n" << indent() << "{\n";
3351 inc();
3352
3353 o << indent() << "typelib_static_enum_type_init( &the_type,\n";
3354 inc(31);
3355 o << indent() << "\"" << name_ << "\",\n"
3356 << indent() << codemaker::cpp::scopedCppName(u2b(name_)) << "_"
3357 << u2b(entity_->getMembers()[0].name) << " );\n";
3358 dec(31);
3359 dec();
3360 o << indent() << "}\n";
3361 o << indent()
3362 << ("return * reinterpret_cast< ::css::uno::Type * >("
3363 " &the_type );\n");
3364 dumpGetCppuTypePostamble(o);
3365}
3366
3367void EnumType::dumpComprehensiveGetCppuType(FileStream& o)
3368{
3369 if (!isPolymorphic())
3371 else
3372 o << "namespace cppu { ";
3373 o << " namespace detail {\n\n";
3374
3375 OUString sStaticTypeClass("the" + id_ + "Type");
3376 o << indent() << "struct " << sStaticTypeClass << " : public rtl::StaticWithInit< ::css::uno::Type *, " << sStaticTypeClass << " >\n";
3377 o << indent() << "{\n";
3378 inc();
3379 o << indent() << "::css::uno::Type * operator()() const\n";
3380 o << indent() << "{\n";
3381
3382 inc();
3383 o << indent() << "::rtl::OUString sTypeName( \"" << name_
3384 << "\" );\n\n";
3385
3386 o << indent() << "// Start inline typedescription generation\n"
3387 << indent() << "typelib_TypeDescription * pTD = 0;\n\n";
3388
3389 o << indent() << "rtl_uString* enumValueNames["
3390 << entity_->getMembers().size() << "];\n";
3391 std::vector< unoidl::EnumTypeEntity::Member >::size_type n = 0;
3392 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3393 o << indent() << "::rtl::OUString sEnumValue" << n << "( \""
3394 << u2b(member.name) << "\" );\n";
3395 o << indent() << "enumValueNames[" << n << "] = sEnumValue" << n
3396 << ".pData;\n";
3397 ++n;
3398 }
3399
3400 o << "\n" << indent() << "sal_Int32 enumValues["
3401 << entity_->getMembers().size() << "];\n";
3402 n = 0;
3403 for (const unoidl::EnumTypeEntity::Member& member : entity_->getMembers()) {
3404 o << indent() << "enumValues[" << n++ << "] = " << member.value << ";\n";
3405 }
3406
3407 o << "\n" << indent() << "typelib_typedescription_newEnum( &pTD,\n";
3408 inc();
3409 o << indent() << "sTypeName.pData,\n"
3410 << indent() << "(sal_Int32)"
3411 << codemaker::cpp::scopedCppName(u2b(name_), false) << "_"
3412 << u2b(entity_->getMembers()[0].name) << ",\n"
3413 << indent() << entity_->getMembers().size()
3414 << ", enumValueNames, enumValues );\n\n";
3415 dec();
3416
3417 o << indent()
3418 << ("typelib_typedescription_register( (typelib_TypeDescription**)&pTD"
3419 " );\n");
3420 o << indent() << "typelib_typedescription_release( pTD );\n"
3421 << indent() << "// End inline typedescription generation\n\n";
3422
3423 o << indent() << "return new ::css::uno::Type( "
3424 << getTypeClass(name_) << ", sTypeName ); // leaked\n";
3425
3426 dec();
3427 o << indent() << "}\n";
3428 dec();
3429 o << indent() << "};\n\n";
3430
3431 if (!isPolymorphic())
3433 else
3434 o << " }";
3435 o << " }\n\n";
3436
3437 dumpGetCppuTypePreamble(o);
3438 o << indent() << "return *detail::" << sStaticTypeClass << "::get();\n";
3439 dumpGetCppuTypePostamble(o);
3440}
3441
3442class Typedef: public CppuType
3443{
3444public:
3445 Typedef(
3447 OUString const & name, rtl::Reference< TypeManager > const & typeMgr):
3448 CppuType(name, typeMgr), entity_(entity) {
3449 assert(entity.is());
3450 }
3451
3452private:
3453 virtual void dumpDeclaration(FileStream& o) override;
3454
3455 void dumpHdlFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3456
3457 void dumpHppFile(FileStream& o, codemaker::cppumaker::Includes & includes) override;
3458
3460};
3461
3462void Typedef::dumpHdlFile(
3464{
3465 OUString headerDefine(dumpHeaderDefine(o, u"HDL"));
3466 o << "\n";
3467
3468 addDefaultHIncludes(includes);
3469 includes.dump(o, nullptr, true);
3470 o << "\n";
3471
3472 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3473 o << "\n";
3474 }
3475
3476 dumpDeclaration(o);
3477
3478 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3479 o << "\n";
3480 }
3481
3482 o << "#endif // "<< headerDefine << "\n";
3483}
3484
3485void Typedef::dumpDeclaration(FileStream& o)
3486{
3487 o << "\ntypedef ";
3488 dumpType(o, entity_->getType());
3489 o << " " << id_ << ";\n\n";
3490}
3491
3492void Typedef::dumpHppFile(
3494{
3495 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3496 o << "\n";
3497
3498 addDefaultHxxIncludes(includes);
3499 includes.dump(o, &name_, true);
3500 o << "\n";
3501
3502 o << "\n#endif // "<< headerDefine << "\n";
3503}
3504
3505class ConstructiveType: public CppuType
3506{
3507public:
3508 ConstructiveType(
3509 OUString const & name, rtl::Reference< TypeManager > const & manager):
3510 CppuType(name, manager) {}
3511
3512private:
3513 virtual void dumpHdlFile(FileStream &, codemaker::cppumaker::Includes &) override {
3514 assert(false); // this cannot happen
3515 }
3516
3517 virtual void dumpFiles(OUString const & uri, CppuOptions const & options) override {
3518 dumpFile(uri, name_, true, options);
3519 }
3520};
3521
3522bool hasRestParameter(
3524{
3525 return !constructor.parameters.empty()
3526 && constructor.parameters.back().rest;
3527}
3528
3529void includeExceptions(
3531 codemaker::ExceptionTreeNode const * node)
3532{
3533 if (node->present) {
3534 includes.add(node->name);
3535 } else {
3536 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3537 includeExceptions(includes, pChild.get());
3538 }
3539 }
3540}
3541
3542class ServiceType: public ConstructiveType
3543{
3544public:
3545 ServiceType(
3547 entity,
3548 OUString const & name, rtl::Reference< TypeManager > const & manager):
3549 ConstructiveType(name, manager), entity_(entity) {
3550 assert(entity.is());
3551 }
3552
3553private:
3554 virtual void dumpHppFile(
3555 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3556
3557 void dumpCatchClauses(
3558 FileStream & out, codemaker::ExceptionTreeNode const * node);
3559
3561};
3562
3563void failsToSupply(
3564 FileStream & o, std::u16string_view service, OString const & type)
3565{
3566 o << "::rtl::OUString(\"component context fails to supply service \") + \""
3567 << service << "\" + \" of type \" + \"" << type << "\"";
3568}
3569
3570void ServiceType::dumpHppFile(
3572{
3573 if (!entity_->getConstructors().empty()) {
3574 //TODO: Decide whether the types added to includes should rather be
3575 // added to m_dependencies (and thus be generated during
3576 // dumpDependedTypes):
3577 includes.addCassert();
3578 includes.addReference();
3579 includes.addRtlUstringH();
3580 includes.addRtlUstringHxx();
3581 includes.add("com.sun.star.uno.DeploymentException");
3582 includes.add("com.sun.star.uno.XComponentContext");
3583 for (const unoidl::SingleInterfaceBasedServiceEntity::Constructor& cons : entity_->getConstructors()) {
3584 if (cons.defaultConstructor) {
3585 includes.add("com.sun.star.uno.Exception");
3586 includes.add("com.sun.star.uno.RuntimeException");
3587 } else {
3588 if (!hasRestParameter(cons)) {
3589 includes.addAny();
3590 includes.addSequence();
3592 cons.parameters) {
3593 if (m_typeMgr->getSort(
3595 u2b(param.type))))
3597 includes.addCppuUnotypeHxx();
3598 break;
3599 }
3600 }
3601 }
3603 for (const OUString& ex : cons.exceptions) {
3604 tree.add(u2b(ex), m_typeMgr);
3605 }
3606 if (!tree.getRoot().present) {
3607 includes.add("com.sun.star.uno.Exception");
3608 includes.add("com.sun.star.uno.RuntimeException");
3609 includeExceptions(includes, &tree.getRoot());
3610 }
3611 }
3612 }
3613 }
3614 OString cppName(
3616 u2b(id_), "service", isGlobal()));
3617 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3618 o << "\n";
3619 includes.dump(o, nullptr, true);
3620 if (!entity_->getConstructors().empty()) {
3621 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3622 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3623 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3624 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3625 << name_.replaceAll(".", "_dot_")
3626 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3627 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3628 << name_.replaceAll(".", "_dot_")
3629 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3630 << name_.replaceAll(".", "_dot_")
3631 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3632 "::css::uno::Any > const &);\n#endif\n";
3633 }
3634 o << "\n";
3635 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3636 o << "\n";
3637 }
3638 o << "\nclass " << cppName << " {\n";
3639 inc();
3640 if (!entity_->getConstructors().empty()) {
3641 OString baseName(u2b(entity_->getBase()));
3642 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3643 o << "public:\n";
3645 entity_->getConstructors()) {
3646 if (cons.defaultConstructor) {
3647 o << indent() << "static ::css::uno::Reference< "
3648 << scopedBaseName << " > "
3651 &cppName)
3652 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3653 " the_context) {\n");
3654 inc();
3655 o << indent() << "assert(the_context.is());\n" << indent()
3656 << "::css::uno::Reference< " << scopedBaseName
3657 << " > the_instance;\n" << indent() << "try {\n";
3658 inc();
3659 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3660 "LO_URE_CTOR_ENV_")
3661 << name_.replaceAll(".", "_dot_")
3662 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3663 << name_.replaceAll(".", "_dot_")
3664 << ") && defined LO_URE_CTOR_FUN_"
3665 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3666 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3667 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3668 "static_cast< ::css::uno::XInterface * >((*"
3669 "LO_URE_CTOR_FUN_")
3670 << name_.replaceAll(".", "_dot_")
3671 << (")(the_context.get(), ::css::uno::Sequence<"
3672 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3673 " ::css::uno::UNO_QUERY);\n#else\n")
3674 << indent() << "the_instance = ::css::uno::Reference< "
3675 << scopedBaseName
3676 << (" >(the_context->getServiceManager()->"
3677 "createInstanceWithContext("
3678 " \"")
3679 << name_
3680 << "\", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3681 dec();
3682 o << indent()
3683 << "} catch (const ::css::uno::RuntimeException &) {\n";
3684 inc();
3685 o << indent() << "throw;\n";
3686 dec();
3687 o << indent()
3688 << "} catch (const ::css::uno::Exception & the_exception) {\n";
3689 inc();
3690 o << indent() << "throw ::css::uno::DeploymentException(";
3691 failsToSupply(o, name_, baseName);
3692 o << " + \": \" + the_exception.Message, the_context);\n";
3693 dec();
3694 o << indent() << "}\n" << indent()
3695 << "if (!the_instance.is()) {\n";
3696 inc();
3697 o << indent() << "throw ::css::uno::DeploymentException(";
3698 failsToSupply(o, name_, baseName);
3699 o << ", the_context);\n";
3700 dec();
3701 o << indent() << "}\n" << indent() << "return the_instance;\n";
3702 dec();
3703 o << indent() << "}\n\n";
3704 } else {
3705 o << indent() << "static ::css::uno::Reference< "
3706 << scopedBaseName << " > "
3709 &cppName)
3710 << ("(::css::uno::Reference< ::css::uno::XComponentContext > const &"
3711 " the_context");
3712 bool rest = hasRestParameter(cons);
3714 cons.parameters) {
3715 o << ", ";
3716 OUStringBuffer buf(2 + param.type.getLength());
3717 if (param.rest) {
3718 buf.append("[]");
3719 }
3720 buf.append(param.type);
3721 OUString type(buf.makeStringAndClear());
3722 bool byRef = passByReference(type);
3723 dumpType(o, type, byRef, byRef);
3724 o << " "
3727 }
3728 o << ") {\n";
3729 inc();
3730 o << indent() << "assert(the_context.is());\n";
3731 if (!rest && !cons.parameters.empty()) {
3732 o << indent()
3733 << "::css::uno::Sequence< ::css::uno::Any > the_arguments("
3734 << cons.parameters.size() << ");\n";
3735 o << indent()
3736 << "::css::uno::Any* the_arguments_array = the_arguments.getArray();\n";
3737
3738 std::vector<
3739 unoidl::SingleInterfaceBasedServiceEntity::Constructor::
3740 Parameter >::size_type n = 0;
3742 cons.parameters) {
3743 o << indent() << "the_arguments_array[" << n++ << "] ";
3744 OString param(
3746 u2b(j.name), "param",
3748 sal_Int32 rank;
3749 if (resolveOuterTypedefs(j.type) == "any") {
3750 o << "= " << param;
3751 } else if (m_typeMgr->getSort(
3753 u2b(j.type), &rank)))
3755 o << "= ::css::uno::Any(&" << param
3756 << ", ::cppu::UnoType< ";
3757 for (sal_Int32 k = 0; k < rank; ++k) {
3758 o << "::cppu::UnoSequenceType< ";
3759 }
3760 o << "::cppu::UnoCharType";
3761 for (sal_Int32 k = 0; k < rank; ++k) {
3762 o << " >";
3763 }
3764 o << " >::get())";
3765 } else {
3766 o << "<<= " << param;
3767 }
3768 o << ";\n";
3769 }
3770 }
3771 o << indent() << "::css::uno::Reference< "
3772 << scopedBaseName << " > the_instance;\n";
3774 for (const OUString& ex : cons.exceptions) {
3775 tree.add(u2b(ex), m_typeMgr);
3776 }
3777 if (!tree.getRoot().present) {
3778 o << indent() << "try {\n";
3779 inc();
3780 }
3781 o << ("#if defined LO_URE_CURRENT_ENV && defined "
3782 "LO_URE_CTOR_ENV_")
3783 << name_.replaceAll(".", "_dot_")
3784 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3785 << name_.replaceAll(".", "_dot_")
3786 << ") && defined LO_URE_CTOR_FUN_"
3787 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3788 << "the_instance = ::css::uno::Reference< " << scopedBaseName
3789 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3790 "static_cast< ::css::uno::XInterface * >((*"
3791 "LO_URE_CTOR_FUN_")
3792 << name_.replaceAll(".", "_dot_")
3793 << ")(the_context.get(), ";
3794 if (rest) {
3796 u2b(cons.parameters.back().name), "param",
3798 } else if (cons.parameters.empty()) {
3799 o << "::css::uno::Sequence< ::css::uno::Any >()";
3800 } else {
3801 o << "the_arguments";
3802 }
3803 o << ")), ::SAL_NO_ACQUIRE), ::css::uno::UNO_QUERY);\n" << indent()
3804 << ("::css::uno::Reference< ::css::lang::XInitialization > "
3805 "init(the_instance, ::css::uno::UNO_QUERY);\n")
3806 << indent() << "if (init.is()) {\n"
3807 << indent() << " init->initialize(";
3808 if (cons.parameters.empty()) {
3809 o << "::css::uno::Sequence< ::css::uno::Any >()";
3810 } else {
3811 o << "the_arguments";
3812 }
3813 o << ");\n" << indent() << "}\n";
3814 o << "#else\n"
3815 << indent() << "the_instance = ::css::uno::Reference< "
3816 << scopedBaseName
3817 << (" >(the_context->getServiceManager()->"
3818 "createInstanceWithArgumentsAndContext("
3819 " \"")
3820 << name_ << "\", ";
3821 if (rest) {
3823 u2b(cons.parameters.back().name), "param",
3825 } else if (cons.parameters.empty()) {
3826 o << "::css::uno::Sequence< ::css::uno::Any >()";
3827 } else {
3828 o << "the_arguments";
3829 }
3830 o << ", the_context), ::css::uno::UNO_QUERY);\n#endif\n";
3831 if (!tree.getRoot().present) {
3832 dec();
3833 o << indent()
3834 << "} catch (const ::css::uno::RuntimeException &) {\n";
3835 inc();
3836 o << indent() << "throw;\n";
3837 dec();
3838 dumpCatchClauses(o, &tree.getRoot());
3839 o << indent()
3840 << ("} catch (const ::css::uno::Exception &"
3841 " the_exception) {\n");
3842 inc();
3843 o << indent() << "throw ::css::uno::DeploymentException(";
3844 failsToSupply(o, name_, baseName);
3845 o << " + \": \" + the_exception.Message, the_context);\n";
3846 dec();
3847 o << indent() << "}\n";
3848 }
3849 o << indent() << "if (!the_instance.is()) {\n";
3850 inc();
3851 o << indent() << "throw ::css::uno::DeploymentException(";
3852 failsToSupply(o, name_, baseName);
3853 o << ", the_context);\n";
3854 dec();
3855 o << indent() << "}\n" << indent() << "return the_instance;\n";
3856 dec();
3857 o << indent() << "}\n\n";
3858 }
3859 }
3860 }
3861 o << "private:\n";
3862 o << indent() << cppName << "(); // not implemented\n"
3863 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3864 << indent() << "~" << cppName << "(); // not implemented\n"
3865 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3866 dec();
3867 o << "};\n\n";
3868 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3869 o << "\n";
3870 }
3871 o << "\n#endif // "<< headerDefine << "\n";
3872}
3873
3874void ServiceType::dumpCatchClauses(
3875 FileStream & out, codemaker::ExceptionTreeNode const * node)
3876{
3877 if (node->present) {
3878 out << indent() << "} catch (const ";
3879 dumpType(out, b2u(node->name));
3880 out << " &) {\n";
3881 inc();
3882 out << indent() << "throw;\n";
3883 dec();
3884 } else {
3885 for (std::unique_ptr<codemaker::ExceptionTreeNode> const & pChild : node->children) {
3886 dumpCatchClauses(out, pChild.get());
3887 }
3888 }
3889}
3890
3891class SingletonType: public ConstructiveType
3892{
3893public:
3894 SingletonType(
3896 OUString const & name, rtl::Reference< TypeManager > const & manager):
3897 ConstructiveType(name, manager), entity_(entity) {
3898 assert(entity.is());
3899 }
3900
3901private:
3902 virtual void dumpHppFile(
3903 FileStream & o, codemaker::cppumaker::Includes & includes) override;
3904
3906};
3907
3908void SingletonType::dumpHppFile(
3910{
3911 OString cppName(
3913 u2b(id_), "singleton", isGlobal()));
3914 OString baseName(u2b(entity_->getBase()));
3915 OString scopedBaseName(codemaker::cpp::scopedCppName(baseName));
3916 OUString headerDefine(dumpHeaderDefine(o, u"HPP"));
3917 o << "\n";
3918 //TODO: Decide whether the types added to includes should rather be added to
3919 // m_dependencies (and thus be generated during dumpDependedTypes):
3920 includes.add("com.sun.star.uno.DeploymentException");
3921 includes.add("com.sun.star.uno.XComponentContext");
3922 includes.addCassert();
3923 includes.addAny();
3924 includes.addReference();
3925 includes.addRtlUstringH();
3926 includes.addRtlUstringHxx();
3927 includes.dump(o, nullptr, true);
3928 o << ("\n#if defined ANDROID || defined IOS //TODO\n"
3929 "#include <com/sun/star/lang/XInitialization.hpp>\n"
3930 "#include <osl/detail/component-defines.h>\n#endif\n\n"
3931 "#if defined LO_URE_CURRENT_ENV && defined LO_URE_CTOR_ENV_")
3932 << name_.replaceAll(".", "_dot_")
3933 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3934 << name_.replaceAll(".", "_dot_") << ") && defined LO_URE_CTOR_FUN_"
3935 << name_.replaceAll(".", "_dot_")
3936 << "\nextern \"C\" ::css::uno::XInterface * SAL_CALL LO_URE_CTOR_FUN_"
3937 << name_.replaceAll(".", "_dot_")
3938 << "(::css::uno::XComponentContext *, ::css::uno::Sequence< "
3939 "::css::uno::Any > const &);\n#endif\n";
3940 o << "\n";
3941 if (codemaker::cppumaker::dumpNamespaceOpen(o, name_, false)) {
3942 o << "\n";
3943 }
3944 o << "\nclass " << cppName << " {\npublic:\n";
3945 inc();
3946 o << indent() << "static ::css::uno::Reference< "
3947 << scopedBaseName << " > "
3950 << ("(::css::uno::Reference<"
3951 " ::css::uno::XComponentContext > const & the_context)"
3952 " {\n");
3953 inc();
3954 o << indent() << "assert(the_context.is());\n" << indent()
3955 << "::css::uno::Reference< " << scopedBaseName
3956 << (" > instance;\n#if defined LO_URE_CURRENT_ENV && defined "
3957 "LO_URE_CTOR_ENV_")
3958 << name_.replaceAll(".", "_dot_")
3959 << " && (LO_URE_CURRENT_ENV) == (LO_URE_CTOR_ENV_"
3960 << name_.replaceAll(".", "_dot_")
3961 << ") && defined LO_URE_CTOR_FUN_"
3962 << name_.replaceAll(".", "_dot_") << "\n" << indent()
3963 << "instance = ::css::uno::Reference< " << scopedBaseName
3964 << (" >(::css::uno::Reference< ::css::uno::XInterface >("
3965 "static_cast< ::css::uno::XInterface * >((*"
3966 "LO_URE_CTOR_FUN_")
3967 << name_.replaceAll(".", "_dot_")
3968 << (")(the_context.get(), ::css::uno::Sequence<"
3969 " ::css::uno::Any >())), ::SAL_NO_ACQUIRE),"
3970 " ::css::uno::UNO_QUERY);\n#else\n")
3971 << indent() << ("the_context->getValueByName("
3972 "::rtl::OUString( \"/singletons/")
3973 << name_ << "\" )) >>= instance;\n#endif\n"
3974 << indent() << "if (!instance.is()) {\n";
3975 inc();
3976 o << indent()
3977 << ("throw ::css::uno::DeploymentException("
3978 "::rtl::OUString( \"component context"
3979 " fails to supply singleton ")
3980 << name_ << " of type " << baseName << "\" ), the_context);\n";
3981 dec();
3982 o << indent() << "}\n" << indent() << "return instance;\n";
3983 dec();
3984 o << indent() << "}\n\n";
3985 o << "private:\n";
3986 o << indent() << cppName << "(); // not implemented\n"
3987 << indent() << cppName << "(" << cppName << " &); // not implemented\n"
3988 << indent() << "~" << cppName << "(); // not implemented\n"
3989 << indent() << "void operator =(" << cppName << "); // not implemented\n";
3990 dec();
3991 o << "};\n\n";
3992 if (codemaker::cppumaker::dumpNamespaceClose(o, name_, false)) {
3993 o << "\n";
3994 }
3995 o << "\n#endif // "<< headerDefine << "\n";
3996}
3997
3998}
3999
4001 OUString const & name, rtl::Reference< TypeManager > const & manager,
4002 codemaker::GeneratedTypeSet & generated, CppuOptions const & options)
4003{
4004 if (generated.contains(u2b(name))) {
4005 return;
4006 }
4007 generated.add(u2b(name));
4008 if (!manager->foundAtPrimaryProvider(name)) {
4009 return;
4010 }
4013 switch (manager->getSort(name, &ent, &cur)) {
4015 OUString prefix;
4016 if (!name.isEmpty()) {
4017 prefix = name + ".";
4018 }
4019 for (;;) {
4020 OUString mem;
4021 if (!cur->getNext(&mem).is()) {
4022 break;
4023 }
4024 produce(prefix + mem, manager, generated, options);
4025 }
4026 break;
4027 }
4029 EnumType t(
4030 dynamic_cast< unoidl::EnumTypeEntity * >(ent.get()), name,
4031 manager);
4032 t.dump(options);
4033 t.dumpDependedTypes(generated, options);
4034 break;
4035 }
4037 PlainStructType t(
4038 dynamic_cast< unoidl::PlainStructTypeEntity * >(ent.get()),
4039 name, manager);
4040 t.dump(options);
4041 t.dumpDependedTypes(generated, options);
4042 break;
4043 }
4045 PolyStructType t(
4047 ent.get()),
4048 name, manager);
4049 t.dump(options);
4050 t.dumpDependedTypes(generated, options);
4051 break;
4052 }
4055 dynamic_cast< unoidl::ExceptionTypeEntity * >(ent.get()), name,
4056 manager);
4057 t.dump(options);
4058 t.dumpDependedTypes(generated, options);
4059 break;
4060 }
4062 InterfaceType t(
4063 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()), name,
4064 manager);
4065 t.dump(options);
4066 t.dumpDependedTypes(generated, options);
4067 break;
4068 }
4070 Typedef t(
4071 dynamic_cast< unoidl::TypedefEntity * >(ent.get()), name,
4072 manager);
4073 t.dump(options);
4074 t.dumpDependedTypes(generated, options);
4075 break;
4076 }
4078 ConstantGroup t(
4079 dynamic_cast< unoidl::ConstantGroupEntity * >(ent.get()), name,
4080 manager);
4081 if (t.hasConstants()) {
4082 t.dump(options);
4083 }
4084 break;
4085 }
4087 ServiceType t(
4089 ent.get()),
4090 name, manager);
4091 t.dump(options);
4092 t.dumpDependedTypes(generated, options);
4093 break;
4094 }
4096 SingletonType t(
4097 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
4098 ent.get()),
4099 name, manager);
4100 t.dump(options);
4101 t.dumpDependedTypes(generated, options);
4102 break;
4103 }
4106 break;
4107 default:
4108 throw CannotDumpException(
4109 "unexpected entity \"" + name + "\" in call to produce");
4110 }
4111}
4112
4113/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
bool isValid(const ::rtl::OString &option) const
Definition: options.cxx:26
const OString & getOption(const ::rtl::OString &option) const
Definition: options.cxx:31
Represents the hierarchy formed by a set of UNO exception types.
void add(rtl::OString const &name, rtl::Reference< TypeManager > const &manager)
Builds the exception hierarchy, by adding one exception type at a time.
ExceptionTreeNode const & getRoot() const
Gives access to the resultant exception hierarchy.
A simple class to track which types have already been processed by a code maker.
bool contains(OString const &type) const
Checks whether a given type has already been generated.
void add(OString const &type)
Add a type to the set of generated types.
A simple class to track which other entities a given entity depends on.
std::map< OUString, Kind > Map
void add(OString const &entityName)
Definition: includes.cxx:72
static void dumpInclude(FileStream &out, OString const &entityName, bool hpp)
Definition: includes.cxx:262
void dump(FileStream &out, OUString const *companionHdl, bool exceptions)
Definition: includes.cxx:136
void addCustom(const OUString &s)
Definition: includes.hxx:61
const OUString & getType() const
rtl::Reference< ParseManager > manager
void produce(OUString const &name, rtl::Reference< TypeManager > const &manager, codemaker::GeneratedTypeSet &generated, CppuOptions const &options)
Definition: cpputype.cxx:4000
void const * base
OString getTempDir(const OString &sFileName)
Definition: global.cxx:52
bool removeTypeFile(const OString &fileName)
Definition: global.cxx:216
OString createFileNameFromType(const OString &destination, const OString &typeName, const OString &postfix)
Definition: global.cxx:65
bool fileExists(const OString &fileName)
Definition: global.cxx:147
bool makeValidTypeFile(const OString &targetFileName, const OString &tmpFileName, bool bFileCheck)
Definition: global.cxx:192
const char * name
OUString aName
sal_Int64 n
rtl::Reference< Manager > manager_
bool SC_DLLPUBLIC isRef(const ScTokenRef &pToken)
VCL_DLLPUBLIC void dump(const SkBitmap &bitmap, const char *file)
Sort
An enumeration of all the sorts of relevant UNOIDL entities.
Definition: unotype.hxx:33
rtl::OString decompose(rtl::OString const &type, sal_Int32 *rank=nullptr, std::vector< rtl::OString > *arguments=nullptr)
Decomposes a UNO type name or UNO type registry name.
OString translateUnoToCppIdentifier(OString const &unoIdentifier, std::string_view prefix, IdentifierTranslationMode transmode, OString const *forbidden)
Definition: commoncpp.cxx:90
OString scopedCppName(OString const &type, bool ns_alias)
Definition: commoncpp.cxx:38
bool dumpNamespaceClose(FileStream &out, std::u16string_view entityName, bool fullModuleType)
Definition: dumputils.cxx:51
bool dumpNamespaceOpen(FileStream &out, std::u16string_view entityName, bool fullModuleType)
Definition: dumputils.cxx:32
void copy(const fs::path &src, const fs::path &dest)
int i
index
m
args
PyRef getTypeClass(const Runtime &)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
std::map< OUString, rtl::Reference< Entity > > map
ExceptionType(unsigned char *pCode, sal_uInt64 pCodeBase, typelib_TypeDescription *pTD) noexcept
Represents a node of the hierarchy from the ExceptionTree class.
OUString b2u(std::string_view s)
Definition: typemanager.hxx:71
OString u2b(std::u16string_view s)
Definition: typemanager.hxx:67
ResultType type
OUString name_