diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-27 01:39:19 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-27 01:39:19 +0100 |
commit | 84f0004cdf45f6fbad6461676897aa27f03cbb93 (patch) | |
tree | acb15536b40d7389c3c65df1567084bb57da416e | |
parent | 495e2de57e587450e9532c7fe4ae0c2bfb196e6c (diff) |
Removed dependency between "Project" model class and parser/resources. This reduces coupling and was stupid beforehand.
-rw-r--r-- | src/core/model/Document.hpp | 11 | ||||
-rw-r--r-- | src/core/model/Node.hpp | 8 | ||||
-rw-r--r-- | src/core/model/Project.cpp | 42 | ||||
-rw-r--r-- | src/core/model/Project.hpp | 104 | ||||
-rw-r--r-- | src/core/parser/ParserContext.cpp | 39 | ||||
-rw-r--r-- | src/core/parser/ParserContext.hpp | 108 | ||||
-rw-r--r-- | src/core/resource/ResourceManager.cpp | 59 | ||||
-rw-r--r-- | src/core/resource/ResourceManager.hpp | 56 | ||||
-rw-r--r-- | src/plugins/xml/XmlParser.cpp | 12 | ||||
-rw-r--r-- | test/core/StandaloneEnvironment.hpp | 17 | ||||
-rw-r--r-- | test/plugins/xml/XmlParserTest.cpp | 6 | ||||
-rw-r--r-- | testdata/xmlparser/generic.oxm | 11 |
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 ®istry) +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 ®istry; - - /** * 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 ®istry); - - /** - * 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 ®istry, + 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 ®istry; + + /** + * 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 ®istry, 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 ®istry, 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 ®istry = 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 ®istry, 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 ®istry, 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 ®istry, 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 ®istry, ParserContext &ctx, return node; } -Rooted<Node> ResourceManager::link(Registry ®istry, 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 ®istry, 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 ®istry, 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 ®istry, 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 ®istry, 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></book>--> |