@@ -648,7 +648,12 @@ def get_meta_prop(o: Union[IMeta, Var]) -> Any:
648648_tag_meta = _meta_getter (SYM_TAG_META_KEY )
649649
650650
651- 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 ]]:
652657 """Fetch the location of the form in the original filename from the
653658 input form, if it has metadata."""
654659 # Technically, IMeta is sufficient for fetching `form.meta` but the
@@ -670,22 +675,17 @@ def _loc(form: Union[LispForm, ISeq]) -> Optional[Tuple[int, int, int, int]]:
670675 return None
671676
672677
673- T_form = TypeVar ("T_form" , bound = LispForm )
674- T_node = TypeVar ("T_node" , Node , None )
675- LispAnalyzer = Callable [[T_form , AnalyzerContext ], T_node ]
676-
677-
678- def _with_loc (f : LispAnalyzer ) -> LispAnalyzer :
678+ def _with_loc (f : LispAnalyzer [T_form , T_node ]) -> LispAnalyzer [T_form , T_node ]:
679679 """Attach any available location information from the input form to
680680 the node environment returned from the parsing function."""
681681
682682 @wraps (f )
683- def _analyze_form (form : T_form , ctx : AnalyzerContext ) -> Node :
683+ def _analyze_form (form : T_form , ctx : AnalyzerContext ) -> T_node :
684684 form_loc = _loc (form )
685685 if form_loc is None :
686686 return f (form , ctx )
687687 else :
688- return f (form , ctx ).fix_missing_locations (form_loc )
688+ return cast ( T_node , f (form , ctx ).fix_missing_locations (form_loc ) )
689689
690690 return _analyze_form
691691
@@ -801,15 +801,15 @@ def _tag_ast(form: Optional[LispForm], ctx: AnalyzerContext) -> Optional[Node]:
801801 return _analyze_form (form , ctx )
802802
803803
804- def _with_meta (gen_node : LispAnalyzer ) -> LispAnalyzer :
804+ def _with_meta (gen_node : LispAnalyzer [ T_form , T_node ] ) -> LispAnalyzer [ T_form , T_node ] :
805805 """Wraps the node generated by gen_node in a :with-meta AST node if the
806806 original form has meta.
807807
808808 :with-meta AST nodes are used for non-quoted collection literals and for
809809 function expressions."""
810810
811811 @wraps (gen_node )
812- def with_meta (form : T_form , ctx : AnalyzerContext ) -> Node :
812+ def with_meta (form : T_form , ctx : AnalyzerContext ) -> T_node :
813813 assert not ctx .is_quoted , "with-meta nodes are not used in quoted expressions"
814814
815815 descriptor = gen_node (form , ctx )
@@ -822,11 +822,14 @@ def with_meta(form: T_form, ctx: AnalyzerContext) -> Node:
822822 assert isinstance (meta_ast , MapNode ) or (
823823 isinstance (meta_ast , Const ) and meta_ast .type == ConstType .MAP
824824 )
825- return WithMeta (
826- form = cast (T_form , form ),
827- meta = meta_ast ,
828- expr = descriptor ,
829- 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+ ),
830833 )
831834
832835 return descriptor
0 commit comments