11import re
22import sys
33import json
4+ from typing import Any , Callable , Dict , List , TypeVar , Union , cast
45
6+ Node = TypeVar ('Node' , bound = 'BaseNode' )
7+ ToJsonFn = Callable [[Dict [str , Any ]], Any ]
58
6- def to_json (value , fn = None ):
9+
10+ def to_json (value : Any , fn : Union [ToJsonFn , None ] = None ) -> Any :
711 if isinstance (value , BaseNode ):
812 return value .to_json (fn )
913 if isinstance (value , list ):
@@ -14,7 +18,7 @@ def to_json(value, fn=None):
1418 return value
1519
1620
17- def from_json (value ) :
21+ def from_json (value : Any ) -> Any :
1822 if isinstance (value , dict ):
1923 cls = getattr (sys .modules [__name__ ], value ['type' ])
2024 args = {
@@ -29,7 +33,7 @@ def from_json(value):
2933 return value
3034
3135
32- def scalars_equal (node1 , node2 , ignored_fields ) :
36+ def scalars_equal (node1 : Any , node2 : Any , ignored_fields : List [ str ]) -> bool :
3337 """Compare two nodes which are not lists."""
3438
3539 if type (node1 ) != type (node2 ):
@@ -38,7 +42,7 @@ def scalars_equal(node1, node2, ignored_fields):
3842 if isinstance (node1 , BaseNode ):
3943 return node1 .equals (node2 , ignored_fields )
4044
41- return node1 == node2
45+ return cast ( bool , node1 == node2 )
4246
4347
4448class BaseNode :
@@ -48,9 +52,9 @@ class BaseNode:
4852 Annotation. Implements __str__, to_json and traverse.
4953 """
5054
51- def clone (self ) :
55+ def clone (self : Node ) -> Node :
5256 """Create a deep clone of the current node."""
53- def visit (value ) :
57+ def visit (value : Any ) -> Any :
5458 """Clone node and its descendants."""
5559 if isinstance (value , BaseNode ):
5660 return value .clone ()
@@ -65,7 +69,7 @@ def visit(value):
6569 ** {name : visit (value ) for name , value in vars (self ).items ()}
6670 )
6771
68- def equals (self , other , ignored_fields = ['span' ]):
72+ def equals (self , other : 'BaseNode' , ignored_fields : List [ str ] = ['span' ]) -> bool :
6973 """Compare two nodes.
7074
7175 Nodes are deeply compared on a field by field basis. If possible, False
@@ -104,7 +108,7 @@ def equals(self, other, ignored_fields=['span']):
104108
105109 return True
106110
107- def to_json (self , fn = None ):
111+ def to_json (self , fn : Union [ ToJsonFn , None ] = None ) -> Any :
108112 obj = {
109113 name : to_json (value , fn )
110114 for name , value in vars (self ).items ()
@@ -114,23 +118,23 @@ def to_json(self, fn=None):
114118 )
115119 return fn (obj ) if fn else obj
116120
117- def __str__ (self ):
121+ def __str__ (self ) -> str :
118122 return json .dumps (self .to_json ())
119123
120124
121125class SyntaxNode (BaseNode ):
122126 """Base class for AST nodes which can have Spans."""
123127
124- def __init__ (self , span = None , ** kwargs ):
128+ def __init__ (self , span : Union [ 'Span' , None ] = None , ** kwargs : Any ):
125129 super ().__init__ (** kwargs )
126130 self .span = span
127131
128- def add_span (self , start , end ) :
132+ def add_span (self , start : int , end : int ) -> None :
129133 self .span = Span (start , end )
130134
131135
132136class Resource (SyntaxNode ):
133- def __init__ (self , body = None , ** kwargs ):
137+ def __init__ (self , body : Union [ List [ 'EntryType' ], None ] = None , ** kwargs : Any ):
134138 super ().__init__ (** kwargs )
135139 self .body = body or []
136140
@@ -140,8 +144,12 @@ class Entry(SyntaxNode):
140144
141145
142146class Message (Entry ):
143- def __init__ (self , id , value = None , attributes = None ,
144- comment = None , ** kwargs ):
147+ def __init__ (self ,
148+ id : 'Identifier' ,
149+ value : Union ['Pattern' , None ] = None ,
150+ attributes : Union [List ['Attribute' ], None ] = None ,
151+ comment : Union ['Comment' , None ] = None ,
152+ ** kwargs : Any ):
145153 super ().__init__ (** kwargs )
146154 self .id = id
147155 self .value = value
@@ -150,8 +158,8 @@ def __init__(self, id, value=None, attributes=None,
150158
151159
152160class Term (Entry ):
153- def __init__ (self , id , value , attributes = None ,
154- comment = None , ** kwargs ):
161+ def __init__ (self , id : 'Identifier' , value : 'Pattern' , attributes : Union [ List [ 'Attribute' ], None ] = None ,
162+ comment : Union [ 'Comment' , None ] = None , ** kwargs : Any ):
155163 super ().__init__ (** kwargs )
156164 self .id = id
157165 self .value = value
@@ -160,7 +168,7 @@ def __init__(self, id, value, attributes=None,
160168
161169
162170class Pattern (SyntaxNode ):
163- def __init__ (self , elements , ** kwargs ):
171+ def __init__ (self , elements : List [ Union [ 'TextElement' , 'Placeable' ]], ** kwargs : Any ):
164172 super ().__init__ (** kwargs )
165173 self .elements = elements
166174
@@ -170,13 +178,15 @@ class PatternElement(SyntaxNode):
170178
171179
172180class TextElement (PatternElement ):
173- def __init__ (self , value , ** kwargs ):
181+ def __init__ (self , value : str , ** kwargs : Any ):
174182 super ().__init__ (** kwargs )
175183 self .value = value
176184
177185
178186class Placeable (PatternElement ):
179- def __init__ (self , expression , ** kwargs ):
187+ def __init__ (self ,
188+ expression : Union ['InlineExpression' , 'Placeable' , 'SelectExpression' ],
189+ ** kwargs : Any ):
180190 super ().__init__ (** kwargs )
181191 self .expression = expression
182192
@@ -187,20 +197,21 @@ class Expression(SyntaxNode):
187197
188198class Literal (Expression ):
189199 """An abstract base class for literals."""
190- def __init__ (self , value , ** kwargs ):
200+
201+ def __init__ (self , value : str , ** kwargs : Any ):
191202 super ().__init__ (** kwargs )
192203 self .value = value
193204
194- def parse (self ):
205+ def parse (self ) -> Dict [ str , Any ] :
195206 return {'value' : self .value }
196207
197208
198209class StringLiteral (Literal ):
199- def parse (self ):
200- def from_escape_sequence (matchobj ) :
210+ def parse (self ) -> Dict [ str , str ] :
211+ def from_escape_sequence (matchobj : Any ) -> str :
201212 c , codepoint4 , codepoint6 = matchobj .groups ()
202213 if c :
203- return c
214+ return cast ( str , c )
204215 codepoint = int (codepoint4 or codepoint6 , 16 )
205216 if codepoint <= 0xD7FF or 0xE000 <= codepoint :
206217 return chr (codepoint )
@@ -218,7 +229,7 @@ def from_escape_sequence(matchobj):
218229
219230
220231class NumberLiteral (Literal ):
221- def parse (self ):
232+ def parse (self ) -> Dict [ str , Union [ float , int ]] :
222233 value = float (self .value )
223234 decimal_position = self .value .find ('.' )
224235 precision = 0
@@ -231,116 +242,135 @@ def parse(self):
231242
232243
233244class MessageReference (Expression ):
234- def __init__ (self , id , attribute = None , ** kwargs ):
245+ def __init__ (self , id : 'Identifier' , attribute : Union [ 'Identifier' , None ] = None , ** kwargs : Any ):
235246 super ().__init__ (** kwargs )
236247 self .id = id
237248 self .attribute = attribute
238249
239250
240251class TermReference (Expression ):
241- def __init__ (self , id , attribute = None , arguments = None , ** kwargs ):
252+ def __init__ (self ,
253+ id : 'Identifier' ,
254+ attribute : Union ['Identifier' , None ] = None ,
255+ arguments : Union ['CallArguments' , None ] = None ,
256+ ** kwargs : Any ):
242257 super ().__init__ (** kwargs )
243258 self .id = id
244259 self .attribute = attribute
245260 self .arguments = arguments
246261
247262
248263class VariableReference (Expression ):
249- def __init__ (self , id , ** kwargs ):
264+ def __init__ (self , id : 'Identifier' , ** kwargs : Any ):
250265 super ().__init__ (** kwargs )
251266 self .id = id
252267
253268
254269class FunctionReference (Expression ):
255- def __init__ (self , id , arguments , ** kwargs ):
270+ def __init__ (self , id : 'Identifier' , arguments : 'CallArguments' , ** kwargs : Any ):
256271 super ().__init__ (** kwargs )
257272 self .id = id
258273 self .arguments = arguments
259274
260275
261276class SelectExpression (Expression ):
262- def __init__ (self , selector , variants , ** kwargs ):
277+ def __init__ (self , selector : 'InlineExpression' , variants : List [ 'Variant' ] , ** kwargs : Any ):
263278 super ().__init__ (** kwargs )
264279 self .selector = selector
265280 self .variants = variants
266281
267282
268283class CallArguments (SyntaxNode ):
269- def __init__ (self , positional = None , named = None , ** kwargs ):
284+ def __init__ (self ,
285+ positional : Union [List [Union ['InlineExpression' , Placeable ]], None ] = None ,
286+ named : Union [List ['NamedArgument' ], None ] = None ,
287+ ** kwargs : Any ):
270288 super ().__init__ (** kwargs )
271289 self .positional = [] if positional is None else positional
272290 self .named = [] if named is None else named
273291
274292
275293class Attribute (SyntaxNode ):
276- def __init__ (self , id , value , ** kwargs ):
294+ def __init__ (self , id : 'Identifier' , value : Pattern , ** kwargs : Any ):
277295 super ().__init__ (** kwargs )
278296 self .id = id
279297 self .value = value
280298
281299
282300class Variant (SyntaxNode ):
283- def __init__ (self , key , value , default = False , ** kwargs ):
301+ def __init__ (self , key : Union [ 'Identifier' , NumberLiteral ], value : Pattern , default : bool = False , ** kwargs : Any ):
284302 super ().__init__ (** kwargs )
285303 self .key = key
286304 self .value = value
287305 self .default = default
288306
289307
290308class NamedArgument (SyntaxNode ):
291- def __init__ (self , name , value , ** kwargs ):
309+ def __init__ (self , name : 'Identifier' , value : Union [ NumberLiteral , StringLiteral ], ** kwargs : Any ):
292310 super ().__init__ (** kwargs )
293311 self .name = name
294312 self .value = value
295313
296314
297315class Identifier (SyntaxNode ):
298- def __init__ (self , name , ** kwargs ):
316+ def __init__ (self , name : str , ** kwargs : Any ):
299317 super ().__init__ (** kwargs )
300318 self .name = name
301319
302320
303321class BaseComment (Entry ):
304- def __init__ (self , content = None , ** kwargs ):
322+ def __init__ (self , content : Union [ str , None ] = None , ** kwargs : Any ):
305323 super ().__init__ (** kwargs )
306324 self .content = content
307325
308326
309327class Comment (BaseComment ):
310- def __init__ (self , content = None , ** kwargs ):
328+ def __init__ (self , content : Union [ str , None ] = None , ** kwargs : Any ):
311329 super ().__init__ (content , ** kwargs )
312330
313331
314332class GroupComment (BaseComment ):
315- def __init__ (self , content = None , ** kwargs ):
333+ def __init__ (self , content : Union [ str , None ] = None , ** kwargs : Any ):
316334 super ().__init__ (content , ** kwargs )
317335
318336
319337class ResourceComment (BaseComment ):
320- def __init__ (self , content = None , ** kwargs ):
338+ def __init__ (self , content : Union [ str , None ] = None , ** kwargs : Any ):
321339 super ().__init__ (content , ** kwargs )
322340
323341
324342class Junk (SyntaxNode ):
325- def __init__ (self , content = None , annotations = None , ** kwargs ):
343+ def __init__ (self ,
344+ content : Union [str , None ] = None ,
345+ annotations : Union [List ['Annotation' ], None ] = None ,
346+ ** kwargs : Any ):
326347 super ().__init__ (** kwargs )
327348 self .content = content
328349 self .annotations = annotations or []
329350
330- def add_annotation (self , annot ) :
351+ def add_annotation (self , annot : 'Annotation' ) -> None :
331352 self .annotations .append (annot )
332353
333354
334355class Span (BaseNode ):
335- def __init__ (self , start , end , ** kwargs ):
356+ def __init__ (self , start : int , end : int , ** kwargs : Any ):
336357 super ().__init__ (** kwargs )
337358 self .start = start
338359 self .end = end
339360
340361
341362class Annotation (SyntaxNode ):
342- def __init__ (self , code , arguments = None , message = None , ** kwargs ):
363+ def __init__ (self ,
364+ code : str ,
365+ arguments : Union [List [Any ], None ] = None ,
366+ message : Union [str , None ] = None ,
367+ ** kwargs : Any ):
343368 super ().__init__ (** kwargs )
344369 self .code = code
345370 self .arguments = arguments or []
346371 self .message = message
372+
373+
374+ EntryType = Union [Message , Term , Comment , GroupComment , ResourceComment , Junk ]
375+ InlineExpression = Union [NumberLiteral , StringLiteral , MessageReference ,
376+ TermReference , VariableReference , FunctionReference ]
0 commit comments