bump product version to 6.4.3.1
[LibreOffice.git] / unoidl / source / sourceprovider-parser.y
blobd7111d0e3cfa2324743a0201ca37dc9684591b5b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 /*TODO: check Exception, RuntimeException, XInterface defns */
12 %locations
13 %pure-parser
17 #include <sal/config.h>
19 #include <rtl/ustrbuf.hxx>
20 #include <unoidl/unoidl.hxx>
22 #include <algorithm>
23 #include <cassert>
24 #include <cerrno>
25 #include <cstddef>
26 #include <cstdlib>
27 #include <limits>
28 #include <new>
29 #include <utility>
30 #include <vector>
32 #include "sourceprovider-parser-requires.hxx"
36 %union {
37 sal_uInt64 ival;
38 double fval;
39 OString * sval;
41 bool bval;
42 std::vector<OUString> * excns;
43 unoidl::detail::SourceProviderAccessDecls decls;
44 unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
45 unoidl::detail::SourceProviderFlags flags;
46 unoidl::detail::SourceProviderExpr expr;
47 unoidl::detail::SourceProviderType * type;
48 std::vector<unoidl::detail::SourceProviderType> * types;
51 /* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
53 %lex-param {yyscan_t yyscanner}
54 %parse-param {yyscan_t yyscanner}
58 #include <osl/file.h>
59 #include <osl/thread.h>
60 #include <sal/log.hxx>
62 #include "sourceprovider-scanner.hxx"
64 #define YYLLOC_DEFAULT(Current, Rhs, N) \
65 do { (Current) = YYRHSLOC((Rhs), (N) ? 1 : 0); } while (0)
67 static void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
68 assert(locp != nullptr);
69 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
70 data->errorLine = *locp;
71 data->parserError = OString(msg);
74 namespace {
76 void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
77 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
78 data->errorLine = location;
79 data->errorMessage = message;
82 OUString flagName(unoidl::detail::SourceProviderFlags flag) {
83 switch (flag) {
84 case unoidl::detail::FLAG_ATTRIBUTE:
85 return "attribute";
86 case unoidl::detail::FLAG_BOUND:
87 return "bound";
88 case unoidl::detail::FLAG_CONSTRAINED:
89 return "constrained";
90 case unoidl::detail::FLAG_MAYBEAMBIGUOUS:
91 return "maybeambiguous";
92 case unoidl::detail::FLAG_MAYBEDEFAULT:
93 return "maybedefault";
94 case unoidl::detail::FLAG_MAYBEVOID:
95 return "maybevoid";
96 case unoidl::detail::FLAG_OPTIONAL:
97 return "optional";
98 case unoidl::detail::FLAG_PROPERTY:
99 return "property";
100 case unoidl::detail::FLAG_READONLY:
101 return "readonly";
102 case unoidl::detail::FLAG_REMOVABLE:
103 return "removable";
104 case unoidl::detail::FLAG_TRANSIENT:
105 return "transient";
106 default:
107 assert(false && "this cannot happen"); for (;;) { std::abort(); }
111 OUString convertName(OString const * name) {
112 assert(name != nullptr);
113 OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
114 delete name;
115 return s;
118 OUString convertToFullName(
119 unoidl::detail::SourceProviderScannerData const * data,
120 OString const * identifier)
122 assert(data != nullptr);
123 OUString pref;
124 if (!data->modules.empty()) {
125 pref = data->modules.back() + ".";
127 return pref + convertName(identifier);
130 void convertToCurrentName(
131 unoidl::detail::SourceProviderScannerData * data,
132 OString const * identifier)
134 assert(data != nullptr);
135 assert(data->currentName.isEmpty());
136 data->currentName = convertToFullName(data, identifier);
137 assert(!data->currentName.isEmpty());
140 void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
141 assert(data != nullptr);
142 data->currentName.clear();
143 data->publishedContext = false;
146 unoidl::detail::SourceProviderEntity * getCurrentEntity(
147 unoidl::detail::SourceProviderScannerData * data)
149 assert(data != nullptr);
150 assert(!data->currentName.isEmpty());
151 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
152 data->entities.find(data->currentName));
153 assert(i != data->entities.end());
154 assert(i->second.kind == unoidl::detail::SourceProviderEntity::KIND_LOCAL);
155 assert(i->second.pad.is());
156 return &i->second;
159 template<typename T> rtl::Reference<T> getCurrentPad(
160 unoidl::detail::SourceProviderScannerData * data)
162 rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
163 assert(pad.is());
164 return pad;
167 bool nameHasSameIdentifierAs(OUString const & name, OUString const & identifier)
169 sal_Int32 i = name.lastIndexOf('.') + 1;
170 return identifier.getLength() == name.getLength() - i
171 && name.match(identifier, i);
174 bool coerce(
175 YYLTYPE location, yyscan_t yyscanner,
176 unoidl::detail::SourceProviderExpr * lhs,
177 unoidl::detail::SourceProviderExpr * rhs)
179 assert(lhs != nullptr);
180 assert(rhs != nullptr);
181 bool ok = bool(); // avoid warnings
182 switch (lhs->type) {
183 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
184 ok = rhs->type != unoidl::detail::SourceProviderExpr::TYPE_BOOL;
185 break;
186 case unoidl::detail::SourceProviderExpr::TYPE_INT:
187 switch (rhs->type) {
188 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
189 ok = false;
190 break;
191 case unoidl::detail::SourceProviderExpr::TYPE_INT:
192 ok = true;
193 break;
194 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
195 if (lhs->ival >= 0) {
196 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
197 ok = true;
198 } else if (rhs->uval <= SAL_MAX_INT64) {
199 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
200 ok = true;
201 } else {
202 ok = false;
204 break;
205 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
207 auto tmp = lhs->ival;
208 lhs->fval = tmp;
209 ok = true;
211 break;
213 break;
214 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
215 switch (rhs->type) {
216 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
217 ok = false;
218 break;
219 case unoidl::detail::SourceProviderExpr::TYPE_INT:
220 if (rhs->ival >= 0) {
221 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
222 ok = true;
223 } else if (lhs->uval <= SAL_MAX_INT64) {
224 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
225 ok = true;
226 } else {
227 ok = false;
229 break;
230 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
231 ok = true;
232 break;
233 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
235 auto nTmp = lhs->uval;
236 lhs->fval = nTmp;
237 ok = true;
239 break;
241 break;
242 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
243 switch (rhs->type) {
244 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
245 ok = false;
246 break;
247 case unoidl::detail::SourceProviderExpr::TYPE_INT:
249 auto tmp = rhs->ival;
250 rhs->fval = tmp;
251 ok = true;
253 break;
254 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
256 auto tmp = rhs->uval;
257 rhs->fval = tmp;
258 ok = true;
260 break;
261 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
262 ok = true;
263 break;
265 break;
267 if (!ok) {
268 error(location, yyscanner, "cannot coerce binary expression arguments");
270 return ok;
273 unoidl::detail::SourceProviderEntity * findEntity_(
274 unoidl::detail::SourceProviderScannerData * data, OUString * name)
276 assert(data != nullptr);
277 assert(name != nullptr);
278 OUString n;
279 if (!name->startsWith(".", &n)) {
280 for (auto i(data->modules.rbegin()); i != data->modules.rend(); ++i) {
281 n = *i + "." + *name;
282 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
283 data->entities.find(n));
284 if (j != data->entities.end()) {
285 *name = n;
286 return &j->second;
288 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
289 if (ent.is()) {
290 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
291 k(data->entities.emplace(
293 unoidl::detail::SourceProviderEntity(
294 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
295 ent)).
296 first);
297 *name = n;
298 return &k->second;
301 n = *name;
303 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
304 data->entities.find(n));
305 if (i != data->entities.end()) {
306 *name = n;
307 return &i->second;
309 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
310 if (ent.is()) {
311 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
312 j(data->entities.emplace(
314 unoidl::detail::SourceProviderEntity(
315 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
316 ent)).
317 first);
318 *name = n;
319 return &j->second;
321 return nullptr;
324 enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
326 Found findEntity(
327 YYLTYPE location, yyscan_t yyscanner,
328 unoidl::detail::SourceProviderScannerData * data,
329 bool resolveInterfaceDefinitions, OUString * name,
330 unoidl::detail::SourceProviderEntity const ** entity, bool * typedefed,
331 unoidl::detail::SourceProviderType * typedefedType)
333 //TODO: avoid recursion
334 assert(data != nullptr);
335 assert(name != nullptr);
336 assert(entity != nullptr);
337 unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
338 OUString n(*name);
339 OUString typeNucleus;
340 std::size_t rank = 0;
341 std::vector<unoidl::detail::SourceProviderType> args;
342 for (;;) {
343 if (e != nullptr) {
344 switch (e->kind) {
345 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
346 if (e->pad.is()) {
347 break;
349 assert(e->entity.is());
350 [[fallthrough]];
351 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
352 if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
353 if (typedefed != nullptr) {
354 *typedefed = true;
356 if (data->publishedContext
357 && !static_cast<unoidl::TypedefEntity *>(
358 e->entity.get())->isPublished())
360 error(
361 location, yyscanner,
362 ("type " + *name + " based on unpublished typedef "
363 + n + " used in published context"));
364 return FOUND_ERROR;
366 OUString t(
367 static_cast<unoidl::TypedefEntity *>(e->entity.get())
368 ->getType());
369 typeNucleus = t;
370 while (typeNucleus.startsWith("[]", &typeNucleus)) {
371 if (!args.empty()) {
372 error(
373 location, yyscanner,
374 ("inconsistent type manager: bad type " + *name
375 + (" based on instantiated polymorphic struct"
376 " type based on sequence type named ")
377 + t));
378 return FOUND_ERROR;
380 if (rank == std::numeric_limits<std::size_t>::max()) {
381 error(
382 location, yyscanner,
383 ("bad type " + *name
384 + " based on sequence type of too high rank"));
385 return FOUND_ERROR;
387 ++rank;
389 sal_Int32 i = typeNucleus.indexOf('<');
390 if (i != -1) {
391 if (!args.empty()) {
392 error(
393 location, yyscanner,
394 ("inconsistent type manager: bad type " + *name
395 + (" based on instantiated polymorphic struct"
396 " type based on instantiated polymorphic"
397 " struct type named ")
398 + t));
399 return FOUND_ERROR;
401 OUString tmpl(typeNucleus.copy(0, i));
402 do {
403 ++i; // skip '<' or ','
404 sal_Int32 j = i;
405 for (sal_Int32 level = 0;
406 j != typeNucleus.getLength(); ++j)
408 sal_Unicode c = typeNucleus[j];
409 if (c == ',') {
410 if (level == 0) {
411 break;
413 } else if (c == '<') {
414 ++level;
415 } else if (c == '>') {
416 if (level == 0) {
417 break;
419 --level;
422 if (j != typeNucleus.getLength()) {
423 OUString argName(typeNucleus.copy(i, j - i));
424 unoidl::detail::SourceProviderEntity const *
425 argEnt;
426 unoidl::detail::SourceProviderType argType;
427 switch (
428 findEntity(
429 location, yyscanner, data, false,
430 &argName, &argEnt, nullptr, &argType))
432 case FOUND_ERROR:
433 return FOUND_ERROR;
434 case FOUND_TYPE:
435 break;
436 case FOUND_ENTITY:
437 if (argEnt == nullptr) {
438 error(
439 location, yyscanner,
440 (("inconsistent type manager: bad"
441 " instantiated polymorphic struct"
442 " type template type argument ")
443 + argName));
444 return FOUND_ERROR;
445 } else {
446 unoidl::detail::SourceProviderType::Type
447 argT
448 = unoidl::detail::SourceProviderType::Type();
449 // avoid warnings
450 switch (argEnt->kind) {
451 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
452 if (e->pad.is()) {
453 error(
454 location, yyscanner,
455 (("inconsistent type"
456 " manager: bad"
457 " instantiated"
458 " polymorphic struct type"
459 " template type"
460 " argument ")
461 + argName));
462 return FOUND_ERROR;
464 assert(e->entity.is());
465 [[fallthrough]];
466 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
467 switch (e->entity->getSort()) {
468 case unoidl::Entity::SORT_ENUM_TYPE:
469 argT = unoidl::detail::SourceProviderType::TYPE_ENUM;
470 break;
471 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
472 argT = unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT;
473 break;
474 case unoidl::Entity::SORT_INTERFACE_TYPE:
475 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
476 break;
477 default:
478 error(
479 location, yyscanner,
480 (("inconsistent type"
481 "manager: bad"
482 " instantiated"
483 " polymorphic struct type"
484 " template type"
485 " argument ")
486 + argName));
487 return FOUND_ERROR;
489 break;
490 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
491 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
492 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
493 break;
494 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
495 assert(false && "this cannot happen");
497 argType
498 = unoidl::detail::SourceProviderType(
499 argT, argName, argEnt);
501 break;
503 args.push_back(argType);
505 i = j;
506 } while (i != typeNucleus.getLength()
507 && typeNucleus[i] != '>');
508 if (i != typeNucleus.getLength() - 1
509 || typeNucleus[i] != '>')
511 error(
512 location, yyscanner,
513 ("inconsistent type manager: bad type name \""
514 + t + "\""));
515 return FOUND_ERROR;
517 assert(!args.empty());
518 typeNucleus = tmpl;
520 if (typeNucleus.isEmpty()) {
521 error(
522 location, yyscanner,
523 ("inconsistent type manager: bad type name \"" + t
524 + "\""));
525 return FOUND_ERROR;
527 if (typeNucleus == "void") {
528 error(
529 location, yyscanner,
530 ("inconsistent type manager: bad type " + *name
531 + " based on void"));
532 return FOUND_ERROR;
534 if (typeNucleus == "boolean" || typeNucleus == "byte"
535 || typeNucleus == "short"
536 || typeNucleus == "unsigned short"
537 || typeNucleus == "long"
538 || typeNucleus == "unsigned long"
539 || typeNucleus == "hyper"
540 || typeNucleus == "unsigned hyper"
541 || typeNucleus == "float" || typeNucleus == "double"
542 || typeNucleus == "char" || typeNucleus == "string"
543 || typeNucleus == "type" || typeNucleus == "any")
545 if (!args.empty()) {
546 error(
547 location, yyscanner,
548 ("inconsistent type manager: bad type " + *name
549 + (" based on instantiated polymorphic struct"
550 " type based on ")
551 + typeNucleus));
552 return FOUND_ERROR;
554 break;
556 n = "." + typeNucleus;
557 typeNucleus.clear();
558 e = findEntity_(data, &n);
559 continue;
561 break;
562 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
563 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
564 if (resolveInterfaceDefinitions) {
565 rtl::Reference<unoidl::Entity> ent(
566 data->manager->findEntity(n));
567 // Do not allow ent to be of SORT_TYPEDEF:
568 if (!ent.is()
569 || (ent->getSort()
570 != unoidl::Entity::SORT_INTERFACE_TYPE))
572 error(
573 location, yyscanner,
574 (*name + " is based on interface declaration " + n
575 + " that is not an interface type entity"));
576 return FOUND_ERROR;
578 e->kind
579 = unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
580 e->entity = ent;
582 break;
583 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
584 error(
585 location, yyscanner,
586 *name + " is based on module entity " + n);
587 return FOUND_ERROR;
590 if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
591 if (typeNucleus.isEmpty() && e == nullptr) {
592 // Found a type name based on an unknown entity:
593 *entity = nullptr;
594 return FOUND_ENTITY;
596 unoidl::detail::SourceProviderType t;
597 if (args.empty()) {
598 if (typeNucleus == "boolean") {
599 t = unoidl::detail::SourceProviderType(
600 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
601 } else if (typeNucleus == "byte") {
602 t = unoidl::detail::SourceProviderType(
603 unoidl::detail::SourceProviderType::TYPE_BYTE);
604 } else if (typeNucleus == "short") {
605 t = unoidl::detail::SourceProviderType(
606 unoidl::detail::SourceProviderType::TYPE_SHORT);
607 } else if (typeNucleus == "unsigned short") {
608 t = unoidl::detail::SourceProviderType(
609 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
610 } else if (typeNucleus == "long") {
611 t = unoidl::detail::SourceProviderType(
612 unoidl::detail::SourceProviderType::TYPE_LONG);
613 } else if (typeNucleus == "unsigned long") {
614 t = unoidl::detail::SourceProviderType(
615 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
616 } else if (typeNucleus == "hyper") {
617 t = unoidl::detail::SourceProviderType(
618 unoidl::detail::SourceProviderType::TYPE_HYPER);
619 } else if (typeNucleus == "unsigned hyper") {
620 t = unoidl::detail::SourceProviderType(
621 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
622 } else if (typeNucleus == "float") {
623 t = unoidl::detail::SourceProviderType(
624 unoidl::detail::SourceProviderType::TYPE_FLOAT);
625 } else if (typeNucleus == "double") {
626 t = unoidl::detail::SourceProviderType(
627 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
628 } else if (typeNucleus == "char") {
629 t = unoidl::detail::SourceProviderType(
630 unoidl::detail::SourceProviderType::TYPE_CHAR);
631 } else if (typeNucleus == "string") {
632 t = unoidl::detail::SourceProviderType(
633 unoidl::detail::SourceProviderType::TYPE_STRING);
634 } else if (typeNucleus == "type") {
635 t = unoidl::detail::SourceProviderType(
636 unoidl::detail::SourceProviderType::TYPE_TYPE);
637 } else if (typeNucleus == "any") {
638 t = unoidl::detail::SourceProviderType(
639 unoidl::detail::SourceProviderType::TYPE_ANY);
640 } else {
641 assert(typeNucleus.isEmpty());
642 assert(e != nullptr);
643 switch (e->kind) {
644 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
645 if (e->pad.is()) {
646 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
647 e->pad.get())
648 != nullptr)
650 t = unoidl::detail::SourceProviderType(
651 unoidl::detail::SourceProviderType::TYPE_ENUM,
652 n, e);
653 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
654 e->pad.get())
655 != nullptr)
657 t = unoidl::detail::SourceProviderType(
658 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
659 n, e);
660 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
661 e->pad.get())
662 != nullptr)
664 error(
665 location, yyscanner,
666 ("bad type " + *name
667 + (" based on recursive reference to"
668 " polymorphic struct type template ")
669 + n));
670 return FOUND_ERROR;
671 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
672 e->pad.get())
673 != nullptr)
675 t = unoidl::detail::SourceProviderType(
676 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
677 n, e);
678 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
679 e->pad.get())
680 != nullptr)
682 t = unoidl::detail::SourceProviderType(
683 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
684 n, e);
685 } else {
686 error(
687 location, yyscanner,
688 ("bad type " + *name
689 + " based on non-type entity " + n));
690 return FOUND_ERROR;
692 break;
694 assert(e->entity.is());
695 [[fallthrough]];
696 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
697 switch (e->entity->getSort()) {
698 case unoidl::Entity::SORT_ENUM_TYPE:
699 t = unoidl::detail::SourceProviderType(
700 unoidl::detail::SourceProviderType::TYPE_ENUM,
701 n, e);
702 break;
703 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
704 t = unoidl::detail::SourceProviderType(
705 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
706 n, e);
707 break;
708 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
709 error(
710 location, yyscanner,
711 ("bad type " + *name
712 + " based on polymorphic struct type template "
713 + n + " without type arguments"));
714 return FOUND_ERROR;
715 case unoidl::Entity::SORT_EXCEPTION_TYPE:
716 t = unoidl::detail::SourceProviderType(
717 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
718 n, e);
719 break;
720 case unoidl::Entity::SORT_INTERFACE_TYPE:
721 t = unoidl::detail::SourceProviderType(
722 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
723 n, e);
724 break;
725 default:
726 error(
727 location, yyscanner,
728 ("bad type " + *name
729 + " based on non-type entity " + n));
730 return FOUND_ERROR;
732 break;
733 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
734 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
735 t = unoidl::detail::SourceProviderType(
736 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
737 n, e);
738 break;
739 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
740 assert(false && "this cannot happen");
743 } else {
744 assert(typeNucleus.isEmpty());
745 assert(e != nullptr);
746 switch (e->kind) {
747 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
748 if (e->pad.is()) {
749 error(
750 location, yyscanner,
751 ("bad type " + *name
752 + (" based on instantiated polymorphic struct type"
753 " based on ")
755 + (" that is either not a polymorphic struct type"
756 " template or a recursive reference to a"
757 " polymorphic struct type template")));
758 return FOUND_ERROR;
760 assert(e->entity.is());
761 [[fallthrough]];
762 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
763 if (e->entity->getSort()
764 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
766 if (args.size()
767 != (static_cast<
768 unoidl::PolymorphicStructTypeTemplateEntity *>(
769 e->entity.get())
770 ->getTypeParameters().size()))
772 error(
773 location, yyscanner,
774 ("bad type " + *name
775 + (" based on instantiated polymorphic struct"
776 " type with ")
777 + OUString::number(args.size())
778 + (" type arguments based on polymorphic"
779 " struct type template ")
780 + n + " with "
781 + OUString::number(
782 static_cast<
783 unoidl::PolymorphicStructTypeTemplateEntity *>(
784 e->entity.get())
785 ->getTypeParameters().size())
786 + " type parameters"));
787 return FOUND_ERROR;
789 t = unoidl::detail::SourceProviderType(n, e, args);
790 break;
792 [[fallthrough]];
793 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
794 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
795 error(
796 location, yyscanner,
797 ("bad type " + *name
798 + (" based on instantiated polymorphic struct type"
799 " based on ")
801 + " that is not a polymorphic struct type template"));
802 return FOUND_ERROR;
803 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
804 assert(false && "this cannot happen");
807 if (typedefedType != nullptr) {
808 for (std::size_t i = 0; i != rank; ++i) {
809 t = unoidl::detail::SourceProviderType(&t);
811 *typedefedType = t;
812 typedefedType->typedefName = *name;
814 *entity = nullptr;
815 return FOUND_TYPE;
817 *entity = e;
818 return FOUND_ENTITY;
823 bool checkTypeArgument(
824 YYLTYPE location, yyscan_t yyscanner,
825 unoidl::detail::SourceProviderType const & type)
827 switch (type.type) {
828 case unoidl::detail::SourceProviderType::TYPE_VOID:
829 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
830 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
831 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
832 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
833 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
834 error(
835 location, yyscanner,
836 "bad instantiated polymorphic struct type argument");
837 return false;
838 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
839 return checkTypeArgument(location, yyscanner, type.subtypes.front());
840 default:
841 return true;
845 bool checkInstantiatedPolymorphicStructTypeArgument(
846 unoidl::detail::SourceProviderType const & type, OUString const & name)
848 if (type.type
849 == unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
851 for (auto & i: type.subtypes) {
852 if (checkInstantiatedPolymorphicStructTypeArgument(i, name)
853 || i.getName() == name) // no need to worry about typedef
855 return true;
859 return false;
862 std::vector<OUString> annotations(bool deprecated) {
863 std::vector<OUString> ann;
864 if (deprecated) {
865 ann.push_back("deprecated");
867 return ann;
874 %token TOK_ELLIPSIS
875 %token TOK_COLONS
876 %token TOK_LEFTSHIFT
877 %token TOK_RIGHTSHIFT
879 %token TOK_FALSE
880 %token TOK_TRUE
881 %token TOK_ANY
882 %token TOK_ATTRIBUTE
883 %token TOK_BOOLEAN
884 %token TOK_BOUND
885 %token TOK_BYTE
886 %token TOK_CHAR
887 %token TOK_CONST
888 %token TOK_CONSTANTS
889 %token TOK_CONSTRAINED
890 %token TOK_DOUBLE
891 %token TOK_ENUM
892 %token TOK_EXCEPTION
893 %token TOK_FLOAT
894 %token TOK_GET
895 %token TOK_HYPER
896 %token TOK_IN
897 %token TOK_INOUT
898 %token TOK_INTERFACE
899 %token TOK_LONG
900 %token TOK_MAYBEAMBIGUOUS
901 %token TOK_MAYBEDEFAULT
902 %token TOK_MAYBEVOID
903 %token TOK_MODULE
904 %token TOK_OPTIONAL
905 %token TOK_OUT
906 %token TOK_PROPERTY
907 %token TOK_PUBLISHED
908 %token TOK_RAISES
909 %token TOK_READONLY
910 %token TOK_REMOVABLE
911 %token TOK_SEQUENCE
912 %token TOK_SERVICE
913 %token TOK_SET
914 %token TOK_SHORT
915 %token TOK_SINGLETON
916 %token TOK_STRING
917 %token TOK_STRUCT
918 %token TOK_TRANSIENT
919 %token TOK_TYPE
920 %token TOK_TYPEDEF
921 %token TOK_UNSIGNED
922 %token TOK_VOID
924 %token<sval> TOK_IDENTIFIER
925 %token<ival> TOK_INTEGER
926 %token<fval> TOK_FLOATING
928 %token TOK_DEPRECATED
930 %token TOK_ERROR
932 %type<sval> identifier name singleInheritance singleInheritance_opt
933 %type<bval> ctors_opt deprecated_opt ellipsis_opt published_opt
934 %type<decls> attributeAccessDecl attributeAccessDecls
935 %type<dir> direction
936 %type<excns> exceptionSpec exceptionSpec_opt exceptions
937 %type<flags> flag flagSection flagSection_opt flags
938 %type<expr> addExpr andExpr expr multExpr orExpr primaryExpr shiftExpr unaryExpr
939 xorExpr
940 %type<type> type
941 %type<types> typeArguments
943 %initial-action { yylloc = 1; }
947 definitions:
948 definitions definition
949 | /* empty */
952 definition:
953 moduleDecl
954 | enumDefn
955 | plainStructDefn
956 | polymorphicStructTemplateDefn
957 | exceptionDefn
958 | interfaceDefn
959 | typedefDefn
960 | constantGroupDefn
961 | singleInterfaceBasedServiceDefn
962 | accumulationBasedServiceDefn
963 | interfaceBasedSingletonDefn
964 | serviceBasedSingletonDefn
965 | interfaceDecl
968 moduleDecl:
969 TOK_MODULE identifier
971 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
972 OUString name(convertToFullName(data, $2));
973 data->modules.push_back(name);
974 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
975 data->entities.emplace(
976 name,
977 unoidl::detail::SourceProviderEntity(
978 unoidl::detail::SourceProviderEntity::KIND_MODULE)));
979 if (!p.second
980 && (p.first->second.kind
981 != unoidl::detail::SourceProviderEntity::KIND_MODULE))
983 error(@2, yyscanner, "multiple entities named " + name);
984 YYERROR;
987 '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
990 enumDefn:
991 deprecated_opt published_opt TOK_ENUM identifier
993 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
994 data->publishedContext = $2;
995 convertToCurrentName(data, $4);
996 if (!data->entities.emplace(
997 data->currentName,
998 unoidl::detail::SourceProviderEntity(
999 new unoidl::detail::SourceProviderEnumTypeEntityPad(
1000 $2))).
1001 second)
1003 error(@4, yyscanner, "multiple entities named " + data->currentName);
1004 YYERROR;
1007 '{' enumMembers '}' ';'
1009 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1010 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1011 unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
1012 dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
1013 ent->pad.get());
1014 assert(pad != nullptr);
1015 ent->entity = new unoidl::EnumTypeEntity(
1016 pad->isPublished(), pad->members, annotations($1));
1017 ent->pad.clear();
1018 clearCurrentState(data);
1022 enumMembers:
1023 | enumMembers ',' enumMember
1024 | enumMember
1027 enumMember:
1028 deprecated_opt identifier
1030 OUString id(convertName($2));
1031 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1032 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1033 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1034 sal_Int32 v;
1035 if (pad->members.empty()) {
1036 v = 0;
1037 } else {
1038 v = pad->members.back().value;
1039 if (v == SAL_MAX_INT32) {
1040 error(
1041 @2, yyscanner,
1042 ("enum " + data->currentName + " member " + id
1043 + " would have out-of-range value 2^31"));
1044 YYERROR;
1046 ++v;
1048 pad->members.emplace_back(id, v, annotations($1));
1050 | deprecated_opt identifier '=' expr
1052 OUString id(convertName($2));
1053 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1054 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1055 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1056 sal_Int32 v;
1057 switch ($4.type) {
1058 case unoidl::detail::SourceProviderExpr::TYPE_INT:
1059 if ($4.ival < SAL_MIN_INT32 || $4.ival > SAL_MAX_INT32) {
1060 error(
1061 @4, yyscanner,
1062 ("out-of-range enum " + data->currentName + " member " + id
1063 + " value " + OUString::number($4.ival)));
1064 YYERROR;
1066 v = static_cast<sal_Int32>($4.ival);
1067 break;
1068 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
1069 if ($4.uval > SAL_MAX_INT32) {
1070 error(
1071 @4, yyscanner,
1072 ("out-of-range enum " + data->currentName + " member " + id
1073 + " value " + OUString::number($4.uval)));
1074 YYERROR;
1076 v = static_cast<sal_Int32>($4.uval);
1077 break;
1078 default:
1079 error(
1080 @4, yyscanner,
1081 ("non-integer enum " + data->currentName + " member " + id
1082 + " value"));
1083 YYERROR;
1084 break;
1086 pad->members.emplace_back(id, v, annotations($1));
1090 plainStructDefn:
1091 deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
1093 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1094 data->publishedContext = $2;
1095 convertToCurrentName(data, $4);
1096 OUString baseName;
1097 rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
1098 if ($5 != nullptr) {
1099 baseName = convertName($5);
1100 unoidl::detail::SourceProviderEntity const * p;
1101 if (findEntity(
1102 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1103 == FOUND_ERROR)
1105 YYERROR;
1107 if (p == nullptr || !p->entity.is()
1108 || p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
1110 error(
1111 @5, yyscanner,
1112 ("plain struct type " + data->currentName + " base "
1113 + baseName
1114 + " does not resolve to an existing plain struct type"));
1115 YYERROR;
1117 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1118 p->entity.get());
1119 if ($2 && !baseEnt->isPublished()) {
1120 error(
1121 @5, yyscanner,
1122 ("published plain struct type " + data->currentName + " base "
1123 + baseName + " is unpublished"));
1124 YYERROR;
1127 if (!data->entities.emplace(
1128 data->currentName,
1129 unoidl::detail::SourceProviderEntity(
1130 new unoidl::detail::SourceProviderPlainStructTypeEntityPad(
1131 $2, baseName, baseEnt))).
1132 second)
1134 error(@4, yyscanner, "multiple entities named " + data->currentName);
1135 YYERROR;
1138 '{' structMembers '}' ';'
1140 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1141 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1142 unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
1143 dynamic_cast<
1144 unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1145 ent->pad.get());
1146 assert(pad != nullptr);
1147 ent->entity = new unoidl::PlainStructTypeEntity(
1148 pad->isPublished(), pad->baseName, pad->members, annotations($1));
1149 ent->pad.clear();
1150 clearCurrentState(data);
1154 polymorphicStructTemplateDefn:
1155 deprecated_opt published_opt TOK_STRUCT identifier '<'
1157 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1158 data->publishedContext = $2;
1159 convertToCurrentName(data, $4);
1160 if (!data->entities.emplace(
1161 data->currentName,
1162 unoidl::detail::SourceProviderEntity(
1163 new unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad(
1164 $2))).
1165 second)
1167 error(@4, yyscanner, "multiple entities named " + data->currentName);
1168 YYERROR;
1171 typeParameters '>' '{' structMembers '}' ';'
1173 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1174 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1175 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1176 pad = dynamic_cast<
1177 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1178 ent->pad.get());
1179 assert(pad != nullptr);
1180 ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
1181 pad->isPublished(), pad->typeParameters, pad->members,
1182 annotations($1));
1183 ent->pad.clear();
1184 clearCurrentState(data);
1188 typeParameters:
1189 typeParameters ',' identifier
1191 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1192 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1193 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1194 data));
1195 OUString id(convertName($3));
1196 if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
1197 != pad->typeParameters.end())
1199 error(
1200 @3, yyscanner,
1201 ("polymorphic struct type template " + data->currentName
1202 + " type parameter " + id
1203 + " has same identifier as another type parameter"));
1204 YYERROR;
1206 pad->typeParameters.push_back(id);
1208 | identifier
1210 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1211 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1212 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1213 data));
1214 OUString id(convertName($1));
1215 assert(pad->typeParameters.empty());
1216 pad->typeParameters.push_back(id);
1220 exceptionDefn:
1221 deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
1223 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1224 data->publishedContext = $2;
1225 convertToCurrentName(data, $4);
1226 OUString baseName;
1227 rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
1228 if ($5 != nullptr) {
1229 baseName = convertName($5);
1230 unoidl::detail::SourceProviderEntity const * p;
1231 if (findEntity(
1232 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1233 == FOUND_ERROR)
1235 YYERROR;
1237 if (p == nullptr || !p->entity.is()
1238 || p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE)
1240 error(
1241 @5, yyscanner,
1242 ("exception type " + data->currentName + " base " + baseName
1243 + " does not resolve to an existing exception type"));
1244 YYERROR;
1246 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1247 p->entity.get());
1248 if ($2 && !baseEnt->isPublished()) {
1249 error(
1250 @5, yyscanner,
1251 ("published exception type " + data->currentName + " base "
1252 + baseName + " is unpublished"));
1253 YYERROR;
1256 if (!data->entities.emplace(
1257 data->currentName,
1258 unoidl::detail::SourceProviderEntity(
1259 new unoidl::detail::SourceProviderExceptionTypeEntityPad(
1260 $2, baseName, baseEnt))).
1261 second)
1263 error(@4, yyscanner, "multiple entities named " + data->currentName);
1264 YYERROR;
1267 '{' structMembers '}' ';'
1269 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1270 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1271 unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
1272 dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1273 ent->pad.get());
1274 assert(pad != nullptr);
1275 ent->entity = new unoidl::ExceptionTypeEntity(
1276 pad->isPublished(), pad->baseName, pad->members, annotations($1));
1277 ent->pad.clear();
1278 clearCurrentState(data);
1282 structMembers:
1283 structMembers structMember
1284 | /* empty */
1287 structMember:
1288 deprecated_opt type identifier ';'
1290 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1291 unoidl::detail::SourceProviderType t(*$2);
1292 delete $2;
1293 OUString id(convertName($3));
1294 switch (t.type) {
1295 case unoidl::detail::SourceProviderType::TYPE_VOID:
1296 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1297 error(
1298 @2, yyscanner,
1299 ("illegal struct/exception type " + data->currentName
1300 + " direct member " + id + " type"));
1301 YYERROR;
1302 break;
1303 default:
1304 break;
1306 if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
1307 && t.getName() == data->currentName) // no need to worry about typedef
1309 error(
1310 @2, yyscanner,
1311 ("struct/exception type " + data->currentName + " direct member "
1312 + id + " has same type as the type itself"));
1313 YYERROR;
1315 if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
1317 error(
1318 @2, yyscanner,
1319 ("struct/exception type " + data->currentName + " direct member "
1320 + id
1321 + (" has instantiated polymorphic struct type that uses the type"
1322 " itself as an argument")));
1323 YYERROR;
1325 if (nameHasSameIdentifierAs(data->currentName, id)) {
1326 error(
1327 @3, yyscanner,
1328 ("struct/exception type " + data->currentName + " direct member "
1329 + id + " has same unqualified identifier as the type itself"));
1330 YYERROR;
1332 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1333 unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
1334 dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1335 ent->pad.get());
1336 if (p1 != nullptr) {
1337 for (const auto & i: p1->members) {
1338 if (id == i.name) {
1339 error(
1340 @3, yyscanner,
1341 ("plain struct type " + data->currentName
1342 + " direct member " + id
1343 + " has same identifier as another direct member"));
1344 YYERROR;
1347 if (p1->baseEntity.is()) {
1348 OUString baseName(p1->baseName);
1349 for (auto baseEnt(p1->baseEntity);;) {
1350 if (nameHasSameIdentifierAs(baseName, id)) {
1351 error(
1352 @3, yyscanner,
1353 ("plain struct type " + data->currentName
1354 + " direct member " + id
1355 + " has same unqalified identifier as base "
1356 + baseName));
1357 YYERROR;
1359 for (auto & i: baseEnt->getDirectMembers()) {
1360 if (id == i.name) {
1361 error(
1362 @3, yyscanner,
1363 ("plain struct type " + data->currentName
1364 + " direct member " + id
1365 + " has same identifier as a member of base "
1366 + baseName));
1367 YYERROR;
1370 baseName = baseEnt->getDirectBase();
1371 if (baseName.isEmpty()) {
1372 break;
1374 unoidl::detail::SourceProviderEntity const * p;
1375 if (findEntity(
1376 @2, yyscanner, data, false, &baseName, &p, nullptr,
1377 nullptr)
1378 == FOUND_ERROR)
1380 YYERROR;
1382 if (p == nullptr || !p->entity.is()
1383 || (p->entity->getSort()
1384 != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE))
1386 error(
1387 @2, yyscanner,
1388 ("inconsistent type manager: plain struct type "
1389 + data->currentName + " base " + baseName
1390 + (" does not resolve to an existing plain struct"
1391 " type")));
1392 YYERROR;
1394 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1395 p->entity.get());
1398 p1->members.emplace_back(id, t.getName(), annotations($1));
1399 } else {
1400 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1401 p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1402 ent->pad.get());
1403 if (p2 != nullptr) {
1404 for (const auto & i: p2->members) {
1405 if (id == i.name) {
1406 error(
1407 @3, yyscanner,
1408 ("polymorphic struct type template "
1409 + data->currentName + " direct member " + id
1410 + " has same identifier as another direct member"));
1411 YYERROR;
1414 p2->members.emplace_back(
1415 id, t.getName(),
1416 t.type == unoidl::detail::SourceProviderType::TYPE_PARAMETER,
1417 annotations($1));
1418 } else {
1419 unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
1420 = dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1421 ent->pad.get());
1422 assert(p3 != nullptr);
1423 for (const auto & i: p3->members) {
1424 if (id == i.name) {
1425 error(
1426 @3, yyscanner,
1427 ("exception type " + data->currentName
1428 + " direct member " + id
1429 + " has same identifier as another direct member"));
1430 YYERROR;
1433 if (p3->baseEntity.is()) {
1434 OUString baseName(p3->baseName);
1435 for (auto baseEnt(p3->baseEntity);;) {
1436 if (nameHasSameIdentifierAs(baseName, id)) {
1437 error(
1438 @3, yyscanner,
1439 ("exception type " + data->currentName
1440 + " direct member " + id
1441 + " has same unqalified identifier as base "
1442 + baseName));
1443 YYERROR;
1445 for (auto & i: baseEnt->getDirectMembers()) {
1446 if (id == i.name) {
1447 error(
1448 @3, yyscanner,
1449 ("exception type " + data->currentName
1450 + " direct member " + id
1451 + " has same identifier as a member of base "
1452 + baseName));
1453 YYERROR;
1456 baseName = baseEnt->getDirectBase();
1457 if (baseName.isEmpty()) {
1458 break;
1460 unoidl::detail::SourceProviderEntity const * p;
1461 if (findEntity(
1462 @2, yyscanner, data, false, &baseName, &p,
1463 nullptr, nullptr)
1464 == FOUND_ERROR)
1466 YYERROR;
1468 if (p == nullptr || !p->entity.is()
1469 || (p->entity->getSort()
1470 != unoidl::Entity::SORT_EXCEPTION_TYPE))
1472 error(
1473 @2, yyscanner,
1474 ("inconsistent type manager: exception type "
1475 + data->currentName + " base " + baseName
1476 + (" does not resolve to an existing exception"
1477 " type")));
1478 YYERROR;
1480 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1481 p->entity.get());
1484 p3->members.emplace_back(id, t.getName(), annotations($1));
1490 interfaceDefn:
1491 deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
1493 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1494 data->publishedContext = $2;
1495 convertToCurrentName(data, $4);
1496 OUString baseName;
1497 rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
1498 if ($5 != nullptr) {
1499 baseName = convertName($5);
1500 unoidl::detail::SourceProviderEntity const * p;
1501 if (findEntity(
1502 @5, yyscanner, data, true, &baseName, &p, nullptr, nullptr)
1503 == FOUND_ERROR)
1505 YYERROR;
1507 if (p == nullptr || !p->entity.is()
1508 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1510 error(
1511 @5, yyscanner,
1512 ("interface type " + data->currentName + " direct base "
1513 + baseName
1514 + " does not resolve to an existing interface type"));
1515 YYERROR;
1517 baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
1518 if ($2 && !baseEnt->isPublished()) {
1519 error(
1520 @5, yyscanner,
1521 ("published interface type " + data->currentName
1522 + " direct base " + baseName + " is unpublished"));
1523 YYERROR;
1526 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
1527 data->entities.find(data->currentName));
1528 if (i != data->entities.end()) {
1529 switch (i->second.kind) {
1530 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1531 break;
1532 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1533 if (!$2) {
1534 error(
1535 @4, yyscanner,
1536 ("unpublished interface type " + data->currentName
1537 + " has been declared published"));
1538 YYERROR;
1540 break;
1541 default:
1542 error(
1543 @4, yyscanner,
1544 "multiple entities named " + data->currentName);
1545 YYERROR;
1546 break;
1549 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1550 new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
1551 $2, baseEnt.is()));
1552 if (baseEnt.is()
1553 && !pad->addDirectBase(
1554 @4, yyscanner, data,
1555 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1556 baseName, baseEnt, std::vector<OUString>()),
1557 false))
1559 YYERROR;
1561 data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
1562 pad.get());
1564 '{' interfaceMembers '}' ';'
1566 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1567 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1568 unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
1569 dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
1570 ent->pad.get());
1571 assert(pad != nullptr);
1572 if (pad->directMandatoryBases.empty()
1573 && data->currentName != "com.sun.star.uno.XInterface")
1575 OUString base(".com.sun.star.uno.XInterface");
1576 unoidl::detail::SourceProviderEntity const * p;
1577 if (findEntity(@4, yyscanner, data, true, &base, &p, nullptr, nullptr)
1578 == FOUND_ERROR)
1580 YYERROR;
1582 if (p == nullptr || !p->entity.is()
1583 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1585 error(
1586 @3, yyscanner,
1587 ("interface type " + data->currentName
1588 + " implicit direct base " + base
1589 + " does not resolve to an existing interface type"));
1590 YYERROR;
1592 if (!pad->addDirectBase(
1593 @3, yyscanner, data,
1594 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1595 base,
1596 static_cast<unoidl::InterfaceTypeEntity *>(
1597 p->entity.get()),
1598 std::vector<OUString>()),
1599 false))
1601 YYERROR;
1604 std::vector<unoidl::AnnotatedReference> mbases;
1605 for (auto & i: pad->directMandatoryBases) {
1606 mbases.emplace_back(i.name, i.annotations);
1608 std::vector<unoidl::AnnotatedReference> obases;
1609 for (auto & i: pad->directOptionalBases) {
1610 obases.emplace_back(i.name, i.annotations);
1612 ent->entity = new unoidl::InterfaceTypeEntity(
1613 pad->isPublished(), mbases, obases, pad->directAttributes,
1614 pad->directMethods, annotations($1));
1615 ent->pad.clear();
1616 clearCurrentState(data);
1620 interfaceMembers:
1621 interfaceMembers interfaceMember
1622 | /* empty */
1625 interfaceMember:
1626 interfaceBase
1627 | interfaceAttribute
1628 | interfaceMethod
1631 interfaceBase:
1632 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
1634 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1635 OUString name(convertName($4));
1636 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1637 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1638 data));
1639 if (pad->singleBase) {
1640 error(
1641 @3, yyscanner,
1642 "single-inheritance interface cannot have additional bases");
1643 YYERROR;
1645 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
1646 error(
1647 @2, yyscanner,
1648 "interface base can only be flagged as [optional]");
1649 YYERROR;
1651 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
1652 OUString orgName(name);
1653 unoidl::detail::SourceProviderEntity const * p;
1654 bool typedefed = false;
1655 if (findEntity(@4, yyscanner, data, true, &name, &p, &typedefed, nullptr)
1656 == FOUND_ERROR)
1658 YYERROR;
1660 if (p == nullptr || !p->entity.is()
1661 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1663 error(
1664 @4, yyscanner,
1665 ("interface type " + data->currentName + " direct base " + name
1666 + " does not resolve to an existing interface type"));
1667 YYERROR;
1669 if (typedefed) {
1670 error(
1671 @4, yyscanner,
1672 ("interface type " + data->currentName + " direct base " + orgName
1673 + " is a typedef"));
1674 YYERROR;
1676 rtl::Reference<unoidl::InterfaceTypeEntity> ent(
1677 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()));
1678 if (data->publishedContext && !ent->isPublished()) {
1679 error(
1680 @4, yyscanner,
1681 ("published interface type " + data->currentName + " direct base "
1682 + name + " is unpublished"));
1683 YYERROR;
1685 if (!pad->addDirectBase(
1686 @4, yyscanner, data,
1687 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1688 name, ent, annotations($1)),
1689 opt))
1691 YYERROR;
1696 interfaceAttribute:
1697 deprecated_opt flagSection type identifier
1699 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1700 unoidl::detail::SourceProviderType t(*$3);
1701 delete $3;
1702 OUString id(convertName($4));
1703 if (($2 & unoidl::detail::FLAG_ATTRIBUTE) == 0) {
1704 error(
1705 @2, yyscanner,
1706 "interface attribute must be flagged as [attribute]");
1707 YYERROR;
1709 if (($2
1710 & ~(unoidl::detail::FLAG_ATTRIBUTE | unoidl::detail::FLAG_BOUND
1711 | unoidl::detail::FLAG_READONLY))
1712 != 0)
1714 error(
1715 @2, yyscanner,
1716 ("interface attribute can only be flagged as [attribute,"
1717 " bound, readonly]"));
1718 YYERROR;
1720 switch (t.type) {
1721 case unoidl::detail::SourceProviderType::TYPE_VOID:
1722 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1723 error(
1724 @3, yyscanner,
1725 ("illegal interface type " + data->currentName
1726 + " direct attribute " + id + " type"));
1727 YYERROR;
1728 break;
1729 default:
1730 break;
1732 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1733 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1734 data));
1735 if (!pad->addDirectMember(@4, yyscanner, data, id)) {
1736 YYERROR;
1738 pad->directAttributes.emplace_back(
1739 id, t.getName(), ($2 & unoidl::detail::FLAG_BOUND) != 0,
1740 ($2 & unoidl::detail::FLAG_READONLY) != 0,
1741 std::vector<OUString>(), std::vector<OUString>(), annotations($1));
1743 attributeAccessDecls_opt ';'
1746 attributeAccessDecls_opt:
1747 '{' attributeAccessDecls '}'
1748 | /* empty */
1751 attributeAccessDecls:
1752 attributeAccessDecls attributeAccessDecl
1754 if (($1 & $2) != 0) {
1755 error(
1756 @2, yyscanner, "duplicate get/set attribute access declaration");
1757 YYERROR;
1759 $$ = unoidl::detail::SourceProviderAccessDecls($1 | $2);
1761 | /* empty */ { $$ = unoidl::detail::SourceProviderAccessDecls(0); }
1764 attributeAccessDecl:
1765 TOK_GET exceptionSpec ';'
1767 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1768 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1769 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1770 data));
1771 assert(!pad->directAttributes.empty());
1772 pad->directAttributes.back().getExceptions = *$2;
1773 delete $2;
1774 $$ = unoidl::detail::ACCESS_DECL_GET;
1776 | TOK_SET exceptionSpec ';'
1778 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1779 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1780 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1781 data));
1782 assert(!pad->directAttributes.empty());
1783 pad->directAttributes.back().setExceptions = *$2;
1784 delete $2;
1785 if (pad->directAttributes.back().readOnly) {
1786 error(
1787 @1, yyscanner,
1788 ("interface type " + data->currentName
1789 + " direct read-only attribute "
1790 + pad->directAttributes.back().name
1791 + " cannot have set access declaration"));
1792 YYERROR;
1794 $$ = unoidl::detail::ACCESS_DECL_SET;
1798 interfaceMethod:
1799 deprecated_opt type identifier
1801 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1802 unoidl::detail::SourceProviderType t(*$2);
1803 delete $2;
1804 OUString id(convertName($3));
1805 if (t.type == unoidl::detail::SourceProviderType::TYPE_EXCEPTION) {
1806 error(
1807 @3, yyscanner,
1808 ("illegal interface type " + data->currentName
1809 + " direct method " + id + " return type"));
1810 YYERROR;
1812 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1813 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1814 data));
1815 if (!pad->addDirectMember(@3, yyscanner, data, id)) {
1816 YYERROR;
1818 pad->directMethods.emplace_back(
1819 id, t.getName(),
1820 std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>(),
1821 std::vector<OUString>(), annotations($1));
1823 '(' methodParams_opt ')' exceptionSpec_opt ';'
1825 if ($8 != nullptr) {
1826 unoidl::detail::SourceProviderScannerData * data
1827 = yyget_extra(yyscanner);
1828 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1829 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1830 data));
1831 assert(!pad->directMethods.empty());
1832 pad->directMethods.back().exceptions = *$8;
1833 delete $8;
1838 methodParams_opt:
1839 methodParams
1840 | /* empty */
1843 methodParams:
1844 methodParams ',' methodParam
1845 | methodParam
1848 methodParam:
1849 '[' direction ']' type identifier
1851 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1852 unoidl::detail::SourceProviderType t(*$4);
1853 delete $4;
1854 OUString id(convertName($5));
1855 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1856 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1857 data));
1858 assert(!pad->directMethods.empty());
1859 switch (t.type) {
1860 case unoidl::detail::SourceProviderType::TYPE_VOID:
1861 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1862 error(
1863 @4, yyscanner,
1864 ("illegal interface type " + data->currentName
1865 + " direct method " + pad->directMethods.back().name
1866 + " parameter " + id + " type"));
1867 YYERROR;
1868 break;
1869 default:
1870 break;
1872 for (const auto & i: pad->directMethods.back().parameters) {
1873 if (id == i.name) {
1874 error(
1875 @5, yyscanner,
1876 ("interface type " + data->currentName + " direct method "
1877 + pad->directMethods.back().name + " parameter " + id
1878 + " has same identifier as another parameter"));
1879 YYERROR;
1882 pad->directMethods.back().parameters.emplace_back(id, t.getName(), $2);
1886 direction:
1887 TOK_IN { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; }
1888 | TOK_OUT
1889 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT; }
1890 | TOK_INOUT
1891 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT; }
1894 typedefDefn:
1895 deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
1897 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1898 data->publishedContext = $2;
1899 unoidl::detail::SourceProviderType t(*$4);
1900 delete $4;
1901 OUString name(convertToFullName(data, $5));
1902 // There is no good reason to forbid typedefs to VOID, to instantiated
1903 // polymorphic struct types, and to exception types, but some old client
1904 // code of registry data expects this typedef restriction (like the
1905 // assert(false) default in handleTypedef in
1906 // codemaker/source/javamaker/javatype.cxx), so forbid them for now:
1907 switch (t.type) {
1908 case unoidl::detail::SourceProviderType::TYPE_VOID:
1909 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1910 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
1911 error(@4, yyscanner, "bad typedef type");
1912 YYERROR;
1913 break;
1914 case unoidl::detail::SourceProviderType::TYPE_ENUM:
1915 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
1916 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
1917 if ($2) {
1918 bool unpub = false;
1919 switch (t.entity->kind) {
1920 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1921 unpub = true;
1922 break;
1923 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1924 break;
1925 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
1926 assert(false && "this cannot happen");
1927 [[fallthrough]];
1928 default:
1929 assert(t.entity->entity.is() || t.entity->pad.is());
1930 unpub
1931 = !(t.entity->entity.is()
1932 ? static_cast<unoidl::PublishableEntity *>(
1933 t.entity->entity.get())->isPublished()
1934 : t.entity->pad->isPublished());
1935 break;
1937 if (unpub) {
1938 error(
1939 @4, yyscanner,
1940 "published typedef " + name + " type is unpublished");
1941 YYERROR;
1944 break;
1945 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
1946 assert(false && "this cannot happen");
1947 [[fallthrough]];
1948 default:
1949 break;
1951 if (!data->entities.emplace(
1952 name,
1953 unoidl::detail::SourceProviderEntity(
1954 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
1955 new unoidl::TypedefEntity(
1956 $2, t.getName(), annotations($1)))).
1957 second)
1959 error(@5, yyscanner, "multiple entities named " + name);
1960 YYERROR;
1962 clearCurrentState(data);
1966 constantGroupDefn:
1967 deprecated_opt published_opt TOK_CONSTANTS identifier
1969 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1970 data->publishedContext = $2;
1971 convertToCurrentName(data, $4);
1972 if (!data->entities.emplace(
1973 data->currentName,
1974 unoidl::detail::SourceProviderEntity(
1975 new unoidl::detail::SourceProviderConstantGroupEntityPad(
1976 $2))).
1977 second)
1979 error(@4, yyscanner, "multiple entities named " + data->currentName);
1980 YYERROR;
1983 '{' constants '}' ';'
1985 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1986 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1987 unoidl::detail::SourceProviderConstantGroupEntityPad * pad =
1988 dynamic_cast<unoidl::detail::SourceProviderConstantGroupEntityPad *>(
1989 ent->pad.get());
1990 assert(pad != nullptr);
1991 ent->entity = new unoidl::ConstantGroupEntity(
1992 pad->isPublished(), pad->members, annotations($1));
1993 ent->pad.clear();
1994 clearCurrentState(data);
1998 constants:
1999 constants constant
2000 | /* empty */
2003 constant:
2004 deprecated_opt TOK_CONST type identifier '=' expr ';'
2006 OUString id(convertName($4));
2007 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2008 rtl::Reference<unoidl::detail::SourceProviderConstantGroupEntityPad> pad(
2009 getCurrentPad<unoidl::detail::SourceProviderConstantGroupEntityPad>(
2010 data));
2011 unoidl::detail::SourceProviderType t(*$3);
2012 delete $3;
2013 unoidl::ConstantValue v(false); // dummy value
2014 switch (t.type) {
2015 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
2016 if ($6.type != unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
2017 error(
2018 @6, yyscanner,
2019 ("bad value of boolean-typed constant " + data->currentName
2020 + "." + id));
2021 YYERROR;
2023 v = unoidl::ConstantValue($6.bval);
2024 break;
2025 case unoidl::detail::SourceProviderType::TYPE_BYTE:
2026 switch ($6.type) {
2027 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2028 if ($6.ival < SAL_MIN_INT8 || $6.ival > SAL_MAX_INT8) {
2029 error(
2030 @6, yyscanner,
2031 ("out-of-range byte-typed constant " + data->currentName
2032 + "." + id + " value " + OUString::number($6.ival)));
2033 YYERROR;
2035 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.ival));
2036 break;
2037 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2038 if ($6.uval > SAL_MAX_INT8) {
2039 error(
2040 @6, yyscanner,
2041 ("out-of-range byte-typed constant " + data->currentName
2042 + "." + id + " value " + OUString::number($6.uval)));
2043 YYERROR;
2045 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.uval));
2046 break;
2047 default:
2048 error(
2049 @6, yyscanner,
2050 ("bad value of byte-typed constant " + data->currentName + "."
2051 + id));
2052 YYERROR;
2053 break;
2055 break;
2056 case unoidl::detail::SourceProviderType::TYPE_SHORT:
2057 switch ($6.type) {
2058 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2059 if ($6.ival < SAL_MIN_INT16 || $6.ival > SAL_MAX_INT16) {
2060 error(
2061 @6, yyscanner,
2062 ("out-of-range short-typed constant " + data->currentName
2063 + "." + id + " value " + OUString::number($6.ival)));
2064 YYERROR;
2066 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.ival));
2067 break;
2068 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2069 if ($6.uval > SAL_MAX_INT16) {
2070 error(
2071 @6, yyscanner,
2072 ("out-of-range short-typed constant " + data->currentName
2073 + "." + id + " value " + OUString::number($6.uval)));
2074 YYERROR;
2076 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.uval));
2077 break;
2078 default:
2079 error(
2080 @6, yyscanner,
2081 ("bad value of short-typed constant " + data->currentName
2082 + "." + id));
2083 YYERROR;
2084 break;
2086 break;
2087 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
2088 switch ($6.type) {
2089 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2090 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT16) {
2091 error(
2092 @6, yyscanner,
2093 ("out-of-range unsigned-short-typed constant "
2094 + data->currentName + "." + id + " value "
2095 + OUString::number($6.ival)));
2096 YYERROR;
2098 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.ival));
2099 break;
2100 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2101 if ($6.uval > SAL_MAX_UINT16) {
2102 error(
2103 @6, yyscanner,
2104 ("out-of-range unsigned-short-typed constant "
2105 + data->currentName + "." + id + " value "
2106 + OUString::number($6.uval)));
2107 YYERROR;
2109 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.uval));
2110 break;
2111 default:
2112 error(
2113 @6, yyscanner,
2114 ("bad value of unsigned-short-typed constant "
2115 + data->currentName + "." + id));
2116 YYERROR;
2117 break;
2119 break;
2120 case unoidl::detail::SourceProviderType::TYPE_LONG:
2121 switch ($6.type) {
2122 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2123 if ($6.ival < SAL_MIN_INT32 || $6.ival > SAL_MAX_INT32) {
2124 error(
2125 @6, yyscanner,
2126 ("out-of-range long-typed constant " + data->currentName
2127 + "." + id + " value " + OUString::number($6.ival)));
2128 YYERROR;
2130 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.ival));
2131 break;
2132 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2133 if ($6.uval > SAL_MAX_INT32) {
2134 error(
2135 @6, yyscanner,
2136 ("out-of-range long-typed constant " + data->currentName
2137 + "." + id + " value " + OUString::number($6.uval)));
2138 YYERROR;
2140 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.uval));
2141 break;
2142 default:
2143 error(
2144 @6, yyscanner,
2145 ("bad value of long-typed constant " + data->currentName
2146 + "." + id));
2147 YYERROR;
2148 break;
2150 break;
2151 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
2152 switch ($6.type) {
2153 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2154 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT32) {
2155 error(
2156 @6, yyscanner,
2157 ("out-of-range unsigned-long-typed constant "
2158 + data->currentName + "." + id + " value "
2159 + OUString::number($6.ival)));
2160 YYERROR;
2162 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.ival));
2163 break;
2164 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2165 if ($6.uval > SAL_MAX_UINT32) {
2166 error(
2167 @6, yyscanner,
2168 ("out-of-range unsigned-long-typed constant "
2169 + data->currentName + "." + id + " value "
2170 + OUString::number($6.uval)));
2171 YYERROR;
2173 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.uval));
2174 break;
2175 default:
2176 error(
2177 @6, yyscanner,
2178 ("bad value of unsigned-long-typed constant "
2179 + data->currentName + "." + id));
2180 YYERROR;
2181 break;
2183 break;
2184 case unoidl::detail::SourceProviderType::TYPE_HYPER:
2185 switch ($6.type) {
2186 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2187 v = unoidl::ConstantValue($6.ival);
2188 break;
2189 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2190 if ($6.uval > SAL_MAX_INT64) {
2191 error(
2192 @6, yyscanner,
2193 ("out-of-range hyper-typed constant " + data->currentName
2194 + "." + id + " value " + OUString::number($6.uval)));
2195 YYERROR;
2197 v = unoidl::ConstantValue(static_cast<sal_Int64>($6.uval));
2198 break;
2199 default:
2200 error(
2201 @6, yyscanner,
2202 ("bad value of hyper-typed constant " + data->currentName
2203 + "." + id));
2204 YYERROR;
2205 break;
2207 break;
2208 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
2209 switch ($6.type) {
2210 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2211 if ($6.ival < 0) {
2212 error(
2213 @6, yyscanner,
2214 ("out-of-range unsigned-hyper-typed constant "
2215 + data->currentName + "." + id + " value "
2216 + OUString::number($6.ival)));
2217 YYERROR;
2219 v = unoidl::ConstantValue(static_cast<sal_uInt64>($6.ival));
2220 break;
2221 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2222 v = unoidl::ConstantValue($6.uval);
2223 break;
2224 default:
2225 error(
2226 @6, yyscanner,
2227 ("bad value of unsigned-hyper-typed constant "
2228 + data->currentName + "." + id));
2229 YYERROR;
2230 break;
2232 break;
2233 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
2234 switch ($6.type) {
2235 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2236 error(
2237 @6, yyscanner,
2238 ("bad boolean value of float-typed constant "
2239 + data->currentName + "." + id));
2240 YYERROR;
2241 break;
2242 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2243 v = unoidl::ConstantValue(static_cast<float>($6.ival));
2244 break;
2245 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2246 v = unoidl::ConstantValue(static_cast<float>($6.uval));
2247 break;
2248 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2249 v = unoidl::ConstantValue(static_cast<float>($6.fval));
2250 break;
2252 break;
2253 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
2254 switch ($6.type) {
2255 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2256 error(
2257 @6, yyscanner,
2258 ("bad boolean value of double-typed constant "
2259 + data->currentName + "." + id));
2260 YYERROR;
2261 break;
2262 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2263 v = unoidl::ConstantValue(static_cast<double>($6.ival));
2264 break;
2265 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2266 v = unoidl::ConstantValue(static_cast<double>($6.uval));
2267 break;
2268 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2269 v = unoidl::ConstantValue($6.fval);
2270 break;
2272 break;
2273 default:
2274 error(
2275 @3, yyscanner,
2276 "bad type for constant " + data->currentName + "." + id);
2277 YYERROR;
2278 break;
2280 pad->members.emplace_back(id, v, annotations($1));
2284 singleInterfaceBasedServiceDefn:
2285 deprecated_opt published_opt TOK_SERVICE identifier singleInheritance
2287 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2288 data->publishedContext = $2;
2289 convertToCurrentName(data, $4);
2290 OUString base(convertName($5));
2291 unoidl::detail::SourceProviderEntity const * p;
2292 if (findEntity(@5, yyscanner, data, false, &base, &p, nullptr, nullptr)
2293 == FOUND_ERROR)
2295 YYERROR;
2297 bool ifcBase = false;
2298 bool pubBase = false;
2299 if (p != nullptr) {
2300 switch (p->kind) {
2301 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2302 ifcBase = true;
2303 pubBase = false;
2304 break;
2305 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2306 ifcBase = true;
2307 pubBase = true;
2308 break;
2309 default:
2310 if (p->entity.is()
2311 && (p->entity->getSort()
2312 == unoidl::Entity::SORT_INTERFACE_TYPE))
2314 ifcBase = true;
2315 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2316 p->entity.get())->isPublished();
2318 break;
2321 if (!ifcBase) {
2322 error(
2323 @5, yyscanner,
2324 ("single-interface--based service " + data->currentName + " base "
2325 + base + " does not resolve to an interface type"));
2326 YYERROR;
2328 if ($2 && !pubBase) {
2329 error(
2330 @5, yyscanner,
2331 ("published single-interface--based service " + data->currentName
2332 + " base " + base + " is unpublished"));
2333 YYERROR;
2335 if (!data->entities.emplace(
2336 data->currentName,
2337 unoidl::detail::SourceProviderEntity(
2338 new unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad(
2339 $2, base))).
2340 second)
2342 error(@4, yyscanner, "multiple entities named " + data->currentName);
2343 YYERROR;
2346 ctors_opt ';'
2348 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2349 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2350 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad * pad =
2351 dynamic_cast<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad *>(
2352 ent->pad.get());
2353 assert(pad != nullptr);
2354 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor> ctors;
2355 if ($7) {
2356 for (const auto & i: pad->constructors) {
2357 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter> parms;
2358 for (auto & j: i.parameters) {
2359 parms.emplace_back(j.name, j.type.getName(), j.rest);
2361 ctors.push_back(
2362 unoidl::SingleInterfaceBasedServiceEntity::Constructor(
2363 i.name, parms, i.exceptions, i.annotations));
2365 } else {
2366 assert(pad->constructors.empty());
2367 ctors.push_back(
2368 unoidl::SingleInterfaceBasedServiceEntity::Constructor());
2370 ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
2371 pad->isPublished(), pad->base, ctors, annotations($1));
2372 ent->pad.clear();
2373 clearCurrentState(data);
2377 ctors_opt:
2378 '{' ctors '}' { $$ = true; }
2379 | /* empty */ { $$ = false; }
2382 ctors:
2383 ctors ctor
2384 | /* empty */
2387 ctor:
2388 deprecated_opt identifier
2390 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2391 OUString id(convertName($2));
2392 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2393 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2394 data));
2395 for (const auto & i: pad->constructors) {
2396 if (id == i.name) {
2397 error(
2398 @2, yyscanner,
2399 ("single-interface--based service " + data->currentName
2400 + " constructor " + id
2401 + " has same identifier as another constructor"));
2402 YYERROR;
2405 pad->constructors.push_back(
2406 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor(
2407 id, annotations($1)));
2409 '(' ctorParams_opt ')' exceptionSpec_opt ';'
2411 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2412 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2413 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2414 data));
2415 assert(!pad->constructors.empty());
2416 if ($7 != nullptr) {
2417 pad->constructors.back().exceptions = *$7;
2418 delete $7;
2420 for (auto i(pad->constructors.begin()); i != pad->constructors.end() - 1;
2421 ++i)
2423 if (i->parameters.size()
2424 == pad->constructors.back().parameters.size())
2426 bool same = true;
2427 for (auto
2428 j(i->parameters.begin()),
2429 k(pad->constructors.back().parameters.begin());
2430 j != i->parameters.end(); ++j, ++k)
2432 if (!j->type.equals(k->type) || j->rest != k->rest) {
2433 same = false;
2434 break;
2437 if (same) {
2438 error(
2439 @2, yyscanner,
2440 ("single-interface--based service " + data->currentName
2441 + " constructor " + pad->constructors.back().name
2442 + " has similar paramete list to constructor "
2443 + i->name));
2444 YYERROR;
2451 ctorParams_opt:
2452 ctorParams
2453 | /* empty */
2456 ctorParams:
2457 ctorParams ',' ctorParam
2458 | ctorParam
2461 ctorParam:
2462 '[' direction ']' type ellipsis_opt identifier
2464 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2465 unoidl::detail::SourceProviderType t(*$4);
2466 delete $4;
2467 OUString id(convertName($6));
2468 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2469 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2470 data));
2471 assert(!pad->constructors.empty());
2472 if ($2 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN) {
2473 error(
2474 @4, yyscanner,
2475 ("single-interface--based service " + data->currentName
2476 + " constructor " + pad->constructors.back().name + " parameter "
2477 + id + " direction must be [in]"));
2478 YYERROR;
2480 switch (t.type) {
2481 case unoidl::detail::SourceProviderType::TYPE_VOID:
2482 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2483 error(
2484 @4, yyscanner,
2485 ("illegal single-interface--based service " + data->currentName
2486 + " constructor " + pad->constructors.back().name + " parameter "
2487 + id + " type"));
2488 YYERROR;
2489 break;
2490 default:
2491 break;
2493 if ($5) {
2494 if (t.type != unoidl::detail::SourceProviderType::TYPE_ANY) {
2495 error(
2496 @4, yyscanner,
2497 ("illegal single-interface--based service "
2498 + data->currentName + " constructor "
2499 + pad->constructors.back().name + " rest parameter " + id
2500 + " non-any type"));
2501 YYERROR;
2503 if (!pad->constructors.back().parameters.empty()) {
2504 error(
2505 @5, yyscanner,
2506 ("single-interface--based service " + data->currentName
2507 + " constructor " + pad->constructors.back().name
2508 + " rest parameter " + id + " must be first parameter"));
2509 YYERROR;
2511 } else if (!pad->constructors.back().parameters.empty()
2512 && pad->constructors.back().parameters.back().rest)
2514 error(
2515 @1, yyscanner,
2516 ("single-interface--based service " + data->currentName
2517 + " constructor " + pad->constructors.back().name
2518 + " rest parameter must be last parameter"));
2519 YYERROR;
2521 for (const auto & i: pad->constructors.back().parameters) {
2522 if (id == i.name) {
2523 error(
2524 @6, yyscanner,
2525 ("single-interface--based service " + data->currentName
2526 + " constructor " + pad->constructors.back().name
2527 + " parameter " + id
2528 + " has same identifier as another parameter"));
2529 YYERROR;
2532 pad->constructors.back().parameters.push_back(
2533 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter(
2534 id, t, $5));
2538 ellipsis_opt:
2539 TOK_ELLIPSIS { $$ = true; }
2540 | /* empty */ { $$ = false; }
2542 accumulationBasedServiceDefn:
2543 deprecated_opt published_opt TOK_SERVICE identifier
2545 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2546 data->publishedContext = $2;
2547 convertToCurrentName(data, $4);
2548 if (!data->entities.emplace(
2549 data->currentName,
2550 unoidl::detail::SourceProviderEntity(
2551 new unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad(
2552 $2))).
2553 second)
2555 error(@4, yyscanner, "multiple entities named " + data->currentName);
2556 YYERROR;
2559 '{' serviceMembers '}' ';'
2561 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2562 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2563 unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad * pad =
2564 dynamic_cast<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad *>(
2565 ent->pad.get());
2566 assert(pad != nullptr);
2567 ent->entity = new unoidl::AccumulationBasedServiceEntity(
2568 pad->isPublished(), pad->directMandatoryBaseServices,
2569 pad->directOptionalBaseServices, pad->directMandatoryBaseInterfaces,
2570 pad->directOptionalBaseInterfaces, pad->directProperties,
2571 annotations($1));
2572 ent->pad.clear();
2573 clearCurrentState(data);
2577 serviceMembers:
2578 serviceMembers serviceMember
2579 | /* empty */
2582 serviceMember:
2583 serviceBase
2584 | serviceInterfaceBase
2585 | serviceProperty
2588 serviceBase:
2589 deprecated_opt flagSection_opt TOK_SERVICE name ';'
2591 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2592 OUString name(convertName($4));
2593 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2594 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2595 data));
2596 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2597 error(
2598 @2, yyscanner,
2599 "service base can only be flagged as [optional]");
2600 YYERROR;
2602 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2603 unoidl::detail::SourceProviderEntity const * p;
2604 if (findEntity(@4, yyscanner, data, false, &name, &p, nullptr, nullptr)
2605 == FOUND_ERROR)
2607 YYERROR;
2609 if (p == nullptr || !p->entity.is()
2610 || (p->entity->getSort()
2611 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2613 error(
2614 @4, yyscanner,
2615 ("accumulation-based service " + data->currentName
2616 + " direct base service " + name
2617 + " does not resolve to an accumulation-based service"));
2618 YYERROR;
2620 if (data->publishedContext
2621 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2622 p->entity.get())->isPublished())
2624 error(
2625 @4, yyscanner,
2626 ("published accumulation-based service " + data->currentName
2627 + " direct base service " + name + " is unpublished"));
2628 YYERROR;
2630 std::vector<unoidl::AnnotatedReference> & v(
2632 ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices);
2633 for (const auto & i: v) {
2634 if (name == i.name) {
2635 error(
2636 @4, yyscanner,
2637 ("accumulation-based service " + data->currentName
2638 + " duplicate direct base service " + name));
2639 YYERROR;
2642 v.emplace_back(name, annotations($1));
2646 serviceInterfaceBase:
2647 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
2649 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2650 OUString name(convertName($4));
2651 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2652 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2653 data));
2654 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2655 error(
2656 @2, yyscanner,
2657 "interface base can only be flagged as [optional]");
2658 YYERROR;
2660 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2661 unoidl::detail::SourceProviderEntity const * p;
2662 if (findEntity(@4, yyscanner, data, false, &name, &p, nullptr, nullptr)
2663 == FOUND_ERROR)
2665 YYERROR;
2667 bool ifcBase = false;
2668 bool pubBase = false;
2669 if (p != nullptr) {
2670 switch (p->kind) {
2671 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2672 ifcBase = true;
2673 pubBase = false;
2674 break;
2675 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2676 ifcBase = true;
2677 pubBase = true;
2678 break;
2679 default:
2680 if (p->entity.is()
2681 && (p->entity->getSort()
2682 == unoidl::Entity::SORT_INTERFACE_TYPE))
2684 ifcBase = true;
2685 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2686 p->entity.get())->isPublished();
2688 break;
2691 if (!ifcBase) {
2692 error(
2693 @4, yyscanner,
2694 ("accumulation-based service " + data->currentName
2695 + " direct base interface " + name
2696 + " does not resolve to an interface type"));
2697 YYERROR;
2699 if (data->publishedContext && !opt && !pubBase) {
2700 error(
2701 @4, yyscanner,
2702 ("published accumulation-based service " + data->currentName
2703 + " direct base interface " + name + " is unpublished"));
2704 YYERROR;
2706 std::vector<unoidl::AnnotatedReference> & v(
2708 ? pad->directOptionalBaseInterfaces
2709 : pad->directMandatoryBaseInterfaces);
2710 for (const auto & i: v) {
2711 if (name == i.name) {
2712 error(
2713 @4, yyscanner,
2714 ("accumulation-based service " + data->currentName
2715 + " duplicate direct base interface " + name));
2716 YYERROR;
2719 v.emplace_back(name, annotations($1));
2723 serviceProperty:
2724 deprecated_opt flagSection type identifier ';'
2726 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2727 unoidl::detail::SourceProviderType t(*$3);
2728 delete $3;
2729 OUString id(convertName($4));
2730 if (($2 & unoidl::detail::FLAG_PROPERTY) == 0) {
2731 error(
2732 @2, yyscanner,
2733 ("accumulation-based service property must be flagged as"
2734 " [property]"));
2735 YYERROR;
2737 if (($2
2738 & ~(unoidl::detail::FLAG_BOUND | unoidl::detail::FLAG_CONSTRAINED
2739 | unoidl::detail::FLAG_MAYBEAMBIGUOUS
2740 | unoidl::detail::FLAG_MAYBEDEFAULT
2741 | unoidl::detail::FLAG_MAYBEVOID | unoidl::detail::FLAG_OPTIONAL
2742 | unoidl::detail::FLAG_PROPERTY | unoidl::detail::FLAG_READONLY
2743 | unoidl::detail::FLAG_REMOVABLE
2744 | unoidl::detail::FLAG_TRANSIENT))
2745 != 0)
2747 error(
2748 @2, yyscanner,
2749 ("accumulation-based service property can only be flagged as"
2750 " [property, bound, constrained, maybeambiguous, maybedefault,"
2751 " maybevoid, optional, readonly, removable, transient]"));
2752 YYERROR;
2754 int att = 0;
2755 if (($2 & unoidl::detail::FLAG_BOUND) != 0) {
2756 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND;
2758 if (($2 & unoidl::detail::FLAG_CONSTRAINED) != 0) {
2759 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED;
2761 if (($2 & unoidl::detail::FLAG_MAYBEAMBIGUOUS) != 0) {
2762 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS;
2764 if (($2 & unoidl::detail::FLAG_MAYBEDEFAULT) != 0) {
2765 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT;
2767 if (($2 & unoidl::detail::FLAG_MAYBEVOID) != 0) {
2768 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID;
2770 if (($2 & unoidl::detail::FLAG_OPTIONAL) != 0) {
2771 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL;
2773 if (($2 & unoidl::detail::FLAG_READONLY) != 0) {
2774 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY;
2776 if (($2 & unoidl::detail::FLAG_REMOVABLE) != 0) {
2777 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE;
2779 if (($2 & unoidl::detail::FLAG_TRANSIENT) != 0) {
2780 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT;
2782 switch (t.type) {
2783 case unoidl::detail::SourceProviderType::TYPE_VOID:
2784 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2785 error(
2786 @3, yyscanner,
2787 ("illegal accumulation-based service " + data->currentName
2788 + " direct property " + id + " type"));
2789 YYERROR;
2790 break;
2791 default:
2792 break;
2794 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>
2795 pad(getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2796 data));
2797 for (const auto & i: pad->directProperties) {
2798 if (id == i.name) {
2799 error(
2800 @4, yyscanner,
2801 ("accumulation-based service " + data->currentName
2802 + " duplicate direct property " + id));
2803 YYERROR;
2806 pad->directProperties.emplace_back(
2807 id, t.getName(),
2808 unoidl::AccumulationBasedServiceEntity::Property::Attributes(att),
2809 annotations($1));
2813 interfaceBasedSingletonDefn:
2814 deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';'
2816 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2817 data->publishedContext = $2;
2818 OUString name(convertToFullName(data, $4));
2819 OUString base(convertName($5));
2820 unoidl::detail::SourceProviderEntity const * p;
2821 if (findEntity(@5, yyscanner, data, false, &base, &p, nullptr, nullptr)
2822 == FOUND_ERROR)
2824 YYERROR;
2826 bool ifcBase = false;
2827 bool pubBase = false;
2828 if (p != nullptr) {
2829 switch (p->kind) {
2830 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2831 ifcBase = true;
2832 pubBase = false;
2833 break;
2834 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2835 ifcBase = true;
2836 pubBase = true;
2837 break;
2838 default:
2839 if (p->entity.is()
2840 && (p->entity->getSort()
2841 == unoidl::Entity::SORT_INTERFACE_TYPE))
2843 ifcBase = true;
2844 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2845 p->entity.get())->isPublished();
2847 break;
2850 if (!ifcBase) {
2851 error(
2852 @5, yyscanner,
2853 ("interface-based singleton " + name + " base " + base
2854 + " does not resolve to an interface type"));
2855 YYERROR;
2857 if ($2 && !pubBase) {
2858 error(
2859 @5, yyscanner,
2860 ("published interface-based singleton " + name + " base " + base
2861 + " is unpublished"));
2862 YYERROR;
2864 if (!data->entities.emplace(
2865 name,
2866 unoidl::detail::SourceProviderEntity(
2867 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2868 new unoidl::InterfaceBasedSingletonEntity(
2869 $2, base, annotations($1)))).
2870 second)
2872 error(@4, yyscanner, "multiple entities named " + name);
2873 YYERROR;
2875 clearCurrentState(data);
2879 serviceBasedSingletonDefn:
2880 deprecated_opt published_opt TOK_SINGLETON identifier '{' TOK_SERVICE name ';'
2881 '}' ';'
2883 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2884 data->publishedContext = $2;
2885 OUString name(convertToFullName(data, $4));
2886 OUString base(convertName($7));
2887 unoidl::detail::SourceProviderEntity const * p;
2888 if (findEntity(@7, yyscanner, data, false, &base, &p, nullptr, nullptr)
2889 == FOUND_ERROR)
2891 YYERROR;
2893 if (p == nullptr
2894 || !p->entity.is()
2895 || (p->entity->getSort()
2896 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2898 error(
2899 @7, yyscanner,
2900 ("service-based singleton " + name + " base " + base
2901 + " does not resolve to an accumulation-based service"));
2902 YYERROR;
2904 if ($2
2905 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2906 p->entity.get())->isPublished())
2908 error(
2909 @7, yyscanner,
2910 ("published service-based singleton " + name + " base " + base
2911 + " is unpublished"));
2912 YYERROR;
2914 if (!data->entities.emplace(
2915 name,
2916 unoidl::detail::SourceProviderEntity(
2917 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2918 new unoidl::ServiceBasedSingletonEntity(
2919 $2, base, annotations($1)))).
2920 second)
2922 error(@4, yyscanner, "multiple entities named " + name);
2923 YYERROR;
2925 clearCurrentState(data);
2929 singleInheritance_opt:
2930 singleInheritance
2931 | /* empty */ { $$ = nullptr; }
2934 singleInheritance: ':' name { $$ = $2; }
2937 exceptionSpec_opt:
2938 exceptionSpec
2939 | /* empty */ { $$ = nullptr; }
2942 exceptionSpec: TOK_RAISES '(' exceptions ')' { $$ = $3; }
2945 exceptions:
2946 exceptions ',' name
2948 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2949 OUString name(convertName($3));
2950 unoidl::detail::SourceProviderEntity const * p;
2951 if (findEntity(@3, yyscanner, data, false, &name, &p, nullptr, nullptr)
2952 == FOUND_ERROR)
2954 delete $1; /* see commented-out %destructor above */
2955 YYERROR;
2957 if (p == nullptr
2958 || !p->entity.is()
2959 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
2961 delete $1; /* see commented-out %destructor above */
2962 error(
2963 @3, yyscanner,
2964 ("exception " + name + " does not resolve to an exception type"));
2965 YYERROR;
2967 if (data->publishedContext
2968 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
2969 ->isPublished()))
2971 delete $1; /* see commented-out %destructor above */
2972 error(
2973 @3, yyscanner,
2974 ("unpublished exception " + name + " used in published context"));
2975 YYERROR;
2977 if (std::find($1->begin(), $1->end(), name) != $1->end()) {
2978 delete $1; /* see commented-out %destructor above */
2979 error(
2980 @3, yyscanner, ("exception " + name + " listed more than once"));
2981 YYERROR;
2983 $1->push_back(name);
2984 $$ = $1;
2986 | name
2988 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2989 OUString name(convertName($1));
2990 unoidl::detail::SourceProviderEntity const * p;
2991 if (findEntity(@1, yyscanner, data, false, &name, &p, nullptr, nullptr)
2992 == FOUND_ERROR)
2994 YYERROR;
2996 if (p == nullptr
2997 || !p->entity.is()
2998 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
3000 error(
3001 @1, yyscanner,
3002 ("exception " + name + " does not resolve to an exception type"));
3003 YYERROR;
3005 if (data->publishedContext
3006 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
3007 ->isPublished()))
3009 error(
3010 @1, yyscanner,
3011 ("unpublished exception " + name + " used in published context"));
3012 YYERROR;
3014 $$ = new std::vector<OUString>; $$->push_back(name);
3018 interfaceDecl:
3019 deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';'
3021 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3022 data->publishedContext = $2;
3023 OUString name(convertToFullName(data, $4));
3024 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
3025 data->entities.emplace(
3026 name,
3027 unoidl::detail::SourceProviderEntity(
3029 ? unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL
3030 : unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL)));
3031 if (!p.second) {
3032 switch (p.first->second.kind) {
3033 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3034 if ($2) {
3035 p.first->second.kind
3036 = unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL;
3038 break;
3039 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3040 break;
3041 default:
3042 assert(p.first->second.entity.is());
3043 if (p.first->second.entity->getSort()
3044 != unoidl::Entity::SORT_INTERFACE_TYPE)
3046 error(
3047 @4, yyscanner,
3048 "multiple entities named " + data->currentName);
3049 YYERROR;
3051 if ($2
3052 && !static_cast<unoidl::InterfaceTypeEntity *>(
3053 p.first->second.entity.get())->isPublished())
3055 error(
3056 @4, yyscanner,
3057 ("published interface type declaration "
3058 + data->currentName + " has been defined unpublished"));
3059 YYERROR;
3063 clearCurrentState(data);
3067 published_opt:
3068 TOK_PUBLISHED { $$ = true; }
3069 | /* empty */ { $$ = false; }
3072 flagSection_opt:
3073 flagSection
3074 | /* empty */ { $$ = unoidl::detail::SourceProviderFlags(0); }
3077 flagSection: '[' flags ']' { $$ = $2; }
3080 flags:
3081 flags ',' flag
3083 if (($1 & $3) != 0) {
3084 error(@3, yyscanner, "duplicate flag " + flagName($3));
3085 YYERROR;
3087 $$ = unoidl::detail::SourceProviderFlags($1 | $3);
3089 | flag
3092 flag:
3093 TOK_ATTRIBUTE { $$ = unoidl::detail::FLAG_ATTRIBUTE; }
3094 | TOK_BOUND { $$ = unoidl::detail::FLAG_BOUND; }
3095 | TOK_CONSTRAINED { $$ = unoidl::detail::FLAG_CONSTRAINED; }
3096 | TOK_MAYBEAMBIGUOUS { $$ = unoidl::detail::FLAG_MAYBEAMBIGUOUS; }
3097 | TOK_MAYBEDEFAULT { $$ = unoidl::detail::FLAG_MAYBEDEFAULT; }
3098 | TOK_MAYBEVOID { $$ = unoidl::detail::FLAG_MAYBEVOID; }
3099 | TOK_OPTIONAL { $$ = unoidl::detail::FLAG_OPTIONAL; }
3100 | TOK_PROPERTY { $$ = unoidl::detail::FLAG_PROPERTY; }
3101 | TOK_READONLY { $$ = unoidl::detail::FLAG_READONLY; }
3102 | TOK_REMOVABLE { $$ = unoidl::detail::FLAG_REMOVABLE; }
3103 | TOK_TRANSIENT { $$ = unoidl::detail::FLAG_TRANSIENT; }
3106 expr: orExpr
3109 orExpr:
3110 orExpr '|' xorExpr
3112 if (!coerce(@1, yyscanner, &$1, &$3)) {
3113 YYERROR;
3115 switch ($1.type) {
3116 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3117 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival | $3.ival);
3118 break;
3119 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3120 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval | $3.uval);
3121 break;
3122 default:
3123 error(@1, yyscanner, "arguments of non-integer type to \"|\"");
3124 YYERROR;
3125 break;
3128 | xorExpr
3131 xorExpr:
3132 xorExpr '^' andExpr
3134 if (!coerce(@1, yyscanner, &$1, &$3)) {
3135 YYERROR;
3137 switch ($1.type) {
3138 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3139 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival ^ $3.ival);
3140 break;
3141 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3142 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval ^ $3.uval);
3143 break;
3144 default:
3145 error(@1, yyscanner, "arguments of non-integer type to \"^\"");
3146 YYERROR;
3147 break;
3150 | andExpr
3153 andExpr:
3154 andExpr '&' shiftExpr
3156 if (!coerce(@1, yyscanner, &$1, &$3)) {
3157 YYERROR;
3159 switch ($1.type) {
3160 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3161 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival & $3.ival);
3162 break;
3163 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3164 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval & $3.uval);
3165 break;
3166 default:
3167 error(@1, yyscanner, "arguments of non-integer type to \"&\"");
3168 YYERROR;
3169 break;
3172 | shiftExpr
3175 shiftExpr:
3176 shiftExpr TOK_LEFTSHIFT addExpr
3178 int n;
3179 switch ($3.type) {
3180 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3181 if ($3.ival < 0 || $3.ival > 63) {
3182 error(
3183 @3, yyscanner,
3184 ("out-of-range shift argument " + OUString::number($3.ival)
3185 + " to \"<<\" "));
3186 YYERROR;
3188 n = static_cast<int>($3.ival);
3189 break;
3190 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3191 if ($3.uval > 63) {
3192 error(
3193 @3, yyscanner,
3194 ("out-of-range shift argument " + OUString::number($3.uval)
3195 + " to \"<<\" "));
3196 YYERROR;
3198 n = static_cast<int>($3.uval);
3199 break;
3200 default:
3201 error(@3, yyscanner, "right argument of non-integer type to \"<<\"");
3202 YYERROR;
3204 switch ($1.type) {
3205 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3206 if ($1.ival < 0) {
3207 error(
3208 @1, yyscanner,
3209 ("cannot left-shift negative argument "
3210 + OUString::number($1.ival)));
3211 YYERROR;
3213 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival << n);
3214 break;
3215 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3216 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval << n);
3217 break;
3218 default:
3219 error(@1, yyscanner, "left argument of non-integer type to \"<<\"");
3220 YYERROR;
3221 break;
3224 | shiftExpr TOK_RIGHTSHIFT addExpr
3226 int n;
3227 switch ($3.type) {
3228 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3229 if ($3.ival < 0 || $3.ival > 63) {
3230 error(
3231 @3, yyscanner,
3232 ("out-of-range shift argument " + OUString::number($3.ival)
3233 + " to \">>\" "));
3234 YYERROR;
3236 n = static_cast<int>($3.ival);
3237 break;
3238 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3239 if ($3.uval > 63) {
3240 error(
3241 @3, yyscanner,
3242 ("out-of-range shift argument " + OUString::number($3.uval)
3243 + " to \">>\" "));
3244 YYERROR;
3246 n = static_cast<int>($3.uval);
3247 break;
3248 default:
3249 error(@3, yyscanner, "right argument of non-integer type to \">>\"");
3250 YYERROR;
3251 break;
3253 switch ($1.type) {
3254 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3255 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival >> n);
3256 break;
3257 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3258 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval >> n);
3259 break;
3260 default:
3261 error(@1, yyscanner, "left argument of non-integer type to \">>\"");
3262 YYERROR;
3263 break;
3266 | addExpr
3269 addExpr:
3270 addExpr '+' multExpr
3272 if (!coerce(@1, yyscanner, &$1, &$3)) {
3273 YYERROR;
3275 switch ($1.type) {
3276 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3277 error(@1, yyscanner, "arguments of boolean type to binary \"+\"");
3278 YYERROR;
3279 break;
3280 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3281 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival + $3.ival); //TODO: overflow
3282 break;
3283 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3284 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval + $3.uval); //TODO: overflow
3285 break;
3286 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3287 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval + $3.fval);
3288 break;
3291 | addExpr '-' multExpr
3293 if (!coerce(@1, yyscanner, &$1, &$3)) {
3294 YYERROR;
3296 switch ($1.type) {
3297 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3298 error(@1, yyscanner, "arguments of boolean type to binary \"-\"");
3299 YYERROR;
3300 break;
3301 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3302 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival - $3.ival); //TODO: overflow
3303 break;
3304 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3305 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval - $3.uval); //TODO: overflow
3306 break;
3307 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3308 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3309 break;
3312 | multExpr
3315 multExpr:
3316 multExpr '*' unaryExpr
3318 if (!coerce(@1, yyscanner, &$1, &$3)) {
3319 YYERROR;
3321 switch ($1.type) {
3322 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3323 error(@1, yyscanner, "arguments of boolean type to \"*\"");
3324 YYERROR;
3325 break;
3326 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3327 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival * $3.ival); //TODO: overflow
3328 break;
3329 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3330 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval * $3.uval); //TODO: overflow
3331 break;
3332 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3333 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval * $3.fval);
3334 break;
3337 | multExpr '/' unaryExpr
3339 if (!coerce(@1, yyscanner, &$1, &$3)) {
3340 YYERROR;
3342 switch ($1.type) {
3343 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3344 error(@1, yyscanner, "arguments of boolean type to \"/\"");
3345 YYERROR;
3346 break;
3347 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3348 if ($3.ival == 0) {
3349 error(@3, yyscanner, "cannot divide by zero");
3350 YYERROR;
3352 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival / $3.ival);
3353 break;
3354 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3355 if ($3.uval == 0) {
3356 error(@3, yyscanner, "cannot divide by zero");
3357 YYERROR;
3359 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval / $3.uval);
3360 break;
3361 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3362 if ($3.fval == 0) {
3363 error(@3, yyscanner, "cannot divide by zero");
3364 YYERROR;
3366 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3367 break;
3370 | multExpr '%' unaryExpr
3372 if (!coerce(@1, yyscanner, &$1, &$3)) {
3373 YYERROR;
3375 switch ($1.type) {
3376 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3377 if ($3.ival == 0) {
3378 error(@3, yyscanner, "cannot divide by zero");
3379 YYERROR;
3381 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival % $3.ival);
3382 break;
3383 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3384 if ($3.uval == 0) {
3385 error(@3, yyscanner, "cannot divide by zero");
3386 YYERROR;
3388 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval % $3.uval);
3389 break;
3390 default:
3391 error(@1, yyscanner, "arguments of non-integer type to \"%\"");
3392 YYERROR;
3393 break;
3396 | unaryExpr
3399 unaryExpr:
3400 '+' primaryExpr
3402 if ($2.type == unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
3403 error(@2, yyscanner, "argument of boolean type to unary \"+\"");
3404 YYERROR;
3406 $$ = $2;
3408 | '-' primaryExpr
3410 switch ($2.type) {
3411 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3412 error(@2, yyscanner, "argument of boolean type to unary \"-\"");
3413 YYERROR;
3414 break;
3415 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3416 if ($2.ival == SAL_MIN_INT64) {
3417 error(@2, yyscanner, "cannot negate -2^63");
3418 YYERROR;
3420 $$ = unoidl::detail::SourceProviderExpr::Int(-$2.ival);
3421 break;
3422 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3423 if ($2.uval == SAL_CONST_UINT64(0x8000000000000000)) {
3424 $$ = unoidl::detail::SourceProviderExpr::Int(SAL_MIN_INT64);
3425 } else {
3426 if ($2.uval > SAL_MAX_INT64) {
3427 error(
3428 @2, yyscanner,
3429 ("cannot negate out-of-range value "
3430 + OUString::number($2.uval)));
3431 YYERROR;
3433 $$ = unoidl::detail::SourceProviderExpr::Int(
3434 -static_cast<sal_Int64>($2.uval));
3436 break;
3437 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3438 $$ = unoidl::detail::SourceProviderExpr::Float(-$2.fval);
3439 break;
3442 | '~' primaryExpr
3444 switch ($2.type) {
3445 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3446 $$ = unoidl::detail::SourceProviderExpr::Int(~$2.ival);
3447 break;
3448 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3449 $$ = unoidl::detail::SourceProviderExpr::Uint(~$2.uval);
3450 break;
3451 default:
3452 error(@2, yyscanner, "argument of non-integer type to \"~\"");
3453 YYERROR;
3454 break;
3457 | primaryExpr
3460 primaryExpr:
3461 '(' expr ')' { $$ = $2; }
3462 | TOK_FALSE { $$ = unoidl::detail::SourceProviderExpr::Bool(false); }
3463 | TOK_TRUE { $$ = unoidl::detail::SourceProviderExpr::Bool(true); }
3464 | TOK_INTEGER { $$ = unoidl::detail::SourceProviderExpr::Uint($1); }
3465 | TOK_FLOATING { $$ = unoidl::detail::SourceProviderExpr::Float($1); }
3466 | name
3468 OUString name(convertName($1));
3469 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3470 unoidl::ConstantValue v(false); // dummy value
3471 bool found = false;
3472 bool unpub = false;
3473 sal_Int32 i = name.lastIndexOf('.');
3474 if (i == -1) {
3475 rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad(
3476 getCurrentEntity(data)->pad);
3477 unoidl::detail::SourceProviderEnumTypeEntityPad * p1 = dynamic_cast<
3478 unoidl::detail::SourceProviderEnumTypeEntityPad *>(pad.get());
3479 if (p1 != nullptr) {
3480 for (const auto & j: p1->members) {
3481 if (j.name == name) {
3482 v = unoidl::ConstantValue(j.value);
3483 found = true;
3484 break;
3487 } else {
3488 unoidl::detail::SourceProviderConstantGroupEntityPad * p2
3489 = dynamic_cast<
3490 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3491 pad.get());
3492 if (p2 != nullptr) {
3493 for (const auto & j: p2->members) {
3494 if (j.name == name) {
3495 v = j.value;
3496 found = true;
3497 break;
3502 } else {
3503 OUString scope(name.copy(0, i));
3504 unoidl::detail::SourceProviderEntity const * ent;
3505 if (findEntity(
3506 @1, yyscanner, data, false, &scope, &ent, nullptr, nullptr)
3507 == FOUND_ERROR)
3509 YYERROR;
3511 if (ent != nullptr) {
3512 OUString id(name.copy(i + 1));
3513 // No need to check for enum members here, as they cannot be
3514 // referenced in expressions by qualified name (TODO: is that true?):
3515 if (ent->entity.is()) {
3516 if (ent->entity->getSort()
3517 == unoidl::Entity::SORT_CONSTANT_GROUP)
3519 std::vector<unoidl::ConstantGroupEntity::Member> const &
3520 mems(
3521 static_cast<unoidl::ConstantGroupEntity *>(
3522 ent->entity.get())->
3523 getMembers());
3524 for (auto & j: mems) {
3525 if (j.name == id) {
3526 v = j.value;
3527 found = true;
3528 unpub
3529 = !static_cast<unoidl::ConstantGroupEntity *>(
3530 ent->entity.get())->isPublished();
3531 break;
3535 } else if (ent->pad.is()) {
3536 unoidl::detail::SourceProviderConstantGroupEntityPad * pad
3537 = dynamic_cast<
3538 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3539 ent->pad.get());
3540 if (pad != nullptr) {
3541 for (const auto & j: pad->members) {
3542 if (j.name == id) {
3543 v = j.value;
3544 found = true;
3545 unpub = !ent->pad->isPublished();
3546 break;
3553 if (!found) {
3554 error(
3555 @1, yyscanner,
3556 (name
3557 + (" does not resolve to neither a constant nor an unqualified"
3558 " enum member")));
3559 YYERROR;
3561 if (data->publishedContext && unpub) {
3562 error(
3563 @1, yyscanner,
3564 "unpublished value " + name + " used in published context");
3565 YYERROR;
3567 switch (v.type) {
3568 case unoidl::ConstantValue::TYPE_BOOLEAN:
3569 $$ = unoidl::detail::SourceProviderExpr::Bool(v.booleanValue);
3570 break;
3571 case unoidl::ConstantValue::TYPE_BYTE:
3572 $$ = unoidl::detail::SourceProviderExpr::Int(v.byteValue);
3573 break;
3574 case unoidl::ConstantValue::TYPE_SHORT:
3575 $$ = unoidl::detail::SourceProviderExpr::Int(v.shortValue);
3576 break;
3577 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
3578 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedShortValue);
3579 break;
3580 case unoidl::ConstantValue::TYPE_LONG:
3581 $$ = unoidl::detail::SourceProviderExpr::Int(v.longValue);
3582 break;
3583 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
3584 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedLongValue);
3585 break;
3586 case unoidl::ConstantValue::TYPE_HYPER:
3587 $$ = unoidl::detail::SourceProviderExpr::Int(v.hyperValue);
3588 break;
3589 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
3590 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedHyperValue);
3591 break;
3592 case unoidl::ConstantValue::TYPE_FLOAT:
3593 $$ = unoidl::detail::SourceProviderExpr::Float(v.floatValue);
3594 break;
3595 case unoidl::ConstantValue::TYPE_DOUBLE:
3596 $$ = unoidl::detail::SourceProviderExpr::Float(v.doubleValue);
3597 break;
3602 typeArguments:
3603 typeArguments ',' type
3605 unoidl::detail::SourceProviderType t(*$3);
3606 delete $3;
3607 if (!checkTypeArgument(@3, yyscanner, t)) {
3608 delete $1; /* see commented-out %destructor above */
3609 YYERROR;
3611 $1->push_back(t);
3612 $$ = $1;
3614 | type
3616 unoidl::detail::SourceProviderType t(*$1);
3617 delete $1;
3618 if (!checkTypeArgument(@1, yyscanner, t)) {
3619 YYERROR;
3621 $$ = new std::vector<unoidl::detail::SourceProviderType>;
3622 $$->push_back(t);
3626 type:
3627 TOK_VOID
3629 $$ = new unoidl::detail::SourceProviderType(
3630 unoidl::detail::SourceProviderType::TYPE_VOID);
3632 | TOK_BOOLEAN
3634 $$ = new unoidl::detail::SourceProviderType(
3635 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
3637 | TOK_BYTE
3639 $$ = new unoidl::detail::SourceProviderType(
3640 unoidl::detail::SourceProviderType::TYPE_BYTE);
3642 | TOK_SHORT
3644 $$ = new unoidl::detail::SourceProviderType(
3645 unoidl::detail::SourceProviderType::TYPE_SHORT);
3647 | TOK_UNSIGNED TOK_SHORT
3649 $$ = new unoidl::detail::SourceProviderType(
3650 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
3652 | TOK_LONG
3654 $$ = new unoidl::detail::SourceProviderType(
3655 unoidl::detail::SourceProviderType::TYPE_LONG);
3657 | TOK_UNSIGNED TOK_LONG
3659 $$ = new unoidl::detail::SourceProviderType(
3660 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
3662 | TOK_HYPER
3664 $$ = new unoidl::detail::SourceProviderType(
3665 unoidl::detail::SourceProviderType::TYPE_HYPER);
3667 | TOK_UNSIGNED TOK_HYPER
3669 $$ = new unoidl::detail::SourceProviderType(
3670 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
3672 | TOK_FLOAT
3674 $$ = new unoidl::detail::SourceProviderType(
3675 unoidl::detail::SourceProviderType::TYPE_FLOAT);
3677 | TOK_DOUBLE
3679 $$ = new unoidl::detail::SourceProviderType(
3680 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
3682 | TOK_CHAR
3684 $$ = new unoidl::detail::SourceProviderType(
3685 unoidl::detail::SourceProviderType::TYPE_CHAR);
3687 | TOK_STRING
3689 $$ = new unoidl::detail::SourceProviderType(
3690 unoidl::detail::SourceProviderType::TYPE_STRING);
3692 | TOK_TYPE
3694 $$ = new unoidl::detail::SourceProviderType(
3695 unoidl::detail::SourceProviderType::TYPE_TYPE);
3697 | TOK_ANY
3699 $$ = new unoidl::detail::SourceProviderType(
3700 unoidl::detail::SourceProviderType::TYPE_ANY);
3702 | TOK_SEQUENCE '<' type '>'
3704 switch ($3->type) {
3705 case unoidl::detail::SourceProviderType::TYPE_VOID:
3706 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
3707 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
3708 error(@3, yyscanner, "illegal sequence type component type");
3709 YYERROR;
3710 break;
3711 default:
3712 break;
3714 $$ = new unoidl::detail::SourceProviderType($3);
3715 delete $3;
3717 | name
3719 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3720 OUString name(convertName($1));
3721 bool done = false;
3722 if (name.indexOf('.') == -1 && !data->currentName.isEmpty()) {
3723 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
3724 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
3725 pad = dynamic_cast<
3726 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3727 ent->pad.get());
3728 if (pad != nullptr
3729 && (std::find(
3730 pad->typeParameters.begin(), pad->typeParameters.end(),
3731 name)
3732 != pad->typeParameters.end()))
3734 $$ = new unoidl::detail::SourceProviderType(name);
3735 done = true;
3738 if (!done) {
3739 unoidl::detail::SourceProviderEntity const * ent;
3740 unoidl::detail::SourceProviderType t;
3741 switch (findEntity(
3742 @1, yyscanner, data, false, &name, &ent, nullptr, &t))
3744 case FOUND_ERROR:
3745 YYERROR;
3746 break;
3747 case FOUND_TYPE:
3748 $$ = new unoidl::detail::SourceProviderType(t);
3749 break;
3750 case FOUND_ENTITY:
3751 if (ent == nullptr) {
3752 error(@1, yyscanner, "unknown entity " + name);
3753 YYERROR;
3755 bool ok = false;
3756 switch (ent->kind) {
3757 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3758 if (ent->pad.is()) {
3759 if (data->publishedContext && !ent->pad->isPublished()) {
3760 error(
3761 @1, yyscanner,
3762 ("unpublished entity " + name
3763 + " used in published context"));
3764 YYERROR;
3766 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
3767 ent->pad.get())
3768 != nullptr)
3770 $$ = new unoidl::detail::SourceProviderType(
3771 unoidl::detail::SourceProviderType::TYPE_ENUM,
3772 name, ent);
3773 ok = true;
3774 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
3775 ent->pad.get())
3776 != nullptr)
3778 $$ = new unoidl::detail::SourceProviderType(
3779 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3780 name, ent);
3781 ok = true;
3782 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3783 ent->pad.get())
3784 != nullptr)
3786 error(
3787 @1, yyscanner,
3788 (("recursive reference to polymorphic struct type"
3789 " template ")
3790 + name));
3791 YYERROR;
3792 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
3793 ent->pad.get())
3794 != nullptr)
3796 $$ = new unoidl::detail::SourceProviderType(
3797 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3798 name, ent);
3799 ok = true;
3800 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
3801 ent->pad.get())
3802 != nullptr)
3804 $$ = new unoidl::detail::SourceProviderType(
3805 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3806 name, ent);
3807 ok = true;
3809 break;
3811 assert(ent->entity.is());
3812 [[fallthrough]];
3813 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3814 if (data->publishedContext
3815 && ent->entity->getSort() != unoidl::Entity::SORT_MODULE
3816 && !static_cast<unoidl::PublishableEntity *>(
3817 ent->entity.get())->isPublished())
3819 error(
3820 @1, yyscanner,
3821 ("unpublished entity " + name
3822 + " used in published context"));
3823 YYERROR;
3825 switch (ent->entity->getSort()) {
3826 case unoidl::Entity::SORT_ENUM_TYPE:
3827 $$ = new unoidl::detail::SourceProviderType(
3828 unoidl::detail::SourceProviderType::TYPE_ENUM, name,
3829 ent);
3830 ok = true;
3831 break;
3832 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
3833 $$ = new unoidl::detail::SourceProviderType(
3834 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3835 name, ent);
3836 ok = true;
3837 break;
3838 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
3839 error(
3840 @1, yyscanner,
3841 ("polymorphic struct type template " + name
3842 + " without type arguments"));
3843 YYERROR;
3844 break;
3845 case unoidl::Entity::SORT_EXCEPTION_TYPE:
3846 $$ = new unoidl::detail::SourceProviderType(
3847 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3848 name, ent);
3849 ok = true;
3850 break;
3851 case unoidl::Entity::SORT_INTERFACE_TYPE:
3852 $$ = new unoidl::detail::SourceProviderType(
3853 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3854 name, ent);
3855 ok = true;
3856 break;
3857 case unoidl::Entity::SORT_TYPEDEF:
3858 assert(false && "this cannot happen");
3859 [[fallthrough]];
3860 default:
3861 break;
3863 break;
3864 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3865 if (data->publishedContext) {
3866 error(
3867 @1, yyscanner,
3868 ("unpublished entity " + name
3869 + " used in published context"));
3870 YYERROR;
3872 [[fallthrough]];
3873 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3874 $$ = new unoidl::detail::SourceProviderType(
3875 unoidl::detail::SourceProviderType::TYPE_INTERFACE, name,
3876 ent);
3877 ok = true;
3878 break;
3879 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3880 assert(false && "this cannot happen");
3882 if (!ok) {
3883 error(@1, yyscanner, "non-type entity " + name);
3884 YYERROR;
3886 break;
3890 | name '<' typeArguments '>'
3892 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3893 OUString name(convertName($1));
3894 std::vector<unoidl::detail::SourceProviderType> args(*$3);
3895 delete $3;
3896 unoidl::detail::SourceProviderEntity const * ent;
3897 if (findEntity(@1, yyscanner, data, false, &name, &ent, nullptr, nullptr)
3898 == FOUND_ERROR)
3900 YYERROR;
3902 if (ent == nullptr) {
3903 error(@1, yyscanner, "unknown entity " + name);
3904 YYERROR;
3906 bool ok = false;
3907 switch (ent->kind) {
3908 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3909 if (ent->pad.is()) {
3910 if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3911 ent->pad.get())
3912 != nullptr)
3914 error(
3915 @1, yyscanner,
3916 (("recursive reference to polymorphic struct type"
3917 " template ")
3918 + name));
3919 YYERROR;
3921 break;
3923 assert(ent->entity.is());
3924 [[fallthrough]];
3925 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3926 if (ent->entity->getSort()
3927 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
3929 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> e(
3930 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
3931 ent->entity.get()));
3932 if (args.size() != e->getTypeParameters().size()) {
3933 error(
3934 @1, yyscanner,
3935 ("bad number of polymorphic struct type template " + name
3936 + " type arguments"));
3937 YYERROR;
3939 if (data->publishedContext && !e->isPublished()) {
3940 error(
3941 @1, yyscanner,
3942 ("unpublished polymorphic struct type template " + name
3943 + " used in published context"));
3944 YYERROR;
3946 $$ = new unoidl::detail::SourceProviderType(name, ent, args);
3947 ok = true;
3949 break;
3950 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3951 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3952 break;
3953 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3954 assert(false && "this cannot happen");
3956 if (!ok) {
3957 error(@1, yyscanner, "non-type entity " + name);
3958 YYERROR;
3963 name:
3964 name TOK_COLONS identifier { *$1 += "." + *$3; delete $3; $$ = $1; }
3965 | TOK_COLONS identifier { *$2 = "." + *$2; $$ = $2; }
3966 | identifier
3969 identifier:
3970 TOK_IDENTIFIER
3971 | TOK_GET { $$ = new OString("get"); }
3972 | TOK_PUBLISHED { $$ = new OString("published"); }
3973 | TOK_SET { $$ = new OString("set"); }
3976 deprecated_opt:
3977 TOK_DEPRECATED { $$ = true; }
3978 | /* empty */ { $$ = false; }
3983 namespace unoidl { namespace detail {
3985 OUString SourceProviderType::getName() const {
3986 if (!typedefName.isEmpty()) {
3987 return typedefName;
3989 switch (type) {
3990 case unoidl::detail::SourceProviderType::TYPE_VOID:
3991 return "void";
3992 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
3993 return "boolean";
3994 case unoidl::detail::SourceProviderType::TYPE_BYTE:
3995 return "byte";
3996 case unoidl::detail::SourceProviderType::TYPE_SHORT:
3997 return "short";
3998 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
3999 return "unsigned short";
4000 case unoidl::detail::SourceProviderType::TYPE_LONG:
4001 return "long";
4002 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
4003 return "unsigned long";
4004 case unoidl::detail::SourceProviderType::TYPE_HYPER:
4005 return "hyper";
4006 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
4007 return "unsigned hyper";
4008 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
4009 return "float";
4010 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
4011 return "double";
4012 case unoidl::detail::SourceProviderType::TYPE_CHAR:
4013 return "char";
4014 case unoidl::detail::SourceProviderType::TYPE_STRING:
4015 return "string";
4016 case unoidl::detail::SourceProviderType::TYPE_TYPE:
4017 return "type";
4018 case unoidl::detail::SourceProviderType::TYPE_ANY:
4019 return "any";
4020 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
4021 assert(subtypes.size() == 1);
4022 return "[]" + subtypes.front().getName();
4023 case unoidl::detail::SourceProviderType::TYPE_ENUM:
4024 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
4025 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
4026 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
4027 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
4028 return name;
4029 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
4031 OUStringBuffer n(512);
4032 n.append(name + "<");
4033 for (auto i(subtypes.begin()); i != subtypes.end(); ++i) {
4034 if (i != subtypes.begin()) {
4035 n.append(",");
4037 n.append(i->getName());
4039 return n.append(">").makeStringAndClear();
4041 default:
4042 assert(false && "this cannot happen"); for (;;) { std::abort(); }
4046 bool SourceProviderType::equals(SourceProviderType const & other) const {
4047 if (type != other.type || name != other.name
4048 || subtypes.size() != other.subtypes.size())
4050 return false;
4052 for (auto i(subtypes.begin()), j(other.subtypes.begin());
4053 i != subtypes.end(); ++i, ++j)
4055 if (!i->equals(*j)) {
4056 return false;
4059 return true;
4062 bool SourceProviderInterfaceTypeEntityPad::addDirectBase(
4063 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4064 DirectBase const & base, bool optional)
4066 std::set<OUString> seen;
4067 if (!(checkBaseClashes(
4068 location, yyscanner, data, base.name, base.entity, true, optional,
4069 optional, &seen)
4070 && addBase(
4071 location, yyscanner, data, base.name, base.name, base.entity,
4072 true, optional)))
4074 return false;
4076 if (optional) {
4077 addOptionalBaseMembers(
4078 location, yyscanner, data, base.name, base.entity);
4080 (optional ? directOptionalBases : directMandatoryBases).push_back(base);
4081 return true;
4084 bool SourceProviderInterfaceTypeEntityPad::addDirectMember(
4085 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4086 OUString const & name)
4088 assert(data != nullptr);
4089 if (!checkMemberClashes(location, yyscanner, data, "", name, true)) {
4090 return false;
4092 allMembers.emplace(name, Member(data->currentName));
4093 return true;
4096 bool SourceProviderInterfaceTypeEntityPad::checkBaseClashes(
4097 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4098 OUString const & name,
4099 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4100 bool optional, bool outerOptional, std::set<OUString> * seen) const
4102 assert(data != nullptr);
4103 assert(entity.is());
4104 assert(seen != nullptr);
4105 if (direct || optional || seen->insert(name).second) {
4106 std::map<OUString, BaseKind>::const_iterator i(allBases.find(name));
4107 if (i != allBases.end()) {
4108 switch (i->second) {
4109 case BASE_INDIRECT_OPTIONAL:
4110 if (direct && optional) {
4111 error(
4112 location, yyscanner,
4113 ("interface type " + data->currentName
4114 + " duplicate base " + name));
4115 return false;
4117 break;
4118 case BASE_DIRECT_OPTIONAL:
4119 if (direct || !outerOptional) {
4120 error(
4121 location, yyscanner,
4122 ("interface type " + data->currentName
4123 + " duplicate base " + name));
4124 return false;
4126 return true;
4127 case BASE_INDIRECT_MANDATORY:
4128 if (direct) {
4129 error(
4130 location, yyscanner,
4131 ("interface type " + data->currentName
4132 + " duplicate base " + name));
4133 return false;
4135 return true;
4136 case BASE_DIRECT_MANDATORY:
4137 if (direct || (!optional && !outerOptional)) {
4138 error(
4139 location, yyscanner,
4140 ("interface type " + data->currentName
4141 + " duplicate base " + name));
4142 return false;
4144 return true;
4147 if (direct || !optional) {
4148 for (auto & j: entity->getDirectMandatoryBases()) {
4149 OUString n("." + j.name);
4150 unoidl::detail::SourceProviderEntity const * p;
4151 if (findEntity(
4152 location, yyscanner, data, true, &n, &p, nullptr,
4153 nullptr)
4154 == FOUND_ERROR)
4156 return false;
4158 if (p == nullptr || !p->entity.is()
4159 || (p->entity->getSort()
4160 != unoidl::Entity::SORT_INTERFACE_TYPE))
4162 error(
4163 location, yyscanner,
4164 ("inconsistent type manager: interface type "
4165 + data->currentName + " base " + n
4166 + " does not resolve to an existing interface type"));
4167 return false;
4169 if (!checkBaseClashes(
4170 location, yyscanner, data, n,
4171 static_cast<unoidl::InterfaceTypeEntity *>(
4172 p->entity.get()),
4173 false, false, outerOptional, seen))
4175 return false;
4178 for (auto & j: entity->getDirectOptionalBases()) {
4179 OUString n("." + j.name);
4180 unoidl::detail::SourceProviderEntity const * p;
4181 if (findEntity(
4182 location, yyscanner, data, true, &n, &p, nullptr,
4183 nullptr)
4184 == FOUND_ERROR)
4186 return false;
4188 if (p == nullptr || !p->entity.is()
4189 || (p->entity->getSort()
4190 != unoidl::Entity::SORT_INTERFACE_TYPE))
4192 error(
4193 location, yyscanner,
4194 ("inconsistent type manager: interface type "
4195 + data->currentName + " base " + n
4196 + " does not resolve to an existing interface type"));
4197 return false;
4199 if (!checkBaseClashes(
4200 location, yyscanner, data, n,
4201 static_cast<unoidl::InterfaceTypeEntity *>(
4202 p->entity.get()),
4203 false, true, outerOptional, seen))
4205 return false;
4208 for (auto & j: entity->getDirectAttributes()) {
4209 if (!checkMemberClashes(
4210 location, yyscanner, data, name, j.name,
4211 !outerOptional))
4213 return false;
4216 for (auto & j: entity->getDirectMethods()) {
4217 if (!checkMemberClashes(
4218 location, yyscanner, data, name, j.name,
4219 !outerOptional))
4221 return false;
4226 return true;
4229 bool SourceProviderInterfaceTypeEntityPad::checkMemberClashes(
4230 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4231 OUString const & interfaceName, OUString const & memberName,
4232 bool checkOptional) const
4234 std::map<OUString, Member>::const_iterator i(allMembers.find(memberName));
4235 if (i != allMembers.end()) {
4236 if (!i->second.mandatory.isEmpty()) {
4237 // For a direct member, interfaceName will be empty, so this will
4238 // catch two direct members with the same name:
4239 if (i->second.mandatory != interfaceName) {
4240 error(
4241 location, yyscanner,
4242 ("interface type " + data->currentName
4243 + " duplicate member " + memberName));
4244 return false;
4246 } else if (checkOptional) {
4247 for (auto & j: i->second.optional) {
4248 if (j != interfaceName) {
4249 error(
4250 location, yyscanner,
4251 ("interface type " + data->currentName
4252 + " duplicate member " + memberName));
4253 return false;
4258 return true;
4261 bool SourceProviderInterfaceTypeEntityPad::addBase(
4262 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4263 OUString const & directBaseName, OUString const & name,
4264 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4265 bool optional)
4267 assert(data != nullptr);
4268 assert(entity.is());
4269 BaseKind kind = optional
4270 ? direct ? BASE_DIRECT_OPTIONAL : BASE_INDIRECT_OPTIONAL
4271 : direct ? BASE_DIRECT_MANDATORY : BASE_INDIRECT_MANDATORY;
4272 std::pair<std::map<OUString, BaseKind>::iterator, bool> p(
4273 allBases.emplace(name, kind));
4274 bool seen = !p.second && p.first->second >= BASE_INDIRECT_MANDATORY;
4275 if (!p.second && kind > p.first->second) {
4276 p.first->second = kind;
4278 if (!optional && !seen) {
4279 for (auto & i: entity->getDirectMandatoryBases()) {
4280 OUString n("." + i.name);
4281 unoidl::detail::SourceProviderEntity const * q;
4282 if (findEntity(
4283 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4284 == FOUND_ERROR)
4286 return false;
4288 if (q == nullptr || !q->entity.is()
4289 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4291 error(
4292 location, yyscanner,
4293 ("inconsistent type manager: interface type "
4294 + data->currentName + " base " + n
4295 + " does not resolve to an existing interface type"));
4296 return false;
4298 if (!addBase(
4299 location, yyscanner, data, directBaseName, n,
4300 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4301 false, false))
4303 return false;
4306 for (auto & i: entity->getDirectOptionalBases())
4308 OUString n("." + i.name);
4309 unoidl::detail::SourceProviderEntity const * q;
4310 if (findEntity(
4311 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4312 == FOUND_ERROR)
4314 return false;
4316 if (q == nullptr || !q->entity.is()
4317 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4319 error(
4320 location, yyscanner,
4321 ("inconsistent type manager: interface type "
4322 + data->currentName + " base " + n
4323 + " does not resolve to an existing interface type"));
4324 return false;
4326 if (!addBase(
4327 location, yyscanner, data, directBaseName, n,
4328 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4329 false, true))
4331 return false;
4334 for (auto & i: entity->getDirectAttributes()) {
4335 allMembers.emplace(i.name, Member(name));
4337 for (auto & i: entity->getDirectMethods()) {
4338 allMembers.emplace(i.name, Member(name));
4341 return true;
4344 bool SourceProviderInterfaceTypeEntityPad::addOptionalBaseMembers(
4345 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4346 OUString const & name,
4347 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity)
4349 assert(entity.is());
4350 for (auto & i: entity->getDirectMandatoryBases()) {
4351 OUString n("." + i.name);
4352 unoidl::detail::SourceProviderEntity const * p;
4353 if (findEntity(
4354 location, yyscanner, data, true, &n, &p, nullptr, nullptr)
4355 == FOUND_ERROR)
4357 return false;
4359 if (p == nullptr || !p->entity.is()
4360 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4362 error(
4363 location, yyscanner,
4364 ("inconsistent type manager: interface type "
4365 + data->currentName + " base " + n
4366 + " does not resolve to an existing interface type"));
4367 return false;
4369 if (!addOptionalBaseMembers(
4370 location, yyscanner, data, n,
4371 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())))
4373 return false;
4376 for (auto & i: entity->getDirectAttributes()) {
4377 Member & m(
4378 allMembers.emplace(i.name, Member(""))
4379 .first->second);
4380 if (m.mandatory.isEmpty()) {
4381 m.optional.insert(name);
4384 for (auto & i: entity->getDirectMethods()) {
4385 Member & m(
4386 allMembers.emplace(i.name, Member(""))
4387 .first->second);
4388 if (m.mandatory.isEmpty()) {
4389 m.optional.insert(name);
4392 return true;
4395 bool parse(OUString const & uri, SourceProviderScannerData * data) {
4396 assert(data != nullptr);
4397 oslFileHandle handle;
4398 oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
4399 switch (e) {
4400 case osl_File_E_None:
4401 break;
4402 case osl_File_E_NOENT:
4403 return false;
4404 default:
4405 throw FileFormatException(uri, "cannot open: " + OUString::number(e));
4407 sal_uInt64 size;
4408 e = osl_getFileSize(handle, &size);
4409 if (e != osl_File_E_None) {
4410 oslFileError e2 = osl_closeFile(handle);
4411 SAL_WARN_IF(
4412 e2 != osl_File_E_None, "unoidl",
4413 "cannot close " << uri << ": " << +e2);
4414 throw FileFormatException(
4415 uri, "cannot get size: " + OUString::number(e));
4417 void * address;
4418 e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
4419 if (e != osl_File_E_None) {
4420 oslFileError e2 = osl_closeFile(handle);
4421 SAL_WARN_IF(
4422 e2 != osl_File_E_None, "unoidl",
4423 "cannot close " << uri << ": " << +e2);
4424 throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
4426 try {
4427 data->setSource(address, size);
4428 yyscan_t yyscanner;
4429 if (yylex_init_extra(data, &yyscanner) != 0) {
4430 // Checking errno for the specific EINVAL, ENOMEM documented for
4431 // yylex_init_extra would not work as those values are not defined
4432 // by the C++ Standard:
4433 int e2 = errno;
4434 throw FileFormatException(
4435 uri,
4436 "yylex_init_extra failed with errno " + OUString::number(e2));
4438 int e2 = yyparse(yyscanner);
4439 yylex_destroy(yyscanner);
4440 switch (e2) {
4441 case 0:
4442 break;
4443 default:
4444 assert(false);
4445 [[fallthrough]];
4446 case 1:
4447 throw FileFormatException(
4448 uri,
4449 ("cannot parse"
4450 + (data->errorLine == 0
4451 ? OUString() : " line " + OUString::number(data->errorLine))
4452 + (data->parserError.isEmpty()
4453 ? OUString()
4454 : (", "
4455 + OStringToOUString(
4456 data->parserError, osl_getThreadTextEncoding())))
4457 + (data->errorMessage.isEmpty()
4458 ? OUString() : ": \"" + data->errorMessage + "\"")));
4459 case 2:
4460 throw std::bad_alloc();
4462 } catch (...) {
4463 e = osl_unmapMappedFile(handle, address, size);
4464 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4465 e = osl_closeFile(handle);
4466 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4467 throw;
4469 e = osl_unmapMappedFile(handle, address, size);
4470 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4471 e = osl_closeFile(handle);
4472 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4473 return true;
4478 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */