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 non-pure-annotation instructions #17

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
17 changes: 2 additions & 15 deletions src/compiler/compile_describe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,6 @@ struct DescribeVisitor {
return message.str();
}

auto operator()(const AnnotationNot &) const -> std::string {
std::ostringstream message;
message
<< "The " << to_string(this->target.type())
<< " value was expected to not validate against the given subschema";
if (!this->valid) {
message << ", but it did";
}

return message.str();
}

auto operator()(const ControlLabel &) const -> std::string {
return describe_reference(this->target);
}
Expand Down Expand Up @@ -619,8 +607,7 @@ struct DescribeVisitor {
return message.str();
}

auto operator()(const AnnotationLoopPropertiesUnevaluated &step) const
-> std::string {
auto operator()(const LoopPropertiesUnevaluated &step) const -> std::string {
if (this->keyword == "unevaluatedProperties") {
std::ostringstream message;
if (!step.children.empty() &&
Expand Down Expand Up @@ -712,7 +699,7 @@ struct DescribeVisitor {
return message.str();
}

auto operator()(const AnnotationLoopItemsUnevaluated &) const -> std::string {
auto operator()(const LoopItemsUnevaluated &) const -> std::string {
assert(this->keyword == "unevaluatedItems");
std::ostringstream message;
message << "The array items not covered by other array keywords, if any, "
Expand Down
7 changes: 2 additions & 5 deletions src/compiler/compile_json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,6 @@ struct StepVisitor {
AnnotationWhenArraySizeGreater)
HANDLE_STEP("annotation", "to-parent", AnnotationToParent)
HANDLE_STEP("annotation", "basename-to-parent", AnnotationBasenameToParent)
HANDLE_STEP("annotation", "loop-properties-unevaluated",
AnnotationLoopPropertiesUnevaluated)
HANDLE_STEP("annotation", "loop-items-unevaluated",
AnnotationLoopItemsUnevaluated)
HANDLE_STEP("annotation", "not", AnnotationNot)
HANDLE_STEP("logical", "not", LogicalNot)
HANDLE_STEP("logical", "or", LogicalOr)
HANDLE_STEP("logical", "and", LogicalAnd)
Expand All @@ -266,6 +261,8 @@ struct StepVisitor {
HANDLE_STEP("logical", "when-defines", LogicalWhenDefines)
HANDLE_STEP("logical", "when-array-size-greater", LogicalWhenArraySizeGreater)
HANDLE_STEP("logical", "when-array-size-equal", LogicalWhenArraySizeEqual)
HANDLE_STEP("loop", "properties-unevaluated", LoopPropertiesUnevaluated)
HANDLE_STEP("loop", "items-unevaluated", LoopItemsUnevaluated)
HANDLE_STEP("loop", "properties-match", LoopPropertiesMatch)
HANDLE_STEP("loop", "properties", LoopProperties)
HANDLE_STEP("loop", "properties-regex", LoopPropertiesRegex)
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/default_compiler_2019_09.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ auto compiler_2019_09_applicator_unevaluateditems(
relative_dynamic_context,
ValuePointer{}));

return {make<AnnotationLoopItemsUnevaluated>(true, context, schema_context,
dynamic_context, ValueNone{},
std::move(children))};
return {make<LoopItemsUnevaluated>(true, context, schema_context,
dynamic_context, ValueNone{},
std::move(children))};
}

auto compiler_2019_09_applicator_unevaluatedproperties(
Expand All @@ -254,9 +254,9 @@ auto compiler_2019_09_applicator_unevaluatedproperties(
relative_dynamic_context,
ValuePointer{}));

return {make<AnnotationLoopPropertiesUnevaluated>(
true, context, schema_context, dynamic_context, ValueNone{},
std::move(children))};
return {make<LoopPropertiesUnevaluated>(true, context, schema_context,
dynamic_context, ValueNone{},
std::move(children))};
}

auto compiler_2019_09_core_recursiveref(const Context &context,
Expand Down
25 changes: 9 additions & 16 deletions src/compiler/default_compiler_draft4.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,22 +818,15 @@ auto compiler_draft4_applicator_not(const Context &context,
const SchemaContext &schema_context,
const DynamicContext &dynamic_context)
-> Template {
// Only emit a `not` instruction that keeps track of
// dropping annotations if we really need it
if (context.mode != Mode::FastValidation ||
context.uses_unevaluated_properties || context.uses_unevaluated_items) {
return {make<AnnotationNot>(
true, context, schema_context, dynamic_context, ValueNone{},
compile(context, schema_context, relative_dynamic_context,
sourcemeta::jsontoolkit::empty_pointer,
sourcemeta::jsontoolkit::empty_pointer))};
} else {
return {make<LogicalNot>(
true, context, schema_context, dynamic_context, ValueNone{},
compile(context, schema_context, relative_dynamic_context,
sourcemeta::jsontoolkit::empty_pointer,
sourcemeta::jsontoolkit::empty_pointer))};
}
return {make<LogicalNot>(true, context, schema_context, dynamic_context,
// Only emit a `not` instruction that keeps track of
// evaluation if we really need it
ValueBoolean{context.uses_unevaluated_properties ||
context.uses_unevaluated_items},
compile(context, schema_context,
relative_dynamic_context,
sourcemeta::jsontoolkit::empty_pointer,
sourcemeta::jsontoolkit::empty_pointer))};
}

auto compiler_draft4_applicator_items_array(
Expand Down
56 changes: 23 additions & 33 deletions src/evaluator/evaluator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,25 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
context.instance_location().back().to_json());
}

case IS_STEP(AnnotationLoopPropertiesUnevaluated): {
EVALUATE_BEGIN(loop, AnnotationLoopPropertiesUnevaluated,
target.is_object());
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;
}
}

EVALUATE_END(logical, LogicalNot);
}

case IS_STEP(LoopPropertiesUnevaluated): {
EVALUATE_BEGIN(loop, LoopPropertiesUnevaluated, target.is_object());
result = true;

for (const auto &entry : target.as_object()) {
Expand All @@ -724,11 +740,11 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
}

evaluate_annotation_loop_properties_unevaluated_end:
EVALUATE_END(loop, AnnotationLoopPropertiesUnevaluated);
EVALUATE_END(loop, LoopPropertiesUnevaluated);
}

case IS_STEP(AnnotationLoopItemsUnevaluated): {
EVALUATE_BEGIN(loop, AnnotationLoopItemsUnevaluated, target.is_array());
case IS_STEP(LoopItemsUnevaluated): {
EVALUATE_BEGIN(loop, LoopItemsUnevaluated, target.is_array());
const auto &array{target.as_array()};
result = true;
for (auto iterator = array.cbegin(); iterator != array.cend();
Expand All @@ -751,33 +767,7 @@ auto evaluate_step(const sourcemeta::blaze::Template::value_type &step,
}

evaluate_compiler_annotation_loop_items_unevaluated_end:
EVALUATE_END(loop, AnnotationLoopItemsUnevaluated);
}

case IS_STEP(AnnotationNot): {
EVALUATE_BEGIN_NO_PRECONDITION(logical, AnnotationNot);
// Ignore annotations produced inside "not"
context.mask();
for (const auto &child : logical.children) {
if (!evaluate_step(child, callback, context)) {
result = true;
break;
}
}

EVALUATE_END(logical, AnnotationNot);
}

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

EVALUATE_END(logical, LogicalNot);
EVALUATE_END(loop, LoopItemsUnevaluated);
}

case IS_STEP(LoopPropertiesMatch): {
Expand Down
44 changes: 18 additions & 26 deletions src/evaluator/include/sourcemeta/blaze/evaluator_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ struct AnnotationWhenArraySizeEqual;
struct AnnotationWhenArraySizeGreater;
struct AnnotationToParent;
struct AnnotationBasenameToParent;
struct AnnotationLoopPropertiesUnevaluated;
struct AnnotationLoopItemsUnevaluated;
struct AnnotationNot;
struct LogicalNot;
struct LogicalOr;
struct LogicalAnd;
Expand All @@ -60,6 +57,8 @@ struct LogicalWhenType;
struct LogicalWhenDefines;
struct LogicalWhenArraySizeGreater;
struct LogicalWhenArraySizeEqual;
struct LoopPropertiesUnevaluated;
struct LoopItemsUnevaluated;
struct LoopPropertiesMatch;
struct LoopProperties;
struct LoopPropertiesRegex;
Expand Down Expand Up @@ -90,11 +89,10 @@ using Template = std::vector<std::variant<
AssertionUnique, AssertionDivisible, AssertionStringType,
AssertionPropertyType, AssertionPropertyTypeStrict, AnnotationEmit,
AnnotationWhenArraySizeEqual, AnnotationWhenArraySizeGreater,
AnnotationToParent, AnnotationBasenameToParent,
AnnotationLoopPropertiesUnevaluated, AnnotationLoopItemsUnevaluated,
AnnotationNot, LogicalNot, LogicalOr, LogicalAnd, LogicalXor,
LogicalCondition, LogicalWhenType, LogicalWhenDefines,
LogicalWhenArraySizeGreater, LogicalWhenArraySizeEqual, LoopPropertiesMatch,
AnnotationToParent, AnnotationBasenameToParent, LogicalNot, LogicalOr,
LogicalAnd, LogicalXor, LogicalCondition, LogicalWhenType,
LogicalWhenDefines, LogicalWhenArraySizeGreater, LogicalWhenArraySizeEqual,
LoopPropertiesUnevaluated, LoopItemsUnevaluated, LoopPropertiesMatch,
LoopProperties, LoopPropertiesRegex, LoopPropertiesExcept,
LoopPropertiesType, LoopPropertiesTypeStrict, LoopKeys, LoopItems,
LoopContains, ControlLabel, ControlMark, ControlEvaluate, ControlJump,
Expand Down Expand Up @@ -138,9 +136,6 @@ enum class TemplateIndex : std::uint8_t {
AnnotationWhenArraySizeGreater,
AnnotationToParent,
AnnotationBasenameToParent,
AnnotationLoopPropertiesUnevaluated,
AnnotationLoopItemsUnevaluated,
AnnotationNot,
LogicalNot,
LogicalOr,
LogicalAnd,
Expand All @@ -150,6 +145,8 @@ enum class TemplateIndex : std::uint8_t {
LogicalWhenDefines,
LogicalWhenArraySizeGreater,
LogicalWhenArraySizeEqual,
LoopPropertiesUnevaluated,
LoopItemsUnevaluated,
LoopPropertiesMatch,
LoopProperties,
LoopPropertiesRegex,
Expand Down Expand Up @@ -365,23 +362,9 @@ DEFINE_STEP_WITH_VALUE(Annotation, ToParent, ValueJSON)
/// annotation to the parent
DEFINE_STEP_WITH_VALUE(Annotation, BasenameToParent, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler step that loops over object properties that
/// were not previously evaluated
DEFINE_STEP_APPLICATOR(Annotation, LoopPropertiesUnevaluated, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler step that loops over unevaluated array items
DEFINE_STEP_APPLICATOR(Annotation, LoopItemsUnevaluated, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents an annotation-aware compiler logical step that represents
/// a negation
DEFINE_STEP_APPLICATOR(Annotation, Not, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler logical step that represents a negation
DEFINE_STEP_APPLICATOR(Logical, Not, ValueNone)
DEFINE_STEP_APPLICATOR(Logical, Not, ValueBoolean)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler logical step that represents a disjunction
Expand Down Expand Up @@ -420,6 +403,15 @@ DEFINE_STEP_APPLICATOR(Logical, WhenArraySizeGreater, ValueUnsignedInteger)
/// the array instance size is equal to the given number
DEFINE_STEP_APPLICATOR(Logical, WhenArraySizeEqual, ValueUnsignedInteger)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler step that loops over object properties that
/// were not previously evaluated
DEFINE_STEP_APPLICATOR(Loop, PropertiesUnevaluated, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler step that loops over unevaluated array items
DEFINE_STEP_APPLICATOR(Loop, ItemsUnevaluated, ValueNone)

/// @ingroup evaluator_instructions
/// @brief Represents a compiler step that matches steps to object properties
DEFINE_STEP_APPLICATOR(Loop, PropertiesMatch, ValueNamedIndexes)
Expand Down
Loading