jaclang 0.7.16__py3-none-any.whl → 0.7.18__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 +140 -77
- jaclang/compiler/absyntree.py +9 -4
- jaclang/compiler/constant.py +8 -8
- jaclang/compiler/parser.py +10 -2
- 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 +152 -50
- jaclang/compiler/passes/main/import_pass.py +88 -59
- jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +46 -6
- jaclang/compiler/passes/main/pyast_load_pass.py +1 -0
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
- jaclang/compiler/passes/main/schedules.py +9 -2
- jaclang/compiler/passes/main/sym_tab_build_pass.py +9 -5
- 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 +15 -5
- jaclang/compiler/passes/tool/jac_formatter_pass.py +13 -3
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -41
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
- jaclang/compiler/passes/utils/mypy_ast_build.py +45 -0
- jaclang/compiler/symtable.py +16 -11
- jaclang/compiler/tests/test_importer.py +17 -9
- jaclang/langserve/engine.py +64 -16
- jaclang/langserve/server.py +16 -1
- jaclang/langserve/tests/fixtures/import_include_statements.jac +3 -3
- jaclang/langserve/tests/fixtures/rename.jac +30 -0
- jaclang/langserve/tests/test_server.py +224 -6
- jaclang/langserve/utils.py +28 -98
- jaclang/plugin/builtin.py +8 -4
- jaclang/plugin/default.py +86 -64
- jaclang/plugin/feature.py +13 -13
- jaclang/plugin/spec.py +10 -11
- jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
- jaclang/plugin/tests/test_jaseci.py +414 -42
- jaclang/runtimelib/architype.py +481 -333
- jaclang/runtimelib/constructs.py +5 -8
- jaclang/runtimelib/context.py +89 -69
- jaclang/runtimelib/importer.py +16 -15
- jaclang/runtimelib/machine.py +66 -2
- jaclang/runtimelib/memory.py +134 -75
- jaclang/runtimelib/utils.py +17 -10
- jaclang/settings.py +2 -4
- 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/bar.jac +34 -0
- jaclang/tests/fixtures/builtin_dotgen.jac +1 -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/foo.jac +43 -0
- jaclang/tests/fixtures/game1.jac +1 -1
- jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
- jaclang/tests/fixtures/import.jac +9 -0
- jaclang/tests/fixtures/index_slice.jac +30 -0
- jaclang/tests/fixtures/objref.jac +12 -0
- jaclang/tests/fixtures/pyfunc_1.py +1 -1
- jaclang/tests/fixtures/pyfunc_2.py +2 -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/test_cli.py +49 -6
- jaclang/tests/test_language.py +126 -80
- jaclang/tests/test_reference.py +2 -9
- jaclang/utils/treeprinter.py +30 -3
- {jaclang-0.7.16.dist-info → jaclang-0.7.18.dist-info}/METADATA +3 -1
- {jaclang-0.7.16.dist-info → jaclang-0.7.18.dist-info}/RECORD +81 -59
- /jaclang/tests/fixtures/{err.test.jac → baddy.test.jac} +0 -0
- {jaclang-0.7.16.dist-info → jaclang-0.7.18.dist-info}/WHEEL +0 -0
- {jaclang-0.7.16.dist-info → jaclang-0.7.18.dist-info}/entry_points.txt +0 -0
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import ast
|
|
6
6
|
import os
|
|
7
|
+
from typing import Callable, TYPE_CHECKING, TextIO
|
|
7
8
|
|
|
8
9
|
from jaclang.compiler.absyntree import AstNode
|
|
9
10
|
from jaclang.compiler.passes import Pass
|
|
@@ -21,13 +22,19 @@ from mypy.build import FileSystemCache
|
|
|
21
22
|
from mypy.build import Graph
|
|
22
23
|
from mypy.build import ModuleNotFound
|
|
23
24
|
from mypy.build import PRI_INDIRECT
|
|
25
|
+
from mypy.build import Plugin
|
|
26
|
+
from mypy.build import SearchPaths
|
|
24
27
|
from mypy.build import compute_search_paths
|
|
25
28
|
from mypy.build import find_module_simple
|
|
29
|
+
from mypy.build import find_module_with_reason
|
|
26
30
|
from mypy.build import load_plugins
|
|
27
31
|
from mypy.build import process_graph
|
|
28
32
|
from mypy.options import Options
|
|
29
33
|
from mypy.semanal_main import semantic_analysis_for_scc
|
|
30
34
|
|
|
35
|
+
if TYPE_CHECKING:
|
|
36
|
+
from mypy.report import Reports # Avoid unconditional slow import
|
|
37
|
+
|
|
31
38
|
|
|
32
39
|
mypy_to_jac_node_map: dict[
|
|
33
40
|
tuple[int, int | None, int | None, int | None], list[AstNode]
|
|
@@ -37,6 +44,43 @@ mypy_to_jac_node_map: dict[
|
|
|
37
44
|
class BuildManager(myb.BuildManager):
|
|
38
45
|
"""Overrides to mypy build manager for direct AST pass through."""
|
|
39
46
|
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
data_dir: str,
|
|
50
|
+
search_paths: SearchPaths,
|
|
51
|
+
ignore_prefix: str,
|
|
52
|
+
source_set: BuildSourceSet,
|
|
53
|
+
reports: Reports | None,
|
|
54
|
+
options: Options,
|
|
55
|
+
version_id: str,
|
|
56
|
+
plugin: Plugin,
|
|
57
|
+
plugins_snapshot: dict[str, str],
|
|
58
|
+
errors: Errors,
|
|
59
|
+
flush_errors: Callable[[str | None, list[str], bool], None],
|
|
60
|
+
fscache: FileSystemCache,
|
|
61
|
+
stdout: TextIO,
|
|
62
|
+
stderr: TextIO,
|
|
63
|
+
) -> None:
|
|
64
|
+
"""Override mypy BuildManager constructor to initialize jac related map."""
|
|
65
|
+
global mypy_to_jac_node_map
|
|
66
|
+
super().__init__(
|
|
67
|
+
data_dir,
|
|
68
|
+
search_paths,
|
|
69
|
+
ignore_prefix,
|
|
70
|
+
source_set,
|
|
71
|
+
reports,
|
|
72
|
+
options,
|
|
73
|
+
version_id,
|
|
74
|
+
plugin,
|
|
75
|
+
plugins_snapshot,
|
|
76
|
+
errors,
|
|
77
|
+
flush_errors,
|
|
78
|
+
fscache,
|
|
79
|
+
stdout,
|
|
80
|
+
stderr,
|
|
81
|
+
)
|
|
82
|
+
mypy_to_jac_node_map = {}
|
|
83
|
+
|
|
40
84
|
def parse_file(
|
|
41
85
|
self,
|
|
42
86
|
id: str,
|
|
@@ -664,6 +708,7 @@ __all__ = [
|
|
|
664
708
|
"BuildSource",
|
|
665
709
|
"BuildSourceSet",
|
|
666
710
|
"FileSystemCache",
|
|
711
|
+
"find_module_with_reason",
|
|
667
712
|
"compute_search_paths",
|
|
668
713
|
"load_graph",
|
|
669
714
|
"load_plugins",
|
jaclang/compiler/symtable.py
CHANGED
|
@@ -137,7 +137,7 @@ class SymbolTable:
|
|
|
137
137
|
return k
|
|
138
138
|
return None
|
|
139
139
|
|
|
140
|
-
def
|
|
140
|
+
def push_kid_scope(self, name: str, key_node: ast.AstNode) -> SymbolTable:
|
|
141
141
|
"""Push a new scope onto the symbol table."""
|
|
142
142
|
self.kid.append(SymbolTable(name, key_node, self))
|
|
143
143
|
return self.kid[-1]
|
|
@@ -205,16 +205,21 @@ class SymbolTable:
|
|
|
205
205
|
for i in node_list:
|
|
206
206
|
if cur_sym_tab is None:
|
|
207
207
|
break
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
208
|
+
lookup = self.use_lookup(i, sym_table=cur_sym_tab)
|
|
209
|
+
if lookup:
|
|
210
|
+
cur_sym_tab = lookup.decl.sym_tab
|
|
211
|
+
|
|
212
|
+
# check if the symbol table name is not the same as symbol name
|
|
213
|
+
# then try to find a child scope with the same name
|
|
214
|
+
# This is used to get the scope in case of
|
|
215
|
+
# import:py math;
|
|
216
|
+
# b = math.floor(1.7);
|
|
217
|
+
if cur_sym_tab.name != i.sym_name:
|
|
218
|
+
t = cur_sym_tab.find_scope(i.sym_name)
|
|
219
|
+
if t:
|
|
220
|
+
cur_sym_tab = t
|
|
221
|
+
else:
|
|
222
|
+
cur_sym_tab = None
|
|
218
223
|
|
|
219
224
|
def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
|
|
220
225
|
"""Update python context for definition."""
|
|
@@ -5,29 +5,37 @@ import sys
|
|
|
5
5
|
|
|
6
6
|
from jaclang import jac_import
|
|
7
7
|
from jaclang.cli import cli
|
|
8
|
-
from jaclang.
|
|
8
|
+
from jaclang.runtimelib.machine import JacMachine, JacProgram
|
|
9
9
|
from jaclang.utils.test import TestCase
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class TestLoader(TestCase):
|
|
13
13
|
"""Test Jac self.prse."""
|
|
14
14
|
|
|
15
|
-
def setUp(self) -> None:
|
|
16
|
-
"""Set up test."""
|
|
17
|
-
return super().setUp()
|
|
18
|
-
|
|
19
15
|
def test_import_basic_python(self) -> None:
|
|
20
16
|
"""Test basic self loading."""
|
|
21
|
-
|
|
17
|
+
JacMachine(self.fixture_abs_path(__file__)).attach_program(
|
|
18
|
+
JacProgram(mod_bundle=None, bytecode=None)
|
|
19
|
+
)
|
|
22
20
|
(h,) = jac_import("fixtures.hello_world", base_path=__file__)
|
|
23
21
|
self.assertEqual(h.hello(), "Hello World!") # type: ignore
|
|
22
|
+
JacMachine.detach()
|
|
24
23
|
|
|
25
24
|
def test_modules_correct(self) -> None:
|
|
26
25
|
"""Test basic self loading."""
|
|
27
|
-
|
|
26
|
+
JacMachine(self.fixture_abs_path(__file__)).attach_program(
|
|
27
|
+
JacProgram(mod_bundle=None, bytecode=None)
|
|
28
|
+
)
|
|
28
29
|
jac_import("fixtures.hello_world", base_path=__file__)
|
|
29
|
-
self.assertIn(
|
|
30
|
-
|
|
30
|
+
self.assertIn(
|
|
31
|
+
"module 'fixtures.hello_world'",
|
|
32
|
+
str(JacMachine.get().loaded_modules),
|
|
33
|
+
)
|
|
34
|
+
self.assertIn(
|
|
35
|
+
"/tests/fixtures/hello_world.jac",
|
|
36
|
+
str(JacMachine.get().loaded_modules),
|
|
37
|
+
)
|
|
38
|
+
JacMachine.detach()
|
|
31
39
|
|
|
32
40
|
def test_jac_py_import(self) -> None:
|
|
33
41
|
"""Basic test for pass."""
|
jaclang/langserve/engine.py
CHANGED
|
@@ -16,13 +16,13 @@ from jaclang.compiler.passes.main.schedules import py_code_gen_typed
|
|
|
16
16
|
from jaclang.compiler.passes.tool import FuseCommentsPass, JacFormatPass
|
|
17
17
|
from jaclang.langserve.sem_manager import SemTokManager
|
|
18
18
|
from jaclang.langserve.utils import (
|
|
19
|
+
add_unique_text_edit,
|
|
19
20
|
collect_all_symbols_in_scope,
|
|
20
21
|
create_range,
|
|
21
22
|
find_deepest_symbol_node_at_pos,
|
|
22
23
|
find_index,
|
|
23
24
|
gen_diagnostics,
|
|
24
|
-
|
|
25
|
-
get_mod_path,
|
|
25
|
+
get_location_range,
|
|
26
26
|
get_symbols_for_outline,
|
|
27
27
|
parse_symbol_path,
|
|
28
28
|
resolve_completion_symbol_table,
|
|
@@ -127,6 +127,15 @@ class JacLangServer(LanguageServer):
|
|
|
127
127
|
build.warnings_had,
|
|
128
128
|
),
|
|
129
129
|
)
|
|
130
|
+
if annex_view:
|
|
131
|
+
self.publish_diagnostics(
|
|
132
|
+
file_path,
|
|
133
|
+
gen_diagnostics(
|
|
134
|
+
file_path,
|
|
135
|
+
build.errors_had,
|
|
136
|
+
build.warnings_had,
|
|
137
|
+
),
|
|
138
|
+
)
|
|
130
139
|
self.log_py(f"PROFILE: Deep check took {time.time() - start_time} seconds.")
|
|
131
140
|
return len(build.errors_had) == 0
|
|
132
141
|
except Exception as e:
|
|
@@ -325,8 +334,9 @@ class JacLangServer(LanguageServer):
|
|
|
325
334
|
and node_selected.parent
|
|
326
335
|
and isinstance(node_selected.parent, ast.ModulePath)
|
|
327
336
|
):
|
|
328
|
-
spec =
|
|
337
|
+
spec = node_selected.parent.abs_path
|
|
329
338
|
if spec:
|
|
339
|
+
spec = spec[5:] if spec.startswith("File:") else spec
|
|
330
340
|
return lspt.Location(
|
|
331
341
|
uri=uris.from_fs_path(spec),
|
|
332
342
|
range=lspt.Range(
|
|
@@ -339,19 +349,28 @@ class JacLangServer(LanguageServer):
|
|
|
339
349
|
elif node_selected.parent and isinstance(
|
|
340
350
|
node_selected.parent, ast.ModuleItem
|
|
341
351
|
):
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
352
|
+
path = node_selected.parent.from_mod_path.abs_path
|
|
353
|
+
try: # TODO: Get rid of this when 'from' import is fixed
|
|
354
|
+
loc_range = tuple(
|
|
355
|
+
loc - 1 if loc > 0 else loc
|
|
356
|
+
for loc in get_location_range(node_selected.parent)
|
|
357
|
+
)
|
|
358
|
+
except ValueError:
|
|
359
|
+
loc_range = (0, 0, 0, 0)
|
|
360
|
+
|
|
361
|
+
if path and loc_range:
|
|
362
|
+
path = path[5:] if path.startswith("File:") else path
|
|
363
|
+
return lspt.Location(
|
|
364
|
+
uri=uris.from_fs_path(path),
|
|
365
|
+
range=lspt.Range(
|
|
366
|
+
start=lspt.Position(
|
|
367
|
+
line=loc_range[0], character=loc_range[1]
|
|
351
368
|
),
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
369
|
+
end=lspt.Position(
|
|
370
|
+
line=loc_range[2], character=loc_range[3]
|
|
371
|
+
),
|
|
372
|
+
),
|
|
373
|
+
)
|
|
355
374
|
elif isinstance(node_selected, (ast.ElementStmt, ast.BuiltinType)):
|
|
356
375
|
return None
|
|
357
376
|
decl_node = (
|
|
@@ -368,7 +387,7 @@ class JacLangServer(LanguageServer):
|
|
|
368
387
|
decl_uri = uris.from_fs_path(decl_node.loc.mod_path)
|
|
369
388
|
try:
|
|
370
389
|
decl_range = create_range(decl_node.loc)
|
|
371
|
-
except ValueError:
|
|
390
|
+
except ValueError:
|
|
372
391
|
return None
|
|
373
392
|
decl_location = lspt.Location(
|
|
374
393
|
uri=decl_uri,
|
|
@@ -404,6 +423,35 @@ class JacLangServer(LanguageServer):
|
|
|
404
423
|
return list_of_references
|
|
405
424
|
return []
|
|
406
425
|
|
|
426
|
+
def rename_symbol(
|
|
427
|
+
self, file_path: str, position: lspt.Position, new_name: str
|
|
428
|
+
) -> Optional[lspt.WorkspaceEdit]:
|
|
429
|
+
"""Rename a symbol in a file."""
|
|
430
|
+
if file_path not in self.modules:
|
|
431
|
+
return None
|
|
432
|
+
index1 = find_index(
|
|
433
|
+
self.modules[file_path].sem_manager.sem_tokens,
|
|
434
|
+
position.line,
|
|
435
|
+
position.character,
|
|
436
|
+
)
|
|
437
|
+
if index1 is None:
|
|
438
|
+
return None
|
|
439
|
+
node_selected = self.modules[file_path].sem_manager.static_sem_tokens[index1][3]
|
|
440
|
+
if node_selected and node_selected.sym:
|
|
441
|
+
changes: dict[str, list[lspt.TextEdit]] = {}
|
|
442
|
+
for node in [
|
|
443
|
+
*node_selected.sym.uses,
|
|
444
|
+
node_selected.sym.defn[0],
|
|
445
|
+
]:
|
|
446
|
+
key = uris.from_fs_path(node.loc.mod_path)
|
|
447
|
+
new_edit = lspt.TextEdit(
|
|
448
|
+
range=create_range(node.loc),
|
|
449
|
+
new_text=new_name,
|
|
450
|
+
)
|
|
451
|
+
add_unique_text_edit(changes, key, new_edit)
|
|
452
|
+
return lspt.WorkspaceEdit(changes=changes)
|
|
453
|
+
return None
|
|
454
|
+
|
|
407
455
|
def get_semantic_tokens(self, file_path: str) -> lspt.SemanticTokens:
|
|
408
456
|
"""Return semantic tokens for a file."""
|
|
409
457
|
if file_path not in self.modules:
|
jaclang/langserve/server.py
CHANGED
|
@@ -17,8 +17,14 @@ server = JacLangServer()
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
@server.feature(lspt.TEXT_DOCUMENT_DID_OPEN)
|
|
20
|
-
@server.feature(lspt.TEXT_DOCUMENT_DID_SAVE)
|
|
21
20
|
async def did_open(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) -> None:
|
|
21
|
+
"""Check syntax on change."""
|
|
22
|
+
ls.deep_check(params.text_document.uri)
|
|
23
|
+
ls.lsp.send_request(lspt.WORKSPACE_SEMANTIC_TOKENS_REFRESH)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@server.feature(lspt.TEXT_DOCUMENT_DID_SAVE)
|
|
27
|
+
async def did_save(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) -> None:
|
|
22
28
|
"""Check syntax on change."""
|
|
23
29
|
await ls.launch_deep_check(params.text_document.uri)
|
|
24
30
|
ls.lsp.send_request(lspt.WORKSPACE_SEMANTIC_TOKENS_REFRESH)
|
|
@@ -132,6 +138,15 @@ def references(ls: JacLangServer, params: lspt.ReferenceParams) -> list[lspt.Loc
|
|
|
132
138
|
return ls.get_references(params.text_document.uri, params.position)
|
|
133
139
|
|
|
134
140
|
|
|
141
|
+
@server.feature(lspt.TEXT_DOCUMENT_RENAME)
|
|
142
|
+
def rename(
|
|
143
|
+
ls: JacLangServer, params: lspt.RenameParams
|
|
144
|
+
) -> Optional[lspt.WorkspaceEdit]:
|
|
145
|
+
"""Rename symbol."""
|
|
146
|
+
ls.log_warning("Auto Rename is Experimental, Please use with caution.")
|
|
147
|
+
return ls.rename_symbol(params.text_document.uri, params.position, params.new_name)
|
|
148
|
+
|
|
149
|
+
|
|
135
150
|
@server.feature(
|
|
136
151
|
lspt.TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
|
|
137
152
|
lspt.SemanticTokensLegend(
|
|
@@ -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}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
can foo;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
:can:foo{
|
|
6
|
+
print("foo");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
obj out{
|
|
11
|
+
has cnt :int;
|
|
12
|
+
can bar;
|
|
13
|
+
can baz;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
:obj:out:can:bar{
|
|
18
|
+
print("bar");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:obj:out:can:baz{
|
|
22
|
+
print("baz");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
with entry{
|
|
26
|
+
foo();
|
|
27
|
+
new = out();
|
|
28
|
+
new.cnt;
|
|
29
|
+
out(1).bar();
|
|
30
|
+
}
|
|
@@ -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:
|
|
@@ -201,6 +205,62 @@ class TestJacLangServer(TestCase):
|
|
|
201
205
|
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
202
206
|
)
|
|
203
207
|
|
|
208
|
+
def test_go_to_definition_foolme(self) -> None:
|
|
209
|
+
"""Test that the go to definition is correct."""
|
|
210
|
+
lsp = JacLangServer()
|
|
211
|
+
workspace_path = self.fixture_abs_path("")
|
|
212
|
+
workspace = Workspace(workspace_path, lsp)
|
|
213
|
+
lsp.lsp._workspace = workspace
|
|
214
|
+
import_file = uris.from_fs_path(
|
|
215
|
+
self.fixture_abs_path(
|
|
216
|
+
"../../../../jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac"
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
lsp.deep_check(import_file)
|
|
220
|
+
positions = [
|
|
221
|
+
(6, 39, "/pygame_mock/__init__.py:2:0-2:0"),
|
|
222
|
+
(6, 45, "/pygame_mock/constants.py:3:0-4:1"),
|
|
223
|
+
(7, 31, "/pygame_mock/__init__.py:2:0-2:0"),
|
|
224
|
+
(7, 35, "/pygame_mock/constants.py:3:0-4:1"),
|
|
225
|
+
(20, 51, "/py_imp_test.jac:6:4-6:11"),
|
|
226
|
+
(20, 64, "/pygame_mock/constants.py:4:3-4:15"),
|
|
227
|
+
(21, 48, "/py_imp_test.jac:10:4-10:6"),
|
|
228
|
+
(21, 58, "/py_imp_test.jac:11:8-11:15"),
|
|
229
|
+
(21, 68, "/pygame_mock/constants.py:4:3-4:15"),
|
|
230
|
+
(23, 58, "/pygame_mock/constants.py:4:3-4:15"),
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
for line, char, expected in positions:
|
|
234
|
+
with self.subTest(line=line, char=char):
|
|
235
|
+
self.assertIn(
|
|
236
|
+
expected,
|
|
237
|
+
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
def test_go_to_definition_index_expr(self) -> None:
|
|
241
|
+
"""Test that the go to definition is correct."""
|
|
242
|
+
lsp = JacLangServer()
|
|
243
|
+
workspace_path = self.fixture_abs_path("")
|
|
244
|
+
workspace = Workspace(workspace_path, lsp)
|
|
245
|
+
lsp.lsp._workspace = workspace
|
|
246
|
+
import_file = uris.from_fs_path(
|
|
247
|
+
self.fixture_abs_path("../../../../jaclang/tests/fixtures/index_slice.jac")
|
|
248
|
+
)
|
|
249
|
+
lsp.deep_check(import_file)
|
|
250
|
+
positions = [
|
|
251
|
+
(23, 20, "index_slice.jac:2:8-2:13"),
|
|
252
|
+
(24, 24, "index_slice.jac:2:8-2:13"),
|
|
253
|
+
(27, 33, "index_slice.jac:2:8-2:13"),
|
|
254
|
+
]
|
|
255
|
+
|
|
256
|
+
for line, char, expected in positions:
|
|
257
|
+
with self.subTest(line=line, char=char):
|
|
258
|
+
print(str(lsp.get_definition(import_file, lspt.Position(line, char))))
|
|
259
|
+
self.assertIn(
|
|
260
|
+
expected,
|
|
261
|
+
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
262
|
+
)
|
|
263
|
+
|
|
204
264
|
def test_sem_tokens(self) -> None:
|
|
205
265
|
"""Test that the Semantic Tokens are generated correctly."""
|
|
206
266
|
lsp = JacLangServer()
|
|
@@ -214,7 +274,7 @@ class TestJacLangServer(TestCase):
|
|
|
214
274
|
("<JacSemTokenType.VARIABLE: 8>, <JacSemTokenModifier.READONLY: 4>", 12),
|
|
215
275
|
(
|
|
216
276
|
"<JacSemTokenType.PROPERTY: 9>, <JacSemTokenModifier.DEFINITION: 2>,",
|
|
217
|
-
|
|
277
|
+
21,
|
|
218
278
|
),
|
|
219
279
|
(
|
|
220
280
|
"<JacSemTokenType.PARAMETER: 7>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
@@ -232,7 +292,6 @@ class TestJacLangServer(TestCase):
|
|
|
232
292
|
3,
|
|
233
293
|
),
|
|
234
294
|
]
|
|
235
|
-
print(str(sem_list))
|
|
236
295
|
for token_type, expected_count in expected_counts:
|
|
237
296
|
self.assertEqual(str(sem_list).count(token_type), expected_count)
|
|
238
297
|
|
|
@@ -351,3 +410,162 @@ class TestJacLangServer(TestCase):
|
|
|
351
410
|
references = str(lsp.get_references(circle_file, lspt.Position(line, char)))
|
|
352
411
|
for expected in expected_refs:
|
|
353
412
|
self.assertIn(expected, references)
|
|
413
|
+
|
|
414
|
+
def test_py_type__definition(self) -> None:
|
|
415
|
+
"""Test that the go to definition is correct for pythoon imports."""
|
|
416
|
+
lsp = JacLangServer()
|
|
417
|
+
workspace_path = self.fixture_abs_path("")
|
|
418
|
+
workspace = Workspace(workspace_path, lsp)
|
|
419
|
+
lsp.lsp._workspace = workspace
|
|
420
|
+
import_file = uris.from_fs_path(
|
|
421
|
+
self.fixture_abs_path(
|
|
422
|
+
"../../../../jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac"
|
|
423
|
+
)
|
|
424
|
+
)
|
|
425
|
+
lsp.deep_check(import_file)
|
|
426
|
+
positions = [
|
|
427
|
+
(19, 29, "pygame_mock/color.py:0:0-2:4"),
|
|
428
|
+
(3, 17, "/pygame_mock/__init__.py:0:0-0:0"),
|
|
429
|
+
(20, 45, "pygame_mock/color.py:0:0-2:4"),
|
|
430
|
+
(19, 77, "mock/constants.py:4:3-4:15"),
|
|
431
|
+
(26, 28, "mock/display.py:0:0-1:7"),
|
|
432
|
+
(24, 22, "/argparse.pyi:124:0-249:13"),
|
|
433
|
+
(19, 74, "pygame_mock/constants.py:4:3-4:15"),
|
|
434
|
+
(27, 17, "/stdlib/os/__init__.pyi:50:0-50:3"),
|
|
435
|
+
]
|
|
436
|
+
|
|
437
|
+
for line, char, expected in positions:
|
|
438
|
+
with self.subTest(line=line, char=char):
|
|
439
|
+
self.assertIn(
|
|
440
|
+
expected,
|
|
441
|
+
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
def test_py_type__references(self) -> None:
|
|
445
|
+
"""Test that the go to definition is correct for pythoon imports."""
|
|
446
|
+
lsp = JacLangServer()
|
|
447
|
+
workspace_path = self.fixture_abs_path("")
|
|
448
|
+
workspace = Workspace(workspace_path, lsp)
|
|
449
|
+
lsp.lsp._workspace = workspace
|
|
450
|
+
|
|
451
|
+
circle_file = uris.from_fs_path(
|
|
452
|
+
self.fixture_abs_path(
|
|
453
|
+
"../../../../jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac"
|
|
454
|
+
)
|
|
455
|
+
)
|
|
456
|
+
lsp.deep_check(circle_file)
|
|
457
|
+
test_cases = [
|
|
458
|
+
(
|
|
459
|
+
2,
|
|
460
|
+
21,
|
|
461
|
+
[
|
|
462
|
+
":6:21-6:32",
|
|
463
|
+
":7:11-7:22",
|
|
464
|
+
":11:25-11:36",
|
|
465
|
+
":12:15-12:26",
|
|
466
|
+
":18:33-18:44",
|
|
467
|
+
"19:46-19:57",
|
|
468
|
+
":19:8-19:19",
|
|
469
|
+
":19:46-19:57",
|
|
470
|
+
":20:8-20:19",
|
|
471
|
+
"21:8-21:19,",
|
|
472
|
+
"23:8-23:19",
|
|
473
|
+
":26:4-26:15",
|
|
474
|
+
],
|
|
475
|
+
),
|
|
476
|
+
(
|
|
477
|
+
19,
|
|
478
|
+
63,
|
|
479
|
+
[
|
|
480
|
+
"6:33-6:42",
|
|
481
|
+
"7:23-7:32",
|
|
482
|
+
"18:45-18:54",
|
|
483
|
+
"19:58-19:67",
|
|
484
|
+
"11:37-11:46",
|
|
485
|
+
"12:27-12:36",
|
|
486
|
+
],
|
|
487
|
+
),
|
|
488
|
+
(
|
|
489
|
+
24,
|
|
490
|
+
53,
|
|
491
|
+
[
|
|
492
|
+
"24:42-24:56",
|
|
493
|
+
"24:16-24:30",
|
|
494
|
+
"argparse.pyi:334:21-334:35",
|
|
495
|
+
"argparse.pyi:163:29-163:43",
|
|
496
|
+
"argparse.pyi:32:52-32:66",
|
|
497
|
+
],
|
|
498
|
+
),
|
|
499
|
+
]
|
|
500
|
+
for line, char, expected_refs in test_cases:
|
|
501
|
+
references = str(lsp.get_references(circle_file, lspt.Position(line, char)))
|
|
502
|
+
for expected in expected_refs:
|
|
503
|
+
self.assertIn(expected, references)
|
|
504
|
+
|
|
505
|
+
def test_rename_symbol(self) -> None:
|
|
506
|
+
"""Test that the rename is correct."""
|
|
507
|
+
lsp = JacLangServer()
|
|
508
|
+
workspace_path = self.fixture_abs_path("")
|
|
509
|
+
workspace = Workspace(workspace_path, lsp)
|
|
510
|
+
lsp.lsp._workspace = workspace
|
|
511
|
+
|
|
512
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle.jac"))
|
|
513
|
+
lsp.deep_check(circle_file)
|
|
514
|
+
test_cases = [
|
|
515
|
+
(
|
|
516
|
+
20,
|
|
517
|
+
14,
|
|
518
|
+
"ShapeKind",
|
|
519
|
+
"27:20-27:29,",
|
|
520
|
+
"36:19-36:28",
|
|
521
|
+
"75:26-75:35",
|
|
522
|
+
"20:5-20:14",
|
|
523
|
+
),
|
|
524
|
+
(12, 34, "circleRadius", "12:21-12:27", "12:30-12:36", "11:19-11:25"),
|
|
525
|
+
(62, 14, "target_area", "65:43-65:56", "70:32-70:45", "62:5-62:18"),
|
|
526
|
+
(57, 33, "type_of_shape", "75:12-75:22", "27:8-27:18,", "57:23-57:33"),
|
|
527
|
+
]
|
|
528
|
+
for tup in test_cases:
|
|
529
|
+
line, char, new_name, *expected_refs = tup
|
|
530
|
+
references = str(
|
|
531
|
+
lsp.rename_symbol(circle_file, lspt.Position(line, char), new_name)
|
|
532
|
+
)
|
|
533
|
+
for expected in expected_refs:
|
|
534
|
+
self.assertIn(expected, references)
|
|
535
|
+
|
|
536
|
+
def test_rename_uses(self) -> None:
|
|
537
|
+
"""Test that the rename is correct."""
|
|
538
|
+
lsp = JacLangServer()
|
|
539
|
+
workspace_path = self.fixture_abs_path("")
|
|
540
|
+
workspace = Workspace(workspace_path, lsp)
|
|
541
|
+
lsp.lsp._workspace = workspace
|
|
542
|
+
|
|
543
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("rename.jac"))
|
|
544
|
+
lsp.deep_check(circle_file)
|
|
545
|
+
# fmt: off
|
|
546
|
+
test_cases = [
|
|
547
|
+
(0, 7, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
548
|
+
(4, 6, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
549
|
+
(25, 7, "func", "25:4-25:7", "0:4-0:7", "4:5-4:8",),
|
|
550
|
+
(10, 10, "canBar", "27:8-27:11", "10:8-10:11"),
|
|
551
|
+
(27, 9, "canBar", "27:8-27:11", "10:8-10:11"),
|
|
552
|
+
(9, 6, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
553
|
+
(26, 11, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
554
|
+
(16, 7, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
555
|
+
(28, 6, "canBar", "26:10-26:13", "28:4-28:7", "16:5-16:8", "9:4-9:7"),
|
|
556
|
+
(11, 10, "canBar", "11:8-11:11", "16:13-16:16", "28:11-28:14"),
|
|
557
|
+
(16, 14, "canBar", "11:8-11:11", "16:13-16:16", "28:11-28:14"),
|
|
558
|
+
(28, 13, "canBar", "11:8-11:11", "16:13-16:16", "28:11-28:14"),
|
|
559
|
+
(12, 10, "canBaz", "12:8-12:11", "20:13-20:16"),
|
|
560
|
+
(20, 14, "canBaz", "12:8-12:11", "20:13-20:16"),
|
|
561
|
+
(26, 6, "count", "27:4-27:7", "26:4-26:7"),
|
|
562
|
+
(27, 5, "count", "27:4-27:7", "26:4-26:7"),
|
|
563
|
+
]
|
|
564
|
+
# fmt: on
|
|
565
|
+
for tup in test_cases:
|
|
566
|
+
line, char, new_name, *expected_refs = tup
|
|
567
|
+
references = str(
|
|
568
|
+
lsp.rename_symbol(circle_file, lspt.Position(line, char), new_name)
|
|
569
|
+
)
|
|
570
|
+
for expected in expected_refs:
|
|
571
|
+
self.assertIn(expected, references)
|