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,4 +1,9 @@
1
- """Jac to python ast link pass."""
1
+ """Jac to python ast link pass.
2
+
3
+ This pass is needed so cases where there are multiple Jac nodes relevant to a
4
+ single python node can be linked. For example FuncDef doesn't have a Name node
5
+ however Ability does.
6
+ """
2
7
 
3
8
  import ast as ast3
4
9
 
@@ -52,10 +57,13 @@ class PyJacAstLinkPass(Pass):
52
57
  decorators: Optional[SubNodeList[ExprType]],
53
58
  """
54
59
  for i in node.target.archs:
55
- if i.sym_link:
56
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
60
+ if i.name_spec.name_of.sym:
61
+ self.link_jac_py_nodes(
62
+ jac_node=i, py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast
63
+ )
57
64
  self.link_jac_py_nodes(
58
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
65
+ jac_node=i.name_spec,
66
+ py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast,
59
67
  )
60
68
 
61
69
  def exit_enum(self, node: ast.Enum) -> None:
@@ -80,10 +88,13 @@ class PyJacAstLinkPass(Pass):
80
88
  decorators: Optional[SubNodeList[ExprType]],
81
89
  """
82
90
  for i in node.target.archs:
83
- if i.sym_link:
84
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
91
+ if i.name_spec.name_of.sym:
85
92
  self.link_jac_py_nodes(
86
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
93
+ jac_node=i, py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast
94
+ )
95
+ self.link_jac_py_nodes(
96
+ jac_node=i.name_spec,
97
+ py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast,
87
98
  )
88
99
 
89
100
  def exit_ability(self, node: ast.Ability) -> None:
@@ -114,10 +125,13 @@ class PyJacAstLinkPass(Pass):
114
125
  decorators: Optional[SubNodeList[ExprType]],
115
126
  """
116
127
  for i in node.target.archs:
117
- if i.sym_link:
118
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
128
+ if i.name_spec.name_of.sym:
129
+ self.link_jac_py_nodes(
130
+ jac_node=i, py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast
131
+ )
119
132
  self.link_jac_py_nodes(
120
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
133
+ jac_node=i.name_spec,
134
+ py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast,
121
135
  )
122
136
 
123
137
  if isinstance(node.parent, ast.Ability) and node.parent.signature:
@@ -214,5 +228,5 @@ class PyJacAstLinkPass(Pass):
214
228
  """
215
229
  if node.is_attr and isinstance(node.right, ast.AstSymbolNode):
216
230
  self.link_jac_py_nodes(
217
- jac_node=node.right.sym_name_node, py_nodes=node.gen.py_ast
231
+ jac_node=node.right.name_spec, py_nodes=node.gen.py_ast
218
232
  )
@@ -35,7 +35,9 @@ class PyOutPass(Pass):
35
35
  f"Unable to find module {node.loc.mod_path} or no code present.", node
36
36
  )
37
37
  return
38
- mods = [node] + self.get_all_sub_nodes(node, ast.Module)
38
+ mods = [node] + [
39
+ i for i in self.get_all_sub_nodes(node, ast.Module) if not i.stub_only
40
+ ]
39
41
  for mod in mods:
40
42
  mod_path, out_path_py, out_path_pyc = self.get_output_targets(mod)
41
43
  if os.path.exists(out_path_pyc) and os.path.getmtime(
@@ -12,7 +12,7 @@ import pickle
12
12
  import jaclang.compiler.absyntree as ast
13
13
  from jaclang.compiler.constant import Constants as Con
14
14
  from jaclang.compiler.passes import Pass
15
- from jaclang.core.registry import SemInfo, SemRegistry
15
+ from jaclang.compiler.semtable import SemInfo, SemRegistry
16
16
  from jaclang.core.utils import get_sem_scope
17
17
 
18
18
 
@@ -48,7 +48,7 @@ class RegistryPass(Pass):
48
48
  seminfo = SemInfo(
49
49
  node.name.value,
50
50
  node.arch_type.value,
51
- node.semstr.lit_value if node.semstr else None,
51
+ node.semstr.lit_value if node.semstr else "",
52
52
  )
53
53
  if (
54
54
  len(self.modules_visited)
@@ -61,7 +61,7 @@ class RegistryPass(Pass):
61
61
  """Save enum information."""
62
62
  scope = get_sem_scope(node)
63
63
  seminfo = SemInfo(
64
- node.name.value, "Enum", node.semstr.lit_value if node.semstr else None
64
+ node.name.value, "Enum", node.semstr.lit_value if node.semstr else ""
65
65
  )
66
66
  if (
67
67
  len(self.modules_visited)
@@ -79,7 +79,7 @@ class RegistryPass(Pass):
79
79
  seminfo = SemInfo(
80
80
  node.name.value,
81
81
  extracted_type,
82
- node.semstr.lit_value if node.semstr else None,
82
+ node.semstr.lit_value if node.semstr else "",
83
83
  )
84
84
  if len(self.modules_visited) and self.modules_visited[-1].registry:
85
85
  self.modules_visited[-1].registry.add(scope, seminfo)
@@ -100,7 +100,7 @@ class RegistryPass(Pass):
100
100
  else ""
101
101
  ),
102
102
  extracted_type,
103
- node.semstr.lit_value if node.semstr else None,
103
+ node.semstr.lit_value if node.semstr else "",
104
104
  )
105
105
  if len(self.modules_visited) and self.modules_visited[-1].registry:
106
106
  self.modules_visited[-1].registry.add(scope, seminfo)
@@ -113,7 +113,7 @@ class RegistryPass(Pass):
113
113
  and node.parent.parent.__class__.__name__ == "Enum"
114
114
  ):
115
115
  scope = get_sem_scope(node)
116
- seminfo = SemInfo(node.value, None, None)
116
+ seminfo = SemInfo(node.value, None, "")
117
117
  if len(self.modules_visited) and self.modules_visited[-1].registry:
118
118
  self.modules_visited[-1].registry.add(scope, seminfo)
119
119
 
@@ -17,19 +17,6 @@ from jaclang.compiler.symtable import Symbol, SymbolAccess, SymbolTable
17
17
  class SymTabPass(Pass):
18
18
  """Jac Ast build pass."""
19
19
 
20
- def before_pass(self) -> None:
21
- """Before pass."""
22
- self.unlinked: set[ast.AstSymbolNode] = set() # Failed use lookups
23
- self.linked: set[ast.AstSymbolNode] = set() # Successful use lookups
24
-
25
- def seen(self, node: ast.AstSymbolNode) -> bool:
26
- """Check if seen."""
27
- result = node in self.linked or node in self.unlinked
28
- if node.sym_link and not result:
29
- self.linked.add(node)
30
- return True
31
- return result
32
-
33
20
  def inherit_sym_tab(self, scope: SymbolTable, sym_tab: SymbolTable) -> None:
34
21
  """Inherit symbol table."""
35
22
  for i in sym_tab.tab.values():
@@ -44,21 +31,20 @@ class SymTabPass(Pass):
44
31
  ) -> Optional[Symbol]:
45
32
  """Insert into symbol table."""
46
33
  table = table_override if table_override else node.sym_tab
47
- if self.seen(node) and node.sym_link and table == node.sym_link.parent_tab:
48
- return node.sym_link
34
+ if node.sym and table == node.sym.parent_tab:
35
+ return node.sym
49
36
  if table:
50
37
  table.insert(
51
38
  node=node, single=single_decl is not None, access_spec=access_spec
52
39
  )
53
40
  self.update_py_ctx_for_def(node)
54
- self.handle_hit_outcome(node)
55
- return node.sym_link
41
+ return node.sym
56
42
 
57
43
  def update_py_ctx_for_def(self, node: ast.AstSymbolNode) -> None:
58
44
  """Update python context for definition."""
59
- node.py_ctx_func = ast3.Store
60
- if isinstance(node.sym_name_node, ast.AstSymbolNode):
61
- node.sym_name_node.py_ctx_func = ast3.Store
45
+ node.name_spec.py_ctx_func = ast3.Store
46
+ if isinstance(node.name_spec, ast.AstSymbolNode):
47
+ node.name_spec.py_ctx_func = ast3.Store
62
48
  if isinstance(node, (ast.TupleVal, ast.ListVal)) and node.values:
63
49
  # Handling of UnaryExpr case for item is only necessary for
64
50
  # the generation of Starred nodes in the AST for examples
@@ -66,11 +52,11 @@ class SymTabPass(Pass):
66
52
  def fix(item: ast.TupleVal | ast.ListVal | ast.UnaryExpr) -> None:
67
53
  if isinstance(item, ast.UnaryExpr):
68
54
  if isinstance(item.operand, ast.AstSymbolNode):
69
- item.operand.py_ctx_func = ast3.Store
55
+ item.operand.name_spec.py_ctx_func = ast3.Store
70
56
  elif isinstance(item, (ast.TupleVal, ast.ListVal)):
71
57
  for i in item.values.items if item.values else []:
72
58
  if isinstance(i, ast.AstSymbolNode):
73
- i.py_ctx_func = ast3.Store
59
+ i.name_spec.py_ctx_func = ast3.Store
74
60
  elif isinstance(i, ast.AtomTrailer):
75
61
  self.chain_def_insert(self.unwind_atom_trailer(i))
76
62
  if isinstance(i, (ast.TupleVal, ast.ListVal, ast.UnaryExpr)):
@@ -84,28 +70,23 @@ class SymTabPass(Pass):
84
70
  sym_table: Optional[SymbolTable] = None,
85
71
  ) -> Optional[Symbol]:
86
72
  """Link to symbol."""
87
- if self.seen(node):
88
- return node.sym_link
73
+ if node.sym:
74
+ return node.sym
89
75
  if not sym_table:
90
76
  sym_table = node.sym_tab
91
77
  if sym_table:
92
- node.sym_link = (
93
- sym_table.lookup(name=node.sym_name, deep=True) if sym_table else None
94
- )
95
- # If successful lookup mark linked, add to table uses, and link others
96
- if node.sym_link:
97
- sym_table.uses.append(node)
98
- self.handle_hit_outcome(node)
99
- return node.sym_link
78
+ lookup = sym_table.lookup(name=node.sym_name, deep=True)
79
+ lookup.add_use(node.name_spec) if lookup else None
80
+ return node.sym
100
81
 
101
82
  def chain_def_insert(self, node_list: Sequence[ast.AstSymbolNode]) -> None:
102
83
  """Link chain of containing names to symbol."""
103
84
  if not node_list:
104
85
  return
105
86
  cur_sym_tab = node_list[0].sym_tab
106
- node_list[-1].py_ctx_func = ast3.Store
107
- if isinstance(node_list[-1].sym_name_node, ast.AstSymbolNode):
108
- node_list[-1].sym_name_node.py_ctx_func = ast3.Store
87
+ node_list[-1].name_spec.py_ctx_func = ast3.Store
88
+ if isinstance(node_list[-1].name_spec, ast.AstSymbolNode):
89
+ node_list[-1].name_spec.py_ctx_func = ast3.Store
109
90
 
110
91
  node_list = node_list[:-1] # Just performs lookup mappings of pre assign chain
111
92
  for i in node_list:
@@ -165,25 +146,6 @@ class SymTabPass(Pass):
165
146
  trag_list.insert(0, left)
166
147
  return trag_list
167
148
 
168
- def handle_hit_outcome(
169
- self,
170
- node: ast.AstSymbolNode,
171
- ) -> None:
172
- """Handle outcome of lookup or insert."""
173
- # If successful lookup mark linked, add to table uses, and link others
174
- if node.sym_link:
175
- self.linked.add(node)
176
- if isinstance(node.sym_name_node, ast.AstSymbolNode):
177
- node.sym_name_node.sym_link = node.sym_link
178
- if not node.sym_link:
179
- # Mark nodes that were not successfully linked
180
- self.unlinked.add(node)
181
- if (
182
- isinstance(node.sym_name_node, ast.AstSymbolNode)
183
- and not node.sym_name_node.sym_link
184
- ):
185
- self.unlinked.add(node.sym_name_node)
186
-
187
149
  def already_declared_err(
188
150
  self,
189
151
  name: str,
@@ -238,7 +200,7 @@ class SymTabBuildPass(SymTabPass):
238
200
  mod_path: str,
239
201
  is_imported: bool,
240
202
  """
241
- self.push_scope(node.name, node, fresh=True)
203
+ self.push_scope(node.name, node, fresh=(node == self.ir))
242
204
  self.sync_node_to_scope(node)
243
205
  for obj in dir(builtins):
244
206
  builtin = ast.Name(
@@ -246,6 +208,7 @@ class SymTabBuildPass(SymTabPass):
246
208
  name=Tok.NAME,
247
209
  value=str(obj),
248
210
  line=0,
211
+ end_line=0,
249
212
  col_start=0,
250
213
  col_end=0,
251
214
  pos_start=0,
@@ -253,6 +216,7 @@ class SymTabBuildPass(SymTabPass):
253
216
  )
254
217
  self.sync_node_to_scope(builtin)
255
218
  self.def_insert(builtin)
219
+ # self.def_insert(ast.Name.gen_stub_from_node(node.name, "root"))
256
220
 
257
221
  def exit_module(self, node: ast.Module) -> None:
258
222
  """Sub objects.
@@ -263,23 +227,7 @@ class SymTabBuildPass(SymTabPass):
263
227
  mod_path: str,
264
228
  is_imported: bool,
265
229
  """
266
- s = self.pop_scope()
267
- # If not the main module add all the other modules symbol table
268
- # as a child to the current symbol table
269
- if node != self.ir:
270
- self.cur_scope().kid.append(s)
271
- s.parent = self.cur_scope()
272
-
273
- if (
274
- isinstance(node.parent, ast.Module)
275
- and node
276
- in [
277
- node.parent.impl_mod,
278
- node.parent.test_mod,
279
- ]
280
- and node.sym_tab
281
- ):
282
- self.inherit_sym_tab(scope=self.cur_scope(), sym_tab=node.sym_tab)
230
+ self.pop_scope()
283
231
 
284
232
  def enter_global_vars(self, node: ast.GlobalVars) -> None:
285
233
  """Sub objects.
@@ -510,6 +458,9 @@ class SymTabBuildPass(SymTabPass):
510
458
  self.def_insert(node, access_spec=node, single_decl="ability")
511
459
  self.push_scope(node.sym_name, node)
512
460
  self.sync_node_to_scope(node)
461
+ if node.is_method:
462
+ self.def_insert(ast.Name.gen_stub_from_node(node, "self"))
463
+ self.def_insert(ast.Name.gen_stub_from_node(node, "super"))
513
464
 
514
465
  def exit_ability(self, node: ast.Ability) -> None:
515
466
  """Sub objects.
@@ -896,6 +847,13 @@ class SymTabBuildPass(SymTabPass):
896
847
  """
897
848
  self.sync_node_to_scope(node)
898
849
 
850
+ def enter_check_stmt(self, node: ast.CheckStmt) -> None:
851
+ """Sub objects.
852
+
853
+ target: Expr,
854
+ """
855
+ self.sync_node_to_scope(node)
856
+
899
857
  def enter_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
900
858
  """Sub objects.
901
859
 
@@ -1,5 +1,6 @@
1
1
  """Test pass module."""
2
2
 
3
+ import jaclang.compiler.absyntree as ast
3
4
  from jaclang.compiler.compile import jac_file_to_pass
4
5
  from jaclang.compiler.passes.main import DeclImplMatchPass
5
6
  from jaclang.utils.test import TestCase
@@ -17,15 +18,31 @@ class DeclImplMatchPassTests(TestCase):
17
18
  state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
18
19
  self.assertFalse(state.errors_had)
19
20
  self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
20
- self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
21
+ self.assertIsNotNone(
22
+ state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.name_of.body
23
+ )
21
24
  self.assertIn("(o)Test.(c)__init__", state.ir.sym_tab.tab)
22
- self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.body)
25
+ self.assertIsNotNone(
26
+ state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.name_of.body
27
+ )
23
28
 
24
29
  def test_ability_connected_to_decl_post(self) -> None:
25
30
  """Basic test for pass."""
26
31
  state = jac_file_to_pass(self.fixture_abs_path("base2.jac"), DeclImplMatchPass)
27
32
  self.assertFalse(state.errors_had)
28
33
  self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
29
- self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
34
+ self.assertIsNotNone(
35
+ state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.name_of.body
36
+ )
30
37
  self.assertIn("(o)Test.(c)__init__", state.ir.sym_tab.tab)
31
- self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.body)
38
+ self.assertIsNotNone(
39
+ state.ir.sym_tab.tab["(o)Test.(c)__init__"].decl.name_of.body
40
+ )
41
+
42
+ def test_arch_ref_has_sym(self) -> None:
43
+ """Basic test for pass."""
44
+ state = jac_file_to_pass(
45
+ self.fixture_abs_path("defs_and_uses.jac"), DeclImplMatchPass
46
+ )
47
+ for i in state.ir.get_all_sub_nodes(ast.ArchRef):
48
+ self.assertIsNotNone(i.sym)
@@ -18,13 +18,8 @@ class DefUsePassTests(TestCase):
18
18
  file_path=self.fixture_abs_path("defs_and_uses.jac"),
19
19
  target=DefUsePass,
20
20
  )
21
- # for i in state.unlinked:
22
- # print(f"Unlinked {i.__class__.__name__} {i.sym_name} {i.loc}")
23
- # for i in state.linked:
24
- # print(
25
- # f"Linked {i.__class__.__name__} {i.sym_name} {i.loc} "
26
- # f", {i.sym_link.decl.loc if i.sym_link else None}"
27
- # )
28
- self.assertGreater(len(state.linked), 5)
29
- self.assertLess(len(state.warnings_had), 50)
30
- self.assertEqual(len(state.errors_had), 0)
21
+ uses = [i.uses for i in state.ir.sym_tab.kid[0].tab.values()]
22
+ self.assertEqual(len(uses[1]), 1)
23
+ self.assertEqual(len(uses[2]), 1)
24
+ self.assertIn("output", [uses[1][0].sym_name, uses[2][0].sym_name])
25
+ self.assertIn("message", [uses[1][0].sym_name, uses[2][0].sym_name])
@@ -41,3 +41,11 @@ class ImportPassPassTests(TestCase):
41
41
  self.assertIn("autoimpl", mod_names)
42
42
  self.assertIn("autoimpl.impl", mod_names)
43
43
  self.assertIn("autoimpl.something.else.impl", mod_names)
44
+
45
+ def test_annexalbe_by_discovery(self) -> None:
46
+ """Basic test for pass."""
47
+ state = jac_file_to_pass(
48
+ self.fixture_abs_path("incautoimpl.jac"), JacImportPass
49
+ )
50
+ for i in state.ir.get_all_sub_nodes(ast.Module):
51
+ self.assertEqual(i.annexable_by, self.fixture_abs_path("autoimpl.jac"))
@@ -59,6 +59,6 @@ class MypyTypeCheckPassTests(TestCase):
59
59
  self.assertIn("HasVar - species - Type: builtins.str", out)
60
60
  self.assertIn("myDog - Type: type_info.Dog", out)
61
61
  self.assertIn("Body - Type: type_info.Dog.Body", out)
62
- self.assertEqual(out.count("Type: builtins.str"), 27)
62
+ self.assertEqual(out.count("Type: builtins.str"), 28)
63
63
  for i in lis:
64
64
  self.assertNotIn(i, out)
@@ -8,9 +8,9 @@ import os
8
8
  import pathlib
9
9
  import sys
10
10
 
11
-
12
11
  import jaclang.compiler.absyntree as ast
13
12
  import jaclang.compiler.passes.utils.mypy_ast_build as myab
13
+ from jaclang.compiler.constant import Constants as Con
14
14
  from jaclang.compiler.passes import Pass
15
15
 
16
16
 
@@ -48,6 +48,7 @@ class JacTypeCheckPass(Pass):
48
48
  """Call mypy APIs to implement type checking in Jac."""
49
49
  # Creating mypy api objects
50
50
  options = myab.myb.Options()
51
+ options.cache_dir = Con.JAC_MYPY_CACHE
51
52
  errors = myab.Errors(self, options)
52
53
  fs_cache = myab.FileSystemCache()
53
54
  search_paths = myab.compute_search_paths([], options, str(self.__path))
@@ -421,7 +421,10 @@ class JacFormatPass(Pass):
421
421
  self.emit_ln(node, "")
422
422
  self.emit_ln(node, i.gen.jac)
423
423
  if isinstance(i, ast.Token) and i.name == Tok.KW_BY:
424
- self.emit(node, f"{i.gen.jac} ")
424
+ if not node.params:
425
+ self.emit(node, f"{i.gen.jac} ")
426
+ else:
427
+ self.emit(node, f" {i.gen.jac} ")
425
428
  else:
426
429
  if (
427
430
  line_break_needed
@@ -481,7 +484,7 @@ class JacFormatPass(Pass):
481
484
 
482
485
  var: Token,
483
486
  """
484
- self.emit(node, node.var.value)
487
+ self.emit(node, node.orig.value)
485
488
 
486
489
  def exit_ability_def(self, node: ast.AbilityDef) -> None:
487
490
  """Sub objects.
@@ -1868,6 +1871,32 @@ class JacFormatPass(Pass):
1868
1871
  if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
1869
1872
  self.emit_ln(node, "")
1870
1873
 
1874
+ def exit_check_stmt(self, node: ast.CheckStmt) -> None:
1875
+ """Sub objects.
1876
+
1877
+ target: ExprType,
1878
+ """
1879
+ start = True
1880
+ for i in node.kid:
1881
+ if isinstance(i, ast.CommentToken):
1882
+ if i.is_inline:
1883
+ self.emit(node, f" {i.gen.jac}")
1884
+ else:
1885
+ if not node.gen.jac.endswith("\n"):
1886
+ self.emit_ln(node, "")
1887
+ self.emit_ln(node, "")
1888
+ self.emit(node, i.gen.jac)
1889
+ elif isinstance(i, ast.Semi):
1890
+ self.emit(node, i.gen.jac)
1891
+ else:
1892
+ if start:
1893
+ self.emit(node, i.gen.jac)
1894
+ start = False
1895
+ else:
1896
+ self.emit(node, f" {i.gen.jac}")
1897
+ if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
1898
+ self.emit_ln(node, "")
1899
+
1871
1900
  def exit_ctrl_stmt(self, node: ast.CtrlStmt) -> None:
1872
1901
  """Sub objects.
1873
1902
 
@@ -1999,7 +2028,6 @@ class JacFormatPass(Pass):
1999
2028
  doc: Optional[Token],
2000
2029
  body: CodeBlock,
2001
2030
  """
2002
- start = True
2003
2031
  for i in node.kid:
2004
2032
  if isinstance(i, ast.CommentToken):
2005
2033
  if i.is_inline:
@@ -2010,14 +2038,10 @@ class JacFormatPass(Pass):
2010
2038
  elif isinstance(i, ast.Semi):
2011
2039
  self.emit(node, i.gen.jac)
2012
2040
  elif isinstance(i, ast.Name):
2013
- if not i.value.startswith("test_t"):
2014
- self.emit(node, f" {i.value} ")
2041
+ if not i.value.startswith("_jac_gen_"):
2042
+ self.emit(node, f" {i.value}")
2015
2043
  else:
2016
- if start:
2017
- self.emit(node, i.gen.jac)
2018
- start = False
2019
- else:
2020
- self.emit(node, f" {i.gen.jac}")
2044
+ self.emit(node, i.gen.jac)
2021
2045
  if isinstance(node.kid[-1], (ast.Semi, ast.CommentToken)):
2022
2046
  self.emit_ln(node, "")
2023
2047
 
@@ -2402,7 +2426,16 @@ class JacFormatPass(Pass):
2402
2426
  and isinstance(node.parent.parent, ast.FString)
2403
2427
  ):
2404
2428
  self.emit(node, node.value)
2405
- self.emit(node, node.value)
2429
+ if "\n" in node.value:
2430
+ string_type = node.value[0:3]
2431
+ pure_string = node.value[3:-3]
2432
+ lines = pure_string.split("\n")
2433
+ self.emit(node, string_type)
2434
+ for line in lines[:-1]:
2435
+ self.emit_ln(node, line)
2436
+ self.emit_ln(node, f"{lines[-1]}{string_type}")
2437
+ else:
2438
+ self.emit(node, node.value)
2406
2439
 
2407
2440
  def enter_bool(self, node: ast.Bool) -> None:
2408
2441
  """Sub objects.
@@ -478,3 +478,19 @@ obj JacPlugin {
478
478
  (walker_obj: Any, expr: Any) -> bool {
479
479
  return walker_obj._jac_.visit_node(expr);
480
480
  }
481
+
482
+ glob expected_area = 78.53981633974483;
483
+
484
+ test a1 {
485
+ check assertAlmostEqual(calculate_area(RAD), expected_area);
486
+ }
487
+
488
+ test a2 {
489
+ c = Circle(RAD);
490
+ check assertAlmostEqual(c.area(), expected_area);
491
+ }
492
+
493
+ test a3 {
494
+ c = Circle(RAD);
495
+ check assertEqual(c.shape_type, ShapeType.CIRCLE);
496
+ }
@@ -478,3 +478,19 @@ obj JacPlugin {
478
478
  (walker_obj: Any, expr: Any) -> bool {
479
479
  return walker_obj._jac_.visit_node(expr);
480
480
  }
481
+
482
+ glob expected_area = 78.53981633974483;
483
+
484
+ test a1 {
485
+ check assertAlmostEqual(calculate_area(RAD), expected_area);
486
+ }
487
+
488
+ test a2 {
489
+ c = Circle(RAD);
490
+ check assertAlmostEqual(c.area(), expected_area);
491
+ }
492
+
493
+ test a3 {
494
+ c = Circle(RAD);
495
+ check assertEqual(c.shape_type, ShapeType.CIRCLE);
496
+ }
@@ -0,0 +1,15 @@
1
+ class foo {
2
+ """
3
+ doc string
4
+ """
5
+ can print_here() {
6
+ print("i'm here");
7
+ }
8
+
9
+ """this is a
10
+ multiline docstring
11
+ to test"""
12
+ can also_print() {
13
+ print("I'm in also");
14
+ }
15
+ }
@@ -44,8 +44,8 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
44
44
 
45
45
  if diff:
46
46
  print(f"Differences found in comparison:\n{diff}")
47
- # raise AssertionError("Files differ after formatting.")
48
- self.skipTest("Test failed, but skipping instead of failing.")
47
+ raise AssertionError("Files differ after formatting.")
48
+
49
49
  except FileNotFoundError:
50
50
  print(f"File not found: {original_file} or {formatted_file}")
51
51
  raise
@@ -76,6 +76,9 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
76
76
  self.compare_files(
77
77
  os.path.join(self.fixture_abs_path(""), "corelib_fmt.jac"),
78
78
  )
79
+ self.compare_files(
80
+ os.path.join(self.fixture_abs_path(""), "doc_string.jac"),
81
+ )
79
82
 
80
83
  def test_compare_myca_fixtures(self) -> None:
81
84
  """Tests if files in the myca fixtures directory do not change after being formatted."""
@@ -135,14 +138,13 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
135
138
  diff = "\n".join(unified_diff(before.splitlines(), after.splitlines()))
136
139
  self.assertFalse(diff, "AST structures differ after formatting.")
137
140
 
138
- except Exception:
141
+ except Exception as e:
139
142
  print(add_line_numbers(code_gen_pure.ir.source.code))
140
143
  print("\n+++++++++++++++++++++++++++++++++++++++\n")
141
144
  print(add_line_numbers(code_gen_format.ir.gen.jac))
142
145
  print("\n+++++++++++++++++++++++++++++++++++++++\n")
143
146
  print("\n".join(unified_diff(before.splitlines(), after.splitlines())))
144
- self.skipTest("Test failed, but skipping instead of failing.")
145
- # raise e
147
+ raise e
146
148
 
147
149
 
148
150
  JacFormatPassTests.self_attach_micro_tests()
@@ -30,7 +30,7 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
30
30
  self.assertEqual(x, y)
31
31
  except Exception as e:
32
32
  print("\n".join(unified_diff(x.splitlines(), y.splitlines())))
33
- self.skipTest(f"Test failed, but skipping instead of failing: {e}")
33
+ raise e
34
34
 
35
35
  def micro_suite_test(self, filename: str) -> None:
36
36
  """Parse micro jac file."""
@@ -75,7 +75,6 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
75
75
 
76
76
  except Exception as e:
77
77
  raise e
78
- # self.skipTest(f"Test failed, but skipping instead of failing: {e}")
79
78
 
80
79
 
81
80
  JacUnparseTests.self_attach_micro_tests()