jaclang 0.7.14__py3-none-any.whl → 0.7.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaclang might be problematic. Click here for more details.
- jaclang/cli/cli.py +147 -77
- jaclang/cli/cmdreg.py +9 -12
- jaclang/compiler/__init__.py +19 -53
- jaclang/compiler/absyntree.py +94 -16
- jaclang/compiler/constant.py +8 -8
- jaclang/compiler/jac.lark +4 -3
- jaclang/compiler/parser.py +41 -25
- jaclang/compiler/passes/ir_pass.py +4 -13
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/access_modifier_pass.py +96 -147
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +155 -54
- jaclang/compiler/passes/main/import_pass.py +99 -75
- jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +328 -565
- jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
- jaclang/compiler/passes/main/registry_pass.py +37 -3
- jaclang/compiler/passes/main/schedules.py +9 -2
- jaclang/compiler/passes/main/sym_tab_build_pass.py +10 -6
- jaclang/compiler/passes/main/tests/__init__.py +1 -1
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.empty.impl.jac +0 -0
- jaclang/compiler/passes/main/tests/fixtures/autoimpl.jac +1 -1
- jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac +29 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +72 -13
- jaclang/compiler/passes/main/type_check_pass.py +22 -5
- jaclang/compiler/passes/tool/jac_formatter_pass.py +135 -89
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -42
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
- jaclang/compiler/passes/transform.py +4 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +45 -0
- jaclang/compiler/semtable.py +31 -7
- jaclang/compiler/symtable.py +16 -11
- jaclang/compiler/tests/test_importer.py +25 -10
- jaclang/langserve/engine.py +104 -118
- jaclang/langserve/sem_manager.py +379 -0
- jaclang/langserve/server.py +24 -11
- jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
- jaclang/langserve/tests/fixtures/circle.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
- jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
- jaclang/langserve/tests/fixtures/rename.jac +30 -0
- jaclang/langserve/tests/test_sem_tokens.py +277 -0
- jaclang/langserve/tests/test_server.py +287 -17
- jaclang/langserve/utils.py +184 -98
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +288 -92
- jaclang/plugin/feature.py +65 -27
- jaclang/plugin/spec.py +62 -23
- jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
- jaclang/plugin/tests/test_jaseci.py +414 -42
- jaclang/runtimelib/architype.py +650 -0
- jaclang/{core → runtimelib}/constructs.py +5 -8
- jaclang/{core → runtimelib}/context.py +86 -59
- jaclang/runtimelib/importer.py +361 -0
- jaclang/runtimelib/machine.py +158 -0
- jaclang/runtimelib/memory.py +158 -0
- jaclang/{core → runtimelib}/utils.py +30 -15
- jaclang/settings.py +5 -4
- jaclang/tests/fixtures/abc.jac +3 -3
- jaclang/tests/fixtures/access_checker.jac +12 -17
- jaclang/tests/fixtures/access_modifier.jac +88 -33
- jaclang/tests/fixtures/baddy.jac +3 -0
- jaclang/tests/fixtures/baddy.test.jac +3 -0
- jaclang/tests/fixtures/bar.jac +34 -0
- jaclang/tests/fixtures/byllmissue.jac +1 -5
- jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
- jaclang/tests/fixtures/cls_method.jac +41 -0
- jaclang/tests/fixtures/dblhello.jac +6 -0
- jaclang/tests/fixtures/deep/one_lev.jac +3 -3
- jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
- jaclang/tests/fixtures/deep_import_mods.jac +13 -0
- jaclang/tests/fixtures/edge_node_walk.jac +1 -1
- jaclang/tests/fixtures/edge_ops.jac +1 -1
- jaclang/tests/fixtures/edges_walk.jac +1 -1
- jaclang/tests/fixtures/err.impl.jac +3 -0
- jaclang/tests/fixtures/err.jac +4 -2
- jaclang/tests/fixtures/err_runtime.jac +15 -0
- jaclang/tests/fixtures/foo.jac +43 -0
- jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
- jaclang/tests/fixtures/hello.jac +4 -0
- jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
- jaclang/tests/fixtures/impl_grab.jac +4 -1
- jaclang/tests/fixtures/import.jac +9 -0
- jaclang/tests/fixtures/index_slice.jac +30 -0
- jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
- jaclang/tests/fixtures/needs_import.jac +2 -2
- jaclang/tests/fixtures/pyfunc_1.py +1 -1
- jaclang/tests/fixtures/pyfunc_2.py +5 -2
- jaclang/tests/fixtures/pygame_mock/__init__.py +3 -0
- jaclang/tests/fixtures/pygame_mock/color.py +3 -0
- jaclang/tests/fixtures/pygame_mock/constants.py +5 -0
- jaclang/tests/fixtures/pygame_mock/display.py +2 -0
- jaclang/tests/fixtures/pygame_mock/inner/__init__.py +0 -0
- jaclang/tests/fixtures/pygame_mock/inner/iner_mod.py +2 -0
- jaclang/tests/fixtures/registry.jac +9 -0
- jaclang/tests/fixtures/run_test.jac +4 -4
- jaclang/tests/fixtures/semstr.jac +1 -4
- jaclang/tests/fixtures/simple_archs.jac +1 -1
- jaclang/tests/test_cli.py +109 -3
- jaclang/tests/test_language.py +170 -68
- jaclang/tests/test_reference.py +2 -3
- jaclang/utils/helpers.py +45 -21
- jaclang/utils/test.py +9 -0
- jaclang/utils/treeprinter.py +30 -7
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/METADATA +3 -2
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/RECORD +126 -90
- jaclang/core/architype.py +0 -502
- jaclang/core/importer.py +0 -344
- jaclang/core/memory.py +0 -99
- jaclang/tests/fixtures/aott_raise.jac +0 -25
- jaclang/tests/fixtures/package_import.jac +0 -6
- /jaclang/{core → runtimelib}/__init__.py +0 -0
- /jaclang/{core → runtimelib}/test.py +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/WHEEL +0 -0
- {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/entry_points.txt +0 -0
|
@@ -128,6 +128,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
128
128
|
is_imported=False,
|
|
129
129
|
kid=valid,
|
|
130
130
|
)
|
|
131
|
+
ret.is_raised_from_py = True
|
|
131
132
|
return self.nu(ret)
|
|
132
133
|
|
|
133
134
|
def proc_function_def(
|
|
@@ -144,12 +145,15 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
144
145
|
if sys.version_info >= (3, 12):
|
|
145
146
|
type_params: list[type_param]
|
|
146
147
|
"""
|
|
148
|
+
from jaclang.compiler import TOKEN_MAP
|
|
149
|
+
|
|
150
|
+
reserved_keywords = [v for _, v in TOKEN_MAP.items()]
|
|
151
|
+
|
|
152
|
+
value = node.name if node.name not in reserved_keywords else f"<>{node.name}"
|
|
147
153
|
name = ast.Name(
|
|
148
154
|
file_path=self.mod_path,
|
|
149
155
|
name=Tok.NAME,
|
|
150
|
-
value=
|
|
151
|
-
node.name if node.name != "root" else "root_"
|
|
152
|
-
), # root is a reserved keyword
|
|
156
|
+
value=value,
|
|
153
157
|
line=node.lineno,
|
|
154
158
|
end_line=node.end_lineno if node.end_lineno else node.lineno,
|
|
155
159
|
col_start=node.col_offset,
|
|
@@ -1875,10 +1879,19 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
1875
1879
|
id: _Identifier
|
|
1876
1880
|
ctx: expr_context
|
|
1877
1881
|
"""
|
|
1882
|
+
from jaclang.compiler import TOKEN_MAP
|
|
1883
|
+
|
|
1884
|
+
reserved_keywords = [
|
|
1885
|
+
v
|
|
1886
|
+
for _, v in TOKEN_MAP.items()
|
|
1887
|
+
if v not in ["float", "int", "str", "bool", "self"]
|
|
1888
|
+
]
|
|
1889
|
+
|
|
1890
|
+
value = node.id if node.id not in reserved_keywords else f"<>{node.id}"
|
|
1878
1891
|
ret = ast.Name(
|
|
1879
1892
|
file_path=self.mod_path,
|
|
1880
1893
|
name=Tok.NAME,
|
|
1881
|
-
value=
|
|
1894
|
+
value=value,
|
|
1882
1895
|
line=node.lineno,
|
|
1883
1896
|
end_line=node.end_lineno if node.end_lineno else node.lineno,
|
|
1884
1897
|
col_start=node.col_offset,
|
|
@@ -1913,13 +1926,18 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
1913
1926
|
class Nonlocal(stmt):
|
|
1914
1927
|
names: list[_Identifier]
|
|
1915
1928
|
"""
|
|
1929
|
+
from jaclang.compiler import TOKEN_MAP
|
|
1930
|
+
|
|
1931
|
+
reserved_keywords = [v for _, v in TOKEN_MAP.items()]
|
|
1932
|
+
|
|
1916
1933
|
names: list[ast.NameAtom] = []
|
|
1917
1934
|
for name in node.names:
|
|
1935
|
+
value = name if name not in reserved_keywords else f"<>{name}"
|
|
1918
1936
|
names.append(
|
|
1919
1937
|
ast.Name(
|
|
1920
1938
|
file_path=self.mod_path,
|
|
1921
1939
|
name=Tok.NAME,
|
|
1922
|
-
value=
|
|
1940
|
+
value=value,
|
|
1923
1941
|
line=node.lineno,
|
|
1924
1942
|
end_line=node.end_lineno if node.end_lineno else node.lineno,
|
|
1925
1943
|
col_start=node.col_offset,
|
|
@@ -2238,10 +2256,19 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
|
|
|
2238
2256
|
arg: _Identifier
|
|
2239
2257
|
annotation: expr | None
|
|
2240
2258
|
"""
|
|
2259
|
+
from jaclang.compiler import TOKEN_MAP
|
|
2260
|
+
|
|
2261
|
+
reserved_keywords = [
|
|
2262
|
+
v
|
|
2263
|
+
for _, v in TOKEN_MAP.items()
|
|
2264
|
+
if v not in ["float", "int", "str", "bool", "self"]
|
|
2265
|
+
]
|
|
2266
|
+
|
|
2267
|
+
value = node.arg if node.arg not in reserved_keywords else f"<>{node.arg}"
|
|
2241
2268
|
name = ast.Name(
|
|
2242
2269
|
file_path=self.mod_path,
|
|
2243
2270
|
name=Tok.NAME,
|
|
2244
|
-
value=
|
|
2271
|
+
value=value,
|
|
2245
2272
|
line=node.lineno,
|
|
2246
2273
|
end_line=node.end_lineno if node.end_lineno else node.lineno,
|
|
2247
2274
|
col_start=node.col_offset,
|
|
@@ -162,6 +162,13 @@ class PyJacAstLinkPass(Pass):
|
|
|
162
162
|
py_nodes=node.parent.signature.return_type.gen.py_ast,
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
+
if isinstance(node.decl_link, ast.Ability) and isinstance(
|
|
166
|
+
node.target, ast.ArchRefChain
|
|
167
|
+
):
|
|
168
|
+
for arch in node.target.archs:
|
|
169
|
+
if arch.arch_name.sym:
|
|
170
|
+
arch.arch_name.sym.add_use(arch.arch_name)
|
|
171
|
+
|
|
165
172
|
def exit_param_var(self, node: ast.ParamVar) -> None:
|
|
166
173
|
"""Sub objects.
|
|
167
174
|
|
|
@@ -13,7 +13,7 @@ import jaclang.compiler.absyntree as ast
|
|
|
13
13
|
from jaclang.compiler.constant import Constants as Con
|
|
14
14
|
from jaclang.compiler.passes import Pass
|
|
15
15
|
from jaclang.compiler.semtable import SemInfo, SemRegistry
|
|
16
|
-
from jaclang.
|
|
16
|
+
from jaclang.runtimelib.utils import get_sem_scope
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class RegistryPass(Pass):
|
|
@@ -46,6 +46,7 @@ class RegistryPass(Pass):
|
|
|
46
46
|
"""Save architype information."""
|
|
47
47
|
scope = get_sem_scope(node)
|
|
48
48
|
seminfo = SemInfo(
|
|
49
|
+
node,
|
|
49
50
|
node.name.value,
|
|
50
51
|
node.arch_type.value,
|
|
51
52
|
node.semstr.lit_value if node.semstr else "",
|
|
@@ -61,7 +62,7 @@ class RegistryPass(Pass):
|
|
|
61
62
|
"""Save enum information."""
|
|
62
63
|
scope = get_sem_scope(node)
|
|
63
64
|
seminfo = SemInfo(
|
|
64
|
-
node.name.value, "Enum", node.semstr.lit_value if node.semstr else ""
|
|
65
|
+
node, node.name.value, "Enum", node.semstr.lit_value if node.semstr else ""
|
|
65
66
|
)
|
|
66
67
|
if (
|
|
67
68
|
len(self.modules_visited)
|
|
@@ -77,6 +78,38 @@ class RegistryPass(Pass):
|
|
|
77
78
|
)
|
|
78
79
|
scope = get_sem_scope(node)
|
|
79
80
|
seminfo = SemInfo(
|
|
81
|
+
node,
|
|
82
|
+
node.name.value,
|
|
83
|
+
extracted_type,
|
|
84
|
+
node.semstr.lit_value if node.semstr else "",
|
|
85
|
+
)
|
|
86
|
+
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
87
|
+
self.modules_visited[-1].registry.add(scope, seminfo)
|
|
88
|
+
|
|
89
|
+
def exit_ability(self, node: ast.Ability) -> None:
|
|
90
|
+
"""Save ability information."""
|
|
91
|
+
scope = get_sem_scope(node)
|
|
92
|
+
seminfo = SemInfo(
|
|
93
|
+
node,
|
|
94
|
+
node.name_ref.sym_name,
|
|
95
|
+
"Ability",
|
|
96
|
+
node.semstr.lit_value if node.semstr else "",
|
|
97
|
+
)
|
|
98
|
+
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
99
|
+
(
|
|
100
|
+
self.modules_visited[-1].registry.add(scope.parent, seminfo)
|
|
101
|
+
if scope.parent
|
|
102
|
+
else None
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def exit_param_var(self, node: ast.ParamVar) -> None:
|
|
106
|
+
"""Save param information."""
|
|
107
|
+
scope = get_sem_scope(node)
|
|
108
|
+
extracted_type = (
|
|
109
|
+
"".join(self.extract_type(node.type_tag.tag)) if node.type_tag else None
|
|
110
|
+
)
|
|
111
|
+
seminfo = SemInfo(
|
|
112
|
+
node,
|
|
80
113
|
node.name.value,
|
|
81
114
|
extracted_type,
|
|
82
115
|
node.semstr.lit_value if node.semstr else "",
|
|
@@ -94,6 +127,7 @@ class RegistryPass(Pass):
|
|
|
94
127
|
)
|
|
95
128
|
scope = get_sem_scope(node)
|
|
96
129
|
seminfo = SemInfo(
|
|
130
|
+
node,
|
|
97
131
|
(
|
|
98
132
|
node.target.items[0].value
|
|
99
133
|
if isinstance(node.target.items[0], ast.Name)
|
|
@@ -113,7 +147,7 @@ class RegistryPass(Pass):
|
|
|
113
147
|
and node.parent.parent.__class__.__name__ == "Enum"
|
|
114
148
|
):
|
|
115
149
|
scope = get_sem_scope(node)
|
|
116
|
-
seminfo = SemInfo(node.value, None, "")
|
|
150
|
+
seminfo = SemInfo(node, node.value, None, "")
|
|
117
151
|
if len(self.modules_visited) and self.modules_visited[-1].registry:
|
|
118
152
|
self.modules_visited[-1].registry.add(scope, seminfo)
|
|
119
153
|
|
|
@@ -19,11 +19,11 @@ from .type_check_pass import JacTypeCheckPass # noqa: I100
|
|
|
19
19
|
from .fuse_typeinfo_pass import FuseTypeInfoPass # noqa: I100
|
|
20
20
|
from .registry_pass import RegistryPass # noqa: I100
|
|
21
21
|
from .access_modifier_pass import AccessCheckPass # noqa: I100
|
|
22
|
+
from .py_collect_dep_pass import PyCollectDepsPass # noqa: I100
|
|
22
23
|
|
|
23
24
|
py_code_gen = [
|
|
24
25
|
SubNodeTabPass,
|
|
25
26
|
JacImportPass,
|
|
26
|
-
PyImportPass,
|
|
27
27
|
SymTabBuildPass,
|
|
28
28
|
DeclImplMatchPass,
|
|
29
29
|
DefUsePass,
|
|
@@ -33,6 +33,13 @@ py_code_gen = [
|
|
|
33
33
|
PyBytecodeGenPass,
|
|
34
34
|
]
|
|
35
35
|
|
|
36
|
-
type_checker_sched = [
|
|
36
|
+
type_checker_sched = [
|
|
37
|
+
JacTypeCheckPass,
|
|
38
|
+
PyCollectDepsPass,
|
|
39
|
+
PyImportPass,
|
|
40
|
+
DefUsePass,
|
|
41
|
+
FuseTypeInfoPass,
|
|
42
|
+
AccessCheckPass,
|
|
43
|
+
]
|
|
37
44
|
py_code_gen_typed = [*py_code_gen, *type_checker_sched]
|
|
38
45
|
py_compiler = [*py_code_gen, PyOutPass]
|
|
@@ -19,12 +19,16 @@ class SymTabBuildPass(Pass):
|
|
|
19
19
|
"""Before pass."""
|
|
20
20
|
self.cur_sym_tab: list[SymbolTable] = []
|
|
21
21
|
|
|
22
|
-
def push_scope(self, name: str, key_node: ast.AstNode
|
|
22
|
+
def push_scope(self, name: str, key_node: ast.AstNode) -> None:
|
|
23
23
|
"""Push scope."""
|
|
24
|
-
|
|
24
|
+
inherit = key_node.parent
|
|
25
|
+
if not len(self.cur_sym_tab) and not inherit:
|
|
25
26
|
self.cur_sym_tab.append(SymbolTable(name, key_node))
|
|
27
|
+
elif not len(self.cur_sym_tab) and inherit:
|
|
28
|
+
self.cur_sym_tab.append(inherit.sym_tab)
|
|
29
|
+
self.cur_sym_tab.append(self.cur_scope.push_kid_scope(name, key_node))
|
|
26
30
|
else:
|
|
27
|
-
self.cur_sym_tab.append(self.cur_scope.
|
|
31
|
+
self.cur_sym_tab.append(self.cur_scope.push_kid_scope(name, key_node))
|
|
28
32
|
|
|
29
33
|
def pop_scope(self) -> SymbolTable:
|
|
30
34
|
"""Pop scope."""
|
|
@@ -48,7 +52,7 @@ class SymTabBuildPass(Pass):
|
|
|
48
52
|
mod_path: str,
|
|
49
53
|
is_imported: bool,
|
|
50
54
|
"""
|
|
51
|
-
self.push_scope(node.name, node
|
|
55
|
+
self.push_scope(node.name, node)
|
|
52
56
|
self.sync_node_to_scope(node)
|
|
53
57
|
for obj in dir(builtins):
|
|
54
58
|
builtin = ast.Name(
|
|
@@ -193,11 +197,11 @@ class SymTabBuildPass(Pass):
|
|
|
193
197
|
if not node.is_absorb:
|
|
194
198
|
for i in node.items.items:
|
|
195
199
|
i.sym_tab.def_insert(i, single_decl="import item")
|
|
196
|
-
elif node.is_absorb and node.
|
|
200
|
+
elif node.is_absorb and node.is_jac:
|
|
197
201
|
source = node.items.items[0]
|
|
198
202
|
if not isinstance(source, ast.ModulePath) or not source.sub_module:
|
|
199
203
|
self.error(
|
|
200
|
-
f"Module {node.from_loc.
|
|
204
|
+
f"Module {node.from_loc.dot_path_str if node.from_loc else 'from location'}"
|
|
201
205
|
f" not found to include *, or ICE occurred!"
|
|
202
206
|
)
|
|
203
207
|
else:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Various tests for Jac passes."""
|
|
File without changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import:py math;
|
|
2
|
+
import:py argparse;
|
|
3
|
+
import:py from pygame_mock { color, display }
|
|
4
|
+
import:py pygame_mock;
|
|
5
|
+
import:py os;
|
|
6
|
+
|
|
7
|
+
can fool_me -> `Type[pygame_mock.constants.CL] {
|
|
8
|
+
return pygame_mock.constants.CL;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
obj kk {
|
|
12
|
+
can fool_me -> `Type[pygame_mock.constants.CL] {
|
|
13
|
+
return pygame_mock.constants.CL;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
with entry {
|
|
18
|
+
b = math.floor(1.7);
|
|
19
|
+
c: color.Color = color.Color(pygame_mock.constants.CONST_VALUE);
|
|
20
|
+
c2: pygame_mock.color.Color = color.Color(pygame_mock.constants.CL.CONST_VALUE2);
|
|
21
|
+
c3: pygame_mock.color.Color = color.Color(fool_me().CONST_VALUE2);
|
|
22
|
+
c4: pygame_mock.color.Color = color.Color(kk().fool_me().CONST_VALUE2);
|
|
23
|
+
g = fool_me();
|
|
24
|
+
c4: pygame_mock.color.Color = color.Color(g.CONST_VALUE2);
|
|
25
|
+
a: argparse.ArgumentParser = argparse.ArgumentParser();
|
|
26
|
+
print("Hello", 1, b);
|
|
27
|
+
pygame_mock.display.set_mode(WIN_WIDTH, WIN_HEIGHT);
|
|
28
|
+
print(os.path.isfile("/jj"));
|
|
29
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
|
+
import io
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
|
|
3
7
|
import jaclang.compiler.absyntree as ast
|
|
8
|
+
from jaclang.cli import cli
|
|
4
9
|
from jaclang.compiler.compile import jac_file_to_pass
|
|
5
10
|
from jaclang.compiler.passes.main import JacImportPass
|
|
11
|
+
from jaclang.compiler.passes.main.fuse_typeinfo_pass import FuseTypeInfoPass
|
|
12
|
+
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
6
13
|
from jaclang.utils.test import TestCase
|
|
7
14
|
|
|
8
15
|
|
|
@@ -24,7 +31,7 @@ class ImportPassPassTests(TestCase):
|
|
|
24
31
|
state = jac_file_to_pass(self.fixture_abs_path("autoimpl.jac"), JacImportPass)
|
|
25
32
|
num_modules = len(state.ir.get_all_sub_nodes(ast.Module))
|
|
26
33
|
mod_names = [i.name for i in state.ir.get_all_sub_nodes(ast.Module)]
|
|
27
|
-
self.assertEqual(num_modules,
|
|
34
|
+
self.assertEqual(num_modules, 4)
|
|
28
35
|
self.assertIn("getme.impl", mod_names)
|
|
29
36
|
self.assertIn("autoimpl.impl", mod_names)
|
|
30
37
|
self.assertIn("autoimpl.something.else.impl", mod_names)
|
|
@@ -36,7 +43,7 @@ class ImportPassPassTests(TestCase):
|
|
|
36
43
|
)
|
|
37
44
|
num_modules = len(state.ir.get_all_sub_nodes(ast.Module))
|
|
38
45
|
mod_names = [i.name for i in state.ir.get_all_sub_nodes(ast.Module)]
|
|
39
|
-
self.assertEqual(num_modules,
|
|
46
|
+
self.assertEqual(num_modules, 5)
|
|
40
47
|
self.assertIn("getme.impl", mod_names)
|
|
41
48
|
self.assertIn("autoimpl", mod_names)
|
|
42
49
|
self.assertIn("autoimpl.impl", mod_names)
|
|
@@ -52,17 +59,69 @@ class ImportPassPassTests(TestCase):
|
|
|
52
59
|
if i.name != "autoimpl":
|
|
53
60
|
count += 1
|
|
54
61
|
self.assertEqual(i.annexable_by, self.fixture_abs_path("autoimpl.jac"))
|
|
55
|
-
self.assertEqual(count,
|
|
62
|
+
self.assertEqual(count, 4)
|
|
63
|
+
|
|
64
|
+
def test_py_raise_map(self) -> None:
|
|
65
|
+
"""Basic test for pass."""
|
|
66
|
+
build = jac_file_to_pass(
|
|
67
|
+
self.fixture_abs_path("py_imp_test.jac"),
|
|
68
|
+
FuseTypeInfoPass,
|
|
69
|
+
schedule=py_code_gen_typed,
|
|
70
|
+
)
|
|
71
|
+
assert isinstance(build.ir, ast.Module)
|
|
72
|
+
p = {
|
|
73
|
+
"math": "jaclang/jaclang/vendor/mypy/typeshed/stdlib/math.pyi",
|
|
74
|
+
"pygame_mock": "pygame_mock/__init__.py",
|
|
75
|
+
"pygame_mock.color": "pygame_mock/color.py",
|
|
76
|
+
"pygame_mock.constants": "pygame_mock/constants.py",
|
|
77
|
+
"argparse": "jaclang/vendor/mypy/typeshed/stdlib/argparse.pyi",
|
|
78
|
+
"builtins": "jaclang/vendor/mypy/typeshed/stdlib/builtins.pyi",
|
|
79
|
+
"pygame_mock.display": "pygame_mock/display.py",
|
|
80
|
+
"os": "jaclang/vendor/mypy/typeshed/stdlib/os/__init__.pyi",
|
|
81
|
+
"genericpath": "jaclang/vendor/mypy/typeshed/stdlib/genericpath.pyi",
|
|
82
|
+
}
|
|
83
|
+
for i in p:
|
|
84
|
+
self.assertIn(i, build.ir.py_raise_map)
|
|
85
|
+
self.assertIn(p[i], re.sub(r".*fixtures/", "", build.ir.py_raise_map[i]))
|
|
56
86
|
|
|
57
|
-
def
|
|
87
|
+
def test_py_raised_mods(self) -> None:
|
|
58
88
|
"""Basic test for pass."""
|
|
59
|
-
state
|
|
60
|
-
self.
|
|
61
|
-
|
|
89
|
+
state = jac_file_to_pass(
|
|
90
|
+
self.fixture_abs_path("py_imp_test.jac"), schedule=py_code_gen_typed
|
|
91
|
+
)
|
|
92
|
+
self.assertEqual(
|
|
93
|
+
len(
|
|
94
|
+
list(
|
|
95
|
+
filter(
|
|
96
|
+
lambda x: x.is_raised_from_py,
|
|
97
|
+
state.ir.get_all_sub_nodes(ast.Module),
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
),
|
|
101
|
+
7,
|
|
62
102
|
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
103
|
+
|
|
104
|
+
# def test_py_resolve_list(self) -> None:
|
|
105
|
+
# """Basic test for pass."""
|
|
106
|
+
# state: JacImportPass = jac_file_to_pass(
|
|
107
|
+
# self.examples_abs_path("rpg_game/jac_impl/jac_impl_5/main.jac"),
|
|
108
|
+
# JacImportPass,
|
|
109
|
+
# )
|
|
110
|
+
# self.assertGreater(len(state.py_resolve_list), 20)
|
|
111
|
+
# self.assertIn("pygame.sprite.Sprite.__init__", state.py_resolve_list)
|
|
112
|
+
# self.assertIn("pygame.mouse.get_pressed", state.py_resolve_list)
|
|
113
|
+
# self.assertIn("pygame.K_SPACE", state.py_resolve_list)
|
|
114
|
+
# self.assertIn("random.randint", state.py_resolve_list)
|
|
115
|
+
# self.assertIn("pygame.font.Font", state.py_resolve_list)
|
|
116
|
+
|
|
117
|
+
def test_double_empty_anx(self) -> None:
|
|
118
|
+
"""Test importing python."""
|
|
119
|
+
captured_output = io.StringIO()
|
|
120
|
+
sys.stdout = captured_output
|
|
121
|
+
cli.run(self.fixture_abs_path("autoimpl.jac"))
|
|
122
|
+
cli.run(self.fixture_abs_path("autoimpl.jac"))
|
|
123
|
+
sys.stdout = sys.__stdout__
|
|
124
|
+
stdout_value = captured_output.getvalue()
|
|
125
|
+
self.assertIn("foo", stdout_value)
|
|
126
|
+
self.assertIn("bar", stdout_value)
|
|
127
|
+
self.assertIn("baz", stdout_value)
|
|
@@ -8,7 +8,6 @@ import os
|
|
|
8
8
|
import pathlib
|
|
9
9
|
import sys
|
|
10
10
|
|
|
11
|
-
# import jaclang
|
|
12
11
|
import jaclang.compiler.absyntree as ast
|
|
13
12
|
import jaclang.compiler.passes.utils.mypy_ast_build as myab
|
|
14
13
|
from jaclang.compiler.constant import Constants as Con
|
|
@@ -35,7 +34,7 @@ class JacTypeCheckPass(Pass):
|
|
|
35
34
|
def after_pass(self) -> None:
|
|
36
35
|
"""Call mypy api after traversing all the modules."""
|
|
37
36
|
try:
|
|
38
|
-
self.api()
|
|
37
|
+
self.api(os.path.dirname(self.ir.loc.mod_path))
|
|
39
38
|
except Exception as e:
|
|
40
39
|
self.error(f"Unable to run type checking: {e}")
|
|
41
40
|
return super().after_pass()
|
|
@@ -45,11 +44,21 @@ class JacTypeCheckPass(Pass):
|
|
|
45
44
|
) -> None:
|
|
46
45
|
"""Mypy errors reporter."""
|
|
47
46
|
|
|
48
|
-
def api(self) -> None:
|
|
47
|
+
def api(self, top_module_path: str = "") -> None:
|
|
49
48
|
"""Call mypy APIs to implement type checking in Jac."""
|
|
50
49
|
# Creating mypy api objects
|
|
51
50
|
options = myab.myb.Options()
|
|
51
|
+
options.ignore_missing_imports = True
|
|
52
52
|
options.cache_dir = Con.JAC_MYPY_CACHE
|
|
53
|
+
options.mypy_path = [
|
|
54
|
+
str(
|
|
55
|
+
pathlib.Path(os.path.dirname(__file__)).parent.parent.parent.parent
|
|
56
|
+
/ "stubs"
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
if top_module_path != "":
|
|
60
|
+
options.mypy_path.append(top_module_path)
|
|
61
|
+
|
|
53
62
|
errors = myab.Errors(self, options)
|
|
54
63
|
fs_cache = myab.FileSystemCache()
|
|
55
64
|
search_paths = myab.compute_search_paths([], options, str(self.__path))
|
|
@@ -94,7 +103,9 @@ class JacTypeCheckPass(Pass):
|
|
|
94
103
|
mypy_graph[module.name] = st
|
|
95
104
|
new_modules.append(st)
|
|
96
105
|
|
|
97
|
-
|
|
106
|
+
if not isinstance(self.ir, ast.Module):
|
|
107
|
+
raise self.ice("Expected module node. Impossible")
|
|
108
|
+
mypy_graph = myab.load_graph(
|
|
98
109
|
[
|
|
99
110
|
myab.BuildSource(
|
|
100
111
|
path=str(self.__path / "typeshed" / "stdlib" / "builtins.pyi"),
|
|
@@ -105,4 +116,10 @@ class JacTypeCheckPass(Pass):
|
|
|
105
116
|
old_graph=mypy_graph,
|
|
106
117
|
new_modules=new_modules, # To parse the dependancies of modules
|
|
107
118
|
)
|
|
108
|
-
|
|
119
|
+
for i in mypy_graph:
|
|
120
|
+
self.ir.py_mod_dep_map[i] = mypy_graph[i].xpath
|
|
121
|
+
for j in mypy_graph[i].dependencies:
|
|
122
|
+
self.ir.py_mod_dep_map[j] = str(
|
|
123
|
+
myab.find_module_with_reason(j, manager)
|
|
124
|
+
)
|
|
125
|
+
myab.process_graph(mypy_graph, manager)
|