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

@@ -140,7 +140,7 @@ class JacParser(Pass):
140
140
  body = kid[1:] if doc else kid
141
141
  body = [i for i in body if isinstance(i, ast.ElementStmt)]
142
142
  mod = ast.Module(
143
- name=self.parse_ref.mod_path.split(os.path.sep)[-1].split(".")[0],
143
+ name=self.parse_ref.mod_path.split(os.path.sep)[-1].rstrip(".jac"),
144
144
  source=self.parse_ref.source,
145
145
  doc=doc,
146
146
  body=body,
@@ -72,7 +72,10 @@ class DeclDefMatchPass(Pass):
72
72
  continue
73
73
  decl_node.body = sym.decl # type: ignore
74
74
  sym.decl.decl_link = decl_node # type: ignore
75
- decl_node.add_kids_right([sym.decl], pos_update=False) # type: ignore
75
+ source_node = sym.decl.parent
76
+ decl_node.add_kids_right([sym.decl]) # type: ignore
77
+ if source_node and sym.decl in source_node.kid:
78
+ source_node.kid.remove(sym.decl)
76
79
  decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
77
80
  for i in sym_tab.kid:
78
81
  self.connect_def_impl(i)
@@ -48,8 +48,16 @@ class FuseTypeInfoPass(Pass):
48
48
  def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
49
49
  typ = node.sym_info.typ.split(".")
50
50
  typ_sym_table = self.ir.sym_tab
51
- if typ_sym_table and typ[0] == typ_sym_table.name:
52
- for i in typ[1:]:
51
+
52
+ if typ[0] == "builtins":
53
+ return
54
+
55
+ assert isinstance(self.ir, ast.Module)
56
+
57
+ if typ_sym_table:
58
+ for i in typ:
59
+ if i == self.ir.name:
60
+ continue
53
61
  f = typ_sym_table.find_scope(i)
54
62
  if f:
55
63
  typ_sym_table = f
@@ -159,11 +167,6 @@ class FuseTypeInfoPass(Pass):
159
167
  type(mypy_node),
160
168
  )
161
169
 
162
- def enter_import(self, node: ast.Import) -> None:
163
- """Pass handler for import nodes."""
164
- # Pruning the import nodes
165
- self.prune()
166
-
167
170
  @__handle_node
168
171
  def enter_name(self, node: ast.NameSpec) -> None:
169
172
  """Pass handler for name nodes."""
@@ -7,8 +7,8 @@ symbols are available for matching.
7
7
 
8
8
  import ast as py_ast
9
9
  import importlib.util
10
+ import os
10
11
  import sys
11
- from os import path
12
12
  from typing import Optional
13
13
 
14
14
 
@@ -40,7 +40,6 @@ class JacImportPass(Pass):
40
40
  self.process_import(node, i)
41
41
  self.enter_module_path(i)
42
42
  SubNodeTabPass(prior=self, input_ir=node)
43
- self.annex_impl(node)
44
43
  node.mod_deps = self.import_table
45
44
 
46
45
  def process_import(self, node: ast.Module, i: ast.ModulePath) -> None:
@@ -53,7 +52,6 @@ class JacImportPass(Pass):
53
52
  )
54
53
  if mod:
55
54
  self.run_again = True
56
- self.annex_impl(mod)
57
55
  i.sub_module = mod
58
56
  i.add_kids_right([mod], pos_update=False)
59
57
 
@@ -61,22 +59,41 @@ class JacImportPass(Pass):
61
59
  """Annex impl and test modules."""
62
60
  if not node.loc.mod_path:
63
61
  self.error("Module has no path")
64
- if node.loc.mod_path.endswith(".jac") and path.exists(
65
- f"{node.loc.mod_path[:-4]}.impl.jac"
66
- ):
67
- mod = self.import_mod_from_file(f"{node.loc.mod_path[:-4]}.impl.jac")
68
- if mod:
69
- node.impl_mod = mod
70
- node.add_kids_left([mod], pos_update=False)
71
- mod.parent = node
72
- if node.loc.mod_path.endswith(".jac") and path.exists(
73
- f"{node.loc.mod_path[:-4]}.test.jac"
74
- ):
75
- mod = self.import_mod_from_file(f"{node.loc.mod_path[:-4]}.test.jac")
76
- if mod:
77
- node.test_mod = mod
78
- node.add_kids_right([mod], pos_update=False)
79
- mod.parent = node
62
+ if not node.loc.mod_path.endswith(".jac"):
63
+ return
64
+ base_path = node.loc.mod_path[:-4]
65
+ directory = os.path.dirname(node.loc.mod_path)
66
+ if not directory:
67
+ directory = os.getcwd()
68
+ base_path = os.path.join(directory, base_path)
69
+ impl_folder = base_path + ".impl"
70
+ search_files = [
71
+ os.path.join(directory, impl_file) for impl_file in os.listdir(directory)
72
+ ]
73
+ if os.path.exists(impl_folder):
74
+ search_files += [
75
+ os.path.join(impl_folder, impl_file)
76
+ for impl_file in os.listdir(impl_folder)
77
+ ]
78
+ for impl_file in search_files:
79
+ if node.loc.mod_path.endswith(impl_file):
80
+ continue
81
+ if (
82
+ impl_file.startswith(f"{base_path}.") or impl_folder in impl_file
83
+ ) and impl_file.endswith(".impl.jac"):
84
+ mod = self.import_mod_from_file(impl_file)
85
+ if mod:
86
+ node.impl_mod.append(mod)
87
+ node.add_kids_left([mod], pos_update=False)
88
+ mod.parent = node
89
+ if (
90
+ impl_file.startswith(f"{base_path}.") or impl_folder in impl_file
91
+ ) and impl_file.endswith(".test.jac"):
92
+ mod = self.import_mod_from_file(impl_file)
93
+ if mod:
94
+ node.test_mod = mod
95
+ node.add_kids_right([mod], pos_update=False)
96
+ mod.parent = node
80
97
 
81
98
  def enter_module_path(self, node: ast.ModulePath) -> None:
82
99
  """Sub objects.
@@ -96,7 +113,7 @@ class JacImportPass(Pass):
96
113
  """Import a module."""
97
114
  self.cur_node = node # impacts error reporting
98
115
  target = import_target_to_relative_path(
99
- node.level, node.path_str, path.dirname(node.loc.mod_path)
116
+ node.level, node.path_str, os.path.dirname(node.loc.mod_path)
100
117
  )
101
118
  return self.import_mod_from_file(target)
102
119
 
@@ -105,7 +122,7 @@ class JacImportPass(Pass):
105
122
  from jaclang.compiler.compile import jac_file_to_pass
106
123
  from jaclang.compiler.passes.main import SubNodeTabPass
107
124
 
108
- if not path.exists(target):
125
+ if not os.path.exists(target):
109
126
  self.error(f"Could not find module {target}")
110
127
  return None
111
128
  if target in self.import_table:
@@ -133,7 +150,7 @@ class JacImportPass(Pass):
133
150
  """Import a module."""
134
151
  from jaclang.compiler.passes.main import PyastBuildPass
135
152
 
136
- base_dir = path.dirname(mod_path)
153
+ base_dir = os.path.dirname(mod_path)
137
154
  sys.path.append(base_dir)
138
155
 
139
156
  try:
@@ -19,8 +19,6 @@ T = TypeVar("T", bound=ast3.AST)
19
19
  class PyastGenPass(Pass):
20
20
  """Jac blue transpilation to python pass."""
21
21
 
22
- cout = 1
23
-
24
22
  @staticmethod
25
23
  def node_compilable_test(node: ast3.AST) -> None:
26
24
  """Convert any AST node to a compilable module node."""
@@ -214,25 +212,18 @@ class PyastGenPass(Pass):
214
212
  i.end_lineno = (
215
213
  jac_node.loc.last_line
216
214
  if jac_node.loc.last_line
215
+ and (jac_node.loc.last_line > jac_node.loc.first_line)
217
216
  else jac_node.loc.first_line
218
217
  )
219
218
  i.end_col_offset = (
220
219
  jac_node.loc.col_end
221
220
  if jac_node.loc.col_end
221
+ and (jac_node.loc.col_end > jac_node.loc.col_start)
222
222
  else jac_node.loc.col_start
223
223
  )
224
224
  i.jac_link: list[ast3.AST] = [jac_node] # type: ignore
225
225
  return py_node
226
226
 
227
- def link_jac_py_nodes(
228
- self, jac_node: ast.AstNode, py_nodes: list[ast3.AST]
229
- ) -> None:
230
- """Link jac name ast to py ast nodes."""
231
- jac_node.gen.py_ast = py_nodes
232
- for i in py_nodes:
233
- if isinstance(i.jac_link, list): # type: ignore
234
- i.jac_link.append(jac_node) # type: ignore
235
-
236
227
  def pyinline_sync(
237
228
  self,
238
229
  py_nodes: list[ast3.AST],
@@ -329,7 +320,10 @@ class PyastGenPass(Pass):
329
320
  is_imported: bool,
330
321
  """
331
322
  clean_body = [i for i in node.body if not isinstance(i, ast.AstImplOnlyNode)]
332
- pre_body = [*node.impl_mod.body, *clean_body] if node.impl_mod else clean_body
323
+ pre_body: list[ast.AstNode] = []
324
+ for pbody in node.impl_mod:
325
+ pre_body = [*pre_body, *pbody.body]
326
+ pre_body = [*pre_body, *clean_body]
333
327
  pre_body = [*pre_body, *node.test_mod.body] if node.test_mod else pre_body
334
328
  body = (
335
329
  [
@@ -648,8 +642,6 @@ class PyastGenPass(Pass):
648
642
  )
649
643
  )
650
644
  ]
651
- if node.alias:
652
- self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
653
645
 
654
646
  def exit_module_item(self, node: ast.ModuleItem) -> None:
655
647
  """Sub objects.
@@ -776,9 +768,6 @@ class PyastGenPass(Pass):
776
768
  )
777
769
  )
778
770
  ]
779
- self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
780
- if isinstance(node.body, ast.ArchDef):
781
- self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
782
771
 
783
772
  def collect_events(
784
773
  self, node: ast.Architype
@@ -831,12 +820,6 @@ class PyastGenPass(Pass):
831
820
  doc: Optional[String],
832
821
  decorators: Optional[SubNodeList[ExprType]],
833
822
  """
834
- for i in node.target.archs:
835
- if i.sym_link:
836
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
837
- self.link_jac_py_nodes(
838
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
839
- )
840
823
 
841
824
  def exit_enum(self, node: ast.Enum) -> None:
842
825
  """Sub objects.
@@ -877,8 +860,6 @@ class PyastGenPass(Pass):
877
860
  )
878
861
  )
879
862
  ]
880
- if isinstance(node.body, ast.EnumDef):
881
- self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
882
863
 
883
864
  def exit_enum_def(self, node: ast.EnumDef) -> None:
884
865
  """Sub objects.
@@ -888,12 +869,6 @@ class PyastGenPass(Pass):
888
869
  doc: Optional[String],
889
870
  decorators: Optional[SubNodeList[ExprType]],
890
871
  """
891
- for i in node.target.archs:
892
- if i.sym_link:
893
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
894
- self.link_jac_py_nodes(
895
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
896
- )
897
872
 
898
873
  def exit_ability(self, node: ast.Ability) -> None:
899
874
  """Sub objects.
@@ -995,9 +970,6 @@ class PyastGenPass(Pass):
995
970
  )
996
971
  )
997
972
  ]
998
- self.link_jac_py_nodes(jac_node=node.name_ref, py_nodes=node.gen.py_ast)
999
- if isinstance(node.body, ast.AbilityDef):
1000
- self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
1001
973
 
1002
974
  def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
1003
975
  """Generate llm body."""
@@ -1291,15 +1263,6 @@ class PyastGenPass(Pass):
1291
1263
  doc: Optional[String],
1292
1264
  decorators: Optional[SubNodeList[ExprType]],
1293
1265
  """
1294
- for i in node.target.archs:
1295
- if i.sym_link:
1296
- self.link_jac_py_nodes(jac_node=i, py_nodes=i.sym_link.decl.gen.py_ast)
1297
- self.link_jac_py_nodes(
1298
- jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
1299
- )
1300
- if isinstance(node.parent, ast.Ability) and node.parent.signature:
1301
- # TODO: Here we need to do a link for each subnode to the original parent signature
1302
- pass
1303
1266
 
1304
1267
  def exit_func_signature(self, node: ast.FuncSignature) -> None:
1305
1268
  """Sub objects.
@@ -1464,7 +1427,6 @@ class PyastGenPass(Pass):
1464
1427
  )
1465
1428
  )
1466
1429
  ]
1467
- self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
1468
1430
 
1469
1431
  def exit_arch_has(self, node: ast.ArchHas) -> None:
1470
1432
  """Sub objects.
@@ -1720,8 +1682,6 @@ class PyastGenPass(Pass):
1720
1682
  )
1721
1683
  )
1722
1684
  ]
1723
- if node.name:
1724
- self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
1725
1685
 
1726
1686
  def exit_finally_stmt(self, node: ast.FinallyStmt) -> None:
1727
1687
  """Sub objects.
@@ -1829,9 +1789,6 @@ class PyastGenPass(Pass):
1829
1789
  )
1830
1790
  )
1831
1791
  ]
1832
- self.link_jac_py_nodes(jac_node=node.expr, py_nodes=node.gen.py_ast)
1833
- if node.alias:
1834
- self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
1835
1792
 
1836
1793
  def exit_raise_stmt(self, node: ast.RaiseStmt) -> None:
1837
1794
  """Sub objects.
@@ -2089,7 +2046,6 @@ class PyastGenPass(Pass):
2089
2046
  jac_node=x,
2090
2047
  )
2091
2048
  )
2092
- self.link_jac_py_nodes(jac_node=x, py_nodes=[py_nodes[-1]])
2093
2049
  node.gen.py_ast = [*py_nodes]
2094
2050
 
2095
2051
  def exit_non_local_stmt(self, node: ast.NonLocalStmt) -> None:
@@ -2105,7 +2061,6 @@ class PyastGenPass(Pass):
2105
2061
  jac_node=x,
2106
2062
  )
2107
2063
  )
2108
- self.link_jac_py_nodes(jac_node=x, py_nodes=[py_nodes[-1]])
2109
2064
  node.gen.py_ast = [*py_nodes]
2110
2065
 
2111
2066
  def exit_assignment(self, node: ast.Assignment) -> None:
@@ -2647,8 +2602,6 @@ class PyastGenPass(Pass):
2647
2602
  )
2648
2603
  )
2649
2604
  ]
2650
- if node.key:
2651
- self.link_jac_py_nodes(jac_node=node.key, py_nodes=node.gen.py_ast)
2652
2605
 
2653
2606
  def exit_inner_compr(self, node: ast.InnerCompr) -> None:
2654
2607
  """Sub objects.
@@ -2758,9 +2711,6 @@ class PyastGenPass(Pass):
2758
2711
  )
2759
2712
  )
2760
2713
  ]
2761
- self.link_jac_py_nodes(
2762
- jac_node=node.right.sym_name_node, py_nodes=node.gen.py_ast
2763
- )
2764
2714
  else:
2765
2715
  self.error("Invalid attribute access")
2766
2716
  elif isinstance(node.right, ast.FilterCompr):
@@ -3025,7 +2975,6 @@ class PyastGenPass(Pass):
3025
2975
  for kw_pair in node.params.items
3026
2976
  if isinstance(kw_pair, ast.KWPair)
3027
2977
  ]
3028
- self.cout += 1
3029
2978
  else:
3030
2979
  inputs = []
3031
2980
 
@@ -0,0 +1,218 @@
1
+ """Jac to python ast link pass."""
2
+
3
+ import ast as ast3
4
+
5
+ import jaclang.compiler.absyntree as ast
6
+ from jaclang.compiler.passes import Pass
7
+
8
+
9
+ class PyJacAstLinkPass(Pass):
10
+ """Link jac ast to python ast nodes."""
11
+
12
+ def link_jac_py_nodes(
13
+ self, jac_node: ast.AstNode, py_nodes: list[ast3.AST]
14
+ ) -> None:
15
+ """Link jac name ast to py ast nodes."""
16
+ jac_node.gen.py_ast = py_nodes
17
+ for i in py_nodes:
18
+ if isinstance(i.jac_link, list): # type: ignore
19
+ i.jac_link.append(jac_node) # type: ignore
20
+
21
+ def exit_module_path(self, node: ast.ModulePath) -> None:
22
+ """Sub objects.
23
+
24
+ path: Sequence[Token],
25
+ alias: Optional[Name],
26
+ path_str: str,
27
+ """
28
+ if node.alias:
29
+ self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
30
+
31
+ def exit_architype(self, node: ast.Architype) -> None:
32
+ """Sub objects.
33
+
34
+ name: Name,
35
+ arch_type: Token,
36
+ access: Optional[SubTag[Token]],
37
+ base_classes: Optional[SubNodeList[AtomType]],
38
+ body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
39
+ doc: Optional[String],
40
+ decorators: Optional[SubNodeList[ExprType]],
41
+ """
42
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
43
+ if isinstance(node.body, ast.ArchDef):
44
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
45
+
46
+ def exit_arch_def(self, node: ast.ArchDef) -> None:
47
+ """Sub objects.
48
+
49
+ target: ArchRefChain,
50
+ body: SubNodeList[ArchBlockStmt],
51
+ doc: Optional[String],
52
+ decorators: Optional[SubNodeList[ExprType]],
53
+ """
54
+ 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)
57
+ self.link_jac_py_nodes(
58
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
59
+ )
60
+
61
+ def exit_enum(self, node: ast.Enum) -> None:
62
+ """Sub objects.
63
+
64
+ name: Name,
65
+ access: Optional[SubTag[Token]],
66
+ base_classes: Optional[Optional[SubNodeList[AtomType]]],
67
+ body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
68
+ doc: Optional[String],
69
+ decorators: Optional[SubNodeList[ExprType]],
70
+ """
71
+ if isinstance(node.body, ast.EnumDef):
72
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
73
+
74
+ def exit_enum_def(self, node: ast.EnumDef) -> None:
75
+ """Sub objects.
76
+
77
+ target: ArchRefChain,
78
+ body: SubNodeList[EnumBlockStmt],
79
+ doc: Optional[String],
80
+ decorators: Optional[SubNodeList[ExprType]],
81
+ """
82
+ 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)
85
+ self.link_jac_py_nodes(
86
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
87
+ )
88
+
89
+ def exit_ability(self, node: ast.Ability) -> None:
90
+ """Sub objects.
91
+
92
+ name_ref: NameType,
93
+ is_func: bool,
94
+ is_async: bool,
95
+ is_static: bool,
96
+ is_abstract: bool,
97
+ access: Optional[SubTag[Token]],
98
+ signature: Optional[FuncSignature | ExprType | EventSignature],
99
+ body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef | FuncCall],
100
+ doc: Optional[String],
101
+ decorators: Optional[SubNodeList[ExprType]],
102
+ """
103
+ self.link_jac_py_nodes(jac_node=node.name_ref, py_nodes=node.gen.py_ast)
104
+ if isinstance(node.body, ast.AbilityDef):
105
+ self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
106
+
107
+ def exit_ability_def(self, node: ast.AbilityDef) -> None:
108
+ """Sub objects.
109
+
110
+ target: ArchRefChain,
111
+ signature: FuncSignature | EventSignature,
112
+ body: SubNodeList[CodeBlockStmt],
113
+ doc: Optional[String],
114
+ decorators: Optional[SubNodeList[ExprType]],
115
+ """
116
+ 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)
119
+ self.link_jac_py_nodes(
120
+ jac_node=i.name_ref, py_nodes=i.sym_link.decl.gen.py_ast
121
+ )
122
+
123
+ if isinstance(node.parent, ast.Ability) and node.parent.signature:
124
+ if isinstance(node.signature, ast.FuncSignature) and node.signature.params:
125
+ for src_prm in node.signature.params.items:
126
+ if (
127
+ isinstance(node.parent.signature, ast.FuncSignature)
128
+ and node.parent.signature.params
129
+ ):
130
+ for trg_prm in node.parent.signature.params.items:
131
+ if src_prm.name.sym_name == trg_prm.name.sym_name:
132
+ self.link_jac_py_nodes(
133
+ jac_node=src_prm, py_nodes=trg_prm.gen.py_ast
134
+ )
135
+ self.link_jac_py_nodes(
136
+ jac_node=src_prm.name,
137
+ py_nodes=trg_prm.name.gen.py_ast,
138
+ )
139
+ if (
140
+ isinstance(node.signature, ast.FuncSignature)
141
+ and node.signature.return_type
142
+ ) and (
143
+ isinstance(node.parent.signature, ast.FuncSignature)
144
+ and node.parent.signature.return_type
145
+ ):
146
+ self.link_jac_py_nodes(
147
+ jac_node=node.signature.return_type,
148
+ py_nodes=node.parent.signature.return_type.gen.py_ast,
149
+ )
150
+
151
+ def exit_param_var(self, node: ast.ParamVar) -> None:
152
+ """Sub objects.
153
+
154
+ name: Name,
155
+ unpack: Optional[Token],
156
+ type_tag: SubTag[ExprType],
157
+ value: Optional[ExprType],
158
+ """
159
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
160
+
161
+ def exit_except(self, node: ast.Except) -> None:
162
+ """Sub objects.
163
+
164
+ ex_type: ExprType,
165
+ name: Optional[Name],
166
+ body: SubNodeList[CodeBlockStmt],
167
+ """
168
+ if node.name:
169
+ self.link_jac_py_nodes(jac_node=node.name, py_nodes=node.gen.py_ast)
170
+
171
+ def exit_expr_as_item(self, node: ast.ExprAsItem) -> None:
172
+ """Sub objects.
173
+
174
+ expr: ExprType,
175
+ alias: Optional[ExprType],
176
+ """
177
+ self.link_jac_py_nodes(jac_node=node.expr, py_nodes=node.gen.py_ast)
178
+ if node.alias:
179
+ self.link_jac_py_nodes(jac_node=node.alias, py_nodes=node.gen.py_ast)
180
+
181
+ def exit_global_stmt(self, node: ast.GlobalStmt) -> None:
182
+ """Sub objects.
183
+
184
+ target: SubNodeList[NameType],
185
+ """
186
+ for x, y in enumerate(node.target.items):
187
+ self.link_jac_py_nodes(jac_node=y, py_nodes=[node.gen.py_ast[x]])
188
+
189
+ def exit_non_local_stmt(self, node: ast.NonLocalStmt) -> None:
190
+ """Sub objects.
191
+
192
+ target: SubNodeList[NameType],
193
+ """
194
+ for x, y in enumerate(node.target.items):
195
+ self.link_jac_py_nodes(jac_node=y, py_nodes=[node.gen.py_ast[x]])
196
+
197
+ def exit_k_w_pair(self, node: ast.KWPair) -> None:
198
+ """Sub objects.
199
+
200
+ key: NameType,
201
+ value: ExprType,
202
+ """
203
+ if node.key:
204
+ self.link_jac_py_nodes(jac_node=node.key, py_nodes=node.gen.py_ast)
205
+
206
+ def exit_atom_trailer(self, node: ast.AtomTrailer) -> None:
207
+ """Sub objects.
208
+
209
+ target: Expr,
210
+ right: AtomExpr | Expr,
211
+ is_attr: bool,
212
+ is_null_ok: bool,
213
+ is_genai: bool = False,
214
+ """
215
+ if node.is_attr and isinstance(node.right, ast.AstSymbolNode):
216
+ self.link_jac_py_nodes(
217
+ jac_node=node.right.sym_name_node, py_nodes=node.gen.py_ast
218
+ )
@@ -14,6 +14,7 @@ from .def_use_pass import DefUsePass # noqa: I100
14
14
  from .pyout_pass import PyOutPass # noqa: I100
15
15
  from .pybc_gen_pass import PyBytecodeGenPass # noqa: I100
16
16
  from .pyast_gen_pass import PyastGenPass # noqa: I100
17
+ from .pyjac_ast_link_pass import PyJacAstLinkPass # noqa: I100
17
18
  from .type_check_pass import JacTypeCheckPass # noqa: I100
18
19
  from .fuse_typeinfo_pass import FuseTypeInfoPass # noqa: I100
19
20
  from .registry_pass import RegistryPass # noqa: I100
@@ -28,6 +29,7 @@ py_code_gen = [
28
29
  DefUsePass,
29
30
  RegistryPass,
30
31
  PyastGenPass,
32
+ PyJacAstLinkPass,
31
33
  PyBytecodeGenPass,
32
34
  ]
33
35
 
@@ -217,9 +217,9 @@ class SymTabBuildPass(SymTabPass):
217
217
  else:
218
218
  self.cur_sym_tab.append(self.cur_scope().push_scope(name, key_node))
219
219
 
220
- def pop_scope(self) -> None:
220
+ def pop_scope(self) -> SymbolTable:
221
221
  """Pop scope."""
222
- self.cur_sym_tab.pop()
222
+ return self.cur_sym_tab.pop()
223
223
 
224
224
  def cur_scope(self) -> SymbolTable:
225
225
  """Return current scope."""
@@ -263,7 +263,13 @@ class SymTabBuildPass(SymTabPass):
263
263
  mod_path: str,
264
264
  is_imported: bool,
265
265
  """
266
- self.pop_scope()
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
+
267
273
  if (
268
274
  isinstance(node.parent, ast.Module)
269
275
  and node
@@ -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 JacImportPass
5
6
  from jaclang.utils.test import TestCase
@@ -17,3 +18,13 @@ class ImportPassPassTests(TestCase):
17
18
  state = jac_file_to_pass(self.fixture_abs_path("base.jac"), JacImportPass)
18
19
  self.assertFalse(state.errors_had)
19
20
  self.assertIn("56", str(state.ir.to_dict()))
21
+
22
+ def test_import_auto_impl(self) -> None:
23
+ """Basic test for pass."""
24
+ state = jac_file_to_pass(self.fixture_abs_path("autoimpl.jac"), JacImportPass)
25
+ num_modules = len(state.ir.get_all_sub_nodes(ast.Module))
26
+ mod_names = [i.name for i in state.ir.get_all_sub_nodes(ast.Module)]
27
+ self.assertEqual(num_modules, 3)
28
+ self.assertIn("getme.impl", mod_names)
29
+ self.assertIn("autoimpl.impl", mod_names)
30
+ self.assertIn("autoimpl.something.else.impl", mod_names)
jaclang/core/aott.py CHANGED
@@ -138,22 +138,31 @@ def get_type_explanation(
138
138
  _, type_info = mod_registry.lookup(scope=sem_info_scope)
139
139
  type_info_str = []
140
140
  type_info_types = []
141
+ type_example = [f"{sem_info.name}("]
141
142
  if sem_info.type == "Enum" and isinstance(type_info, list):
142
143
  for enum_item in type_info:
143
144
  type_info_str.append(
144
145
  f"{enum_item.semstr} ({enum_item.name}) (EnumItem)"
145
146
  )
147
+ type_example[0] = type_example[0].replace("(", f".{enum_item.name}")
146
148
  elif sem_info.type in ["obj", "class", "node", "edge"] and isinstance(
147
149
  type_info, list
148
150
  ):
149
151
  for arch_item in type_info:
152
+ if arch_item.type in ["obj", "class", "node", "edge"]:
153
+ continue
150
154
  type_info_str.append(
151
155
  f"{arch_item.semstr} ({arch_item.name}) ({arch_item.type})"
152
156
  )
157
+ type_example.append(f"{arch_item.name}={arch_item.type}, ")
153
158
  if arch_item.type and extract_non_primary_type(arch_item.type):
154
159
  type_info_types.extend(extract_non_primary_type(arch_item.type))
160
+ if len(type_example) > 1:
161
+ type_example[-1] = type_example[-1].replace(", ", ")")
162
+ else:
163
+ type_example.append(")")
155
164
  return (
156
- f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) = {', '.join(type_info_str)}",
165
+ f"{sem_info.semstr} ({sem_info.name}) ({sem_info.type}) eg:- {''.join(type_example)} -> {', '.join(type_info_str)}", # noqa: E501
157
166
  set(type_info_types),
158
167
  )
159
168
  return None, None