summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-27 01:39:19 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-27 01:39:19 +0100
commit84f0004cdf45f6fbad6461676897aa27f03cbb93 (patch)
treeacb15536b40d7389c3c65df1567084bb57da416e
parent495e2de57e587450e9532c7fe4ae0c2bfb196e6c (diff)
Removed dependency between "Project" model class and parser/resources. This reduces coupling and was stupid beforehand.
-rw-r--r--src/core/model/Document.hpp11
-rw-r--r--src/core/model/Node.hpp8
-rw-r--r--src/core/model/Project.cpp42
-rw-r--r--src/core/model/Project.hpp104
-rw-r--r--src/core/parser/ParserContext.cpp39
-rw-r--r--src/core/parser/ParserContext.hpp108
-rw-r--r--src/core/resource/ResourceManager.cpp59
-rw-r--r--src/core/resource/ResourceManager.hpp56
-rw-r--r--src/plugins/xml/XmlParser.cpp12
-rw-r--r--test/core/StandaloneEnvironment.hpp17
-rw-r--r--test/plugins/xml/XmlParserTest.cpp6
-rw-r--r--testdata/xmlparser/generic.oxm11
12 files changed, 222 insertions, 251 deletions
diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp
index 9ea2d6e..1f2fb37 100644
--- a/src/core/model/Document.hpp
+++ b/src/core/model/Document.hpp
@@ -744,17 +744,6 @@ public:
}
/**
- * This sets up an empty document.
- *
- * @param mgr is the Manager instance.
- * @param name is a name for this Document.
- */
- static Rooted<Document> createEmptyDocument(Manager &mgr, std::string name)
- {
- return Rooted<Document>{new Document(mgr, std::move(name))};
- }
-
- /**
* Sets the root StructuredEntity of this Document. This also sets the
* parent of the given StructuredEntity if it is not set to this Document
* already.
diff --git a/src/core/model/Node.hpp b/src/core/model/Node.hpp
index 6fc7dba..60d22e0 100644
--- a/src/core/model/Node.hpp
+++ b/src/core/model/Node.hpp
@@ -410,6 +410,7 @@ public:
* Initializes the node with empty name and parent.
*
* @param mgr is a reference to the Manager instace the node belongs to.
+ * @param parent is a handle pointing at the parent node.
*/
Node(Manager &mgr, Handle<Node> parent = nullptr)
: Managed(mgr),
@@ -424,6 +425,8 @@ public:
* @param mgr is a reference to the Manager instace the node belongs to.
* @param name is the name of the Node.
* @param parent is a handle pointing at the parent node.
+ * @param location is the location in the source code at which this node
+ * was defined.
*/
Node(Manager &mgr, std::string name, Handle<Node> parent = nullptr)
: Managed(mgr),
@@ -540,7 +543,10 @@ public:
* @param location describes the exact position of the Node in a source
* file.
*/
- void setLocation(const SourceLocation &location) {this->location = location;}
+ void setLocation(const SourceLocation &location)
+ {
+ this->location = location;
+ }
};
/**
diff --git a/src/core/model/Project.cpp b/src/core/model/Project.cpp
index 2833b37..b355969 100644
--- a/src/core/model/Project.cpp
+++ b/src/core/model/Project.cpp
@@ -17,8 +17,6 @@
*/
#include <core/common/RttiBuilder.hpp>
-#include <core/parser/ParserScope.hpp>
-#include <core/parser/ParserContext.hpp>
#include "Domain.hpp"
#include "Document.hpp"
@@ -27,52 +25,22 @@
namespace ousia {
-Project::Project(Manager &mgr, Registry &registry)
+Project::Project(Manager &mgr)
: Node(mgr),
- registry(registry),
systemTypesystem(acquire(new SystemTypesystem(mgr))),
documents(this)
{
}
-Rooted<Node> Project::parse(const std::string &path, const std::string mimetype,
- const std::string rel,
- const RttiSet &supportedTypes, Logger &logger)
-{
- ParserScope scope;
- ParserContext context(this, scope, logger);
- return resourceManager.link(registry, context, path, mimetype, rel,
- supportedTypes);
-}
-
-Rooted<Node> Project::link(ParserContext &ctx, const std::string &path,
- const std::string mimetype, const std::string rel,
- const RttiSet &supportedTypes)
-{
- return resourceManager.link(registry, ctx, path, mimetype, rel,
- supportedTypes);
-}
-
-Rooted<Node> Project::include(ParserContext &ctx, const std::string &path,
- const std::string mimetype, const std::string rel,
- const RttiSet &supportedTypes)
-{
- return resourceManager.include(registry, ctx, path, mimetype, rel,
- supportedTypes);
-}
-
-SourceContextCallback Project::getSourceContextCallback()
-{
- return [&](const SourceLocation &location) {
- return resourceManager.readContext(location);
- };
-}
-
bool Project::doValidate(Logger &logger) const
{
return continueValidation(documents, logger);
}
+void Project::doResolve(ResolutionState &state){
+ continueResolveComposita(documents, documents.getIndex(), state);
+}
+
Rooted<SystemTypesystem> Project::getSystemTypesystem()
{
return systemTypesystem;
diff --git a/src/core/model/Project.hpp b/src/core/model/Project.hpp
index 1c33dc8..9b81058 100644
--- a/src/core/model/Project.hpp
+++ b/src/core/model/Project.hpp
@@ -28,8 +28,6 @@
#ifndef _OUSIA_PROJECT_HPP_
#define _OUSIA_PROJECT_HPP_
-#include <core/resource/ResourceManager.hpp>
-
#include "Node.hpp"
namespace ousia {
@@ -38,7 +36,6 @@ namespace ousia {
class Logger;
class Rtti;
class Registry;
-class ParserContext;
class SystemTypesystem;
class Typesystem;
class Document;
@@ -52,11 +49,6 @@ class Domain;
class Project : public Node {
private:
/**
- * Reference at the internally used Registry instance.
- */
- Registry &registry;
-
- /**
* Private instance of the system typesystem which is distributed as a
* reference to all child typesystems.
*/
@@ -67,109 +59,17 @@ private:
*/
NodeVector<Document> documents;
- /**
- * ResourceManager used to manage all resources used by the project.
- */
- ResourceManager resourceManager;
-
protected:
- /**
- * Validates the project and all parts it consists of.
- *
- * @param logger is the logger instance to which errors will be logged.
- */
bool doValidate(Logger &loger) const override;
+ void doResolve(ResolutionState &state) override;
public:
/**
* Constructor of the Project class.
*
* @param mgr is the manager instance used for managing this Node.
- * @param registry is the registry instance that should be used for locating
- * files and finding parsers for these files.
- */
- Project(Manager &mgr, Registry &registry);
-
- /**
- * Parses a file with the given Logger in an empty ParserScope. This
- * function is meant to be called by the top-level (e.g. a main function)
- * and not by other parsers. These should use the link and include methods
- * instead.
- *
- * @param path is the path of the file that should be parsed.
- * @param mimetype is the mimetype of the resource that should be parsed
- * (may be empty, in which case the mimetype is deduced from the file
- * extension).
- * @param rel is a "relation string" supplied by the user which specifies
- * the relationship of the specified resource. May be empty, in which case
- * the relation is deduced from the supported types and the types of the
- * parser for the given mimetype.
- * @param supportedTypes contains the types of the returned Node the caller
- * can deal with. Note that only the types the parser claims to return are
- * checked, not the actual result.
- * @param logger is the logger that should be used
- * @return the parsed node or nullptr if something goes wrong.
- */
- Rooted<Node> parse(const std::string &path, const std::string mimetype,
- const std::string rel, const RttiSet &supportedTypes,
- Logger &logger);
-
- /**
- * Parses a file with ParserContext and an empty ParserScope. The parsed
- * object graph of files that are parsed using the "link" function is
- * cached (in contrast to the "include" function).
- *
- * @param ctx is the ParserContext that should be passed to the underlying
- * parser. The scope in the ParserContext will be exchanged.
- * @param path is the path of the file that should be parsed.
- * @param mimetype is the mimetype of the resource that should be parsed
- * (may be empty, in which case the mimetype is deduced from the file
- * extension).
- * @param rel is a "relation string" supplied by the user which specifies
- * the relationship of the specified resource. May be empty, in which case
- * the relation is deduced from the supported types and the types of the
- * parser for the given mimetype.
- * @param supportedTypes contains the types of the returned Node the caller
- * can deal with. Note that only the types the parser claims to return are
- * checked, not the actual result.
- * @return the parsed node or nullptr if something goes wrong.
- */
- Rooted<Node> link(ParserContext &ctx, const std::string &path,
- const std::string mimetype, const std::string rel,
- const RttiSet &supportedTypes);
-
- /**
- * Parses a file with ParserContext and the current ParserScope. In contrast
- * to the "link" function, include() does not cache the parsed node (as it
- * depends on the current ParserScope).
- *
- * @param ctx is the ParserContext that should be passed to the underlying
- * parser. The scope in the ParserContext will be exchanged.
- * @param path is the path of the file that should be parsed.
- * @param mimetype is the mimetype of the resource that should be parsed
- * (may be empty, in which case the mimetype is deduced from the file
- * extension).
- * @param rel is a "relation string" supplied by the user which specifies
- * the relationship of the specified resource. May be empty, in which case
- * the relation is deduced from the supported types and the types of the
- * parser for the given mimetype.
- * @param supportedTypes contains the types of the returned Node the caller
- * can deal with. Note that only the types the parser claims to return are
- * checked, not the actual result.
- * @return the parsed node or nullptr if something goes wrong.
- */
- Rooted<Node> include(ParserContext &ctx, const std::string &path,
- const std::string mimetype, const std::string rel,
- const RttiSet &supportedTypes);
-
- /**
- * Returns a SourceContextCallback that can be passed to a logger instance.
- * Remeber to reset the SourceContextCallback after the Project instance has
- * been freed.
- *
- * @return a SourceContextCallback that is coupled to this Project instance.
*/
- SourceContextCallback getSourceContextCallback();
+ Project(Manager &mgr);
/**
* Returns a reference to the internal system typesystem.
diff --git a/src/core/parser/ParserContext.cpp b/src/core/parser/ParserContext.cpp
index 0a75fdf..b0d04d4 100644
--- a/src/core/parser/ParserContext.cpp
+++ b/src/core/parser/ParserContext.cpp
@@ -16,32 +16,55 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <core/resource/ResourceManager.hpp>
+#include <core/Registry.hpp>
+
+#include "ParserScope.hpp"
#include "ParserContext.hpp"
namespace ousia {
/* Class ParserContext */
-ParserContext::ParserContext(Handle<Project> project, ParserScope &scope,
- SourceId sourceId, Logger &logger)
- : project(project), scope(scope), sourceId(sourceId), logger(logger)
+ParserContext::ParserContext(Registry &registry,
+ ResourceManager &resourceManager,
+ ParserScope &scope, Handle<Project> project,
+ Logger &logger, SourceId sourceId)
+ : registry(registry),
+ resourceManager(resourceManager),
+ scope(scope),
+ project(project),
+ logger(logger),
+ sourceId(sourceId)
+{
+}
+
+Rooted<Node> ParserContext::link(const std::string &path,
+ const std::string mimetype,
+ const std::string rel,
+ const RttiSet &supportedTypes)
{
+ return resourceManager.link(*this, path, mimetype, rel, supportedTypes);
}
-ParserContext::ParserContext(Handle<Project> project, ParserScope &scope,
- Logger &logger)
- : project(project), scope(scope), sourceId(InvalidSourceId), logger(logger)
+Rooted<Node> ParserContext::include(const std::string &path,
+ const std::string mimetype,
+ const std::string rel,
+ const RttiSet &supportedTypes)
{
+ return resourceManager.include(*this, path, mimetype, rel, supportedTypes);
}
ParserContext ParserContext::clone(ParserScope &scope, SourceId sourceId) const
{
- return ParserContext{project, scope, sourceId, logger};
+ return ParserContext{registry, resourceManager, scope,
+ project, logger, sourceId};
}
ParserContext ParserContext::clone(SourceId sourceId) const
{
- return ParserContext{project, scope, sourceId, logger};
+ return ParserContext{registry, resourceManager, scope,
+ project, logger, sourceId};
}
Manager &ParserContext::getManager() const { return project->getManager(); }
diff --git a/src/core/parser/ParserContext.hpp b/src/core/parser/ParserContext.hpp
index e36c0d9..f422e10 100644
--- a/src/core/parser/ParserContext.hpp
+++ b/src/core/parser/ParserContext.hpp
@@ -29,7 +29,7 @@
#define _OUSIA_PARSER_CONTEXT_HPP_
#include <core/common/Location.hpp>
-#include <core/managed/Managed.hpp>
+#include <core/common/Rtti.hpp>
#include <core/model/Project.hpp>
namespace ousia {
@@ -37,6 +37,8 @@ namespace ousia {
// Forward declaration
class Logger;
class ParserScope;
+class Registry;
+class ResourceManager;
/**
* Class containing the objects that are passed to a parser instance.
@@ -44,9 +46,14 @@ class ParserScope;
class ParserContext {
private:
/**
- * Project instance into which the new content should be parsed.
+ * Reference at the internally used Registry instance.
*/
- Rooted<Project> project;
+ Registry &registry;
+
+ /**
+ * ResourceManager used to manage all resources used by the project.
+ */
+ ResourceManager &resourceManager;
/**
* Reference to the ParserScope instance that should be used within the
@@ -55,42 +62,83 @@ private:
ParserScope &scope;
/**
- * SourceId is the ID of the resource that is currently being processed.
+ * Project instance into which the new content should be parsed.
*/
- SourceId sourceId;
+ Rooted<Project> project;
/**
* Reference to the Logger the parser should log any messages to.
*/
Logger &logger;
+ /**
+ * SourceId is the ID of the resource that is currently being processed.
+ */
+ SourceId sourceId;
+
public:
/**
* Constructor of the ParserContext class.
*
- * @param project is the project into which the content should be parsed.
+ * @param registry is the registry instance that should be used for locating
+ * files and finding parsers for these files.
+ * @param resourceManager is a reference at the ResourceManager which
+ * manages the inclusion of source files.
* @param scope is a reference to the ParserScope instance that should be
* used to lookup names.
- * @param sourceId is a SourceId instance specifying the source the parser
- * is reading from.
+ * @param project is the project into which the content should be parsed.
* @param logger is a reference to the Logger instance that should be used
* to log error messages and warnings that occur while parsing the document.
+ * @param sourceId is a SourceId instance specifying the source the parser
+ * is reading from.
*/
- ParserContext(Handle<Project> project, ParserScope &scope,
- SourceId sourceId, Logger &logger);
+ ParserContext(Registry &registry, ResourceManager &resourceManager,
+ ParserScope &scope, Handle<Project> project, Logger &logger,
+ SourceId sourceId = InvalidSourceId);
/**
- * Constructor of the ParserContext class with the sourceId being set
- * to the InvalidSourceId value.
+ * Parses a file with ParserContext and an empty ParserScope. The parsed
+ * object graph of files that are parsed using the "link" function is
+ * cached (in contrast to the "include" function). A copy of this parser
+ * context will be passed to the called parser, with the ParserScope
+ * reference stored in the "scope" variable exchanged by an empty scope.
*
- * @param project is the project into which the content should be parsed.
- * @param scope is a reference to the ParserScope instance that should be
- * used to lookup names.
- * @param logger is a reference to the Logger instance that should be used
- * to log error messages and warnings that occur while parsing the document.
+ * @param path is the path of the file that should be parsed.
+ * @param mimetype is the mimetype of the resource that should be parsed
+ * (may be empty, in which case the mimetype is deduced from the file
+ * extension).
+ * @param rel is a "relation string" supplied by the user which specifies
+ * the relationship of the specified resource. May be empty, in which case
+ * the relation is deduced from the supported types and the types of the
+ * parser for the given mimetype.
+ * @param supportedTypes contains the types of the returned Node the caller
+ * can deal with. Note that only the types the parser claims to return are
+ * checked, not the actual result.
+ * @return the parsed node or nullptr if something goes wrong.
*/
- ParserContext(Handle<Project> project, ParserScope &scope,
- Logger &logger);
+ Rooted<Node> link(const std::string &path, const std::string mimetype,
+ const std::string rel, const RttiSet &supportedTypes);
+
+ /**
+ * Parses a file with ParserContext and the current ParserScope. In contrast
+ * to the "link" function, include() does not cache the parsed node (as it
+ * depends on the current ParserScope).
+ *
+ * @param path is the path of the file that should be parsed.
+ * @param mimetype is the mimetype of the resource that should be parsed
+ * (may be empty, in which case the mimetype is deduced from the file
+ * extension).
+ * @param rel is a "relation string" supplied by the user which specifies
+ * the relationship of the specified resource. May be empty, in which case
+ * the relation is deduced from the supported types and the types of the
+ * parser for the given mimetype.
+ * @param supportedTypes contains the types of the returned Node the caller
+ * can deal with. Note that only the types the parser claims to return are
+ * checked, not the actual result.
+ * @return the parsed node or nullptr if something goes wrong.
+ */
+ Rooted<Node> include(const std::string &path, const std::string mimetype,
+ const std::string rel, const RttiSet &supportedTypes);
/**
* Clones the ParserContext instance but exchanges the ParserScope instance
@@ -111,11 +159,20 @@ public:
ParserContext clone(SourceId sourceId) const;
/**
- * Returns a handle pointing at the Project node.
+ * Returns a reference pointing at the Registry used within this parser
+ * context.
*
- * @return a project node handle.
+ * @return a reference at the registry instance.
*/
- Rooted<Project> getProject() const { return project; }
+ Registry &getRegistry() const { return registry; }
+
+ /**
+ * Returns a reference pointing at the ResourceManager used within this
+ * parser context.
+ *
+ * @return a reference at the ResourceManager instance.
+ */
+ ResourceManager &getResourceManager() const { return resourceManager; }
/**
* Returns a reference pointing at the current ParserScope instance.
@@ -126,6 +183,13 @@ public:
ParserScope &getScope() const { return scope; }
/**
+ * Returns a handle pointing at the Project node.
+ *
+ * @return a project node handle.
+ */
+ Rooted<Project> getProject() const { return project; }
+
+ /**
* Returns a reference pointing at the current LoggerInstance.
*
* @return a reference at LoggerInstance to which all error messages should
diff --git a/src/core/resource/ResourceManager.cpp b/src/core/resource/ResourceManager.cpp
index c7a4104..d149e49 100644
--- a/src/core/resource/ResourceManager.cpp
+++ b/src/core/resource/ResourceManager.cpp
@@ -70,14 +70,23 @@ void ResourceManager::purgeResource(SourceId sourceId)
contextReaders.erase(sourceId);
}
-Rooted<Node> ResourceManager::parse(Registry &registry, ParserContext &ctx,
- const ResourceRequest &req, ParseMode mode)
+Rooted<Node> ResourceManager::parse(ParserContext &ctx, const std::string &path,
+ const std::string &mimetype,
+ const std::string &rel,
+ const RttiSet &supportedTypes,
+ ParseMode mode)
{
+ // Some references used for convenience
+ Registry &registry = ctx.getRegistry();
+ Logger &logger = ctx.getLogger();
+ Resource relativeTo = getResource(ctx.getSourceId());
+
// Locate the resource relative to the old resource, abort if this did not
// work
+ ResourceRequest req{path, mimetype, rel, supportedTypes};
Resource resource;
- if (!req.locate(registry, ctx.getLogger(), resource,
- getResource(ctx.getSourceId()))) {
+ if (!req.deduce(registry, logger) ||
+ !req.locate(registry, logger, resource, relativeTo)) {
return nullptr;
}
@@ -87,17 +96,18 @@ Rooted<Node> ResourceManager::parse(Registry &registry, ParserContext &ctx,
// We can now try to parse the given file
Rooted<Node> node;
try {
- // Set the current source id in the logger instance
{
- GuardedLogger logger(ctx.getLogger(), SourceLocation{sourceId});
+ // Set the current source id in the logger instance. Note that this
+ // modifies the logger instance -- the GuardedLogger is just used to
+ // make sure the default location is popped from the stack again.
+ GuardedLogger guardedLogger(logger, SourceLocation{sourceId});
// Fetch the input stream and create a char reader
std::unique_ptr<std::istream> is = resource.stream();
CharReader reader(*is, sourceId);
// Actually parse the input stream, distinguish the LINK and the
- // INCLUDE
- // mode
+ // INCLUDE mode
switch (mode) {
case ParseMode::LINK: {
ParserScope scope; // New empty parser scope instance
@@ -105,11 +115,11 @@ Rooted<Node> ResourceManager::parse(Registry &registry, ParserContext &ctx,
node = req.getParser()->parse(reader, childCtx);
// Perform all deferred resolutions
- scope.performDeferredResolution(ctx.getLogger());
+ scope.performDeferredResolution(logger);
// Validate the parsed node
if (node != nullptr) {
- node->validate(ctx.getLogger());
+ node->validate(logger);
}
break;
}
@@ -121,13 +131,14 @@ Rooted<Node> ResourceManager::parse(Registry &registry, ParserContext &ctx,
}
}
if (node == nullptr) {
- throw LoggableException{"Requested file \"" + resource.getLocation() +
+ throw LoggableException{"Requested file \"" +
+ resource.getLocation() +
"\" cannot be parsed."};
}
}
catch (LoggableException ex) {
// Log the exception and return nullptr
- ctx.getLogger().log(ex);
+ logger.log(ex);
return nullptr;
}
@@ -140,30 +151,21 @@ Rooted<Node> ResourceManager::parse(Registry &registry, ParserContext &ctx,
return node;
}
-Rooted<Node> ResourceManager::link(Registry &registry, ParserContext &ctx,
- const std::string &path,
+Rooted<Node> ResourceManager::link(ParserContext &ctx, const std::string &path,
const std::string &mimetype,
const std::string &rel,
const RttiSet &supportedTypes)
{
- ResourceRequest req{path, mimetype, rel, supportedTypes};
- if (req.deduce(registry, ctx.getLogger())) {
- return parse(registry, ctx, req, ParseMode::LINK);
- }
- return nullptr;
+ return parse(ctx, path, mimetype, rel, supportedTypes, ParseMode::LINK);
}
-Rooted<Node> ResourceManager::include(Registry &registry, ParserContext &ctx,
+Rooted<Node> ResourceManager::include(ParserContext &ctx,
const std::string &path,
const std::string &mimetype,
const std::string &rel,
const RttiSet &supportedTypes)
{
- ResourceRequest req{path, mimetype, rel, supportedTypes};
- if (req.deduce(registry, ctx.getLogger())) {
- return parse(registry, ctx, req, ParseMode::INCLUDE);
- }
- return nullptr;
+ return parse(ctx, path, mimetype, rel, supportedTypes, ParseMode::INCLUDE);
}
SourceContext ResourceManager::readContext(const SourceLocation &location,
@@ -236,5 +238,12 @@ Rooted<Node> ResourceManager::getNode(Manager &mgr, const Resource &resource)
{
return getNode(mgr, getSourceId(resource));
}
+
+SourceContextCallback ResourceManager::getSourceContextCallback()
+{
+ return [this](const SourceLocation &location) {
+ return this->readContext(location);
+ };
+}
}
diff --git a/src/core/resource/ResourceManager.hpp b/src/core/resource/ResourceManager.hpp
index cdd0e34..e98e8f4 100644
--- a/src/core/resource/ResourceManager.hpp
+++ b/src/core/resource/ResourceManager.hpp
@@ -42,7 +42,6 @@
namespace ousia {
// Forward declarations
-class Registry;
class Node;
class Parser;
class ParserContext;
@@ -119,16 +118,23 @@ private:
* "link" or the "include" mode. In the latter case the ParserScope instance
* inside the ParserContext is exchanged with an empty one.
*
- * @param registry is the registry that should be used to locate the
- * resource.
* @param ctx is the context that should be passed to the parser.
- * @param req is a ResourceRequest instance that contains all information
- * about the requested resource.
+ * @param mimetype is the mimetype of the resource that should be parsed
+ * (may be empty, in which case the mimetype is deduced from the file
+ * extension)
+ * @param rel is a "relation string" supplied by the user which specifies
+ * the relationship of the specified resource. May be empty, in which case
+ * the relation is deduced from the supported types and the types of the
+ * parser for the given mimetype.
+ * @param supportedTypes contains the types of the returned Node the caller
+ * can deal with. Note that only the types the parser claims to return are
+ * checked, not the actual result.
* @param mode describes whether the file should be included or linked.
* @return the parsed node or nullptr if something goes wrong.
*/
- Rooted<Node> parse(Registry &registry, ParserContext &ctx,
- const ResourceRequest &req, ParseMode mode);
+ Rooted<Node> parse(ParserContext &ctx, const std::string &path,
+ const std::string &mimetype, const std::string &rel,
+ const RttiSet &supportedTypes, ParseMode mode);
public:
/**
@@ -138,13 +144,11 @@ public:
* which allows the Node instance returned by the parser to be cached. Logs
* any problem in the logger instance of the given ParserContext.
*
- * @param registry is the registry instance that should be used to lookup
- * the parser instances and to locate the resources.
* @param ctx is the context from which the Logger instance will be looked
- * up. This context instance is not directly passed to the Parser, the
- * ParserScope instance is replaced with a new one. The sourceId specified
- * in the context instance will be used as relative location for looking up
- * the new resource.
+ * up. The sourceId specified in the context instance will be used as
+ * relative location for looking up the new resource. The registry specified
+ * in the ParserContext is used to lookup the parser instances and to
+ * locate the resources.
* @param mimetype is the mimetype of the resource that should be parsed
* (may be empty, in which case the mimetype is deduced from the file
* extension)
@@ -157,9 +161,8 @@ public:
* checked, not the actual result.
* @return the parsed node or nullptr if something goes wrong.
*/
- Rooted<Node> link(Registry &registry, ParserContext &ctx,
- const std::string &path, const std::string &mimetype,
- const std::string &rel,
+ Rooted<Node> link(ParserContext &ctx, const std::string &path,
+ const std::string &mimetype, const std::string &rel,
const RttiSet &supportedTypes);
/**
@@ -171,11 +174,11 @@ public:
* a new ParserScope and thus guarantees reproducible results. Logs any
* problem in the logger instance of the given ParserContext.
*
- * @param registry is the registry instance that should be used to lookup
- * the parser instances and to locate the resources.
* @param ctx is the context from which the Logger instance will be looked
* up. The sourceId specified in the context instance will be used as
- * relative location for looking up the new resource.
+ * relative location for looking up the new resource. The registry specified
+ * in the ParserContext is used to lookup the parser instances and to
+ * locate the resources.
* @param path is the requested path of the file that should be included.
* @param mimetype is the mimetype of the resource that should be parsed
* (may be empty, in which case the mimetype is deduced from the file
@@ -189,10 +192,8 @@ public:
* checked, not the actual result.
* @return the parsed node or nullptr if something goes wrong.
*/
- Rooted<Node> include(Registry &registry, ParserContext &ctx,
- const std::string &path,
- const std::string &mimetype,
- const std::string &rel,
+ Rooted<Node> include(ParserContext &ctx, const std::string &path,
+ const std::string &mimetype, const std::string &rel,
const RttiSet &supportedTypes);
/**
@@ -290,6 +291,15 @@ public:
* @return the Node instance corresponding to the given resource.
*/
Rooted<Node> getNode(Manager &mgr, const Resource &resource);
+
+ /**
+ * Returns a SourceContextCallback that can be passed to a logger instance.
+ * Remeber to reset the SourceContextCallback after the Project instance has
+ * been freed.
+ *
+ * @return a SourceContextCallback that is coupled to this Project instance.
+ */
+ SourceContextCallback getSourceContextCallback();
};
}
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp
index 3831b3d..bb9d678 100644
--- a/src/plugins/xml/XmlParser.cpp
+++ b/src/plugins/xml/XmlParser.cpp
@@ -57,13 +57,13 @@ public:
void start(Variant::mapType &args) override
{
- scope().push(project()->createTypesystem(args["name"].asString()));
+ Rooted<Typesystem> typesystem =
+ project()->createTypesystem(args["name"].asString());
+ typesystem->setLocation(location());
+ scope().push(typesystem);
}
- void end() override
- {
- scope().pop();
- }
+ void end() override { scope().pop(); }
static Handler *create(const HandlerData &handlerData)
{
@@ -84,6 +84,7 @@ public:
// Fetch the current typesystem and create the struct node
Rooted<Typesystem> typesystem = scope().getLeaf().cast<Typesystem>();
Rooted<StructType> structType = typesystem->createStructType(name);
+ structType->setLocation(location());
// Try to resolve the parent type and set it as parent structure
if (!parent.empty()) {
@@ -128,6 +129,7 @@ public:
Rooted<StructType> structType = scope().getLeaf().cast<StructType>();
Rooted<Attribute> attribute =
structType->createAttribute(name, defaultValue, optional, logger());
+ attribute->setLocation(location());
// Try to resolve the type
scope().resolve<Type>(
diff --git a/test/core/StandaloneEnvironment.hpp b/test/core/StandaloneEnvironment.hpp
index 23efbe0..eaaa9bf 100644
--- a/test/core/StandaloneEnvironment.hpp
+++ b/test/core/StandaloneEnvironment.hpp
@@ -26,6 +26,7 @@
#include <core/parser/Parser.hpp>
#include <core/parser/ParserScope.hpp>
#include <core/parser/ParserContext.hpp>
+#include <core/resource/ResourceManager.hpp>
#include <core/Registry.hpp>
namespace ousia {
@@ -34,23 +35,31 @@ struct StandaloneEnvironment {
ConcreteLogger &logger;
Manager manager;
Registry registry;
- Rooted<Project> project;
+ ResourceManager resourceManager;
ParserScope scope;
+ Rooted<Project> project;
ParserContext context;
StandaloneEnvironment(ConcreteLogger &logger)
- : logger(logger), project(new Project(manager, registry)),
- context(project, scope, logger)
+ : logger(logger), project(new Project(manager)),
+ context(registry, resourceManager, scope, project, logger)
{
logger.reset();
logger.setSourceContextCallback(
- project->getSourceContextCallback());
+ resourceManager.getSourceContextCallback());
}
~StandaloneEnvironment()
{
logger.setSourceContextCallback(NullSourceContextCallback);
}
+
+ Rooted<Node> parse(const std::string &path,
+ const std::string mimetype, const std::string rel,
+ const RttiSet &supportedTypes)
+ {
+ return context.link(path, mimetype, rel, supportedTypes);
+ }
};
}
diff --git a/test/plugins/xml/XmlParserTest.cpp b/test/plugins/xml/XmlParserTest.cpp
index 7ca191e..0f00c86 100644
--- a/test/plugins/xml/XmlParserTest.cpp
+++ b/test/plugins/xml/XmlParserTest.cpp
@@ -58,16 +58,14 @@ static TerminalLogger logger(std::cerr, true);
TEST(XmlParser, mismatchedTag)
{
XmlStandaloneEnvironment env(logger);
- env.project->parse("mismatchedTag.oxm", "", "",
- RttiSet{&RttiTypes::Document}, logger);
+ env.parse("mismatchedTag.oxm", "", "", RttiSet{&RttiTypes::Document});
ASSERT_TRUE(logger.hasError());
}
TEST(XmlParser, generic)
{
XmlStandaloneEnvironment env(logger);
- env.project->parse("generic.oxm", "", "", RttiSet{&RttiTypes::Document},
- logger);
+ env.parse("generic.oxm", "", "", RttiSet{&RttiTypes::Document});
#ifdef MANAGER_GRAPHVIZ_EXPORT
env.manager.exportGraphviz("xmlDocument.dot");
#endif
diff --git a/testdata/xmlparser/generic.oxm b/testdata/xmlparser/generic.oxm
index 2dbd72b..56a8745 100644
--- a/testdata/xmlparser/generic.oxm
+++ b/testdata/xmlparser/generic.oxm
@@ -3,25 +3,18 @@
<head>
<typesystem name="color">
<types>
- <struct name="rgb">
+ <struct name="rgb"> <!-- Instance 1 -->
<field name="r" type="double"/>
<field name="g" type="double"/>
<field name="b" type="double"/>
</struct>
- <struct name="rgb">
+ <struct name="rgb"> <!-- Instance 2 -->
</struct>
<struct name="rgba" parent="rgb">
<field name="a" type="double" default="0xf3"/>
</struct>
</types>
</typesystem>
- <typesystem name="color2">
- <types>
- <struct name="rgba" parent="rgb">
- <field name="a" type="bla" default="0xf3"/>
- </struct>
- </types>
- </typesystem>
</head>
<body xmlAttr="blub">
<!--<book>Dies ist ein Test&gt;</book>-->