Kaydet (Commit) 87dc2228 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Fix unoidl sourceprovider "published" checks

Change-Id: I93b9fcc2b20ed7a7c160a9ef3294b6e578678f53
üst 75144495
...@@ -636,3 +636,46 @@ singleton S: I1; ...@@ -636,3 +636,46 @@ singleton S: I1;
EXPECT SUCCESS "published.tests 118": EXPECT SUCCESS "published.tests 118":
published interface I1 {}; published interface I1 {};
published singleton S: I1; published singleton S: I1;
EXPECT FAILURE "published.tests 119":
interface I1 {};
published interface I2 { [optional] interface I1; };
EXPECT FAILURE "published.tests 120":
service S1 {};
published service S2 { [optional] service S1; };
EXPECT SUCCESS "published.tests 121":
interface I {};
published service S { [optional] interface I; };
EXPECT FAILURE "published.tests 122":
interface I {};
published service S { [optional, property] I p; };
EXPECT FAILURE "published.tests 123":
interface I {};
published service S { [optional, property] sequence<I> p; };
EXPECT FAILURE "published.tests 124":
struct P<T> { T m; };
interface I {};
published service S { [optional, property] P<I> p; };
EXPECT FAILURE "published.tests 125":
published struct P<T> { T m; };
interface I {};
published service S { [optional, property] P<I> p; };
EXPECT FAILURE "published.tests 126":
struct P<T> { T m; };
published interface I {};
published service S { [optional, property] P<I> p; };
...@@ -134,10 +134,10 @@ void convertToCurrentName( ...@@ -134,10 +134,10 @@ void convertToCurrentName(
assert(!data->currentName.isEmpty()); assert(!data->currentName.isEmpty());
} }
void clearCurrentName(unoidl::detail::SourceProviderScannerData * data) { void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
assert(data != 0); assert(data != 0);
assert(!data->currentName.isEmpty());
data->currentName = ""; data->currentName = "";
data->publishedContext = false;
} }
unoidl::detail::SourceProviderEntity * getCurrentEntity( unoidl::detail::SourceProviderEntity * getCurrentEntity(
...@@ -339,6 +339,16 @@ Found findEntity( ...@@ -339,6 +339,16 @@ Found findEntity(
// fall through // fall through
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL: case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) { if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
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( OUString t(
static_cast<unoidl::TypedefEntity *>(e->entity.get()) static_cast<unoidl::TypedefEntity *>(e->entity.get())
->getType()); ->getType());
...@@ -461,6 +471,7 @@ Found findEntity( ...@@ -461,6 +471,7 @@ Found findEntity(
} }
break; break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE; argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
break; break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE: case unoidl::detail::SourceProviderEntity::KIND_MODULE:
...@@ -532,6 +543,7 @@ Found findEntity( ...@@ -532,6 +543,7 @@ Found findEntity(
} }
break; break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
if (resolveInterfaceDefinitions) { if (resolveInterfaceDefinitions) {
rtl::Reference<unoidl::Entity> ent( rtl::Reference<unoidl::Entity> ent(
data->manager->findEntity(n)); data->manager->findEntity(n));
...@@ -702,6 +714,7 @@ Found findEntity( ...@@ -702,6 +714,7 @@ Found findEntity(
} }
break; break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
t = unoidl::detail::SourceProviderType( t = unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_INTERFACE, unoidl::detail::SourceProviderType::TYPE_INTERFACE,
n, e); n, e);
...@@ -761,6 +774,7 @@ Found findEntity( ...@@ -761,6 +774,7 @@ Found findEntity(
} }
// fall through // fall through
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
error( error(
location, yyscanner, location, yyscanner,
("bad type " + *name ("bad type " + *name
...@@ -941,6 +955,7 @@ enumDefn: ...@@ -941,6 +955,7 @@ enumDefn:
deprecated_opt published_opt TOK_ENUM identifier deprecated_opt published_opt TOK_ENUM identifier
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -965,7 +980,7 @@ enumDefn: ...@@ -965,7 +980,7 @@ enumDefn:
ent->entity = new unoidl::EnumTypeEntity( ent->entity = new unoidl::EnumTypeEntity(
pad->isPublished(), pad->members, annotations($1)); pad->isPublished(), pad->members, annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -1043,6 +1058,7 @@ plainStructDefn: ...@@ -1043,6 +1058,7 @@ plainStructDefn:
deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
OUString baseName; OUString baseName;
rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt; rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
...@@ -1066,6 +1082,13 @@ plainStructDefn: ...@@ -1066,6 +1082,13 @@ plainStructDefn:
} }
baseEnt = static_cast<unoidl::PlainStructTypeEntity *>( baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
p->entity.get()); p->entity.get());
if ($2 && !baseEnt->isPublished()) {
error(
@5, yyscanner,
("published plain struct type " + data->currentName + " base "
+ baseName + " is unpublished"));
YYERROR;
}
} }
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -1091,7 +1114,7 @@ plainStructDefn: ...@@ -1091,7 +1114,7 @@ plainStructDefn:
ent->entity = new unoidl::PlainStructTypeEntity( ent->entity = new unoidl::PlainStructTypeEntity(
pad->isPublished(), pad->baseName, pad->members, annotations($1)); pad->isPublished(), pad->baseName, pad->members, annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -1099,6 +1122,7 @@ polymorphicStructTemplateDefn: ...@@ -1099,6 +1122,7 @@ polymorphicStructTemplateDefn:
deprecated_opt published_opt TOK_STRUCT identifier '<' deprecated_opt published_opt TOK_STRUCT identifier '<'
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -1125,7 +1149,7 @@ polymorphicStructTemplateDefn: ...@@ -1125,7 +1149,7 @@ polymorphicStructTemplateDefn:
pad->isPublished(), pad->typeParameters, pad->members, pad->isPublished(), pad->typeParameters, pad->members,
annotations($1)); annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -1182,6 +1206,7 @@ exceptionDefn: ...@@ -1182,6 +1206,7 @@ exceptionDefn:
deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
OUString baseName; OUString baseName;
rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt; rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
...@@ -1204,6 +1229,13 @@ exceptionDefn: ...@@ -1204,6 +1229,13 @@ exceptionDefn:
} }
baseEnt = static_cast<unoidl::ExceptionTypeEntity *>( baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
p->entity.get()); p->entity.get());
if ($2 && !baseEnt->isPublished()) {
error(
@5, yyscanner,
("published exception type " + data->currentName + " base "
+ baseName + " is unpublished"));
YYERROR;
}
} }
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -1228,7 +1260,7 @@ exceptionDefn: ...@@ -1228,7 +1260,7 @@ exceptionDefn:
ent->entity = new unoidl::ExceptionTypeEntity( ent->entity = new unoidl::ExceptionTypeEntity(
pad->isPublished(), pad->baseName, pad->members, annotations($1)); pad->isPublished(), pad->baseName, pad->members, annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -1458,6 +1490,7 @@ interfaceDefn: ...@@ -1458,6 +1490,7 @@ interfaceDefn:
deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
OUString baseName; OUString baseName;
rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt; rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
...@@ -1480,15 +1513,36 @@ interfaceDefn: ...@@ -1480,15 +1513,36 @@ interfaceDefn:
YYERROR; YYERROR;
} }
baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()); 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( std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
data->entities.find(data->currentName)); data->entities.find(data->currentName));
if (i != data->entities.end() if (i != data->entities.end()) {
&& (i->second.kind switch (i->second.kind) {
!= unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL)) case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
{ break;
error(@4, yyscanner, "multiple entities named " + data->currentName); case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
YYERROR; 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;
}
} }
data->entities[data->currentName] = unoidl::detail::SourceProviderEntity( data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
new unoidl::detail::SourceProviderInterfaceTypeEntityPad( new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
...@@ -1547,7 +1601,7 @@ interfaceDefn: ...@@ -1547,7 +1601,7 @@ interfaceDefn:
pad->isPublished(), mbases, obases, pad->attributes, pad->methods, pad->isPublished(), mbases, obases, pad->attributes, pad->methods,
annotations($1)); annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -1596,6 +1650,16 @@ interfaceBase: ...@@ -1596,6 +1650,16 @@ interfaceBase:
+ " does not resolve to an existing interface type")); + " does not resolve to an existing interface type"));
YYERROR; YYERROR;
} }
if (data->publishedContext
&& !(static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())
->isPublished()))
{
error(
@4, yyscanner,
("published interface type " + data->currentName + " direct base "
+ name + " is unpublished"));
YYERROR;
}
//TODO: check uniqueness (incl. that opt base != XInterface) //TODO: check uniqueness (incl. that opt base != XInterface)
(opt ? pad->optionalBases : pad->mandatoryBases).push_back( (opt ? pad->optionalBases : pad->mandatoryBases).push_back(
unoidl::detail::SourceProviderInterfaceTypeEntityPad::Base( unoidl::detail::SourceProviderInterfaceTypeEntityPad::Base(
...@@ -1807,8 +1871,10 @@ typedefDefn: ...@@ -1807,8 +1871,10 @@ typedefDefn:
deprecated_opt published_opt TOK_TYPEDEF type identifier ';' deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
unoidl::detail::SourceProviderType t(*$4); unoidl::detail::SourceProviderType t(*$4);
delete $4; delete $4;
OUString name(convertToFullName(data, $5));
// There is no good reason to forbid typedefs to VOID and to instantiated // There is no good reason to forbid typedefs to VOID and to instantiated
// polymorphic struct types, but some old client code of registry data // polymorphic struct types, but some old client code of registry data
// expects this typedef restriction (like the assert(false) default in // expects this typedef restriction (like the assert(false) default in
...@@ -1819,12 +1885,43 @@ typedefDefn: ...@@ -1819,12 +1885,43 @@ typedefDefn:
case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT: case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
error(@4, yyscanner, "bad typedef type"); error(@4, yyscanner, "bad typedef type");
YYERROR; YYERROR;
break;
case unoidl::detail::SourceProviderType::TYPE_ENUM:
case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
if ($2) {
bool unpub = false;
switch (t.entity->kind) {
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
unpub = true;
break;
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE:
assert(false); // this cannot happen
default:
assert(t.entity->entity.is() || t.entity->pad.is());
unpub
= !(t.entity->entity.is()
? static_cast<unoidl::PublishableEntity *>(
t.entity->entity.get())->isPublished()
: t.entity->pad->isPublished());
break;
}
if (unpub) {
error(
@4, yyscanner,
"published typedef " + name + " type is unpublished");
YYERROR;
}
}
break;
case unoidl::detail::SourceProviderType::TYPE_PARAMETER: case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
assert(false); // this cannot happen assert(false); // this cannot happen
default: default:
break; break;
} }
OUString name(convertToFullName(data, $5));
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
name, name,
...@@ -1837,6 +1934,7 @@ typedefDefn: ...@@ -1837,6 +1934,7 @@ typedefDefn:
error(@5, yyscanner, "multiple entities named " + name); error(@5, yyscanner, "multiple entities named " + name);
YYERROR; YYERROR;
} }
clearCurrentState(data);
} }
; ;
...@@ -1844,6 +1942,7 @@ constantGroupDefn: ...@@ -1844,6 +1942,7 @@ constantGroupDefn:
deprecated_opt published_opt TOK_CONSTANTS identifier deprecated_opt published_opt TOK_CONSTANTS identifier
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -1868,7 +1967,7 @@ constantGroupDefn: ...@@ -1868,7 +1967,7 @@ constantGroupDefn:
ent->entity = new unoidl::ConstantGroupEntity( ent->entity = new unoidl::ConstantGroupEntity(
pad->isPublished(), pad->members, annotations($1)); pad->isPublished(), pad->members, annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -2163,25 +2262,51 @@ singleInterfaceBasedServiceDefn: ...@@ -2163,25 +2262,51 @@ singleInterfaceBasedServiceDefn:
deprecated_opt published_opt TOK_SERVICE identifier singleInheritance deprecated_opt published_opt TOK_SERVICE identifier singleInheritance
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
OUString base(convertName($5)); OUString base(convertName($5));
unoidl::detail::SourceProviderEntity const * p; unoidl::detail::SourceProviderEntity const * p;
if (findEntity(@5, yyscanner, data, false, &base, &p, 0) == FOUND_ERROR) { if (findEntity(@5, yyscanner, data, false, &base, &p, 0) == FOUND_ERROR) {
YYERROR; YYERROR;
} }
if (p == 0 bool ifcBase = false;
|| ((p->kind bool pubBase = false;
!= unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL) if (p != 0) {
&& (!p->entity.is() switch (p->kind) {
|| (p->entity->getSort() case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
!= unoidl::Entity::SORT_INTERFACE_TYPE)))) ifcBase = true;
{ pubBase = false;
break;
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
ifcBase = true;
pubBase = true;
break;
default:
if (p->entity.is()
&& (p->entity->getSort()
== unoidl::Entity::SORT_INTERFACE_TYPE))
{
ifcBase = true;
pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
p->entity.get())->isPublished();
}
break;
}
}
if (!ifcBase) {
error( error(
@5, yyscanner, @5, yyscanner,
("single-interface--based service " + data->currentName + " base " ("single-interface--based service " + data->currentName + " base "
+ base + " does not resolve to an interface type")); + base + " does not resolve to an interface type"));
YYERROR; YYERROR;
} }
if ($2 && !pubBase) {
error(
@5, yyscanner,
("published single-interface--based service " + data->currentName
+ " base " + base + " is unpublished"));
YYERROR;
}
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
data->currentName, data->currentName,
...@@ -2229,7 +2354,7 @@ singleInterfaceBasedServiceDefn: ...@@ -2229,7 +2354,7 @@ singleInterfaceBasedServiceDefn:
ent->entity = new unoidl::SingleInterfaceBasedServiceEntity( ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
pad->isPublished(), pad->base, ctors, annotations($1)); pad->isPublished(), pad->base, ctors, annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -2409,6 +2534,7 @@ accumulationBasedServiceDefn: ...@@ -2409,6 +2534,7 @@ accumulationBasedServiceDefn:
deprecated_opt published_opt TOK_SERVICE identifier deprecated_opt published_opt TOK_SERVICE identifier
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
convertToCurrentName(data, $4); convertToCurrentName(data, $4);
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
...@@ -2436,7 +2562,7 @@ accumulationBasedServiceDefn: ...@@ -2436,7 +2562,7 @@ accumulationBasedServiceDefn:
pad->directOptionalBaseInterfaces, pad->directProperties, pad->directOptionalBaseInterfaces, pad->directProperties,
annotations($1)); annotations($1));
ent->pad.clear(); ent->pad.clear();
clearCurrentName(data); clearCurrentState(data);
} }
; ;
...@@ -2481,6 +2607,16 @@ serviceBase: ...@@ -2481,6 +2607,16 @@ serviceBase:
+ " does not resolve to an accumulation-based service")); + " does not resolve to an accumulation-based service"));
YYERROR; YYERROR;
} }
if (data->publishedContext
&& !static_cast<unoidl::AccumulationBasedServiceEntity *>(
p->entity.get())->isPublished())
{
error(
@4, yyscanner,
("published accumulation-based service " + data->currentName
+ " direct base service " + name + " is unpublished"));
YYERROR;
}
//TODO: check uniqueness //TODO: check uniqueness
(opt ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices) (opt ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices)
.push_back(unoidl::AnnotatedReference(name, annotations($1))); .push_back(unoidl::AnnotatedReference(name, annotations($1)));
...@@ -2506,13 +2642,31 @@ serviceInterfaceBase: ...@@ -2506,13 +2642,31 @@ serviceInterfaceBase:
if (findEntity(@4, yyscanner, data, false, &name, &p, 0) == FOUND_ERROR) { if (findEntity(@4, yyscanner, data, false, &name, &p, 0) == FOUND_ERROR) {
YYERROR; YYERROR;
} }
if (p == 0 bool ifcBase = false;
|| ((p->kind bool pubBase = false;
!= unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL) if (p != 0) {
&& (!p->entity.is() switch (p->kind) {
|| (p->entity->getSort() case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
!= unoidl::Entity::SORT_INTERFACE_TYPE)))) ifcBase = true;
{ pubBase = false;
break;
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
ifcBase = true;
pubBase = true;
break;
default:
if (p->entity.is()
&& (p->entity->getSort()
== unoidl::Entity::SORT_INTERFACE_TYPE))
{
ifcBase = true;
pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
p->entity.get())->isPublished();
}
break;
}
}
if (!ifcBase) {
error( error(
@4, yyscanner, @4, yyscanner,
("accumulation-based service " + data->currentName ("accumulation-based service " + data->currentName
...@@ -2520,6 +2674,13 @@ serviceInterfaceBase: ...@@ -2520,6 +2674,13 @@ serviceInterfaceBase:
+ " does not resolve to an interface type")); + " does not resolve to an interface type"));
YYERROR; YYERROR;
} }
if (data->publishedContext && !opt && !pubBase) {
error(
@5, yyscanner,
("published accumulation-based service " + data->currentName
+ " direct base interface " + name + " is unpublished"));
YYERROR;
}
//TODO: check uniqueness //TODO: check uniqueness
(opt (opt
? pad->directOptionalBaseInterfaces ? pad->directOptionalBaseInterfaces
...@@ -2615,25 +2776,51 @@ interfaceBasedSingletonDefn: ...@@ -2615,25 +2776,51 @@ interfaceBasedSingletonDefn:
deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';' deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';'
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
OUString name(convertToFullName(data, $4)); OUString name(convertToFullName(data, $4));
OUString base(convertName($5)); OUString base(convertName($5));
unoidl::detail::SourceProviderEntity const * p; unoidl::detail::SourceProviderEntity const * p;
if (findEntity(@5, yyscanner, data, false, &base, &p, 0) == FOUND_ERROR) { if (findEntity(@5, yyscanner, data, false, &base, &p, 0) == FOUND_ERROR) {
YYERROR; YYERROR;
} }
if (p == 0 bool ifcBase = false;
|| ((p->kind bool pubBase = false;
!= unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL) if (p != 0) {
&& (!p->entity.is() switch (p->kind) {
|| (p->entity->getSort() case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
!= unoidl::Entity::SORT_INTERFACE_TYPE)))) ifcBase = true;
{ pubBase = false;
break;
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
ifcBase = true;
pubBase = true;
break;
default:
if (p->entity.is()
&& (p->entity->getSort()
== unoidl::Entity::SORT_INTERFACE_TYPE))
{
ifcBase = true;
pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
p->entity.get())->isPublished();
}
break;
}
}
if (!ifcBase) {
error( error(
@5, yyscanner, @5, yyscanner,
("interface-based singleton " + name + " base " + base ("interface-based singleton " + name + " base " + base
+ " does not resolve to an interface type")); + " does not resolve to an interface type"));
YYERROR; YYERROR;
} }
if ($2 && !pubBase) {
error(
@5, yyscanner,
("published interface-based singleton " + name + " base " + base
+ " is unpublished"));
YYERROR;
}
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
name, name,
...@@ -2646,6 +2833,7 @@ interfaceBasedSingletonDefn: ...@@ -2646,6 +2833,7 @@ interfaceBasedSingletonDefn:
error(@4, yyscanner, "multiple entities named " + name); error(@4, yyscanner, "multiple entities named " + name);
YYERROR; YYERROR;
} }
clearCurrentState(data);
} }
; ;
...@@ -2654,6 +2842,7 @@ serviceBasedSingletonDefn: ...@@ -2654,6 +2842,7 @@ serviceBasedSingletonDefn:
'}' ';' '}' ';'
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
OUString name(convertToFullName(data, $4)); OUString name(convertToFullName(data, $4));
OUString base(convertName($7)); OUString base(convertName($7));
unoidl::detail::SourceProviderEntity const * p; unoidl::detail::SourceProviderEntity const * p;
...@@ -2671,6 +2860,16 @@ serviceBasedSingletonDefn: ...@@ -2671,6 +2860,16 @@ serviceBasedSingletonDefn:
+ " does not resolve to an accumulation-based service")); + " does not resolve to an accumulation-based service"));
YYERROR; YYERROR;
} }
if ($2
&& !static_cast<unoidl::AccumulationBasedServiceEntity *>(
p->entity.get())->isPublished())
{
error(
@7, yyscanner,
("published service-based singleton " + name + " base " + base
+ " is unpublished"));
YYERROR;
}
if (!data->entities.insert( if (!data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
name, name,
...@@ -2683,6 +2882,7 @@ serviceBasedSingletonDefn: ...@@ -2683,6 +2882,7 @@ serviceBasedSingletonDefn:
error(@4, yyscanner, "multiple entities named " + name); error(@4, yyscanner, "multiple entities named " + name);
YYERROR; YYERROR;
} }
clearCurrentState(data);
} }
; ;
...@@ -2722,6 +2922,16 @@ exceptions: ...@@ -2722,6 +2922,16 @@ exceptions:
("exception " + name + " does not resolve to an exception type")); ("exception " + name + " does not resolve to an exception type"));
YYERROR; YYERROR;
} }
if (data->publishedContext
&& !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
->isPublished()))
{
delete $1; /* see commented-out %destructor above */
error(
@3, yyscanner,
("unpublished exception " + name + " used in published context"));
YYERROR;
}
if (std::find($1->begin(), $1->end(), name) != $1->end()) { if (std::find($1->begin(), $1->end(), name) != $1->end()) {
delete $1; /* see commented-out %destructor above */ delete $1; /* see commented-out %destructor above */
error( error(
...@@ -2748,6 +2958,15 @@ exceptions: ...@@ -2748,6 +2958,15 @@ exceptions:
("exception " + name + " does not resolve to an exception type")); ("exception " + name + " does not resolve to an exception type"));
YYERROR; YYERROR;
} }
if (data->publishedContext
&& !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
->isPublished()))
{
error(
@1, yyscanner,
("unpublished exception " + name + " used in published context"));
YYERROR;
}
$$ = new std::vector<OUString>; $$->push_back(name); $$ = new std::vector<OUString>; $$->push_back(name);
} }
; ;
...@@ -2756,27 +2975,49 @@ interfaceDecl: ...@@ -2756,27 +2975,49 @@ interfaceDecl:
deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';' deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';'
{ {
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
data->publishedContext = $2;
OUString name(convertToFullName(data, $4)); OUString name(convertToFullName(data, $4));
std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p( std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
data->entities.insert( data->entities.insert(
std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type( std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
name, name,
unoidl::detail::SourceProviderEntity( unoidl::detail::SourceProviderEntity(
unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL)))); $2
if (!p.second ? unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL
&& (p.first->second.kind : unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL))));
!= unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL)) if (!p.second) {
{ switch (p.first->second.kind) {
assert(p.first->second.entity.is()); case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
if (p.first->second.entity->getSort() if ($2) {
!= unoidl::Entity::SORT_INTERFACE_TYPE) p.first->second.kind
{ = unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL;
error( }
@4, yyscanner, break;
"multiple entities named " + data->currentName); case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
YYERROR; break;
default:
assert(p.first->second.entity.is());
if (p.first->second.entity->getSort()
!= unoidl::Entity::SORT_INTERFACE_TYPE)
{
error(
@4, yyscanner,
"multiple entities named " + data->currentName);
YYERROR;
}
if ($2
&& !static_cast<unoidl::InterfaceTypeEntity *>(
p.first->second.entity.get())->isPublished())
{
error(
@4, yyscanner,
("published interface type declaration "
+ data->currentName + " has been defined unpublished"));
YYERROR;
}
} }
} }
clearCurrentState(data);
} }
; ;
...@@ -3185,6 +3426,7 @@ primaryExpr: ...@@ -3185,6 +3426,7 @@ primaryExpr:
unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner); unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
unoidl::ConstantValue v(false); // dummy value unoidl::ConstantValue v(false); // dummy value
bool found = false; bool found = false;
bool unpub = false;
sal_Int32 i = name.lastIndexOf('.'); sal_Int32 i = name.lastIndexOf('.');
if (i == -1) { if (i == -1) {
rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad( rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad(
...@@ -3248,6 +3490,9 @@ primaryExpr: ...@@ -3248,6 +3490,9 @@ primaryExpr:
if (j->name == id) { if (j->name == id) {
v = j->value; v = j->value;
found = true; found = true;
unpub
= !static_cast<unoidl::ConstantGroupEntity *>(
ent->entity.get())->isPublished();
break; break;
} }
} }
...@@ -3265,6 +3510,7 @@ primaryExpr: ...@@ -3265,6 +3510,7 @@ primaryExpr:
if (j->name == id) { if (j->name == id) {
v = j->value; v = j->value;
found = true; found = true;
unpub = !ent->pad->isPublished();
break; break;
} }
} }
...@@ -3280,6 +3526,12 @@ primaryExpr: ...@@ -3280,6 +3526,12 @@ primaryExpr:
" enum member"))); " enum member")));
YYERROR; YYERROR;
} }
if (data->publishedContext && unpub) {
error(
@1, yyscanner,
"unpublished value " + name + " used in published context");
YYERROR;
}
switch (v.type) { switch (v.type) {
case unoidl::ConstantValue::TYPE_BOOLEAN: case unoidl::ConstantValue::TYPE_BOOLEAN:
$$ = unoidl::detail::SourceProviderExpr::Bool(v.booleanValue); $$ = unoidl::detail::SourceProviderExpr::Bool(v.booleanValue);
...@@ -3470,6 +3722,13 @@ type: ...@@ -3470,6 +3722,13 @@ type:
switch (ent->kind) { switch (ent->kind) {
case unoidl::detail::SourceProviderEntity::KIND_LOCAL: case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
if (ent->pad.is()) { if (ent->pad.is()) {
if (data->publishedContext && !ent->pad->isPublished()) {
error(
@1, yyscanner,
("unpublished entity " + name
+ " used in published context"));
YYERROR;
}
if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>( if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
ent->pad.get()) ent->pad.get())
!= 0) != 0)
...@@ -3518,6 +3777,17 @@ type: ...@@ -3518,6 +3777,17 @@ type:
assert(ent->entity.is()); assert(ent->entity.is());
// fall through // fall through
case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL: case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
if (data->publishedContext
&& ent->entity->getSort() != unoidl::Entity::SORT_MODULE
&& !static_cast<unoidl::PublishableEntity *>(
ent->entity.get())->isPublished())
{
error(
@1, yyscanner,
("unpublished entity " + name
+ " used in published context"));
YYERROR;
}
switch (ent->entity->getSort()) { switch (ent->entity->getSort()) {
case unoidl::Entity::SORT_ENUM_TYPE: case unoidl::Entity::SORT_ENUM_TYPE:
$$ = new unoidl::detail::SourceProviderType( $$ = new unoidl::detail::SourceProviderType(
...@@ -3558,6 +3828,15 @@ type: ...@@ -3558,6 +3828,15 @@ type:
} }
break; break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
if (data->publishedContext) {
error(
@1, yyscanner,
("unpublished entity " + name
+ " used in published context"));
YYERROR;
}
// fall through
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
$$ = new unoidl::detail::SourceProviderType( $$ = new unoidl::detail::SourceProviderType(
unoidl::detail::SourceProviderType::TYPE_INTERFACE, name, unoidl::detail::SourceProviderType::TYPE_INTERFACE, name,
ent); ent);
...@@ -3612,23 +3891,29 @@ type: ...@@ -3612,23 +3891,29 @@ type:
if (ent->entity->getSort() if (ent->entity->getSort()
== unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE) == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
{ {
if (args.size() rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> e(
!= (static_cast< static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
unoidl::PolymorphicStructTypeTemplateEntity *>( ent->entity.get()));
ent->entity.get())-> if (args.size() != e->getTypeParameters().size()) {
getTypeParameters().size()))
{
error( error(
@1, yyscanner, @1, yyscanner,
("bad number of polymorphic struct type template " + name ("bad number of polymorphic struct type template " + name
+ " type arguments")); + " type arguments"));
YYERROR; YYERROR;
} }
if (data->publishedContext && !e->isPublished()) {
error(
@1, yyscanner,
("unpublished polymorphic struct type template " + name
+ " used in published context"));
YYERROR;
}
$$ = new unoidl::detail::SourceProviderType(name, ent, args); $$ = new unoidl::detail::SourceProviderType(name, ent, args);
ok = true; ok = true;
} }
break; break;
case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL: case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
break; break;
case unoidl::detail::SourceProviderEntity::KIND_MODULE: case unoidl::detail::SourceProviderEntity::KIND_MODULE:
assert(false); // this cannot happen assert(false); // this cannot happen
......
...@@ -218,7 +218,10 @@ private: ...@@ -218,7 +218,10 @@ private:
}; };
struct SourceProviderEntity { struct SourceProviderEntity {
enum Kind { KIND_EXTERNAL, KIND_LOCAL, KIND_INTERFACE_DECL, KIND_MODULE }; enum Kind {
KIND_EXTERNAL, KIND_LOCAL, KIND_INTERFACE_DECL,
KIND_PUBLISHED_INTERFACE_DECL, KIND_MODULE
};
explicit SourceProviderEntity( explicit SourceProviderEntity(
Kind theKind, rtl::Reference<unoidl::Entity> const & externalEntity): Kind theKind, rtl::Reference<unoidl::Entity> const & externalEntity):
...@@ -248,7 +251,7 @@ struct SourceProviderScannerData { ...@@ -248,7 +251,7 @@ struct SourceProviderScannerData {
manager(theManager), manager(theManager),
sourcePosition(), sourceEnd(), sourcePosition(), sourceEnd(),
// avoid false warnings about uninitialized members // avoid false warnings about uninitialized members
errorLine(0) errorLine(0), publishedContext(false)
{ assert(manager.is()); } { assert(manager.is()); }
void setSource(void const * address, sal_uInt64 size) { void setSource(void const * address, sal_uInt64 size) {
...@@ -267,6 +270,7 @@ struct SourceProviderScannerData { ...@@ -267,6 +270,7 @@ struct SourceProviderScannerData {
std::map<OUString, SourceProviderEntity> entities; std::map<OUString, SourceProviderEntity> entities;
std::vector<OUString> modules; std::vector<OUString> modules;
OUString currentName; OUString currentName;
bool publishedContext;
}; };
bool parse(OUString const & uri, SourceProviderScannerData * data); bool parse(OUString const & uri, SourceProviderScannerData * data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment