jaclang 0.7.18__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/cli/cli.py +2 -2
- jaclang/compiler/absyntree.py +1 -1
- jaclang/compiler/parser.py +1 -1
- 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/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 +58 -30
- 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 +68 -7
- jaclang/langserve/tests/test_server.py +3 -3
- jaclang/langserve/utils.py +0 -113
- jaclang/plugin/tests/test_jaseci.py +23 -4
- jaclang/runtimelib/importer.py +3 -0
- jaclang/runtimelib/machine.py +45 -3
- jaclang/runtimelib/memory.py +1 -1
- jaclang/settings.py +4 -0
- 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/bar.jac +1 -1
- jaclang/tests/fixtures/builtins_test.jac +16 -0
- jaclang/tests/fixtures/foo.jac +0 -1
- jaclang/tests/fixtures/match_multi_ex.jac +12 -0
- jaclang/tests/fixtures/walker_update.jac +19 -0
- jaclang/tests/test_cli.py +29 -2
- jaclang/tests/test_language.py +70 -2
- jaclang/utils/treeprinter.py +1 -1
- {jaclang-0.7.18.dist-info → jaclang-0.7.20.dist-info}/METADATA +4 -2
- {jaclang-0.7.18.dist-info → jaclang-0.7.20.dist-info}/RECORD +103 -34
- {jaclang-0.7.18.dist-info → jaclang-0.7.20.dist-info}/WHEEL +0 -0
- {jaclang-0.7.18.dist-info → jaclang-0.7.20.dist-info}/entry_points.txt +0 -0
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:
|
|
@@ -349,7 +407,10 @@ class JacLangServer(LanguageServer):
|
|
|
349
407
|
elif node_selected.parent and isinstance(
|
|
350
408
|
node_selected.parent, ast.ModuleItem
|
|
351
409
|
):
|
|
352
|
-
path =
|
|
410
|
+
path = (
|
|
411
|
+
node_selected.parent.abs_path
|
|
412
|
+
or node_selected.parent.from_mod_path.abs_path
|
|
413
|
+
)
|
|
353
414
|
try: # TODO: Get rid of this when 'from' import is fixed
|
|
354
415
|
loc_range = tuple(
|
|
355
416
|
loc - 1 if loc > 0 else loc
|
|
@@ -371,7 +432,7 @@ class JacLangServer(LanguageServer):
|
|
|
371
432
|
),
|
|
372
433
|
),
|
|
373
434
|
)
|
|
374
|
-
elif isinstance(node_selected,
|
|
435
|
+
elif isinstance(node_selected, ast.ElementStmt):
|
|
375
436
|
return None
|
|
376
437
|
decl_node = (
|
|
377
438
|
node_selected.parent.body.target
|
|
@@ -218,9 +218,9 @@ class TestJacLangServer(TestCase):
|
|
|
218
218
|
)
|
|
219
219
|
lsp.deep_check(import_file)
|
|
220
220
|
positions = [
|
|
221
|
-
(6, 39, "/pygame_mock/__init__.
|
|
221
|
+
(6, 39, "/pygame_mock/__init__.pyi:2:0-2:0"),
|
|
222
222
|
(6, 45, "/pygame_mock/constants.py:3:0-4:1"),
|
|
223
|
-
(7, 31, "/pygame_mock/__init__.
|
|
223
|
+
(7, 31, "/pygame_mock/__init__.pyi:2:0-2:0"),
|
|
224
224
|
(7, 35, "/pygame_mock/constants.py:3:0-4:1"),
|
|
225
225
|
(20, 51, "/py_imp_test.jac:6:4-6:11"),
|
|
226
226
|
(20, 64, "/pygame_mock/constants.py:4:3-4:15"),
|
|
@@ -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"
|
|
@@ -340,6 +342,7 @@ class JacImporter(Importer):
|
|
|
340
342
|
spec.full_target,
|
|
341
343
|
caller_dir=spec.caller_dir,
|
|
342
344
|
cachable=spec.cachable,
|
|
345
|
+
reload=reload if reload else False,
|
|
343
346
|
)
|
|
344
347
|
try:
|
|
345
348
|
if not codeobj:
|
jaclang/runtimelib/machine.py
CHANGED
|
@@ -6,7 +6,7 @@ import os
|
|
|
6
6
|
import sys
|
|
7
7
|
import types
|
|
8
8
|
from contextvars import ContextVar
|
|
9
|
-
from typing import Optional
|
|
9
|
+
from typing import Optional, Union
|
|
10
10
|
|
|
11
11
|
from jaclang.compiler.absyntree import Module
|
|
12
12
|
from jaclang.compiler.compile import compile_jac
|
|
@@ -55,11 +55,12 @@ class JacMachine:
|
|
|
55
55
|
full_target: str,
|
|
56
56
|
caller_dir: str,
|
|
57
57
|
cachable: bool = True,
|
|
58
|
+
reload: bool = False,
|
|
58
59
|
) -> Optional[types.CodeType]:
|
|
59
60
|
"""Retrieve bytecode from the attached JacProgram."""
|
|
60
61
|
if self.jac_program:
|
|
61
62
|
return self.jac_program.get_bytecode(
|
|
62
|
-
module_name, full_target, caller_dir, cachable
|
|
63
|
+
module_name, full_target, caller_dir, cachable, reload=reload
|
|
63
64
|
)
|
|
64
65
|
return None
|
|
65
66
|
|
|
@@ -105,6 +106,46 @@ class JacMachine:
|
|
|
105
106
|
return nodes
|
|
106
107
|
return []
|
|
107
108
|
|
|
109
|
+
def update_walker(
|
|
110
|
+
self, module_name: str, items: Optional[dict[str, Union[str, Optional[str]]]]
|
|
111
|
+
) -> tuple[types.ModuleType, ...]:
|
|
112
|
+
"""Reimport the module."""
|
|
113
|
+
from .importer import JacImporter, ImportPathSpec
|
|
114
|
+
|
|
115
|
+
if module_name in self.loaded_modules:
|
|
116
|
+
try:
|
|
117
|
+
old_module = self.loaded_modules[module_name]
|
|
118
|
+
importer = JacImporter(self)
|
|
119
|
+
spec = ImportPathSpec(
|
|
120
|
+
target=module_name,
|
|
121
|
+
base_path=self.base_path,
|
|
122
|
+
absorb=False,
|
|
123
|
+
cachable=True,
|
|
124
|
+
mdl_alias=None,
|
|
125
|
+
override_name=None,
|
|
126
|
+
lng="jac",
|
|
127
|
+
items=items,
|
|
128
|
+
)
|
|
129
|
+
import_result = importer.run_import(spec, reload=True)
|
|
130
|
+
ret_items = []
|
|
131
|
+
if items:
|
|
132
|
+
for item_name in items:
|
|
133
|
+
if hasattr(old_module, item_name):
|
|
134
|
+
new_attr = getattr(import_result.ret_mod, item_name, None)
|
|
135
|
+
if new_attr:
|
|
136
|
+
ret_items.append(new_attr)
|
|
137
|
+
setattr(
|
|
138
|
+
old_module,
|
|
139
|
+
item_name,
|
|
140
|
+
new_attr,
|
|
141
|
+
)
|
|
142
|
+
return (old_module,) if not items else tuple(ret_items)
|
|
143
|
+
except Exception as e:
|
|
144
|
+
logger.error(f"Failed to update module {module_name}: {e}")
|
|
145
|
+
else:
|
|
146
|
+
logger.warning(f"Module {module_name} not found in loaded modules.")
|
|
147
|
+
return ()
|
|
148
|
+
|
|
108
149
|
@staticmethod
|
|
109
150
|
def get(base_path: str = "") -> "JacMachine":
|
|
110
151
|
"""Get current jac machine."""
|
|
@@ -134,6 +175,7 @@ class JacProgram:
|
|
|
134
175
|
full_target: str,
|
|
135
176
|
caller_dir: str,
|
|
136
177
|
cachable: bool = True,
|
|
178
|
+
reload: bool = False,
|
|
137
179
|
) -> Optional[types.CodeType]:
|
|
138
180
|
"""Get the bytecode for a specific module."""
|
|
139
181
|
if self.mod_bundle and isinstance(self.mod_bundle, Module):
|
|
@@ -141,7 +183,7 @@ class JacProgram:
|
|
|
141
183
|
return marshal.loads(codeobj) if isinstance(codeobj, bytes) else None
|
|
142
184
|
gen_dir = os.path.join(caller_dir, Con.JAC_GEN_DIR)
|
|
143
185
|
pyc_file_path = os.path.join(gen_dir, module_name + ".jbc")
|
|
144
|
-
if cachable and os.path.exists(pyc_file_path):
|
|
186
|
+
if cachable and os.path.exists(pyc_file_path) and not reload:
|
|
145
187
|
with open(pyc_file_path, "rb") as f:
|
|
146
188
|
return marshal.load(f)
|
|
147
189
|
|
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
|
jaclang/settings.py
CHANGED
|
File without changes
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from jaclang import jac_import as jac_import
|
|
2
|
+
from jaclang.cli.cmdreg import (
|
|
3
|
+
CommandShell as CommandShell,
|
|
4
|
+
cmd_registry as cmd_registry,
|
|
5
|
+
)
|
|
6
|
+
from jaclang.compiler.compile import jac_file_to_pass as jac_file_to_pass
|
|
7
|
+
from jaclang.compiler.constant import Constants as Constants
|
|
8
|
+
from jaclang.compiler.passes.main.pyast_load_pass import (
|
|
9
|
+
PyastBuildPass as PyastBuildPass,
|
|
10
|
+
)
|
|
11
|
+
from jaclang.compiler.passes.main.schedules import (
|
|
12
|
+
py_code_gen_typed as py_code_gen_typed,
|
|
13
|
+
)
|
|
14
|
+
from jaclang.compiler.passes.tool.schedules import format_pass as format_pass
|
|
15
|
+
from jaclang.plugin.builtin import dotgen as dotgen
|
|
16
|
+
from jaclang.runtimelib.constructs import Architype as Architype
|
|
17
|
+
from jaclang.utils.lang_tools import AstTool as AstTool
|
|
18
|
+
|
|
19
|
+
def format(path: str, outfile: str = "", debug: bool = False) -> None: ...
|
|
20
|
+
def run(
|
|
21
|
+
filename: str,
|
|
22
|
+
session: str = "",
|
|
23
|
+
main: bool = True,
|
|
24
|
+
cache: bool = True,
|
|
25
|
+
walker: str = "",
|
|
26
|
+
node: str = "",
|
|
27
|
+
) -> None: ...
|
|
28
|
+
def get_object(id: str, session: str = "") -> dict: ...
|
|
29
|
+
def build(filename: str) -> None: ...
|
|
30
|
+
def check(filename: str, print_errs: bool = True) -> None: ...
|
|
31
|
+
def lsp() -> None: ...
|
|
32
|
+
def enter(filename: str, entrypoint: str, args: list) -> None: ...
|
|
33
|
+
def test(
|
|
34
|
+
filepath: str,
|
|
35
|
+
filter: str = "",
|
|
36
|
+
xit: bool = False,
|
|
37
|
+
maxfail: int = None,
|
|
38
|
+
directory: str = "",
|
|
39
|
+
verbose: bool = False,
|
|
40
|
+
) -> None: ...
|
|
41
|
+
def tool(tool: str, args: list | None = None) -> None: ...
|
|
42
|
+
def clean() -> None: ...
|
|
43
|
+
def debug(filename: str, main: bool = True, cache: bool = False) -> None: ...
|
|
44
|
+
def dot(
|
|
45
|
+
filename: str,
|
|
46
|
+
session: str = "",
|
|
47
|
+
initial: str = "",
|
|
48
|
+
depth: int = -1,
|
|
49
|
+
traverse: bool = False,
|
|
50
|
+
connection: list[str] = [],
|
|
51
|
+
bfs: bool = False,
|
|
52
|
+
edge_limit: int = 512,
|
|
53
|
+
node_limit: int = 512,
|
|
54
|
+
saveto: str = "",
|
|
55
|
+
) -> None: ...
|
|
56
|
+
def py2jac(filename: str) -> None: ...
|
|
57
|
+
def jac2py(filename: str) -> None: ...
|
|
58
|
+
def start_cli() -> None: ...
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import cmd
|
|
3
|
+
import inspect
|
|
4
|
+
from _typeshed import Incomplete
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
class Command:
|
|
8
|
+
func: Callable
|
|
9
|
+
sig: inspect.Signature
|
|
10
|
+
def __init__(self, func: Callable) -> None: ...
|
|
11
|
+
def call(self, *args: list, **kwargs: dict) -> str: ...
|
|
12
|
+
|
|
13
|
+
class CommandRegistry:
|
|
14
|
+
registry: dict[str, Command]
|
|
15
|
+
sub_parsers: argparse._SubParsersAction
|
|
16
|
+
parser: argparse.ArgumentParser
|
|
17
|
+
args: argparse.Namespace
|
|
18
|
+
def __init__(self) -> None: ...
|
|
19
|
+
def register(self, func: Callable) -> Callable: ...
|
|
20
|
+
def get(self, name: str) -> Command | None: ...
|
|
21
|
+
def get_all_commands(self) -> dict: ...
|
|
22
|
+
|
|
23
|
+
cmd_registry: Incomplete
|
|
24
|
+
|
|
25
|
+
class CommandShell(cmd.Cmd):
|
|
26
|
+
intro: str
|
|
27
|
+
prompt: str
|
|
28
|
+
cmd_reg: CommandRegistry
|
|
29
|
+
def __init__(self, cmd_reg: CommandRegistry) -> None: ...
|
|
30
|
+
def do_exit(self, arg: list) -> bool: ...
|
|
31
|
+
def default(self, line: str) -> None: ...
|
|
32
|
+
def do_help(self, arg: str) -> None: ...
|