Quelle sourceprovider-parser.y
Sprache: unbekannt
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*TODO: check Exception, RuntimeException, XInterface defns */
%locations
%pure-parser
%{
#include <sal/config.h>
#include <o3tl/unreachable.hxx>
#include <o3tl/string_view.hxx>
#include <rtl/ustrbuf.hxx>
#include <unoidl/unoidl.hxx>
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstddef>
#include <cstdlib>
#include <limits>
#include <new>
#include <utility>
#include <vector>
#include "sourceprovider-parser-requires.hxx"
%}
%union {
sal_uInt64 ival;
double fval;
OString * sval;
bool bval;
std::vector<OUString> * excns;
unoidl::detail::SourceProviderAccessDecls decls;
unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
unoidl::detail::SourceProviderFlags flags;
unoidl::detail::SourceProviderExpr expr;
unoidl::detail::SourceProviderType * type;
std::vector<unoidl::detail::SourceProviderType> * types;
}
/* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
%lex-param {yyscan_t yyscanner}
%parse-param {yyscan_t yyscanner}
%{
#include <osl/file.h>
#include <osl/thread.h>
#include <sal/log.hxx>
#include "sourceprovider-scanner.hxx"
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { (Current) = YYRHSLOC((Rhs), (N) ? 1 : 0); } while (0)
static void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
assert(locp != nullptr);
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->errorLine = *locp;
data->parserError = OString(msg);
}
namespace {
void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->errorLine = location;
data->errorMessage = message;
}
OUString flagName(unoidl::detail::SourceProviderFlags flag) {
switch (flag) {
case unoidl::detail::FLAG_ATTRIBUTE:
return u"attribute"_ustr;
case unoidl::detail::FLAG_BOUND:
return u"bound"_ustr;
case unoidl::detail::FLAG_CONSTRAINED:
return u"constrained"_ustr;
case unoidl::detail::FLAG_MAYBEAMBIGUOUS:
return u"maybeambiguous"_ustr;
case unoidl::detail::FLAG_MAYBEDEFAULT:
return u"maybedefault"_ustr;
case unoidl::detail::FLAG_MAYBEVOID:
return u"maybevoid"_ustr;
case unoidl::detail::FLAG_OPTIONAL:
return u"optional"_ustr;
case unoidl::detail::FLAG_PROPERTY:
return u"property"_ustr;
case unoidl::detail::FLAG_READONLY:
return u"readonly"_ustr;
case unoidl::detail::FLAG_REMOVABLE:
return u"removable"_ustr;
case unoidl::detail::FLAG_TRANSIENT:
return u"transient"_ustr;
default:
assert(false && "this cannot happen"); for (;;) { std::abort(); }
}
}
OUString convertName(OString const * name) {
assert(name != nullptr);
OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
delete name;
return s;
}
OUString convertToFullName(
unoidl::detail::SourceProviderScannerData const * data,
OString const * identifier)
{
assert(data != nullptr);
OUString pref;
if (!data->modules.empty()) {
pref = data->modules.back() + ".";
}
return pref + convertName(identifier);
}
void convertToCurrentName(
unoidl::detail::SourceProviderScannerData * data,
OString const * identifier)
{
assert(data != nullptr);
assert(data->currentName.isEmpty());
data->currentName = convertToFullName(data, identifier);
assert(!data->currentName.isEmpty());
}
void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
assert(data != nullptr);
data->currentName.clear();
data->publishedContext = false;
}
unoidl::detail::SourceProviderEntity * getCurrentEntity(
unoidl::detail::SourceProviderScannerData * data)
{
assert(data != nullptr);
assert(!data->currentName.isEmpty());
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
data->entities.find(data->currentName));
assert(i != data->entities.end());
assert(i->second.kind == unoidl::detail::SourceProviderEntity::KIND_LOCAL);
assert(i->second.pad.is());
return &i->second;
}
template<typename T> rtl::Reference<T> getCurrentPad(
unoidl::detail::SourceProviderScannerData * data)
{
rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
assert(pad.is());
return pad;
}
bool nameHasSameIdentifierAs(std::u16string_view name, std::u16string_view identifier)
{
std::u16string_view::size_type pos = name.rfind('.');
size_t i = (pos != std::u16string_view::npos) ? pos + 1 : 0;
return identifier.size() == name.size() - i
&& o3tl::starts_with(name.substr(i), identifier);
}
bool coerce(
YYLTYPE location, yyscan_t yyscanner,
unoidl::detail::SourceProviderExpr * lhs,
unoidl::detail::SourceProviderExpr * rhs)
{
assert(lhs != nullptr);
assert(rhs != nullptr);
bool ok = bool(); // avoid warnings
switch (lhs->type) {
case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
ok = rhs->type != unoidl::detail::SourceProviderExpr::TYPE_BOOL;
break;
case unoidl::detail::SourceProviderExpr::TYPE_INT:
switch (rhs->type) {
case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
ok = false;
break;
case unoidl::detail::SourceProviderExpr::TYPE_INT:
ok = true;
break;
case unoidl::detail::SourceProviderExpr::TYPE_UINT:
if (lhs->ival >= 0) {
lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
ok = true;
} else if (rhs->uval <= SAL_MAX_INT64) {
rhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
ok = true;
} else {
ok = false;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
{
auto tmp = lhs->ival;
lhs->fval = tmp;
ok = true;
}
break;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_UINT:
switch (rhs->type) {
case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
ok = false;
break;
case unoidl::detail::SourceProviderExpr::TYPE_INT:
if (rhs->ival >= 0) {
rhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
ok = true;
} else if (lhs->uval <= SAL_MAX_INT64) {
lhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
ok = true;
} else {
ok = false;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_UINT:
ok = true;
break;
case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
{
auto nTmp = lhs->uval;
lhs->fval = nTmp;
ok = true;
}
break;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
switch (rhs->type) {
case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
ok = false;
break;
case unoidl::detail::SourceProviderExpr::TYPE_INT:
{
auto tmp = rhs->ival;
rhs->fval = tmp;
ok = true;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_UINT:
{
auto tmp = rhs->uval;
rhs->fval = tmp;
ok = true;
}
break;
case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
ok = true;
break;
}
break;
}
if (!ok) {
error(location, yyscanner, u"cannot coerce binary expression arguments"_ustr);
}
return ok;
}
unoidl::detail::SourceProviderEntity * findEntity_(
unoidl::detail::SourceProviderScannerData * data, OUString * name)
{
assert(data != nullptr);
assert(name != nullptr);
OUString n;
if (!name->startsWith(".", &n)) {
for (auto i(data->modules.rbegin()); i != data->modules.rend(); ++i) {
n = *i + "." + *name;
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
data->entities.find(n));
if (j != data->entities.end()) {
*name = n;
return &j->second;
}
rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
if (ent.is()) {
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
k(data->entities.emplace(
n,
unoidl::detail::SourceProviderEntity(
unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
ent)).
first);
*name = n;
return &k->second;
}
}
n = *name;
}
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
data->entities.find(n));
if (i != data->entities.end()) {
*name = n;
return &i->second;
}
rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
if (ent.is()) {
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
j(data->entities.emplace(
n,
unoidl::detail::SourceProviderEntity(
unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
ent)).
first);
*name = n;
return &j->second;
}
return nullptr;
}
enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
Found findEntity(
YYLTYPE location, yyscan_t yyscanner,
unoidl::detail::SourceProviderScannerData * data,
bool resolveInterfaceDefinitions, OUString * name,
unoidl::detail::SourceProviderEntity const ** entity, bool * typedefed,
unoidl::detail::SourceProviderType * typedefedType)
{
//TODO: avoid recursion
assert(data != nullptr);
assert(name != nullptr);
assert(entity != nullptr);
unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
OUString n(*name);
OUString typeNucleus;
std::size_t rank = 0;
std::vector<unoidl::detail::SourceProviderType> args;
for (;;) {
if (e != nullptr) {
switch (e->kind) {
case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
if (e->pad.is()) {
break;
}
assert(e->entity.is());
[[fallthrough]];
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
if (typedefed != nullptr) {
*typedefed = true;
}
if (data->publishedContext
&& !static_cast<unoidl::TypedefEntity *>(
e->entity.get())->isPublished())
{
error(
location, yyscanner,
("type " + *name + " based on unpublished typedef "
+ n + " used in published context"));
return FOUND_ERROR;
}
OUString t(
static_cast<unoidl::TypedefEntity *>(e->entity.get())
->getType());
typeNucleus = t;
while (typeNucleus.startsWith("[]", &typeNucleus)) {
if (!args.empty()) {
error(
location, yyscanner,
("inconsistent type manager: bad type " + *name
+ (" based on instantiated polymorphic struct"
" type based on sequence type named ")
+ t));
return FOUND_ERROR;
}
if (rank == std::numeric_limits<std::size_t>::max()) {
error(
location, yyscanner,
("bad type " + *name
+ " based on sequence type of too high rank"));
return FOUND_ERROR;
}
++rank;
}
sal_Int32 i = typeNucleus.indexOf('<');
if (i != -1) {
if (!args.empty()) {
error(
location, yyscanner,
("inconsistent type manager: bad type " + *name
+ (" based on instantiated polymorphic struct"
" type based on instantiated polymorphic"
" struct type named ")
+ t));
return FOUND_ERROR;
}
std::u16string_view tmpl(typeNucleus.subView(0, i));
do {
++i; // skip '<' or ','
sal_Int32 j = i;
for (sal_Int32 level = 0;
j != typeNucleus.getLength(); ++j)
{
sal_Unicode c = typeNucleus[j];
if (c == ',') {
if (level == 0) {
break;
}
} else if (c == '<') {
++level;
} else if (c == '>') {
if (level == 0) {
break;
}
--level;
}
}
if (j != typeNucleus.getLength()) {
OUString argName(typeNucleus.copy(i, j - i));
unoidl::detail::SourceProviderEntity const *
argEnt;
unoidl::detail::SourceProviderType argType;
switch (
findEntity(
location, yyscanner, data, false,
&argName, &argEnt, nullptr, &argType))
{
case FOUND_ERROR:
return FOUND_ERROR;
case FOUND_TYPE:
break;
case FOUND_ENTITY:
if (argEnt == nullptr) {
error(
location, yyscanner,
(("inconsistent type manager: bad"
" instantiated polymorphic struct"
" type template type argument ")
+ argName));
return FOUND_ERROR;
} else {
unoidl::detail::SourceProviderType::Type
argT
= unoidl::detail::SourceProviderType::Type();
// avoid warnings
switch (argEnt->kind) {
case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
if (e->pad.is()) {
error(
location, yyscanner,
(("inconsistent type"
" manager: bad"
" instantiated"
" polymorphic struct type"
" template type"
" argument ")
+ argName));
return FOUND_ERROR;
}
assert(e->entity.is());
[[fallthrough]];
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
switch (e->entity->getSort()) {
case unoidl::Entity::SORT_ENUM_TYPE:
argT = unoidl::detail::SourceProviderType::TYPE_ENUM;
break;
case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
argT = unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT;
break;
case unoidl::Entity::SORT_INTERFACE_TYPE:
argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
break;
default:
error(
location, yyscanner,
(("inconsistent type"
"manager: bad"
" instantiated"
" polymorphic struct type"
" template type"
" argument ")
+ argName));
return FOUND_ERROR;
}
break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE:
assert(false && "this cannot happen");
}
argType
= unoidl::detail::SourceProviderType(
argT, argName, argEnt);
}
break;
}
args.push_back(argType);
}
i = j;
} while (i != typeNucleus.getLength()
&& typeNucleus[i] != '>');
if (i != typeNucleus.getLength() - 1
|| typeNucleus[i] != '>')
{
error(
location, yyscanner,
("inconsistent type manager: bad type name \""
+ t + "\""));
return FOUND_ERROR;
}
assert(!args.empty());
typeNucleus = tmpl;
}
if (typeNucleus.isEmpty()) {
error(
location, yyscanner,
("inconsistent type manager: bad type name \"" + t
+ "\""));
return FOUND_ERROR;
}
if (typeNucleus == "void") {
error(
location, yyscanner,
("inconsistent type manager: bad type " + *name
+ " based on void"));
return FOUND_ERROR;
}
if (typeNucleus == "boolean" || typeNucleus == "byte"
|| typeNucleus == "short"
|| typeNucleus == "unsigned short"
|| typeNucleus == "long"
|| typeNucleus == "unsigned long"
|| typeNucleus == "hyper"
|| typeNucleus == "unsigned hyper"
|| typeNucleus == "float" || typeNucleus == "double"
|| typeNucleus == "char" || typeNucleus == "string"
|| typeNucleus == "type" || typeNucleus == "any")
{
if (!args.empty()) {
error(
location, yyscanner,
("inconsistent type manager: bad type " + *name
+ (" based on instantiated polymorphic struct"
" type based on ")
+ typeNucleus));
return FOUND_ERROR;
}
break;
}
n = "." + typeNucleus;
typeNucleus.clear();
e = findEntity_(data, &n);
continue;
}
break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
if (resolveInterfaceDefinitions) {
rtl::Reference<unoidl::Entity> ent(
data->manager->findEntity(n));
// Do not allow ent to be of SORT_TYPEDEF:
if (!ent.is()
|| (ent->getSort()
!= unoidl::Entity::SORT_INTERFACE_TYPE))
{
error(
location, yyscanner,
(*name + " is based on interface declaration " + n
+ " that is not an interface type entity"));
return FOUND_ERROR;
}
e->kind
= unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
e->entity = std::move(ent);
}
break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE:
error(
location, yyscanner,
*name + " is based on module entity " + n);
return FOUND_ERROR;
}
}
if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
if (typeNucleus.isEmpty() && e == nullptr) {
// Found a type name based on an unknown entity:
*entity = nullptr;
return FOUND_ENTITY;
}
unoidl::detail::SourceProviderType t;
if (args.empty()) {
if (typeNucleus == "boolean") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
} else if (typeNucleus == "byte") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_BYTE);
} else if (typeNucleus == "short") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_SHORT);
} else if (typeNucleus == "unsigned short") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
} else if (typeNucleus == "long") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_LONG);
} else if (typeNucleus == "unsigned long") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
} else if (typeNucleus == "hyper") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_HYPER);
} else if (typeNucleus == "unsigned hyper") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
} else if (typeNucleus == "float") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_FLOAT);
} else if (typeNucleus == "double") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_DOUBLE);
} else if (typeNucleus == "char") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_CHAR);
} else if (typeNucleus == "string") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_STRING);
} else if (typeNucleus == "type") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_TYPE);
} else if (typeNucleus == "any") {
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_ANY);
} else {
assert(typeNucleus.isEmpty());
assert(e != nullptr);
switch (e->kind) {
case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
if (e->pad.is()) {
if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
e->pad.get())
!= nullptr)
{
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_ENUM,
n, e);
} else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
e->pad.get())
!= nullptr)
{
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
n, e);
} else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
e->pad.get())
!= nullptr)
{
error(
location, yyscanner,
("bad type " + *name
+ (" based on recursive reference to"
" polymorphic struct type template ")
+ n));
return FOUND_ERROR;
} else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
e->pad.get())
!= nullptr)
{
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
n, e);
} else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
e->pad.get())
!= nullptr)
{
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_INTERFACE,
n, e);
} else {
error(
location, yyscanner,
("bad type " + *name
+ " based on non-type entity " + n));
return FOUND_ERROR;
}
break;
}
assert(e->entity.is());
[[fallthrough]];
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
switch (e->entity->getSort()) {
case unoidl::Entity::SORT_ENUM_TYPE:
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_ENUM,
n, e);
break;
case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
n, e);
break;
case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
error(
location, yyscanner,
("bad type " + *name
+ " based on polymorphic struct type template "
+ n + " without type arguments"));
return FOUND_ERROR;
case unoidl::Entity::SORT_EXCEPTION_TYPE:
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
n, e);
break;
case unoidl::Entity::SORT_INTERFACE_TYPE:
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_INTERFACE,
n, e);
break;
default:
error(
location, yyscanner,
("bad type " + *name
+ " based on non-type entity " + n));
return FOUND_ERROR;
}
break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_INTERFACE,
n, e);
break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE:
assert(false && "this cannot happen");
}
}
} else {
assert(typeNucleus.isEmpty());
assert(e != nullptr);
switch (e->kind) {
case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
if (e->pad.is()) {
error(
location, yyscanner,
("bad type " + *name
+ (" based on instantiated polymorphic struct type"
" based on ")
+ n
+ (" that is either not a polymorphic struct type"
" template or a recursive reference to a"
" polymorphic struct type template")));
return FOUND_ERROR;
}
assert(e->entity.is());
[[fallthrough]];
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
if (e->entity->getSort()
== unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
{
if (args.size()
!= (static_cast<
unoidl::PolymorphicStructTypeTemplateEntity *>(
e->entity.get())
->getTypeParameters().size()))
{
error(
location, yyscanner,
("bad type " + *name
+ (" based on instantiated polymorphic struct"
" type with ")
+ OUString::number(args.size())
+ (" type arguments based on polymorphic"
" struct type template ")
+ n + " with "
+ OUString::number(
static_cast<
unoidl::PolymorphicStructTypeTemplateEntity *>(
e->entity.get())
->getTypeParameters().size())
+ " type parameters"));
return FOUND_ERROR;
}
t = unoidl::detail::SourceProviderType(n, e, std::move(args));
break;
}
[[fallthrough]];
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
error(
location, yyscanner,
("bad type " + *name
+ (" based on instantiated polymorphic struct type"
" based on ")
+ n
+ " that is not a polymorphic struct type template"));
return FOUND_ERROR;
case unoidl::detail::SourceProviderEntity::KIND_MODULE:
assert(false && "this cannot happen");
}
}
if (typedefedType != nullptr) {
for (std::size_t i = 0; i != rank; ++i) {
t = unoidl::detail::SourceProviderType(&t);
}
*typedefedType = std::move(t);
typedefedType->typedefName = *name;
}
*entity = nullptr;
return FOUND_TYPE;
}
*entity = e;
return FOUND_ENTITY;
}
}
bool checkTypeArgument(
YYLTYPE location, yyscan_t yyscanner,
unoidl::detail::SourceProviderType const & type)
{
switch (type.type) {
case unoidl::detail::SourceProviderType::TYPE_VOID:
case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
error(
location, yyscanner,
u"bad instantiated polymorphic struct type argument"_ustr);
return false;
case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
return checkTypeArgument(location, yyscanner, type.subtypes.front());
default:
return true;
}
}
bool checkInstantiatedPolymorphicStructTypeArgument(
unoidl::detail::SourceProviderType const & type, OUString const & name)
{
if (type.type
== unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
{
for (auto & i: type.subtypes) {
if (checkInstantiatedPolymorphicStructTypeArgument(i, name)
|| i.getName() == name) // no need to worry about typedef
{
return true;
}
}
}
return false;
}
std::vector<OUString> annotations(bool deprecated) {
std::vector<OUString> ann;
if (deprecated) {
ann.push_back(u"deprecated"_ustr);
}
return ann;
}
}
%}
%token TOK_ELLIPSIS
%token TOK_COLONS
%token TOK_LEFTSHIFT
%token TOK_RIGHTSHIFT
%token TOK_FALSE
%token TOK_TRUE
%token TOK_ANY
%token TOK_ATTRIBUTE
%token TOK_BOOLEAN
%token TOK_BOUND
%token TOK_BYTE
%token TOK_CHAR
%token TOK_CONST
%token TOK_CONSTANTS
%token TOK_CONSTRAINED
%token TOK_DOUBLE
%token TOK_ENUM
%token TOK_EXCEPTION
%token TOK_FLOAT
%token TOK_GET
%token TOK_HYPER
%token TOK_IN
%token TOK_INOUT
%token TOK_INTERFACE
%token TOK_LONG
%token TOK_MAYBEAMBIGUOUS
%token TOK_MAYBEDEFAULT
%token TOK_MAYBEVOID
%token TOK_MODULE
%token TOK_OPTIONAL
%token TOK_OUT
%token TOK_PROPERTY
%token TOK_PUBLISHED
%token TOK_RAISES
%token TOK_READONLY
%token TOK_REMOVABLE
%token TOK_SEQUENCE
%token TOK_SERVICE
%token TOK_SET
%token TOK_SHORT
%token TOK_SINGLETON
%token TOK_STRING
%token TOK_STRUCT
%token TOK_TRANSIENT
%token TOK_TYPE
%token TOK_TYPEDEF
%token TOK_UNSIGNED
%token TOK_VOID
%token<sval> TOK_IDENTIFIER
%token<ival> TOK_INTEGER
%token<fval> TOK_FLOATING
%token TOK_DEPRECATED
%token TOK_ERROR
%type<sval> identifier name singleInheritance singleInheritance_opt
%type<bval> ctors_opt deprecated_opt ellipsis_opt published_opt
%type<decls> attributeAccessDecl attributeAccessDecls
%type<dir> direction
%type<excns> exceptionSpec exceptionSpec_opt exceptions
%type<flags> flag flagSection flagSection_opt flags
%type<expr> addExpr andExpr expr multExpr orExpr primaryExpr shiftExpr unaryExpr
xorExpr
%type<type> type
%type<types> typeArguments
%initial-action { yylloc = 1; }
%%
definitions:
definitions definition
| /* empty */
;
definition:
moduleDecl
| enumDefn
| plainStructDefn
| polymorphicStructTemplateDefn
| exceptionDefn
| interfaceDefn
| typedefDefn
| constantGroupDefn
| singleInterfaceBasedServiceDefn
| accumulationBasedServiceDefn
| interfaceBasedSingletonDefn
| serviceBasedSingletonDefn
| interfaceDecl
;
moduleDecl:
TOK_MODULE identifier
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
OUString name(convertToFullName(data, $2));
data->modules.push_back(name);
std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
data->entities.emplace(
name,
unoidl::detail::SourceProviderEntity(
unoidl::detail::SourceProviderEntity::KIND_MODULE)));
if (!p.second
&& (p.first->second.kind
!= unoidl::detail::SourceProviderEntity::KIND_MODULE))
{
error(@2, yyscanner, "multiple entities named " + name);
YYERROR;
}
}
'{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
;
enumDefn:
deprecated_opt published_opt TOK_ENUM identifier
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4);
if (!data->entities.emplace(
data->currentName,
unoidl::detail::SourceProviderEntity(
new unoidl::detail::SourceProviderEnumTypeEntityPad(
$2))).
second)
{
error(@4, yyscanner, "multiple entities named " + data->currentName);
YYERROR;
}
}
'{' enumMembers '}' ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
ent->pad.get());
assert(pad != nullptr);
ent->entity = new unoidl::EnumTypeEntity(
pad->isPublished(), std::move(pad->members), annotations($1));
ent->pad.clear();
clearCurrentState(data);
}
;
enumMembers:
| enumMembers ',' enumMember
| enumMember
;
enumMember:
deprecated_opt identifier
{
OUString id(convertName($2));
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
sal_Int32 v;
if (pad->members.empty()) {
v = 0;
} else {
v = pad->members.back().value;
if (v == SAL_MAX_INT32) {
error(
@2, yyscanner,
("enum " + data->currentName + " member " + id
+ " would have out-of-range value 2^31"));
YYERROR;
}
++v;
}
pad->members.emplace_back(id, v, annotations($1));
}
| deprecated_opt identifier '=' expr
{
OUString id(convertName($2));
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
sal_Int32 v;
switch ($4.type) {
case unoidl::detail::SourceProviderExpr::TYPE_INT:
if ($4.ival < SAL_MIN_INT32 || $4.ival > SAL_MAX_INT32) {
error(
@4, yyscanner,
("out-of-range enum " + data->currentName + " member " + id
+ " value " + OUString::number($4.ival)));
YYERROR;
}
v = static_cast<sal_Int32>($4.ival);
break;
case unoidl::detail::SourceProviderExpr::TYPE_UINT:
if ($4.uval > SAL_MAX_INT32) {
error(
@4, yyscanner,
("out-of-range enum " + data->currentName + " member " + id
+ " value " + OUString::number($4.uval)));
YYERROR;
}
v = static_cast<sal_Int32>($4.uval);
break;
default:
error(
@4, yyscanner,
("non-integer enum " + data->currentName + " member " + id
+ " value"));
YYERROR;
break;
}
pad->members.emplace_back(id, v, annotations($1));
}
;
plainStructDefn:
deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4);
OUString baseName;
rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
if ($5 != nullptr) {
baseName = convertName($5);
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(
@5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
{
error(
@5, yyscanner,
("plain struct type " + data->currentName + " base "
+ baseName
+ " does not resolve to an existing plain struct type"));
YYERROR;
}
baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
p->entity.get());
if ($2 && !baseEnt->isPublished()) {
error(
@5, yyscanner,
("published plain struct type " + data->currentName + " base "
+ baseName + " is unpublished"));
YYERROR;
}
}
if (!data->entities.emplace(
data->currentName,
unoidl::detail::SourceProviderEntity(
new unoidl::detail::SourceProviderPlainStructTypeEntityPad(
$2, baseName, baseEnt))).
second)
{
error(@4, yyscanner, "multiple entities named " + data->currentName);
YYERROR;
}
}
'{' structMembers '}' ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
dynamic_cast<
unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
ent->pad.get());
assert(pad != nullptr);
ent->entity = new unoidl::PlainStructTypeEntity(
pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
ent->pad.clear();
clearCurrentState(data);
}
;
polymorphicStructTemplateDefn:
deprecated_opt published_opt TOK_STRUCT identifier '<'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4);
if (!data->entities.emplace(
data->currentName,
unoidl::detail::SourceProviderEntity(
new unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad(
$2))).
second)
{
error(@4, yyscanner, "multiple entities named " + data->currentName);
YYERROR;
}
}
typeParameters '>' '{' structMembers '}' ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
pad = dynamic_cast<
unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
ent->pad.get());
assert(pad != nullptr);
ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
pad->isPublished(), std::move(pad->typeParameters), std::move(pad->members),
annotations($1));
ent->pad.clear();
clearCurrentState(data);
}
;
typeParameters:
typeParameters ',' identifier
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
data));
OUString id(convertName($3));
if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
!= pad->typeParameters.end())
{
error(
@3, yyscanner,
("polymorphic struct type template " + data->currentName
+ " type parameter " + id
+ " has same identifier as another type parameter"));
YYERROR;
}
pad->typeParameters.push_back(id);
}
| identifier
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
data));
OUString id(convertName($1));
assert(pad->typeParameters.empty());
pad->typeParameters.push_back(id);
}
;
exceptionDefn:
deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4);
OUString baseName;
rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
if ($5 != nullptr) {
baseName = convertName($5);
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(
@5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE)
{
error(
@5, yyscanner,
("exception type " + data->currentName + " base " + baseName
+ " does not resolve to an existing exception type"));
YYERROR;
}
baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
p->entity.get());
if ($2 && !baseEnt->isPublished()) {
error(
@5, yyscanner,
("published exception type " + data->currentName + " base "
+ baseName + " is unpublished"));
YYERROR;
}
}
if (!data->entities.emplace(
data->currentName,
unoidl::detail::SourceProviderEntity(
new unoidl::detail::SourceProviderExceptionTypeEntityPad(
$2, baseName, baseEnt))).
second)
{
error(@4, yyscanner, "multiple entities named " + data->currentName);
YYERROR;
}
}
'{' structMembers '}' ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
ent->pad.get());
assert(pad != nullptr);
ent->entity = new unoidl::ExceptionTypeEntity(
pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
ent->pad.clear();
clearCurrentState(data);
}
;
structMembers:
structMembers structMember
| /* empty */
;
structMember:
deprecated_opt type identifier ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderType t(*$2);
delete $2;
OUString id(convertName($3));
switch (t.type) {
case unoidl::detail::SourceProviderType::TYPE_VOID:
case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
error(
@2, yyscanner,
("illegal struct/exception type " + data->currentName
+ " direct member " + id + " type"));
YYERROR;
break;
default:
break;
}
if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
&& t.getName() == data->currentName) // no need to worry about typedef
{
error(
@2, yyscanner,
("struct/exception type " + data->currentName + " direct member "
+ id + " has same type as the type itself"));
YYERROR;
}
if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
{
error(
@2, yyscanner,
("struct/exception type " + data->currentName + " direct member "
+ id
+ (" has instantiated polymorphic struct type that uses the type"
" itself as an argument")));
YYERROR;
}
if (nameHasSameIdentifierAs(data->currentName, id)) {
error(
@3, yyscanner,
("struct/exception type " + data->currentName + " direct member "
+ id + " has same unqualified identifier as the type itself"));
YYERROR;
}
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
ent->pad.get());
if (p1 != nullptr) {
for (const auto & i: p1->members) {
if (id == i.name) {
error(
@3, yyscanner,
("plain struct type " + data->currentName
+ " direct member " + id
+ " has same identifier as another direct member"));
YYERROR;
}
}
if (p1->baseEntity.is()) {
OUString baseName(p1->baseName);
for (auto baseEnt(p1->baseEntity);;) {
if (nameHasSameIdentifierAs(baseName, id)) {
error(
@3, yyscanner,
("plain struct type " + data->currentName
+ " direct member " + id
+ " has same unqalified identifier as base "
+ baseName));
YYERROR;
}
for (auto & i: baseEnt->getDirectMembers()) {
if (id == i.name) {
error(
@3, yyscanner,
("plain struct type " + data->currentName
+ " direct member " + id
+ " has same identifier as a member of base "
+ baseName));
YYERROR;
}
}
baseName = baseEnt->getDirectBase();
if (baseName.isEmpty()) {
break;
}
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(
@2, yyscanner, data, false, &baseName, &p, nullptr,
nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| (p->entity->getSort()
!= unoidl::Entity::SORT_PLAIN_STRUCT_TYPE))
{
error(
@2, yyscanner,
("inconsistent type manager: plain struct type "
+ data->currentName + " base " + baseName
+ (" does not resolve to an existing plain struct"
" type")));
YYERROR;
}
baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
p->entity.get());
}
}
p1->members.emplace_back(id, t.getName(), annotations($1));
} else {
unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
ent->pad.get());
if (p2 != nullptr) {
for (const auto & i: p2->members) {
if (id == i.name) {
error(
@3, yyscanner,
("polymorphic struct type template "
+ data->currentName + " direct member " + id
+ " has same identifier as another direct member"));
YYERROR;
}
}
p2->members.emplace_back(
id, t.getName(),
t.type == unoidl::detail::SourceProviderType::TYPE_PARAMETER,
annotations($1));
} else {
unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
= dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
ent->pad.get());
assert(p3 != nullptr);
for (const auto & i: p3->members) {
if (id == i.name) {
error(
@3, yyscanner,
("exception type " + data->currentName
+ " direct member " + id
+ " has same identifier as another direct member"));
YYERROR;
}
}
if (p3->baseEntity.is()) {
OUString baseName(p3->baseName);
for (auto baseEnt(p3->baseEntity);;) {
if (nameHasSameIdentifierAs(baseName, id)) {
error(
@3, yyscanner,
("exception type " + data->currentName
+ " direct member " + id
+ " has same unqalified identifier as base "
+ baseName));
YYERROR;
}
for (auto & i: baseEnt->getDirectMembers()) {
if (id == i.name) {
error(
@3, yyscanner,
("exception type " + data->currentName
+ " direct member " + id
+ " has same identifier as a member of base "
+ baseName));
YYERROR;
}
}
baseName = baseEnt->getDirectBase();
if (baseName.isEmpty()) {
break;
}
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(
@2, yyscanner, data, false, &baseName, &p,
nullptr, nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| (p->entity->getSort()
!= unoidl::Entity::SORT_EXCEPTION_TYPE))
{
error(
@2, yyscanner,
("inconsistent type manager: exception type "
+ data->currentName + " base " + baseName
+ (" does not resolve to an existing exception"
" type")));
YYERROR;
}
baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
p->entity.get());
}
}
p3->members.emplace_back(id, t.getName(), annotations($1));
}
}
}
;
interfaceDefn:
deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4);
OUString baseName;
rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
if ($5 != nullptr) {
baseName = convertName($5);
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(
@5, yyscanner, data, true, &baseName, &p, nullptr, nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
{
error(
@5, yyscanner,
("interface type " + data->currentName + " direct base "
+ baseName
+ " does not resolve to an existing interface type"));
YYERROR;
}
baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
if ($2 && !baseEnt->isPublished()) {
error(
@5, yyscanner,
("published interface type " + data->currentName
+ " direct base " + baseName + " is unpublished"));
YYERROR;
}
}
std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
data->entities.find(data->currentName));
if (i != data->entities.end()) {
switch (i->second.kind) {
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
break;
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
if (!$2) {
error(
@4, yyscanner,
("unpublished interface type " + data->currentName
+ " has been declared published"));
YYERROR;
}
break;
default:
error(
@4, yyscanner,
"multiple entities named " + data->currentName);
YYERROR;
break;
}
}
rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
$2, baseEnt.is()));
if (baseEnt.is()
&& !pad->addDirectBase(
@4, yyscanner, data,
unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
baseName, baseEnt, std::vector<OUString>()),
false))
{
YYERROR;
}
data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
pad);
}
'{' interfaceMembers '}' ';'
{
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
ent->pad.get());
assert(pad != nullptr);
if (pad->directMandatoryBases.empty()
&& data->currentName != "com.sun.star.uno.XInterface")
{
OUString base(u".com.sun.star.uno.XInterface"_ustr);
unoidl::detail::SourceProviderEntity const * p;
if (findEntity(@4, yyscanner, data, true, &base, &p, nullptr, nullptr)
== FOUND_ERROR)
{
YYERROR;
}
if (p == nullptr || !p->entity.is()
|| p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
{
error(
@3, yyscanner,
("interface type " + data->currentName
+ " implicit direct base " + base
+ " does not resolve to an existing interface type"));
YYERROR;
}
if (!pad->addDirectBase(
@3, yyscanner, data,
unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
base,
static_cast<unoidl::InterfaceTypeEntity *>(
p->entity.get()),
std::vector<OUString>()),
false))
{
YYERROR;
}
}
std::vector<unoidl::AnnotatedReference> mbases;
for (auto & i: pad->directMandatoryBases) {
mbases.emplace_back(i.name, std::move(i.annotations));
}
std::vector<unoidl::AnnotatedReference> obases;
--> --------------------
--> maximum size reached
--> --------------------
[ Verzeichnis aufwärts0.28unsichere Verbindung
Übersetzung europäischer Sprachen durch Browser
]
|
2026-03-28
|