jaclang 0.7.1__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 (85) hide show
  1. jaclang/cli/cli.py +2 -2
  2. jaclang/compiler/absyntree.py +378 -277
  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 +29 -11
  9. jaclang/compiler/passes/main/def_use_pass.py +48 -17
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +49 -30
  11. jaclang/compiler/passes/main/import_pass.py +12 -7
  12. jaclang/compiler/passes/main/pyast_gen_pass.py +110 -47
  13. jaclang/compiler/passes/main/pyast_load_pass.py +49 -13
  14. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +25 -11
  15. jaclang/compiler/passes/main/pyout_pass.py +3 -1
  16. jaclang/compiler/passes/main/registry_pass.py +6 -6
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +30 -72
  18. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
  19. jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
  20. jaclang/compiler/passes/main/tests/test_import_pass.py +8 -0
  21. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  22. jaclang/compiler/passes/main/type_check_pass.py +2 -1
  23. jaclang/compiler/passes/tool/jac_formatter_pass.py +44 -11
  24. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
  25. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
  26. jaclang/compiler/passes/tool/tests/fixtures/doc_string.jac +15 -0
  27. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +7 -5
  28. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +1 -2
  29. jaclang/compiler/passes/transform.py +2 -4
  30. jaclang/{core/registry.py → compiler/semtable.py} +1 -3
  31. jaclang/compiler/symtable.py +39 -31
  32. jaclang/compiler/tests/test_parser.py +2 -2
  33. jaclang/core/aott.py +112 -16
  34. jaclang/core/{construct.py → architype.py} +44 -93
  35. jaclang/core/constructs.py +44 -0
  36. jaclang/core/context.py +157 -0
  37. jaclang/core/importer.py +18 -9
  38. jaclang/core/llms/anthropic.py +31 -2
  39. jaclang/core/llms/base.py +3 -3
  40. jaclang/core/llms/groq.py +4 -1
  41. jaclang/core/llms/huggingface.py +4 -1
  42. jaclang/core/llms/ollama.py +4 -1
  43. jaclang/core/llms/openai.py +6 -2
  44. jaclang/core/llms/togetherai.py +4 -1
  45. jaclang/core/memory.py +53 -2
  46. jaclang/core/test.py +90 -0
  47. jaclang/core/utils.py +2 -2
  48. jaclang/langserve/engine.py +119 -122
  49. jaclang/langserve/server.py +27 -5
  50. jaclang/langserve/tests/fixtures/circle.jac +16 -12
  51. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  52. jaclang/langserve/tests/fixtures/circle_pure.impl.jac +8 -4
  53. jaclang/langserve/tests/fixtures/circle_pure.jac +2 -2
  54. jaclang/langserve/tests/test_server.py +114 -0
  55. jaclang/langserve/utils.py +104 -10
  56. jaclang/plugin/builtin.py +1 -1
  57. jaclang/plugin/default.py +46 -90
  58. jaclang/plugin/feature.py +32 -16
  59. jaclang/plugin/spec.py +17 -19
  60. jaclang/plugin/tests/test_features.py +0 -33
  61. jaclang/settings.py +4 -0
  62. jaclang/tests/fixtures/abc.jac +16 -12
  63. jaclang/tests/fixtures/byllmissue.jac +12 -0
  64. jaclang/tests/fixtures/edgetypetest.jac +16 -0
  65. jaclang/tests/fixtures/hash_init_check.jac +17 -0
  66. jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
  67. jaclang/tests/fixtures/impl_match_confused.jac +5 -0
  68. jaclang/tests/fixtures/math_question.jpg +0 -0
  69. jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
  70. jaclang/tests/fixtures/nosigself.jac +19 -0
  71. jaclang/tests/fixtures/run_test.jac +17 -5
  72. jaclang/tests/fixtures/walker_override.jac +21 -0
  73. jaclang/tests/fixtures/with_llm_vision.jac +25 -0
  74. jaclang/tests/test_bugs.py +19 -0
  75. jaclang/tests/test_cli.py +1 -1
  76. jaclang/tests/test_language.py +116 -11
  77. jaclang/tests/test_reference.py +1 -1
  78. jaclang/utils/lang_tools.py +5 -4
  79. jaclang/utils/test.py +2 -1
  80. jaclang/utils/treeprinter.py +35 -4
  81. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/METADATA +3 -2
  82. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/RECORD +84 -71
  83. jaclang/core/shelve_storage.py +0 -55
  84. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/WHEEL +0 -0
  85. {jaclang-0.7.1.dist-info → jaclang-0.7.5.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,15 @@
1
1
  """Utility functions for the language server."""
2
2
 
3
3
  import asyncio
4
+ import builtins
4
5
  from functools import wraps
5
6
  from typing import Any, Awaitable, Callable, Coroutine, Optional, ParamSpec, TypeVar
6
7
 
7
8
  import jaclang.compiler.absyntree as ast
8
- from jaclang.compiler.symtable import SymbolTable
9
+ from jaclang.compiler.codeloc import CodeLocInfo
10
+ from jaclang.compiler.symtable import Symbol, SymbolTable
9
11
 
12
+ import lsprotocol.types as lspt
10
13
 
11
14
  T = TypeVar("T", bound=Callable[..., Coroutine[Any, Any, Any]])
12
15
  P = ParamSpec("P")
@@ -55,17 +58,23 @@ def sym_tab_list(sym_tab: SymbolTable, file_path: str) -> list[SymbolTable]:
55
58
  return sym_tabs
56
59
 
57
60
 
58
- def find_deepest_node_at_pos(
61
+ def find_deepest_symbol_node_at_pos(
59
62
  node: ast.AstNode, line: int, character: int
60
- ) -> Optional[ast.AstNode]:
61
- """Return the deepest node that contains the given position."""
63
+ ) -> Optional[ast.AstSymbolNode]:
64
+ """Return the deepest symbol node that contains the given position."""
65
+ last_symbol_node = None
66
+
62
67
  if position_within_node(node, line, character):
63
- for i in node.kid:
64
- if position_within_node(i, line, character):
65
- return find_deepest_node_at_pos(i, line, character)
66
- return node
67
- else:
68
- return None
68
+ if isinstance(node, ast.AstSymbolNode):
69
+ last_symbol_node = node
70
+
71
+ for child in node.kid:
72
+ if position_within_node(child, line, character):
73
+ deeper_node = find_deepest_symbol_node_at_pos(child, line, character)
74
+ if deeper_node is not None:
75
+ last_symbol_node = deeper_node
76
+
77
+ return last_symbol_node
69
78
 
70
79
 
71
80
  def position_within_node(node: ast.AstNode, line: int, character: int) -> bool:
@@ -88,3 +97,88 @@ def position_within_node(node: ast.AstNode, line: int, character: int) -> bool:
88
97
  ):
89
98
  return True
90
99
  return False
100
+
101
+
102
+ def collect_symbols(node: SymbolTable) -> list[lspt.DocumentSymbol]:
103
+ """Recursively collect symbols from the AST."""
104
+ symbols = []
105
+ if node is None:
106
+ return symbols
107
+
108
+ for key, item in node.tab.items():
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
+ ):
114
+ continue
115
+ else:
116
+
117
+ pos = create_range(item.decl.loc)
118
+ symbol = lspt.DocumentSymbol(
119
+ name=key,
120
+ kind=kind_map(item.decl),
121
+ range=pos,
122
+ selection_range=pos,
123
+ children=[],
124
+ )
125
+ symbols.append(symbol)
126
+
127
+ for sub_tab in [
128
+ i for i in node.kid if i.owner.loc.mod_path == node.owner.loc.mod_path
129
+ ]:
130
+ sub_symbols = collect_symbols(sub_tab)
131
+
132
+ if isinstance(
133
+ sub_tab.owner,
134
+ (ast.IfStmt, ast.ElseStmt, ast.WhileStmt, ast.IterForStmt, ast.InForStmt),
135
+ ):
136
+ symbols.extend(sub_symbols)
137
+ else:
138
+ sub_pos = create_range(sub_tab.owner.loc)
139
+ symbol = lspt.DocumentSymbol(
140
+ name=sub_tab.name,
141
+ kind=kind_map(sub_tab.owner),
142
+ range=sub_pos,
143
+ selection_range=sub_pos,
144
+ children=sub_symbols,
145
+ )
146
+ symbols.append(symbol)
147
+
148
+ return symbols
149
+
150
+
151
+ def owner_sym(table: SymbolTable) -> Optional[Symbol]:
152
+ """Get owner sym."""
153
+ if table.has_parent() and isinstance(table.owner, ast.AstSymbolNode):
154
+ return table.parent.lookup(table.owner.sym_name)
155
+ return None
156
+
157
+
158
+ def create_range(loc: CodeLocInfo) -> lspt.Range:
159
+ """Create an lspt.Range from a location object."""
160
+ return lspt.Range(
161
+ start=lspt.Position(line=loc.first_line - 1, character=loc.col_start - 1),
162
+ end=lspt.Position(line=loc.last_line - 1, character=loc.col_end - 1),
163
+ )
164
+
165
+
166
+ def kind_map(sub_tab: ast.AstNode) -> lspt.SymbolKind:
167
+ """Map the symbol node to an lspt.SymbolKind."""
168
+ return (
169
+ lspt.SymbolKind.Function
170
+ if isinstance(sub_tab, (ast.Ability, ast.AbilityDef))
171
+ else (
172
+ lspt.SymbolKind.Class
173
+ if isinstance(sub_tab, (ast.Architype, ast.ArchDef))
174
+ else (
175
+ lspt.SymbolKind.Module
176
+ if isinstance(sub_tab, ast.Module)
177
+ else (
178
+ lspt.SymbolKind.Enum
179
+ if isinstance(sub_tab, (ast.Enum, ast.EnumDef))
180
+ else lspt.SymbolKind.Variable
181
+ )
182
+ )
183
+ )
184
+ )
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
@@ -7,40 +7,39 @@ import html
7
7
  import os
8
8
  import pickle
9
9
  import types
10
- from contextvars import ContextVar
10
+ from collections import OrderedDict
11
11
  from dataclasses import field
12
12
  from functools import wraps
13
13
  from typing import Any, Callable, Optional, Type, Union
14
- from uuid import UUID
15
14
 
16
15
  from jaclang.compiler.absyntree import Module
17
16
  from jaclang.compiler.constant import EdgeDir, colors
17
+ from jaclang.compiler.semtable import SemInfo, SemRegistry, SemScope
18
18
  from jaclang.core.aott import (
19
19
  aott_raise,
20
20
  extract_non_primary_type,
21
21
  get_all_type_explanations,
22
22
  get_info_types,
23
- get_object_string,
24
- get_type_annotation,
23
+ get_input_information,
25
24
  )
26
- from jaclang.core.construct import (
25
+ from jaclang.core.constructs import (
27
26
  Architype,
28
27
  DSFunc,
29
28
  EdgeAnchor,
30
29
  EdgeArchitype,
30
+ ExecutionContext,
31
31
  GenericEdge,
32
32
  JacTestCheck,
33
+ Memory,
33
34
  NodeAnchor,
34
35
  NodeArchitype,
35
36
  ObjectAnchor,
36
37
  Root,
37
38
  WalkerAnchor,
38
39
  WalkerArchitype,
40
+ exec_context,
39
41
  )
40
42
  from jaclang.core.importer import jac_importer
41
- from jaclang.core.memory import Memory
42
- from jaclang.core.registry import SemInfo, SemRegistry, SemScope
43
- from jaclang.core.shelve_storage import ShelveStorage
44
43
  from jaclang.core.utils import traverse_graph
45
44
  from jaclang.plugin.feature import JacFeature as Jac
46
45
  from jaclang.plugin.spec import T
@@ -70,65 +69,6 @@ __all__ = [
70
69
  hookimpl = pluggy.HookimplMarker("jac")
71
70
 
72
71
 
73
- class ExecutionContext:
74
- """Default Execution Context implementation."""
75
-
76
- mem: Optional[Memory]
77
- root: Optional[Root]
78
-
79
- def __init__(self) -> None:
80
- super().__init__()
81
- self.mem = ShelveStorage()
82
- self.root = None
83
-
84
- def init_memory(self, session: str = "") -> None:
85
- if session:
86
- self.mem = ShelveStorage(session)
87
- else:
88
- self.mem = Memory()
89
-
90
- def get_root(self) -> Root:
91
- if self.mem is None:
92
- raise ValueError("Memory not initialized")
93
-
94
- if not self.root:
95
- root = self.mem.get_obj(UUID(int=0))
96
- if root is None:
97
- self.root = Root()
98
- self.mem.save_obj(self.root, persistent=self.root._jac_.persistent)
99
- elif not isinstance(root, Root):
100
- raise ValueError(f"Invalid root object: {root}")
101
- else:
102
- self.root = root
103
- return self.root
104
-
105
- def get_obj(self, obj_id: UUID) -> Architype | None:
106
- """Get object from memory."""
107
- if self.mem is None:
108
- raise ValueError("Memory not initialized")
109
-
110
- return self.mem.get_obj(obj_id)
111
-
112
- def save_obj(self, item: Architype, persistent: bool) -> None:
113
- """Save object to memory."""
114
- if self.mem is None:
115
- raise ValueError("Memory not initialized")
116
-
117
- self.mem.save_obj(item, persistent)
118
-
119
- def reset(self) -> None:
120
- """Reset the execution context."""
121
- if self.mem:
122
- self.mem.close()
123
- self.mem = None
124
- self.root = None
125
-
126
-
127
- ExecContext: ContextVar[ExecutionContext | None] = ContextVar(
128
- "ExecutionContext", default=None
129
- )
130
-
131
-
132
72
  class JacFeatureDefaults:
133
73
  """Jac Feature."""
134
74
 
@@ -138,20 +78,20 @@ class JacFeatureDefaults:
138
78
  @hookimpl
139
79
  def context(session: str = "") -> ExecutionContext:
140
80
  """Get the execution context."""
141
- ctx = ExecContext.get()
81
+ ctx = exec_context.get()
142
82
  if ctx is None:
143
83
  ctx = ExecutionContext()
144
- ExecContext.set(ctx)
84
+ exec_context.set(ctx)
145
85
  return ctx
146
86
 
147
87
  @staticmethod
148
88
  @hookimpl
149
89
  def reset_context() -> None:
150
90
  """Reset the execution context."""
151
- ctx = ExecContext.get()
91
+ ctx = exec_context.get()
152
92
  if ctx:
153
93
  ctx.reset()
154
- ExecContext.set(None)
94
+ exec_context.set(None)
155
95
 
156
96
  @staticmethod
157
97
  @hookimpl
@@ -170,7 +110,9 @@ class JacFeatureDefaults:
170
110
  """Create a new architype."""
171
111
  for i in on_entry + on_exit:
172
112
  i.resolve(cls)
173
- if not issubclass(cls, arch_base):
113
+ if not hasattr(cls, "_jac_entry_funcs_") or not hasattr(
114
+ cls, "_jac_exit_funcs_"
115
+ ):
174
116
  # Saving the module path and reassign it after creating cls
175
117
  # So the jac modules are part of the correct module
176
118
  cur_module = cls.__module__
@@ -179,12 +121,20 @@ class JacFeatureDefaults:
179
121
  cls._jac_entry_funcs_ = on_entry # type: ignore
180
122
  cls._jac_exit_funcs_ = on_exit # type: ignore
181
123
  else:
182
- cls._jac_entry_funcs_ = cls._jac_entry_funcs_ + [
183
- x for x in on_entry if x not in cls._jac_entry_funcs_
184
- ]
185
- cls._jac_exit_funcs_ = cls._jac_exit_funcs_ + [
186
- x for x in on_exit if x not in cls._jac_exit_funcs_
187
- ]
124
+ new_entry_funcs = OrderedDict(zip([i.name for i in on_entry], on_entry))
125
+ entry_funcs = OrderedDict(
126
+ zip([i.name for i in cls._jac_entry_funcs_], cls._jac_entry_funcs_)
127
+ )
128
+ entry_funcs.update(new_entry_funcs)
129
+ cls._jac_entry_funcs_ = list(entry_funcs.values())
130
+
131
+ new_exit_funcs = OrderedDict(zip([i.name for i in on_exit], on_exit))
132
+ exit_funcs = OrderedDict(
133
+ zip([i.name for i in cls._jac_exit_funcs_], cls._jac_exit_funcs_)
134
+ )
135
+ exit_funcs.update(new_exit_funcs)
136
+ cls._jac_exit_funcs_ = list(exit_funcs.values())
137
+
188
138
  inner_init = cls.__init__ # type: ignore
189
139
 
190
140
  @wraps(inner_init)
@@ -268,7 +218,7 @@ class JacFeatureDefaults:
268
218
  cachable: bool,
269
219
  mdl_alias: Optional[str],
270
220
  override_name: Optional[str],
271
- mod_bundle: Optional[Module],
221
+ mod_bundle: Optional[Module | str],
272
222
  lng: Optional[str],
273
223
  items: Optional[dict[str, Union[str, bool]]],
274
224
  ) -> Optional[types.ModuleType]:
@@ -387,7 +337,13 @@ class JacFeatureDefaults:
387
337
  @hookimpl
388
338
  def ignore(
389
339
  walker: WalkerArchitype,
390
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
340
+ expr: (
341
+ list[NodeArchitype | EdgeArchitype]
342
+ | list[NodeArchitype]
343
+ | list[EdgeArchitype]
344
+ | NodeArchitype
345
+ | EdgeArchitype
346
+ ),
391
347
  ) -> bool:
392
348
  """Jac's ignore stmt feature."""
393
349
  return walker._jac_.ignore_node(expr)
@@ -396,7 +352,13 @@ class JacFeatureDefaults:
396
352
  @hookimpl
397
353
  def visit_node(
398
354
  walker: WalkerArchitype,
399
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
355
+ expr: (
356
+ list[NodeArchitype | EdgeArchitype]
357
+ | list[NodeArchitype]
358
+ | list[EdgeArchitype]
359
+ | NodeArchitype
360
+ | EdgeArchitype
361
+ ),
400
362
  ) -> bool:
401
363
  """Jac's visit stmt feature."""
402
364
  if isinstance(walker, WalkerArchitype):
@@ -698,16 +660,10 @@ class JacFeatureDefaults:
698
660
  incl_info = [x for x in incl_info if not isinstance(x[1], type)]
699
661
  information, collected_types = get_info_types(_scope, mod_registry, incl_info)
700
662
  type_collector.extend(collected_types)
701
- inputs_information_list = []
702
- for i in inputs:
703
- typ_anno = get_type_annotation(i[3])
704
- type_collector.extend(extract_non_primary_type(typ_anno))
705
- inputs_information_list.append(
706
- f"{i[0]} ({i[2]}) ({typ_anno}) = {get_object_string(i[3])}"
707
- )
708
- inputs_information = "\n".join(inputs_information_list)
709
663
 
710
- output_information = f"{outputs[0]} ({outputs[1]})"
664
+ inputs_information = get_input_information(inputs, type_collector)
665
+
666
+ output_information = f"{outputs[0]} ({outputs[1]})".strip()
711
667
  type_collector.extend(extract_non_primary_type(outputs[1]))
712
668
  output_type_explanations = "\n".join(
713
669
  list(
jaclang/plugin/feature.py CHANGED
@@ -3,22 +3,20 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import types
6
- from typing import Any, Callable, Optional, TYPE_CHECKING, 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.constructs import (
10
+ Architype,
11
+ EdgeArchitype,
12
+ Memory,
13
+ NodeArchitype,
14
+ Root,
15
+ WalkerArchitype,
16
+ )
17
+ from jaclang.plugin.default import ExecutionContext
9
18
  from jaclang.plugin.spec import JacBuiltin, JacCmdSpec, JacFeatureSpec, T
10
19
 
11
- if TYPE_CHECKING:
12
- from jaclang.core.construct import (
13
- Architype,
14
- EdgeArchitype,
15
- NodeArchitype,
16
- WalkerArchitype,
17
- Root,
18
- )
19
- from jaclang.plugin.default import ExecutionContext
20
- from jaclang.core.memory import Memory
21
-
22
20
 
23
21
  import pluggy
24
22
 
@@ -33,7 +31,13 @@ class JacFeature:
33
31
 
34
32
  import abc
35
33
  from jaclang.compiler.constant import EdgeDir
36
- 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
37
41
 
38
42
  @staticmethod
39
43
  def context(session: str = "") -> ExecutionContext:
@@ -98,7 +102,7 @@ class JacFeature:
98
102
  cachable: bool = True,
99
103
  mdl_alias: Optional[str] = None,
100
104
  override_name: Optional[str] = None,
101
- mod_bundle: Optional[Module] = None,
105
+ mod_bundle: Optional[Module | str] = None,
102
106
  lng: Optional[str] = "jac",
103
107
  items: Optional[dict[str, Union[str, bool]]] = None,
104
108
  ) -> Optional[types.ModuleType]:
@@ -162,7 +166,13 @@ class JacFeature:
162
166
  @staticmethod
163
167
  def ignore(
164
168
  walker: WalkerArchitype,
165
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
169
+ expr: (
170
+ list[NodeArchitype | EdgeArchitype]
171
+ | list[NodeArchitype]
172
+ | list[EdgeArchitype]
173
+ | NodeArchitype
174
+ | EdgeArchitype
175
+ ),
166
176
  ) -> bool: # noqa: ANN401
167
177
  """Jac's ignore stmt feature."""
168
178
  return pm.hook.ignore(walker=walker, expr=expr)
@@ -170,7 +180,13 @@ class JacFeature:
170
180
  @staticmethod
171
181
  def visit_node(
172
182
  walker: WalkerArchitype,
173
- expr: list[NodeArchitype | EdgeArchitype] | NodeArchitype | EdgeArchitype,
183
+ expr: (
184
+ list[NodeArchitype | EdgeArchitype]
185
+ | list[NodeArchitype]
186
+ | list[EdgeArchitype]
187
+ | NodeArchitype
188
+ | EdgeArchitype
189
+ ),
174
190
  ) -> bool: # noqa: ANN401
175
191
  """Jac's visit stmt feature."""
176
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
@@ -1,12 +1,8 @@
1
1
  """Tests for Jac parser."""
2
2
 
3
3
  import inspect
4
- import io
5
- import sys
6
- import traceback
7
4
  from typing import List, Type
8
5
 
9
- from jaclang.cli import cli
10
6
  from jaclang.plugin.default import JacFeatureDefaults
11
7
  from jaclang.plugin.feature import JacFeature
12
8
  from jaclang.plugin.spec import JacFeatureSpec
@@ -58,32 +54,3 @@ class TestFeatures(TestCase):
58
54
  self.assertEqual(jac_feature_spec_methods, jac_feature_defaults_methods)
59
55
  for i in jac_feature_spec_methods:
60
56
  self.assertIn(i, jac_feature_methods)
61
-
62
- def test_impl_match_error_reporting(self) -> None:
63
- """Basic test for error reporting."""
64
- captured_output = io.StringIO()
65
- original_stderr = sys.stderr
66
- sys.stderr = captured_output
67
-
68
- try:
69
- # Execute the function that is expected to raise an exception
70
- cli.run(self.fixture_abs_path("impl_match.jac")) # type: ignore
71
- except Exception:
72
- # Print the full stack trace to the captured output
73
- traceback.print_exc(file=captured_output)
74
- finally:
75
- # Restore the original stderr
76
- sys.stderr = original_stderr
77
-
78
- # Retrieve the captured output
79
- stderr_val = captured_output.getvalue()
80
- # Assertions or verifications
81
- try:
82
- self.assertIn("impl_match.jac", stderr_val)
83
- self.assertIn("impl_match_impl.jac", stderr_val)
84
- self.assertLess(
85
- stderr_val.index("impl_match.jac"),
86
- stderr_val.index("impl_match_impl.jac"),
87
- )
88
- except AssertionError:
89
- self.skipTest("Error reporting not implemented yet")
jaclang/settings.py CHANGED
@@ -12,11 +12,15 @@ class Settings:
12
12
  # Debug configuration
13
13
  fuse_type_info_debug: bool = False
14
14
  filter_sym_builtins: bool = True
15
+ ast_symbol_info_detailed: bool = False
15
16
 
16
17
  # Import configuration
17
18
  py_raise: bool = False
18
19
  py_raise_deep: bool = False
19
20
 
21
+ # LSP configuration
22
+ lsp_debug: bool = False
23
+
20
24
  def __post_init__(self) -> None:
21
25
  """Initialize settings."""
22
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
  }
@@ -0,0 +1,12 @@
1
+ class Foo {
2
+ '''
3
+ a doc string
4
+ '''
5
+ can bar() {
6
+ return 1;
7
+ }
8
+ }
9
+
10
+ with entry {
11
+ my_thing = YourThing(level=thingy by llm());
12
+ }
@@ -0,0 +1,16 @@
1
+
2
+ # node x {}
3
+
4
+ # edge edg {
5
+
6
+ # has name: str;
7
+
8
+ # }
9
+
10
+ # with entry {
11
+
12
+ # nodes = root +:edg:name="hello":+> x();
13
+
14
+ # print(nodes);
15
+
16
+ # }