summaryrefslogtreecommitdiff
path: root/unoidl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-09-20 13:11:59 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-09-20 15:38:02 +0200
commit60f8d808c2451fd37f02c1f86ed7fe60f4f58fa6 (patch)
tree53e16e64c480f2d2635460f8a19d3150d88a3aaf /unoidl
parentaeee571501df4d3b1d91e10d61b434f0ecac4d6a (diff)
Reject "too similar" service constructors
Change-Id: Ie81e9994084b5a2f44a436c764318ea6e5049faf
Diffstat (limited to 'unoidl')
-rw-r--r--unoidl/source/sourceprovider-parser-requires.hxx2
-rw-r--r--unoidl/source/sourceprovider-parser.y95
-rw-r--r--unoidl/source/sourceprovider-scanner.hxx33
3 files changed, 112 insertions, 18 deletions
diff --git a/unoidl/source/sourceprovider-parser-requires.hxx b/unoidl/source/sourceprovider-parser-requires.hxx
index fc84c5d41e02..98657205ac7a 100644
--- a/unoidl/source/sourceprovider-parser-requires.hxx
+++ b/unoidl/source/sourceprovider-parser-requires.hxx
@@ -118,6 +118,8 @@ struct SourceProviderType {
OUString getName() const;
+ bool equals(SourceProviderType const & other) const;
+
Type type;
OUString name; // TYPE_ENUM ... TYPE_PARAMETER
SourceProviderEntity const * entity;
diff --git a/unoidl/source/sourceprovider-parser.y b/unoidl/source/sourceprovider-parser.y
index e410f35f8d4c..6512e4a69d64 100644
--- a/unoidl/source/sourceprovider-parser.y
+++ b/unoidl/source/sourceprovider-parser.y
@@ -2205,13 +2205,32 @@ singleInterfaceBasedServiceDefn:
dynamic_cast<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad *>(
ent->pad.get());
assert(pad != 0);
- if (!$7) {
+ std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor> ctors;
+ if ($7) {
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
+ i(pad->constructors.begin());
+ i != pad->constructors.end(); ++i)
+ {
+ std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter> parms;
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
+ j(i->parameters.begin());
+ j != i->parameters.end(); ++j)
+ {
+ parms.push_back(
+ unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter(
+ j->name, j->type.getName(), j->rest));
+ }
+ ctors.push_back(
+ unoidl::SingleInterfaceBasedServiceEntity::Constructor(
+ i->name, parms, i->exceptions, i->annotations));
+ }
+ } else {
assert(pad->constructors.empty());
- pad->constructors.push_back(
+ ctors.push_back(
unoidl::SingleInterfaceBasedServiceEntity::Constructor());
}
ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
- pad->isPublished(), pad->base, pad->constructors, annotations($1));
+ pad->isPublished(), pad->base, ctors, annotations($1));
ent->pad.clear();
clearCurrentName(data);
}
@@ -2235,7 +2254,7 @@ ctor:
rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
data));
- for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::iterator
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
i(pad->constructors.begin());
i != pad->constructors.end(); ++i)
{
@@ -2249,22 +2268,49 @@ ctor:
}
}
pad->constructors.push_back(
- unoidl::SingleInterfaceBasedServiceEntity::Constructor(
- id, std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>(),
- std::vector<OUString>(), annotations($1)));
+ unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor(
+ id, annotations($1)));
}
'(' ctorParams_opt ')' exceptionSpec_opt ';'
{
+ unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
+ rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
+ pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
+ data));
+ assert(!pad->constructors.empty());
if ($7 != 0) {
- unoidl::detail::SourceProviderScannerData * data
- = yyget_extra(yyscanner);
- rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
- pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
- data));
- assert(!pad->constructors.empty());
pad->constructors.back().exceptions = *$7;
delete $7;
}
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
+ i(pad->constructors.begin());
+ i != pad->constructors.end() - 1; ++i)
+ {
+ if (i->parameters.size()
+ == pad->constructors.back().parameters.size())
+ {
+ bool same = true;
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
+ j(i->parameters.begin()),
+ k(pad->constructors.back().parameters.begin());
+ j != i->parameters.end(); ++j, ++k)
+ {
+ if (!j->type.equals(k->type) || j->rest != k->rest) {
+ same = false;
+ break;
+ }
+ }
+ if (same) {
+ error(
+ @2, yyscanner,
+ ("single-interface--based service " + data->currentName
+ + " constructor " + pad->constructors.back().name
+ + " has similar paramete list to constructor "
+ + i->name));
+ YYERROR;
+ }
+ }
+ }
}
;
@@ -2338,7 +2384,7 @@ ctorParam:
+ " rest parameter must be last parameter"));
YYERROR;
}
- for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::iterator
+ for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
i(pad->constructors.back().parameters.begin());
i != pad->constructors.back().parameters.end(); ++i)
{
@@ -2353,8 +2399,8 @@ ctorParam:
}
}
pad->constructors.back().parameters.push_back(
- unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter(
- id, t.getName(), $5));
+ unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter(
+ id, t, $5));
}
;
@@ -3682,6 +3728,23 @@ OUString SourceProviderType::getName() const {
}
}
+bool SourceProviderType::equals(SourceProviderType const & other) const {
+ if (type != other.type || name != other.name
+ || subtypes.size() != other.subtypes.size())
+ {
+ return false;
+ }
+ for (std::vector<SourceProviderType>::const_iterator
+ i(subtypes.begin()), j(other.subtypes.begin());
+ i != subtypes.end(); ++i, ++j)
+ {
+ if (!i->equals(*j)) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool parse(OUString const & uri, SourceProviderScannerData * data) {
assert(data != 0);
oslFileHandle handle;
diff --git a/unoidl/source/sourceprovider-scanner.hxx b/unoidl/source/sourceprovider-scanner.hxx
index 8a79d3172d6d..0c08a13208d0 100644
--- a/unoidl/source/sourceprovider-scanner.hxx
+++ b/unoidl/source/sourceprovider-scanner.hxx
@@ -156,14 +156,43 @@ class SourceProviderSingleInterfaceBasedServiceEntityPad:
public SourceProviderEntityPad
{
public:
+ struct Constructor {
+ struct Parameter {
+ Parameter(
+ rtl::OUString const & theName,
+ SourceProviderType const & theType, bool theRest):
+ name(theName), type(theType), rest(theRest)
+ {}
+
+ rtl::OUString name;
+
+ SourceProviderType type;
+
+ bool rest;
+ };
+
+ Constructor(
+ rtl::OUString const & theName,
+ std::vector< rtl::OUString > const & theAnnotations):
+ name(theName), annotations(theAnnotations)
+ {}
+
+ rtl::OUString const name;
+
+ std::vector< Parameter > parameters;
+
+ std::vector< rtl::OUString > exceptions;
+
+ std::vector< rtl::OUString > const annotations;
+ };
+
explicit SourceProviderSingleInterfaceBasedServiceEntityPad(
bool published, OUString const & theBase):
SourceProviderEntityPad(published), base(theBase)
{}
OUString const base;
- std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>
- constructors;
+ std::vector<Constructor> constructors;
private:
virtual ~SourceProviderSingleInterfaceBasedServiceEntityPad() throw () {}