summaryrefslogtreecommitdiff
path: root/src/plugins/xml/XmlParser.cpp
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-04 18:24:32 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-04 18:24:32 +0100
commite76f58e912bd6661ba755d27da97bebf711f06ad (patch)
tree84db508d8d65ad48522ea835f84b21f9f4d4dff9 /src/plugins/xml/XmlParser.cpp
parent0149f97eca604662493e8aa2ebcceecba5fc5b94 (diff)
added mechanism for parent parsing, which does not fully work as of now.
Diffstat (limited to 'src/plugins/xml/XmlParser.cpp')
-rw-r--r--src/plugins/xml/XmlParser.cpp188
1 files changed, 184 insertions, 4 deletions
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp
index 52176db..b52e39d 100644
--- a/src/plugins/xml/XmlParser.cpp
+++ b/src/plugins/xml/XmlParser.cpp
@@ -357,7 +357,7 @@ public:
}
// TODO: Is inheritance possible here?
- Rooted<Descriptor> parent = scope().select<Descriptor>();
+ Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
Rooted<FieldDescriptor> field = parent->createFieldDescriptor(
type, args["name"].asString(), args["optional"].asBool());
@@ -374,6 +374,34 @@ public:
}
};
+class DomainFieldRefHandler : public Handler {
+public:
+ using Handler::Handler;
+
+ void start(Variant::mapType &args) override
+ {
+ // TODO: Is inheritance possible here?
+ Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
+
+ const std::string &name = args["name"].asString();
+ scope().resolve<FieldDescriptor>(
+ name, parent, logger(),
+ [](Handle<Node> field, Handle<Node> parent, Logger &logger) {
+ if (field != nullptr) {
+ parent.cast<StructuredClass>()->copyFieldDescriptor(
+ field.cast<FieldDescriptor>());
+ }
+ });
+ }
+
+ void end() override {}
+
+ static Handler *create(const HandlerData &handlerData)
+ {
+ return new DomainFieldRefHandler{handlerData};
+ }
+};
+
class DomainPrimitiveHandler : public Handler {
public:
using Handler::Handler;
@@ -381,7 +409,7 @@ public:
void start(Variant::mapType &args) override
{
// TODO: Is inheritance possible here?
- Rooted<Descriptor> parent = scope().select<Descriptor>();
+ Rooted<Descriptor> parent = scope().selectOrThrow<Descriptor>();
Rooted<FieldDescriptor> field = parent->createPrimitiveFieldDescriptor(
nullptr, args["name"].asString(), args["optional"].asBool());
@@ -414,7 +442,8 @@ public:
void start(Variant::mapType &args) override
{
- Rooted<FieldDescriptor> field = scope().select<FieldDescriptor>();
+ Rooted<FieldDescriptor> field =
+ scope().selectOrThrow<FieldDescriptor>();
const std::string &ref = args["ref"].asString();
scope().resolve<StructuredClass>(
@@ -435,7 +464,128 @@ public:
}
};
-// TODO: Add parent handler
+class DummyParentNode : public Node {
+public:
+ DummyParentNode(Manager &mgr, std::string name, Handle<Node> parent)
+ : Node(mgr, name, parent)
+ {
+ }
+};
+
+namespace RttiTypes {
+const Rtti DummyParentNode =
+ RttiBuilder<ousia::DummyParentNode>("DummyParentNode").parent(&Node);
+}
+
+class DomainParentHandler : public Handler {
+public:
+ using Handler::Handler;
+
+ void start(Variant::mapType &args) override
+ {
+ Rooted<StructuredClass> strct =
+ scope().selectOrThrow<StructuredClass>();
+
+ // TODO: Is there a better way for this?
+ Rooted<DummyParentNode> dummy{new DummyParentNode(
+ strct->getManager(), args["name"].asString(), strct)};
+ dummy->setLocation(location());
+ scope().push(dummy);
+ }
+
+ void end() override { scope().pop(); }
+
+ static Handler *create(const HandlerData &handlerData)
+ {
+ return new DomainParentHandler{handlerData};
+ }
+};
+
+class DomainParentFieldHandler : public Handler {
+public:
+ using Handler::Handler;
+
+ void start(Variant::mapType &args) override
+ {
+ Rooted<DummyParentNode> dummy =
+ scope().selectOrThrow<DummyParentNode>();
+ FieldDescriptor::FieldType type;
+ if (args["isSubtree"].asBool()) {
+ type = FieldDescriptor::FieldType::SUBTREE;
+ } else {
+ type = FieldDescriptor::FieldType::TREE;
+ }
+
+ const std::string &name = args["name"].asString();
+ const bool optional = args["optional"].asBool();
+ Rooted<StructuredClass> strct =
+ dummy->getParent().cast<StructuredClass>();
+
+ // resolve the parent, create the declared field and add the declared
+ // StructuredClass as child to it.
+ scope().resolve<Descriptor>(
+ dummy->getName(), strct, logger(),
+ [&type, &name, &optional](Handle<Node> parent, Handle<Node> strct,
+ Logger &logger) {
+ if (parent != nullptr) {
+ Rooted<FieldDescriptor> field =
+ parent.cast<Descriptor>()->createFieldDescriptor(
+ type, name, optional);
+ field->addChild(strct.cast<StructuredClass>());
+ }
+ });
+ }
+
+ void end() override {}
+
+ static Handler *create(const HandlerData &handlerData)
+ {
+ return new DomainParentFieldHandler{handlerData};
+ }
+};
+
+class DomainParentFieldRefHandler : public Handler {
+public:
+ using Handler::Handler;
+
+ void start(Variant::mapType &args) override
+ {
+ Rooted<DummyParentNode> dummy =
+ scope().selectOrThrow<DummyParentNode>();
+
+ const std::string &name = args["name"].asString();
+ Rooted<StructuredClass> strct =
+ dummy->getParent().cast<StructuredClass>();
+ auto loc = location();
+
+ // resolve the parent, get the referenced field and add the declared
+ // StructuredClass as child to it.
+ scope().resolve<Descriptor>(dummy->getName(), strct, logger(),
+ [&name, &loc](Handle<Node> parent,
+ Handle<Node> strct,
+ Logger &logger) {
+ if (parent != nullptr) {
+ auto res = parent->resolve(RttiTypes::FieldDescriptor, name);
+ if (res.size() != 1) {
+ logger.error(
+ std::string("Could not find referenced field ") + name,
+ loc);
+ }
+ Rooted<FieldDescriptor> field =
+ res[0].node.cast<FieldDescriptor>();
+ field->addChild(strct.cast<StructuredClass>());
+ }
+ });
+ }
+
+ void end() override {}
+
+ static Handler *create(const HandlerData &handlerData)
+ {
+ return new DomainParentFieldRefHandler{handlerData};
+ }
+};
+
// TODO: Add annotation handler
/*
@@ -571,6 +721,12 @@ static const ParserState DomainStructField =
.arguments({Argument::String("name", ""),
Argument::Bool("isSubtree", false),
Argument::Bool("optional", false)});
+static const ParserState DomainStructFieldRef =
+ ParserStateBuilder()
+ .parent(&DomainStruct)
+ .createdNodeType(&RttiTypes::FieldDescriptor)
+ .elementHandler(DomainFieldRefHandler::create)
+ .arguments({Argument::String("name", "")});
static const ParserState DomainStructPrimitive =
ParserStateBuilder()
.parent(&DomainStruct)
@@ -584,6 +740,26 @@ static const ParserState DomainStructChild =
.parent(&DomainStructField)
.elementHandler(DomainChildHandler::create)
.arguments({Argument::String("ref")});
+static const ParserState DomainStructParent =
+ ParserStateBuilder()
+ .parent(&DomainStruct)
+ .createdNodeType(&RttiTypes::DummyParentNode)
+ .elementHandler(DomainParentHandler::create)
+ .arguments({Argument::String("name")});
+static const ParserState DomainStructParentField =
+ ParserStateBuilder()
+ .parent(&DomainStructParent)
+ .createdNodeType(&RttiTypes::FieldDescriptor)
+ .elementHandler(DomainParentFieldHandler::create)
+ .arguments({Argument::String("name", ""),
+ Argument::Bool("isSubtree", false),
+ Argument::Bool("optional", false)});
+static const ParserState DomainStructParentFieldRef =
+ ParserStateBuilder()
+ .parent(&DomainStructParent)
+ .createdNodeType(&RttiTypes::FieldDescriptor)
+ .elementHandler(DomainParentFieldRefHandler::create)
+ .arguments({Argument::String("name", "")});
/* Typesystem states */
static const ParserState Typesystem =
@@ -642,8 +818,12 @@ static const std::multimap<std::string, const ParserState *> XmlStates{
{"domain", &Domain},
{"struct", &DomainStruct},
{"field", &DomainStructField},
+ {"fieldRef", &DomainStructFieldRef},
{"primitive", &DomainStructPrimitive},
{"child", &DomainStructChild},
+ {"parent", &DomainStructParent},
+ {"field", &DomainStructParentField},
+ {"fieldRef", &DomainStructParentFieldRef},
{"typesystem", &Typesystem},
{"enum", &TypesystemEnum},
{"entry", &TypesystemEnumEntry},