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
22 #include <codemaker/codemaker.hxx>
23 #include <codemaker/commoncpp.hxx>
24 #include <codemaker/global.hxx>
25
26 #include "skeletoncommon.hxx"
27 #include "skeletoncpp.hxx"
28
29 #include <algorithm>
30
31 using namespace ::codemaker::cpp;
32
33 namespace skeletonmaker { namespace cpp {
34
printType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,OUString const & nucleus,sal_Int32 rank,std::vector<OUString> const & arguments,rtl::Reference<unoidl::Entity> const & entity,short referenceType,bool defaultvalue)35 static void printType(
36 std::ostream & o, ProgramOptions const & options,
37 rtl::Reference< TypeManager > const & manager,
38 codemaker::UnoType::Sort sort, OUString const & nucleus, sal_Int32 rank,
39 std::vector< OUString > const & arguments,
40 rtl::Reference< unoidl::Entity > const & entity, short referenceType,
41 bool defaultvalue)
42 {
43 if (defaultvalue && rank == 0 && sort <= codemaker::UnoType::Sort::Char) {
44 switch (sort) {
45 case codemaker::UnoType::Sort::Boolean:
46 o << "sal_False";
47 return;
48 case codemaker::UnoType::Sort::Char:
49 case codemaker::UnoType::Sort::Byte:
50 case codemaker::UnoType::Sort::Short:
51 case codemaker::UnoType::Sort::UnsignedShort:
52 case codemaker::UnoType::Sort::Long:
53 case codemaker::UnoType::Sort::UnsignedLong:
54 case codemaker::UnoType::Sort::Hyper:
55 case codemaker::UnoType::Sort::UnsignedHyper:
56 case codemaker::UnoType::Sort::Float:
57 case codemaker::UnoType::Sort::Double:
58 o << "0";
59 return;
60 default:
61 break;
62 }
63 }
64
65 if (defaultvalue && referenceType == 16) {
66 if (sort == codemaker::UnoType::Sort::Enum) {
67 auto pEnumTypeEntity(dynamic_cast<unoidl::EnumTypeEntity *>(entity.get()));
68 assert(pEnumTypeEntity);
69 o << nucleus.copy(nucleus.lastIndexOf('.') + 1) << "_"
70 << pEnumTypeEntity->getMembers()[0].name;
71 }
72 return;
73 }
74 bool bReference = false;
75 if (((sort > codemaker::UnoType::Sort::Char ||
76 rank > 0) && referenceType != 8 &&
77 !(sort == codemaker::UnoType::Sort::Enum && referenceType == 4 && rank == 0)) ||
78 (sort <= codemaker::UnoType::Sort::Char && referenceType == 2))
79 {
80 bReference = true;
81 }
82
83 if (bReference && referenceType == 4)
84 o << "const ";
85
86 for (sal_Int32 i = 0; i < rank; ++i) {
87 o << ((options.shortnames) ? "css::uno::Sequence< " :
88 "::com::sun::star::uno::Sequence< ");
89 }
90 if (sort == codemaker::UnoType::Sort::Interface && referenceType > 0) {
91 o << ((options.shortnames) ? "css::uno::Reference< " :
92 "::com::sun::star::uno::Reference< ");
93 }
94
95 o << scopedCppName(codemaker::cpp::translateUnoToCppType(sort, nucleus),
96 options.shortnames && referenceType > 0);
97
98 if (sort == codemaker::UnoType::Sort::Interface && referenceType > 0)
99 o << " >";
100
101 if (!arguments.empty()) {
102 o << "< ";
103 for (std::vector< OUString >::const_iterator i(arguments.begin());
104 i != arguments.end(); ++i)
105 {
106 if (i != arguments.begin())
107 o << ", ";
108
109 printType(o, options, manager, *i, 1);
110 }
111 o << " >";
112 }
113
114 for (sal_Int32 i = 0; i < rank; ++i)
115 o << " >";
116
117 if (bReference && referenceType > 1)
118 o << " &";
119
120 if (referenceType == 8 && (sort > codemaker::UnoType::Sort::Char || rank > 0))
121 o << "()";
122 }
123
printType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,short referenceType,bool defaultvalue)124 void printType(
125 std::ostream & o, ProgramOptions const & options,
126 rtl::Reference< TypeManager > const & manager, OUString const & name,
127 short referenceType, bool defaultvalue)
128 {
129 OUString nucleus;
130 sal_Int32 rank;
131 std::vector< OUString > arguments;
132 rtl::Reference< unoidl::Entity > entity;
133 codemaker::UnoType::Sort sort = manager->decompose(
134 name, true, &nucleus, &rank, &arguments, &entity);
135 printType(
136 o, options, manager, sort, nucleus, rank, arguments, entity,
137 referenceType, defaultvalue);
138 }
139
printConstructorParameters(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,rtl::Reference<unoidl::Entity> const & entity,OUString const & name,std::vector<OUString> const & arguments)140 static bool printConstructorParameters(
141 std::ostream & o, ProgramOptions const & options,
142 rtl::Reference< TypeManager > const & manager,
143 codemaker::UnoType::Sort sort,
144 rtl::Reference< unoidl::Entity > const & entity, OUString const & name,
145 std::vector< OUString > const & arguments)
146 {
147 bool previous = false;
148 switch (sort) {
149 case codemaker::UnoType::Sort::PlainStruct:
150 {
151 rtl::Reference< unoidl::PlainStructTypeEntity > ent2(
152 dynamic_cast< unoidl::PlainStructTypeEntity * >(entity.get()));
153 assert(ent2.is());
154 if (!ent2->getDirectBase().isEmpty()) {
155 rtl::Reference< unoidl::Entity > baseEnt;
156 codemaker::UnoType::Sort baseSort = manager->getSort(
157 ent2->getDirectBase(), &baseEnt);
158 previous = printConstructorParameters(
159 o, options, manager, baseSort, baseEnt,
160 ent2->getDirectBase(), std::vector< OUString >());
161 }
162 for (const auto& rMember : ent2->getDirectMembers())
163 {
164 if (previous) {
165 o << ", ";
166 }
167 previous = true;
168 printType(o, options, manager, rMember.type, 4);
169 o << ' '
170 << codemaker::cpp::translateUnoToCppIdentifier(
171 u2b(rMember.name), "param");
172 }
173 break;
174 }
175 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
176 {
177 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > ent2(
178 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
179 entity.get()));
180 assert(ent2.is());
181 for (const auto& rMember : ent2->getMembers())
182 {
183 if (previous) {
184 o << ", ";
185 }
186 previous = true;
187 if (rMember.parameterized) {
188 o << rMember.type;
189 } else {
190 printType(o, options, manager, rMember.type, 4);
191 }
192 o << ' '
193 << codemaker::cpp::translateUnoToCppIdentifier(
194 u2b(rMember.name), "param");
195 }
196 break;
197 }
198 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
199 {
200 rtl::Reference< unoidl::PolymorphicStructTypeTemplateEntity > ent2(
201 dynamic_cast< unoidl::PolymorphicStructTypeTemplateEntity * >(
202 entity.get()));
203 assert(ent2.is());
204 for (const auto& rMember : ent2->getMembers())
205 {
206 if (previous) {
207 o << ", ";
208 }
209 previous = true;
210 if (rMember.parameterized) {
211 auto j = std::find(ent2->getTypeParameters().begin(),
212 ent2->getTypeParameters().end(), rMember.type);
213 if (j != ent2->getTypeParameters().end()) {
214 o << arguments[j - ent2->getTypeParameters().begin()];
215 }
216 } else {
217 printType(o, options, manager, rMember.type, 4);
218 }
219 o << ' '
220 << codemaker::cpp::translateUnoToCppIdentifier(
221 u2b(rMember.name), "param");
222 }
223 break;
224 }
225 case codemaker::UnoType::Sort::Exception:
226 {
227 rtl::Reference< unoidl::ExceptionTypeEntity > ent2(
228 dynamic_cast< unoidl::ExceptionTypeEntity * >(entity.get()));
229 assert(ent2.is());
230 if (!ent2->getDirectBase().isEmpty()) {
231 rtl::Reference< unoidl::Entity > baseEnt;
232 codemaker::UnoType::Sort baseSort = manager->getSort(
233 ent2->getDirectBase(), &baseEnt);
234 previous = printConstructorParameters(
235 o, options, manager, baseSort, baseEnt,
236 ent2->getDirectBase(), std::vector< OUString >());
237 }
238 for (const auto& rMember : ent2->getDirectMembers())
239 {
240 if (previous) {
241 o << ", ";
242 }
243 previous = true;
244 printType(o, options, manager, rMember.type, 4);
245 o << ' '
246 << codemaker::cpp::translateUnoToCppIdentifier(
247 u2b(rMember.name), "param");
248 }
249 break;
250 }
251 default:
252 throw CannotDumpException(
253 "unexpected entity \"" + name
254 + "\" in call to skeletonmaker::cpp::printConstructorParameters");
255 }
256 return previous;
257 }
258
printConstructor(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,rtl::Reference<unoidl::Entity> const & entity,OUString const & name,std::vector<OUString> const & arguments)259 static void printConstructor(
260 std::ostream & o, ProgramOptions const & options,
261 rtl::Reference< TypeManager > const & manager,
262 codemaker::UnoType::Sort sort,
263 rtl::Reference< unoidl::Entity > const & entity, OUString const & name,
264 std::vector< OUString > const & arguments)
265 {
266 o << "public " << name.copy(name.lastIndexOf('.') + 1) << '(';
267 printConstructorParameters(
268 o, options, manager, sort, entity, name, arguments);
269 o << ");\n";
270 }
271
printMethodParameters(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,std::vector<unoidl::InterfaceTypeEntity::Method::Parameter> const & parameters,bool withType)272 static void printMethodParameters(
273 std::ostream & o, ProgramOptions const & options,
274 rtl::Reference< TypeManager > const & manager,
275 std::vector< unoidl::InterfaceTypeEntity::Method::Parameter > const &
276 parameters,
277 bool withType)
278 {
279 for (std::vector< unoidl::InterfaceTypeEntity::Method::Parameter >::
280 const_iterator i(parameters.begin());
281 i != parameters.end(); ++i)
282 {
283 if (i != parameters.begin()) {
284 o << ", ";
285 }
286 if (withType) {
287 short referenceType;
288 if (i->direction
289 == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
290 {
291 referenceType = 4;
292 } else {
293 referenceType = 2;
294 }
295 printType(o, options, manager, i->type, referenceType);
296 o << ' ';
297 }
298 o << codemaker::cpp::translateUnoToCppIdentifier(u2b(i->name), "param");
299 }
300 }
301
printExceptionSpecification(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,std::vector<OUString> const & exceptions)302 static void printExceptionSpecification(
303 std::ostream & o,
304 ProgramOptions const & options,
305 rtl::Reference< TypeManager > const & manager,
306 std::vector< OUString > const & exceptions)
307 {
308 o << ((options.shortnames) ? " throw (css::uno::RuntimeException" :
309 " throw (::com::sun::star::uno::RuntimeException");
310 for (const auto& rException : exceptions)
311 {
312 o << ", ";
313 printType(o, options, manager, rException, 1);
314 }
315 o << ")";
316 }
317
printSetPropertyMixinBody(std::ostream & o,unoidl::InterfaceTypeEntity::Attribute const & attribute)318 static void printSetPropertyMixinBody(
319 std::ostream & o, unoidl::InterfaceTypeEntity::Attribute const & attribute)
320 {
321 unoidl::AccumulationBasedServiceEntity::Property::Attributes propFlags
322 = checkAdditionalPropertyFlags(attribute);
323
324 o << "\n{\n";
325
326 if (attribute.bound)
327 o << " BoundListeners l;\n";
328
329 if (propFlags & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED) {
330 OString fieldtype = codemaker::convertString(attribute.type);
331
332 sal_Int32 index = fieldtype.lastIndexOf('<');
333 sal_Int32 nPos=0;
334 bool single = true;
335 bool optional = false;
336 OStringBuffer buffer1(64);
337 OStringBuffer buffer2(64);
338 do
339 {
340 OString s(fieldtype.getToken(0, '<', nPos));
341 OString t = s.copy(s.lastIndexOf('/')+1);
342
343 if (t == "Optional") {
344 optional=true;
345 if (single) {
346 single=false;
347 buffer1.append("the_value.IsPresent");
348 buffer2.append("the_value.Value");
349 } else {
350 buffer1.insert(0, t);
351 buffer1.append(".IsPresent");
352 buffer2.insert(0, t);
353 buffer2.append(".Value");
354 }
355 } else {
356 if (single) {
357 single=false;
358 if (!optional)
359 buffer1.append("the_value.Value");
360
361 buffer2.append("the_value.Value");
362 } else {
363 if (!optional) {
364 buffer1.insert(0, t);
365 buffer1.append(".Value");
366 }
367 buffer2.insert(0, t);
368 buffer2.append(".Value");
369 }
370 }
371 } while( nPos <= index );
372
373 o << " css::uno::Any v;\n";
374 if (optional) {
375 o << " if(" << buffer1.makeStringAndClear() << ")\n {\n v <<= " << buffer2.makeStringAndClear() << ";\n }\n";
376 } else {
377 o << " v <<= " << buffer2.makeStringAndClear() << ";\n\n";
378 }
379
380 o << " prepareSet(\n OUString(\""
381 << attribute.name << "\"),\n css::uno::Any(), v, ";
382 } else {
383 o << " prepareSet(\n OUString(\""
384 << attribute.name << "\"),\n css::uno::Any(), css::uno::Any(), ";
385 }
386
387 if (attribute.bound)
388 o << "&l);\n";
389 else
390 o << "0);\n";
391
392 o << " {\n osl::MutexGuard g(m_aMutex);\n m_"
393 << attribute.name << " = the_value;\n }\n";
394
395 if (attribute.bound)
396 o << " l.notify();\n";
397
398 o << "}\n\n";
399 }
400
printMethods(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,codemaker::GeneratedTypeSet & generated,OString const & delegate,OString const & classname,OString const & indentation,bool defaultvalue,OUString const & propertyhelper)401 void printMethods(std::ostream & o,
402 ProgramOptions const & options, rtl::Reference< TypeManager > const & manager,
403 OUString const & name, codemaker::GeneratedTypeSet & generated,
404 OString const & delegate, OString const & classname,
405 OString const & indentation, bool defaultvalue,
406 OUString const & propertyhelper)
407 {
408 if (generated.contains(u2b(name)) || name == "com.sun.star.uno.XInterface" ||
409 (defaultvalue &&
410 ( name == "com.sun.star.lang.XComponent" ||
411 name == "com.sun.star.lang.XTypeProvider" ||
412 name == "com.sun.star.uno.XWeak" ) ) )
413 {
414 return;
415 }
416
417 static OString sd("_");
418 bool body = !delegate.isEmpty();
419 bool defaultbody = delegate == sd;
420
421 if (body && propertyhelper.getLength() > 1) {
422 if (name == "com.sun.star.beans.XPropertySet") {
423 generated.add(u2b(name));
424 generateXPropertySetBodies(
425 o, classname, scopedCppName(u2b(propertyhelper)));
426 return;
427 } else if (name == "com.sun.star.beans.XFastPropertySet") {
428 generated.add(u2b(name));
429 generateXFastPropertySetBodies(
430 o, classname, scopedCppName(u2b(propertyhelper)));
431 return;
432 } else if (name == "com.sun.star.beans.XPropertyAccess") {
433 generated.add(u2b(name));
434 generateXPropertyAccessBodies(
435 o, classname, scopedCppName(u2b(propertyhelper)));
436 return;
437 }
438 }
439
440 if (body && options.componenttype == 2) {
441 if (name == "com.sun.star.lang.XServiceName") {
442 o << "// ::com::sun::star::lang::XServiceName:\n"
443 "OUString SAL_CALL " << classname << "getServiceName() "
444 "throw (css::uno::RuntimeException)\n{\n "
445 "return OUString("
446 "sADDIN_SERVICENAME);\n}\n";
447 generated.add(u2b(name));
448 return;
449 } else if (name == "com.sun.star.sheet.XAddIn") {
450 generateXAddInBodies(o, classname);
451 generated.add(u2b(name));
452
453 // special handling of XLocalizable -> parent of XAddIn
454 if (!generated.contains("com.sun.star.lang.XLocalizable")) {
455 generateXLocalizable(o, classname);
456 generated.add("com.sun.star.lang.XLocalizable");
457 }
458 return;
459 } else if (name == "com.sun.star.lang.XLocalizable") {
460 generateXLocalizable(o, classname);
461 generated.add(u2b(name));
462 return;
463 } else if (name == "com.sun.star.sheet.XCompatibilityNames") {
464 generateXCompatibilityNamesBodies(o, classname);
465 generated.add(u2b(name));
466 return;
467 }
468 }
469
470 if (body && options.componenttype == 3) {
471 if (name == "com.sun.star.lang.XInitialization") {
472 generateXInitialization(o, classname);
473 generated.add(u2b(name));
474 return;
475 } else if (name == "com.sun.star.frame.XDispatch") {
476 generateXDispatch(o, classname, options.protocolCmdMap);
477 generated.add(u2b(name));
478 return;
479 } else if (name == "com.sun.star.frame.XDispatchProvider") {
480 generateXDispatchProvider(o, classname, options.protocolCmdMap);
481 generated.add(u2b(name));
482 return;
483 }
484 }
485
486 generated.add(u2b(name));
487 rtl::Reference< unoidl::Entity > ent;
488 if (manager->getSort(name, &ent) != codemaker::UnoType::Sort::Interface)
489 {
490 throw CannotDumpException(
491 "unexpected entity \"" + name
492 + "\" in call to skeletonmaker::cpp::printMethods");
493 }
494 rtl::Reference< unoidl::InterfaceTypeEntity > ent2(
495 dynamic_cast< unoidl::InterfaceTypeEntity * >(ent.get()));
496 assert(ent2.is());
497 if (options.all || defaultvalue) {
498 for (const auto& rBase : ent2->getDirectMandatoryBases())
499 {
500 printMethods(
501 o, options, manager, rBase.name, generated, delegate, classname,
502 indentation, defaultvalue, propertyhelper);
503 }
504 if (!(ent2->getDirectAttributes().empty()
505 && ent2->getDirectMethods().empty()))
506 {
507 o << indentation << "// ";
508 printType(o, options, manager, name, 0);
509 o << ":\n";
510 }
511 }
512 for (const auto& rAttr : ent2->getDirectAttributes())
513 {
514 o << indentation;
515 if (!body)
516 o << "virtual ";
517
518 printType(o, options, manager, rAttr.type, 1);
519 o << " SAL_CALL ";
520 if (!classname.isEmpty())
521 o << classname;
522
523 o << "get" << rAttr.name << "()";
524 printExceptionSpecification(o, options, manager, rAttr.getExceptions);
525 if (body) {
526 if (defaultbody) {
527 if (!propertyhelper.isEmpty()) {
528 o << "\n{\n osl::MutexGuard g(m_aMutex);\n return m_"
529 << rAttr.name << ";\n}\n\n";
530 } else {
531 o << "\n{\n return ";
532 if (options.componenttype == 1) {
533 o << "m_" << rAttr.name;
534 } else {
535 printType(o, options, manager, rAttr.type, 8, true);
536 }
537 o << ";\n}\n\n";
538 }
539 } else {
540 o << "\n" << indentation << "{\n" << indentation << " return "
541 << delegate << "get" << rAttr.name << "();\n"
542 << indentation << "}\n\n";
543 }
544 } else {
545 o << ";\n";
546 }
547
548 if (!rAttr.readOnly) {
549 o << indentation;
550 if (!body)
551 o << "virtual ";
552
553 o << "void SAL_CALL ";
554 if (!classname.isEmpty())
555 o << classname;
556
557 o << "set" << rAttr.name << '(';
558 printType(o, options, manager, rAttr.type, 4);
559 o << " the_value)";
560 printExceptionSpecification(o, options, manager, rAttr.setExceptions);
561 if (body) {
562 if (defaultbody) {
563 if (!propertyhelper.isEmpty()) {
564 printSetPropertyMixinBody(o, rAttr);
565 } else {
566 if (options.componenttype == 1) {
567 o << "\n{\n m_" << rAttr.name
568 << " = the_value;\n}\n\n";
569 } else {
570 o << "\n{\n\n}\n\n";
571 }
572 }
573 } else {
574 o << "\n" << indentation << "{\n" << indentation << " "
575 << delegate << "set" << rAttr.name
576 << "(the_value);\n" << indentation << "}\n\n";
577 }
578 } else {
579 o << ";\n";
580 }
581 }
582 }
583 for (const auto& rMethod : ent2->getDirectMethods())
584 {
585 o << indentation;
586 if (!body)
587 o << "virtual ";
588
589 printType(o, options, manager, rMethod.returnType, 1);
590 o << " SAL_CALL ";
591 if (!classname.isEmpty())
592 o << classname;
593
594 o << rMethod.name << '(';
595 printMethodParameters(o, options, manager, rMethod.parameters, true);
596 o << ')';
597 printExceptionSpecification(o, options, manager, rMethod.exceptions);
598 if (body) {
599 if (defaultbody) {
600 o << "\n{\n";
601 if (rMethod.returnType != "void") {
602 o << " // TODO: Exchange the default return implementation for \""
603 << rMethod.name << "\" !!!\n";
604 o << " // Exchange the default return implementation.\n"
605 " // NOTE: Default initialized polymorphic structs "
606 "can cause problems because of\n // missing default "
607 "initialization of primitive types of some C++ compilers or"
608 "\n // different Any initialization in Java and C++ "
609 "polymorphic structs.\n return ";
610 printType(o, options, manager, rMethod.returnType, 8, true);
611 o << ";";
612 } else {
613 o << " // TODO: Insert your implementation for \""
614 << rMethod.name << "\" here.";
615 }
616 o << "\n}\n\n";
617 } else {
618 o << "\n" << indentation << "{\n" << indentation << " ";
619 if (rMethod.returnType != "void")
620 o << "return ";
621
622 o << delegate << rMethod.name << '(';
623 printMethodParameters(
624 o, options, manager, rMethod.parameters, false);
625 o << ");\n" << indentation << "}\n\n";
626 }
627 } else {
628 o << ";\n";
629 }
630 }
631
632 if (!body)
633 o << "\n";
634 }
635
printConstructors(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name)636 static void printConstructors(
637 std::ostream & o, ProgramOptions const & options,
638 rtl::Reference< TypeManager > const & manager, OUString const & name)
639 {
640 rtl::Reference< unoidl::Entity > ent;
641 if (manager->getSort(name, &ent)
642 != codemaker::UnoType::Sort::SingleInterfaceBasedService)
643 {
644 throw CannotDumpException(
645 "unexpected entity \"" + name
646 + "\" in call to skeletonmaker::java::printConstructors");
647 }
648 rtl::Reference< unoidl::SingleInterfaceBasedServiceEntity > ent2(
649 dynamic_cast< unoidl::SingleInterfaceBasedServiceEntity * >(ent.get()));
650 assert(ent2.is());
651 for (const auto& rConstructor : ent2->getConstructors())
652 {
653 o << "static ";
654 printType(o, options, manager, ent2->getBase(), 1);
655 o << ' ';
656 if (rConstructor.defaultConstructor) {
657 o << "create";
658 } else {
659 o << codemaker::cpp::translateUnoToCppIdentifier(
660 u2b(rConstructor.name), "method");
661 }
662 o << ((options.shortnames) ? "(css::uno::Reference< css" :
663 "(::com::sun::star::uno::Reference< ::com::sun::star")
664 << "::uno::XComponentContext > const & the_context";
665 for (const auto& rParam : rConstructor.parameters)
666 {
667 o << ", ";
668 printType(o, options, manager, rParam.type, 4);
669 o << ' '
670 << codemaker::cpp::translateUnoToCppIdentifier(
671 u2b(rParam.name), "param");
672 }
673 o << ')';
674 printExceptionSpecification(o, options, manager, rConstructor.exceptions);
675 o << ";\n";
676 }
677 }
678
printServiceMembers(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OUString const & name,rtl::Reference<unoidl::AccumulationBasedServiceEntity> const & entity,OString const & delegate)679 static void printServiceMembers(
680 std::ostream & o, ProgramOptions const & options,
681 rtl::Reference< TypeManager > const & manager,
682 OUString const & name,
683 rtl::Reference< unoidl::AccumulationBasedServiceEntity > const & entity,
684 OString const & delegate)
685 {
686 assert(entity.is());
687 for (const auto& rService : entity->getDirectMandatoryBaseServices())
688 {
689 o << "\n// exported service " << rService.name << "\n";
690 generateDocumentation(o, options, manager, u2b(rService.name), delegate);
691 o << "\n// end of exported service " << rService.name << "\n";
692 }
693 for (const auto& rIface : entity->getDirectMandatoryBaseInterfaces())
694 {
695 o << "\n// supported interface " << rIface.name << "\n";
696 generateDocumentation(o, options, manager, u2b(rIface.name), delegate);
697 }
698 if (delegate.isEmpty()) {
699 o << "\n// properties of service \""<< name << "\"\n";
700 for (const auto& rProp : entity->getDirectProperties())
701 {
702 o << "// private ";
703 printType(o, options, manager, rProp.type, 1);
704 o << " "
705 << codemaker::cpp::translateUnoToCppIdentifier(
706 u2b(rProp.name), "property")
707 << ";\n";
708 }
709 }
710 }
711
printMapsToCppType(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,codemaker::UnoType::Sort sort,OUString const & nucleus,sal_Int32 rank,std::vector<OUString> const & arguments,rtl::Reference<unoidl::Entity> const & entity,const char * cppTypeSort)712 static void printMapsToCppType(
713 std::ostream & o, ProgramOptions const & options,
714 rtl::Reference< TypeManager > const & manager,
715 codemaker::UnoType::Sort sort, OUString const & nucleus, sal_Int32 rank,
716 std::vector< OUString > const & arguments,
717 rtl::Reference< unoidl::Entity > const & entity, const char * cppTypeSort)
718 {
719 o << "maps to C++ ";
720 if (cppTypeSort != nullptr)
721 o << cppTypeSort << ' ';
722
723 o << "type \"";
724 if (rank == 0 && nucleus == "com.sun.star.uno.XInterface") {
725 o << "Reference< com::sun::star::uno::XInterface >";
726 } else {
727 printType(
728 o, options, manager, sort, nucleus, rank, arguments, entity, 0,
729 false);
730 }
731 o << '"';
732 }
733
generateDocumentation(std::ostream & o,ProgramOptions const & options,rtl::Reference<TypeManager> const & manager,OString const & type,OString const & delegate)734 void generateDocumentation(std::ostream & o,
735 ProgramOptions const & options, rtl::Reference< TypeManager > const & manager,
736 OString const & type, OString const & delegate)
737 {
738 OUString nucleus;
739 sal_Int32 rank;
740 codemaker::UnoType::Sort sort = manager->decompose(
741 b2u(type), false, &nucleus, &rank, nullptr, nullptr);
742
743 bool comment = true;
744 if (!delegate.isEmpty()) {
745 if (sort != codemaker::UnoType::Sort::Interface &&
746 sort != codemaker::UnoType::Sort::SingleInterfaceBasedService &&
747 sort != codemaker::UnoType::Sort::AccumulationBasedService )
748 {
749 return;
750 }
751 comment = false;
752 }
753
754 if (comment) {
755 o << "\n// UNO";
756 if (rank != 0) {
757 o << " sequence type";
758 } else if (sort <= codemaker::UnoType::Sort::Any) {
759 o << " simple type";
760 } else {
761 switch (sort) {
762 case codemaker::UnoType::Sort::Interface:
763 o << " interface type";
764 break;
765
766 case codemaker::UnoType::Sort::Module:
767 o << "IDL module";
768 break;
769
770 case codemaker::UnoType::Sort::PlainStruct:
771 o << " simple struct type";
772 break;
773
774 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
775 o << " polymorphic struct type template";
776 break;
777
778 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
779 o << " instantiated polymorphic struct type";
780 break;
781
782 case codemaker::UnoType::Sort::Enum:
783 o << " enum type";
784 break;
785
786 case codemaker::UnoType::Sort::Exception:
787 o << " exception type";
788 break;
789
790 case codemaker::UnoType::Sort::Typedef:
791 o << "IDL typedef";
792 break;
793
794 case codemaker::UnoType::Sort::SingleInterfaceBasedService:
795 o << " single-inheritance--based service";
796 break;
797
798 case codemaker::UnoType::Sort::AccumulationBasedService:
799 o << "IDL accumulation-based service";
800 break;
801
802 case codemaker::UnoType::Sort::InterfaceBasedSingleton:
803 o << " inheritance-based singleton";
804 break;
805
806 case codemaker::UnoType::Sort::ServiceBasedSingleton:
807 o << "IDL service-based singleton";
808 break;
809
810 case codemaker::UnoType::Sort::ConstantGroup:
811 o << "IDL constant group";
812 break;
813
814 default:
815 OSL_ASSERT(false);
816 break;
817 }
818 }
819 o << " \"" << type << "\" ";
820 }
821 std::vector< OUString > arguments;
822 rtl::Reference< unoidl::Entity > entity;
823 sort = manager->decompose(
824 b2u(type), true, &nucleus, &rank, &arguments, &entity);
825 if (rank != 0) {
826 if (comment) {
827 printMapsToCppType(
828 o, options, manager, sort, nucleus, rank, arguments, entity,
829 "array");
830 o << '\n';
831 }
832 } else if (sort <= codemaker::UnoType::Sort::Any) {
833 if (comment) {
834 printMapsToCppType(
835 o, options, manager, sort, nucleus, rank, arguments, entity, nullptr);
836 o << '\n';
837 }
838 } else {
839 switch (sort) {
840 case codemaker::UnoType::Sort::Interface:
841 if (comment)
842 printMapsToCppType(
843 o, options, manager, sort, nucleus, rank, arguments, entity,
844 "interface");
845 if (nucleus == "com.sun.star.uno.XInterface") {
846 if (comment)
847 o << '\n';
848 } else {
849 if (comment)
850 o << "; " << (options.all ? "all" : "direct") << " methods:\n";
851
852 codemaker::GeneratedTypeSet generated;
853 printMethods(
854 o, options, manager, nucleus, generated, delegate,
855 options.implname, "");
856 }
857 break;
858
859 case codemaker::UnoType::Sort::Module:
860 printMapsToCppType(
861 o, options, manager, sort, nucleus, rank, arguments, entity,
862 "namespace");
863 o << '\n';
864 break;
865
866 case codemaker::UnoType::Sort::PlainStruct:
867 printMapsToCppType(
868 o, options, manager, sort, nucleus, rank, arguments, entity,
869 "class");
870 o << "; full constructor:\n";
871 printConstructor(
872 o, options, manager, codemaker::UnoType::Sort::PlainStruct,
873 entity, nucleus, arguments);
874 break;
875
876 case codemaker::UnoType::Sort::PolymorphicStructTemplate:
877 printMapsToCppType(
878 o, options, manager, sort, nucleus, rank, arguments, entity,
879 "class template");
880 o << "; full constructor:\n";
881 printConstructor(
882 o, options, manager,
883 codemaker::UnoType::Sort::PolymorphicStructTemplate,
884 entity, nucleus, arguments);
885 break;
886
887 case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
888 printMapsToCppType(
889 o, options, manager, sort, nucleus, rank, arguments, entity,
890 "class template instantiation");
891 o << "; full constructor:\n";
892 printConstructor(
893 o, options, manager,
894 codemaker::UnoType::Sort::InstantiatedPolymorphicStruct,
895 entity, nucleus, arguments);
896 break;
897
898 case codemaker::UnoType::Sort::Enum:
899 printMapsToCppType(
900 o, options, manager, sort, nucleus, rank, arguments, entity,
901 "enum");
902 o << '\n';
903 break;
904
905 case codemaker::UnoType::Sort::ConstantGroup:
906 printMapsToCppType(
907 o, options, manager, sort, nucleus, rank, arguments, entity,
908 "namespace");
909 o << '\n';
910 break;
911
912 case codemaker::UnoType::Sort::Exception:
913 printMapsToCppType(
914 o, options, manager, sort, nucleus, rank, arguments, entity,
915 "exception class");
916 o << "; full constructor:\n";
917 printConstructor(
918 o, options, manager, codemaker::UnoType::Sort::Exception,
919 entity, nucleus, arguments);
920 break;
921
922 case codemaker::UnoType::Sort::SingleInterfaceBasedService:
923 if (comment) {
924 printMapsToCppType(
925 o, options, manager, sort, nucleus, rank, arguments, entity,
926 "class");
927 o << "; construction methods:\n";
928 printConstructors(o, options, manager, nucleus);
929 }
930 generateDocumentation(
931 o, options, manager,
932 u2b(dynamic_cast<unoidl::SingleInterfaceBasedServiceEntity&>(*entity)
933 .getBase()),
934 delegate);
935 break;
936
937 case codemaker::UnoType::Sort::AccumulationBasedService:
938 if (comment)
939 o << ("does not map to C++\n"
940 "// the service members are generated instead\n");
941 printServiceMembers(
942 o, options, manager, nucleus,
943 dynamic_cast< unoidl::AccumulationBasedServiceEntity * >(
944 entity.get()),
945 delegate);
946 break;
947
948 case codemaker::UnoType::Sort::InterfaceBasedSingleton:
949 printMapsToCppType(
950 o, options, manager, sort, nucleus, rank, arguments, entity,
951 "class");
952 o << "; get method:\nstatic ";
953 printType(
954 o, options, manager,
955 dynamic_cast< unoidl::InterfaceBasedSingletonEntity * >(
956 entity.get())->getBase(),
957 1);
958 o << " get(::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context);\n";
959 break;
960
961 case codemaker::UnoType::Sort::ServiceBasedSingleton:
962 o << "does not map to C++\n";
963 break;
964
965 default:
966 OSL_ASSERT(false);
967 break;
968 }
969 }
970 }
971
972 } }
973
974
975 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
976