jaclang 0.7.1__py3-none-any.whl → 0.7.7__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 +2 -2
- jaclang/compiler/absyntree.py +539 -297
- jaclang/compiler/codeloc.py +2 -2
- jaclang/compiler/constant.py +100 -2
- jaclang/compiler/jac.lark +27 -19
- jaclang/compiler/parser.py +119 -92
- jaclang/compiler/passes/main/access_modifier_pass.py +20 -12
- jaclang/compiler/passes/main/def_impl_match_pass.py +32 -12
- jaclang/compiler/passes/main/def_use_pass.py +59 -40
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +71 -30
- jaclang/compiler/passes/main/import_pass.py +12 -7
- jaclang/compiler/passes/main/pyast_gen_pass.py +110 -47
- jaclang/compiler/passes/main/pyast_load_pass.py +49 -13
- jaclang/compiler/passes/main/pyjac_ast_link_pass.py +25 -11
- jaclang/compiler/passes/main/pyout_pass.py +3 -1
- jaclang/compiler/passes/main/registry_pass.py +6 -6
- jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
- jaclang/compiler/passes/main/sym_tab_build_pass.py +43 -235
- jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
- jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
- jaclang/compiler/passes/main/tests/test_import_pass.py +8 -0
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/main/type_check_pass.py +2 -1
- jaclang/compiler/passes/tool/jac_formatter_pass.py +44 -11
- jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
- jaclang/compiler/passes/tool/tests/fixtures/doc_string.jac +15 -0
- jaclang/compiler/passes/tool/tests/fixtures/genai/essay_review.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/expert_answer.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/joke_gen.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/odd_word_out.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/personality_finder.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/text_to_type.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/translator.jac +1 -1
- jaclang/compiler/passes/tool/tests/fixtures/genai/wikipedia.jac +1 -1
- jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +7 -5
- jaclang/compiler/passes/tool/tests/test_unparse_validate.py +1 -2
- jaclang/compiler/passes/transform.py +2 -4
- jaclang/{core/registry.py → compiler/semtable.py} +1 -3
- jaclang/compiler/symtable.py +150 -89
- jaclang/compiler/tests/test_parser.py +2 -2
- jaclang/core/aott.py +118 -18
- jaclang/core/{construct.py → architype.py} +44 -93
- jaclang/core/constructs.py +44 -0
- jaclang/core/context.py +157 -0
- jaclang/core/importer.py +18 -9
- jaclang/core/memory.py +53 -2
- jaclang/core/test.py +90 -0
- jaclang/core/utils.py +2 -2
- jaclang/langserve/engine.py +199 -138
- jaclang/langserve/server.py +48 -53
- jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
- jaclang/langserve/tests/fixtures/circle.jac +16 -12
- jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
- jaclang/langserve/tests/fixtures/circle_pure.impl.jac +8 -4
- jaclang/langserve/tests/fixtures/circle_pure.jac +2 -2
- jaclang/langserve/tests/fixtures/circle_pure.test.jac +15 -0
- jaclang/langserve/tests/fixtures/import_include_statements.jac +6 -0
- jaclang/langserve/tests/fixtures/py_import.py +26 -0
- jaclang/langserve/tests/test_server.py +200 -2
- jaclang/langserve/utils.py +214 -10
- jaclang/plugin/builtin.py +1 -1
- jaclang/plugin/default.py +48 -92
- jaclang/plugin/feature.py +33 -17
- jaclang/plugin/spec.py +18 -20
- jaclang/plugin/tests/test_features.py +0 -33
- jaclang/settings.py +4 -0
- jaclang/tests/fixtures/abc.jac +16 -12
- jaclang/tests/fixtures/aott_raise.jac +1 -1
- jaclang/tests/fixtures/byllmissue.jac +12 -0
- jaclang/tests/fixtures/edgetypeissue.jac +10 -0
- jaclang/tests/fixtures/hash_init_check.jac +17 -0
- jaclang/tests/fixtures/hello.jac +1 -1
- jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
- jaclang/tests/fixtures/impl_match_confused.jac +5 -0
- jaclang/tests/fixtures/math_question.jpg +0 -0
- jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
- jaclang/tests/fixtures/nosigself.jac +19 -0
- jaclang/tests/fixtures/run_test.jac +17 -5
- jaclang/tests/fixtures/walker_override.jac +21 -0
- jaclang/tests/fixtures/with_llm_function.jac +1 -1
- jaclang/tests/fixtures/with_llm_lower.jac +1 -1
- jaclang/tests/fixtures/with_llm_method.jac +1 -1
- jaclang/tests/fixtures/with_llm_type.jac +1 -1
- jaclang/tests/fixtures/with_llm_vision.jac +25 -0
- jaclang/tests/test_bugs.py +19 -0
- jaclang/tests/test_cli.py +1 -1
- jaclang/tests/test_language.py +197 -82
- jaclang/tests/test_reference.py +1 -1
- jaclang/utils/lang_tools.py +5 -4
- jaclang/utils/test.py +2 -1
- jaclang/utils/treeprinter.py +35 -4
- {jaclang-0.7.1.dist-info → jaclang-0.7.7.dist-info}/METADATA +3 -2
- {jaclang-0.7.1.dist-info → jaclang-0.7.7.dist-info}/RECORD +96 -88
- jaclang/core/llms/__init__.py +0 -20
- jaclang/core/llms/anthropic.py +0 -61
- jaclang/core/llms/base.py +0 -206
- jaclang/core/llms/groq.py +0 -67
- jaclang/core/llms/huggingface.py +0 -73
- jaclang/core/llms/ollama.py +0 -78
- jaclang/core/llms/openai.py +0 -61
- jaclang/core/llms/togetherai.py +0 -60
- jaclang/core/llms/utils.py +0 -9
- jaclang/core/shelve_storage.py +0 -55
- {jaclang-0.7.1.dist-info → jaclang-0.7.7.dist-info}/WHEEL +0 -0
- {jaclang-0.7.1.dist-info → jaclang-0.7.7.dist-info}/entry_points.txt +0 -0
jaclang/langserve/server.py
CHANGED
|
@@ -2,66 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import threading
|
|
6
5
|
from typing import Optional
|
|
7
6
|
|
|
7
|
+
from jaclang.compiler.constant import (
|
|
8
|
+
JacSemTokenModifier as SemTokMod,
|
|
9
|
+
JacSemTokenType as SemTokType,
|
|
10
|
+
)
|
|
8
11
|
from jaclang.langserve.engine import JacLangServer
|
|
9
12
|
from jaclang.langserve.utils import debounce
|
|
10
13
|
|
|
11
14
|
import lsprotocol.types as lspt
|
|
12
15
|
|
|
13
16
|
server = JacLangServer()
|
|
14
|
-
analysis_thread: Optional[threading.Thread] = None
|
|
15
|
-
analysis_stop_event = threading.Event()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def analyze_and_publish(ls: JacLangServer, uri: str) -> None:
|
|
19
|
-
"""Analyze and publish diagnostics."""
|
|
20
|
-
global analysis_thread, analysis_stop_event
|
|
21
|
-
|
|
22
|
-
def run_analysis() -> None:
|
|
23
|
-
ls.quick_check(uri)
|
|
24
|
-
ls.push_diagnostics(uri)
|
|
25
|
-
ls.deep_check(uri)
|
|
26
|
-
ls.push_diagnostics(uri)
|
|
27
|
-
ls.type_check(uri)
|
|
28
|
-
ls.push_diagnostics(uri)
|
|
29
|
-
|
|
30
|
-
analysis_thread = threading.Thread(target=run_analysis)
|
|
31
|
-
analysis_thread.start()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def stop_analysis() -> None:
|
|
35
|
-
"""Stop analysis."""
|
|
36
|
-
global analysis_thread, analysis_stop_event
|
|
37
|
-
if analysis_thread is not None:
|
|
38
|
-
analysis_stop_event.set()
|
|
39
|
-
analysis_thread.join()
|
|
40
|
-
analysis_stop_event.clear()
|
|
41
17
|
|
|
42
18
|
|
|
43
19
|
@server.feature(lspt.TEXT_DOCUMENT_DID_OPEN)
|
|
44
|
-
|
|
20
|
+
@server.feature(lspt.TEXT_DOCUMENT_DID_SAVE)
|
|
21
|
+
def did_open(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) -> None:
|
|
45
22
|
"""Check syntax on change."""
|
|
46
|
-
|
|
47
|
-
|
|
23
|
+
ls.analyze_and_publish(params.text_document.uri)
|
|
24
|
+
# token_params = lspt.SemanticTokensParams(
|
|
25
|
+
# text_document=lspt.TextDocumentIdentifier(uri=params.text_document.uri)
|
|
26
|
+
# )
|
|
27
|
+
# tokens = semantic_tokens_full(ls, token_params)
|
|
28
|
+
# ls.send_notification("textDocument/publishSemanticTokens", tokens)
|
|
48
29
|
|
|
49
30
|
|
|
50
31
|
@server.feature(lspt.TEXT_DOCUMENT_DID_CHANGE)
|
|
51
32
|
@debounce(0.1)
|
|
52
|
-
async def did_change(
|
|
53
|
-
ls: JacLangServer, params: lspt.DidChangeTextDocumentParams
|
|
54
|
-
) -> None:
|
|
33
|
+
async def did_change(ls: JacLangServer, params: lspt.DidOpenTextDocumentParams) -> None:
|
|
55
34
|
"""Check syntax on change."""
|
|
56
|
-
|
|
57
|
-
analyze_and_publish(ls, params.text_document.uri)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
@server.feature(lspt.TEXT_DOCUMENT_DID_SAVE)
|
|
61
|
-
async def did_save(ls: JacLangServer, params: lspt.DidSaveTextDocumentParams) -> None:
|
|
62
|
-
"""Check syntax on save."""
|
|
63
|
-
stop_analysis()
|
|
64
|
-
analyze_and_publish(ls, params.text_document.uri)
|
|
35
|
+
ls.analyze_and_publish(params.text_document.uri, level=0)
|
|
65
36
|
|
|
66
37
|
|
|
67
38
|
@server.feature(
|
|
@@ -72,11 +43,8 @@ async def did_save(ls: JacLangServer, params: lspt.DidSaveTextDocumentParams) ->
|
|
|
72
43
|
]
|
|
73
44
|
),
|
|
74
45
|
)
|
|
75
|
-
|
|
46
|
+
def did_create_files(ls: JacLangServer, params: lspt.CreateFilesParams) -> None:
|
|
76
47
|
"""Check syntax on file creation."""
|
|
77
|
-
for file in params.files:
|
|
78
|
-
ls.quick_check(file.uri)
|
|
79
|
-
ls.push_diagnostics(file.uri)
|
|
80
48
|
|
|
81
49
|
|
|
82
50
|
@server.feature(
|
|
@@ -87,13 +55,12 @@ async def did_create_files(ls: JacLangServer, params: lspt.CreateFilesParams) ->
|
|
|
87
55
|
]
|
|
88
56
|
),
|
|
89
57
|
)
|
|
90
|
-
|
|
58
|
+
def did_rename_files(ls: JacLangServer, params: lspt.RenameFilesParams) -> None:
|
|
91
59
|
"""Check syntax on file rename."""
|
|
92
60
|
new_uris = [file.new_uri for file in params.files]
|
|
93
61
|
old_uris = [file.old_uri for file in params.files]
|
|
94
62
|
for i in range(len(new_uris)):
|
|
95
63
|
ls.rename_module(old_uris[i], new_uris[i])
|
|
96
|
-
ls.quick_check(new_uris[i])
|
|
97
64
|
|
|
98
65
|
|
|
99
66
|
@server.feature(
|
|
@@ -104,7 +71,7 @@ async def did_rename_files(ls: JacLangServer, params: lspt.RenameFilesParams) ->
|
|
|
104
71
|
]
|
|
105
72
|
),
|
|
106
73
|
)
|
|
107
|
-
|
|
74
|
+
def did_delete_files(ls: JacLangServer, params: lspt.DeleteFilesParams) -> None:
|
|
108
75
|
"""Check syntax on file delete."""
|
|
109
76
|
for file in params.files:
|
|
110
77
|
ls.delete_module(file.uri)
|
|
@@ -114,9 +81,7 @@ async def did_delete_files(ls: JacLangServer, params: lspt.DeleteFilesParams) ->
|
|
|
114
81
|
lspt.TEXT_DOCUMENT_COMPLETION,
|
|
115
82
|
lspt.CompletionOptions(trigger_characters=[".", ":", ""]),
|
|
116
83
|
)
|
|
117
|
-
|
|
118
|
-
ls: JacLangServer, params: lspt.CompletionParams
|
|
119
|
-
) -> lspt.CompletionList:
|
|
84
|
+
def completion(ls: JacLangServer, params: lspt.CompletionParams) -> lspt.CompletionList:
|
|
120
85
|
"""Provide completion."""
|
|
121
86
|
return ls.get_completion(params.text_document.uri, params.position)
|
|
122
87
|
|
|
@@ -137,6 +102,36 @@ def hover(
|
|
|
137
102
|
return ls.get_hover_info(params.text_document.uri, params.position)
|
|
138
103
|
|
|
139
104
|
|
|
105
|
+
@server.feature(lspt.TEXT_DOCUMENT_DOCUMENT_SYMBOL)
|
|
106
|
+
def document_symbol(
|
|
107
|
+
ls: JacLangServer, params: lspt.DocumentSymbolParams
|
|
108
|
+
) -> list[lspt.DocumentSymbol]:
|
|
109
|
+
"""Provide document symbols."""
|
|
110
|
+
return ls.get_document_symbols(params.text_document.uri)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@server.feature(lspt.TEXT_DOCUMENT_DEFINITION)
|
|
114
|
+
def definition(
|
|
115
|
+
ls: JacLangServer, params: lspt.TextDocumentPositionParams
|
|
116
|
+
) -> Optional[lspt.Location]:
|
|
117
|
+
"""Provide definition."""
|
|
118
|
+
return ls.get_definition(params.text_document.uri, params.position)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@server.feature(
|
|
122
|
+
lspt.TEXT_DOCUMENT_SEMANTIC_TOKENS_FULL,
|
|
123
|
+
lspt.SemanticTokensLegend(
|
|
124
|
+
token_types=SemTokType.as_str_list(),
|
|
125
|
+
token_modifiers=SemTokMod.as_str_list(),
|
|
126
|
+
),
|
|
127
|
+
)
|
|
128
|
+
def semantic_tokens_full(
|
|
129
|
+
ls: JacLangServer, params: lspt.SemanticTokensParams
|
|
130
|
+
) -> lspt.SemanticTokens:
|
|
131
|
+
"""Provide semantic tokens."""
|
|
132
|
+
return ls.get_semantic_tokens(params.text_document.uri)
|
|
133
|
+
|
|
134
|
+
|
|
140
135
|
def run_lang_server() -> None:
|
|
141
136
|
"""Run the language server."""
|
|
142
137
|
server.start_io()
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""A Docstring can be added the head of any module.
|
|
2
|
+
|
|
3
|
+
Any element in the module can also have a docstring.
|
|
4
|
+
If there is only one docstring before the first element,
|
|
5
|
+
it is assumed to be a module docstring.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
"""A docstring for add function"""
|
|
9
|
+
can add(a: int, b: int) -> int {
|
|
10
|
+
return a + b;
|
|
11
|
+
}
|
|
12
|
+
# No docstring for subtract function
|
|
13
|
+
|
|
14
|
+
can subtract(a: int, b: int) -> int {
|
|
15
|
+
return a - b;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
with entry:__main__ {
|
|
19
|
+
print(add(1, subtract(3, 1)));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
glob x: int = 10;
|
|
23
|
+
|
|
24
|
+
enum Color {
|
|
25
|
+
RED,
|
|
26
|
+
GREEN,
|
|
27
|
+
BLUE
|
|
28
|
+
}
|
|
@@ -18,9 +18,9 @@ Below we have the demonstration of a class to calculate the area of a circle.
|
|
|
18
18
|
*#
|
|
19
19
|
|
|
20
20
|
"""Enum for shape types"""
|
|
21
|
-
enum ShapeType
|
|
22
|
-
CIRCLE="Circle",
|
|
23
|
-
UNKNOWN="Unknown"
|
|
21
|
+
enum ShapeType {
|
|
22
|
+
CIRCLE = "Circle",
|
|
23
|
+
UNKNOWN = "Unknown"
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
"""Base class for a shape."""
|
|
@@ -50,24 +50,28 @@ with entry {
|
|
|
50
50
|
# Global also works here
|
|
51
51
|
|
|
52
52
|
with entry:__main__ {
|
|
53
|
-
# To run the program functionality
|
|
54
|
-
print(
|
|
55
|
-
|
|
53
|
+
# To run the program functionality
|
|
54
|
+
print(
|
|
55
|
+
f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}"
|
|
56
|
+
);
|
|
57
|
+
print(
|
|
58
|
+
f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}"
|
|
59
|
+
);
|
|
56
60
|
}
|
|
57
61
|
# Unit Tests!
|
|
58
62
|
|
|
59
63
|
glob expected_area = 78.53981633974483;
|
|
60
64
|
|
|
61
|
-
test calc_area
|
|
62
|
-
check
|
|
65
|
+
test calc_area {
|
|
66
|
+
check assertAlmostEqual(calculate_area(RAD), expected_area);
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
test circle_area
|
|
69
|
+
test circle_area {
|
|
66
70
|
c = Circle(RAD);
|
|
67
|
-
check
|
|
71
|
+
check assertAlmostEqual(c.area(), expected_area);
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
test circle_type
|
|
74
|
+
test circle_type {
|
|
71
75
|
c = Circle(RAD);
|
|
72
|
-
check
|
|
76
|
+
check assertEqual(c.shape_type, ShapeType.CIRCLE);
|
|
73
77
|
}
|
|
@@ -59,15 +59,15 @@ print(f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}
|
|
|
59
59
|
glob expected_area = 78.53981633974483;
|
|
60
60
|
|
|
61
61
|
test calc_area {
|
|
62
|
-
check
|
|
62
|
+
check assertAlmostEqual(calculate_area(RAD), expected_area);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
test circle_area {
|
|
66
66
|
c = Circle(RAD);
|
|
67
|
-
check
|
|
67
|
+
check assertAlmostEqual(c.area(), expected_area);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
test circle_type {
|
|
71
71
|
c = Circle(RAD);
|
|
72
|
-
check
|
|
72
|
+
check assertEqual(c.shape_type, ShapeType.CIRCLE);
|
|
73
73
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Enum for shape types"""
|
|
2
2
|
|
|
3
3
|
:enum:ShapeType {
|
|
4
|
-
CIRCLE="Circle",
|
|
5
|
-
UNKNOWN="Unknown"
|
|
4
|
+
CIRCLE = "Circle",
|
|
5
|
+
UNKNOWN = "Unknown"
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
"""Function to calculate the area of a circle."""
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
:can:main_run {
|
|
26
|
-
print(
|
|
27
|
-
|
|
26
|
+
print(
|
|
27
|
+
f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}"
|
|
28
|
+
);
|
|
29
|
+
print(
|
|
30
|
+
f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}"
|
|
31
|
+
);
|
|
28
32
|
}
|
|
@@ -11,7 +11,7 @@ can calculate_area(radius: float) -> float;
|
|
|
11
11
|
can main_run;
|
|
12
12
|
|
|
13
13
|
"""Base class for a shape."""
|
|
14
|
-
obj Shape {
|
|
14
|
+
obj : priv Shape {
|
|
15
15
|
has shape_type: ShapeType;
|
|
16
16
|
|
|
17
17
|
can area -> float abs;
|
|
@@ -22,7 +22,7 @@ obj Circle :Shape: {
|
|
|
22
22
|
has radius: float;
|
|
23
23
|
|
|
24
24
|
can init(radius: float);
|
|
25
|
-
can area -> float;
|
|
25
|
+
override can area -> float;
|
|
26
26
|
}
|
|
27
27
|
# Radius of the demo circle
|
|
28
28
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
glob expected_area = 78.53981633974483;
|
|
2
|
+
|
|
3
|
+
test a1 {
|
|
4
|
+
check assertAlmostEqual(calculate_area(RAD), expected_area);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
test a2 {
|
|
8
|
+
c = Circle(RAD);
|
|
9
|
+
check assertAlmostEqual(c.area(), expected_area);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test a3 {
|
|
13
|
+
c = Circle(RAD);
|
|
14
|
+
check assertEqual(c.shape_type, ShapeType.CIRCLE);
|
|
15
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import:py os;
|
|
2
|
+
import:py from math, sqrt as square_root;
|
|
3
|
+
import:py datetime as dt;
|
|
4
|
+
import:jac from base_module_structure, add as adsd, subtract,x,Color as clr;
|
|
5
|
+
import:jac base_module_structure as base_module_structure;
|
|
6
|
+
import:py from py_import,add1 as ss, sub1 as subtract1,apple,Orange1;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""This is a helper file."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def add1():
|
|
5
|
+
return 1 + 1
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def sub1():
|
|
9
|
+
return 1 - 1
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# classes
|
|
13
|
+
class Orange1:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.orange = 1
|
|
16
|
+
|
|
17
|
+
def get_orange(self):
|
|
18
|
+
return self.orange
|
|
19
|
+
|
|
20
|
+
def set_orange(self, orange):
|
|
21
|
+
self.orange = orange
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# variables
|
|
25
|
+
orange2 = 1
|
|
26
|
+
apple = 1
|
|
@@ -4,6 +4,8 @@ from jaclang.vendor.pygls.workspace import Workspace
|
|
|
4
4
|
from jaclang.langserve.engine import JacLangServer
|
|
5
5
|
from .session import LspSession
|
|
6
6
|
|
|
7
|
+
import lsprotocol.types as lspt
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
class TestJacLangServer(TestCase):
|
|
9
11
|
|
|
@@ -61,8 +63,204 @@ class TestJacLangServer(TestCase):
|
|
|
61
63
|
self.assertEqual(len(lsp.modules), 1)
|
|
62
64
|
self.assertEqual(lsp.modules[circle_file].diagnostics[0].range.start.line, 22)
|
|
63
65
|
lsp.deep_check(circle_file)
|
|
64
|
-
self.assertEqual(len(lsp.modules), 1)
|
|
66
|
+
# self.assertEqual(len(lsp.modules), 1)
|
|
65
67
|
self.assertEqual(lsp.modules[circle_file].diagnostics[0].range.start.line, 22)
|
|
66
68
|
lsp.type_check(circle_file)
|
|
67
|
-
self.assertEqual(len(lsp.modules), 1)
|
|
69
|
+
# self.assertEqual(len(lsp.modules), 1)
|
|
68
70
|
self.assertEqual(lsp.modules[circle_file].diagnostics[0].range.start.line, 22)
|
|
71
|
+
|
|
72
|
+
def test_impl_stay_connected(self) -> None:
|
|
73
|
+
"""Test that the server doesn't run if there is a syntax error."""
|
|
74
|
+
lsp = JacLangServer()
|
|
75
|
+
# Set up the workspace path to "fixtures/"
|
|
76
|
+
workspace_path = self.fixture_abs_path("")
|
|
77
|
+
workspace = Workspace(workspace_path, lsp)
|
|
78
|
+
lsp.lsp._workspace = workspace
|
|
79
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
|
|
80
|
+
circle_impl_file = uris.from_fs_path(
|
|
81
|
+
self.fixture_abs_path("circle_pure.impl.jac")
|
|
82
|
+
)
|
|
83
|
+
lsp.quick_check(circle_file)
|
|
84
|
+
lsp.deep_check(circle_file)
|
|
85
|
+
lsp.type_check(circle_file)
|
|
86
|
+
pos = lspt.Position(20, 8)
|
|
87
|
+
self.assertIn(
|
|
88
|
+
"Circle class inherits from Shape.",
|
|
89
|
+
lsp.get_hover_info(circle_file, pos).contents.value,
|
|
90
|
+
)
|
|
91
|
+
lsp.type_check(circle_impl_file)
|
|
92
|
+
pos = lspt.Position(8, 11)
|
|
93
|
+
self.assertIn(
|
|
94
|
+
"ability) calculate_area: float",
|
|
95
|
+
lsp.get_hover_info(circle_impl_file, pos).contents.value,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def test_impl_auto_discover(self) -> None:
|
|
99
|
+
"""Test that the server doesn't run if there is a syntax error."""
|
|
100
|
+
lsp = JacLangServer()
|
|
101
|
+
# Set up the workspace path to "fixtures/"
|
|
102
|
+
workspace_path = self.fixture_abs_path("")
|
|
103
|
+
workspace = Workspace(workspace_path, lsp)
|
|
104
|
+
lsp.lsp._workspace = workspace
|
|
105
|
+
circle_impl_file = uris.from_fs_path(
|
|
106
|
+
self.fixture_abs_path("circle_pure.impl.jac")
|
|
107
|
+
)
|
|
108
|
+
lsp.quick_check(circle_impl_file)
|
|
109
|
+
lsp.deep_check(circle_impl_file)
|
|
110
|
+
lsp.type_check(circle_impl_file)
|
|
111
|
+
pos = lspt.Position(8, 11)
|
|
112
|
+
self.assertIn(
|
|
113
|
+
"ability) calculate_area: float",
|
|
114
|
+
lsp.get_hover_info(circle_impl_file, pos).contents.value,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def test_show_type_impl(self) -> None:
|
|
118
|
+
"""Test that the server doesn't run if there is a syntax error."""
|
|
119
|
+
lsp = JacLangServer()
|
|
120
|
+
# Set up the workspace path to "fixtures/"
|
|
121
|
+
workspace_path = self.fixture_abs_path("")
|
|
122
|
+
workspace = Workspace(workspace_path, lsp)
|
|
123
|
+
lsp.lsp._workspace = workspace
|
|
124
|
+
target = uris.from_fs_path(
|
|
125
|
+
self.fixture_abs_path("../../../../examples/guess_game/guess_game4.jac")
|
|
126
|
+
)
|
|
127
|
+
lsp.quick_check(target)
|
|
128
|
+
lsp.deep_check(target)
|
|
129
|
+
lsp.type_check(target)
|
|
130
|
+
pos = lspt.Position(43, 18)
|
|
131
|
+
self.assertIn(
|
|
132
|
+
"attempts: int",
|
|
133
|
+
lsp.get_hover_info(target, pos).contents.value,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
def test_outline_symbols(self) -> None:
|
|
137
|
+
"""Test that the outline symbols are correct."""
|
|
138
|
+
lsp = JacLangServer()
|
|
139
|
+
workspace_path = self.fixture_abs_path("")
|
|
140
|
+
workspace = Workspace(workspace_path, lsp)
|
|
141
|
+
lsp.lsp._workspace = workspace
|
|
142
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
|
|
143
|
+
lsp.quick_check(circle_file)
|
|
144
|
+
lsp.deep_check(circle_file)
|
|
145
|
+
lsp.type_check(circle_file)
|
|
146
|
+
self.assertEqual(8, len(lsp.get_document_symbols(circle_file)))
|
|
147
|
+
|
|
148
|
+
def test_go_to_definition(self) -> None:
|
|
149
|
+
"""Test that the go to definition is correct."""
|
|
150
|
+
lsp = JacLangServer()
|
|
151
|
+
workspace_path = self.fixture_abs_path("")
|
|
152
|
+
workspace = Workspace(workspace_path, lsp)
|
|
153
|
+
lsp.lsp._workspace = workspace
|
|
154
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.jac"))
|
|
155
|
+
lsp.quick_check(circle_file)
|
|
156
|
+
lsp.deep_check(circle_file)
|
|
157
|
+
lsp.type_check(circle_file)
|
|
158
|
+
self.assertIn(
|
|
159
|
+
"fixtures/circle_pure.impl.jac:8:0-8:19",
|
|
160
|
+
str(lsp.get_definition(circle_file, lspt.Position(9, 16))),
|
|
161
|
+
)
|
|
162
|
+
self.assertIn(
|
|
163
|
+
"fixtures/circle_pure.jac:13:11-13:16",
|
|
164
|
+
str(lsp.get_definition(circle_file, lspt.Position(20, 17))),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def test_go_to_definition_method(self) -> None:
|
|
168
|
+
"""Test that the go to definition is correct."""
|
|
169
|
+
lsp = JacLangServer()
|
|
170
|
+
workspace_path = self.fixture_abs_path("")
|
|
171
|
+
workspace = Workspace(workspace_path, lsp)
|
|
172
|
+
lsp.lsp._workspace = workspace
|
|
173
|
+
guess_game_file = uris.from_fs_path(
|
|
174
|
+
self.fixture_abs_path("../../../../examples/guess_game/guess_game4.jac")
|
|
175
|
+
)
|
|
176
|
+
lsp.quick_check(guess_game_file)
|
|
177
|
+
lsp.deep_check(guess_game_file)
|
|
178
|
+
lsp.type_check(guess_game_file)
|
|
179
|
+
self.assertIn(
|
|
180
|
+
"guess_game4.jac:27:8-27:21",
|
|
181
|
+
str(lsp.get_definition(guess_game_file, lspt.Position(46, 45))),
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
def test_test_annex(self) -> None:
|
|
185
|
+
"""Test that the server doesn't run if there is a syntax error."""
|
|
186
|
+
lsp = JacLangServer()
|
|
187
|
+
# Set up the workspace path to "fixtures/"
|
|
188
|
+
workspace_path = self.fixture_abs_path("")
|
|
189
|
+
workspace = Workspace(workspace_path, lsp)
|
|
190
|
+
lsp.lsp._workspace = workspace
|
|
191
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle_pure.test.jac"))
|
|
192
|
+
lsp.quick_check(circle_file)
|
|
193
|
+
lsp.deep_check(circle_file)
|
|
194
|
+
lsp.type_check(circle_file)
|
|
195
|
+
pos = lspt.Position(13, 29)
|
|
196
|
+
self.assertIn(
|
|
197
|
+
"shape_type: circle_pure.ShapeType",
|
|
198
|
+
lsp.get_hover_info(circle_file, pos).contents.value,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def test_go_to_defintion_import(self) -> None:
|
|
202
|
+
"""Test that the go to definition is correct."""
|
|
203
|
+
lsp = JacLangServer()
|
|
204
|
+
workspace_path = self.fixture_abs_path("")
|
|
205
|
+
workspace = Workspace(workspace_path, lsp)
|
|
206
|
+
lsp.lsp._workspace = workspace
|
|
207
|
+
import_file = uris.from_fs_path(
|
|
208
|
+
self.fixture_abs_path("import_include_statements.jac")
|
|
209
|
+
)
|
|
210
|
+
lsp.quick_check(import_file)
|
|
211
|
+
lsp.deep_check(import_file)
|
|
212
|
+
lsp.type_check(import_file)
|
|
213
|
+
positions = [
|
|
214
|
+
(2, 16, "datetime.py:0:0-0:0"),
|
|
215
|
+
(3, 17, "base_module_structure.jac:0:0-0:0"),
|
|
216
|
+
(3, 74, "base_module_structure.jac:23:0-23:5"),
|
|
217
|
+
(5, 65, "py_import.py:12:0-20:5"),
|
|
218
|
+
(5, 35, "py_import.py:3:0-4:5"),
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
for line, char, expected in positions:
|
|
222
|
+
with self.subTest(line=line, char=char):
|
|
223
|
+
self.assertIn(
|
|
224
|
+
expected,
|
|
225
|
+
str(lsp.get_definition(import_file, lspt.Position(line, char))),
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def test_sem_tokens(self) -> None:
|
|
229
|
+
"""Test that the Semantic Tokens are generated correctly."""
|
|
230
|
+
lsp = JacLangServer()
|
|
231
|
+
workspace_path = self.fixture_abs_path("")
|
|
232
|
+
workspace = Workspace(workspace_path, lsp)
|
|
233
|
+
lsp.lsp._workspace = workspace
|
|
234
|
+
circle_file = uris.from_fs_path(self.fixture_abs_path("circle.jac"))
|
|
235
|
+
lsp.quick_check(circle_file)
|
|
236
|
+
lsp.deep_check(circle_file)
|
|
237
|
+
lsp.type_check(circle_file)
|
|
238
|
+
sem_list = lsp.get_semantic_tokens(circle_file).data
|
|
239
|
+
expected_counts = [
|
|
240
|
+
("<JacSemTokenType.VARIABLE: 8>, <JacSemTokenModifier.READONLY: 4>", 206),
|
|
241
|
+
(
|
|
242
|
+
"<JacSemTokenType.PROPERTY: 9>, <JacSemTokenModifier.DEFINITION: 2>,",
|
|
243
|
+
112,
|
|
244
|
+
),
|
|
245
|
+
(
|
|
246
|
+
"<JacSemTokenType.PARAMETER: 7>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
247
|
+
56,
|
|
248
|
+
),
|
|
249
|
+
(
|
|
250
|
+
"<JacSemTokenType.FUNCTION: 12>, <JacSemTokenModifier.DECLARATION: 1>,",
|
|
251
|
+
25,
|
|
252
|
+
),
|
|
253
|
+
("<JacSemTokenType.METHOD: 13>, <JacSemTokenModifier.DECLARATION: 1>", 12),
|
|
254
|
+
("<JacSemTokenType.ENUM: 3>, <JacSemTokenModifier.DECLARATION: 1>,", 37),
|
|
255
|
+
("<JacSemTokenType.CLASS: 2>, <JacSemTokenModifier.DECLARATION: ", 162),
|
|
256
|
+
(
|
|
257
|
+
"<JacSemTokenType.NAMESPACE: 0>, <JacSemTokenModifier.DEFINITION: 2>,",
|
|
258
|
+
10,
|
|
259
|
+
),
|
|
260
|
+
("0, 0, 4,", 22),
|
|
261
|
+
("0, 0, 3,", 192),
|
|
262
|
+
("0, 0, 6, ", 65),
|
|
263
|
+
(" 0, 7, 3,", 3),
|
|
264
|
+
]
|
|
265
|
+
for token_type, expected_count in expected_counts:
|
|
266
|
+
self.assertEqual(str(sem_list).count(token_type), expected_count)
|