Skip to content

Commit 9f2e4b1

Browse files
committed
Pick keywords for dialect from respective json file
1 parent 90dbcd7 commit 9f2e4b1

File tree

9 files changed

+394
-64
lines changed

9 files changed

+394
-64
lines changed

jsonschema_lexer/_lexer.py

Lines changed: 32 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
Contains the main functionality of the JSONSchemaLexer.
33
"""
44

5+
from importlib.resources import files
6+
from pathlib import Path
57
from typing import Any, ClassVar
8+
import json
69

710
from pygments.lexers.data import ( # type: ignore[reportMissingTypeStubs]
811
JsonLexer,
912
)
1013
from pygments.token import Token
11-
import jsonschema
1214

1315

1416
class JSONSchemaLexer(JsonLexer):
@@ -33,11 +35,13 @@ class JSONSchemaLexer(JsonLexer):
3335
'"boolean"',
3436
'"null"',
3537
]
36-
38+
keywords: ClassVar[dict[str | None, list[str]]] = {}
39+
identifier: ClassVar[dict[str | None, str]] = {}
3740
default_dialect = None
3841

3942
def __init__(self, default_dialect: str | None = None):
4043
super().__init__() # type: ignore[reportUnknownMemberType]
44+
self._populate_keywords_and_identifiers()
4145
if default_dialect and default_dialect[0] != '"':
4246
default_dialect = '"' + default_dialect
4347

@@ -46,61 +50,25 @@ def __init__(self, default_dialect: str | None = None):
4650

4751
self.default_dialect = default_dialect
4852

49-
def get_dialect_keywords(self, dialect_url: str | None) -> list[str]:
50-
match dialect_url:
51-
case '"https://json-schema.org/draft/2020-12/schema"':
52-
return list(
53-
jsonschema.Draft202012Validator.VALIDATORS.keys(),
54-
) + [
55-
"$schema",
56-
"$id",
57-
]
58-
case '"https://json-schema.org/draft/2019-09/schema"':
59-
return list(
60-
jsonschema.Draft201909Validator.VALIDATORS.keys(),
61-
) + [
62-
"$schema",
63-
"$id",
64-
]
65-
case '"http://json-schema.org/draft-07/schema#"':
66-
return list(jsonschema.Draft7Validator.VALIDATORS.keys()) + [
67-
"$schema",
68-
"$id",
69-
]
70-
case '"http://json-schema.org/draft-06/schema#"':
71-
return list(jsonschema.Draft6Validator.VALIDATORS.keys()) + [
72-
"$schema",
73-
"$id",
74-
]
75-
case '"http://json-schema.org/draft-04/schema#"':
76-
return list(jsonschema.Draft4Validator.VALIDATORS.keys()) + [
77-
"$schema",
78-
"id",
79-
]
80-
case '"http://json-schema.org/draft-03/schema#"':
81-
return list(jsonschema.Draft3Validator.VALIDATORS.keys()) + [
82-
"$schema",
83-
"id",
84-
]
85-
case _:
86-
return []
87-
88-
def get_dialect_identifier(self, dialect: str | None):
89-
match dialect:
90-
case '"https://json-schema.org/draft/2020-12/schema"':
91-
return '"$id"'
92-
case '"https://json-schema.org/draft/2019-09/schema"':
93-
return '"$id"'
94-
case '"http://json-schema.org/draft-07/schema#"':
95-
return '"$id"'
96-
case '"http://json-schema.org/draft-06/schema#"':
97-
return '"$id"'
98-
case '"http://json-schema.org/draft-04/schema#"':
99-
return '"id"'
100-
case '"https://json-schema.org/draft-03/schema"':
101-
return '"id"'
102-
case _:
103-
return None
53+
def _populate_keywords_and_identifiers(self):
54+
dialect_files = files("jsonschema_lexer") / "data" / "keywords"
55+
if not dialect_files.is_dir():
56+
dialect_files = Path(__file__).parent.parent / "data" / "keywords"
57+
for dialect_file in dialect_files.iterdir():
58+
with dialect_file.open() as file:
59+
json_content = json.load(file)
60+
dialect_name = self._make_string_double_quoted(
61+
json_content["dialect"],
62+
)
63+
self.keywords[dialect_name] = json_content["keywords"]
64+
self.identifier[dialect_name] = (
65+
self._make_string_double_quoted(
66+
json_content["identifier"],
67+
)
68+
)
69+
70+
def _make_string_double_quoted(self, string: str):
71+
return '"' + string + '"'
10472

10573
def _find_rightmost_token_index(
10674
self,
@@ -140,11 +108,9 @@ def _get_nearest_valid_dialect(
140108
tokens,
141109
nearest_schema_index,
142110
)
143-
identifier = self.get_dialect_identifier(dialect)
144-
is_dialect_valid = (
145-
True
146-
if identifier or syntax_stack[nearest_schema_index][0] == 0
147-
else False
111+
identifier = self.identifier.get(dialect, None)
112+
is_dialect_valid = bool(
113+
identifier or syntax_stack[nearest_schema_index][0] == 0,
148114
)
149115
nearest_identifier_index = self._find_rightmost_token_index(
150116
syntax_stack[: index + 1],
@@ -209,12 +175,14 @@ def map_tokens_by_schema(self, tokens: list[tuple[int, Any, str]]):
209175
dialect = self._get_nearest_valid_dialect(tokens, syntax_stack)
210176
yield self._parse_token_tuple(
211177
(start, token, value),
212-
self.get_dialect_keywords(dialect),
178+
self.keywords.get(dialect, []),
213179
)
214180

215181
def get_tokens_unprocessed(self, text: str): # type: ignore[reportUnknownParameterType]
216182
"""
217183
Add token classes to it according to JSON Schema.
218184
"""
219-
json_tokens: list[tuple[int, Any, str]] = list(super().get_tokens_unprocessed(text)) # type: ignore[reportUnknownParameterType]
185+
json_tokens: list[tuple[int, Any, str]] = list(
186+
super().get_tokens_unprocessed(text),
187+
) # type: ignore[reportUnknownParameterType]
220188
yield from self.map_tokens_by_schema(json_tokens)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-01/schema#",
3+
"identifier": "id",
4+
"keywords": [
5+
"type",
6+
"properties",
7+
"items",
8+
"optional",
9+
"additionalProperties",
10+
"requires",
11+
"minimum",
12+
"maximum",
13+
"minimumCanEqual",
14+
"maximumCanEqual",
15+
"minItems",
16+
"maxItems",
17+
"pattern",
18+
"minLength",
19+
"maxLength",
20+
"enum",
21+
"title",
22+
"description",
23+
"format",
24+
"contentEncoding",
25+
"default",
26+
"maxDecimal",
27+
"disallow",
28+
"extends",
29+
"$schema",
30+
"id"
31+
]
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-02/schema#",
3+
"identifier": "id",
4+
"keywords": [
5+
"type",
6+
"properties",
7+
"items",
8+
"optional",
9+
"additionalProperties",
10+
"requires",
11+
"minimum",
12+
"maximum",
13+
"minimumCanEqual",
14+
"maximumCanEqual",
15+
"minItems",
16+
"maxItems",
17+
"uniqueItems",
18+
"pattern",
19+
"minLength",
20+
"maxLength",
21+
"enum",
22+
"title",
23+
"description",
24+
"format",
25+
"contentEncoding",
26+
"default",
27+
"divisibleBy",
28+
"disallow",
29+
"extends",
30+
"$schema",
31+
"id"
32+
]
33+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-03/schema#",
3+
"identifier": "id",
4+
"keywords": [
5+
"type",
6+
"properties",
7+
"patternProperties",
8+
"additionalProperties",
9+
"items",
10+
"additionalItems",
11+
"required",
12+
"dependencies",
13+
"minimum",
14+
"maximum",
15+
"exclusiveMinimum",
16+
"exclusiveMaximum",
17+
"minItems",
18+
"maxItems",
19+
"uniqueItems",
20+
"pattern",
21+
"minLength",
22+
"maxLength",
23+
"enum",
24+
"default",
25+
"title",
26+
"description",
27+
"format",
28+
"divisibleBy",
29+
"disallow",
30+
"extends",
31+
"id",
32+
"$ref",
33+
"$schema"
34+
]
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-04/schema#",
3+
"identifier": "id",
4+
"keywords": [
5+
"id",
6+
"$schema",
7+
"title",
8+
"description",
9+
"default",
10+
"multipleOf",
11+
"maximum",
12+
"exclusiveMaximum",
13+
"minimum",
14+
"exclusiveMinimum",
15+
"maxLength",
16+
"minLength",
17+
"pattern",
18+
"additionalItems",
19+
"items",
20+
"maxItems",
21+
"minItems",
22+
"uniqueItems",
23+
"maxProperties",
24+
"minProperties",
25+
"required",
26+
"additionalProperties",
27+
"definitions",
28+
"properties",
29+
"patternProperties",
30+
"dependencies",
31+
"enum",
32+
"type",
33+
"format",
34+
"allOf",
35+
"anyOf",
36+
"oneOf",
37+
"not"
38+
]
39+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-06/schema#",
3+
"identifier": "$id",
4+
"keywords": [
5+
"$id",
6+
"$schema",
7+
"$ref",
8+
"title",
9+
"description",
10+
"default",
11+
"examples",
12+
"multipleOf",
13+
"maximum",
14+
"exclusiveMaximum",
15+
"minimum",
16+
"exclusiveMinimum",
17+
"maxLength",
18+
"minLength",
19+
"pattern",
20+
"additionalItems",
21+
"items",
22+
"maxItems",
23+
"minItems",
24+
"uniqueItems",
25+
"contains",
26+
"maxProperties",
27+
"minProperties",
28+
"required",
29+
"additionalProperties",
30+
"definitions",
31+
"properties",
32+
"patternProperties",
33+
"dependencies",
34+
"propertyNames",
35+
"const",
36+
"enum",
37+
"type",
38+
"format",
39+
"allOf",
40+
"anyOf",
41+
"oneOf",
42+
"not"
43+
]
44+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"dialect": "http://json-schema.org/draft-07/schema#",
3+
"identifier": "$id",
4+
"keywords": [
5+
"$id",
6+
"$schema",
7+
"$ref",
8+
"$comment",
9+
"title",
10+
"description",
11+
"default",
12+
"readOnly",
13+
"writeOnly",
14+
"examples",
15+
"multipleOf",
16+
"maximum",
17+
"exclusiveMaximum",
18+
"minimum",
19+
"exclusiveMinimum",
20+
"maxLength",
21+
"minLength",
22+
"pattern",
23+
"additionalItems",
24+
"items",
25+
"maxItems",
26+
"minItems",
27+
"uniqueItems",
28+
"contains",
29+
"maxProperties",
30+
"minProperties",
31+
"required",
32+
"additionalProperties",
33+
"definitions",
34+
"properties",
35+
"patternProperties",
36+
"dependencies",
37+
"propertyNames",
38+
"const",
39+
"enum",
40+
"type",
41+
"format",
42+
"contentMediaType",
43+
"contentEncoding",
44+
"if",
45+
"then",
46+
"else",
47+
"allOf",
48+
"anyOf",
49+
"oneOf",
50+
"not"
51+
]
52+
}

0 commit comments

Comments
 (0)