jaclang 0.7.17__py3-none-any.whl → 0.7.21__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 +5 -7
- jaclang/compiler/absyntree.py +1 -1
- jaclang/compiler/jac.lark +14 -14
- jaclang/compiler/parser.py +71 -59
- jaclang/compiler/passes/ir_pass.py +2 -0
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +50 -13
- jaclang/compiler/passes/main/import_pass.py +29 -1
- jaclang/compiler/passes/main/py_collect_dep_pass.py +8 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +25 -0
- jaclang/compiler/passes/main/registry_pass.py +4 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +0 -18
- jaclang/compiler/passes/main/tests/fixtures/mod_type_assign.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.pyi +3 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +10 -10
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +23 -1
- jaclang/compiler/passes/main/type_check_pass.py +4 -4
- jaclang/compiler/passes/tool/jac_formatter_pass.py +63 -31
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/line_spacing.jac +57 -0
- jaclang/compiler/semtable.py +4 -4
- jaclang/compiler/symtable.py +5 -0
- jaclang/langserve/engine.py +92 -22
- jaclang/langserve/tests/fixtures/import_include_statements.jac +3 -3
- jaclang/langserve/tests/test_server.py +11 -7
- jaclang/langserve/utils.py +11 -213
- jaclang/plugin/builtin.py +8 -4
- jaclang/plugin/default.py +17 -3
- jaclang/plugin/feature.py +10 -0
- jaclang/plugin/spec.py +12 -0
- jaclang/plugin/tests/test_jaseci.py +23 -4
- jaclang/runtimelib/architype.py +20 -2
- jaclang/runtimelib/importer.py +4 -0
- jaclang/runtimelib/machine.py +92 -4
- jaclang/runtimelib/memory.py +7 -7
- jaclang/settings.py +4 -0
- jaclang/tests/fixtures/bar.jac +1 -1
- jaclang/tests/fixtures/builtin_dotgen.jac +1 -0
- jaclang/tests/fixtures/builtins_test.jac +16 -0
- jaclang/tests/fixtures/dynamic_architype.jac +34 -0
- jaclang/tests/fixtures/entry_exit.jac +36 -0
- jaclang/tests/fixtures/foo.jac +0 -1
- jaclang/tests/fixtures/match_multi_ex.jac +12 -0
- jaclang/tests/fixtures/objref.jac +12 -0
- jaclang/tests/fixtures/trailing_comma.jac +88 -0
- jaclang/tests/fixtures/walker_update.jac +19 -0
- jaclang/tests/test_cli.py +29 -2
- jaclang/tests/test_language.py +144 -4
- jaclang/utils/treeprinter.py +1 -1
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/METADATA +6 -2
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/RECORD +53 -43
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/WHEEL +0 -0
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/entry_points.txt +0 -0
|
@@ -14,6 +14,7 @@ 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
16
|
from jaclang.runtimelib.utils import get_sem_scope
|
|
17
|
+
from jaclang.settings import settings
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class RegistryPass(Pass):
|
|
@@ -23,6 +24,9 @@ class RegistryPass(Pass):
|
|
|
23
24
|
|
|
24
25
|
def enter_module(self, node: ast.Module) -> None:
|
|
25
26
|
"""Create registry for each module."""
|
|
27
|
+
if settings.disable_mtllm:
|
|
28
|
+
self.terminate()
|
|
29
|
+
return None
|
|
26
30
|
node.registry = SemRegistry()
|
|
27
31
|
self.modules_visited.append(node)
|
|
28
32
|
|
|
@@ -4,10 +4,7 @@ This pass builds the symbol table tree for the Jaseci Ast. It also adds symbols
|
|
|
4
4
|
for globals, imports, architypes, and abilities declarations and definitions.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import builtins
|
|
8
|
-
|
|
9
7
|
import jaclang.compiler.absyntree as ast
|
|
10
|
-
from jaclang.compiler.constant import Tokens as Tok
|
|
11
8
|
from jaclang.compiler.passes import Pass
|
|
12
9
|
from jaclang.compiler.symtable import SymbolTable
|
|
13
10
|
|
|
@@ -54,21 +51,6 @@ class SymTabBuildPass(Pass):
|
|
|
54
51
|
"""
|
|
55
52
|
self.push_scope(node.name, node)
|
|
56
53
|
self.sync_node_to_scope(node)
|
|
57
|
-
for obj in dir(builtins):
|
|
58
|
-
builtin = ast.Name(
|
|
59
|
-
file_path=node.loc.mod_path,
|
|
60
|
-
name=Tok.NAME,
|
|
61
|
-
value=str(obj),
|
|
62
|
-
line=0,
|
|
63
|
-
end_line=0,
|
|
64
|
-
col_start=0,
|
|
65
|
-
col_end=0,
|
|
66
|
-
pos_start=0,
|
|
67
|
-
pos_end=0,
|
|
68
|
-
)
|
|
69
|
-
self.sync_node_to_scope(builtin)
|
|
70
|
-
builtin.sym_tab.def_insert(builtin)
|
|
71
|
-
# self.def_insert(ast.Name.gen_stub_from_node(node.name, "root"))
|
|
72
54
|
|
|
73
55
|
def exit_module(self, node: ast.Module) -> None:
|
|
74
56
|
"""Sub objects.
|
|
@@ -70,19 +70,19 @@ class ImportPassPassTests(TestCase):
|
|
|
70
70
|
)
|
|
71
71
|
assert isinstance(build.ir, ast.Module)
|
|
72
72
|
p = {
|
|
73
|
-
"math": "jaclang/
|
|
74
|
-
"pygame_mock": "pygame_mock/__init__.
|
|
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",
|
|
73
|
+
"math": r"jaclang/vendor/mypy/typeshed/stdlib/math.pyi$",
|
|
74
|
+
"pygame_mock": r"pygame_mock/__init__.pyi$",
|
|
75
|
+
"pygame_mock.color": r"pygame_mock/color.py$",
|
|
76
|
+
"pygame_mock.constants": r"pygame_mock/constants.py$",
|
|
77
|
+
"argparse": r"jaclang/vendor/mypy/typeshed/stdlib/argparse.pyi$",
|
|
78
|
+
"builtins": r"jaclang/vendor/mypy/typeshed/stdlib/builtins.pyi$",
|
|
79
|
+
"pygame_mock.display": r"pygame_mock/display.py$",
|
|
80
|
+
"os": r"jaclang/vendor/mypy/typeshed/stdlib/os/__init__.pyi$",
|
|
81
|
+
"genericpath": r"jaclang/vendor/mypy/typeshed/stdlib/genericpath.pyi$",
|
|
82
82
|
}
|
|
83
83
|
for i in p:
|
|
84
84
|
self.assertIn(i, build.ir.py_raise_map)
|
|
85
|
-
self.
|
|
85
|
+
self.assertRegex(re.sub(r".*fixtures/", "", build.ir.py_raise_map[i]), p[i])
|
|
86
86
|
|
|
87
87
|
def test_py_raised_mods(self) -> None:
|
|
88
88
|
"""Basic test for pass."""
|
|
@@ -59,6 +59,6 @@ class MypyTypeCheckPassTests(TestCase):
|
|
|
59
59
|
self.assertIn("HasVar - species - Type: builtins.str", out)
|
|
60
60
|
self.assertIn("myDog - Type: type_info.Dog", out)
|
|
61
61
|
self.assertIn("Body - Type: type_info.Dog.Body", out)
|
|
62
|
-
self.assertEqual(out.count("Type: builtins.str"),
|
|
62
|
+
self.assertEqual(out.count("Type: builtins.str"), 34)
|
|
63
63
|
for i in lis:
|
|
64
64
|
self.assertNotIn(i, out)
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
"""Test pass module."""
|
|
2
2
|
|
|
3
|
+
from jaclang.compiler.compile import jac_file_to_pass
|
|
4
|
+
from jaclang.compiler.passes.main.fuse_typeinfo_pass import FuseTypeInfoPass
|
|
5
|
+
from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
3
6
|
from jaclang.utils.test import TestCase
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
class TestFuseTypeInfo(TestCase):
|
|
7
|
-
"""Test
|
|
10
|
+
"""Test FuseTypeInfoPass module."""
|
|
11
|
+
|
|
12
|
+
def setUp(self) -> None:
|
|
13
|
+
"""Set up test."""
|
|
14
|
+
return super().setUp()
|
|
15
|
+
|
|
16
|
+
def test_mod_type_assign(self) -> None:
|
|
17
|
+
"""Test module type assignment."""
|
|
18
|
+
gen_ast = jac_file_to_pass(
|
|
19
|
+
self.fixture_abs_path("mod_type_assign.jac"),
|
|
20
|
+
FuseTypeInfoPass,
|
|
21
|
+
schedule=py_code_gen_typed,
|
|
22
|
+
).ir.pp()
|
|
23
|
+
type_info_list = [
|
|
24
|
+
"kl - Type: types.ModuleType, SymbolTable: blip",
|
|
25
|
+
"l1 - Type: types.ModuleType, SymbolTable: blip",
|
|
26
|
+
"l2 - Type: types.ModuleType, SymbolTable: blip",
|
|
27
|
+
]
|
|
28
|
+
for type_info in type_info_list:
|
|
29
|
+
self.assertIn(type_info, str(gen_ast))
|
|
@@ -51,10 +51,10 @@ class JacTypeCheckPass(Pass):
|
|
|
51
51
|
options.ignore_missing_imports = True
|
|
52
52
|
options.cache_dir = Con.JAC_MYPY_CACHE
|
|
53
53
|
options.mypy_path = [
|
|
54
|
-
str(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
54
|
+
# str( # TODO: Remove me, this was the wrong way to point to stubs
|
|
55
|
+
# pathlib.Path(os.path.dirname(__file__)).parent.parent.parent.parent
|
|
56
|
+
# / "stubs"
|
|
57
|
+
# )
|
|
58
58
|
]
|
|
59
59
|
if top_module_path != "":
|
|
60
60
|
options.mypy_path.append(top_module_path)
|
|
@@ -126,11 +126,14 @@ class JacFormatPass(Pass):
|
|
|
126
126
|
last_element = None
|
|
127
127
|
for counter, i in enumerate(node.body):
|
|
128
128
|
counter += 1
|
|
129
|
+
if last_element and (
|
|
130
|
+
i.loc.first_line - last_element.loc.last_line > 1
|
|
131
|
+
and not last_element.gen.jac.endswith("\n\n")
|
|
132
|
+
):
|
|
133
|
+
self.emit_ln(node, "")
|
|
129
134
|
if isinstance(i, ast.Import):
|
|
130
135
|
self.emit_ln(node, i.gen.jac)
|
|
131
136
|
else:
|
|
132
|
-
if isinstance(last_element, ast.Import):
|
|
133
|
-
self.emit_ln(node, "")
|
|
134
137
|
if last_element and (
|
|
135
138
|
isinstance(i, ast.Architype)
|
|
136
139
|
and isinstance(last_element, ast.Architype)
|
|
@@ -140,21 +143,6 @@ class JacFormatPass(Pass):
|
|
|
140
143
|
self.emit_ln(node, "")
|
|
141
144
|
self.emit_ln(node, i.gen.jac)
|
|
142
145
|
|
|
143
|
-
if counter <= len(node.body) - 1:
|
|
144
|
-
if (
|
|
145
|
-
isinstance(i, ast.Ability)
|
|
146
|
-
and isinstance(node.body[counter], ast.Ability)
|
|
147
|
-
and i.gen.jac.endswith(";")
|
|
148
|
-
or (
|
|
149
|
-
isinstance(i, ast.Architype)
|
|
150
|
-
and len(node.body[counter].kid[-1].kid) == 2
|
|
151
|
-
and len(node.body[counter - 1].kid[-1].kid) == 2
|
|
152
|
-
)
|
|
153
|
-
and node.gen.jac.endswith("\n")
|
|
154
|
-
):
|
|
155
|
-
self.emit(node, "")
|
|
156
|
-
else:
|
|
157
|
-
self.emit_ln(node, "")
|
|
158
146
|
last_element = i
|
|
159
147
|
|
|
160
148
|
def exit_global_vars(self, node: ast.GlobalVars) -> None:
|
|
@@ -222,6 +210,20 @@ class JacFormatPass(Pass):
|
|
|
222
210
|
"""
|
|
223
211
|
prev_token = None
|
|
224
212
|
for stmt in node.kid:
|
|
213
|
+
line_emiited = False
|
|
214
|
+
if prev_token and stmt.loc.first_line - prev_token.loc.last_line > 1:
|
|
215
|
+
if (
|
|
216
|
+
stmt.kid
|
|
217
|
+
and isinstance(stmt.kid[-1], ast.SubNodeList)
|
|
218
|
+
and not isinstance(stmt.kid[-1].kid[-1], ast.CommentToken)
|
|
219
|
+
):
|
|
220
|
+
self.emit(node, "")
|
|
221
|
+
|
|
222
|
+
else:
|
|
223
|
+
line_emiited = True
|
|
224
|
+
self.indent_level -= 1
|
|
225
|
+
self.emit_ln(node, "")
|
|
226
|
+
self.indent_level += 1
|
|
225
227
|
if isinstance(node.parent, (ast.EnumDef, ast.Enum)) and stmt.gen.jac == ",":
|
|
226
228
|
self.indent_level -= 1
|
|
227
229
|
self.emit_ln(node, f"{stmt.gen.jac}")
|
|
@@ -266,9 +268,10 @@ class JacFormatPass(Pass):
|
|
|
266
268
|
self.indent_level += 1
|
|
267
269
|
else:
|
|
268
270
|
self.emit(node, f" {stmt.gen.jac}")
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
271
|
+
if not line_emiited:
|
|
272
|
+
self.indent_level -= 1
|
|
273
|
+
self.emit_ln(node, "")
|
|
274
|
+
self.indent_level += 1
|
|
272
275
|
else:
|
|
273
276
|
if not node.gen.jac.endswith("\n"):
|
|
274
277
|
self.indent_level -= 1
|
|
@@ -279,12 +282,21 @@ class JacFormatPass(Pass):
|
|
|
279
282
|
if prev_token and isinstance(prev_token, ast.Ability):
|
|
280
283
|
self.emit(node, f"{stmt.gen.jac}")
|
|
281
284
|
else:
|
|
282
|
-
self.
|
|
283
|
-
if
|
|
285
|
+
token_before = self.token_before(stmt)
|
|
286
|
+
if (
|
|
287
|
+
token_before is not None
|
|
288
|
+
and isinstance(token_before, ast.Token)
|
|
289
|
+
and token_before.name == Tok.LBRACE
|
|
290
|
+
and stmt.loc.first_line - token_before.loc.last_line > 1
|
|
291
|
+
):
|
|
284
292
|
self.indent_level -= 1
|
|
285
|
-
self.emit_ln(stmt, "")
|
|
286
293
|
self.emit_ln(node, "")
|
|
287
294
|
self.indent_level += 1
|
|
295
|
+
self.emit(node, stmt.gen.jac)
|
|
296
|
+
self.indent_level -= 1
|
|
297
|
+
self.emit_ln(stmt, "")
|
|
298
|
+
self.emit_ln(node, "")
|
|
299
|
+
self.indent_level += 1
|
|
288
300
|
elif stmt.gen.jac == ",":
|
|
289
301
|
self.emit(node, f"{stmt.value} ")
|
|
290
302
|
elif stmt.value == "=":
|
|
@@ -304,10 +316,29 @@ class JacFormatPass(Pass):
|
|
|
304
316
|
isinstance(prev_token, ast.Ability)
|
|
305
317
|
and isinstance(stmt, (ast.Ability, ast.AbilityDef))
|
|
306
318
|
):
|
|
307
|
-
if
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
319
|
+
if (
|
|
320
|
+
not isinstance(prev_token.kid[-1], ast.CommentToken)
|
|
321
|
+
and not line_emiited
|
|
322
|
+
):
|
|
323
|
+
if (
|
|
324
|
+
prev_token.kid
|
|
325
|
+
and isinstance(prev_token.kid[-1], ast.SubNodeList)
|
|
326
|
+
and isinstance(prev_token.kid[-1].kid[-1], ast.CommentToken)
|
|
327
|
+
):
|
|
328
|
+
if (
|
|
329
|
+
prev_token
|
|
330
|
+
and stmt.loc.first_line - prev_token.kid[-1].kid[-1].line_no
|
|
331
|
+
> 1
|
|
332
|
+
):
|
|
333
|
+
self.indent_level -= 1
|
|
334
|
+
self.emit_ln(node, "")
|
|
335
|
+
self.indent_level += 1
|
|
336
|
+
else:
|
|
337
|
+
self.emit(node, "")
|
|
338
|
+
else:
|
|
339
|
+
self.indent_level -= 1
|
|
340
|
+
self.emit_ln(node, "")
|
|
341
|
+
self.indent_level += 1
|
|
311
342
|
self.emit(node, stmt.gen.jac)
|
|
312
343
|
else:
|
|
313
344
|
if prev_token and prev_token.gen.jac.strip() == "{":
|
|
@@ -373,7 +404,9 @@ class JacFormatPass(Pass):
|
|
|
373
404
|
indented = True
|
|
374
405
|
for count, j in enumerate(i.kid):
|
|
375
406
|
if j.gen.jac == ",":
|
|
376
|
-
if i.kid
|
|
407
|
+
if len(i.kid) > count + 1 and i.kid[
|
|
408
|
+
count + 1
|
|
409
|
+
].gen.jac.startswith("#"):
|
|
377
410
|
self.indent_level -= 1
|
|
378
411
|
self.emit(node, f"{j.gen.jac} ")
|
|
379
412
|
self.indent_level += 1
|
|
@@ -907,8 +940,6 @@ class JacFormatPass(Pass):
|
|
|
907
940
|
"""Check if the length of the current generated code exceeds the max line length."""
|
|
908
941
|
if max_line_length == 0:
|
|
909
942
|
max_line_length = self.MAX_LINE_LENGTH
|
|
910
|
-
# print(content)
|
|
911
|
-
# print(len(content))
|
|
912
943
|
return len(content) > max_line_length
|
|
913
944
|
|
|
914
945
|
def exit_binary_expr(self, node: ast.BinaryExpr) -> None:
|
|
@@ -958,7 +989,6 @@ class JacFormatPass(Pass):
|
|
|
958
989
|
self.error(
|
|
959
990
|
f"Binary operator {node.op.value} not supported in bootstrap Jac"
|
|
960
991
|
)
|
|
961
|
-
# print(node.gen)
|
|
962
992
|
if isinstance(
|
|
963
993
|
node.kid[-1], (ast.Semi, ast.CommentToken)
|
|
964
994
|
) and not node.gen.jac.endswith("\n"):
|
|
@@ -1562,6 +1592,8 @@ class JacFormatPass(Pass):
|
|
|
1562
1592
|
self.emit(node, f"not {node.operand.gen.jac}")
|
|
1563
1593
|
elif node.op.name in [Tok.PIPE_FWD, Tok.KW_SPAWN, Tok.A_PIPE_FWD]:
|
|
1564
1594
|
self.emit(node, f"{node.op.value} {node.operand.gen.jac}")
|
|
1595
|
+
elif node.op.name in [Tok.BW_AND]:
|
|
1596
|
+
self.emit(node, f"{node.op.value}{node.operand.gen.jac}")
|
|
1565
1597
|
else:
|
|
1566
1598
|
self.error(f"Unary operator {node.op.value} not supported in bootstrap Jac")
|
|
1567
1599
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import:py math;
|
|
2
|
+
|
|
3
|
+
glob RAD = 5;
|
|
4
|
+
|
|
5
|
+
glob DIA = 10;
|
|
6
|
+
|
|
7
|
+
# this comment is for walker
|
|
8
|
+
|
|
9
|
+
walker decorator_walk {
|
|
10
|
+
can hash(func: Any) {
|
|
11
|
+
can inner(a: Any) {
|
|
12
|
+
print(("#" * 20));
|
|
13
|
+
func(a);
|
|
14
|
+
print(("#" * 20));
|
|
15
|
+
}
|
|
16
|
+
return inner;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
can exclaim(func: Any) {
|
|
20
|
+
can inner(b: Any) {
|
|
21
|
+
print(("!" * 20));
|
|
22
|
+
func(b);
|
|
23
|
+
print(("!" * 20));
|
|
24
|
+
}
|
|
25
|
+
return inner;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
can tilde(func: Any) {
|
|
29
|
+
can inner(c: Any) {
|
|
30
|
+
print(("~" * 20));
|
|
31
|
+
func(c);
|
|
32
|
+
print(("~" * 20));
|
|
33
|
+
}
|
|
34
|
+
return inner;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
can greeter(name: Any) {
|
|
38
|
+
print("Hello, " + name + "!");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Entry point for the walker
|
|
42
|
+
|
|
43
|
+
can start with entry {
|
|
44
|
+
|
|
45
|
+
# Apply decorators to greeter
|
|
46
|
+
decorated_greeter = hash(exclaim(tilde(greeter)));
|
|
47
|
+
|
|
48
|
+
# Call the decorated greeter function
|
|
49
|
+
decorated_greeter("World");
|
|
50
|
+
|
|
51
|
+
# this is another comment
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
with entry {
|
|
56
|
+
root spawn decorator_walk();
|
|
57
|
+
}
|
jaclang/compiler/semtable.py
CHANGED
|
@@ -19,13 +19,13 @@ class SemInfo:
|
|
|
19
19
|
self,
|
|
20
20
|
node: ast.AstNode,
|
|
21
21
|
name: str,
|
|
22
|
-
|
|
22
|
+
type_str: Optional[str] = None,
|
|
23
23
|
semstr: str = "",
|
|
24
24
|
) -> None:
|
|
25
25
|
"""Initialize the class."""
|
|
26
|
-
self.
|
|
26
|
+
self.node_type = type(node)
|
|
27
27
|
self.name = name
|
|
28
|
-
self.type =
|
|
28
|
+
self.type = type_str
|
|
29
29
|
self.semstr = semstr
|
|
30
30
|
|
|
31
31
|
def __repr__(self) -> str:
|
|
@@ -40,7 +40,7 @@ class SemInfo:
|
|
|
40
40
|
self_scope = str(scope) + f".{self.name}({self.type})"
|
|
41
41
|
_, children = sem_registry.lookup(scope=SemScope.get_scope_from_str(self_scope))
|
|
42
42
|
if filter and children and isinstance(children, list):
|
|
43
|
-
return [i for i in children if
|
|
43
|
+
return [i for i in children if i.node_type == filter]
|
|
44
44
|
return children if children and isinstance(children, list) else []
|
|
45
45
|
|
|
46
46
|
|
jaclang/compiler/symtable.py
CHANGED
|
@@ -54,6 +54,11 @@ class Symbol:
|
|
|
54
54
|
out.reverse()
|
|
55
55
|
return ".".join(out)
|
|
56
56
|
|
|
57
|
+
@property
|
|
58
|
+
def fetch_sym_tab(self) -> Optional[SymbolTable]:
|
|
59
|
+
"""Get symbol table."""
|
|
60
|
+
return self.parent_tab.find_scope(self.sym_name)
|
|
61
|
+
|
|
57
62
|
def add_defn(self, node: ast.NameAtom) -> None:
|
|
58
63
|
"""Add defn."""
|
|
59
64
|
self.defn.append(node)
|
jaclang/langserve/engine.py
CHANGED
|
@@ -22,11 +22,9 @@ from jaclang.langserve.utils import (
|
|
|
22
22
|
find_deepest_symbol_node_at_pos,
|
|
23
23
|
find_index,
|
|
24
24
|
gen_diagnostics,
|
|
25
|
-
|
|
26
|
-
get_mod_path,
|
|
25
|
+
get_location_range,
|
|
27
26
|
get_symbols_for_outline,
|
|
28
27
|
parse_symbol_path,
|
|
29
|
-
resolve_completion_symbol_table,
|
|
30
28
|
)
|
|
31
29
|
from jaclang.vendor.pygls import uris
|
|
32
30
|
from jaclang.vendor.pygls.server import LanguageServer
|
|
@@ -189,14 +187,73 @@ class JacLangServer(LanguageServer):
|
|
|
189
187
|
if not node_selected
|
|
190
188
|
else node_selected.sym_tab
|
|
191
189
|
)
|
|
192
|
-
current_tab = self.modules[file_path].ir._sym_tab
|
|
193
190
|
current_symbol_table = mod_tab
|
|
194
191
|
|
|
195
192
|
if completion_trigger == ".":
|
|
196
193
|
if current_symbol_path:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
194
|
+
temp_tab = mod_tab
|
|
195
|
+
for symbol in current_symbol_path:
|
|
196
|
+
if symbol == "self":
|
|
197
|
+
is_ability_def = (
|
|
198
|
+
temp_tab.owner
|
|
199
|
+
if isinstance(temp_tab.owner, ast.AbilityDef)
|
|
200
|
+
else temp_tab.owner.find_parent_of_type(ast.AbilityDef)
|
|
201
|
+
)
|
|
202
|
+
if not is_ability_def:
|
|
203
|
+
archi_owner = mod_tab.owner.find_parent_of_type(
|
|
204
|
+
ast.Architype
|
|
205
|
+
)
|
|
206
|
+
temp_tab = (
|
|
207
|
+
archi_owner._sym_tab
|
|
208
|
+
if archi_owner and archi_owner._sym_tab
|
|
209
|
+
else mod_tab
|
|
210
|
+
)
|
|
211
|
+
continue
|
|
212
|
+
else:
|
|
213
|
+
archi_owner = (
|
|
214
|
+
(
|
|
215
|
+
is_ability_def.decl_link.find_parent_of_type(
|
|
216
|
+
ast.Architype
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
if is_ability_def.decl_link
|
|
220
|
+
else None
|
|
221
|
+
)
|
|
222
|
+
temp_tab = (
|
|
223
|
+
archi_owner.sym_tab
|
|
224
|
+
if archi_owner and archi_owner.sym_tab
|
|
225
|
+
else temp_tab
|
|
226
|
+
)
|
|
227
|
+
continue
|
|
228
|
+
symb = temp_tab.lookup(symbol)
|
|
229
|
+
if symb:
|
|
230
|
+
fetc_tab = symb.fetch_sym_tab
|
|
231
|
+
if fetc_tab:
|
|
232
|
+
temp_tab = fetc_tab
|
|
233
|
+
else:
|
|
234
|
+
temp_tab = (
|
|
235
|
+
symb.defn[0].type_sym_tab
|
|
236
|
+
if symb.defn[0].type_sym_tab
|
|
237
|
+
else temp_tab
|
|
238
|
+
)
|
|
239
|
+
else:
|
|
240
|
+
break
|
|
241
|
+
completion_items = collect_all_symbols_in_scope(temp_tab, up_tree=False)
|
|
242
|
+
if (
|
|
243
|
+
isinstance(temp_tab.owner, ast.Architype)
|
|
244
|
+
and temp_tab.owner.base_classes
|
|
245
|
+
):
|
|
246
|
+
base = []
|
|
247
|
+
for base_name in temp_tab.owner.base_classes.items:
|
|
248
|
+
if isinstance(base_name, ast.Name) and base_name.sym:
|
|
249
|
+
base.append(base_name.sym)
|
|
250
|
+
for base_class_symbol in base:
|
|
251
|
+
if base_class_symbol.fetch_sym_tab:
|
|
252
|
+
completion_items += collect_all_symbols_in_scope(
|
|
253
|
+
base_class_symbol.fetch_sym_tab,
|
|
254
|
+
up_tree=False,
|
|
255
|
+
)
|
|
256
|
+
|
|
200
257
|
else:
|
|
201
258
|
completion_items = []
|
|
202
259
|
else:
|
|
@@ -335,8 +392,9 @@ class JacLangServer(LanguageServer):
|
|
|
335
392
|
and node_selected.parent
|
|
336
393
|
and isinstance(node_selected.parent, ast.ModulePath)
|
|
337
394
|
):
|
|
338
|
-
spec =
|
|
395
|
+
spec = node_selected.parent.abs_path
|
|
339
396
|
if spec:
|
|
397
|
+
spec = spec[5:] if spec.startswith("File:") else spec
|
|
340
398
|
return lspt.Location(
|
|
341
399
|
uri=uris.from_fs_path(spec),
|
|
342
400
|
range=lspt.Range(
|
|
@@ -349,20 +407,32 @@ class JacLangServer(LanguageServer):
|
|
|
349
407
|
elif node_selected.parent and isinstance(
|
|
350
408
|
node_selected.parent, ast.ModuleItem
|
|
351
409
|
):
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
410
|
+
path = (
|
|
411
|
+
node_selected.parent.abs_path
|
|
412
|
+
or node_selected.parent.from_mod_path.abs_path
|
|
413
|
+
)
|
|
414
|
+
try: # TODO: Get rid of this when 'from' import is fixed
|
|
415
|
+
loc_range = tuple(
|
|
416
|
+
loc - 1 if loc > 0 else loc
|
|
417
|
+
for loc in get_location_range(node_selected.parent)
|
|
418
|
+
)
|
|
419
|
+
except ValueError:
|
|
420
|
+
loc_range = (0, 0, 0, 0)
|
|
421
|
+
|
|
422
|
+
if path and loc_range:
|
|
423
|
+
path = path[5:] if path.startswith("File:") else path
|
|
424
|
+
return lspt.Location(
|
|
425
|
+
uri=uris.from_fs_path(path),
|
|
426
|
+
range=lspt.Range(
|
|
427
|
+
start=lspt.Position(
|
|
428
|
+
line=loc_range[0], character=loc_range[1]
|
|
361
429
|
),
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
430
|
+
end=lspt.Position(
|
|
431
|
+
line=loc_range[2], character=loc_range[3]
|
|
432
|
+
),
|
|
433
|
+
),
|
|
434
|
+
)
|
|
435
|
+
elif isinstance(node_selected, ast.ElementStmt):
|
|
366
436
|
return None
|
|
367
437
|
decl_node = (
|
|
368
438
|
node_selected.parent.body.target
|
|
@@ -378,7 +448,7 @@ class JacLangServer(LanguageServer):
|
|
|
378
448
|
decl_uri = uris.from_fs_path(decl_node.loc.mod_path)
|
|
379
449
|
try:
|
|
380
450
|
decl_range = create_range(decl_node.loc)
|
|
381
|
-
except ValueError:
|
|
451
|
+
except ValueError:
|
|
382
452
|
return None
|
|
383
453
|
decl_location = lspt.Location(
|
|
384
454
|
uri=decl_uri,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import:py os;
|
|
2
|
-
import:py from math
|
|
2
|
+
import:py from math{ sqrt as square_root}
|
|
3
3
|
import:py datetime as dt;
|
|
4
|
-
import:jac from base_module_structure
|
|
4
|
+
import:jac from base_module_structure{ add as add_numbers , subtract,x,Colorenum as clr}
|
|
5
5
|
import:jac base_module_structure as base_module_structure;
|
|
6
|
-
import:py from py_import
|
|
6
|
+
import:py from py_import{add1 as ss, sub1 as subtract1,apple,Orange1}
|
|
@@ -187,11 +187,15 @@ class TestJacLangServer(TestCase):
|
|
|
187
187
|
)
|
|
188
188
|
lsp.deep_check(import_file)
|
|
189
189
|
positions = [
|
|
190
|
-
(
|
|
190
|
+
(0, 12, "tdlib/os/__init__.pyi:0:0-0:0"),
|
|
191
|
+
(1, 18, "stdlib/math.pyi:0:0-0:0"),
|
|
192
|
+
(2, 24, "datetime.pyi:0:0-0:0"),
|
|
191
193
|
(3, 17, "base_module_structure.jac:0:0-0:0"),
|
|
192
|
-
(3, 87, "base_module_structure.jac:23:
|
|
193
|
-
(5, 65, "py_import.py:
|
|
194
|
-
(5, 35, "py_import.py:
|
|
194
|
+
(3, 87, "base_module_structure.jac:23:5-23:14"),
|
|
195
|
+
(5, 65, "py_import.py:0:0-0:0"),
|
|
196
|
+
(5, 35, "py_import.py:0:0-0:0"),
|
|
197
|
+
# (5, 65, "py_import.py:12:0-20:5"), # TODO : Should work after 'from' import files are raised
|
|
198
|
+
# (5, 35, "py_import.py:3:0-4:5"),
|
|
195
199
|
]
|
|
196
200
|
|
|
197
201
|
for line, char, expected in positions:
|
|
@@ -214,9 +218,9 @@ class TestJacLangServer(TestCase):
|
|
|
214
218
|
)
|
|
215
219
|
lsp.deep_check(import_file)
|
|
216
220
|
positions = [
|
|
217
|
-
(6, 39, "/pygame_mock/__init__.
|
|
221
|
+
(6, 39, "/pygame_mock/__init__.pyi:2:0-2:0"),
|
|
218
222
|
(6, 45, "/pygame_mock/constants.py:3:0-4:1"),
|
|
219
|
-
(7, 31, "/pygame_mock/__init__.
|
|
223
|
+
(7, 31, "/pygame_mock/__init__.pyi:2:0-2:0"),
|
|
220
224
|
(7, 35, "/pygame_mock/constants.py:3:0-4:1"),
|
|
221
225
|
(20, 51, "/py_imp_test.jac:6:4-6:11"),
|
|
222
226
|
(20, 64, "/pygame_mock/constants.py:4:3-4:15"),
|
|
@@ -278,7 +282,7 @@ class TestJacLangServer(TestCase):
|
|
|
278
282
|
),
|
|
279
283
|
(
|
|
280
284
|
"<JacSemTokenType.FUNCTION: 12>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
281
|
-
|
|
285
|
+
8,
|
|
282
286
|
),
|
|
283
287
|
("<JacSemTokenType.METHOD: 13>, <JacSemTokenModifier.DECLARATION: 1>", 6),
|
|
284
288
|
("<JacSemTokenType.ENUM: 3>, <JacSemTokenModifier.DECLARATION: 1>,", 4),
|