Skip to content

Commit

Permalink
Introduce the idea of syntax sugar lint rules
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Sep 10, 2024
1 parent a7fd9aa commit 69d2fa2
Show file tree
Hide file tree
Showing 14 changed files with 804 additions and 295 deletions.
3 changes: 3 additions & 0 deletions src/linter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ noa_library(NAMESPACE sourcemeta PROJECT alterschema NAME linter
simplify/minimum_real_for_integer.h
simplify/single_type_array.h

# Desugar
desugar/type_boolean_as_enum.h

# Redundant
redundant/additional_properties_default.h
redundant/content_media_type_without_encoding.h
Expand Down
35 changes: 35 additions & 0 deletions src/linter/desugar/type_boolean_as_enum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class TypeBooleanAsEnum final : public Rule {
public:
TypeBooleanAsEnum()
: Rule{"type_boolean_as_enum",
"Setting `type` to `boolean` is syntax sugar for an enumeration "
"of two values: `false` and `true`"} {};

[[nodiscard]] auto
condition(const sourcemeta::jsontoolkit::JSON &schema, const std::string &,
const std::set<std::string> &vocabularies,
const sourcemeta::jsontoolkit::Pointer &) const -> bool override {
return contains_any(
vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/validation",
"https://json-schema.org/draft/2019-09/vocab/validation",
"http://json-schema.org/draft-07/schema#",
"http://json-schema.org/draft-06/schema#",
"http://json-schema.org/draft-04/schema#",
"http://json-schema.org/draft-03/schema#",
"http://json-schema.org/draft-02/hyper-schema#",
"http://json-schema.org/draft-01/hyper-schema#"}) &&
schema.is_object() && schema.defines("type") &&
schema.at("type").is_string() &&
schema.at("type").to_string() == "boolean" &&
!schema.defines("enum") && !schema.defines("const");
}

auto transform(Transformer &transformer) const -> void override {
auto choices = sourcemeta::jsontoolkit::JSON::make_array();
choices.push_back(sourcemeta::jsontoolkit::JSON{false});
choices.push_back(sourcemeta::jsontoolkit::JSON{true});
transformer.assign("enum", choices);
transformer.erase("type");
}
};
3 changes: 3 additions & 0 deletions src/linter/include/sourcemeta/alterschema/linter.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ enum class LinterCategory {
/// Rules that simplify the given schema
Simplify,

/// Rules that simplify keywords that are syntax sugar to other keywords
Desugar,

/// Rules that remove schema redundancies
Redundant
};
Expand Down
5 changes: 5 additions & 0 deletions src/linter/linter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ template <typename T> auto every_item_is_boolean(const T &container) -> bool {
#include "simplify/maximum_real_for_integer.h"
#include "simplify/minimum_real_for_integer.h"
#include "simplify/single_type_array.h"
// Desugar
#include "desugar/type_boolean_as_enum.h"
// Redundant
#include "redundant/additional_properties_default.h"
#include "redundant/content_media_type_without_encoding.h"
Expand Down Expand Up @@ -176,6 +178,9 @@ auto add(Bundle &bundle, const LinterCategory category) -> void {
bundle.add<MinimumRealForInteger>();
bundle.add<SingleTypeArray>();
break;
case LinterCategory::Desugar:
bundle.add<TypeBooleanAsEnum>();
break;
case LinterCategory::Redundant:
bundle.add<AdditionalPropertiesDefault>();
bundle.add<ContentMediaTypeWithoutEncoding>();
Expand Down
Loading

0 comments on commit 69d2fa2

Please sign in to comment.