Skip to content

Commit b152221

Browse files
committed
Simpler
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 3b823fa commit b152221

1 file changed

Lines changed: 39 additions & 21 deletions

File tree

src/ir/ir.cc

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,49 @@
77

88
#include "ir_default_compiler.h"
99

10-
namespace sourcemeta::codegen {
10+
namespace {
11+
12+
auto is_validation_subschema(
13+
const sourcemeta::core::SchemaFrame &frame,
14+
const sourcemeta::core::SchemaFrame::Location &location,
15+
const sourcemeta::core::SchemaWalker &walker,
16+
const sourcemeta::core::SchemaResolver &resolver) -> bool {
17+
if (!location.parent.has_value()) {
18+
return false;
19+
}
1120

12-
static auto
13-
is_validation_only_location(const sourcemeta::core::WeakPointer &pointer)
14-
-> bool {
15-
static const std::unordered_set<std::string_view> validation_only_keywords{
16-
"propertyNames", "contains"};
17-
static const std::unordered_set<std::string_view> container_keywords{
18-
"properties", "patternProperties", "$defs", "definitions"};
19-
for (std::size_t index = 0; index < pointer.size(); ++index) {
20-
const auto &token{pointer.at(index)};
21-
if (!token.is_property() ||
22-
!validation_only_keywords.contains(token.to_property())) {
23-
continue;
24-
}
21+
const auto &parent{location.parent.value()};
22+
if (parent.size() >= location.pointer.size()) {
23+
return false;
24+
}
2525

26-
if (index == 0 || !pointer.at(index - 1).is_property() ||
27-
!container_keywords.contains(pointer.at(index - 1).to_property())) {
28-
return true;
29-
}
26+
const auto &keyword_token{location.pointer.at(parent.size())};
27+
if (!keyword_token.is_property()) {
28+
return false;
3029
}
3130

32-
return false;
31+
const auto parent_location{frame.traverse(parent)};
32+
if (!parent_location.has_value()) {
33+
return false;
34+
}
35+
36+
const auto vocabularies{
37+
frame.vocabularies(parent_location.value().get(), resolver)};
38+
const auto &walker_result{walker(keyword_token.to_property(), vocabularies)};
39+
using Type = sourcemeta::core::SchemaKeywordType;
40+
if (walker_result.type == Type::ApplicatorValueTraverseAnyPropertyKey ||
41+
walker_result.type == Type::ApplicatorValueTraverseAnyItem) {
42+
return true;
43+
}
44+
45+
return is_validation_subschema(frame, parent_location.value().get(), walker,
46+
resolver);
3347
}
3448

49+
} // anonymous namespace
50+
51+
namespace sourcemeta::codegen {
52+
3553
auto compile(const sourcemeta::core::JSON &input,
3654
const sourcemeta::core::SchemaWalker &walker,
3755
const sourcemeta::core::SchemaResolver &resolver,
@@ -91,8 +109,8 @@ auto compile(const sourcemeta::core::JSON &input,
91109
}
92110

93111
// Skip subschemas under validation-only keywords that do not contribute
94-
// to the type structure
95-
if (is_validation_only_location(location.pointer)) {
112+
// to the type structure (like `contains`)
113+
if (is_validation_subschema(frame, location, walker, resolver)) {
96114
continue;
97115
}
98116

0 commit comments

Comments
 (0)