Skip to content

Commit b2525db

Browse files
authored
Drop annotations from contains that were emitted to non-matching items (#447)
Fixes: #446 Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent d9a902a commit b2525db

File tree

3 files changed

+40
-16
lines changed

3 files changed

+40
-16
lines changed

src/compiler/compile_output_simple.cc

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,32 +65,23 @@ auto SimpleOutput::operator()(
6565
const auto &keyword{evaluate_path.back().to_property()};
6666
// To ease the output
6767
if (keyword == "anyOf" || keyword == "oneOf" || keyword == "not" ||
68-
keyword == "if") {
69-
this->mask.emplace(evaluate_path, true);
70-
} else if (keyword == "contains") {
71-
this->mask.emplace(evaluate_path, false);
68+
keyword == "if" || keyword == "contains") {
69+
this->mask.emplace(evaluate_path, instance_location);
7270
}
7371
} else if (type == EvaluationType::Post &&
74-
this->mask.contains(evaluate_path)) {
75-
this->mask.erase(evaluate_path);
72+
this->mask.contains({evaluate_path, instance_location})) {
73+
this->mask.erase({evaluate_path, instance_location});
7674
}
7775

7876
if (result) {
7977
return;
8078
}
8179

82-
if (std::any_of(this->mask.cbegin(), this->mask.cend(),
83-
[&evaluate_path](const auto &entry) {
84-
return evaluate_path.starts_with(entry.first) &&
85-
!entry.second;
86-
})) {
87-
return;
88-
}
89-
9080
if (type == EvaluationType::Post && !this->annotations_.empty()) {
9181
for (auto iterator = this->annotations_.begin();
9282
iterator != this->annotations_.end();) {
93-
if (iterator->first.evaluate_path.starts_with_initial(evaluate_path)) {
83+
if (iterator->first.evaluate_path.starts_with_initial(evaluate_path) &&
84+
iterator->first.instance_location == instance_location) {
9485
iterator = this->annotations_.erase(iterator);
9586
} else {
9687
iterator++;

src/compiler/include/sourcemeta/blaze/compiler_output.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string> // std::string
2020
#include <string_view> // std::string_view
2121
#include <tuple> // std::tie
22+
#include <utility> // std::pair
2223
#include <vector> // std::vector
2324

2425
namespace sourcemeta::blaze {
@@ -126,7 +127,9 @@ class SOURCEMETA_BLAZE_COMPILER_EXPORT SimpleOutput {
126127
const sourcemeta::core::JSON &instance_;
127128
const sourcemeta::core::WeakPointer base_;
128129
container_type output;
129-
std::map<sourcemeta::core::WeakPointer, bool> mask;
130+
std::set<
131+
std::pair<sourcemeta::core::WeakPointer, sourcemeta::core::WeakPointer>>
132+
mask;
130133
std::map<Location, std::vector<sourcemeta::core::JSON>> annotations_;
131134
#if defined(_MSC_VER)
132135
#pragma warning(default : 4251)

test/compiler/compiler_output_simple_test.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,36 @@ TEST(Compiler_output_simple, annotations_success_9) {
803803
0, sourcemeta::core::JSON{true});
804804
}
805805

806+
TEST(Compiler_output_simple, annotations_success_10) {
807+
const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({
808+
"$schema": "https://json-schema.org/draft/2020-12/schema",
809+
"contains": { "type": "number", "title": "Test" }
810+
})JSON")};
811+
812+
const auto schema_template{sourcemeta::blaze::compile(
813+
schema, sourcemeta::core::schema_official_walker,
814+
sourcemeta::core::schema_official_resolver,
815+
sourcemeta::blaze::default_schema_compiler,
816+
sourcemeta::blaze::Mode::Exhaustive)};
817+
818+
const sourcemeta::core::JSON instance{
819+
sourcemeta::core::parse_json("[ \"foo\", 42, true ]")};
820+
821+
sourcemeta::blaze::SimpleOutput output{instance};
822+
sourcemeta::blaze::Evaluator evaluator;
823+
const auto result{
824+
evaluator.validate(schema_template, instance, std::ref(output))};
825+
EXPECT_TRUE(result);
826+
827+
EXPECT_ANNOTATION_COUNT(output, 2);
828+
829+
EXPECT_ANNOTATION_ENTRY(output, "", "/contains", "#/contains", 1);
830+
EXPECT_ANNOTATION_ENTRY(output, "/1", "/contains/title", "#/contains/title",
831+
1);
832+
EXPECT_ANNOTATION_VALUE(output, "/1", "/contains/title", "#/contains/title",
833+
0, sourcemeta::core::JSON{"Test"});
834+
}
835+
806836
TEST(Compiler_output_simple, annotations_failure_1) {
807837
const sourcemeta::core::JSON schema{sourcemeta::core::parse_json(R"JSON({
808838
"$schema": "https://json-schema.org/draft/2020-12/schema",

0 commit comments

Comments
 (0)