jaclang 0.8.0__py3-none-any.whl → 0.8.2__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 (124) hide show
  1. jaclang/__init__.py +6 -0
  2. jaclang/cli/cli.py +23 -50
  3. jaclang/compiler/codeinfo.py +0 -1
  4. jaclang/compiler/jac.lark +14 -22
  5. jaclang/compiler/larkparse/jac_parser.py +2 -2
  6. jaclang/compiler/parser.py +378 -531
  7. jaclang/compiler/passes/main/__init__.py +0 -14
  8. jaclang/compiler/passes/main/annex_pass.py +2 -8
  9. jaclang/compiler/passes/main/cfg_build_pass.py +39 -13
  10. jaclang/compiler/passes/main/def_impl_match_pass.py +14 -13
  11. jaclang/compiler/passes/main/def_use_pass.py +4 -7
  12. jaclang/compiler/passes/main/import_pass.py +6 -14
  13. jaclang/compiler/passes/main/inheritance_pass.py +2 -2
  14. jaclang/compiler/passes/main/pyast_gen_pass.py +428 -799
  15. jaclang/compiler/passes/main/pyast_load_pass.py +115 -311
  16. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +8 -7
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +3 -3
  18. jaclang/compiler/passes/main/sym_tab_link_pass.py +6 -9
  19. jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/action/actions.jac +1 -5
  20. jaclang/compiler/passes/main/tests/fixtures/symtab_link_tests/main.jac +1 -8
  21. jaclang/compiler/passes/main/tests/test_cfg_build_pass.py +5 -9
  22. jaclang/compiler/passes/main/tests/test_decl_impl_match_pass.py +7 -8
  23. jaclang/compiler/passes/main/tests/test_import_pass.py +5 -18
  24. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -6
  25. jaclang/compiler/passes/main/tests/test_sub_node_pass.py +1 -3
  26. jaclang/compiler/passes/main/tests/test_sym_tab_link_pass.py +20 -17
  27. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +425 -216
  28. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -0
  29. jaclang/compiler/passes/tool/tests/fixtures/archetype_frmt.jac +14 -0
  30. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +5 -4
  31. jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +6 -0
  32. jaclang/compiler/passes/tool/tests/fixtures/simple_walk_fmt.jac +3 -3
  33. jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +9 -0
  34. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +18 -3
  35. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +2 -2
  36. jaclang/compiler/program.py +22 -66
  37. jaclang/compiler/tests/fixtures/fam.jac +2 -2
  38. jaclang/compiler/tests/fixtures/pkg_import_lib/__init__.jac +1 -0
  39. jaclang/compiler/tests/fixtures/pkg_import_lib/sub/__init__.jac +1 -0
  40. jaclang/compiler/tests/fixtures/pkg_import_lib/sub/helper.jac +3 -0
  41. jaclang/compiler/tests/fixtures/pkg_import_lib/tools.jac +3 -0
  42. jaclang/compiler/tests/fixtures/pkg_import_lib_py/__init__.py +5 -0
  43. jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/__init__.py +3 -0
  44. jaclang/compiler/tests/fixtures/pkg_import_lib_py/sub/helper.jac +3 -0
  45. jaclang/compiler/tests/fixtures/pkg_import_lib_py/tools.jac +3 -0
  46. jaclang/compiler/tests/fixtures/pkg_import_main.jac +10 -0
  47. jaclang/compiler/tests/fixtures/pkg_import_main_py.jac +11 -0
  48. jaclang/compiler/tests/test_importer.py +30 -13
  49. jaclang/compiler/tests/test_parser.py +1 -0
  50. jaclang/compiler/unitree.py +488 -320
  51. jaclang/langserve/__init__.jac +1 -0
  52. jaclang/langserve/engine.jac +503 -0
  53. jaclang/langserve/sem_manager.jac +309 -0
  54. jaclang/langserve/server.jac +201 -0
  55. jaclang/langserve/tests/server_test/test_lang_serve.py +139 -48
  56. jaclang/langserve/tests/server_test/utils.py +35 -6
  57. jaclang/langserve/tests/session.jac +294 -0
  58. jaclang/langserve/tests/test_sem_tokens.py +2 -2
  59. jaclang/langserve/tests/test_server.py +8 -7
  60. jaclang/langserve/utils.jac +51 -30
  61. jaclang/runtimelib/archetype.py +128 -6
  62. jaclang/runtimelib/builtin.py +17 -14
  63. jaclang/runtimelib/importer.py +51 -76
  64. jaclang/runtimelib/machine.py +469 -305
  65. jaclang/runtimelib/meta_importer.py +86 -0
  66. jaclang/runtimelib/tests/fixtures/graph_purger.jac +24 -26
  67. jaclang/runtimelib/tests/fixtures/other_root_access.jac +25 -16
  68. jaclang/runtimelib/tests/fixtures/traversing_save.jac +7 -5
  69. jaclang/runtimelib/tests/test_jaseci.py +3 -1
  70. jaclang/runtimelib/utils.py +3 -3
  71. jaclang/tests/fixtures/arch_rel_import_creation.jac +23 -23
  72. jaclang/tests/fixtures/async_ability.jac +43 -10
  73. jaclang/tests/fixtures/async_function.jac +18 -0
  74. jaclang/tests/fixtures/async_walker.jac +17 -12
  75. jaclang/tests/fixtures/backward_edge_visit.jac +31 -0
  76. jaclang/tests/fixtures/builtin_printgraph.jac +85 -0
  77. jaclang/tests/fixtures/builtin_printgraph_json.jac +21 -0
  78. jaclang/tests/fixtures/builtin_printgraph_mermaid.jac +16 -0
  79. jaclang/tests/fixtures/chandra_bugs2.jac +20 -13
  80. jaclang/tests/fixtures/concurrency.jac +1 -1
  81. jaclang/tests/fixtures/create_dynamic_archetype.jac +25 -28
  82. jaclang/tests/fixtures/deep/deeper/deep_outer_import.jac +7 -4
  83. jaclang/tests/fixtures/deep/deeper/snd_lev.jac +2 -2
  84. jaclang/tests/fixtures/deep/deeper/snd_lev_dup.jac +6 -0
  85. jaclang/tests/fixtures/deep/one_lev.jac +2 -2
  86. jaclang/tests/fixtures/deep/one_lev_dup.jac +4 -3
  87. jaclang/tests/fixtures/dynamic_archetype.jac +19 -12
  88. jaclang/tests/fixtures/edge_ability.jac +49 -0
  89. jaclang/tests/fixtures/foo.jac +14 -22
  90. jaclang/tests/fixtures/guess_game.jac +1 -1
  91. jaclang/tests/fixtures/here_usage_error.jac +21 -0
  92. jaclang/tests/fixtures/here_visitor_usage.jac +21 -0
  93. jaclang/tests/fixtures/jac_from_py.py +1 -1
  94. jaclang/tests/fixtures/jp_importer.jac +6 -6
  95. jaclang/tests/fixtures/jp_importer_auto.jac +5 -3
  96. jaclang/tests/fixtures/node_del.jac +30 -36
  97. jaclang/tests/fixtures/unicode_strings.jac +24 -0
  98. jaclang/tests/fixtures/visit_traversal.jac +47 -0
  99. jaclang/tests/fixtures/walker_update.jac +5 -7
  100. jaclang/tests/test_cli.py +12 -7
  101. jaclang/tests/test_language.py +218 -145
  102. jaclang/tests/test_reference.py +9 -4
  103. jaclang/tests/test_typecheck.py +13 -26
  104. jaclang/utils/helpers.py +14 -6
  105. jaclang/utils/lang_tools.py +9 -8
  106. jaclang/utils/module_resolver.py +23 -0
  107. jaclang/utils/tests/test_lang_tools.py +2 -1
  108. jaclang/utils/treeprinter.py +3 -4
  109. {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/METADATA +4 -3
  110. {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/RECORD +112 -94
  111. {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/WHEEL +1 -1
  112. jaclang/compiler/passes/main/tests/fixtures/main_err.jac +0 -6
  113. jaclang/compiler/passes/main/tests/fixtures/second_err.jac +0 -4
  114. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +0 -644
  115. jaclang/compiler/passes/tool/tests/test_doc_ir_gen_pass.py +0 -29
  116. jaclang/langserve/__init__.py +0 -1
  117. jaclang/langserve/engine.py +0 -553
  118. jaclang/langserve/sem_manager.py +0 -383
  119. jaclang/langserve/server.py +0 -167
  120. jaclang/langserve/tests/session.py +0 -255
  121. jaclang/tests/fixtures/builtin_dotgen.jac +0 -42
  122. jaclang/tests/fixtures/builtin_dotgen_json.jac +0 -21
  123. jaclang/tests/fixtures/deep/deeper/__init__.jac +0 -1
  124. {jaclang-0.8.0.dist-info → jaclang-0.8.2.dist-info}/entry_points.txt +0 -0
@@ -1,7 +1,5 @@
1
1
  """Collection of passes for Jac IR."""
2
2
 
3
- from enum import Enum
4
-
5
3
  from ..transform import Alert, Transform # noqa: I100
6
4
  from .annex_pass import JacAnnexPass # noqa: I100
7
5
  from .sym_tab_build_pass import SymTabBuildPass, UniPass # noqa: I100
@@ -17,17 +15,6 @@ from .pyjac_ast_link_pass import PyJacAstLinkPass # noqa: I100
17
15
  from .inheritance_pass import InheritancePass # noqa: I100
18
16
 
19
17
 
20
- class CompilerMode(Enum):
21
- """Compiler modes."""
22
-
23
- PARSE = "PARSE"
24
- NO_CGEN = "NO_CGEN"
25
- NO_CGEN_SINGLE = "NO_CGEN_SINGLE"
26
- COMPILE = "COMPILE"
27
- COMPILE_SINGLE = "COMPILE_SINGLE"
28
- TYPECHECK = "TYPECHECK"
29
-
30
-
31
18
  __all__ = [
32
19
  "Alert",
33
20
  "Transform",
@@ -42,7 +29,6 @@ __all__ = [
42
29
  "PyastBuildPass",
43
30
  "PyastGenPass",
44
31
  "PyBytecodeGenPass",
45
- "CompilerMode",
46
32
  "CFGBuildPass",
47
33
  "PyJacAstLinkPass",
48
34
  "InheritancePass",
@@ -48,8 +48,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
48
48
 
49
49
  def load_annexes(self, jac_program: JacProgram, node: uni.Module) -> None:
50
50
  """Parse and attach annex modules to the node."""
51
- from jaclang.compiler.program import CompilerMode
52
-
53
51
  if node.stub_only or not self.mod_path.endswith(".jac"):
54
52
  return
55
53
  if not self.mod_path:
@@ -64,9 +62,7 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
64
62
  path.startswith(f"{self.base_path}.")
65
63
  or os.path.dirname(path) == self.impl_folder
66
64
  ):
67
- mod = jac_program.compile(
68
- file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
69
- )
65
+ mod = jac_program.compile(file_path=path, no_cgen=True)
70
66
  if mod:
71
67
  node.impl_mod.append(mod)
72
68
 
@@ -78,8 +74,6 @@ class JacAnnexPass(Transform[uni.Module, uni.Module]):
78
74
  or os.path.dirname(path) == self.test_folder
79
75
  )
80
76
  ):
81
- mod = jac_program.compile(
82
- file_path=path, mode=CompilerMode.NO_CGEN_SINGLE
83
- )
77
+ mod = jac_program.compile(file_path=path, no_cgen=True)
84
78
  if mod:
85
79
  node.test_mod.append(mod)
@@ -10,6 +10,8 @@ The CFG provides a foundation for data flow analysis, optimization, and understa
10
10
  The pass also includes functionality to coalesce basic blocks and generate visual representations of the CFG.
11
11
  """
12
12
 
13
+ from typing import Sequence
14
+
13
15
  import jaclang.compiler.unitree as uni
14
16
  from jaclang.compiler.passes import UniPass
15
17
 
@@ -65,26 +67,48 @@ class CFGBuildPass(UniPass):
65
67
  else:
66
68
  target.bb_in = [source]
67
69
 
70
+ def get_code_block_sequence(
71
+ self, node: uni.CodeBlockStmt
72
+ ) -> list[uni.UniCFGNode] | None:
73
+ """Get code block sequence."""
74
+ sequence: list[uni.UniCFGNode] = []
75
+ if hasattr(node, "body") and isinstance(node.body, Sequence):
76
+ for bbs in node.body:
77
+ if isinstance(bbs, uni.UniCFGNode):
78
+ sequence.append(bbs)
79
+ if sequence:
80
+ return sequence
81
+ else:
82
+ return None
83
+ else:
84
+ return None
85
+
68
86
  def enter_node(self, node: uni.UniNode) -> None:
69
87
  """Enter BasicBlockStmt nodes."""
70
88
  if isinstance(node, uni.UniCFGNode) and not isinstance(node, uni.Semi):
71
- if isinstance(node.parent, uni.SubNodeList) and self.first_exit:
72
- bb_stmts = [
73
- bbs for bbs in node.parent.kid if isinstance(bbs, uni.UniCFGNode)
74
- ]
89
+ # check if the current node is a CodeBlockStmt in a sequence of statements
90
+ bb_stmts = self.get_code_block_sequence(node.parent)
91
+ if (
92
+ isinstance(node, uni.CodeBlockStmt)
93
+ and node.parent
94
+ and (not (isinstance(node, (uni.ElseIf, uni.ElseStmt))))
95
+ and bb_stmts
96
+ and self.first_exit
97
+ ):
98
+ # bb_stmts = self.get_code_block_sequence(node.parent)
99
+ # bb_stmts = [
100
+ # bbs for bbs in node.parent.body if isinstance(bbs, uni.UniCFGNode)
101
+ # ]
75
102
  if (
76
- node.parent.parent
77
- and isinstance(node.parent.parent, uni.Archetype)
103
+ node.parent
104
+ and isinstance(node.parent, uni.Archetype)
78
105
  # and isinstance(node.parent.parent, uni.BasicBlockStmt)
79
106
  ):
80
- parent_obj = node.parent.parent
107
+ parent_obj = node.parent
81
108
  if parent_obj:
82
109
  self.link_bbs(parent_obj, node)
83
110
  elif bb_stmts[0] == node:
84
- if (
85
- isinstance(node.parent.parent, uni.ModuleCode)
86
- and self.to_connect
87
- ):
111
+ if isinstance(node.parent, uni.ModuleCode) and self.to_connect:
88
112
  for bb in self.to_connect:
89
113
  self.link_bbs(bb, node)
90
114
  self.to_connect.remove(bb) # if self.to_connect:
@@ -92,7 +116,9 @@ class CFGBuildPass(UniPass):
92
116
  parent_bb = self.get_parent_bb_stmt(node)
93
117
  if parent_bb:
94
118
  self.link_bbs(parent_bb, node)
95
- elif self.to_connect:
119
+ elif self.to_connect and not isinstance(
120
+ node, (uni.ElseIf, uni.ElseStmt)
121
+ ):
96
122
  to_remove = []
97
123
  for parent in self.to_connect:
98
124
  if isinstance(parent, uni.UniCFGNode):
@@ -199,7 +225,7 @@ class CoalesceBBPass(UniPass):
199
225
  }
200
226
  self.bb_counter += 1
201
227
 
202
- def dotgen_cfg(self) -> str:
228
+ def printgraph_cfg(self) -> str:
203
229
  """Generate dot graph for CFG."""
204
230
  cfg: dict = {}
205
231
  dot = "digraph G {\n"
@@ -17,6 +17,8 @@ developers to define archetype and ability interfaces in one file while implemen
17
17
  their behavior in separate files.
18
18
  """
19
19
 
20
+ from typing import Sequence
21
+
20
22
  import jaclang.compiler.unitree as uni
21
23
  from jaclang.compiler.constant import Tokens as Tok
22
24
  from jaclang.compiler.passes.transform import Transform
@@ -124,7 +126,7 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
124
126
 
125
127
  valid_decl.body = sym.decl.name_of
126
128
  sym.decl.name_of.decl_link = valid_decl
127
- for idx, a in enumerate(sym.decl.name_of.target.items):
129
+ for idx, a in enumerate(sym.decl.name_of.target):
128
130
  if idx < len(name_of_links) and name_of_links[idx]:
129
131
  a.name_spec.name_of = name_of_links[idx].name_of
130
132
  a.name_spec.sym = name_of_links[idx].sym
@@ -159,7 +161,7 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
159
161
 
160
162
  if params_decl and params_defn:
161
163
  # Check if the parameter count is matched.
162
- if len(params_defn.items) != len(params_decl.items):
164
+ if len(params_defn) != len(params_decl):
163
165
  self.log_error(
164
166
  f"Parameter count mismatch for ability {sym.sym_name}.",
165
167
  sym.decl.name_of.name_spec,
@@ -170,10 +172,11 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
170
172
  )
171
173
  else:
172
174
  # Copy the parameter names from the declaration to the definition.
173
- for idx in range(len(params_defn.items)):
174
- params_decl.items[idx] = params_defn.items[idx]
175
- for idx in range(len(params_defn.kid)):
176
- params_decl.kid[idx] = params_defn.kid[idx]
175
+ for idx in range(len(params_defn)):
176
+ if (par := params_decl[idx].parent) is not None:
177
+ loc_in_kid = par.kid.index(params_decl[idx])
178
+ par.kid[loc_in_kid] = params_defn[idx]
179
+ params_decl[idx] = params_defn[idx]
177
180
 
178
181
  def check_archetypes(self, ir_in: uni.Module) -> None:
179
182
  """Check all archetypes for issues with attributes and methods."""
@@ -182,15 +185,13 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
182
185
 
183
186
  def check_archetype(self, node: uni.Archetype) -> None:
184
187
  """Check a single archetype for issues."""
185
- if node.arch_type.name == Tok.KW_OBJECT and isinstance(
186
- node.body, uni.SubNodeList
187
- ):
188
+ if node.arch_type.name == Tok.KW_OBJECT and isinstance(node.body, Sequence):
188
189
  self.cur_node = node
189
190
  found_default_init = False
190
- for stmnt in node.body.items:
191
+ for stmnt in node.body:
191
192
  if not isinstance(stmnt, uni.ArchHas):
192
193
  continue
193
- for var in stmnt.vars.items:
194
+ for var in stmnt.vars:
194
195
  if (var.value is not None) or (var.defer):
195
196
  found_default_init = True
196
197
  else:
@@ -204,10 +205,10 @@ class DeclImplMatchPass(Transform[uni.Module, uni.Module]):
204
205
  post_init_vars: list[uni.HasVar] = []
205
206
  postinit_method: uni.Ability | None = None
206
207
 
207
- for item in node.body.items:
208
+ for item in node.body:
208
209
 
209
210
  if isinstance(item, uni.ArchHas):
210
- for var in item.vars.items:
211
+ for var in item.vars:
211
212
  if var.defer:
212
213
  post_init_vars.append(var)
213
214
 
@@ -38,6 +38,7 @@ class DefUsePass(UniPass):
38
38
  + node.get_all_sub_nodes(uni.IgnoreStmt)
39
39
  + node.get_all_sub_nodes(uni.DisengageStmt)
40
40
  + node.get_all_sub_nodes(uni.EdgeOpRef)
41
+ + node.get_all_sub_nodes(uni.EventSignature)
41
42
  ):
42
43
  i.from_walker = True
43
44
 
@@ -57,19 +58,15 @@ class DefUsePass(UniPass):
57
58
  node.sym_tab.def_insert(node)
58
59
 
59
60
  def enter_has_var(self, node: uni.HasVar) -> None:
60
- if isinstance(node.parent, uni.SubNodeList) and isinstance(
61
- node.parent.parent, uni.ArchHas
62
- ):
61
+ if isinstance(node.parent, uni.ArchHas):
63
62
  node.sym_tab.def_insert(
64
- node,
65
- single_decl="has var",
66
- access_spec=node.parent.parent,
63
+ node, single_decl="has var", access_spec=node.parent
67
64
  )
68
65
  else:
69
66
  self.ice("Inconsistency in AST, has var should be under arch has")
70
67
 
71
68
  def enter_assignment(self, node: uni.Assignment) -> None:
72
- for i in node.target.items:
69
+ for i in node.target:
73
70
  if isinstance(i, uni.AtomTrailer):
74
71
  i.sym_tab.chain_def_insert(i.as_attr_list)
75
72
  elif isinstance(i, uni.AstSymbolNode):
@@ -63,8 +63,6 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
63
63
 
64
64
  def import_jac_module(self, node: uni.ModulePath) -> None:
65
65
  """Import a module."""
66
- from jaclang.compiler.passes.main import CompilerMode as CMode
67
-
68
66
  target = node.resolve_relative_path()
69
67
  # If the module is a package (dir)
70
68
  if os.path.isdir(target):
@@ -73,7 +71,7 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
73
71
  # And the import is a from import and I am the from module
74
72
  if node == import_node.from_loc:
75
73
  # Import all from items as modules or packages
76
- for i in import_node.items.items:
74
+ for i in import_node.items:
77
75
  if isinstance(i, uni.ModuleItem):
78
76
  from_mod_target = node.resolve_relative_path(i.name.value)
79
77
  # If package
@@ -83,15 +81,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
83
81
  else:
84
82
  if from_mod_target in self.prog.mod.hub:
85
83
  return
86
- self.load_mod(
87
- self.prog.compile(
88
- file_path=from_mod_target, mode=CMode.PARSE
89
- )
90
- )
84
+ self.load_mod(self.prog.compile(file_path=from_mod_target))
91
85
  else:
92
86
  if target in self.prog.mod.hub:
93
87
  return
94
- self.load_mod(self.prog.compile(file_path=target, mode=CMode.PARSE))
88
+ self.load_mod(self.prog.compile(file_path=target))
95
89
 
96
90
  def load_mod(self, mod: uni.Module) -> None:
97
91
  """Attach a module to a node."""
@@ -102,13 +96,11 @@ class JacImportDepsPass(Transform[uni.Module, uni.Module]):
102
96
 
103
97
  def import_jac_mod_from_dir(self, target: str) -> uni.Module:
104
98
  """Import a module from a directory."""
105
- from jaclang.compiler.passes.main import CompilerMode as CMode
106
-
107
99
  jac_init_path = os.path.join(target, "__init__.jac")
108
100
  if os.path.exists(jac_init_path):
109
101
  if jac_init_path in self.prog.mod.hub:
110
102
  return self.prog.mod.hub[jac_init_path]
111
- return self.prog.compile(file_path=jac_init_path, mode=CMode.PARSE)
103
+ return self.prog.compile(file_path=jac_init_path)
112
104
  elif os.path.exists(py_init_path := os.path.join(target, "__init__.py")):
113
105
  with open(py_init_path, "r") as f:
114
106
  file_source = f.read()
@@ -204,8 +196,8 @@ class PyImportDepsPass(JacImportDepsPass):
204
196
  """Process the imports in form of `import X`."""
205
197
  # Expected that each ImportStatement will import one item
206
198
  # In case of this assertion fired then we need to revisit this item
207
- assert len(imp_node.items.items) == 1
208
- imported_item = imp_node.items.items[0]
199
+ assert len(imp_node.items) == 1
200
+ imported_item = imp_node.items[0]
209
201
  assert isinstance(imported_item, uni.ModulePath)
210
202
 
211
203
  imported_mod = self.__import_py_module(
@@ -36,11 +36,11 @@ class InheritancePass(Transform[uni.Module, uni.Module]):
36
36
 
37
37
  def process_archetype_inheritance(self, node: uni.Archetype) -> None:
38
38
  """Fill archetype symbol tables with abilities from parent archetypes."""
39
- if node.base_classes is None:
39
+ if not node.base_classes:
40
40
  return
41
41
 
42
42
  self.cur_node = node
43
- for item in node.base_classes.items:
43
+ for item in node.base_classes:
44
44
  # Handle different types of base class references
45
45
  if isinstance(item, uni.Name):
46
46
  self.inherit_from_name(node, item)