28
28
Pattern ,
29
29
Set ,
30
30
Tuple ,
31
+ TypeVar ,
31
32
Union ,
32
33
cast ,
33
34
)
@@ -647,7 +648,12 @@ def get_meta_prop(o: Union[IMeta, Var]) -> Any:
647
648
_tag_meta = _meta_getter (SYM_TAG_META_KEY )
648
649
649
650
650
- def _loc (form : Union [LispForm , ISeq ]) -> Optional [Tuple [int , int , int , int ]]:
651
+ T_form = TypeVar ("T_form" , bound = ReaderForm )
652
+ T_node = TypeVar ("T_node" , bound = Node )
653
+ LispAnalyzer = Callable [[T_form , AnalyzerContext ], T_node ]
654
+
655
+
656
+ def _loc (form : T_form ) -> Optional [Tuple [int , int , int , int ]]:
651
657
"""Fetch the location of the form in the original filename from the
652
658
input form, if it has metadata."""
653
659
# Technically, IMeta is sufficient for fetching `form.meta` but the
@@ -669,17 +675,17 @@ def _loc(form: Union[LispForm, ISeq]) -> Optional[Tuple[int, int, int, int]]:
669
675
return None
670
676
671
677
672
- def _with_loc (f ) :
678
+ def _with_loc (f : LispAnalyzer [ T_form , T_node ]) -> LispAnalyzer [ T_form , T_node ] :
673
679
"""Attach any available location information from the input form to
674
680
the node environment returned from the parsing function."""
675
681
676
682
@wraps (f )
677
- def _analyze_form (form : Union [ LispForm , ISeq ], ctx : AnalyzerContext ) -> Node :
683
+ def _analyze_form (form : T_form , ctx : AnalyzerContext ) -> T_node :
678
684
form_loc = _loc (form )
679
685
if form_loc is None :
680
686
return f (form , ctx )
681
687
else :
682
- return f (form , ctx ).fix_missing_locations (form_loc )
688
+ return cast ( T_node , f (form , ctx ).fix_missing_locations (form_loc ) )
683
689
684
690
return _analyze_form
685
691
@@ -795,24 +801,15 @@ def _tag_ast(form: Optional[LispForm], ctx: AnalyzerContext) -> Optional[Node]:
795
801
return _analyze_form (form , ctx )
796
802
797
803
798
- def _with_meta (gen_node ) :
804
+ def _with_meta (gen_node : LispAnalyzer [ T_form , T_node ]) -> LispAnalyzer [ T_form , T_node ] :
799
805
"""Wraps the node generated by gen_node in a :with-meta AST node if the
800
806
original form has meta.
801
807
802
808
:with-meta AST nodes are used for non-quoted collection literals and for
803
809
function expressions."""
804
810
805
811
@wraps (gen_node )
806
- def with_meta (
807
- form : Union [
808
- llist .PersistentList ,
809
- lmap .PersistentMap ,
810
- ISeq ,
811
- lset .PersistentSet ,
812
- vec .PersistentVector ,
813
- ],
814
- ctx : AnalyzerContext ,
815
- ) -> Node :
812
+ def with_meta (form : T_form , ctx : AnalyzerContext ) -> T_node :
816
813
assert not ctx .is_quoted , "with-meta nodes are not used in quoted expressions"
817
814
818
815
descriptor = gen_node (form , ctx )
@@ -825,11 +822,14 @@ def with_meta(
825
822
assert isinstance (meta_ast , MapNode ) or (
826
823
isinstance (meta_ast , Const ) and meta_ast .type == ConstType .MAP
827
824
)
828
- return WithMeta (
829
- form = form ,
830
- meta = meta_ast ,
831
- expr = descriptor ,
832
- env = ctx .get_node_env (pos = ctx .syntax_position ),
825
+ return cast (
826
+ T_node ,
827
+ WithMeta (
828
+ form = cast (LispForm , form ),
829
+ meta = meta_ast ,
830
+ expr = descriptor ,
831
+ env = ctx .get_node_env (pos = ctx .syntax_position ),
832
+ ),
833
833
)
834
834
835
835
return descriptor
@@ -3113,7 +3113,7 @@ def _yield_ast(form: ISeq, ctx: AnalyzerContext) -> Yield:
3113
3113
return Yield .expressionless (form , ctx .get_node_env (pos = ctx .syntax_position ))
3114
3114
3115
3115
3116
- SpecialFormHandler = Callable [[ISeq , AnalyzerContext ], SpecialFormNode ]
3116
+ SpecialFormHandler = Callable [[T_form , AnalyzerContext ], SpecialFormNode ]
3117
3117
_SPECIAL_FORM_HANDLERS : Mapping [sym .Symbol , SpecialFormHandler ] = {
3118
3118
SpecialForm .AWAIT : _await_ast ,
3119
3119
SpecialForm .DEF : _def_ast ,
0 commit comments