Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify EvaluationContext with regards to evaluation tracking #18

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 10 additions & 37 deletions src/evaluator/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ auto EvaluationContext::prepare(const sourcemeta::jsontoolkit::JSON &instance)
this->labels.clear();
this->property_as_instance = false;
this->evaluated_.clear();
this->annotation_blacklist.clear();
this->evaluated_blacklist_.clear();
}

auto EvaluationContext::push_without_traverse(
Expand Down Expand Up @@ -92,14 +92,6 @@ auto EvaluationContext::pop(const bool dynamic) -> void {
}
}

// TODO: At least currently, we only need to mask if a schema
// makes use of `unevaluatedProperties` or `unevaluatedItems`
// Detect if a schema does need this so if not, we avoid
// an unnecessary copy
auto EvaluationContext::mask() -> void {
this->annotation_blacklist.push_back(this->evaluate_path_);
}

auto EvaluationContext::enter(
const sourcemeta::jsontoolkit::WeakPointer::Token::Property &property)
-> void {
Expand Down Expand Up @@ -219,42 +211,19 @@ auto EvaluationContext::evaluate(
}

auto EvaluationContext::is_evaluated(
const sourcemeta::jsontoolkit::Pointer::Token::Property &property) const
-> bool {
auto expected_instance_location = this->instance_location_;
expected_instance_location.push_back(property);

for (const auto &entry : this->evaluated_) {
if (entry.first == expected_instance_location &&
// Its not possible to affect cousins
entry.second.starts_with(this->evaluate_path_.initial())) {
// Handle "not"
for (const auto &mask : this->annotation_blacklist) {
if (entry.second.starts_with(mask) &&
!this->evaluate_path_.starts_with(mask)) {
return false;
}
}

return true;
}
}

return false;
}

auto EvaluationContext::is_evaluated(
const sourcemeta::jsontoolkit::Pointer::Token::Index index) const -> bool {
sourcemeta::jsontoolkit::WeakPointer::Token &&token) const -> bool {
auto expected_instance_location = this->instance_location_;
expected_instance_location.push_back(index);
// TODO: Allow directly pushing back a token
expected_instance_location.push_back(
sourcemeta::jsontoolkit::WeakPointer{std::move(token)});

for (const auto &entry : this->evaluated_) {
if ((entry.first == expected_instance_location ||
entry.first == this->instance_location_) &&
// Its not possible to affect cousins
entry.second.starts_with(this->evaluate_path_.initial())) {
// Handle "not"
for (const auto &mask : this->annotation_blacklist) {
for (const auto &mask : this->evaluated_blacklist_) {
if (entry.second.starts_with(mask) &&
!this->evaluate_path_.starts_with(mask)) {
return false;
Expand All @@ -268,4 +237,8 @@ auto EvaluationContext::is_evaluated(
return false;
}

auto EvaluationContext::unevaluate() -> void {
this->evaluated_blacklist_.push_back(this->evaluate_path_);
}

} // namespace sourcemeta::blaze
14 changes: 8 additions & 6 deletions src/evaluator/evaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -703,17 +703,17 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
case IS_STEP(LogicalNot): {
EVALUATE_BEGIN_NO_PRECONDITION(logical, LogicalNot);

if (logical.value) {
context.mask();
}

for (const auto &child : logical.children) {
if (!evaluate_step(child, callback, context)) {
result = true;
break;
}
}

if (logical.value) {
context.unevaluate();
}

EVALUATE_END(logical, LogicalNot);
}

Expand All @@ -722,7 +722,8 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
result = true;

for (const auto &entry : target.as_object()) {
if (context.is_evaluated(entry.first)) {
if (context.is_evaluated(
sourcemeta::jsontoolkit::WeakPointer::Token{entry.first})) {
continue;
}

Expand Down Expand Up @@ -750,7 +751,8 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
for (auto iterator = array.cbegin(); iterator != array.cend();
++iterator) {
const auto index{std::distance(array.cbegin(), iterator)};
if (context.is_evaluated(static_cast<Pointer::Token::Index>(index))) {
if (context.is_evaluated(
static_cast<WeakPointer::Token::Index>(index))) {
continue;
}

Expand Down
17 changes: 5 additions & 12 deletions src/evaluator/include/sourcemeta/blaze/evaluator_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,9 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT EvaluationContext {
auto
evaluate(const sourcemeta::jsontoolkit::Pointer &relative_instance_location)
-> void;
auto mask() -> void;

// TODO: Have a single is_evaluated() that operates on a Token?
auto is_evaluated(
const sourcemeta::jsontoolkit::Pointer::Token::Property &property) const
-> bool;
auto
is_evaluated(const sourcemeta::jsontoolkit::Pointer::Token::Index index) const
auto is_evaluated(sourcemeta::jsontoolkit::WeakPointer::Token &&token) const
-> bool;
auto unevaluate() -> void;

public:
// TODO: Remove this
Expand All @@ -128,13 +122,12 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT EvaluationContext {
std::vector<std::size_t> resources_;
std::map<std::size_t, const std::reference_wrapper<const Template>> labels;
bool property_as_instance{false};
// TODO: Turn this into a trie

// TODO: Turn these into a trie
std::vector<std::pair<sourcemeta::jsontoolkit::WeakPointer,
sourcemeta::jsontoolkit::WeakPointer>>
evaluated_;

// TODO: Make this part of the trie above
std::vector<sourcemeta::jsontoolkit::WeakPointer> annotation_blacklist;
std::vector<sourcemeta::jsontoolkit::WeakPointer> evaluated_blacklist_;
#if defined(_MSC_VER)
#pragma warning(default : 4251 4275)
#endif
Expand Down