Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 2 additions & 0 deletions src/extension/alterschema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME alterschema
linter/modern_official_dialect_with_empty_fragment.h
linter/then_empty.h
linter/else_empty.h
linter/else_false.h
linter/then_false.h
linter/then_without_if.h
linter/property_names_type_default.h
linter/property_names_default.h)
Expand Down
4 changes: 4 additions & 0 deletions src/extension/alterschema/alterschema.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ contains_any(const Vocabularies &container,
#include "linter/duplicate_enum_values.h"
#include "linter/duplicate_required_values.h"
#include "linter/else_empty.h"
#include "linter/else_false.h"
#include "linter/else_without_if.h"
#include "linter/enum_to_const.h"
#include "linter/enum_with_type.h"
Expand All @@ -73,6 +74,7 @@ contains_any(const Vocabularies &container,
#include "linter/property_names_type_default.h"
#include "linter/single_type_array.h"
#include "linter/then_empty.h"
#include "linter/then_false.h"
#include "linter/then_without_if.h"
#include "linter/unevaluated_items_default.h"
#include "linter/unevaluated_properties_default.h"
Expand Down Expand Up @@ -103,7 +105,9 @@ auto add(SchemaTransformer &bundle, const AlterSchemaMode mode)
bundle.add<MaxContainsWithoutContains>();
bundle.add<MinContainsWithoutContains>();
bundle.add<ThenEmpty>();
bundle.add<ThenFalse>();
bundle.add<ElseEmpty>();
bundle.add<ElseFalse>();
bundle.add<ThenWithoutIf>();
bundle.add<DependenciesPropertyTautology>();
bundle.add<DependentRequiredTautology>();
Expand Down
38 changes: 38 additions & 0 deletions src/extension/alterschema/linter/else_false.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class ElseFalse final : public SchemaTransformRule {
public:
ElseFalse()
: SchemaTransformRule{"else_false",
"`if: S, else: false` collapses to just `S`"} {};

[[nodiscard]] auto
condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,
const SchemaFrame &, const SchemaFrame::Location &,
const SchemaWalker &, const SchemaResolver &) const
-> SchemaTransformRule::Result override {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think at this point you can simplify the condition by making it a one liner on a return. That will make it easier to read, as we won't be reading negated conditionals

return contains_any(
vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/applicator",
"https://json-schema.org/draft/2019-09/vocab/applicator",
"http://json-schema.org/draft-07/schema#"}) &&
schema.is_object() && schema.defines("if") &&
schema.defines("else") && schema.at("else").is_boolean() &&
!schema.at("else").to_boolean();
}

auto transform(JSON &schema) const -> void override {
const auto if_schema = schema.at("if");
schema.erase("if");
schema.erase("else");
if (if_schema.is_object()) {
for (const auto &entry : if_schema.as_object()) {
if (!schema.defines(entry.first)) {
schema.assign(entry.first, entry.second);
}
}
} else if (if_schema.is_boolean()) {
if (if_schema.to_boolean()) {
} else {
}
}
}
};
29 changes: 29 additions & 0 deletions src/extension/alterschema/linter/then_false.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class ThenFalse final : public SchemaTransformRule {
public:
ThenFalse()
: SchemaTransformRule{
"then_false",
"`if: S, then: false` is logically equivalent to `not: S`"} {};

[[nodiscard]] auto
condition(const JSON &schema, const JSON &, const Vocabularies &vocabularies,
const SchemaFrame &, const SchemaFrame::Location &,
const SchemaWalker &, const SchemaResolver &) const
-> SchemaTransformRule::Result override {
return contains_any(
vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/applicator",
"https://json-schema.org/draft/2019-09/vocab/applicator",
"http://json-schema.org/draft-07/schema#"}) &&
schema.is_object() && schema.defines("if") &&
schema.defines("then") && schema.at("then").is_boolean() &&
!schema.at("then").to_boolean();
}

auto transform(JSON &schema) const -> void override {
const auto if_schema = schema.at("if");
schema.erase("if");
schema.erase("then");
schema.assign("not", if_schema);
}
};
56 changes: 56 additions & 0 deletions test/alterschema/alterschema_lint_2019_09_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2294,3 +2294,59 @@ TEST(AlterSchema_lint_2019_09, property_names_default_1) {

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, then_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"not": {
"properties": {
"flag": {
"const": true
}
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2019_09, else_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"else": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2019-09/schema",
"properties": {
"flag": {
"const": true
}
}
})JSON");

EXPECT_EQ(document, expected);
}
56 changes: 56 additions & 0 deletions test/alterschema/alterschema_lint_2020_12_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2528,3 +2528,59 @@ TEST(AlterSchema_lint_2020_12, property_names_default_1) {

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2020_12, then_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"not": {
"properties": {
"flag": {
"const": true
}
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_2020_12, else_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"else": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"flag": {
"const": true
}
}
})JSON");

EXPECT_EQ(document, expected);
}
56 changes: 56 additions & 0 deletions test/alterschema/alterschema_lint_draft7_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1718,3 +1718,59 @@ TEST(AlterSchema_lint_draft7, property_names_default_1) {

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_draft7, then_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "http://json-schema.org/draft-07/schema#",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"then": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "http://json-schema.org/draft-07/schema#",
"not": {
"properties": {
"flag": {
"const": true
}
}
}
})JSON");

EXPECT_EQ(document, expected);
}

TEST(AlterSchema_lint_draft7, else_false_1) {
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
"$schema": "http://json-schema.org/draft-07/schema#",
"if": {
"properties": {
"flag": {
"const": true
}
}
},
"else": false
})JSON");

LINT_AND_FIX_FOR_READABILITY(document);

const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"flag": {
"const": true
}
}
})JSON");

EXPECT_EQ(document, expected);
}
Loading