diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/common/Logger.hpp | 14 | ||||
-rw-r--r-- | src/core/common/Variant.hpp | 6 | ||||
-rw-r--r-- | src/core/managed/Managed.hpp | 10 | ||||
-rw-r--r-- | src/core/managed/ManagedContainer.hpp | 4 | ||||
-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 |
13 files changed, 215 insertions, 258 deletions
diff --git a/src/core/common/Logger.hpp b/src/core/common/Logger.hpp index 479160b..433aa31 100644 --- a/src/core/common/Logger.hpp +++ b/src/core/common/Logger.hpp @@ -269,12 +269,6 @@ public: // Default constructor Logger() {} - // No copy - Logger(const Logger &) = delete; - - // No assign - Logger &operator=(const Logger &) = delete; - /** * Logs the given message. The file name is set to the topmost file name on * the file name stack. @@ -601,14 +595,6 @@ protected: SourceContextCallback sourceContextCallback) override; public: - // Default move constructor - LoggerFork(LoggerFork &&l) - : calls(std::move(l.calls)), - messages(std::move(l.messages)), - locations(std::move(l.locations)), - callbacks(std::move(l.callbacks)), - parent(std::move(l.parent)){}; - /** * Commits all collected messages to the parent Logger instance. */ diff --git a/src/core/common/Variant.hpp b/src/core/common/Variant.hpp index fc4faf5..103c0e7 100644 --- a/src/core/common/Variant.hpp +++ b/src/core/common/Variant.hpp @@ -211,7 +211,7 @@ private: * * @param v is the Variant instance that should be copied to this instance. */ - void move(Variant &&v) + void move(Variant &&v) noexcept { destroy(); type = v.type; @@ -290,7 +290,7 @@ public: * @param v is the reference to the Variant instance that should be moved, * this instance is invalidated afterwards. */ - Variant(Variant &&v) : ptrVal(nullptr) { move(std::move(v)); } + Variant(Variant &&v) noexcept : ptrVal(nullptr) { move(std::move(v)); } /** * Default constructor. VariantType is set to VariantType:NULLPTR. @@ -413,7 +413,7 @@ public: /** * Move assignment operator. */ - Variant &operator=(Variant &&v) + Variant &operator=(Variant &&v) noexcept { move(std::move(v)); return *this; diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index cb7104b..7c43527 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -453,7 +453,7 @@ public: * * @param h is the Rooted to be moved to this instance. */ - Rooted(Rooted<T> &&h) : Handle<T>(h.ptr) { h.ptr = nullptr; } + Rooted(Rooted<T> &&h) noexcept : Handle<T>(h.ptr) { h.ptr = nullptr; } /** * Constructor of the Rooted class. @@ -494,7 +494,7 @@ public: * * @param h is the Owned to be moved to this instance. */ - Rooted<T> &operator=(Rooted<T> &&h) + Rooted<T> &operator=(Rooted<T> &&h) noexcept { deleteRef(); this->ptr = h.ptr; @@ -523,7 +523,7 @@ public: * * @param h is the Owned to be moved to this instance. */ - Rooted<T> &operator=(Handle<T> &&h) + Rooted<T> &operator=(Handle<T> &&h) noexcept { deleteRef(); this->ptr = h.ptr; @@ -600,7 +600,7 @@ public: * * @param h is the Owned to be moved to this instance. */ - Owned(Owned<T> &&h) : Handle<T>(h.get()), owner(h.getOwner()) + Owned(Owned<T> &&h) noexcept : Handle<T>(h.get()), owner(h.getOwner()) { h.ptr = nullptr; } @@ -627,7 +627,7 @@ public: * * @param h is the Owned to be moved to this instance. */ - Owned<T> &operator=(Owned<T> &&h) + Owned<T> &operator=(Owned<T> &&h) noexcept { deleteRef(); this->ptr = h.ptr; diff --git a/src/core/managed/ManagedContainer.hpp b/src/core/managed/ManagedContainer.hpp index f62ba11..35d431b 100644 --- a/src/core/managed/ManagedContainer.hpp +++ b/src/core/managed/ManagedContainer.hpp @@ -319,7 +319,7 @@ public: * * @param other is the other container that should be moved. */ - ManagedContainer(own_type &&other) + ManagedContainer(own_type &&other) noexcept : owner(other.owner), c(std::move(other.c)) { // other.owner = nullptr; @@ -408,7 +408,7 @@ public: * @param other is the collection instance that should be moved; * @return this instance. */ - own_type &operator=(own_type &&other) + own_type &operator=(own_type &&other) noexcept { finalize(); owner = other.owner; 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>( |