49
49
Await ,
50
50
Binding ,
51
51
Catch ,
52
+ ClassMethod ,
52
53
Const ,
53
54
ConstType ,
54
55
Def ,
55
56
DefType ,
57
+ DefTypeMember ,
56
58
Do ,
57
59
Fn ,
58
60
FnMethod ,
72
74
Node ,
73
75
NodeEnv ,
74
76
NodeOp ,
77
+ PropertyMethod ,
75
78
PyDict ,
76
79
PyList ,
77
80
PySet ,
81
84
Recur ,
82
85
Set as SetNode ,
83
86
SetBang ,
87
+ StaticMethod ,
84
88
Throw ,
85
89
Try ,
86
90
VarRef ,
@@ -484,6 +488,9 @@ def _is_redefable(v: Var) -> bool:
484
488
_COERCE_SEQ_FN_NAME = _load_attr (f"{ _RUNTIME_ALIAS } .to_seq" )
485
489
_BASILISP_FN_FN_NAME = _load_attr (f"{ _RUNTIME_ALIAS } ._basilisp_fn" )
486
490
_FN_WITH_ATTRS_FN_NAME = _load_attr (f"{ _RUNTIME_ALIAS } ._with_attrs" )
491
+ _PY_CLASSMETHOD_FN_NAME = _load_attr ("classmethod" )
492
+ _PY_PROPERTY_FN_NAME = _load_attr ("property" )
493
+ _PY_STATICMETHOD_FN_NAME = _load_attr ("staticmethod" )
487
494
_TRAMPOLINE_FN_NAME = _load_attr (f"{ _RUNTIME_ALIAS } ._trampoline" )
488
495
_TRAMPOLINE_ARGS_FN_NAME = _load_attr (f"{ _RUNTIME_ALIAS } ._TrampolineArgs" )
489
496
@@ -705,9 +712,76 @@ def _def_to_py_ast( # pylint: disable=too-many-branches
705
712
706
713
707
714
@_with_ast_loc
708
- def __deftype_method_to_py_ast ( # pylint: disable=too-many-branches
709
- ctx : GeneratorContext , node : Method
715
+ def __deftype_classmethod_to_py_ast (
716
+ ctx : GeneratorContext , node : ClassMethod
710
717
) -> GeneratedPyAST :
718
+ assert node .op == NodeOp .CLASS_METHOD
719
+ method_name = munge (node .name )
720
+
721
+ with ctx .new_symbol_table (node .name ):
722
+ class_name = genname (munge (node .class_local .name ))
723
+ class_sym = sym .symbol (node .class_local .name )
724
+ ctx .symbol_table .new_symbol (class_sym , class_name , LocalType .ARG )
725
+
726
+ fn_args , varg , fn_body_ast = __fn_args_to_py_ast (ctx , node .params , node .body )
727
+ return GeneratedPyAST (
728
+ node = ast .FunctionDef (
729
+ name = method_name ,
730
+ args = ast .arguments (
731
+ args = list (
732
+ chain ([ast .arg (arg = class_name , annotation = None )], fn_args )
733
+ ),
734
+ kwarg = None ,
735
+ vararg = varg ,
736
+ kwonlyargs = [],
737
+ defaults = [],
738
+ kw_defaults = [],
739
+ ),
740
+ body = fn_body_ast ,
741
+ decorator_list = [_PY_CLASSMETHOD_FN_NAME ],
742
+ returns = None ,
743
+ )
744
+ )
745
+
746
+
747
+ @_with_ast_loc
748
+ def __deftype_property_to_py_ast (
749
+ ctx : GeneratorContext , node : PropertyMethod
750
+ ) -> GeneratedPyAST :
751
+ assert node .op == NodeOp .PROPERTY_METHOD
752
+ method_name = munge (node .name )
753
+
754
+ with ctx .new_symbol_table (node .name ):
755
+ this_name = genname (munge (node .this_local .name ))
756
+ this_sym = sym .symbol (node .this_local .name )
757
+ ctx .symbol_table .new_symbol (this_sym , this_name , LocalType .THIS )
758
+
759
+ with ctx .new_this (this_sym ):
760
+ fn_args , varg , fn_body_ast = __fn_args_to_py_ast (
761
+ ctx , node .params , node .body
762
+ )
763
+ return GeneratedPyAST (
764
+ node = ast .FunctionDef (
765
+ name = method_name ,
766
+ args = ast .arguments (
767
+ args = list (
768
+ chain ([ast .arg (arg = this_name , annotation = None )], fn_args )
769
+ ),
770
+ kwarg = None ,
771
+ vararg = varg ,
772
+ kwonlyargs = [],
773
+ defaults = [],
774
+ kw_defaults = [],
775
+ ),
776
+ body = fn_body_ast ,
777
+ decorator_list = [_PY_PROPERTY_FN_NAME ],
778
+ returns = None ,
779
+ )
780
+ )
781
+
782
+
783
+ @_with_ast_loc
784
+ def __deftype_method_to_py_ast (ctx : GeneratorContext , node : Method ) -> GeneratedPyAST :
711
785
assert node .op == NodeOp .METHOD
712
786
method_name = munge (node .name )
713
787
@@ -744,6 +818,52 @@ def __deftype_method_to_py_ast( # pylint: disable=too-many-branches
744
818
)
745
819
746
820
821
+ @_with_ast_loc
822
+ def __deftype_staticmethod_to_py_ast (
823
+ ctx : GeneratorContext , node : StaticMethod
824
+ ) -> GeneratedPyAST :
825
+ assert node .op == NodeOp .STATIC_METHOD
826
+ method_name = munge (node .name )
827
+
828
+ with ctx .new_symbol_table (node .name ):
829
+ fn_args , varg , fn_body_ast = __fn_args_to_py_ast (ctx , node .params , node .body )
830
+ return GeneratedPyAST (
831
+ node = ast .FunctionDef (
832
+ name = method_name ,
833
+ args = ast .arguments (
834
+ args = list (fn_args ),
835
+ kwarg = None ,
836
+ vararg = varg ,
837
+ kwonlyargs = [],
838
+ defaults = [],
839
+ kw_defaults = [],
840
+ ),
841
+ body = fn_body_ast ,
842
+ decorator_list = [_PY_STATICMETHOD_FN_NAME ],
843
+ returns = None ,
844
+ )
845
+ )
846
+
847
+
848
+ _DEFTYPE_MEMBER_HANDLER : Mapping [NodeOp , PyASTGenerator ] = {
849
+ NodeOp .CLASS_METHOD : __deftype_classmethod_to_py_ast ,
850
+ NodeOp .METHOD : __deftype_method_to_py_ast ,
851
+ NodeOp .PROPERTY_METHOD : __deftype_property_to_py_ast ,
852
+ NodeOp .STATIC_METHOD : __deftype_staticmethod_to_py_ast ,
853
+ }
854
+
855
+
856
+ def __deftype_member_to_py_ast (
857
+ ctx : GeneratorContext , node : DefTypeMember
858
+ ) -> GeneratedPyAST :
859
+ member_type = node .op
860
+ handle_deftype_member = _DEFTYPE_MEMBER_HANDLER .get (member_type )
861
+ assert (
862
+ handle_deftype_member is not None
863
+ ), f"Invalid :const AST type handler for { member_type } "
864
+ return handle_deftype_member (ctx , node )
865
+
866
+
747
867
@_with_ast_loc
748
868
def _deftype_to_py_ast ( # pylint: disable=too-many-branches
749
869
ctx : GeneratorContext , node : DefType
@@ -784,9 +904,9 @@ def _deftype_to_py_ast( # pylint: disable=too-many-branches
784
904
ctx .symbol_table .new_symbol (sym .symbol (field .name ), safe_field , field .local )
785
905
786
906
type_deps : List [ast .AST ] = []
787
- for method in node .methods :
788
- type_ast = __deftype_method_to_py_ast (ctx , method )
789
- type_nodes .append (type_ast .node )
907
+ for member in node .members :
908
+ type_ast = __deftype_member_to_py_ast (ctx , member )
909
+ type_nodes .append (type_ast .node ) # type: ignore
790
910
type_deps .extend (type_ast .dependencies )
791
911
792
912
return GeneratedPyAST (
@@ -1870,7 +1990,11 @@ def _var_sym_to_py_ast(
1870
1990
if safe_name in ns_module .__dict__ :
1871
1991
if ns is ctx .current_ns :
1872
1992
return GeneratedPyAST (node = ast .Name (id = safe_name , ctx = py_var_ctx ))
1873
- return GeneratedPyAST (node = _load_attr (f"{ safe_ns } .{ safe_name } " , ctx = py_var_ctx ))
1993
+ return GeneratedPyAST (
1994
+ node = _load_attr (
1995
+ f"{ _MODULE_ALIASES .get (ns_name , safe_ns )} .{ safe_name } " , ctx = py_var_ctx
1996
+ )
1997
+ )
1874
1998
1875
1999
if ctx .warn_on_var_indirection :
1876
2000
logger .warning (f"could not resolve a direct link to Var '{ var_name } '" )
@@ -1930,10 +2054,7 @@ def _maybe_class_to_py_ast(_: GeneratorContext, node: MaybeClass) -> GeneratedPy
1930
2054
variable name."""
1931
2055
assert node .op == NodeOp .MAYBE_CLASS
1932
2056
return GeneratedPyAST (
1933
- node = ast .Name (
1934
- id = Maybe (_MODULE_ALIASES .get (node .class_ )).or_else_get (node .class_ ),
1935
- ctx = ast .Load (),
1936
- )
2057
+ node = ast .Name (id = _MODULE_ALIASES .get (node .class_ , node .class_ ), ctx = ast .Load ())
1937
2058
)
1938
2059
1939
2060
@@ -1945,9 +2066,7 @@ def _maybe_host_form_to_py_ast(
1945
2066
variable name with a namespace."""
1946
2067
assert node .op == NodeOp .MAYBE_HOST_FORM
1947
2068
return GeneratedPyAST (
1948
- node = _load_attr (
1949
- f"{ Maybe (_MODULE_ALIASES .get (node .class_ )).or_else_get (node .class_ )} .{ node .field } "
1950
- )
2069
+ node = _load_attr (f"{ _MODULE_ALIASES .get (node .class_ , node .class_ )} .{ node .field } " )
1951
2070
)
1952
2071
1953
2072
@@ -2373,7 +2492,9 @@ def _collection_literal_to_py_ast(
2373
2492
ConstType .KEYWORD : _kw_to_py_ast ,
2374
2493
ConstType .MAP : _const_map_to_py_ast ,
2375
2494
ConstType .SET : _const_set_to_py_ast ,
2495
+ ConstType .RECORD : None ,
2376
2496
ConstType .SEQ : _const_seq_to_py_ast ,
2497
+ ConstType .TYPE : None ,
2377
2498
ConstType .REGEX : _regex_to_py_ast ,
2378
2499
ConstType .SYMBOL : _const_sym_to_py_ast ,
2379
2500
ConstType .STRING : _str_to_py_ast ,
0 commit comments