|
1 | | -/* auto-generated on 2026-04-10 20:35:19 +0300. Do not edit! */ |
| 1 | +/* auto-generated on 2026-04-12 17:45:05 +0300. Do not edit! */ |
2 | 2 | /* begin file src/ata.cpp */ |
3 | 3 | #include "ata.h" |
4 | 4 |
|
@@ -438,6 +438,10 @@ struct compiled_schema { |
438 | 438 | std::unordered_map<std::string, schema_node_ptr>> resource_dynamic_anchors; |
439 | 439 | bool has_dynamic_refs = false; |
440 | 440 | std::string current_resource_id; // compile-time only |
| 441 | + |
| 442 | + // compile-time warnings (misplaced keywords, etc.) |
| 443 | + std::vector<schema_warning> warnings; |
| 444 | + std::string compile_path; // current JSON pointer during compilation |
441 | 445 | }; |
442 | 446 |
|
443 | 447 | // Thread-local persistent parsers — reused across all validate calls on the |
@@ -828,6 +832,61 @@ static schema_node_ptr compile_node(dom::element el, |
828 | 832 | } |
829 | 833 | } |
830 | 834 |
|
| 835 | + // Warn about keywords used at the wrong type level. |
| 836 | + // Only check when an explicit "type" is declared (type_mask != 0). |
| 837 | + if (node->type_mask != 0) { |
| 838 | + const uint8_t array_bit = json_type_bit(json_type::array); |
| 839 | + const uint8_t string_bit = json_type_bit(json_type::string); |
| 840 | + const uint8_t number_bits = json_type_bit(json_type::number) | |
| 841 | + json_type_bit(json_type::integer); |
| 842 | + const uint8_t object_bit = json_type_bit(json_type::object); |
| 843 | + |
| 844 | + auto warn = [&](const char* keyword, const char* expected_type) { |
| 845 | + ctx.warnings.push_back({ |
| 846 | + ctx.compile_path, |
| 847 | + std::string(keyword) + " has no effect on type \"" + |
| 848 | + (node->type_mask & json_type_bit(json_type::string) ? "string" : |
| 849 | + node->type_mask & json_type_bit(json_type::boolean) ? "boolean" : |
| 850 | + node->type_mask & json_type_bit(json_type::number) ? "number" : |
| 851 | + node->type_mask & object_bit ? "object" : |
| 852 | + node->type_mask & array_bit ? "array" : "unknown") + |
| 853 | + "\", only applies to " + expected_type |
| 854 | + }); |
| 855 | + }; |
| 856 | + |
| 857 | + // Array keywords on non-array type |
| 858 | + if (!(node->type_mask & array_bit)) { |
| 859 | + if (node->min_items.has_value()) warn("minItems", "array"); |
| 860 | + if (node->max_items.has_value()) warn("maxItems", "array"); |
| 861 | + if (node->unique_items) warn("uniqueItems", "array"); |
| 862 | + if (!node->prefix_items.empty()) warn("prefixItems", "array"); |
| 863 | + if (node->items_schema) warn("items", "array"); |
| 864 | + if (node->contains_schema) warn("contains", "array"); |
| 865 | + } |
| 866 | + |
| 867 | + // String keywords on non-string type |
| 868 | + if (!(node->type_mask & string_bit)) { |
| 869 | + if (node->min_length.has_value()) warn("minLength", "string"); |
| 870 | + if (node->max_length.has_value()) warn("maxLength", "string"); |
| 871 | + if (node->pattern.has_value()) warn("pattern", "string"); |
| 872 | + } |
| 873 | + |
| 874 | + // Numeric keywords on non-numeric type |
| 875 | + if (!(node->type_mask & number_bits)) { |
| 876 | + if (node->minimum.has_value()) warn("minimum", "number"); |
| 877 | + if (node->maximum.has_value()) warn("maximum", "number"); |
| 878 | + if (node->exclusive_minimum.has_value()) warn("exclusiveMinimum", "number"); |
| 879 | + if (node->exclusive_maximum.has_value()) warn("exclusiveMaximum", "number"); |
| 880 | + if (node->multiple_of.has_value()) warn("multipleOf", "number"); |
| 881 | + } |
| 882 | + |
| 883 | + // Object keywords on non-object type |
| 884 | + if (!(node->type_mask & object_bit)) { |
| 885 | + if (!node->properties.empty()) warn("properties", "object"); |
| 886 | + if (!node->required.empty()) warn("required", "object"); |
| 887 | + } |
| 888 | + } |
| 889 | + |
831 | 890 | ctx.current_resource_id = prev_resource; |
832 | 891 | return node; |
833 | 892 | } |
@@ -2622,6 +2681,7 @@ schema_ref compile(std::string_view schema_json) { |
2622 | 2681 |
|
2623 | 2682 | schema_ref ref; |
2624 | 2683 | ref.impl = ctx; |
| 2684 | + ref.warnings = std::move(ctx->warnings); |
2625 | 2685 | return ref; |
2626 | 2686 | } |
2627 | 2687 |
|
|
0 commit comments