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