diff --git a/src/evaluator/evaluator.cc b/src/evaluator/evaluator.cc index 274c84bf..3a75e3ed 100644 --- a/src/evaluator/evaluator.cc +++ b/src/evaluator/evaluator.cc @@ -637,21 +637,6 @@ auto evaluate_step( EVALUATE_END(logical, SchemaCompilerLogicalCondition); } - case IS_STEP(SchemaCompilerLogicalNot): { - EVALUATE_BEGIN_NO_PRECONDITION(logical, SchemaCompilerLogicalNot); - // Ignore annotations produced inside "not" - context.mask(); - result = false; - for (const auto &child : logical.children) { - if (!evaluate_step(child, callback, context)) { - result = true; - break; - } - } - - EVALUATE_END(logical, SchemaCompilerLogicalNot); - } - case IS_STEP(SchemaCompilerControlLabel): { EVALUATE_BEGIN_NO_PRECONDITION(control, SchemaCompilerControlLabel); context.mark(control.value, control.children); @@ -847,6 +832,20 @@ auto evaluate_step( EVALUATE_END(loop, SchemaCompilerAnnotationLoopItemsUnevaluated); } + case IS_STEP(SchemaCompilerAnnotationNot): { + EVALUATE_BEGIN_NO_PRECONDITION(logical, SchemaCompilerAnnotationNot); + // 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, SchemaCompilerAnnotationNot); + } + case IS_STEP(SchemaCompilerLoopPropertiesMatch): { EVALUATE_BEGIN(loop, SchemaCompilerLoopPropertiesMatch, target.is_object()); diff --git a/src/evaluator/include/sourcemeta/jsontoolkit/evaluator_template.h b/src/evaluator/include/sourcemeta/jsontoolkit/evaluator_template.h index e3c13375..f5e28f5c 100644 --- a/src/evaluator/include/sourcemeta/jsontoolkit/evaluator_template.h +++ b/src/evaluator/include/sourcemeta/jsontoolkit/evaluator_template.h @@ -51,11 +51,11 @@ struct SchemaCompilerAnnotationBasenameToParent; struct SchemaCompilerAnnotationLoopPropertiesUnevaluated; struct SchemaCompilerAnnotationLoopItemsUnmarked; struct SchemaCompilerAnnotationLoopItemsUnevaluated; +struct SchemaCompilerAnnotationNot; struct SchemaCompilerLogicalOr; struct SchemaCompilerLogicalAnd; struct SchemaCompilerLogicalXor; struct SchemaCompilerLogicalCondition; -struct SchemaCompilerLogicalNot; struct SchemaCompilerLogicalWhenType; struct SchemaCompilerLogicalWhenDefines; struct SchemaCompilerLogicalWhenArraySizeGreater; @@ -103,11 +103,10 @@ using SchemaCompilerTemplate = std::vector std::string { + auto operator()(const SchemaCompilerAnnotationNot &) const -> std::string { std::ostringstream message; message << "The " << to_string(this->target.type()) diff --git a/src/jsonschema/compile_json.cc b/src/jsonschema/compile_json.cc index ff869330..5b93d986 100644 --- a/src/jsonschema/compile_json.cc +++ b/src/jsonschema/compile_json.cc @@ -269,11 +269,11 @@ struct StepVisitor { SchemaCompilerAnnotationLoopItemsUnmarked) HANDLE_STEP("annotation", "loop-items-unevaluated", SchemaCompilerAnnotationLoopItemsUnevaluated) + HANDLE_STEP("annotation", "not", SchemaCompilerAnnotationNot) HANDLE_STEP("logical", "or", SchemaCompilerLogicalOr) HANDLE_STEP("logical", "and", SchemaCompilerLogicalAnd) HANDLE_STEP("logical", "xor", SchemaCompilerLogicalXor) HANDLE_STEP("logical", "condition", SchemaCompilerLogicalCondition) - HANDLE_STEP("logical", "not", SchemaCompilerLogicalNot) HANDLE_STEP("logical", "when-type", SchemaCompilerLogicalWhenType) HANDLE_STEP("logical", "when-defines", SchemaCompilerLogicalWhenDefines) HANDLE_STEP("logical", "when-array-size-greater", diff --git a/src/jsonschema/default_compiler_draft4.h b/src/jsonschema/default_compiler_draft4.h index dc30f55e..1b58a7f4 100644 --- a/src/jsonschema/default_compiler_draft4.h +++ b/src/jsonschema/default_compiler_draft4.h @@ -824,7 +824,8 @@ auto compiler_draft4_applicator_not( const SchemaCompilerSchemaContext &schema_context, const SchemaCompilerDynamicContext &dynamic_context) -> SchemaCompilerTemplate { - return {make( + // TODO: Don't mask annotations if annotations are not needed + return {make( true, context, schema_context, dynamic_context, SchemaCompilerValueNone{}, compile(context, schema_context, relative_dynamic_context, empty_pointer, empty_pointer))}; diff --git a/test/evaluator/evaluator_draft4_test.cc b/test/evaluator/evaluator_draft4_test.cc index 6362e834..25af57bc 100644 --- a/test/evaluator/evaluator_draft4_test.cc +++ b/test/evaluator/evaluator_draft4_test.cc @@ -2207,12 +2207,12 @@ TEST(JSONSchema_evaluator_draft4, not_1) { const sourcemeta::jsontoolkit::JSON instance{5}; EVALUATE_WITH_TRACE_FAST_SUCCESS(schema, instance, 2); - EVALUATE_TRACE_PRE(0, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_PRE(0, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_PRE(1, AssertionTypeStrict, "/not/type", "#/not/type", ""); EVALUATE_TRACE_POST_FAILURE(0, AssertionTypeStrict, "/not/type", "#/not/type", ""); - EVALUATE_TRACE_POST_SUCCESS(1, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_POST_SUCCESS(1, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_POST_DESCRIBE( instance, 0, @@ -2234,12 +2234,12 @@ TEST(JSONSchema_evaluator_draft4, not_2) { const sourcemeta::jsontoolkit::JSON instance{"foo"}; EVALUATE_WITH_TRACE_FAST_FAILURE(schema, instance, 2); - EVALUATE_TRACE_PRE(0, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_PRE(0, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_PRE(1, AssertionTypeStrict, "/not/type", "#/not/type", ""); EVALUATE_TRACE_POST_SUCCESS(0, AssertionTypeStrict, "/not/type", "#/not/type", ""); - EVALUATE_TRACE_POST_FAILURE(1, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_POST_FAILURE(1, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_POST_DESCRIBE(instance, 0, "The value was expected to be of type string"); @@ -2269,7 +2269,7 @@ TEST(JSONSchema_evaluator_draft4, not_3) { EVALUATE_WITH_TRACE_FAST_SUCCESS(schema, instance, 4); - EVALUATE_TRACE_PRE(0, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_PRE(0, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_PRE(1, AssertionPropertyTypeStrict, "/not/properties/foo/type", "#/not/properties/foo/type", "/foo"); EVALUATE_TRACE_PRE(2, LoopPropertiesExcept, "/not/additionalProperties", @@ -2286,7 +2286,7 @@ TEST(JSONSchema_evaluator_draft4, not_3) { EVALUATE_TRACE_POST_FAILURE(2, LoopPropertiesExcept, "/not/additionalProperties", "#/not/additionalProperties", ""); - EVALUATE_TRACE_POST_SUCCESS(3, LogicalNot, "/not", "#/not", ""); + EVALUATE_TRACE_POST_SUCCESS(3, AnnotationNot, "/not", "#/not", ""); EVALUATE_TRACE_POST_DESCRIBE(instance, 0, "The value was expected to be of type boolean");