jaclang 0.7.2__py3-none-any.whl → 0.7.5__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.

Files changed (62) hide show
  1. jaclang/cli/cli.py +2 -2
  2. jaclang/compiler/absyntree.py +337 -273
  3. jaclang/compiler/codeloc.py +2 -2
  4. jaclang/compiler/constant.py +2 -0
  5. jaclang/compiler/jac.lark +25 -19
  6. jaclang/compiler/parser.py +115 -92
  7. jaclang/compiler/passes/main/access_modifier_pass.py +15 -9
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +25 -13
  9. jaclang/compiler/passes/main/def_use_pass.py +48 -17
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +34 -34
  11. jaclang/compiler/passes/main/import_pass.py +8 -6
  12. jaclang/compiler/passes/main/pyast_gen_pass.py +97 -42
  13. jaclang/compiler/passes/main/pyast_load_pass.py +47 -12
  14. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +19 -10
  15. jaclang/compiler/passes/main/registry_pass.py +6 -6
  16. jaclang/compiler/passes/main/sym_tab_build_pass.py +30 -72
  17. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
  18. jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
  19. jaclang/compiler/passes/main/type_check_pass.py +2 -1
  20. jaclang/compiler/passes/tool/jac_formatter_pass.py +30 -9
  21. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
  22. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
  23. jaclang/compiler/passes/transform.py +2 -4
  24. jaclang/{core/registry.py → compiler/semtable.py} +1 -3
  25. jaclang/compiler/symtable.py +25 -37
  26. jaclang/compiler/tests/test_parser.py +2 -2
  27. jaclang/core/aott.py +8 -8
  28. jaclang/core/{construct.py → architype.py} +25 -240
  29. jaclang/core/constructs.py +44 -0
  30. jaclang/core/context.py +157 -0
  31. jaclang/core/importer.py +18 -9
  32. jaclang/core/memory.py +99 -0
  33. jaclang/core/test.py +90 -0
  34. jaclang/core/utils.py +2 -2
  35. jaclang/langserve/engine.py +32 -19
  36. jaclang/langserve/tests/fixtures/circle.jac +16 -12
  37. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  38. jaclang/langserve/tests/test_server.py +3 -12
  39. jaclang/langserve/utils.py +10 -6
  40. jaclang/plugin/builtin.py +1 -1
  41. jaclang/plugin/default.py +21 -7
  42. jaclang/plugin/feature.py +24 -6
  43. jaclang/plugin/spec.py +17 -19
  44. jaclang/settings.py +3 -0
  45. jaclang/tests/fixtures/abc.jac +16 -12
  46. jaclang/tests/fixtures/byllmissue.jac +9 -0
  47. jaclang/tests/fixtures/edgetypetest.jac +16 -0
  48. jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
  49. jaclang/tests/fixtures/impl_match_confused.jac +5 -0
  50. jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
  51. jaclang/tests/fixtures/run_test.jac +17 -5
  52. jaclang/tests/test_bugs.py +19 -0
  53. jaclang/tests/test_cli.py +1 -1
  54. jaclang/tests/test_language.py +56 -1
  55. jaclang/tests/test_reference.py +1 -1
  56. jaclang/utils/lang_tools.py +5 -4
  57. jaclang/utils/test.py +2 -1
  58. jaclang/utils/treeprinter.py +22 -8
  59. {jaclang-0.7.2.dist-info → jaclang-0.7.5.dist-info}/METADATA +1 -1
  60. {jaclang-0.7.2.dist-info → jaclang-0.7.5.dist-info}/RECORD +62 -54
  61. {jaclang-0.7.2.dist-info → jaclang-0.7.5.dist-info}/WHEEL +0 -0
  62. {jaclang-0.7.2.dist-info → jaclang-0.7.5.dist-info}/entry_points.txt +0 -0
jaclang/core/test.py ADDED
@@ -0,0 +1,90 @@
1
+ """Core constructs for Jac Language."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import unittest
6
+ from typing import Callable, Optional
7
+
8
+
9
+ class JacTestResult(unittest.TextTestResult):
10
+ """Jac test result class."""
11
+
12
+ def __init__(
13
+ self,
14
+ stream, # noqa
15
+ descriptions, # noqa
16
+ verbosity: int,
17
+ max_failures: Optional[int] = None,
18
+ ) -> None:
19
+ """Initialize FailFastTestResult object."""
20
+ super().__init__(stream, descriptions, verbosity) # noqa
21
+ self.failures_count = JacTestCheck.failcount
22
+ self.max_failures = max_failures
23
+
24
+ def addFailure(self, test, err) -> None: # noqa
25
+ """Count failures and stop."""
26
+ super().addFailure(test, err)
27
+ self.failures_count += 1
28
+ if self.max_failures is not None and self.failures_count >= self.max_failures:
29
+ self.stop()
30
+
31
+ def stop(self) -> None:
32
+ """Stop the test execution."""
33
+ self.shouldStop = True
34
+
35
+
36
+ class JacTextTestRunner(unittest.TextTestRunner):
37
+ """Jac test runner class."""
38
+
39
+ def __init__(self, max_failures: Optional[int] = None, **kwargs) -> None: # noqa
40
+ """Initialize JacTextTestRunner object."""
41
+ self.max_failures = max_failures
42
+ super().__init__(**kwargs)
43
+
44
+ def _makeResult(self) -> JacTestResult: # noqa
45
+ """Override the method to return an instance of JacTestResult."""
46
+ return JacTestResult(
47
+ self.stream,
48
+ self.descriptions,
49
+ self.verbosity,
50
+ max_failures=self.max_failures,
51
+ )
52
+
53
+
54
+ class JacTestCheck:
55
+ """Jac Testing and Checking."""
56
+
57
+ test_case = unittest.TestCase()
58
+ test_suite = unittest.TestSuite()
59
+ breaker = False
60
+ failcount = 0
61
+
62
+ @staticmethod
63
+ def reset() -> None:
64
+ """Clear the test suite."""
65
+ JacTestCheck.test_case = unittest.TestCase()
66
+ JacTestCheck.test_suite = unittest.TestSuite()
67
+
68
+ @staticmethod
69
+ def run_test(xit: bool, maxfail: int | None, verbose: bool) -> None:
70
+ """Run the test suite."""
71
+ verb = 2 if verbose else 1
72
+ runner = JacTextTestRunner(max_failures=maxfail, failfast=xit, verbosity=verb)
73
+ result = runner.run(JacTestCheck.test_suite)
74
+ if result.wasSuccessful():
75
+ print("Passed successfully.")
76
+ else:
77
+ fails = len(result.failures)
78
+ JacTestCheck.failcount += fails
79
+ JacTestCheck.breaker = (
80
+ (JacTestCheck.failcount >= maxfail) if maxfail else True
81
+ )
82
+
83
+ @staticmethod
84
+ def add_test(test_fun: Callable) -> None:
85
+ """Create a new test."""
86
+ JacTestCheck.test_suite.addTest(unittest.FunctionTestCase(test_fun))
87
+
88
+ def __getattr__(self, name: str) -> object:
89
+ """Make convenient check.Equal(...) etc."""
90
+ return getattr(JacTestCheck.test_case, name)
jaclang/core/utils.py CHANGED
@@ -8,10 +8,10 @@ from contextlib import contextmanager
8
8
  from typing import Callable, Iterator, TYPE_CHECKING
9
9
 
10
10
  import jaclang.compiler.absyntree as ast
11
- from jaclang.core.registry import SemScope
11
+ from jaclang.compiler.semtable import SemScope
12
12
 
13
13
  if TYPE_CHECKING:
14
- from jaclang.core.construct import NodeAnchor, NodeArchitype
14
+ from jaclang.core.constructs import NodeAnchor, NodeArchitype
15
15
 
16
16
 
17
17
  @contextmanager
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import logging
6
6
  from enum import IntEnum
7
7
  from hashlib import md5
8
- from typing import Optional, Sequence
8
+ from typing import Optional
9
9
 
10
10
 
11
11
  import jaclang.compiler.absyntree as ast
@@ -40,8 +40,8 @@ class ModuleInfo:
40
40
  def __init__(
41
41
  self,
42
42
  ir: ast.Module,
43
- errors: Sequence[Alert],
44
- warnings: Sequence[Alert],
43
+ errors: list[Alert],
44
+ warnings: list[Alert],
45
45
  alev: ALev,
46
46
  parent: Optional[ModuleInfo] = None,
47
47
  ) -> None:
@@ -63,6 +63,14 @@ class ModuleInfo:
63
63
  """Return if there are syntax errors."""
64
64
  return len(self.errors) > 0 and self.alev == ALev.QUICK
65
65
 
66
+ def update_with(self, new_info: ModuleInfo) -> None:
67
+ """Update module info."""
68
+ self.ir = new_info.ir
69
+ self.errors += [i for i in new_info.errors if i not in self.errors]
70
+ self.warnings += [i for i in new_info.warnings if i not in self.warnings]
71
+ self.alev = new_info.alev
72
+ self.diagnostics = self.gen_diagnostics()
73
+
66
74
  def gen_diagnostics(self) -> list[lspt.Diagnostic]:
67
75
  """Return diagnostics."""
68
76
  return [
@@ -124,15 +132,14 @@ class JacLangServer(LanguageServer):
124
132
  self.quick_check(file_path)
125
133
  return file_path
126
134
 
127
- def update_modules(self, file_path: str, build: Pass, alev: ALev) -> None:
135
+ def update_modules(
136
+ self, file_path: str, build: Pass, alev: ALev, refresh: bool = False
137
+ ) -> None:
128
138
  """Update modules."""
129
139
  if not isinstance(build.ir, ast.Module):
130
140
  self.log_error("Error with module build.")
131
141
  return
132
- save_parent = (
133
- self.modules[file_path].parent if file_path in self.modules else None
134
- )
135
- self.modules[file_path] = ModuleInfo(
142
+ new_mod = ModuleInfo(
136
143
  ir=build.ir,
137
144
  errors=[
138
145
  i
@@ -146,15 +153,22 @@ class JacLangServer(LanguageServer):
146
153
  ],
147
154
  alev=alev,
148
155
  )
149
- self.modules[file_path].parent = save_parent
156
+ if not refresh and file_path in self.modules:
157
+ self.modules[file_path].update_with(new_mod)
158
+ else:
159
+ self.modules[file_path] = new_mod
150
160
  for p in build.ir.mod_deps.keys():
151
161
  uri = uris.from_fs_path(p)
152
- self.modules[uri] = ModuleInfo(
162
+ new_mod = ModuleInfo(
153
163
  ir=build.ir.mod_deps[p],
154
164
  errors=[i for i in build.errors_had if i.loc.mod_path == p],
155
165
  warnings=[i for i in build.warnings_had if i.loc.mod_path == p],
156
166
  alev=alev,
157
167
  )
168
+ if not refresh and uri in self.modules:
169
+ self.modules[uri].update_with(new_mod)
170
+ else:
171
+ self.modules[uri] = new_mod
158
172
  self.modules[uri].parent = (
159
173
  self.modules[file_path] if file_path != uri else None
160
174
  )
@@ -170,7 +184,7 @@ class JacLangServer(LanguageServer):
170
184
  )
171
185
  except Exception as e:
172
186
  self.log_error(f"Error during syntax check: {e}")
173
- self.update_modules(file_path, build, ALev.QUICK)
187
+ self.update_modules(file_path, build, ALev.QUICK, refresh=True)
174
188
 
175
189
  def deep_check(self, file_path: str, force: bool = False) -> None:
176
190
  """Rebuild a file and its dependencies."""
@@ -275,21 +289,20 @@ class JacLangServer(LanguageServer):
275
289
  def get_node_info(self, node: ast.AstSymbolNode) -> Optional[str]:
276
290
  """Extract meaningful information from the AST node."""
277
291
  try:
278
- if isinstance(node, ast.NameSpec):
292
+ if isinstance(node, ast.NameAtom):
279
293
  node = node.name_of
280
- access = node.sym_link.access.value + " " if node.sym_link else None
294
+ access = node.sym.access.value + " " if node.sym else None
281
295
  node_info = (
282
- f"({access if access else ''}{node.sym_type.value}) {node.sym_name}"
296
+ f"({access if access else ''}{node.sym_category.value}) {node.sym_name}"
283
297
  )
284
- if node.sym_info.clean_type:
285
- node_info += f": {node.sym_info.clean_type}"
298
+ if node.name_spec.clean_type:
299
+ node_info += f": {node.name_spec.clean_type}"
286
300
  if isinstance(node, ast.AstSemStrNode) and node.semstr:
287
301
  node_info += f"\n{node.semstr.value}"
288
302
  if isinstance(node, ast.AstDocNode) and node.doc:
289
303
  node_info += f"\n{node.doc.value}"
290
304
  if isinstance(node, ast.Ability) and node.signature:
291
305
  node_info += f"\n{node.signature.unparse()}"
292
- self.log_py(node.pp())
293
306
  self.log_py(f"mypy_node: {node.gen.mypy_ast}")
294
307
  except AttributeError as e:
295
308
  self.log_warning(f"Attribute error when accessing node attributes: {e}")
@@ -318,8 +331,8 @@ class JacLangServer(LanguageServer):
318
331
  and isinstance(node_selected.parent, ast.AstImplNeedingNode)
319
332
  and isinstance(node_selected.parent.body, ast.AstImplOnlyNode)
320
333
  else (
321
- node_selected.sym_link.decl
322
- if (node_selected.sym_link and node_selected.sym_link.decl)
334
+ node_selected.sym.decl
335
+ if (node_selected.sym and node_selected.sym.decl)
323
336
  else node_selected
324
337
  )
325
338
  )
@@ -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(f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}");
55
- print(f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}");
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.assertAlmostEqual(calculate_area(RAD), expected_area);
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.assertAlmostEqual(c.area(), expected_area);
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.assertEqual(c.shape_type, ShapeType.CIRCLE);
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.assertAlmostEqual(calculate_area(RAD), expected_area);
62
+ check assertAlmostEqual(calculate_area(RAD), expected_area);
63
63
  }
64
64
 
65
65
  test circle_area {
66
66
  c = Circle(RAD);
67
- check.assertAlmostEqual(c.area(), expected_area);
67
+ check assertAlmostEqual(c.area(), expected_area);
68
68
  }
69
69
 
70
70
  test circle_type {
71
71
  c = Circle(RAD);
72
- check.assertEqual(c.shape_type, ShapeType.CIRCLE);
72
+ check assertEqual(c.shape_type, ShapeType.CIRCLE);
73
73
  }
@@ -143,16 +143,7 @@ class TestJacLangServer(TestCase):
143
143
  lsp.quick_check(circle_file)
144
144
  lsp.deep_check(circle_file)
145
145
  lsp.type_check(circle_file)
146
- expected_string = (
147
- "DocumentSymbol(name='calculate_area', kind=<SymbolKind.Function: 12>, range=9:0-9:43, "
148
- "selection_range=9:0-9:43, detail=None, tags=None, deprecated=None, children=["
149
- "DocumentSymbol(name='radius', kind=<SymbolKind.Variable: 13>, range=9:1-9:14, "
150
- "selection_range=9:1-9:14, detail=None, tags=None, deprecated=None, children=[])])"
151
- )
152
- self.assertEqual(
153
- expected_string, str((lsp.get_document_symbols(circle_file))[6])
154
- )
155
- self.assertEqual(10, len(lsp.get_document_symbols(circle_file)))
146
+ self.assertEqual(8, len(lsp.get_document_symbols(circle_file)))
156
147
 
157
148
  def test_go_to_definition(self) -> None:
158
149
  """Test that the go to definition is correct."""
@@ -169,7 +160,7 @@ class TestJacLangServer(TestCase):
169
160
  str(lsp.get_definition(circle_file, lspt.Position(9, 16))),
170
161
  )
171
162
  self.assertIn(
172
- "fixtures/circle_pure.jac:12:0-17:1",
163
+ "fixtures/circle_pure.jac:13:11-13:16",
173
164
  str(lsp.get_definition(circle_file, lspt.Position(20, 17))),
174
165
  )
175
166
 
@@ -186,6 +177,6 @@ class TestJacLangServer(TestCase):
186
177
  lsp.deep_check(guess_game_file)
187
178
  lsp.type_check(guess_game_file)
188
179
  self.assertIn(
189
- "guess_game4.jac:27:4-27:34",
180
+ "guess_game4.jac:27:8-27:21",
190
181
  str(lsp.get_definition(guess_game_file, lspt.Position(46, 45))),
191
182
  )
@@ -106,23 +106,27 @@ def collect_symbols(node: SymbolTable) -> list[lspt.DocumentSymbol]:
106
106
  return symbols
107
107
 
108
108
  for key, item in node.tab.items():
109
- if key in dir(builtins):
110
- continue
111
- if item in [owner_sym(tab) for tab in node.kid]:
109
+ if (
110
+ key in dir(builtins)
111
+ or item in [owner_sym(tab) for tab in node.kid]
112
+ or item.decl.loc.mod_path != node.owner.loc.mod_path
113
+ ):
112
114
  continue
113
115
  else:
114
116
 
115
- pos = create_range(item.defn[0].loc)
117
+ pos = create_range(item.decl.loc)
116
118
  symbol = lspt.DocumentSymbol(
117
119
  name=key,
118
- kind=kind_map(item.defn[0]),
120
+ kind=kind_map(item.decl),
119
121
  range=pos,
120
122
  selection_range=pos,
121
123
  children=[],
122
124
  )
123
125
  symbols.append(symbol)
124
126
 
125
- for sub_tab in node.kid:
127
+ for sub_tab in [
128
+ i for i in node.kid if i.owner.loc.mod_path == node.owner.loc.mod_path
129
+ ]:
126
130
  sub_symbols = collect_symbols(sub_tab)
127
131
 
128
132
  if isinstance(
jaclang/plugin/builtin.py CHANGED
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
6
6
 
7
7
  if TYPE_CHECKING:
8
8
  from typing import Optional
9
- from jaclang.core.construct import NodeArchitype
9
+ from jaclang.core.constructs import NodeArchitype
10
10
 
11
11
 
12
12
  def dotgen(
jaclang/plugin/default.py CHANGED
@@ -14,6 +14,7 @@ from typing import Any, Callable, Optional, Type, Union
14
14
 
15
15
  from jaclang.compiler.absyntree import Module
16
16
  from jaclang.compiler.constant import EdgeDir, colors
17
+ from jaclang.compiler.semtable import SemInfo, SemRegistry, SemScope
17
18
  from jaclang.core.aott import (
18
19
  aott_raise,
19
20
  extract_non_primary_type,
@@ -21,7 +22,7 @@ from jaclang.core.aott import (
21
22
  get_info_types,
22
23
  get_input_information,
23
24
  )
24
- from jaclang.core.construct import (
25
+ from jaclang.core.constructs import (
25
26
  Architype,
26
27
  DSFunc,
27
28
  EdgeAnchor,
@@ -39,7 +40,6 @@ from jaclang.core.construct import (
39
40
  exec_context,
40
41
  )
41
42
  from jaclang.core.importer import jac_importer
42
- from jaclang.core.registry import SemInfo, SemRegistry, SemScope
43
43
  from jaclang.core.utils import traverse_graph
44
44
  from jaclang.plugin.feature import JacFeature as Jac
45
45
  from jaclang.plugin.spec import T
@@ -110,7 +110,9 @@ class JacFeatureDefaults:
110
110
  """Create a new architype."""
111
111
  for i in on_entry + on_exit:
112
112
  i.resolve(cls)
113
- if not issubclass(cls, arch_base):
113
+ if not hasattr(cls, "_jac_entry_funcs_") or not hasattr(
114
+ cls, "_jac_exit_funcs_"
115
+ ):
114
116
  # Saving the module path and reassign it after creating cls
115
117
  # So the jac modules are part of the correct module
116
118
  cur_module = cls.__module__
@@ -216,7 +218,7 @@ class JacFeatureDefaults:
216
218
  cachable: bool,
217
219
  mdl_alias: Optional[str],
218
220
  override_name: Optional[str],
219
- mod_bundle: Optional[Module],
221
+ mod_bundle: Optional[Module | str],
220
222
  lng: Optional[str],
221
223
  items: Optional[dict[str, Union[str, bool]]],
222
224
  ) -> Optional[types.ModuleType]:
@@ -335,7 +337,13 @@ class JacFeatureDefaults:
335
337
  @hookimpl
336
338
  def ignore(
337
339
  walker: WalkerArchitype,
338
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
340
+ expr: (
341
+ list[NodeArchitype | EdgeArchitype]
342
+ | list[NodeArchitype]
343
+ | list[EdgeArchitype]
344
+ | NodeArchitype
345
+ | EdgeArchitype
346
+ ),
339
347
  ) -> bool:
340
348
  """Jac's ignore stmt feature."""
341
349
  return walker._jac_.ignore_node(expr)
@@ -344,7 +352,13 @@ class JacFeatureDefaults:
344
352
  @hookimpl
345
353
  def visit_node(
346
354
  walker: WalkerArchitype,
347
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
355
+ expr: (
356
+ list[NodeArchitype | EdgeArchitype]
357
+ | list[NodeArchitype]
358
+ | list[EdgeArchitype]
359
+ | NodeArchitype
360
+ | EdgeArchitype
361
+ ),
348
362
  ) -> bool:
349
363
  """Jac's visit stmt feature."""
350
364
  if isinstance(walker, WalkerArchitype):
@@ -649,7 +663,7 @@ class JacFeatureDefaults:
649
663
 
650
664
  inputs_information = get_input_information(inputs, type_collector)
651
665
 
652
- output_information = f"{outputs[0]} ({outputs[1]})"
666
+ output_information = f"{outputs[0]} ({outputs[1]})".strip()
653
667
  type_collector.extend(extract_non_primary_type(outputs[1]))
654
668
  output_type_explanations = "\n".join(
655
669
  list(
jaclang/plugin/feature.py CHANGED
@@ -3,10 +3,10 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import types
6
- from typing import Any, Callable, Optional, Type, Union
6
+ from typing import Any, Callable, Optional, Type, TypeAlias, Union
7
7
 
8
8
  from jaclang.compiler.absyntree import Module
9
- from jaclang.core.construct import (
9
+ from jaclang.core.constructs import (
10
10
  Architype,
11
11
  EdgeArchitype,
12
12
  Memory,
@@ -31,7 +31,13 @@ class JacFeature:
31
31
 
32
32
  import abc
33
33
  from jaclang.compiler.constant import EdgeDir
34
- from jaclang.plugin.spec import DSFunc
34
+ from jaclang.core.constructs import DSFunc
35
+
36
+ RootType: TypeAlias = Root
37
+ Obj: TypeAlias = Architype
38
+ Node: TypeAlias = NodeArchitype
39
+ Edge: TypeAlias = EdgeArchitype
40
+ Walker: TypeAlias = WalkerArchitype
35
41
 
36
42
  @staticmethod
37
43
  def context(session: str = "") -> ExecutionContext:
@@ -96,7 +102,7 @@ class JacFeature:
96
102
  cachable: bool = True,
97
103
  mdl_alias: Optional[str] = None,
98
104
  override_name: Optional[str] = None,
99
- mod_bundle: Optional[Module] = None,
105
+ mod_bundle: Optional[Module | str] = None,
100
106
  lng: Optional[str] = "jac",
101
107
  items: Optional[dict[str, Union[str, bool]]] = None,
102
108
  ) -> Optional[types.ModuleType]:
@@ -160,7 +166,13 @@ class JacFeature:
160
166
  @staticmethod
161
167
  def ignore(
162
168
  walker: WalkerArchitype,
163
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
169
+ expr: (
170
+ list[NodeArchitype | EdgeArchitype]
171
+ | list[NodeArchitype]
172
+ | list[EdgeArchitype]
173
+ | NodeArchitype
174
+ | EdgeArchitype
175
+ ),
164
176
  ) -> bool: # noqa: ANN401
165
177
  """Jac's ignore stmt feature."""
166
178
  return pm.hook.ignore(walker=walker, expr=expr)
@@ -168,7 +180,13 @@ class JacFeature:
168
180
  @staticmethod
169
181
  def visit_node(
170
182
  walker: WalkerArchitype,
171
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
183
+ expr: (
184
+ list[NodeArchitype | EdgeArchitype]
185
+ | list[NodeArchitype]
186
+ | list[EdgeArchitype]
187
+ | NodeArchitype
188
+ | EdgeArchitype
189
+ ),
172
190
  ) -> bool: # noqa: ANN401
173
191
  """Jac's visit stmt feature."""
174
192
  return pm.hook.visit_node(walker=walker, expr=expr)
jaclang/plugin/spec.py CHANGED
@@ -3,19 +3,19 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import types
6
- from dataclasses import dataclass
7
6
  from typing import Any, Callable, Optional, TYPE_CHECKING, Type, TypeVar, Union
8
7
 
9
8
  from jaclang.compiler.absyntree import Module
10
9
 
11
10
  if TYPE_CHECKING:
12
- from jaclang.core.construct import EdgeArchitype, NodeArchitype
11
+ from jaclang.core.constructs import EdgeArchitype, NodeArchitype
13
12
  from jaclang.plugin.default import (
14
13
  Architype,
15
14
  EdgeDir,
16
15
  ExecutionContext,
17
16
  WalkerArchitype,
18
17
  Root,
18
+ DSFunc,
19
19
  )
20
20
  from jaclang.core.memory import Memory
21
21
 
@@ -26,20 +26,6 @@ hookspec = pluggy.HookspecMarker("jac")
26
26
  T = TypeVar("T")
27
27
 
28
28
 
29
- # TODO: DSFunc should be moved into jaclang/core
30
- @dataclass(eq=False)
31
- class DSFunc:
32
- """Data Spatial Function."""
33
-
34
- name: str
35
- trigger: type | types.UnionType | tuple[type | types.UnionType, ...] | None
36
- func: Callable[[Any, Any], Any] | None = None
37
-
38
- def resolve(self, cls: type) -> None:
39
- """Resolve the function."""
40
- self.func = getattr(cls, self.name)
41
-
42
-
43
29
  class JacFeatureSpec:
44
30
  """Jac Feature."""
45
31
 
@@ -113,7 +99,7 @@ class JacFeatureSpec:
113
99
  cachable: bool,
114
100
  mdl_alias: Optional[str],
115
101
  override_name: Optional[str],
116
- mod_bundle: Optional[Module],
102
+ mod_bundle: Optional[Module | str],
117
103
  lng: Optional[str],
118
104
  items: Optional[dict[str, Union[str, bool]]],
119
105
  ) -> Optional[types.ModuleType]:
@@ -167,7 +153,13 @@ class JacFeatureSpec:
167
153
  @hookspec(firstresult=True)
168
154
  def ignore(
169
155
  walker: WalkerArchitype,
170
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
156
+ expr: (
157
+ list[NodeArchitype | EdgeArchitype]
158
+ | list[NodeArchitype]
159
+ | list[EdgeArchitype]
160
+ | NodeArchitype
161
+ | EdgeArchitype
162
+ ),
171
163
  ) -> bool:
172
164
  """Jac's ignore stmt feature."""
173
165
  raise NotImplementedError
@@ -176,7 +168,13 @@ class JacFeatureSpec:
176
168
  @hookspec(firstresult=True)
177
169
  def visit_node(
178
170
  walker: WalkerArchitype,
179
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
171
+ expr: (
172
+ list[NodeArchitype | EdgeArchitype]
173
+ | list[NodeArchitype]
174
+ | list[EdgeArchitype]
175
+ | NodeArchitype
176
+ | EdgeArchitype
177
+ ),
180
178
  ) -> bool: # noqa: ANN401
181
179
  """Jac's visit stmt feature."""
182
180
  raise NotImplementedError
jaclang/settings.py CHANGED
@@ -18,6 +18,9 @@ class Settings:
18
18
  py_raise: bool = False
19
19
  py_raise_deep: bool = False
20
20
 
21
+ # LSP configuration
22
+ lsp_debug: bool = False
23
+
21
24
  def __post_init__(self) -> None:
22
25
  """Initialize settings."""
23
26
  home_dir = os.path.expanduser("~")
@@ -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(f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}");
55
- print(f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}");
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.assertAlmostEqual(calculate_area(RAD), expected_area);
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.assertAlmostEqual(c.area(), expected_area);
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.assertEqual(c.shape_type, ShapeType.CIRCLE);
76
+ check assertEqual(c.shape_type, ShapeType.CIRCLE);
73
77
  }