jaclang 0.7.19__py3-none-any.whl → 0.7.20__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/compiler/absyntree.py +1 -1
- jaclang/compiler/parser.py +1 -1
- 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 +27 -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/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +23 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +10 -0
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/line_spacing.jac +3 -1
- jaclang/compiler/semtable.py +4 -4
- jaclang/compiler/symtable.py +5 -0
- jaclang/langserve/engine.py +64 -6
- jaclang/langserve/tests/test_server.py +1 -1
- jaclang/langserve/utils.py +0 -113
- jaclang/plugin/tests/test_jaseci.py +23 -4
- jaclang/runtimelib/importer.py +2 -0
- jaclang/runtimelib/memory.py +1 -1
- jaclang/stubs/jaclang/__init__.pyi +5 -0
- jaclang/stubs/jaclang/cli/__init__.pyi +0 -0
- jaclang/stubs/jaclang/cli/cli.pyi +58 -0
- jaclang/stubs/jaclang/cli/cmdreg.pyi +32 -0
- jaclang/stubs/jaclang/compiler/__init__.pyi +6 -0
- jaclang/stubs/jaclang/compiler/absyntree.pyi +1248 -0
- jaclang/stubs/jaclang/compiler/codeloc.pyi +45 -0
- jaclang/stubs/jaclang/compiler/compile.pyi +29 -0
- jaclang/stubs/jaclang/compiler/constant.pyi +287 -0
- jaclang/stubs/jaclang/compiler/generated/__init__.pyi +0 -0
- jaclang/stubs/jaclang/compiler/generated/jac_parser.pyi +898 -0
- jaclang/stubs/jaclang/compiler/parser.pyi +266 -0
- jaclang/stubs/jaclang/compiler/passes/__init__.pyi +3 -0
- jaclang/stubs/jaclang/compiler/passes/ir_pass.pyi +40 -0
- jaclang/stubs/jaclang/compiler/passes/main/__init__.pyi +27 -0
- jaclang/stubs/jaclang/compiler/passes/main/access_modifier_pass.pyi +23 -0
- jaclang/stubs/jaclang/compiler/passes/main/def_impl_match_pass.pyi +12 -0
- jaclang/stubs/jaclang/compiler/passes/main/def_use_pass.pyi +31 -0
- jaclang/stubs/jaclang/compiler/passes/main/fuse_typeinfo_pass.pyi +66 -0
- jaclang/stubs/jaclang/compiler/passes/main/import_pass.pyi +34 -0
- jaclang/stubs/jaclang/compiler/passes/main/pyast_gen_pass.pyi +178 -0
- jaclang/stubs/jaclang/compiler/passes/main/pyast_load_pass.pyi +135 -0
- jaclang/stubs/jaclang/compiler/passes/main/pybc_gen_pass.pyi +6 -0
- jaclang/stubs/jaclang/compiler/passes/main/pyjac_ast_link_pass.pyi +22 -0
- jaclang/stubs/jaclang/compiler/passes/main/pyout_pass.pyi +9 -0
- jaclang/stubs/jaclang/compiler/passes/main/registry_pass.pyi +15 -0
- jaclang/stubs/jaclang/compiler/passes/main/schedules.pyi +19 -0
- jaclang/stubs/jaclang/compiler/passes/main/sub_node_tab_pass.pyi +6 -0
- jaclang/stubs/jaclang/compiler/passes/main/sym_tab_build_pass.pyi +147 -0
- jaclang/stubs/jaclang/compiler/passes/main/type_check_pass.pyi +11 -0
- jaclang/stubs/jaclang/compiler/passes/tool/__init__.pyi +4 -0
- jaclang/stubs/jaclang/compiler/passes/tool/fuse_comments_pass.pyi +12 -0
- jaclang/stubs/jaclang/compiler/passes/tool/jac_formatter_pass.pyi +134 -0
- jaclang/stubs/jaclang/compiler/passes/tool/schedules.pyi +11 -0
- jaclang/stubs/jaclang/compiler/passes/transform.pyi +28 -0
- jaclang/stubs/jaclang/compiler/passes/utils/__init__.pyi +0 -0
- jaclang/stubs/jaclang/compiler/passes/utils/mypy_ast_build.pyi +151 -0
- jaclang/stubs/jaclang/compiler/semtable.pyi +35 -0
- jaclang/stubs/jaclang/compiler/symtable.pyi +65 -0
- jaclang/stubs/jaclang/langserve/__init__.pyi +0 -0
- jaclang/stubs/jaclang/langserve/engine.pyi +73 -0
- jaclang/stubs/jaclang/langserve/sem_manager.pyi +89 -0
- jaclang/stubs/jaclang/langserve/server.pyi +38 -0
- jaclang/stubs/jaclang/langserve/utils.pyi +55 -0
- jaclang/stubs/jaclang/plugin/__init__.pyi +3 -0
- jaclang/stubs/jaclang/plugin/builtin.pyi +12 -0
- jaclang/stubs/jaclang/plugin/default.pyi +202 -0
- jaclang/stubs/jaclang/plugin/feature.pyi +176 -0
- jaclang/stubs/jaclang/plugin/spec.pyi +181 -0
- jaclang/stubs/jaclang/runtimelib/__init__.pyi +0 -0
- jaclang/stubs/jaclang/runtimelib/architype.pyi +133 -0
- jaclang/stubs/jaclang/runtimelib/constructs.pyi +41 -0
- jaclang/stubs/jaclang/runtimelib/context.pyi +48 -0
- jaclang/stubs/jaclang/runtimelib/importer.pyi +104 -0
- jaclang/stubs/jaclang/runtimelib/machine.pyi +6 -0
- jaclang/stubs/jaclang/runtimelib/memory.pyi +26 -0
- jaclang/stubs/jaclang/runtimelib/utils.pyi +35 -0
- jaclang/stubs/jaclang/settings.pyi +35 -0
- jaclang/stubs/jaclang/utils/__init__.pyi +0 -0
- jaclang/stubs/jaclang/utils/helpers.pyi +18 -0
- jaclang/stubs/jaclang/utils/lang_tools.pyi +43 -0
- jaclang/stubs/jaclang/utils/log.pyi +3 -0
- jaclang/stubs/jaclang/utils/treeprinter.pyi +47 -0
- jaclang/tests/fixtures/builtins_test.jac +16 -0
- jaclang/tests/fixtures/match_multi_ex.jac +12 -0
- jaclang/tests/test_cli.py +29 -2
- jaclang/tests/test_language.py +10 -0
- jaclang/utils/treeprinter.py +1 -1
- {jaclang-0.7.19.dist-info → jaclang-0.7.20.dist-info}/METADATA +1 -1
- {jaclang-0.7.19.dist-info → jaclang-0.7.20.dist-info}/RECORD +91 -25
- {jaclang-0.7.19.dist-info → jaclang-0.7.20.dist-info}/WHEEL +0 -0
- {jaclang-0.7.19.dist-info → jaclang-0.7.20.dist-info}/entry_points.txt +0 -0
jaclang/compiler/absyntree.py
CHANGED
jaclang/compiler/parser.py
CHANGED
|
@@ -3587,7 +3587,7 @@ class JacParser(Pass):
|
|
|
3587
3587
|
match_case_block: KW_CASE pattern_seq (KW_IF expression)? COLON statement_list
|
|
3588
3588
|
"""
|
|
3589
3589
|
pattern = kid[1]
|
|
3590
|
-
guard = kid[3] if
|
|
3590
|
+
guard = kid[3] if isinstance(kid[3], ast.Expr) else None
|
|
3591
3591
|
stmts = [i for i in kid if isinstance(i, ast.CodeBlockStmt)]
|
|
3592
3592
|
if isinstance(pattern, ast.MatchPattern) and isinstance(
|
|
3593
3593
|
guard, (ast.Expr, type(None))
|
|
@@ -6,6 +6,7 @@ mypy apis into Jac and use jac py ast in it.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import re
|
|
9
10
|
from typing import Callable, Optional, TypeVar
|
|
10
11
|
|
|
11
12
|
import jaclang.compiler.absyntree as ast
|
|
@@ -46,24 +47,24 @@ class FuseTypeInfoPass(Pass):
|
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
|
|
49
|
-
typ = node.sym_type.split(".")
|
|
50
50
|
typ_sym_table = self.ir.sym_tab
|
|
51
|
+
assert isinstance(self.ir, ast.Module)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
sym_type = node.sym_type
|
|
54
|
+
if re.match(r"builtins.(list|dict|tuple)", sym_type):
|
|
55
|
+
sym_type = re.sub(r"\[.*\]", "", sym_type)
|
|
56
|
+
|
|
57
|
+
typ = sym_type.split(".")
|
|
54
58
|
|
|
55
59
|
if node.sym_type == "types.ModuleType" and node.sym:
|
|
56
60
|
node.name_spec.type_sym_tab = node.sym.parent_tab.find_scope(node.sym_name)
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
f = typ_sym_table.find_scope(i)
|
|
65
|
-
if f:
|
|
66
|
-
typ_sym_table = f
|
|
62
|
+
for i in typ:
|
|
63
|
+
if i == self.ir.name:
|
|
64
|
+
continue
|
|
65
|
+
f = typ_sym_table.find_scope(i)
|
|
66
|
+
if f:
|
|
67
|
+
typ_sym_table = f
|
|
67
68
|
|
|
68
69
|
if typ_sym_table != self.ir.sym_tab:
|
|
69
70
|
node.name_spec.type_sym_tab = typ_sym_table
|
|
@@ -144,6 +145,11 @@ class FuseTypeInfoPass(Pass):
|
|
|
144
145
|
self.__set_sym_table_link(node)
|
|
145
146
|
self.__collect_python_dependencies(node)
|
|
146
147
|
|
|
148
|
+
# Special handing for BuiltinType
|
|
149
|
+
elif isinstance(node, ast.BuiltinType):
|
|
150
|
+
func(self, node) # type: ignore
|
|
151
|
+
self.__set_sym_table_link(node)
|
|
152
|
+
|
|
147
153
|
# Jac node doesn't have mypy nodes linked to it
|
|
148
154
|
else:
|
|
149
155
|
self.__debug_print(
|
|
@@ -209,10 +215,21 @@ class FuseTypeInfoPass(Pass):
|
|
|
209
215
|
f"{type(mypy_node)}"
|
|
210
216
|
)
|
|
211
217
|
|
|
218
|
+
def __check_builltin_symbol(self, node: ast.NameAtom) -> None:
|
|
219
|
+
if isinstance(node.parent, ast.AtomTrailer) and node is node.parent.right:
|
|
220
|
+
return
|
|
221
|
+
builtins_sym_tab = self.ir.sym_tab.find_scope("builtins")
|
|
222
|
+
assert builtins_sym_tab is not None
|
|
223
|
+
builtins_sym = builtins_sym_tab.lookup(node.sym_name)
|
|
224
|
+
if builtins_sym:
|
|
225
|
+
node.name_spec._sym = builtins_sym
|
|
226
|
+
|
|
212
227
|
@__handle_node
|
|
213
228
|
def enter_name(self, node: ast.NameAtom) -> None:
|
|
214
229
|
"""Pass handler for name nodes."""
|
|
215
230
|
self.__collect_type_from_symbol(node)
|
|
231
|
+
if node.sym is None:
|
|
232
|
+
self.__check_builltin_symbol(node)
|
|
216
233
|
|
|
217
234
|
@__handle_node
|
|
218
235
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
@@ -423,7 +440,8 @@ class FuseTypeInfoPass(Pass):
|
|
|
423
440
|
@__handle_node
|
|
424
441
|
def enter_builtin_type(self, node: ast.BuiltinType) -> None:
|
|
425
442
|
"""Pass handler for BuiltinType nodes."""
|
|
426
|
-
self.
|
|
443
|
+
self.__check_builltin_symbol(node)
|
|
444
|
+
node.name_spec.sym_type = f"builtins.{node.sym_name}"
|
|
427
445
|
|
|
428
446
|
def get_type_from_instance(
|
|
429
447
|
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
|
|
@@ -483,6 +501,21 @@ class FuseTypeInfoPass(Pass):
|
|
|
483
501
|
if self_obj.type_sym_tab and isinstance(right_obj, ast.AstSymbolNode):
|
|
484
502
|
self_obj.type_sym_tab.def_insert(right_obj)
|
|
485
503
|
|
|
504
|
+
# Support adding the correct type symbol table in case of ModuleType
|
|
505
|
+
# This will only work for target=Val & target1=target2=val and
|
|
506
|
+
# target is a moduleType
|
|
507
|
+
# it won't work in case of
|
|
508
|
+
# - target1, target2 = Val1, Val2 <-- tuples need more attention
|
|
509
|
+
# - target = a.b.c <-- will be fixed after thakee's PR
|
|
510
|
+
# - a.b.c = val <-- will be fixed after thakee's PR
|
|
511
|
+
for target in node.target.items:
|
|
512
|
+
if (
|
|
513
|
+
isinstance(target, ast.Name)
|
|
514
|
+
and target.sym_type == "types.ModuleType"
|
|
515
|
+
and isinstance(node.value, ast.Name)
|
|
516
|
+
):
|
|
517
|
+
target.type_sym_tab = node.value.type_sym_tab
|
|
518
|
+
|
|
486
519
|
def expand_atom_trailer(self, node_list: list[ast.AstNode]) -> list[ast.AstNode]:
|
|
487
520
|
"""Expand the atom trailer object in a list of AstNode."""
|
|
488
521
|
out: list[ast.AstNode] = []
|
|
@@ -552,6 +585,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
552
585
|
type_symtab: Optional[SymbolTable] = self.ir.sym_tab
|
|
553
586
|
assert isinstance(self.ir, ast.Module)
|
|
554
587
|
assert isinstance(type_symtab, SymbolTable)
|
|
588
|
+
|
|
589
|
+
if re.match(r"builtins.(list|dict|tuple)", node_type):
|
|
590
|
+
node_type = re.sub(r"\[.*\]", "", node_type)
|
|
591
|
+
|
|
555
592
|
for j in node_type.split("."):
|
|
556
593
|
if j == self.ir.name:
|
|
557
594
|
continue
|
|
@@ -7,6 +7,7 @@ symbols are available for matching.
|
|
|
7
7
|
|
|
8
8
|
import ast as py_ast
|
|
9
9
|
import os
|
|
10
|
+
import pathlib
|
|
10
11
|
from typing import Optional
|
|
11
12
|
|
|
12
13
|
|
|
@@ -200,6 +201,7 @@ class PyImportPass(JacImportPass):
|
|
|
200
201
|
def before_pass(self) -> None:
|
|
201
202
|
"""Only run pass if settings are set to raise python."""
|
|
202
203
|
super().before_pass()
|
|
204
|
+
self.__load_builtins()
|
|
203
205
|
|
|
204
206
|
def __get_current_module(self, node: ast.AstNode) -> str:
|
|
205
207
|
parent = node.find_parent_of_type(ast.Module)
|
|
@@ -296,6 +298,31 @@ class PyImportPass(JacImportPass):
|
|
|
296
298
|
raise e
|
|
297
299
|
return None
|
|
298
300
|
|
|
301
|
+
def __load_builtins(self) -> None:
|
|
302
|
+
"""Pyraise builtins to help with builtins auto complete."""
|
|
303
|
+
from jaclang.compiler.passes.main import PyastBuildPass
|
|
304
|
+
|
|
305
|
+
assert isinstance(self.ir, ast.Module)
|
|
306
|
+
|
|
307
|
+
file_to_raise = str(
|
|
308
|
+
pathlib.Path(os.path.dirname(__file__)).parent.parent.parent
|
|
309
|
+
/ "vendor"
|
|
310
|
+
/ "mypy"
|
|
311
|
+
/ "typeshed"
|
|
312
|
+
/ "stdlib"
|
|
313
|
+
/ "builtins.pyi"
|
|
314
|
+
)
|
|
315
|
+
with open(file_to_raise, "r", encoding="utf-8") as f:
|
|
316
|
+
mod = PyastBuildPass(
|
|
317
|
+
input_ir=ast.PythonModuleAst(
|
|
318
|
+
py_ast.parse(f.read()), mod_path=file_to_raise
|
|
319
|
+
),
|
|
320
|
+
).ir
|
|
321
|
+
mod.parent = self.ir
|
|
322
|
+
SubNodeTabPass(input_ir=mod, prior=self)
|
|
323
|
+
SymTabBuildPass(input_ir=mod, prior=self)
|
|
324
|
+
mod.parent = None
|
|
325
|
+
|
|
299
326
|
def annex_impl(self, node: ast.Module) -> None:
|
|
300
327
|
"""Annex impl and test modules."""
|
|
301
328
|
return None
|
|
@@ -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.
|
|
@@ -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))
|
|
@@ -282,6 +282,16 @@ class JacFormatPass(Pass):
|
|
|
282
282
|
if prev_token and isinstance(prev_token, ast.Ability):
|
|
283
283
|
self.emit(node, f"{stmt.gen.jac}")
|
|
284
284
|
else:
|
|
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
|
+
):
|
|
292
|
+
self.indent_level -= 1
|
|
293
|
+
self.emit_ln(node, "")
|
|
294
|
+
self.indent_level += 1
|
|
285
295
|
self.emit(node, stmt.gen.jac)
|
|
286
296
|
self.indent_level -= 1
|
|
287
297
|
self.emit_ln(stmt, "")
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import:py math;
|
|
2
2
|
|
|
3
3
|
glob RAD = 5;
|
|
4
|
+
|
|
4
5
|
glob DIA = 10;
|
|
5
6
|
|
|
6
7
|
# this comment is for walker
|
|
8
|
+
|
|
7
9
|
walker decorator_walk {
|
|
8
10
|
can hash(func: Any) {
|
|
9
11
|
can inner(a: Any) {
|
|
@@ -39,6 +41,7 @@ walker decorator_walk {
|
|
|
39
41
|
# Entry point for the walker
|
|
40
42
|
|
|
41
43
|
can start with entry {
|
|
44
|
+
|
|
42
45
|
# Apply decorators to greeter
|
|
43
46
|
decorated_greeter = hash(exclaim(tilde(greeter)));
|
|
44
47
|
|
|
@@ -46,7 +49,6 @@ walker decorator_walk {
|
|
|
46
49
|
decorated_greeter("World");
|
|
47
50
|
|
|
48
51
|
# this is another comment
|
|
49
|
-
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
|
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
|
@@ -25,7 +25,6 @@ from jaclang.langserve.utils import (
|
|
|
25
25
|
get_location_range,
|
|
26
26
|
get_symbols_for_outline,
|
|
27
27
|
parse_symbol_path,
|
|
28
|
-
resolve_completion_symbol_table,
|
|
29
28
|
)
|
|
30
29
|
from jaclang.vendor.pygls import uris
|
|
31
30
|
from jaclang.vendor.pygls.server import LanguageServer
|
|
@@ -188,14 +187,73 @@ class JacLangServer(LanguageServer):
|
|
|
188
187
|
if not node_selected
|
|
189
188
|
else node_selected.sym_tab
|
|
190
189
|
)
|
|
191
|
-
current_tab = self.modules[file_path].ir._sym_tab
|
|
192
190
|
current_symbol_table = mod_tab
|
|
193
191
|
|
|
194
192
|
if completion_trigger == ".":
|
|
195
193
|
if current_symbol_path:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
+
|
|
199
257
|
else:
|
|
200
258
|
completion_items = []
|
|
201
259
|
else:
|
|
@@ -374,7 +432,7 @@ class JacLangServer(LanguageServer):
|
|
|
374
432
|
),
|
|
375
433
|
),
|
|
376
434
|
)
|
|
377
|
-
elif isinstance(node_selected,
|
|
435
|
+
elif isinstance(node_selected, ast.ElementStmt):
|
|
378
436
|
return None
|
|
379
437
|
decl_node = (
|
|
380
438
|
node_selected.parent.body.target
|
|
@@ -282,7 +282,7 @@ class TestJacLangServer(TestCase):
|
|
|
282
282
|
),
|
|
283
283
|
(
|
|
284
284
|
"<JacSemTokenType.FUNCTION: 12>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
285
|
-
|
|
285
|
+
8,
|
|
286
286
|
),
|
|
287
287
|
("<JacSemTokenType.METHOD: 13>, <JacSemTokenModifier.DECLARATION: 1>", 6),
|
|
288
288
|
("<JacSemTokenType.ENUM: 3>, <JacSemTokenModifier.DECLARATION: 1>,", 4),
|
jaclang/langserve/utils.py
CHANGED
|
@@ -332,119 +332,6 @@ def parse_symbol_path(text: str, dot_position: int) -> list[str]:
|
|
|
332
332
|
return all_words
|
|
333
333
|
|
|
334
334
|
|
|
335
|
-
def resolve_symbol_path(sym_name: str, node_tab: SymbolTable) -> str:
|
|
336
|
-
"""Resolve symbol path."""
|
|
337
|
-
visited = set()
|
|
338
|
-
current_tab: Optional[SymbolTable] = node_tab
|
|
339
|
-
|
|
340
|
-
while current_tab is not None and current_tab not in visited:
|
|
341
|
-
visited.add(current_tab)
|
|
342
|
-
for name, symbol in current_tab.tab.items():
|
|
343
|
-
if name not in dir(builtins) and name == sym_name:
|
|
344
|
-
path = symbol.defn[0]._sym_type
|
|
345
|
-
if symbol.sym_type == SymbolType.ENUM_ARCH:
|
|
346
|
-
if isinstance(current_tab.owner, ast.Module):
|
|
347
|
-
return current_tab.owner.name + "." + sym_name
|
|
348
|
-
elif isinstance(current_tab.owner, ast.AstSymbolNode):
|
|
349
|
-
return current_tab.owner.name_spec._sym_type + "." + sym_name
|
|
350
|
-
return path
|
|
351
|
-
current_tab = current_tab.parent if current_tab.parent != current_tab else None
|
|
352
|
-
return ""
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
def find_symbol_table(path: str, current_tab: Optional[SymbolTable]) -> SymbolTable:
|
|
356
|
-
"""Find symbol table."""
|
|
357
|
-
path = path.lstrip(".")
|
|
358
|
-
current_table = current_tab
|
|
359
|
-
if current_table:
|
|
360
|
-
for segment in path.split("."):
|
|
361
|
-
current_table = next(
|
|
362
|
-
(
|
|
363
|
-
child_table
|
|
364
|
-
for child_table in current_table.kid
|
|
365
|
-
if child_table.name == segment
|
|
366
|
-
),
|
|
367
|
-
current_table,
|
|
368
|
-
)
|
|
369
|
-
if current_table:
|
|
370
|
-
return current_table
|
|
371
|
-
raise ValueError(f"Symbol table not found for path {path}")
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
def resolve_completion_symbol_table(
|
|
375
|
-
mod_tab: SymbolTable,
|
|
376
|
-
current_symbol_path: list[str],
|
|
377
|
-
current_tab: Optional[SymbolTable],
|
|
378
|
-
) -> list[lspt.CompletionItem]:
|
|
379
|
-
"""Resolve symbol table for completion items."""
|
|
380
|
-
current_symbol_table = mod_tab
|
|
381
|
-
for obj in current_symbol_path:
|
|
382
|
-
if obj == "self":
|
|
383
|
-
try:
|
|
384
|
-
try:
|
|
385
|
-
is_abilitydef = (
|
|
386
|
-
mod_tab.owner
|
|
387
|
-
if isinstance(mod_tab.owner, ast.AbilityDef)
|
|
388
|
-
else mod_tab.owner.parent_of_type(ast.AbilityDef)
|
|
389
|
-
)
|
|
390
|
-
archi_owner = (
|
|
391
|
-
(is_abilitydef.decl_link.parent_of_type(ast.Architype))
|
|
392
|
-
if is_abilitydef.decl_link
|
|
393
|
-
else None
|
|
394
|
-
)
|
|
395
|
-
current_symbol_table = (
|
|
396
|
-
archi_owner._sym_tab
|
|
397
|
-
if archi_owner and archi_owner._sym_tab
|
|
398
|
-
else mod_tab
|
|
399
|
-
)
|
|
400
|
-
continue
|
|
401
|
-
|
|
402
|
-
except ValueError:
|
|
403
|
-
pass
|
|
404
|
-
archi_owner = mod_tab.owner.parent_of_type(ast.Architype)
|
|
405
|
-
current_symbol_table = (
|
|
406
|
-
archi_owner._sym_tab
|
|
407
|
-
if archi_owner and archi_owner._sym_tab
|
|
408
|
-
else mod_tab
|
|
409
|
-
)
|
|
410
|
-
except ValueError:
|
|
411
|
-
pass
|
|
412
|
-
else:
|
|
413
|
-
path: str = resolve_symbol_path(obj, current_symbol_table)
|
|
414
|
-
if path:
|
|
415
|
-
current_symbol_table = find_symbol_table(path, current_tab)
|
|
416
|
-
else:
|
|
417
|
-
if (
|
|
418
|
-
isinstance(current_symbol_table.owner, ast.Architype)
|
|
419
|
-
and current_symbol_table.owner.base_classes
|
|
420
|
-
):
|
|
421
|
-
for base_name in current_symbol_table.owner.base_classes.items:
|
|
422
|
-
if isinstance(base_name, ast.Name) and base_name.sym:
|
|
423
|
-
path = base_name.sym.sym_dotted_name + "." + obj
|
|
424
|
-
current_symbol_table = find_symbol_table(path, current_tab)
|
|
425
|
-
if (
|
|
426
|
-
isinstance(current_symbol_table.owner, ast.Architype)
|
|
427
|
-
and current_symbol_table.owner.base_classes
|
|
428
|
-
):
|
|
429
|
-
base = []
|
|
430
|
-
for base_name in current_symbol_table.owner.base_classes.items:
|
|
431
|
-
if isinstance(base_name, ast.Name) and base_name.sym:
|
|
432
|
-
base.append(base_name.sym.sym_dotted_name)
|
|
433
|
-
for base_ in base:
|
|
434
|
-
completion_items = collect_all_symbols_in_scope(
|
|
435
|
-
find_symbol_table(base_, current_tab),
|
|
436
|
-
up_tree=False,
|
|
437
|
-
)
|
|
438
|
-
else:
|
|
439
|
-
completion_items = []
|
|
440
|
-
if isinstance(current_symbol_table.owner, (ast.Ability, ast.AbilityDef)):
|
|
441
|
-
return completion_items
|
|
442
|
-
completion_items.extend(
|
|
443
|
-
collect_all_symbols_in_scope(current_symbol_table, up_tree=False)
|
|
444
|
-
)
|
|
445
|
-
return completion_items
|
|
446
|
-
|
|
447
|
-
|
|
448
335
|
def get_token_start(
|
|
449
336
|
token_index: int | None, sem_tokens: list[int]
|
|
450
337
|
) -> tuple[int, int, int]:
|
|
@@ -337,8 +337,8 @@ class TestJaseciPlugin(TestCase):
|
|
|
337
337
|
|
|
338
338
|
# --------- NO UPDATE SHOULD HAPPEN -------- #
|
|
339
339
|
|
|
340
|
-
self.
|
|
341
|
-
self.
|
|
340
|
+
self.assertEqual(archs[0], "A(val=2)")
|
|
341
|
+
self.assertEqual(archs[1], "A(val=1)")
|
|
342
342
|
|
|
343
343
|
self._output2buffer()
|
|
344
344
|
cli.enter(
|
|
@@ -435,8 +435,8 @@ class TestJaseciPlugin(TestCase):
|
|
|
435
435
|
|
|
436
436
|
# --------- UPDATE SHOULD HAPPEN -------- #
|
|
437
437
|
|
|
438
|
-
self.
|
|
439
|
-
self.
|
|
438
|
+
self.assertEqual(archs[0], "A(val=20)")
|
|
439
|
+
self.assertEqual(archs[1], "A(val=10)")
|
|
440
440
|
|
|
441
441
|
self._output2buffer()
|
|
442
442
|
cli.enter(
|
|
@@ -474,6 +474,25 @@ class TestJaseciPlugin(TestCase):
|
|
|
474
474
|
)
|
|
475
475
|
self.assertFalse(self.capturedOutput.getvalue().strip())
|
|
476
476
|
|
|
477
|
+
# --------- ROOTS RESET OWN NODE -------- #
|
|
478
|
+
|
|
479
|
+
cli.enter(
|
|
480
|
+
filename=self.fixture_abs_path("other_root_access.jac"),
|
|
481
|
+
entrypoint="update_node",
|
|
482
|
+
args=[1],
|
|
483
|
+
session=session,
|
|
484
|
+
root=self.roots[0],
|
|
485
|
+
node=self.nodes[0],
|
|
486
|
+
)
|
|
487
|
+
cli.enter(
|
|
488
|
+
filename=self.fixture_abs_path("other_root_access.jac"),
|
|
489
|
+
entrypoint="update_node",
|
|
490
|
+
args=[2],
|
|
491
|
+
session=session,
|
|
492
|
+
root=self.roots[1],
|
|
493
|
+
node=self.nodes[1],
|
|
494
|
+
)
|
|
495
|
+
|
|
477
496
|
def test_other_root_access(self) -> None:
|
|
478
497
|
"""Test filtering on node, then visit."""
|
|
479
498
|
global session
|
jaclang/runtimelib/importer.py
CHANGED
|
@@ -195,6 +195,8 @@ class PythonImporter(Importer):
|
|
|
195
195
|
loaded_items: list = []
|
|
196
196
|
if spec.target.startswith("."):
|
|
197
197
|
spec.target = spec.target.lstrip(".")
|
|
198
|
+
if len(spec.target.split(".")) > 1:
|
|
199
|
+
spec.target = spec.target.split(".")[-1]
|
|
198
200
|
full_target = path.normpath(path.join(spec.caller_dir, spec.target))
|
|
199
201
|
imp_spec = importlib.util.spec_from_file_location(
|
|
200
202
|
spec.target, full_target + ".py"
|
jaclang/runtimelib/memory.py
CHANGED
|
@@ -106,7 +106,7 @@ class ShelfStorage(Memory[UUID, Anchor]):
|
|
|
106
106
|
if root.has_write_access(d):
|
|
107
107
|
if hash(dumps(p_d.access)) != hash(dumps(d.access)):
|
|
108
108
|
p_d.access = d.access
|
|
109
|
-
if hash(dumps(
|
|
109
|
+
if hash(dumps(p_d.architype)) != hash(dumps(d.architype)):
|
|
110
110
|
p_d.architype = d.architype
|
|
111
111
|
|
|
112
112
|
self.__shelf__[_id] = p_d
|
|
File without changes
|