Skip to content

Commit

Permalink
refactor(config_compiler): seperate out part of the implementation to…
Browse files Browse the repository at this point in the history
… be used by plugins
  • Loading branch information
lotem committed Sep 15, 2017
1 parent ecf3397 commit a862298
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 98 deletions.
122 changes: 24 additions & 98 deletions src/rime/config/config_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,12 @@
#include <rime/common.h>
#include <rime/resource.h>
#include <rime/config/config_compiler.h>
#include <rime/config/config_compiler_impl.h>
#include <rime/config/config_data.h>
#include <rime/config/config_types.h>

namespace rime {

enum DependencyPriority {
kPendingChild = 0,
kInclude = 1,
kPatch = 2,
};

struct Dependency {
an<ConfigItemRef> target;

virtual DependencyPriority priority() const = 0;
bool blocking() const {
return priority() > kPendingChild;
}
virtual string repr() const = 0;
virtual bool Resolve(ConfigCompiler* compiler) = 0;
};

template <class StreamT>
StreamT& operator<< (StreamT& stream, const Dependency& dep) {
return stream << dep.repr();
}

struct PendingChild : Dependency {
string child_path;
an<ConfigItemRef> child_ref;

PendingChild(const string& path, const an<ConfigItemRef>& 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 ? " <optional>" : "");
}

template <class StreamT>
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<ConfigMap> patch;

PatchLiteral(an<ConfigMap> map) : patch(map) {
}
DependencyPriority priority() const override {
return kPatch;
}
string repr() const override {
return "Patch(<literal>)";
}
bool Resolve(ConfigCompiler* compiler) override;
};

struct ConfigDependencyGraph {
map<string, of<ConfigResource>> resources;
vector<of<ConfigItemRef>> node_stack;
Expand All @@ -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 ? " <optional>" : "");
}

bool PendingChild::Resolve(ConfigCompiler* compiler) {
return compiler->ResolveDependencies(child_path);
}
Expand Down Expand Up @@ -156,8 +74,7 @@ bool PatchReference::Resolve(ConfigCompiler* compiler) {
return false;
}
PatchLiteral patch{As<ConfigMap>(item)};
patch.target = target;
return patch.Resolve(compiler);
return patch.TargetedAt(target).Resolve(compiler);
}

static bool AppendToString(an<ConfigItemRef> target, an<ConfigValue> value) {
Expand Down Expand Up @@ -294,7 +211,7 @@ void ConfigDependencyGraph::Add(an<Dependency> 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();
Expand Down Expand Up @@ -353,6 +270,10 @@ void ConfigCompiler::AddDependency(an<Dependency> dependency) {
graph_->Add(dependency);
}

void ConfigCompiler::Push(an<ConfigResource> resource) {
graph_->Push(resource, resource->resource_id + ":");
}

void ConfigCompiler::Push(an<ConfigList> config_list, size_t index) {
graph_->Push(
New<ConfigListEntryRef>(nullptr, config_list, index),
Expand All @@ -378,10 +299,10 @@ an<ConfigResource> ConfigCompiler::Compile(const string& file_name) {
auto resource_id = resource_resolver_->ToResourceId(file_name);
auto resource = New<ConfigResource>(resource_id, New<ConfigData>());
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;
}

Expand Down Expand Up @@ -462,6 +383,11 @@ bool ConfigCompiler::resolved(const string& full_path) const {
return found == graph_->deps.end() || found->second.empty();
}

vector<of<Dependency>> ConfigCompiler::GetDependencies(const string& path) {
auto found = graph_->deps.find(path);
return found == graph_->deps.end() ? vector<of<Dependency>>() : found->second;
}

static an<ConfigItem> ResolveReference(ConfigCompiler* compiler,
const Reference& reference) {
auto resource = compiler->GetCompiledResource(reference.resource_id);
Expand Down
2 changes: 2 additions & 0 deletions src/rime/config/config_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ConfigCompiler {

Reference CreateReference(const string& qualified_path);
void AddDependency(an<Dependency> dependency);
void Push(an<ConfigResource> resource);
void Push(an<ConfigList> config_list, size_t index);
void Push(an<ConfigMap> config_map, const string& key);
bool Parse(const string& key, const an<ConfigItem>& item);
Expand All @@ -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<of<Dependency>> GetDependencies(const string& path);
bool ResolveDependencies(const string& path);

private:
Expand Down
100 changes: 100 additions & 0 deletions src/rime/config/config_compiler_impl.h
Original file line number Diff line number Diff line change
@@ -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 <rime/common.h>
#include <rime/config/config_compiler.h>
#include <rime/config/config_types.h>

namespace rime {

enum DependencyPriority {
kPendingChild = 0,
kInclude = 1,
kPatch = 2,
};

struct Dependency {
an<ConfigItemRef> target;

virtual DependencyPriority priority() const = 0;
bool blocking() const {
return priority() > kPendingChild;
}
virtual string repr() const = 0;
Dependency& TargetedAt(an<ConfigItemRef> target) {
this->target = target;
return *this;
}
virtual bool Resolve(ConfigCompiler* compiler) = 0;
};

template <class StreamT, class RepresentableT>
StreamT& operator<< (StreamT& stream, const RepresentableT& representable) {
return stream << representable.repr();
}

struct PendingChild : Dependency {
string child_path;
an<ConfigItemRef> child_ref;

PendingChild(const string& path, const an<ConfigItemRef>& 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<ConfigMap> patch;

PatchLiteral(an<ConfigMap> map) : patch(map) {
}
DependencyPriority priority() const override {
return kPatch;
}
string repr() const override {
return "Patch(<literal>)";
}
bool Resolve(ConfigCompiler* compiler) override;
};

} // namespace rime

#endif // RIME_CONFIG_COMPILER_IMPL_H_

0 comments on commit a862298

Please sign in to comment.