jaclang 0.6.5__py3-none-any.whl → 0.7.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.

Files changed (36) hide show
  1. jaclang/compiler/absyntree.py +4 -36
  2. jaclang/compiler/compile.py +21 -0
  3. jaclang/compiler/parser.py +13 -4
  4. jaclang/compiler/passes/main/__init__.py +2 -2
  5. jaclang/compiler/passes/main/def_impl_match_pass.py +1 -5
  6. jaclang/compiler/passes/main/def_use_pass.py +14 -7
  7. jaclang/compiler/passes/main/import_pass.py +56 -10
  8. jaclang/compiler/passes/main/pyast_gen_pass.py +55 -2
  9. jaclang/compiler/passes/main/schedules.py +4 -3
  10. jaclang/compiler/passes/main/tests/fixtures/incautoimpl.jac +7 -0
  11. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +4 -4
  12. jaclang/compiler/passes/main/tests/test_import_pass.py +13 -0
  13. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  14. jaclang/compiler/passes/transform.py +13 -4
  15. jaclang/compiler/tests/fixtures/mod_doc_test.jac +3 -1
  16. jaclang/langserve/engine.py +375 -0
  17. jaclang/langserve/server.py +112 -74
  18. jaclang/langserve/tests/fixtures/circle.jac +73 -0
  19. jaclang/langserve/tests/fixtures/circle_err.jac +73 -0
  20. jaclang/langserve/tests/fixtures/circle_pure.impl.jac +28 -0
  21. jaclang/langserve/tests/fixtures/circle_pure.jac +34 -0
  22. jaclang/langserve/tests/fixtures/circle_pure_err.impl.jac +32 -0
  23. jaclang/langserve/tests/fixtures/circle_pure_err.jac +34 -0
  24. jaclang/langserve/tests/test_server.py +33 -1
  25. jaclang/langserve/utils.py +53 -16
  26. jaclang/plugin/default.py +1 -1
  27. jaclang/tests/fixtures/type_info.jac +1 -1
  28. jaclang/tests/test_cli.py +1 -1
  29. jaclang/utils/helpers.py +3 -5
  30. jaclang/utils/test.py +1 -1
  31. {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/METADATA +8 -16
  32. {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/RECORD +34 -28
  33. jaclang/compiler/tests/test_workspace.py +0 -93
  34. jaclang/compiler/workspace.py +0 -234
  35. {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/WHEEL +0 -0
  36. {jaclang-0.6.5.dist-info → jaclang-0.7.1.dist-info}/entry_points.txt +0 -0
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import ast as ast3
6
+ from hashlib import md5
6
7
  from types import EllipsisType
7
8
  from typing import Any, Callable, Generic, Optional, Sequence, Type, TypeVar
8
9
 
@@ -700,10 +701,12 @@ class ModuleItem(AstSymbolNode):
700
701
  name: Name,
701
702
  alias: Optional[Name],
702
703
  kid: Sequence[AstNode],
704
+ sub_module: Optional[Module] = None,
703
705
  ) -> None:
704
706
  """Initialize module item node."""
705
707
  self.name = name
706
708
  self.alias = alias
709
+ self.sub_module = sub_module
707
710
  AstNode.__init__(self, kid=kid)
708
711
  AstSymbolNode.__init__(
709
712
  self,
@@ -1026,16 +1029,6 @@ class Ability(
1026
1029
  AstDocNode.__init__(self, doc=doc)
1027
1030
  AstAsyncNode.__init__(self, is_async=is_async)
1028
1031
 
1029
- @property
1030
- def is_method(self) -> bool:
1031
- """Check if is method."""
1032
- check = isinstance(self.parent, SubNodeList) and isinstance(
1033
- self.parent.parent, Architype
1034
- )
1035
- if check:
1036
- self.sym_type = SymbolType.METHOD
1037
- return check
1038
-
1039
1032
  @property
1040
1033
  def is_func(self) -> bool:
1041
1034
  """Check if is func."""
@@ -1151,14 +1144,6 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
1151
1144
  self.set_kids(nodes=new_kid)
1152
1145
  return res
1153
1146
 
1154
- @property
1155
- def is_method(self) -> bool:
1156
- """Check if is method."""
1157
- return (
1158
- len(self.target.archs) > 1
1159
- and self.target.archs[-2].arch.name != Tok.ABILITY_OP
1160
- )
1161
-
1162
1147
 
1163
1148
  class FuncSignature(AstSemStrNode):
1164
1149
  """FuncSignature node type for Jac Ast."""
@@ -1196,13 +1181,6 @@ class FuncSignature(AstSemStrNode):
1196
1181
  self.set_kids(nodes=new_kid)
1197
1182
  return res
1198
1183
 
1199
- @property
1200
- def is_method(self) -> bool:
1201
- """Check if is method."""
1202
- return (isinstance(self.parent, Ability) and self.parent.is_method) or (
1203
- isinstance(self.parent, AbilityDef) and self.parent.is_method
1204
- )
1205
-
1206
1184
  @property
1207
1185
  def is_static(self) -> bool:
1208
1186
  """Check if is static."""
@@ -1255,17 +1233,6 @@ class EventSignature(AstSemStrNode):
1255
1233
  self.set_kids(nodes=new_kid)
1256
1234
  return res
1257
1235
 
1258
- @property
1259
- def is_method(self) -> bool:
1260
- """Check if is method."""
1261
- if (isinstance(self.parent, Ability) and self.parent.is_method) or (
1262
- isinstance(self.parent, AbilityDef)
1263
- and isinstance(self.parent.decl_link, Ability)
1264
- and self.parent.decl_link.is_method
1265
- ):
1266
- return True
1267
- return False
1268
-
1269
1236
 
1270
1237
  class ArchRefChain(AstNode):
1271
1238
  """Arch ref list node type for Jac Ast."""
@@ -4081,6 +4048,7 @@ class JacSource(EmptyToken):
4081
4048
  """Initialize source string."""
4082
4049
  super().__init__()
4083
4050
  self.value = source
4051
+ self.hash = md5(source.encode()).hexdigest()
4084
4052
  self.file_path = mod_path
4085
4053
  self.comments: list[CommentToken] = []
4086
4054
 
@@ -57,6 +57,27 @@ def jac_str_to_pass(
57
57
  return ast_ret
58
58
 
59
59
 
60
+ def jac_ir_to_pass(
61
+ ir: ast.AstNode,
62
+ target: Optional[Type[Pass]] = None,
63
+ schedule: list[Type[Pass]] = pass_schedule,
64
+ ) -> Pass:
65
+ """Convert a Jac file to an AST."""
66
+ if not target:
67
+ target = schedule[-1] if schedule else None
68
+ ast_ret = (
69
+ Pass(input_ir=ir, prior=None)
70
+ if not len(schedule)
71
+ else schedule[0](input_ir=ir, prior=None)
72
+ )
73
+ for i in schedule[1:]:
74
+ if i == target:
75
+ break
76
+ ast_ret = i(input_ir=ast_ret.ir, prior=ast_ret)
77
+ ast_ret = target(input_ir=ast_ret.ir, prior=ast_ret) if target else ast_ret
78
+ return ast_ret
79
+
80
+
60
81
  def jac_pass_to_pass(
61
82
  in_pass: Pass,
62
83
  target: Optional[Type[Pass]] = None,
@@ -28,7 +28,7 @@ class JacParser(Pass):
28
28
  JacParser.make_dev()
29
29
  Pass.__init__(self, input_ir=input_ir, prior=None)
30
30
 
31
- def transform(self, ir: ast.AstNode) -> ast.AstNode:
31
+ def transform(self, ir: ast.AstNode) -> ast.Module:
32
32
  """Transform input IR."""
33
33
  try:
34
34
  tree, comments = JacParser.parse(
@@ -36,6 +36,10 @@ class JacParser(Pass):
36
36
  )
37
37
  mod = JacParser.TreeToAST(parser=self).transform(tree)
38
38
  self.source.comments = [self.proc_comment(i, mod) for i in comments]
39
+ if isinstance(mod, ast.Module):
40
+ return mod
41
+ else:
42
+ raise self.ice()
39
43
  except jl.UnexpectedInput as e:
40
44
  catch_error = ast.EmptyToken()
41
45
  catch_error.file_path = self.mod_path
@@ -43,11 +47,16 @@ class JacParser(Pass):
43
47
  catch_error.c_start = e.column
44
48
  catch_error.c_end = e.column
45
49
  self.error(f"Syntax Error: {e}", node_override=catch_error)
46
- mod = self.source
47
50
  except Exception as e:
48
- mod = self.source
49
51
  self.error(f"Internal Error: {e}")
50
- return mod
52
+ return ast.Module(
53
+ name="",
54
+ source=self.source,
55
+ doc=None,
56
+ body=[],
57
+ is_imported=False,
58
+ kid=[ast.EmptyToken()],
59
+ )
51
60
 
52
61
  @staticmethod
53
62
  def proc_comment(token: jl.Token, mod: ast.AstNode) -> ast.CommentToken:
@@ -3,7 +3,7 @@
3
3
  from .sub_node_tab_pass import SubNodeTabPass
4
4
  from .import_pass import JacImportPass, PyImportPass # noqa: I100
5
5
  from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
6
- from .def_impl_match_pass import DeclDefMatchPass # noqa: I100
6
+ from .def_impl_match_pass import DeclImplMatchPass # noqa: I100
7
7
  from .def_use_pass import DefUsePass # noqa: I100
8
8
  from .pyout_pass import PyOutPass # noqa: I100
9
9
  from .pyast_load_pass import PyastBuildPass # type: ignore # noqa: I100
@@ -20,7 +20,7 @@ __all__ = [
20
20
  "JacImportPass",
21
21
  "PyImportPass",
22
22
  "SymTabBuildPass",
23
- "DeclDefMatchPass",
23
+ "DeclImplMatchPass",
24
24
  "DefUsePass",
25
25
  "PyOutPass",
26
26
  "PyastBuildPass",
@@ -12,7 +12,7 @@ from jaclang.compiler.passes.main import SubNodeTabPass
12
12
  from jaclang.compiler.symtable import Symbol, SymbolTable, SymbolType
13
13
 
14
14
 
15
- class DeclDefMatchPass(Pass):
15
+ class DeclImplMatchPass(Pass):
16
16
  """Decls and Def matching pass."""
17
17
 
18
18
  def enter_module(self, node: ast.Module) -> None:
@@ -76,10 +76,6 @@ class DeclDefMatchPass(Pass):
76
76
  continue
77
77
  decl_node.body = sym.decl # type: ignore
78
78
  sym.decl.decl_link = decl_node # type: ignore
79
- source_node = sym.decl.parent
80
- decl_node.add_kids_right([sym.decl]) # type: ignore
81
- if source_node and sym.decl in source_node.kid:
82
- source_node.kid.remove(sym.decl)
83
79
  decl_node.sym_tab.tab = sym.decl.sym_tab.tab # type: ignore
84
80
  for i in sym_tab.kid:
85
81
  self.connect_def_impl(i)
@@ -28,13 +28,20 @@ class DefUsePass(SymTabPass):
28
28
  sym_tab: Optional[SymbolTable],
29
29
  """
30
30
  if node.arch_type.name == Tok.KW_WALKER:
31
- for i in (
32
- self.get_all_sub_nodes(node, ast.VisitStmt)
33
- + self.get_all_sub_nodes(node, ast.IgnoreStmt)
34
- + self.get_all_sub_nodes(node, ast.DisengageStmt)
35
- + self.get_all_sub_nodes(node, ast.EdgeOpRef)
36
- ):
37
- i.from_walker = True
31
+ self.inform_from_walker(node)
32
+ for i in self.get_all_sub_nodes(node, ast.Ability):
33
+ if isinstance(i.body, ast.AbilityDef):
34
+ self.inform_from_walker(i.body)
35
+
36
+ def inform_from_walker(self, node: ast.AstNode) -> None:
37
+ """Inform all sub nodes that they are from a walker."""
38
+ for i in (
39
+ self.get_all_sub_nodes(node, ast.VisitStmt)
40
+ + self.get_all_sub_nodes(node, ast.IgnoreStmt)
41
+ + self.get_all_sub_nodes(node, ast.DisengageStmt)
42
+ + self.get_all_sub_nodes(node, ast.EdgeOpRef)
43
+ ):
44
+ i.from_walker = True
38
45
 
39
46
  def enter_arch_ref(self, node: ast.ArchRef) -> None:
40
47
  """Sub objects.
@@ -46,14 +46,20 @@ class JacImportPass(Pass):
46
46
  """Process an import."""
47
47
  lang = i.parent_of_type(ast.Import).hint.tag.value
48
48
  if lang == "jac" and not i.sub_module:
49
- mod = self.import_jac_module(
49
+ self.import_jac_module(
50
50
  node=i,
51
51
  mod_path=node.loc.mod_path,
52
52
  )
53
- if mod:
54
- self.run_again = True
55
- i.sub_module = mod
56
- i.add_kids_right([mod], pos_update=False)
53
+
54
+ def attach_mod_to_node(
55
+ self, node: ast.ModulePath | ast.ModuleItem, mod: ast.Module | None
56
+ ) -> None:
57
+ """Attach a module to a node."""
58
+ if mod:
59
+ self.run_again = True
60
+ node.sub_module = mod
61
+ self.__annex_impl(mod)
62
+ node.add_kids_right([mod], pos_update=False)
57
63
 
58
64
  def __annex_impl(self, node: ast.Module) -> None:
59
65
  """Annex impl and test modules."""
@@ -114,15 +120,55 @@ class JacImportPass(Pass):
114
120
  node.sub_module.name = node.alias.value
115
121
  # Items matched during def/decl pass
116
122
 
117
- def import_jac_module(
118
- self, node: ast.ModulePath, mod_path: str
119
- ) -> ast.Module | None:
123
+ def import_jac_module(self, node: ast.ModulePath, mod_path: str) -> None:
120
124
  """Import a module."""
121
125
  self.cur_node = node # impacts error reporting
122
126
  target = import_target_to_relative_path(
123
- node.level, node.path_str, os.path.dirname(node.loc.mod_path)
127
+ level=node.level,
128
+ target=node.path_str,
129
+ base_path=os.path.dirname(node.loc.mod_path),
124
130
  )
125
- return self.import_jac_mod_from_file(target)
131
+ # If the module is a package (dir)
132
+ if os.path.isdir(target):
133
+ self.attach_mod_to_node(node, self.import_jac_mod_from_dir(target))
134
+ import_node = node.parent_of_type(ast.Import)
135
+ # And the import is a from import and I am the from module
136
+ if node == import_node.from_loc:
137
+ # Import all from items as modules or packages
138
+ for i in import_node.items.items:
139
+ if isinstance(i, ast.ModuleItem):
140
+ from_mod_target = import_target_to_relative_path(
141
+ level=node.level,
142
+ target=node.path_str + "." + i.name.value,
143
+ base_path=os.path.dirname(node.loc.mod_path),
144
+ )
145
+ # If package
146
+ if os.path.isdir(from_mod_target):
147
+ self.attach_mod_to_node(
148
+ i, self.import_jac_mod_from_dir(from_mod_target)
149
+ )
150
+ # Else module
151
+ else:
152
+ self.attach_mod_to_node(
153
+ i, self.import_jac_mod_from_file(from_mod_target)
154
+ )
155
+ else:
156
+ self.attach_mod_to_node(node, self.import_jac_mod_from_file(target))
157
+
158
+ def import_jac_mod_from_dir(self, target: str) -> ast.Module | None:
159
+ """Import a module from a directory."""
160
+ with_init = os.path.join(target, "__init__.jac")
161
+ if os.path.exists(with_init):
162
+ return self.import_jac_mod_from_file(with_init)
163
+ else:
164
+ return ast.Module(
165
+ name=target.split(os.path.sep)[-1],
166
+ source=ast.JacSource("", mod_path=target),
167
+ doc=None,
168
+ body=[],
169
+ is_imported=False,
170
+ kid=[ast.EmptyToken()],
171
+ )
126
172
 
127
173
  def import_jac_mod_from_file(self, target: str) -> ast.Module | None:
128
174
  """Import a module from a file."""
@@ -42,6 +42,7 @@ class PyastGenPass(Pass):
42
42
  """Initialize pass."""
43
43
  self.debuginfo: dict[str, list[str]] = {"jac_mods": []}
44
44
  self.already_added: list[str] = []
45
+ self.method_sigs: list[ast.FuncSignature | ast.EventSignature] = []
45
46
  self.preamble: list[ast3.AST] = [
46
47
  self.sync(
47
48
  ast3.ImportFrom(
@@ -658,6 +659,28 @@ class PyastGenPass(Pass):
658
659
  )
659
660
  ]
660
661
 
662
+ def enter_architype(self, node: ast.Architype) -> None:
663
+ """Sub objects.
664
+
665
+ name: Name,
666
+ arch_type: Token,
667
+ access: Optional[SubTag[Token]],
668
+ base_classes: Optional[SubNodeList[AtomType]],
669
+ body: Optional[SubNodeList[ArchBlockStmt] | ArchDef],
670
+ doc: Optional[String],
671
+ decorators: Optional[SubNodeList[ExprType]],
672
+ """
673
+ # Record all signatures that are part of methods
674
+ for i in (
675
+ node.body.body.items
676
+ if isinstance(node.body, ast.ArchDef)
677
+ else node.body.items if node.body else []
678
+ ):
679
+ if isinstance(i, ast.Ability) and i.signature:
680
+ self.method_sigs.append(i.signature)
681
+ if isinstance(node.body, ast.ArchDef):
682
+ self.traverse(node.body)
683
+
661
684
  def exit_architype(self, node: ast.Architype) -> None:
662
685
  """Sub objects.
663
686
 
@@ -821,6 +844,19 @@ class PyastGenPass(Pass):
821
844
  decorators: Optional[SubNodeList[ExprType]],
822
845
  """
823
846
 
847
+ def enter_enum(self, node: ast.Enum) -> None:
848
+ """Sub objects.
849
+
850
+ name: Name,
851
+ access: Optional[SubTag[Token]],
852
+ base_classes: Optional[SubNodeList[AtomType]],
853
+ body: Optional[SubNodeList[EnumBlockStmt] | EnumDef],
854
+ doc: Optional[String],
855
+ decorators: Optional[SubNodeList[ExprType]],
856
+ """
857
+ if isinstance(node.body, ast.EnumDef):
858
+ self.traverse(node.body)
859
+
824
860
  def exit_enum(self, node: ast.Enum) -> None:
825
861
  """Sub objects.
826
862
 
@@ -870,6 +906,23 @@ class PyastGenPass(Pass):
870
906
  decorators: Optional[SubNodeList[ExprType]],
871
907
  """
872
908
 
909
+ def enter_ability(self, node: ast.Ability) -> None:
910
+ """Sub objects.
911
+
912
+ name_ref: NameType,
913
+ is_func: bool,
914
+ is_async: bool,
915
+ is_static: bool,
916
+ is_abstract: bool,
917
+ access: Optional[SubTag[Token]],
918
+ signature: Optional[FuncSignature | ExprType | EventSignature],
919
+ body: Optional[SubNodeList[CodeBlockStmt] | AbilityDef | FuncCall],
920
+ doc: Optional[String],
921
+ decorators: Optional[SubNodeList[ExprType]],
922
+ """
923
+ if isinstance(node.body, ast.AbilityDef):
924
+ self.traverse(node.body)
925
+
873
926
  def exit_ability(self, node: ast.Ability) -> None:
874
927
  """Sub objects.
875
928
 
@@ -1272,7 +1325,7 @@ class PyastGenPass(Pass):
1272
1325
  """
1273
1326
  params = (
1274
1327
  [self.sync(ast3.arg(arg="self", annotation=None))]
1275
- if node.is_method and not node.is_static
1328
+ if node in self.method_sigs and not node.is_static
1276
1329
  else []
1277
1330
  )
1278
1331
  vararg = None
@@ -1330,7 +1383,7 @@ class PyastGenPass(Pass):
1330
1383
  posonlyargs=[],
1331
1384
  args=(
1332
1385
  [self.sync(ast3.arg(arg="self", annotation=None)), here]
1333
- if node.is_method
1386
+ if node in self.method_sigs
1334
1387
  else [here]
1335
1388
  ),
1336
1389
  kwonlyargs=[],
@@ -9,7 +9,7 @@ from __future__ import annotations
9
9
  from .sub_node_tab_pass import SubNodeTabPass # noqa: I100
10
10
  from .import_pass import JacImportPass, PyImportPass # noqa: I100
11
11
  from .sym_tab_build_pass import SymTabBuildPass # noqa: I100
12
- from .def_impl_match_pass import DeclDefMatchPass # noqa: I100
12
+ from .def_impl_match_pass import DeclImplMatchPass # noqa: I100
13
13
  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
@@ -25,7 +25,7 @@ py_code_gen = [
25
25
  JacImportPass,
26
26
  PyImportPass,
27
27
  SymTabBuildPass,
28
- DeclDefMatchPass,
28
+ DeclImplMatchPass,
29
29
  DefUsePass,
30
30
  RegistryPass,
31
31
  PyastGenPass,
@@ -33,5 +33,6 @@ py_code_gen = [
33
33
  PyBytecodeGenPass,
34
34
  ]
35
35
 
36
- py_code_gen_typed = [*py_code_gen, JacTypeCheckPass, FuseTypeInfoPass, AccessCheckPass]
36
+ type_checker_sched = [JacTypeCheckPass, FuseTypeInfoPass, AccessCheckPass]
37
+ py_code_gen_typed = [*py_code_gen, *type_checker_sched]
37
38
  py_compiler = [*py_code_gen, PyOutPass]
@@ -0,0 +1,7 @@
1
+ include:jac autoimpl;
2
+
3
+ with entry {
4
+ foo();
5
+ bar();
6
+ baz();
7
+ }
@@ -1,11 +1,11 @@
1
1
  """Test pass module."""
2
2
 
3
3
  from jaclang.compiler.compile import jac_file_to_pass
4
- from jaclang.compiler.passes.main import DeclDefMatchPass
4
+ from jaclang.compiler.passes.main import DeclImplMatchPass
5
5
  from jaclang.utils.test import TestCase
6
6
 
7
7
 
8
- class DeclDefMatchPassTests(TestCase):
8
+ class DeclImplMatchPassTests(TestCase):
9
9
  """Test pass module."""
10
10
 
11
11
  def setUp(self) -> None:
@@ -14,7 +14,7 @@ class DeclDefMatchPassTests(TestCase):
14
14
 
15
15
  def test_ability_connected_to_decl(self) -> None:
16
16
  """Basic test for pass."""
17
- state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclDefMatchPass)
17
+ state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
18
18
  self.assertFalse(state.errors_had)
19
19
  self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
20
20
  self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
@@ -23,7 +23,7 @@ class DeclDefMatchPassTests(TestCase):
23
23
 
24
24
  def test_ability_connected_to_decl_post(self) -> None:
25
25
  """Basic test for pass."""
26
- state = jac_file_to_pass(self.fixture_abs_path("base2.jac"), DeclDefMatchPass)
26
+ state = jac_file_to_pass(self.fixture_abs_path("base2.jac"), DeclImplMatchPass)
27
27
  self.assertFalse(state.errors_had)
28
28
  self.assertIn("(o)Test.(c)say_hi", state.ir.sym_tab.tab)
29
29
  self.assertIsNotNone(state.ir.sym_tab.tab["(o)Test.(c)say_hi"].decl.body)
@@ -28,3 +28,16 @@ class ImportPassPassTests(TestCase):
28
28
  self.assertIn("getme.impl", mod_names)
29
29
  self.assertIn("autoimpl.impl", mod_names)
30
30
  self.assertIn("autoimpl.something.else.impl", mod_names)
31
+
32
+ def test_import_include_auto_impl(self) -> None:
33
+ """Basic test for pass."""
34
+ state = jac_file_to_pass(
35
+ self.fixture_abs_path("incautoimpl.jac"), JacImportPass
36
+ )
37
+ num_modules = len(state.ir.get_all_sub_nodes(ast.Module))
38
+ mod_names = [i.name for i in state.ir.get_all_sub_nodes(ast.Module)]
39
+ self.assertEqual(num_modules, 4)
40
+ self.assertIn("getme.impl", mod_names)
41
+ self.assertIn("autoimpl", mod_names)
42
+ self.assertIn("autoimpl.impl", mod_names)
43
+ self.assertIn("autoimpl.something.else.impl", mod_names)
@@ -1161,7 +1161,7 @@ class JacFormatPass(Pass):
1161
1161
  if (
1162
1162
  node.parent
1163
1163
  and node.parent.parent
1164
- and isinstance(node.parent.parent, (ast.Ability))
1164
+ and not isinstance(node.parent.parent, (ast.Ability, ast.ModuleCode))
1165
1165
  and node.parent.kid[1].gen.jac != "self.jaseci_sdk = {};\n"
1166
1166
  ):
1167
1167
  self.emit_ln(node, "")
@@ -1229,7 +1229,7 @@ class JacFormatPass(Pass):
1229
1229
 
1230
1230
  body: CodeBlock,
1231
1231
  """
1232
- self.emit(node, "finally")
1232
+ self.emit(node, " finally")
1233
1233
 
1234
1234
  self.emit(node, node.body.gen.jac)
1235
1235
 
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from abc import ABC, abstractmethod
6
- from typing import Generic, Optional
6
+ from typing import Generic, Optional, Type
7
7
 
8
8
  from jaclang.compiler.absyntree import AstNode, T
9
9
  from jaclang.compiler.codeloc import CodeLocInfo
@@ -13,10 +13,11 @@ from jaclang.utils.log import logging
13
13
  class Alert:
14
14
  """Alert interface."""
15
15
 
16
- def __init__(self, msg: str, loc: CodeLocInfo) -> None:
16
+ def __init__(self, msg: str, loc: CodeLocInfo, from_pass: Type[Transform]) -> None:
17
17
  """Initialize alert."""
18
18
  self.msg = msg
19
19
  self.loc: CodeLocInfo = loc
20
+ self.from_pass: Type[Transform] = from_pass
20
21
 
21
22
  def __str__(self) -> str:
22
23
  """Return string representation of alert."""
@@ -52,14 +53,22 @@ class Transform(ABC, Generic[T]):
52
53
 
53
54
  def log_error(self, msg: str, node_override: Optional[AstNode] = None) -> None:
54
55
  """Pass Error."""
55
- alrt = Alert(msg, self.cur_node.loc if not node_override else node_override.loc)
56
+ alrt = Alert(
57
+ msg,
58
+ self.cur_node.loc if not node_override else node_override.loc,
59
+ self.__class__,
60
+ )
56
61
  self.errors_had.append(alrt)
57
62
  # print("Error:", str(alrt))
58
63
  self.logger.error(str(alrt))
59
64
 
60
65
  def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
61
66
  """Pass Error."""
62
- alrt = Alert(msg, self.cur_node.loc if not node_override else node_override.loc)
67
+ alrt = Alert(
68
+ msg,
69
+ self.cur_node.loc if not node_override else node_override.loc,
70
+ self.__class__,
71
+ )
63
72
  self.warnings_had.append(alrt)
64
73
  # print("Warning:", str(alrt))
65
74
  self.logger.warning(str(alrt))
@@ -1 +1,3 @@
1
- with entry { print("hello"); }
1
+ with entry {
2
+ print("hello");
3
+ }