diff --git a/src/rime/config/config_compiler.cc b/src/rime/config/config_compiler.cc index 6e8b23091..376cfb475 100644 --- a/src/rime/config/config_compiler.cc +++ b/src/rime/config/config_compiler.cc @@ -2,100 +2,12 @@ #include #include #include +#include #include #include namespace rime { -enum DependencyPriority { - kPendingChild = 0, - kInclude = 1, - kPatch = 2, -}; - -struct Dependency { - an target; - - virtual DependencyPriority priority() const = 0; - bool blocking() const { - return priority() > kPendingChild; - } - virtual string repr() const = 0; - virtual bool Resolve(ConfigCompiler* compiler) = 0; -}; - -template -StreamT& operator<< (StreamT& stream, const Dependency& dep) { - return stream << dep.repr(); -} - -struct PendingChild : Dependency { - string child_path; - an child_ref; - - PendingChild(const string& path, const an& ref) - : child_path(path), child_ref(ref) { - } - DependencyPriority priority() const override { - return kPendingChild; - } - string repr() const override { - return "PendingChild(" + child_path + ")"; - } - bool Resolve(ConfigCompiler* compiler) override; -}; - -string Reference::repr() const { - return resource_id + ":" + local_path + (optional ? " " : ""); -} - -template -StreamT& operator<< (StreamT& stream, const Reference& reference) { - return stream << reference.repr(); -} - -struct IncludeReference : Dependency { - IncludeReference(const Reference& r) : reference(r) { - } - DependencyPriority priority() const override { - return kInclude; - } - string repr() const override { - return "Include(" + reference.repr() + ")"; - } - bool Resolve(ConfigCompiler* compiler) override; - - Reference reference; -}; - -struct PatchReference : Dependency { - PatchReference(const Reference& r) : reference(r) { - } - DependencyPriority priority() const override { - return kPatch; - } - string repr() const override { - return "Patch(" + reference.repr() + ")"; - } - bool Resolve(ConfigCompiler* compiler) override; - - Reference reference; -}; - -struct PatchLiteral : Dependency { - an patch; - - PatchLiteral(an map) : patch(map) { - } - DependencyPriority priority() const override { - return kPatch; - } - string repr() const override { - return "Patch()"; - } - bool Resolve(ConfigCompiler* compiler) override; -}; - struct ConfigDependencyGraph { map> resources; vector> node_stack; @@ -114,12 +26,18 @@ struct ConfigDependencyGraph { key_stack.pop_back(); } - string current_resource_id() const { - return key_stack.empty() ? string() - : boost::trim_right_copy_if(key_stack.front(), boost::is_any_of(":")); - } + string current_resource_id() const; }; +string ConfigDependencyGraph::current_resource_id() const { + return key_stack.empty() ? string() + : boost::trim_right_copy_if(key_stack.front(), boost::is_any_of(":")); +} + +string Reference::repr() const { + return resource_id + ":" + local_path + (optional ? " " : ""); +} + bool PendingChild::Resolve(ConfigCompiler* compiler) { return compiler->ResolveDependencies(child_path); } @@ -156,8 +74,7 @@ bool PatchReference::Resolve(ConfigCompiler* compiler) { return false; } PatchLiteral patch{As(item)}; - patch.target = target; - return patch.Resolve(compiler); + return patch.TargetedAt(target).Resolve(compiler); } static bool AppendToString(an target, an value) { @@ -294,7 +211,7 @@ void ConfigDependencyGraph::Add(an dependency) { << node_stack.size(); if (node_stack.empty()) return; const auto& target = node_stack.back(); - dependency->target = target; + dependency->TargetedAt(target); auto target_path = ConfigData::JoinPath(key_stack); auto& target_deps = deps[target_path]; bool target_was_pending = !target_deps.empty(); @@ -353,6 +270,10 @@ void ConfigCompiler::AddDependency(an dependency) { graph_->Add(dependency); } +void ConfigCompiler::Push(an resource) { + graph_->Push(resource, resource->resource_id + ":"); +} + void ConfigCompiler::Push(an config_list, size_t index) { graph_->Push( New(nullptr, config_list, index), @@ -378,10 +299,10 @@ an ConfigCompiler::Compile(const string& file_name) { auto resource_id = resource_resolver_->ToResourceId(file_name); auto resource = New(resource_id, New()); graph_->resources[resource_id] = resource; - graph_->Push(resource, resource_id + ":"); + Push(resource); resource->loaded = resource->data->LoadFromFile( resource_resolver_->ResolvePath(resource_id).string(), this); - graph_->Pop(); + Pop(); return resource; } @@ -462,6 +383,11 @@ bool ConfigCompiler::resolved(const string& full_path) const { return found == graph_->deps.end() || found->second.empty(); } +vector> ConfigCompiler::GetDependencies(const string& path) { + auto found = graph_->deps.find(path); + return found == graph_->deps.end() ? vector>() : found->second; +} + static an ResolveReference(ConfigCompiler* compiler, const Reference& reference) { auto resource = compiler->GetCompiledResource(reference.resource_id); diff --git a/src/rime/config/config_compiler.h b/src/rime/config/config_compiler.h index 16704d49f..2975d2fcb 100644 --- a/src/rime/config/config_compiler.h +++ b/src/rime/config/config_compiler.h @@ -51,6 +51,7 @@ class ConfigCompiler { Reference CreateReference(const string& qualified_path); void AddDependency(an dependency); + void Push(an resource); void Push(an config_list, size_t index); void Push(an config_map, const string& key); bool Parse(const string& key, const an& item); @@ -63,6 +64,7 @@ class ConfigCompiler { bool blocking(const string& full_path) const; bool pending(const string& full_path) const; bool resolved(const string& full_path) const; + vector> GetDependencies(const string& path); bool ResolveDependencies(const string& path); private: diff --git a/src/rime/config/config_compiler_impl.h b/src/rime/config/config_compiler_impl.h new file mode 100644 index 000000000..cde33a7bd --- /dev/null +++ b/src/rime/config/config_compiler_impl.h @@ -0,0 +1,100 @@ +// +// Copyright RIME Developers +// Distributed under the BSD License +// +#ifndef RIME_CONFIG_COMPILER_IMPL_H_ +#define RIME_CONFIG_COMPILER_IMPL_H_ + +#include +#include +#include + +namespace rime { + +enum DependencyPriority { + kPendingChild = 0, + kInclude = 1, + kPatch = 2, +}; + +struct Dependency { + an target; + + virtual DependencyPriority priority() const = 0; + bool blocking() const { + return priority() > kPendingChild; + } + virtual string repr() const = 0; + Dependency& TargetedAt(an target) { + this->target = target; + return *this; + } + virtual bool Resolve(ConfigCompiler* compiler) = 0; +}; + +template +StreamT& operator<< (StreamT& stream, const RepresentableT& representable) { + return stream << representable.repr(); +} + +struct PendingChild : Dependency { + string child_path; + an child_ref; + + PendingChild(const string& path, const an& ref) + : child_path(path), child_ref(ref) { + } + DependencyPriority priority() const override { + return kPendingChild; + } + string repr() const override { + return "PendingChild(" + child_path + ")"; + } + bool Resolve(ConfigCompiler* compiler) override; +}; + +struct IncludeReference : Dependency { + Reference reference; + + IncludeReference(const Reference& r) : reference(r) { + } + DependencyPriority priority() const override { + return kInclude; + } + string repr() const override { + return "Include(" + reference.repr() + ")"; + } + bool Resolve(ConfigCompiler* compiler) override; +}; + +struct PatchReference : Dependency { + Reference reference; + + PatchReference(const Reference& r) : reference(r) { + } + DependencyPriority priority() const override { + return kPatch; + } + string repr() const override { + return "Patch(" + reference.repr() + ")"; + } + bool Resolve(ConfigCompiler* compiler) override; +}; + +struct PatchLiteral : Dependency { + an patch; + + PatchLiteral(an map) : patch(map) { + } + DependencyPriority priority() const override { + return kPatch; + } + string repr() const override { + return "Patch()"; + } + bool Resolve(ConfigCompiler* compiler) override; +}; + +} // namespace rime + +#endif // RIME_CONFIG_COMPILER_IMPL_H_