calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / unoidl / source / sourceprovider-parser.y
blobabe17e3558d8a3e2a54b7c46c537340e3f8edd81
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 <o3tl/unreachable.hxx>
20 #include <o3tl/string_view.hxx>
21 #include <rtl/ustrbuf.hxx>
22 #include <unoidl/unoidl.hxx>
24 #include <algorithm>
25 #include <cassert>
26 #include <cerrno>
27 #include <cstddef>
28 #include <cstdlib>
29 #include <limits>
30 #include <new>
31 #include <utility>
32 #include <vector>
34 #include "sourceprovider-parser-requires.hxx"
38 %union {
39 sal_uInt64 ival;
40 double fval;
41 OString * sval;
43 bool bval;
44 std::vector<OUString> * excns;
45 unoidl::detail::SourceProviderAccessDecls decls;
46 unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
47 unoidl::detail::SourceProviderFlags flags;
48 unoidl::detail::SourceProviderExpr expr;
49 unoidl::detail::SourceProviderType * type;
50 std::vector<unoidl::detail::SourceProviderType> * types;
53 /* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
55 %lex-param {yyscan_t yyscanner}
56 %parse-param {yyscan_t yyscanner}
60 #include <osl/file.h>
61 #include <osl/thread.h>
62 #include <sal/log.hxx>
64 #include "sourceprovider-scanner.hxx"
66 #define YYLLOC_DEFAULT(Current, Rhs, N) \
67 do { (Current) = YYRHSLOC((Rhs), (N) ? 1 : 0); } while (0)
69 static void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
70 assert(locp != nullptr);
71 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
72 data->errorLine = *locp;
73 data->parserError = OString(msg);
76 namespace {
78 void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
79 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
80 data->errorLine = location;
81 data->errorMessage = message;
84 OUString flagName(unoidl::detail::SourceProviderFlags flag) {
85 switch (flag) {
86 case unoidl::detail::FLAG_ATTRIBUTE:
87 return "attribute";
88 case unoidl::detail::FLAG_BOUND:
89 return "bound";
90 case unoidl::detail::FLAG_CONSTRAINED:
91 return "constrained";
92 case unoidl::detail::FLAG_MAYBEAMBIGUOUS:
93 return "maybeambiguous";
94 case unoidl::detail::FLAG_MAYBEDEFAULT:
95 return "maybedefault";
96 case unoidl::detail::FLAG_MAYBEVOID:
97 return "maybevoid";
98 case unoidl::detail::FLAG_OPTIONAL:
99 return "optional";
100 case unoidl::detail::FLAG_PROPERTY:
101 return "property";
102 case unoidl::detail::FLAG_READONLY:
103 return "readonly";
104 case unoidl::detail::FLAG_REMOVABLE:
105 return "removable";
106 case unoidl::detail::FLAG_TRANSIENT:
107 return "transient";
108 default:
109 assert(false && "this cannot happen"); for (;;) { std::abort(); }
113 OUString convertName(OString const * name) {
114 assert(name != nullptr);
115 OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
116 delete name;
117 return s;
120 OUString convertToFullName(
121 unoidl::detail::SourceProviderScannerData const * data,
122 OString const * identifier)
124 assert(data != nullptr);
125 OUString pref;
126 if (!data->modules.empty()) {
127 pref = data->modules.back() + ".";
129 return pref + convertName(identifier);
132 void convertToCurrentName(
133 unoidl::detail::SourceProviderScannerData * data,
134 OString const * identifier)
136 assert(data != nullptr);
137 assert(data->currentName.isEmpty());
138 data->currentName = convertToFullName(data, identifier);
139 assert(!data->currentName.isEmpty());
142 void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
143 assert(data != nullptr);
144 data->currentName.clear();
145 data->publishedContext = false;
148 unoidl::detail::SourceProviderEntity * getCurrentEntity(
149 unoidl::detail::SourceProviderScannerData * data)
151 assert(data != nullptr);
152 assert(!data->currentName.isEmpty());
153 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
154 data->entities.find(data->currentName));
155 assert(i != data->entities.end());
156 assert(i->second.kind == unoidl::detail::SourceProviderEntity::KIND_LOCAL);
157 assert(i->second.pad.is());
158 return &i->second;
161 template<typename T> rtl::Reference<T> getCurrentPad(
162 unoidl::detail::SourceProviderScannerData * data)
164 rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
165 assert(pad.is());
166 return pad;
169 bool nameHasSameIdentifierAs(std::u16string_view name, std::u16string_view identifier)
171 size_t i = name.rfind('.') + 1;
172 return identifier.size() == name.size() - i
173 && o3tl::starts_with(name.substr(i), identifier);
176 bool coerce(
177 YYLTYPE location, yyscan_t yyscanner,
178 unoidl::detail::SourceProviderExpr * lhs,
179 unoidl::detail::SourceProviderExpr * rhs)
181 assert(lhs != nullptr);
182 assert(rhs != nullptr);
183 bool ok = bool(); // avoid warnings
184 switch (lhs->type) {
185 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
186 ok = rhs->type != unoidl::detail::SourceProviderExpr::TYPE_BOOL;
187 break;
188 case unoidl::detail::SourceProviderExpr::TYPE_INT:
189 switch (rhs->type) {
190 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
191 ok = false;
192 break;
193 case unoidl::detail::SourceProviderExpr::TYPE_INT:
194 ok = true;
195 break;
196 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
197 if (lhs->ival >= 0) {
198 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
199 ok = true;
200 } else if (rhs->uval <= SAL_MAX_INT64) {
201 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
202 ok = true;
203 } else {
204 ok = false;
206 break;
207 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
209 auto tmp = lhs->ival;
210 lhs->fval = tmp;
211 ok = true;
213 break;
215 break;
216 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
217 switch (rhs->type) {
218 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
219 ok = false;
220 break;
221 case unoidl::detail::SourceProviderExpr::TYPE_INT:
222 if (rhs->ival >= 0) {
223 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
224 ok = true;
225 } else if (lhs->uval <= SAL_MAX_INT64) {
226 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
227 ok = true;
228 } else {
229 ok = false;
231 break;
232 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
233 ok = true;
234 break;
235 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
237 auto nTmp = lhs->uval;
238 lhs->fval = nTmp;
239 ok = true;
241 break;
243 break;
244 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
245 switch (rhs->type) {
246 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
247 ok = false;
248 break;
249 case unoidl::detail::SourceProviderExpr::TYPE_INT:
251 auto tmp = rhs->ival;
252 rhs->fval = tmp;
253 ok = true;
255 break;
256 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
258 auto tmp = rhs->uval;
259 rhs->fval = tmp;
260 ok = true;
262 break;
263 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
264 ok = true;
265 break;
267 break;
269 if (!ok) {
270 error(location, yyscanner, "cannot coerce binary expression arguments");
272 return ok;
275 unoidl::detail::SourceProviderEntity * findEntity_(
276 unoidl::detail::SourceProviderScannerData * data, OUString * name)
278 assert(data != nullptr);
279 assert(name != nullptr);
280 OUString n;
281 if (!name->startsWith(".", &n)) {
282 for (auto i(data->modules.rbegin()); i != data->modules.rend(); ++i) {
283 n = *i + "." + *name;
284 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
285 data->entities.find(n));
286 if (j != data->entities.end()) {
287 *name = n;
288 return &j->second;
290 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
291 if (ent.is()) {
292 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
293 k(data->entities.emplace(
295 unoidl::detail::SourceProviderEntity(
296 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
297 ent)).
298 first);
299 *name = n;
300 return &k->second;
303 n = *name;
305 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
306 data->entities.find(n));
307 if (i != data->entities.end()) {
308 *name = n;
309 return &i->second;
311 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
312 if (ent.is()) {
313 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
314 j(data->entities.emplace(
316 unoidl::detail::SourceProviderEntity(
317 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
318 ent)).
319 first);
320 *name = n;
321 return &j->second;
323 return nullptr;
326 enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
328 Found findEntity(
329 YYLTYPE location, yyscan_t yyscanner,
330 unoidl::detail::SourceProviderScannerData * data,
331 bool resolveInterfaceDefinitions, OUString * name,
332 unoidl::detail::SourceProviderEntity const ** entity, bool * typedefed,
333 unoidl::detail::SourceProviderType * typedefedType)
335 //TODO: avoid recursion
336 assert(data != nullptr);
337 assert(name != nullptr);
338 assert(entity != nullptr);
339 unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
340 OUString n(*name);
341 OUString typeNucleus;
342 std::size_t rank = 0;
343 std::vector<unoidl::detail::SourceProviderType> args;
344 for (;;) {
345 if (e != nullptr) {
346 switch (e->kind) {
347 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
348 if (e->pad.is()) {
349 break;
351 assert(e->entity.is());
352 [[fallthrough]];
353 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
354 if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
355 if (typedefed != nullptr) {
356 *typedefed = true;
358 if (data->publishedContext
359 && !static_cast<unoidl::TypedefEntity *>(
360 e->entity.get())->isPublished())
362 error(
363 location, yyscanner,
364 ("type " + *name + " based on unpublished typedef "
365 + n + " used in published context"));
366 return FOUND_ERROR;
368 OUString t(
369 static_cast<unoidl::TypedefEntity *>(e->entity.get())
370 ->getType());
371 typeNucleus = t;
372 while (typeNucleus.startsWith("[]", &typeNucleus)) {
373 if (!args.empty()) {
374 error(
375 location, yyscanner,
376 ("inconsistent type manager: bad type " + *name
377 + (" based on instantiated polymorphic struct"
378 " type based on sequence type named ")
379 + t));
380 return FOUND_ERROR;
382 if (rank == std::numeric_limits<std::size_t>::max()) {
383 error(
384 location, yyscanner,
385 ("bad type " + *name
386 + " based on sequence type of too high rank"));
387 return FOUND_ERROR;
389 ++rank;
391 sal_Int32 i = typeNucleus.indexOf('<');
392 if (i != -1) {
393 if (!args.empty()) {
394 error(
395 location, yyscanner,
396 ("inconsistent type manager: bad type " + *name
397 + (" based on instantiated polymorphic struct"
398 " type based on instantiated polymorphic"
399 " struct type named ")
400 + t));
401 return FOUND_ERROR;
403 std::u16string_view tmpl(typeNucleus.subView(0, i));
404 do {
405 ++i; // skip '<' or ','
406 sal_Int32 j = i;
407 for (sal_Int32 level = 0;
408 j != typeNucleus.getLength(); ++j)
410 sal_Unicode c = typeNucleus[j];
411 if (c == ',') {
412 if (level == 0) {
413 break;
415 } else if (c == '<') {
416 ++level;
417 } else if (c == '>') {
418 if (level == 0) {
419 break;
421 --level;
424 if (j != typeNucleus.getLength()) {
425 OUString argName(typeNucleus.copy(i, j - i));
426 unoidl::detail::SourceProviderEntity const *
427 argEnt;
428 unoidl::detail::SourceProviderType argType;
429 switch (
430 findEntity(
431 location, yyscanner, data, false,
432 &argName, &argEnt, nullptr, &argType))
434 case FOUND_ERROR:
435 return FOUND_ERROR;
436 case FOUND_TYPE:
437 break;
438 case FOUND_ENTITY:
439 if (argEnt == nullptr) {
440 error(
441 location, yyscanner,
442 (("inconsistent type manager: bad"
443 " instantiated polymorphic struct"
444 " type template type argument ")
445 + argName));
446 return FOUND_ERROR;
447 } else {
448 unoidl::detail::SourceProviderType::Type
449 argT
450 = unoidl::detail::SourceProviderType::Type();
451 // avoid warnings
452 switch (argEnt->kind) {
453 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
454 if (e->pad.is()) {
455 error(
456 location, yyscanner,
457 (("inconsistent type"
458 " manager: bad"
459 " instantiated"
460 " polymorphic struct type"
461 " template type"
462 " argument ")
463 + argName));
464 return FOUND_ERROR;
466 assert(e->entity.is());
467 [[fallthrough]];
468 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
469 switch (e->entity->getSort()) {
470 case unoidl::Entity::SORT_ENUM_TYPE:
471 argT = unoidl::detail::SourceProviderType::TYPE_ENUM;
472 break;
473 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
474 argT = unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT;
475 break;
476 case unoidl::Entity::SORT_INTERFACE_TYPE:
477 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
478 break;
479 default:
480 error(
481 location, yyscanner,
482 (("inconsistent type"
483 "manager: bad"
484 " instantiated"
485 " polymorphic struct type"
486 " template type"
487 " argument ")
488 + argName));
489 return FOUND_ERROR;
491 break;
492 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
493 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
494 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
495 break;
496 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
497 assert(false && "this cannot happen");
499 argType
500 = unoidl::detail::SourceProviderType(
501 argT, argName, argEnt);
503 break;
505 args.push_back(argType);
507 i = j;
508 } while (i != typeNucleus.getLength()
509 && typeNucleus[i] != '>');
510 if (i != typeNucleus.getLength() - 1
511 || typeNucleus[i] != '>')
513 error(
514 location, yyscanner,
515 ("inconsistent type manager: bad type name \""
516 + t + "\""));
517 return FOUND_ERROR;
519 assert(!args.empty());
520 typeNucleus = tmpl;
522 if (typeNucleus.isEmpty()) {
523 error(
524 location, yyscanner,
525 ("inconsistent type manager: bad type name \"" + t
526 + "\""));
527 return FOUND_ERROR;
529 if (typeNucleus == "void") {
530 error(
531 location, yyscanner,
532 ("inconsistent type manager: bad type " + *name
533 + " based on void"));
534 return FOUND_ERROR;
536 if (typeNucleus == "boolean" || typeNucleus == "byte"
537 || typeNucleus == "short"
538 || typeNucleus == "unsigned short"
539 || typeNucleus == "long"
540 || typeNucleus == "unsigned long"
541 || typeNucleus == "hyper"
542 || typeNucleus == "unsigned hyper"
543 || typeNucleus == "float" || typeNucleus == "double"
544 || typeNucleus == "char" || typeNucleus == "string"
545 || typeNucleus == "type" || typeNucleus == "any")
547 if (!args.empty()) {
548 error(
549 location, yyscanner,
550 ("inconsistent type manager: bad type " + *name
551 + (" based on instantiated polymorphic struct"
552 " type based on ")
553 + typeNucleus));
554 return FOUND_ERROR;
556 break;
558 n = "." + typeNucleus;
559 typeNucleus.clear();
560 e = findEntity_(data, &n);
561 continue;
563 break;
564 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
565 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
566 if (resolveInterfaceDefinitions) {
567 rtl::Reference<unoidl::Entity> ent(
568 data->manager->findEntity(n));
569 // Do not allow ent to be of SORT_TYPEDEF:
570 if (!ent.is()
571 || (ent->getSort()
572 != unoidl::Entity::SORT_INTERFACE_TYPE))
574 error(
575 location, yyscanner,
576 (*name + " is based on interface declaration " + n
577 + " that is not an interface type entity"));
578 return FOUND_ERROR;
580 e->kind
581 = unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
582 e->entity = ent;
584 break;
585 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
586 error(
587 location, yyscanner,
588 *name + " is based on module entity " + n);
589 return FOUND_ERROR;
592 if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
593 if (typeNucleus.isEmpty() && e == nullptr) {
594 // Found a type name based on an unknown entity:
595 *entity = nullptr;
596 return FOUND_ENTITY;
598 unoidl::detail::SourceProviderType t;
599 if (args.empty()) {
600 if (typeNucleus == "boolean") {
601 t = unoidl::detail::SourceProviderType(
602 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
603 } else if (typeNucleus == "byte") {
604 t = unoidl::detail::SourceProviderType(
605 unoidl::detail::SourceProviderType::TYPE_BYTE);
606 } else if (typeNucleus == "short") {
607 t = unoidl::detail::SourceProviderType(
608 unoidl::detail::SourceProviderType::TYPE_SHORT);
609 } else if (typeNucleus == "unsigned short") {
610 t = unoidl::detail::SourceProviderType(
611 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
612 } else if (typeNucleus == "long") {
613 t = unoidl::detail::SourceProviderType(
614 unoidl::detail::SourceProviderType::TYPE_LONG);
615 } else if (typeNucleus == "unsigned long") {
616 t = unoidl::detail::SourceProviderType(
617 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
618 } else if (typeNucleus == "hyper") {
619 t = unoidl::detail::SourceProviderType(
620 unoidl::detail::SourceProviderType::TYPE_HYPER);
621 } else if (typeNucleus == "unsigned hyper") {
622 t = unoidl::detail::SourceProviderType(
623 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
624 } else if (typeNucleus == "float") {
625 t = unoidl::detail::SourceProviderType(
626 unoidl::detail::SourceProviderType::TYPE_FLOAT);
627 } else if (typeNucleus == "double") {
628 t = unoidl::detail::SourceProviderType(
629 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
630 } else if (typeNucleus == "char") {
631 t = unoidl::detail::SourceProviderType(
632 unoidl::detail::SourceProviderType::TYPE_CHAR);
633 } else if (typeNucleus == "string") {
634 t = unoidl::detail::SourceProviderType(
635 unoidl::detail::SourceProviderType::TYPE_STRING);
636 } else if (typeNucleus == "type") {
637 t = unoidl::detail::SourceProviderType(
638 unoidl::detail::SourceProviderType::TYPE_TYPE);
639 } else if (typeNucleus == "any") {
640 t = unoidl::detail::SourceProviderType(
641 unoidl::detail::SourceProviderType::TYPE_ANY);
642 } else {
643 assert(typeNucleus.isEmpty());
644 assert(e != nullptr);
645 switch (e->kind) {
646 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
647 if (e->pad.is()) {
648 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
649 e->pad.get())
650 != nullptr)
652 t = unoidl::detail::SourceProviderType(
653 unoidl::detail::SourceProviderType::TYPE_ENUM,
654 n, e);
655 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
656 e->pad.get())
657 != nullptr)
659 t = unoidl::detail::SourceProviderType(
660 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
661 n, e);
662 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
663 e->pad.get())
664 != nullptr)
666 error(
667 location, yyscanner,
668 ("bad type " + *name
669 + (" based on recursive reference to"
670 " polymorphic struct type template ")
671 + n));
672 return FOUND_ERROR;
673 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
674 e->pad.get())
675 != nullptr)
677 t = unoidl::detail::SourceProviderType(
678 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
679 n, e);
680 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
681 e->pad.get())
682 != nullptr)
684 t = unoidl::detail::SourceProviderType(
685 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
686 n, e);
687 } else {
688 error(
689 location, yyscanner,
690 ("bad type " + *name
691 + " based on non-type entity " + n));
692 return FOUND_ERROR;
694 break;
696 assert(e->entity.is());
697 [[fallthrough]];
698 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
699 switch (e->entity->getSort()) {
700 case unoidl::Entity::SORT_ENUM_TYPE:
701 t = unoidl::detail::SourceProviderType(
702 unoidl::detail::SourceProviderType::TYPE_ENUM,
703 n, e);
704 break;
705 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
706 t = unoidl::detail::SourceProviderType(
707 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
708 n, e);
709 break;
710 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
711 error(
712 location, yyscanner,
713 ("bad type " + *name
714 + " based on polymorphic struct type template "
715 + n + " without type arguments"));
716 return FOUND_ERROR;
717 case unoidl::Entity::SORT_EXCEPTION_TYPE:
718 t = unoidl::detail::SourceProviderType(
719 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
720 n, e);
721 break;
722 case unoidl::Entity::SORT_INTERFACE_TYPE:
723 t = unoidl::detail::SourceProviderType(
724 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
725 n, e);
726 break;
727 default:
728 error(
729 location, yyscanner,
730 ("bad type " + *name
731 + " based on non-type entity " + n));
732 return FOUND_ERROR;
734 break;
735 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
736 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
737 t = unoidl::detail::SourceProviderType(
738 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
739 n, e);
740 break;
741 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
742 assert(false && "this cannot happen");
745 } else {
746 assert(typeNucleus.isEmpty());
747 assert(e != nullptr);
748 switch (e->kind) {
749 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
750 if (e->pad.is()) {
751 error(
752 location, yyscanner,
753 ("bad type " + *name
754 + (" based on instantiated polymorphic struct type"
755 " based on ")
757 + (" that is either not a polymorphic struct type"
758 " template or a recursive reference to a"
759 " polymorphic struct type template")));
760 return FOUND_ERROR;
762 assert(e->entity.is());
763 [[fallthrough]];
764 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
765 if (e->entity->getSort()
766 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
768 if (args.size()
769 != (static_cast<
770 unoidl::PolymorphicStructTypeTemplateEntity *>(
771 e->entity.get())
772 ->getTypeParameters().size()))
774 error(
775 location, yyscanner,
776 ("bad type " + *name
777 + (" based on instantiated polymorphic struct"
778 " type with ")
779 + OUString::number(args.size())
780 + (" type arguments based on polymorphic"
781 " struct type template ")
782 + n + " with "
783 + OUString::number(
784 static_cast<
785 unoidl::PolymorphicStructTypeTemplateEntity *>(
786 e->entity.get())
787 ->getTypeParameters().size())
788 + " type parameters"));
789 return FOUND_ERROR;
791 t = unoidl::detail::SourceProviderType(n, e, std::move(args));
792 break;
794 [[fallthrough]];
795 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
796 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
797 error(
798 location, yyscanner,
799 ("bad type " + *name
800 + (" based on instantiated polymorphic struct type"
801 " based on ")
803 + " that is not a polymorphic struct type template"));
804 return FOUND_ERROR;
805 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
806 assert(false && "this cannot happen");
809 if (typedefedType != nullptr) {
810 for (std::size_t i = 0; i != rank; ++i) {
811 t = unoidl::detail::SourceProviderType(&t);
813 *typedefedType = t;
814 typedefedType->typedefName = *name;
816 *entity = nullptr;
817 return FOUND_TYPE;
819 *entity = e;
820 return FOUND_ENTITY;
825 bool checkTypeArgument(
826 YYLTYPE location, yyscan_t yyscanner,
827 unoidl::detail::SourceProviderType const & type)
829 switch (type.type) {
830 case unoidl::detail::SourceProviderType::TYPE_VOID:
831 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
832 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
833 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
834 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
835 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
836 error(
837 location, yyscanner,
838 "bad instantiated polymorphic struct type argument");
839 return false;
840 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
841 return checkTypeArgument(location, yyscanner, type.subtypes.front());
842 default:
843 return true;
847 bool checkInstantiatedPolymorphicStructTypeArgument(
848 unoidl::detail::SourceProviderType const & type, OUString const & name)
850 if (type.type
851 == unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
853 for (auto & i: type.subtypes) {
854 if (checkInstantiatedPolymorphicStructTypeArgument(i, name)
855 || i.getName() == name) // no need to worry about typedef
857 return true;
861 return false;
864 std::vector<OUString> annotations(bool deprecated) {
865 std::vector<OUString> ann;
866 if (deprecated) {
867 ann.push_back("deprecated");
869 return ann;
876 %token TOK_ELLIPSIS
877 %token TOK_COLONS
878 %token TOK_LEFTSHIFT
879 %token TOK_RIGHTSHIFT
881 %token TOK_FALSE
882 %token TOK_TRUE
883 %token TOK_ANY
884 %token TOK_ATTRIBUTE
885 %token TOK_BOOLEAN
886 %token TOK_BOUND
887 %token TOK_BYTE
888 %token TOK_CHAR
889 %token TOK_CONST
890 %token TOK_CONSTANTS
891 %token TOK_CONSTRAINED
892 %token TOK_DOUBLE
893 %token TOK_ENUM
894 %token TOK_EXCEPTION
895 %token TOK_FLOAT
896 %token TOK_GET
897 %token TOK_HYPER
898 %token TOK_IN
899 %token TOK_INOUT
900 %token TOK_INTERFACE
901 %token TOK_LONG
902 %token TOK_MAYBEAMBIGUOUS
903 %token TOK_MAYBEDEFAULT
904 %token TOK_MAYBEVOID
905 %token TOK_MODULE
906 %token TOK_OPTIONAL
907 %token TOK_OUT
908 %token TOK_PROPERTY
909 %token TOK_PUBLISHED
910 %token TOK_RAISES
911 %token TOK_READONLY
912 %token TOK_REMOVABLE
913 %token TOK_SEQUENCE
914 %token TOK_SERVICE
915 %token TOK_SET
916 %token TOK_SHORT
917 %token TOK_SINGLETON
918 %token TOK_STRING
919 %token TOK_STRUCT
920 %token TOK_TRANSIENT
921 %token TOK_TYPE
922 %token TOK_TYPEDEF
923 %token TOK_UNSIGNED
924 %token TOK_VOID
926 %token<sval> TOK_IDENTIFIER
927 %token<ival> TOK_INTEGER
928 %token<fval> TOK_FLOATING
930 %token TOK_DEPRECATED
932 %token TOK_ERROR
934 %type<sval> identifier name singleInheritance singleInheritance_opt
935 %type<bval> ctors_opt deprecated_opt ellipsis_opt published_opt
936 %type<decls> attributeAccessDecl attributeAccessDecls
937 %type<dir> direction
938 %type<excns> exceptionSpec exceptionSpec_opt exceptions
939 %type<flags> flag flagSection flagSection_opt flags
940 %type<expr> addExpr andExpr expr multExpr orExpr primaryExpr shiftExpr unaryExpr
941 xorExpr
942 %type<type> type
943 %type<types> typeArguments
945 %initial-action { yylloc = 1; }
949 definitions:
950 definitions definition
951 | /* empty */
954 definition:
955 moduleDecl
956 | enumDefn
957 | plainStructDefn
958 | polymorphicStructTemplateDefn
959 | exceptionDefn
960 | interfaceDefn
961 | typedefDefn
962 | constantGroupDefn
963 | singleInterfaceBasedServiceDefn
964 | accumulationBasedServiceDefn
965 | interfaceBasedSingletonDefn
966 | serviceBasedSingletonDefn
967 | interfaceDecl
970 moduleDecl:
971 TOK_MODULE identifier
973 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
974 OUString name(convertToFullName(data, $2));
975 data->modules.push_back(name);
976 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
977 data->entities.emplace(
978 name,
979 unoidl::detail::SourceProviderEntity(
980 unoidl::detail::SourceProviderEntity::KIND_MODULE)));
981 if (!p.second
982 && (p.first->second.kind
983 != unoidl::detail::SourceProviderEntity::KIND_MODULE))
985 error(@2, yyscanner, "multiple entities named " + name);
986 YYERROR;
989 '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
992 enumDefn:
993 deprecated_opt published_opt TOK_ENUM identifier
995 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
996 data->publishedContext = $2;
997 convertToCurrentName(data, $4);
998 if (!data->entities.emplace(
999 data->currentName,
1000 unoidl::detail::SourceProviderEntity(
1001 new unoidl::detail::SourceProviderEnumTypeEntityPad(
1002 $2))).
1003 second)
1005 error(@4, yyscanner, "multiple entities named " + data->currentName);
1006 YYERROR;
1009 '{' enumMembers '}' ';'
1011 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1012 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1013 unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
1014 dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
1015 ent->pad.get());
1016 assert(pad != nullptr);
1017 ent->entity = new unoidl::EnumTypeEntity(
1018 pad->isPublished(), std::move(pad->members), annotations($1));
1019 ent->pad.clear();
1020 clearCurrentState(data);
1024 enumMembers:
1025 | enumMembers ',' enumMember
1026 | enumMember
1029 enumMember:
1030 deprecated_opt identifier
1032 OUString id(convertName($2));
1033 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1034 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1035 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1036 sal_Int32 v;
1037 if (pad->members.empty()) {
1038 v = 0;
1039 } else {
1040 v = pad->members.back().value;
1041 if (v == SAL_MAX_INT32) {
1042 error(
1043 @2, yyscanner,
1044 ("enum " + data->currentName + " member " + id
1045 + " would have out-of-range value 2^31"));
1046 YYERROR;
1048 ++v;
1050 pad->members.emplace_back(id, v, annotations($1));
1052 | deprecated_opt identifier '=' expr
1054 OUString id(convertName($2));
1055 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1056 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1057 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1058 sal_Int32 v;
1059 switch ($4.type) {
1060 case unoidl::detail::SourceProviderExpr::TYPE_INT:
1061 if ($4.ival < SAL_MIN_INT32 || $4.ival > SAL_MAX_INT32) {
1062 error(
1063 @4, yyscanner,
1064 ("out-of-range enum " + data->currentName + " member " + id
1065 + " value " + OUString::number($4.ival)));
1066 YYERROR;
1068 v = static_cast<sal_Int32>($4.ival);
1069 break;
1070 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
1071 if ($4.uval > SAL_MAX_INT32) {
1072 error(
1073 @4, yyscanner,
1074 ("out-of-range enum " + data->currentName + " member " + id
1075 + " value " + OUString::number($4.uval)));
1076 YYERROR;
1078 v = static_cast<sal_Int32>($4.uval);
1079 break;
1080 default:
1081 error(
1082 @4, yyscanner,
1083 ("non-integer enum " + data->currentName + " member " + id
1084 + " value"));
1085 YYERROR;
1086 break;
1088 pad->members.emplace_back(id, v, annotations($1));
1092 plainStructDefn:
1093 deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
1095 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1096 data->publishedContext = $2;
1097 convertToCurrentName(data, $4);
1098 OUString baseName;
1099 rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
1100 if ($5 != nullptr) {
1101 baseName = convertName($5);
1102 unoidl::detail::SourceProviderEntity const * p;
1103 if (findEntity(
1104 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1105 == FOUND_ERROR)
1107 YYERROR;
1109 if (p == nullptr || !p->entity.is()
1110 || p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
1112 error(
1113 @5, yyscanner,
1114 ("plain struct type " + data->currentName + " base "
1115 + baseName
1116 + " does not resolve to an existing plain struct type"));
1117 YYERROR;
1119 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1120 p->entity.get());
1121 if ($2 && !baseEnt->isPublished()) {
1122 error(
1123 @5, yyscanner,
1124 ("published plain struct type " + data->currentName + " base "
1125 + baseName + " is unpublished"));
1126 YYERROR;
1129 if (!data->entities.emplace(
1130 data->currentName,
1131 unoidl::detail::SourceProviderEntity(
1132 new unoidl::detail::SourceProviderPlainStructTypeEntityPad(
1133 $2, baseName, baseEnt))).
1134 second)
1136 error(@4, yyscanner, "multiple entities named " + data->currentName);
1137 YYERROR;
1140 '{' structMembers '}' ';'
1142 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1143 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1144 unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
1145 dynamic_cast<
1146 unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1147 ent->pad.get());
1148 assert(pad != nullptr);
1149 ent->entity = new unoidl::PlainStructTypeEntity(
1150 pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
1151 ent->pad.clear();
1152 clearCurrentState(data);
1156 polymorphicStructTemplateDefn:
1157 deprecated_opt published_opt TOK_STRUCT identifier '<'
1159 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1160 data->publishedContext = $2;
1161 convertToCurrentName(data, $4);
1162 if (!data->entities.emplace(
1163 data->currentName,
1164 unoidl::detail::SourceProviderEntity(
1165 new unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad(
1166 $2))).
1167 second)
1169 error(@4, yyscanner, "multiple entities named " + data->currentName);
1170 YYERROR;
1173 typeParameters '>' '{' structMembers '}' ';'
1175 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1176 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1177 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1178 pad = dynamic_cast<
1179 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1180 ent->pad.get());
1181 assert(pad != nullptr);
1182 ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
1183 pad->isPublished(), std::move(pad->typeParameters), std::move(pad->members),
1184 annotations($1));
1185 ent->pad.clear();
1186 clearCurrentState(data);
1190 typeParameters:
1191 typeParameters ',' identifier
1193 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1194 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1195 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1196 data));
1197 OUString id(convertName($3));
1198 if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
1199 != pad->typeParameters.end())
1201 error(
1202 @3, yyscanner,
1203 ("polymorphic struct type template " + data->currentName
1204 + " type parameter " + id
1205 + " has same identifier as another type parameter"));
1206 YYERROR;
1208 pad->typeParameters.push_back(id);
1210 | identifier
1212 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1213 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1214 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1215 data));
1216 OUString id(convertName($1));
1217 assert(pad->typeParameters.empty());
1218 pad->typeParameters.push_back(id);
1222 exceptionDefn:
1223 deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
1225 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1226 data->publishedContext = $2;
1227 convertToCurrentName(data, $4);
1228 OUString baseName;
1229 rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
1230 if ($5 != nullptr) {
1231 baseName = convertName($5);
1232 unoidl::detail::SourceProviderEntity const * p;
1233 if (findEntity(
1234 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1235 == FOUND_ERROR)
1237 YYERROR;
1239 if (p == nullptr || !p->entity.is()
1240 || p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE)
1242 error(
1243 @5, yyscanner,
1244 ("exception type " + data->currentName + " base " + baseName
1245 + " does not resolve to an existing exception type"));
1246 YYERROR;
1248 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1249 p->entity.get());
1250 if ($2 && !baseEnt->isPublished()) {
1251 error(
1252 @5, yyscanner,
1253 ("published exception type " + data->currentName + " base "
1254 + baseName + " is unpublished"));
1255 YYERROR;
1258 if (!data->entities.emplace(
1259 data->currentName,
1260 unoidl::detail::SourceProviderEntity(
1261 new unoidl::detail::SourceProviderExceptionTypeEntityPad(
1262 $2, baseName, baseEnt))).
1263 second)
1265 error(@4, yyscanner, "multiple entities named " + data->currentName);
1266 YYERROR;
1269 '{' structMembers '}' ';'
1271 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1272 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1273 unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
1274 dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1275 ent->pad.get());
1276 assert(pad != nullptr);
1277 ent->entity = new unoidl::ExceptionTypeEntity(
1278 pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
1279 ent->pad.clear();
1280 clearCurrentState(data);
1284 structMembers:
1285 structMembers structMember
1286 | /* empty */
1289 structMember:
1290 deprecated_opt type identifier ';'
1292 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1293 unoidl::detail::SourceProviderType t(*$2);
1294 delete $2;
1295 OUString id(convertName($3));
1296 switch (t.type) {
1297 case unoidl::detail::SourceProviderType::TYPE_VOID:
1298 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1299 error(
1300 @2, yyscanner,
1301 ("illegal struct/exception type " + data->currentName
1302 + " direct member " + id + " type"));
1303 YYERROR;
1304 break;
1305 default:
1306 break;
1308 if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
1309 && t.getName() == data->currentName) // no need to worry about typedef
1311 error(
1312 @2, yyscanner,
1313 ("struct/exception type " + data->currentName + " direct member "
1314 + id + " has same type as the type itself"));
1315 YYERROR;
1317 if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
1319 error(
1320 @2, yyscanner,
1321 ("struct/exception type " + data->currentName + " direct member "
1322 + id
1323 + (" has instantiated polymorphic struct type that uses the type"
1324 " itself as an argument")));
1325 YYERROR;
1327 if (nameHasSameIdentifierAs(data->currentName, id)) {
1328 error(
1329 @3, yyscanner,
1330 ("struct/exception type " + data->currentName + " direct member "
1331 + id + " has same unqualified identifier as the type itself"));
1332 YYERROR;
1334 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1335 unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
1336 dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1337 ent->pad.get());
1338 if (p1 != nullptr) {
1339 for (const auto & i: p1->members) {
1340 if (id == i.name) {
1341 error(
1342 @3, yyscanner,
1343 ("plain struct type " + data->currentName
1344 + " direct member " + id
1345 + " has same identifier as another direct member"));
1346 YYERROR;
1349 if (p1->baseEntity.is()) {
1350 OUString baseName(p1->baseName);
1351 for (auto baseEnt(p1->baseEntity);;) {
1352 if (nameHasSameIdentifierAs(baseName, id)) {
1353 error(
1354 @3, yyscanner,
1355 ("plain struct type " + data->currentName
1356 + " direct member " + id
1357 + " has same unqalified identifier as base "
1358 + baseName));
1359 YYERROR;
1361 for (auto & i: baseEnt->getDirectMembers()) {
1362 if (id == i.name) {
1363 error(
1364 @3, yyscanner,
1365 ("plain struct type " + data->currentName
1366 + " direct member " + id
1367 + " has same identifier as a member of base "
1368 + baseName));
1369 YYERROR;
1372 baseName = baseEnt->getDirectBase();
1373 if (baseName.isEmpty()) {
1374 break;
1376 unoidl::detail::SourceProviderEntity const * p;
1377 if (findEntity(
1378 @2, yyscanner, data, false, &baseName, &p, nullptr,
1379 nullptr)
1380 == FOUND_ERROR)
1382 YYERROR;
1384 if (p == nullptr || !p->entity.is()
1385 || (p->entity->getSort()
1386 != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE))
1388 error(
1389 @2, yyscanner,
1390 ("inconsistent type manager: plain struct type "
1391 + data->currentName + " base " + baseName
1392 + (" does not resolve to an existing plain struct"
1393 " type")));
1394 YYERROR;
1396 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1397 p->entity.get());
1400 p1->members.emplace_back(id, t.getName(), annotations($1));
1401 } else {
1402 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1403 p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1404 ent->pad.get());
1405 if (p2 != nullptr) {
1406 for (const auto & i: p2->members) {
1407 if (id == i.name) {
1408 error(
1409 @3, yyscanner,
1410 ("polymorphic struct type template "
1411 + data->currentName + " direct member " + id
1412 + " has same identifier as another direct member"));
1413 YYERROR;
1416 p2->members.emplace_back(
1417 id, t.getName(),
1418 t.type == unoidl::detail::SourceProviderType::TYPE_PARAMETER,
1419 annotations($1));
1420 } else {
1421 unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
1422 = dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1423 ent->pad.get());
1424 assert(p3 != nullptr);
1425 for (const auto & i: p3->members) {
1426 if (id == i.name) {
1427 error(
1428 @3, yyscanner,
1429 ("exception type " + data->currentName
1430 + " direct member " + id
1431 + " has same identifier as another direct member"));
1432 YYERROR;
1435 if (p3->baseEntity.is()) {
1436 OUString baseName(p3->baseName);
1437 for (auto baseEnt(p3->baseEntity);;) {
1438 if (nameHasSameIdentifierAs(baseName, id)) {
1439 error(
1440 @3, yyscanner,
1441 ("exception type " + data->currentName
1442 + " direct member " + id
1443 + " has same unqalified identifier as base "
1444 + baseName));
1445 YYERROR;
1447 for (auto & i: baseEnt->getDirectMembers()) {
1448 if (id == i.name) {
1449 error(
1450 @3, yyscanner,
1451 ("exception type " + data->currentName
1452 + " direct member " + id
1453 + " has same identifier as a member of base "
1454 + baseName));
1455 YYERROR;
1458 baseName = baseEnt->getDirectBase();
1459 if (baseName.isEmpty()) {
1460 break;
1462 unoidl::detail::SourceProviderEntity const * p;
1463 if (findEntity(
1464 @2, yyscanner, data, false, &baseName, &p,
1465 nullptr, nullptr)
1466 == FOUND_ERROR)
1468 YYERROR;
1470 if (p == nullptr || !p->entity.is()
1471 || (p->entity->getSort()
1472 != unoidl::Entity::SORT_EXCEPTION_TYPE))
1474 error(
1475 @2, yyscanner,
1476 ("inconsistent type manager: exception type "
1477 + data->currentName + " base " + baseName
1478 + (" does not resolve to an existing exception"
1479 " type")));
1480 YYERROR;
1482 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1483 p->entity.get());
1486 p3->members.emplace_back(id, t.getName(), annotations($1));
1492 interfaceDefn:
1493 deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
1495 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1496 data->publishedContext = $2;
1497 convertToCurrentName(data, $4);
1498 OUString baseName;
1499 rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
1500 if ($5 != nullptr) {
1501 baseName = convertName($5);
1502 unoidl::detail::SourceProviderEntity const * p;
1503 if (findEntity(
1504 @5, yyscanner, data, true, &baseName, &p, nullptr, nullptr)
1505 == FOUND_ERROR)
1507 YYERROR;
1509 if (p == nullptr || !p->entity.is()
1510 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1512 error(
1513 @5, yyscanner,
1514 ("interface type " + data->currentName + " direct base "
1515 + baseName
1516 + " does not resolve to an existing interface type"));
1517 YYERROR;
1519 baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
1520 if ($2 && !baseEnt->isPublished()) {
1521 error(
1522 @5, yyscanner,
1523 ("published interface type " + data->currentName
1524 + " direct base " + baseName + " is unpublished"));
1525 YYERROR;
1528 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
1529 data->entities.find(data->currentName));
1530 if (i != data->entities.end()) {
1531 switch (i->second.kind) {
1532 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1533 break;
1534 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1535 if (!$2) {
1536 error(
1537 @4, yyscanner,
1538 ("unpublished interface type " + data->currentName
1539 + " has been declared published"));
1540 YYERROR;
1542 break;
1543 default:
1544 error(
1545 @4, yyscanner,
1546 "multiple entities named " + data->currentName);
1547 YYERROR;
1548 break;
1551 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1552 new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
1553 $2, baseEnt.is()));
1554 if (baseEnt.is()
1555 && !pad->addDirectBase(
1556 @4, yyscanner, data,
1557 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1558 baseName, baseEnt, std::vector<OUString>()),
1559 false))
1561 YYERROR;
1563 data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
1564 pad);
1566 '{' interfaceMembers '}' ';'
1568 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1569 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1570 unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
1571 dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
1572 ent->pad.get());
1573 assert(pad != nullptr);
1574 if (pad->directMandatoryBases.empty()
1575 && data->currentName != "com.sun.star.uno.XInterface")
1577 OUString base(".com.sun.star.uno.XInterface");
1578 unoidl::detail::SourceProviderEntity const * p;
1579 if (findEntity(@4, yyscanner, data, true, &base, &p, nullptr, nullptr)
1580 == FOUND_ERROR)
1582 YYERROR;
1584 if (p == nullptr || !p->entity.is()
1585 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1587 error(
1588 @3, yyscanner,
1589 ("interface type " + data->currentName
1590 + " implicit direct base " + base
1591 + " does not resolve to an existing interface type"));
1592 YYERROR;
1594 if (!pad->addDirectBase(
1595 @3, yyscanner, data,
1596 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1597 base,
1598 static_cast<unoidl::InterfaceTypeEntity *>(
1599 p->entity.get()),
1600 std::vector<OUString>()),
1601 false))
1603 YYERROR;
1606 std::vector<unoidl::AnnotatedReference> mbases;
1607 for (auto & i: pad->directMandatoryBases) {
1608 mbases.emplace_back(i.name, std::move(i.annotations));
1610 std::vector<unoidl::AnnotatedReference> obases;
1611 for (auto & i: pad->directOptionalBases) {
1612 obases.emplace_back(i.name, std::move(i.annotations));
1614 ent->entity = new unoidl::InterfaceTypeEntity(
1615 pad->isPublished(), std::move(mbases), std::move(obases), std::move(pad->directAttributes),
1616 std::move(pad->directMethods), annotations($1));
1617 ent->pad.clear();
1618 clearCurrentState(data);
1622 interfaceMembers:
1623 interfaceMembers interfaceMember
1624 | /* empty */
1627 interfaceMember:
1628 interfaceBase
1629 | interfaceAttribute
1630 | interfaceMethod
1633 interfaceBase:
1634 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
1636 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1637 OUString name(convertName($4));
1638 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1639 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1640 data));
1641 if (pad->singleBase) {
1642 error(
1643 @3, yyscanner,
1644 "single-inheritance interface cannot have additional bases");
1645 YYERROR;
1647 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
1648 error(
1649 @2, yyscanner,
1650 "interface base can only be flagged as [optional]");
1651 YYERROR;
1653 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
1654 OUString orgName(name);
1655 unoidl::detail::SourceProviderEntity const * p;
1656 bool typedefed = false;
1657 if (findEntity(@4, yyscanner, data, true, &name, &p, &typedefed, nullptr)
1658 == FOUND_ERROR)
1660 YYERROR;
1662 if (p == nullptr || !p->entity.is()
1663 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1665 error(
1666 @4, yyscanner,
1667 ("interface type " + data->currentName + " direct base " + name
1668 + " does not resolve to an existing interface type"));
1669 YYERROR;
1671 if (typedefed) {
1672 error(
1673 @4, yyscanner,
1674 ("interface type " + data->currentName + " direct base " + orgName
1675 + " is a typedef"));
1676 YYERROR;
1678 rtl::Reference<unoidl::InterfaceTypeEntity> ent(
1679 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()));
1680 if (data->publishedContext && !ent->isPublished()) {
1681 error(
1682 @4, yyscanner,
1683 ("published interface type " + data->currentName + " direct base "
1684 + name + " is unpublished"));
1685 YYERROR;
1687 if (!pad->addDirectBase(
1688 @4, yyscanner, data,
1689 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1690 name, ent, annotations($1)),
1691 opt))
1693 YYERROR;
1698 interfaceAttribute:
1699 deprecated_opt flagSection type identifier
1701 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1702 unoidl::detail::SourceProviderType t(*$3);
1703 delete $3;
1704 OUString id(convertName($4));
1705 if (($2 & unoidl::detail::FLAG_ATTRIBUTE) == 0) {
1706 error(
1707 @2, yyscanner,
1708 "interface attribute must be flagged as [attribute]");
1709 YYERROR;
1711 if (($2
1712 & ~(unoidl::detail::FLAG_ATTRIBUTE | unoidl::detail::FLAG_BOUND
1713 | unoidl::detail::FLAG_READONLY))
1714 != 0)
1716 error(
1717 @2, yyscanner,
1718 ("interface attribute can only be flagged as [attribute,"
1719 " bound, readonly]"));
1720 YYERROR;
1722 switch (t.type) {
1723 case unoidl::detail::SourceProviderType::TYPE_VOID:
1724 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1725 error(
1726 @3, yyscanner,
1727 ("illegal interface type " + data->currentName
1728 + " direct attribute " + id + " type"));
1729 YYERROR;
1730 break;
1731 default:
1732 break;
1734 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1735 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1736 data));
1737 if (!pad->addDirectMember(@4, yyscanner, data, id)) {
1738 YYERROR;
1740 pad->directAttributes.emplace_back(
1741 id, t.getName(), ($2 & unoidl::detail::FLAG_BOUND) != 0,
1742 ($2 & unoidl::detail::FLAG_READONLY) != 0,
1743 std::vector<OUString>(), std::vector<OUString>(), annotations($1));
1745 attributeAccessDecls_opt ';'
1748 attributeAccessDecls_opt:
1749 '{' attributeAccessDecls '}'
1750 | /* empty */
1753 attributeAccessDecls:
1754 attributeAccessDecls attributeAccessDecl
1756 if (($1 & $2) != 0) {
1757 error(
1758 @2, yyscanner, "duplicate get/set attribute access declaration");
1759 YYERROR;
1761 $$ = unoidl::detail::SourceProviderAccessDecls($1 | $2);
1763 | /* empty */ { $$ = unoidl::detail::SourceProviderAccessDecls(0); }
1766 attributeAccessDecl:
1767 TOK_GET exceptionSpec ';'
1769 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1770 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1771 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1772 data));
1773 assert(!pad->directAttributes.empty());
1774 pad->directAttributes.back().getExceptions = *$2;
1775 delete $2;
1776 $$ = unoidl::detail::ACCESS_DECL_GET;
1778 | TOK_SET exceptionSpec ';'
1780 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1781 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1782 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1783 data));
1784 assert(!pad->directAttributes.empty());
1785 pad->directAttributes.back().setExceptions = *$2;
1786 delete $2;
1787 if (pad->directAttributes.back().readOnly) {
1788 error(
1789 @1, yyscanner,
1790 ("interface type " + data->currentName
1791 + " direct read-only attribute "
1792 + pad->directAttributes.back().name
1793 + " cannot have set access declaration"));
1794 YYERROR;
1796 $$ = unoidl::detail::ACCESS_DECL_SET;
1800 interfaceMethod:
1801 deprecated_opt type identifier
1803 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1804 unoidl::detail::SourceProviderType t(*$2);
1805 delete $2;
1806 OUString id(convertName($3));
1807 if (t.type == unoidl::detail::SourceProviderType::TYPE_EXCEPTION) {
1808 error(
1809 @3, yyscanner,
1810 ("illegal interface type " + data->currentName
1811 + " direct method " + id + " return type"));
1812 YYERROR;
1814 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1815 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1816 data));
1817 if (!pad->addDirectMember(@3, yyscanner, data, id)) {
1818 YYERROR;
1820 pad->directMethods.emplace_back(
1821 id, t.getName(),
1822 std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>(),
1823 std::vector<OUString>(), annotations($1));
1825 '(' methodParams_opt ')' exceptionSpec_opt ';'
1827 if ($8 != nullptr) {
1828 unoidl::detail::SourceProviderScannerData * data
1829 = yyget_extra(yyscanner);
1830 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1831 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1832 data));
1833 assert(!pad->directMethods.empty());
1834 pad->directMethods.back().exceptions = *$8;
1835 delete $8;
1840 methodParams_opt:
1841 methodParams
1842 | /* empty */
1845 methodParams:
1846 methodParams ',' methodParam
1847 | methodParam
1850 methodParam:
1851 '[' direction ']' type identifier
1853 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1854 unoidl::detail::SourceProviderType t(*$4);
1855 delete $4;
1856 OUString id(convertName($5));
1857 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1858 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1859 data));
1860 assert(!pad->directMethods.empty());
1861 switch (t.type) {
1862 case unoidl::detail::SourceProviderType::TYPE_VOID:
1863 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1864 error(
1865 @4, yyscanner,
1866 ("illegal interface type " + data->currentName
1867 + " direct method " + pad->directMethods.back().name
1868 + " parameter " + id + " type"));
1869 YYERROR;
1870 break;
1871 default:
1872 break;
1874 for (const auto & i: pad->directMethods.back().parameters) {
1875 if (id == i.name) {
1876 error(
1877 @5, yyscanner,
1878 ("interface type " + data->currentName + " direct method "
1879 + pad->directMethods.back().name + " parameter " + id
1880 + " has same identifier as another parameter"));
1881 YYERROR;
1884 pad->directMethods.back().parameters.emplace_back(id, t.getName(), $2);
1888 direction:
1889 TOK_IN { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; }
1890 | TOK_OUT
1891 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT; }
1892 | TOK_INOUT
1893 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT; }
1896 typedefDefn:
1897 deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
1899 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1900 data->publishedContext = $2;
1901 unoidl::detail::SourceProviderType t(*$4);
1902 delete $4;
1903 OUString name(convertToFullName(data, $5));
1904 // There is no good reason to forbid typedefs to VOID, to instantiated
1905 // polymorphic struct types, and to exception types, but some old client
1906 // code of registry data expects this typedef restriction (like the
1907 // assert(false) default in handleTypedef in
1908 // codemaker/source/javamaker/javatype.cxx), so forbid them for now:
1909 switch (t.type) {
1910 case unoidl::detail::SourceProviderType::TYPE_VOID:
1911 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1912 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
1913 error(@4, yyscanner, "bad typedef type");
1914 YYERROR;
1915 break;
1916 case unoidl::detail::SourceProviderType::TYPE_ENUM:
1917 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
1918 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
1919 if ($2) {
1920 bool unpub = false;
1921 switch (t.entity->kind) {
1922 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1923 unpub = true;
1924 break;
1925 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1926 break;
1927 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
1928 O3TL_UNREACHABLE;
1929 default:
1930 assert(t.entity->entity.is() || t.entity->pad.is());
1931 unpub
1932 = !(t.entity->entity.is()
1933 ? static_cast<unoidl::PublishableEntity *>(
1934 t.entity->entity.get())->isPublished()
1935 : t.entity->pad->isPublished());
1936 break;
1938 if (unpub) {
1939 error(
1940 @4, yyscanner,
1941 "published typedef " + name + " type is unpublished");
1942 YYERROR;
1945 break;
1946 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
1947 O3TL_UNREACHABLE;
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(), std::move(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, std::vector(parms), std::vector(i.exceptions), std::vector(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, std::move(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, std::move(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(), std::move(pad->directMandatoryBaseServices),
2569 std::move(pad->directOptionalBaseServices), std::move(pad->directMandatoryBaseInterfaces),
2570 std::move(pad->directOptionalBaseInterfaces), std::move(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 std::u16string_view id(name.subView(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 O3TL_UNREACHABLE;
3859 default:
3860 break;
3862 break;
3863 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3864 if (data->publishedContext) {
3865 error(
3866 @1, yyscanner,
3867 ("unpublished entity " + name
3868 + " used in published context"));
3869 YYERROR;
3871 [[fallthrough]];
3872 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3873 $$ = new unoidl::detail::SourceProviderType(
3874 unoidl::detail::SourceProviderType::TYPE_INTERFACE, name,
3875 ent);
3876 ok = true;
3877 break;
3878 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3879 assert(false && "this cannot happen");
3881 if (!ok) {
3882 error(@1, yyscanner, "non-type entity " + name);
3883 YYERROR;
3885 break;
3889 | name '<' typeArguments '>'
3891 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3892 OUString name(convertName($1));
3893 std::vector<unoidl::detail::SourceProviderType> args(*$3);
3894 delete $3;
3895 unoidl::detail::SourceProviderEntity const * ent;
3896 if (findEntity(@1, yyscanner, data, false, &name, &ent, nullptr, nullptr)
3897 == FOUND_ERROR)
3899 YYERROR;
3901 if (ent == nullptr) {
3902 error(@1, yyscanner, "unknown entity " + name);
3903 YYERROR;
3905 bool ok = false;
3906 switch (ent->kind) {
3907 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3908 if (ent->pad.is()) {
3909 if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3910 ent->pad.get())
3911 != nullptr)
3913 error(
3914 @1, yyscanner,
3915 (("recursive reference to polymorphic struct type"
3916 " template ")
3917 + name));
3918 YYERROR;
3920 break;
3922 assert(ent->entity.is());
3923 [[fallthrough]];
3924 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3925 if (ent->entity->getSort()
3926 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
3928 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> e(
3929 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
3930 ent->entity.get()));
3931 if (args.size() != e->getTypeParameters().size()) {
3932 error(
3933 @1, yyscanner,
3934 ("bad number of polymorphic struct type template " + name
3935 + " type arguments"));
3936 YYERROR;
3938 if (data->publishedContext && !e->isPublished()) {
3939 error(
3940 @1, yyscanner,
3941 ("unpublished polymorphic struct type template " + name
3942 + " used in published context"));
3943 YYERROR;
3945 $$ = new unoidl::detail::SourceProviderType(name, ent, std::move(args));
3946 ok = true;
3948 break;
3949 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3950 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3951 break;
3952 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3953 assert(false && "this cannot happen");
3955 if (!ok) {
3956 error(@1, yyscanner, "non-type entity " + name);
3957 YYERROR;
3962 name:
3963 name TOK_COLONS identifier { *$1 += "." + *$3; delete $3; $$ = $1; }
3964 | TOK_COLONS identifier { *$2 = "." + *$2; $$ = $2; }
3965 | identifier
3968 identifier:
3969 TOK_IDENTIFIER
3970 | TOK_GET { $$ = new OString("get"); }
3971 | TOK_PUBLISHED { $$ = new OString("published"); }
3972 | TOK_SET { $$ = new OString("set"); }
3975 deprecated_opt:
3976 TOK_DEPRECATED { $$ = true; }
3977 | /* empty */ { $$ = false; }
3982 namespace unoidl::detail {
3984 OUString SourceProviderType::getName() const {
3985 if (!typedefName.isEmpty()) {
3986 return typedefName;
3988 switch (type) {
3989 case unoidl::detail::SourceProviderType::TYPE_VOID:
3990 return "void";
3991 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
3992 return "boolean";
3993 case unoidl::detail::SourceProviderType::TYPE_BYTE:
3994 return "byte";
3995 case unoidl::detail::SourceProviderType::TYPE_SHORT:
3996 return "short";
3997 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
3998 return "unsigned short";
3999 case unoidl::detail::SourceProviderType::TYPE_LONG:
4000 return "long";
4001 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
4002 return "unsigned long";
4003 case unoidl::detail::SourceProviderType::TYPE_HYPER:
4004 return "hyper";
4005 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
4006 return "unsigned hyper";
4007 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
4008 return "float";
4009 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
4010 return "double";
4011 case unoidl::detail::SourceProviderType::TYPE_CHAR:
4012 return "char";
4013 case unoidl::detail::SourceProviderType::TYPE_STRING:
4014 return "string";
4015 case unoidl::detail::SourceProviderType::TYPE_TYPE:
4016 return "type";
4017 case unoidl::detail::SourceProviderType::TYPE_ANY:
4018 return "any";
4019 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
4020 assert(subtypes.size() == 1);
4021 return "[]" + subtypes.front().getName();
4022 case unoidl::detail::SourceProviderType::TYPE_ENUM:
4023 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
4024 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
4025 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
4026 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
4027 return name;
4028 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
4030 OUStringBuffer n(512);
4031 n.append(name + "<");
4032 for (auto i(subtypes.begin()); i != subtypes.end(); ++i) {
4033 if (i != subtypes.begin()) {
4034 n.append(",");
4036 n.append(i->getName());
4038 return n.append(">").makeStringAndClear();
4040 default:
4041 assert(false && "this cannot happen"); for (;;) { std::abort(); }
4045 bool SourceProviderType::equals(SourceProviderType const & other) const {
4046 if (type != other.type || name != other.name
4047 || subtypes.size() != other.subtypes.size())
4049 return false;
4051 for (auto i(subtypes.begin()), j(other.subtypes.begin());
4052 i != subtypes.end(); ++i, ++j)
4054 if (!i->equals(*j)) {
4055 return false;
4058 return true;
4061 bool SourceProviderInterfaceTypeEntityPad::addDirectBase(
4062 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4063 DirectBase const & base, bool optional)
4065 std::set<OUString> seen;
4066 if (!(checkBaseClashes(
4067 location, yyscanner, data, base.name, base.entity, true, optional,
4068 optional, &seen)
4069 && addBase(
4070 location, yyscanner, data, base.name, base.name, base.entity,
4071 true, optional)))
4073 return false;
4075 if (optional) {
4076 addOptionalBaseMembers(
4077 location, yyscanner, data, base.name, base.entity);
4079 (optional ? directOptionalBases : directMandatoryBases).push_back(base);
4080 return true;
4083 bool SourceProviderInterfaceTypeEntityPad::addDirectMember(
4084 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4085 OUString const & name)
4087 assert(data != nullptr);
4088 if (!checkMemberClashes(location, yyscanner, data, u"", name, true)) {
4089 return false;
4091 allMembers.emplace(name, Member(data->currentName));
4092 return true;
4095 bool SourceProviderInterfaceTypeEntityPad::checkBaseClashes(
4096 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4097 OUString const & name,
4098 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4099 bool optional, bool outerOptional, std::set<OUString> * seen) const
4101 assert(data != nullptr);
4102 assert(entity.is());
4103 assert(seen != nullptr);
4104 if (direct || optional || seen->insert(name).second) {
4105 std::map<OUString, BaseKind>::const_iterator i(allBases.find(name));
4106 if (i != allBases.end()) {
4107 switch (i->second) {
4108 case BASE_INDIRECT_OPTIONAL:
4109 if (direct && optional) {
4110 error(
4111 location, yyscanner,
4112 ("interface type " + data->currentName
4113 + " duplicate base " + name));
4114 return false;
4116 break;
4117 case BASE_DIRECT_OPTIONAL:
4118 if (direct || !outerOptional) {
4119 error(
4120 location, yyscanner,
4121 ("interface type " + data->currentName
4122 + " duplicate base " + name));
4123 return false;
4125 return true;
4126 case BASE_INDIRECT_MANDATORY:
4127 if (direct) {
4128 error(
4129 location, yyscanner,
4130 ("interface type " + data->currentName
4131 + " duplicate base " + name));
4132 return false;
4134 return true;
4135 case BASE_DIRECT_MANDATORY:
4136 if (direct || (!optional && !outerOptional)) {
4137 error(
4138 location, yyscanner,
4139 ("interface type " + data->currentName
4140 + " duplicate base " + name));
4141 return false;
4143 return true;
4146 if (direct || !optional) {
4147 for (auto & j: entity->getDirectMandatoryBases()) {
4148 OUString n("." + j.name);
4149 unoidl::detail::SourceProviderEntity const * p;
4150 if (findEntity(
4151 location, yyscanner, data, true, &n, &p, nullptr,
4152 nullptr)
4153 == FOUND_ERROR)
4155 return false;
4157 if (p == nullptr || !p->entity.is()
4158 || (p->entity->getSort()
4159 != unoidl::Entity::SORT_INTERFACE_TYPE))
4161 error(
4162 location, yyscanner,
4163 ("inconsistent type manager: interface type "
4164 + data->currentName + " base " + n
4165 + " does not resolve to an existing interface type"));
4166 return false;
4168 if (!checkBaseClashes(
4169 location, yyscanner, data, n,
4170 static_cast<unoidl::InterfaceTypeEntity *>(
4171 p->entity.get()),
4172 false, false, outerOptional, seen))
4174 return false;
4177 for (auto & j: entity->getDirectOptionalBases()) {
4178 OUString n("." + j.name);
4179 unoidl::detail::SourceProviderEntity const * p;
4180 if (findEntity(
4181 location, yyscanner, data, true, &n, &p, nullptr,
4182 nullptr)
4183 == FOUND_ERROR)
4185 return false;
4187 if (p == nullptr || !p->entity.is()
4188 || (p->entity->getSort()
4189 != unoidl::Entity::SORT_INTERFACE_TYPE))
4191 error(
4192 location, yyscanner,
4193 ("inconsistent type manager: interface type "
4194 + data->currentName + " base " + n
4195 + " does not resolve to an existing interface type"));
4196 return false;
4198 if (!checkBaseClashes(
4199 location, yyscanner, data, n,
4200 static_cast<unoidl::InterfaceTypeEntity *>(
4201 p->entity.get()),
4202 false, true, outerOptional, seen))
4204 return false;
4207 for (auto & j: entity->getDirectAttributes()) {
4208 if (!checkMemberClashes(
4209 location, yyscanner, data, name, j.name,
4210 !outerOptional))
4212 return false;
4215 for (auto & j: entity->getDirectMethods()) {
4216 if (!checkMemberClashes(
4217 location, yyscanner, data, name, j.name,
4218 !outerOptional))
4220 return false;
4225 return true;
4228 bool SourceProviderInterfaceTypeEntityPad::checkMemberClashes(
4229 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4230 std::u16string_view interfaceName, OUString const & memberName,
4231 bool checkOptional) const
4233 std::map<OUString, Member>::const_iterator i(allMembers.find(memberName));
4234 if (i != allMembers.end()) {
4235 if (!i->second.mandatory.isEmpty()) {
4236 // For a direct member, interfaceName will be empty, so this will
4237 // catch two direct members with the same name:
4238 if (i->second.mandatory != interfaceName) {
4239 error(
4240 location, yyscanner,
4241 ("interface type " + data->currentName
4242 + " duplicate member " + memberName));
4243 return false;
4245 } else if (checkOptional) {
4246 for (auto & j: i->second.optional) {
4247 if (j != interfaceName) {
4248 error(
4249 location, yyscanner,
4250 ("interface type " + data->currentName
4251 + " duplicate member " + memberName));
4252 return false;
4257 return true;
4260 bool SourceProviderInterfaceTypeEntityPad::addBase(
4261 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4262 OUString const & directBaseName, OUString const & name,
4263 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4264 bool optional)
4266 assert(data != nullptr);
4267 assert(entity.is());
4268 BaseKind kind = optional
4269 ? direct ? BASE_DIRECT_OPTIONAL : BASE_INDIRECT_OPTIONAL
4270 : direct ? BASE_DIRECT_MANDATORY : BASE_INDIRECT_MANDATORY;
4271 std::pair<std::map<OUString, BaseKind>::iterator, bool> p(
4272 allBases.emplace(name, kind));
4273 bool seen = !p.second && p.first->second >= BASE_INDIRECT_MANDATORY;
4274 if (!p.second && kind > p.first->second) {
4275 p.first->second = kind;
4277 if (!optional && !seen) {
4278 for (auto & i: entity->getDirectMandatoryBases()) {
4279 OUString n("." + i.name);
4280 unoidl::detail::SourceProviderEntity const * q;
4281 if (findEntity(
4282 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4283 == FOUND_ERROR)
4285 return false;
4287 if (q == nullptr || !q->entity.is()
4288 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4290 error(
4291 location, yyscanner,
4292 ("inconsistent type manager: interface type "
4293 + data->currentName + " base " + n
4294 + " does not resolve to an existing interface type"));
4295 return false;
4297 if (!addBase(
4298 location, yyscanner, data, directBaseName, n,
4299 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4300 false, false))
4302 return false;
4305 for (auto & i: entity->getDirectOptionalBases())
4307 OUString n("." + i.name);
4308 unoidl::detail::SourceProviderEntity const * q;
4309 if (findEntity(
4310 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4311 == FOUND_ERROR)
4313 return false;
4315 if (q == nullptr || !q->entity.is()
4316 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4318 error(
4319 location, yyscanner,
4320 ("inconsistent type manager: interface type "
4321 + data->currentName + " base " + n
4322 + " does not resolve to an existing interface type"));
4323 return false;
4325 if (!addBase(
4326 location, yyscanner, data, directBaseName, n,
4327 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4328 false, true))
4330 return false;
4333 for (auto & i: entity->getDirectAttributes()) {
4334 allMembers.emplace(i.name, Member(name));
4336 for (auto & i: entity->getDirectMethods()) {
4337 allMembers.emplace(i.name, Member(name));
4340 return true;
4343 bool SourceProviderInterfaceTypeEntityPad::addOptionalBaseMembers(
4344 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4345 OUString const & name,
4346 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity)
4348 assert(entity.is());
4349 for (auto & i: entity->getDirectMandatoryBases()) {
4350 OUString n("." + i.name);
4351 unoidl::detail::SourceProviderEntity const * p;
4352 if (findEntity(
4353 location, yyscanner, data, true, &n, &p, nullptr, nullptr)
4354 == FOUND_ERROR)
4356 return false;
4358 if (p == nullptr || !p->entity.is()
4359 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4361 error(
4362 location, yyscanner,
4363 ("inconsistent type manager: interface type "
4364 + data->currentName + " base " + n
4365 + " does not resolve to an existing interface type"));
4366 return false;
4368 if (!addOptionalBaseMembers(
4369 location, yyscanner, data, n,
4370 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())))
4372 return false;
4375 for (auto & i: entity->getDirectAttributes()) {
4376 Member & m(
4377 allMembers.emplace(i.name, Member(""))
4378 .first->second);
4379 if (m.mandatory.isEmpty()) {
4380 m.optional.insert(name);
4383 for (auto & i: entity->getDirectMethods()) {
4384 Member & m(
4385 allMembers.emplace(i.name, Member(""))
4386 .first->second);
4387 if (m.mandatory.isEmpty()) {
4388 m.optional.insert(name);
4391 return true;
4394 bool parse(OUString const & uri, SourceProviderScannerData * data) {
4395 assert(data != nullptr);
4396 oslFileHandle handle;
4397 oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
4398 switch (e) {
4399 case osl_File_E_None:
4400 break;
4401 case osl_File_E_NOENT:
4402 return false;
4403 default:
4404 throw FileFormatException(uri, "cannot open: " + OUString::number(e));
4406 sal_uInt64 size;
4407 e = osl_getFileSize(handle, &size);
4408 if (e != osl_File_E_None) {
4409 oslFileError e2 = osl_closeFile(handle);
4410 SAL_WARN_IF(
4411 e2 != osl_File_E_None, "unoidl",
4412 "cannot close " << uri << ": " << +e2);
4413 throw FileFormatException(
4414 uri, "cannot get size: " + OUString::number(e));
4416 void * address;
4417 e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
4418 if (e != osl_File_E_None) {
4419 oslFileError e2 = osl_closeFile(handle);
4420 SAL_WARN_IF(
4421 e2 != osl_File_E_None, "unoidl",
4422 "cannot close " << uri << ": " << +e2);
4423 throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
4425 try {
4426 data->setSource(address, size);
4427 yyscan_t yyscanner;
4428 if (yylex_init_extra(data, &yyscanner) != 0) {
4429 // Checking errno for the specific EINVAL, ENOMEM documented for
4430 // yylex_init_extra would not work as those values are not defined
4431 // by the C++ Standard:
4432 int e2 = errno;
4433 throw FileFormatException(
4434 uri,
4435 "yylex_init_extra failed with errno " + OUString::number(e2));
4437 int e2 = yyparse(yyscanner);
4438 yylex_destroy(yyscanner);
4439 switch (e2) {
4440 case 0:
4441 break;
4442 default:
4443 O3TL_UNREACHABLE;
4444 case 1:
4445 throw FileFormatException(
4446 uri,
4447 ("cannot parse"
4448 + (data->errorLine == 0
4449 ? OUString() : " line " + OUString::number(data->errorLine))
4450 + (data->parserError.isEmpty()
4451 ? OUString()
4452 : (", "
4453 + OStringToOUString(
4454 data->parserError, osl_getThreadTextEncoding())))
4455 + (data->errorMessage.isEmpty()
4456 ? OUString() : ": \"" + data->errorMessage + "\"")));
4457 case 2:
4458 throw std::bad_alloc();
4460 } catch (...) {
4461 e = osl_unmapMappedFile(handle, address, size);
4462 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4463 e = osl_closeFile(handle);
4464 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4465 throw;
4467 e = osl_unmapMappedFile(handle, address, size);
4468 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4469 e = osl_closeFile(handle);
4470 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4471 return true;
4476 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */