jaclang 0.7.16__py3-none-any.whl → 0.7.17__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 (77) hide show
  1. jaclang/cli/cli.py +140 -75
  2. jaclang/compiler/absyntree.py +9 -4
  3. jaclang/compiler/constant.py +8 -8
  4. jaclang/compiler/parser.py +10 -2
  5. jaclang/compiler/passes/main/__init__.py +1 -1
  6. jaclang/compiler/passes/main/access_modifier_pass.py +96 -147
  7. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +152 -50
  8. jaclang/compiler/passes/main/import_pass.py +88 -59
  9. jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
  10. jaclang/compiler/passes/main/pyast_gen_pass.py +21 -6
  11. jaclang/compiler/passes/main/pyast_load_pass.py +1 -0
  12. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
  13. jaclang/compiler/passes/main/schedules.py +9 -2
  14. jaclang/compiler/passes/main/sym_tab_build_pass.py +9 -5
  15. jaclang/compiler/passes/main/tests/fixtures/autoimpl.empty.impl.jac +0 -0
  16. jaclang/compiler/passes/main/tests/fixtures/autoimpl.jac +1 -1
  17. jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac +29 -0
  18. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -0
  19. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/color.py +3 -0
  20. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/constants.py +5 -0
  21. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/display.py +2 -0
  22. jaclang/compiler/passes/main/tests/test_import_pass.py +72 -13
  23. jaclang/compiler/passes/main/type_check_pass.py +15 -5
  24. jaclang/compiler/passes/tool/jac_formatter_pass.py +11 -3
  25. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
  26. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -41
  27. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
  28. jaclang/compiler/passes/utils/mypy_ast_build.py +45 -0
  29. jaclang/compiler/symtable.py +16 -11
  30. jaclang/compiler/tests/test_importer.py +17 -9
  31. jaclang/langserve/engine.py +39 -0
  32. jaclang/langserve/server.py +16 -1
  33. jaclang/langserve/tests/fixtures/rename.jac +30 -0
  34. jaclang/langserve/tests/test_server.py +216 -2
  35. jaclang/langserve/utils.py +21 -2
  36. jaclang/plugin/default.py +78 -70
  37. jaclang/plugin/feature.py +7 -17
  38. jaclang/plugin/spec.py +6 -19
  39. jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
  40. jaclang/plugin/tests/test_jaseci.py +414 -42
  41. jaclang/runtimelib/architype.py +481 -333
  42. jaclang/runtimelib/constructs.py +5 -8
  43. jaclang/runtimelib/context.py +89 -69
  44. jaclang/runtimelib/importer.py +15 -15
  45. jaclang/runtimelib/machine.py +66 -2
  46. jaclang/runtimelib/memory.py +134 -75
  47. jaclang/runtimelib/utils.py +17 -10
  48. jaclang/settings.py +2 -4
  49. jaclang/tests/fixtures/access_checker.jac +12 -17
  50. jaclang/tests/fixtures/access_modifier.jac +88 -33
  51. jaclang/tests/fixtures/baddy.jac +3 -0
  52. jaclang/tests/fixtures/bar.jac +34 -0
  53. jaclang/tests/fixtures/edge_node_walk.jac +1 -1
  54. jaclang/tests/fixtures/edge_ops.jac +1 -1
  55. jaclang/tests/fixtures/edges_walk.jac +1 -1
  56. jaclang/tests/fixtures/foo.jac +43 -0
  57. jaclang/tests/fixtures/game1.jac +1 -1
  58. jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
  59. jaclang/tests/fixtures/import.jac +9 -0
  60. jaclang/tests/fixtures/index_slice.jac +30 -0
  61. jaclang/tests/fixtures/pyfunc_1.py +1 -1
  62. jaclang/tests/fixtures/pyfunc_2.py +2 -2
  63. jaclang/tests/fixtures/pygame_mock/__init__.py +3 -0
  64. jaclang/tests/fixtures/pygame_mock/color.py +3 -0
  65. jaclang/tests/fixtures/pygame_mock/constants.py +5 -0
  66. jaclang/tests/fixtures/pygame_mock/display.py +2 -0
  67. jaclang/tests/fixtures/pygame_mock/inner/__init__.py +0 -0
  68. jaclang/tests/fixtures/pygame_mock/inner/iner_mod.py +2 -0
  69. jaclang/tests/test_cli.py +49 -6
  70. jaclang/tests/test_language.py +113 -78
  71. jaclang/tests/test_reference.py +2 -9
  72. jaclang/utils/treeprinter.py +30 -3
  73. {jaclang-0.7.16.dist-info → jaclang-0.7.17.dist-info}/METADATA +1 -1
  74. {jaclang-0.7.16.dist-info → jaclang-0.7.17.dist-info}/RECORD +77 -56
  75. /jaclang/tests/fixtures/{err.test.jac → baddy.test.jac} +0 -0
  76. {jaclang-0.7.16.dist-info → jaclang-0.7.17.dist-info}/WHEEL +0 -0
  77. {jaclang-0.7.16.dist-info → jaclang-0.7.17.dist-info}/entry_points.txt +0 -0
@@ -8,7 +8,6 @@ import os
8
8
  import pathlib
9
9
  import sys
10
10
 
11
- # import jaclang
12
11
  import jaclang.compiler.absyntree as ast
13
12
  import jaclang.compiler.passes.utils.mypy_ast_build as myab
14
13
  from jaclang.compiler.constant import Constants as Con
@@ -35,7 +34,7 @@ class JacTypeCheckPass(Pass):
35
34
  def after_pass(self) -> None:
36
35
  """Call mypy api after traversing all the modules."""
37
36
  try:
38
- self.api()
37
+ self.api(os.path.dirname(self.ir.loc.mod_path))
39
38
  except Exception as e:
40
39
  self.error(f"Unable to run type checking: {e}")
41
40
  return super().after_pass()
@@ -45,7 +44,7 @@ class JacTypeCheckPass(Pass):
45
44
  ) -> None:
46
45
  """Mypy errors reporter."""
47
46
 
48
- def api(self) -> None:
47
+ def api(self, top_module_path: str = "") -> None:
49
48
  """Call mypy APIs to implement type checking in Jac."""
50
49
  # Creating mypy api objects
51
50
  options = myab.myb.Options()
@@ -57,6 +56,9 @@ class JacTypeCheckPass(Pass):
57
56
  / "stubs"
58
57
  )
59
58
  ]
59
+ if top_module_path != "":
60
+ options.mypy_path.append(top_module_path)
61
+
60
62
  errors = myab.Errors(self, options)
61
63
  fs_cache = myab.FileSystemCache()
62
64
  search_paths = myab.compute_search_paths([], options, str(self.__path))
@@ -101,7 +103,9 @@ class JacTypeCheckPass(Pass):
101
103
  mypy_graph[module.name] = st
102
104
  new_modules.append(st)
103
105
 
104
- graph = myab.load_graph(
106
+ if not isinstance(self.ir, ast.Module):
107
+ raise self.ice("Expected module node. Impossible")
108
+ mypy_graph = myab.load_graph(
105
109
  [
106
110
  myab.BuildSource(
107
111
  path=str(self.__path / "typeshed" / "stdlib" / "builtins.pyi"),
@@ -112,4 +116,10 @@ class JacTypeCheckPass(Pass):
112
116
  old_graph=mypy_graph,
113
117
  new_modules=new_modules, # To parse the dependancies of modules
114
118
  )
115
- myab.process_graph(graph, manager)
119
+ for i in mypy_graph:
120
+ self.ir.py_mod_dep_map[i] = mypy_graph[i].xpath
121
+ for j in mypy_graph[i].dependencies:
122
+ self.ir.py_mod_dep_map[j] = str(
123
+ myab.find_module_with_reason(j, manager)
124
+ )
125
+ myab.process_graph(mypy_graph, manager)
@@ -322,6 +322,7 @@ class JacFormatPass(Pass):
322
322
  tag: T,
323
323
  """
324
324
  start = True
325
+ prev_token = None
325
326
  for i in node.kid:
326
327
  if isinstance(i, ast.CommentToken):
327
328
  if i.is_inline:
@@ -336,8 +337,13 @@ class JacFormatPass(Pass):
336
337
  elif i.gen.jac == ",":
337
338
  self.emit(node, f"{i.gen.jac} ")
338
339
  else:
339
- if start:
340
- self.emit(node, i.gen.jac)
340
+ if isinstance(i, ast.Token) and not isinstance(i, ast.BuiltinType):
341
+ try:
342
+ prev_token = self.token_before(i)
343
+ except Exception:
344
+ prev_token = None
345
+ if start or (prev_token and prev_token.gen.jac.strip() == ":"):
346
+ self.emit(node, i.gen.jac.strip())
341
347
  start = False
342
348
  else:
343
349
  self.emit(node, f" {i.gen.jac}")
@@ -439,7 +445,7 @@ class JacFormatPass(Pass):
439
445
  path: list[Token],
440
446
  alias: Optional[Name],
441
447
  """
442
- self.emit(node, node.path_str)
448
+ self.emit(node, node.dot_path_str)
443
449
  if node.alias:
444
450
  self.emit(node, " as " + node.alias.gen.jac)
445
451
 
@@ -651,6 +657,8 @@ class JacFormatPass(Pass):
651
657
  self.emit(node, i.gen.jac)
652
658
  elif isinstance(i, ast.SubNodeList) and i.gen.jac.startswith("@"):
653
659
  self.emit_ln(node, i.gen.jac)
660
+ elif isinstance(i, ast.SubTag):
661
+ self.emit(node, i.gen.jac)
654
662
  else:
655
663
  if start:
656
664
  self.emit(node, i.gen.jac)
@@ -32,7 +32,7 @@ obj ExecutionContext {
32
32
  "Global Execution Context, should be monkey patched by the user."
33
33
  glob exec_ctx = ExecutionContext();
34
34
 
35
- obj ElementAnchor {
35
+ obj Anchor :ArchitypeProtocol: {
36
36
  has ob: object,
37
37
  jid: UUID = :> uuid4,
38
38
  timestamp: datetime = :> datetime.now,
@@ -41,8 +41,12 @@ obj ElementAnchor {
41
41
  rw_access: set = :> set,
42
42
  ro_access: set = :> set,
43
43
  owner_id: UUID = exec_ctx.master,
44
- mem: Memory = exec_ctx.memory;
44
+ mem: Memory = exec_ctx.memory,
45
+ ds_entry_funcs: list[DSFunc],
46
+ ds_exit_funcs: list[DSFunc];
45
47
 
48
+ static can on_entry(cls: type, triggers: list[type]);
49
+ static can on_exit(cls: type, triggers: list[type]);
46
50
  can make_public_ro;
47
51
  can make_public_rw;
48
52
  can make_private;
@@ -55,15 +59,7 @@ obj ElementAnchor {
55
59
  can revoke_access(caller_id: UUID);
56
60
  }
57
61
 
58
- obj ObjectAnchor :ElementAnchor, ArchitypeProtocol: {
59
- has ds_entry_funcs: list[DSFunc],
60
- ds_exit_funcs: list[DSFunc];
61
-
62
- static can on_entry(cls: type, triggers: list[type]);
63
- static can on_exit(cls: type, triggers: list[type]);
64
- }
65
-
66
- obj NodeAnchor :ObjectAnchor: {
62
+ obj NodeAnchor :Anchor: {
67
63
  has edges: dict[EdgeDir, list[Edge]] = {EdgeDir.IN: [], EdgeDir.OUT: []};
68
64
 
69
65
  can connect_node(nd: Node, edg: Edge) -> Node;
@@ -71,7 +67,7 @@ obj NodeAnchor :ObjectAnchor: {
71
67
  can __call__(walk: Walker);
72
68
  }
73
69
 
74
- obj EdgeAnchor :ObjectAnchor: {
70
+ obj EdgeAnchor :Anchor: {
75
71
  has source: Node = None,
76
72
  target: Node = None,
77
73
  dir: EdgeDir = None;
@@ -81,7 +77,7 @@ obj EdgeAnchor :ObjectAnchor: {
81
77
  can __call__(walk: Walker);
82
78
  }
83
79
 
84
- obj WalkerAnchor :ObjectAnchor: {
80
+ obj WalkerAnchor :Anchor: {
85
81
  has path: list[Node] = [],
86
82
  next: list[Node] = [],
87
83
  ignores: list[Node] = [],
@@ -94,27 +90,27 @@ obj WalkerAnchor :ObjectAnchor: {
94
90
  }
95
91
 
96
92
  obj Root :AbsRootHook: {
97
- has _jac_: NodeAnchor | None = None;
93
+ has __jac__: NodeAnchor | None = None;
98
94
 
99
95
  can postinit {
100
- self._jac_ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
96
+ self.__jac__ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
101
97
  }
102
98
  }
103
99
 
104
100
  obj GenericEdge :ArchitypeProtocol: {
105
- has _jac_: EdgeAnchor | None = None;
101
+ has __jac__: EdgeAnchor | None = None;
106
102
 
107
103
  can postinit {
108
- self._jac_ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
104
+ self.__jac__ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
109
105
  }
110
106
  }
111
107
 
112
108
  obj Master {
113
- has _jac_: ElementAnchor | None = None;
109
+ has __jac__: Anchor | None = None;
114
110
  has root_node: Root = Root(Root);
115
111
 
116
112
  can postinit {
117
- self._jac_ = ElementAnchor(self);
113
+ self.__jac__ = Anchor(self);
118
114
  }
119
115
  }
120
116
 
@@ -204,31 +200,31 @@ obj JacPlugin {
204
200
  PRIVATE
205
201
  }
206
202
 
207
- :obj:ElementAnchor:can:make_public_ro {
203
+ :obj:Anchor:can:make_public_ro {
208
204
  self.__jinfo.access_mode = AccessMode.READ_ONLY;
209
205
  }
210
206
 
211
- :obj:ElementAnchor:can:make_public_rw {
207
+ :obj:Anchor:can:make_public_rw {
212
208
  self.__jinfo.access_mode = AccessMode.READ_WRITE;
213
209
  }
214
210
 
215
- :obj:ElementAnchor:can:make_private {
211
+ :obj:Anchor:can:make_private {
216
212
  self.__jinfo.access_mode = AccessMode.PRIVATE;
217
213
  }
218
214
 
219
- :obj:ElementAnchor:can:is_public_ro -> bool {
215
+ :obj:Anchor:can:is_public_ro -> bool {
220
216
  return self.__jinfo.access_mode == AccessMode.READ_ONLY;
221
217
  }
222
218
 
223
- :obj:ElementAnchor:can:is_public_rw -> bool {
219
+ :obj:Anchor:can:is_public_rw -> bool {
224
220
  return self.__jinfo.access_mode == AccessMode.READ_WRITE;
225
221
  }
226
222
 
227
- :obj:ElementAnchor:can:is_private -> bool {
223
+ :obj:Anchor:can:is_private -> bool {
228
224
  return self.__jinfo.access_mode == AccessMode.PRIVATE;
229
225
  }
230
226
 
231
- :obj:ElementAnchor:can:is_readable
227
+ :obj:Anchor:can:is_readable
232
228
  (caller_id: UUID) -> bool {
233
229
  return (caller_id == self.owner_id
234
230
  or |> self.is_public_read
@@ -236,14 +232,14 @@ obj JacPlugin {
236
232
  or caller_id in self.rw_access);
237
233
  }
238
234
 
239
- :obj:ElementAnchor:can:is_writable
235
+ :obj:Anchor:can:is_writable
240
236
  (caller_id: UUID) -> bool {
241
237
  return (caller_id == self.owner_id
242
238
  or |> self.is_public_write
243
239
  or caller_id in self.rw_access);
244
240
  }
245
241
 
246
- :obj:ElementAnchor:can:give_access
242
+ :obj:Anchor:can:give_access
247
243
  (caller_id: UUID, read_write: bool=False) {
248
244
  if read_write {
249
245
  caller_id |> self.rw_access.add;
@@ -252,13 +248,13 @@ obj JacPlugin {
252
248
  }
253
249
  }
254
250
 
255
- :obj:ElementAnchor:can:revoke_access
251
+ :obj:Anchor:can:revoke_access
256
252
  (caller_id: UUID) {
257
253
  caller_id |> self.ro_access.discard;
258
254
  caller_id |> self.rw_access.discard;
259
255
  }
260
256
 
261
- :obj:ObjectAnchor:can:on_entry
257
+ :obj:Anchor:can:on_entry
262
258
  (cls: type, triggers: list) {
263
259
  can decorator(func: callable) -> callable {
264
260
  cls.ds_entry_funcs.append(
@@ -272,7 +268,7 @@ obj JacPlugin {
272
268
  return decorator;
273
269
  }
274
270
 
275
- :obj:ObjectAnchor:can:on_exit
271
+ :obj:Anchor:can:on_exit
276
272
  (cls: type, triggers: list) {
277
273
  can decorator(func: callable) -> callable {
278
274
  cls.ds_exit_funcs.append(
@@ -361,7 +357,7 @@ obj JacPlugin {
361
357
 
362
358
  :obj:NodeAnchor:can:__call__
363
359
  (walk: object) {
364
- if not isinstance(walk._jac_, WalkerAnchor) {
360
+ if not isinstance(walk.__jac__, WalkerAnchor) {
365
361
  raise TypeError("Argument must be a Walker instance");
366
362
  }
367
363
  walk(self);
@@ -369,10 +365,10 @@ obj JacPlugin {
369
365
 
370
366
  :obj:EdgeAnchor:can:__call__
371
367
  (walk: EdgeInterface) {
372
- if not isinstance(walk._jac_, WalkerAnchor) {
368
+ if not isinstance(walk.__jac__, WalkerAnchor) {
373
369
  raise TypeError("Argument must be a Walker instance");
374
370
  }
375
- walk(self._jac_.target);
371
+ walk(self.__jac__.target);
376
372
  }
377
373
 
378
374
  :obj:WalkerAnchor:can:__call__
@@ -423,25 +419,25 @@ obj JacPlugin {
423
419
  (arch: AT, arch_type: str, on_entry: list[DSFunc], on_exit: list[DSFunc]) -> bool {
424
420
  match arch_type {
425
421
  case 'obj':
426
- arch._jac_ = ObjectAnchor(
422
+ arch.__jac__ = Anchor(
427
423
  ob=arch,
428
424
  ds_entry_funcs=on_entry,
429
425
  ds_exit_funcs=on_exit
430
426
  );
431
427
  case 'node':
432
- arch._jac_ = NodeAnchor(
428
+ arch.__jac__ = NodeAnchor(
433
429
  ob=arch,
434
430
  ds_entry_funcs=on_entry,
435
431
  ds_exit_funcs=on_exit
436
432
  );
437
433
  case 'edge':
438
- arch._jac_ = EdgeAnchor(
434
+ arch.__jac__ = EdgeAnchor(
439
435
  ob=arch,
440
436
  ds_entry_funcs=on_entry,
441
437
  ds_exit_funcs=on_exit
442
438
  );
443
439
  case 'walker':
444
- arch._jac_ = WalkerAnchor(
440
+ arch.__jac__ = WalkerAnchor(
445
441
  ob=arch,
446
442
  ds_entry_funcs=on_entry,
447
443
  ds_exit_funcs=on_exit
@@ -464,19 +460,19 @@ obj JacPlugin {
464
460
  edg_type = edge_spec[1];
465
461
  }
466
462
  edg = edg_type(*(edge_spec[2])) if edge_spec[2] else edg_type();
467
- edg._jac_.apply_dir(edge_spec[0]);
463
+ edg.__jac__.apply_dir(edge_spec[0]);
468
464
  return edg;
469
465
  }
470
466
 
471
467
  :obj:JacPlugin:can:connect
472
468
  (left: T, right: T, edge_spec: tuple[int, Optional[type], Optional[tuple]]) -> Architype {
473
469
  edg = JacPlugin.build_edge(edge_spec);
474
- left.connect_node(right._jac_, edg._jac_);
470
+ left.connect_node(right.__jac__, edg.__jac__);
475
471
  }
476
472
 
477
473
  :obj:JacPlugin:can:visit_node
478
474
  (walker_obj: Any, expr: Any) -> bool {
479
- return walker_obj._jac_.visit_node(expr);
475
+ return walker_obj.__jac__.visit_node(expr);
480
476
  }
481
477
 
482
478
  glob expected_area = 78.53981633974483;
@@ -31,7 +31,7 @@ obj ExecutionContext {
31
31
  "Global Execution Context, should be monkey patched by the user."
32
32
  glob exec_ctx = ExecutionContext();
33
33
 
34
- obj ElementAnchor {
34
+ obj Anchor :ArchitypeProtocol: {
35
35
  has ob: object,
36
36
  jid: UUID = :> uuid4,
37
37
  timestamp: datetime = :> datetime.now,
@@ -40,8 +40,12 @@ obj ElementAnchor {
40
40
  rw_access: set = :> set,
41
41
  ro_access: set = :> set,
42
42
  owner_id: UUID = exec_ctx.master,
43
- mem: Memory = exec_ctx.memory;
43
+ mem: Memory = exec_ctx.memory,
44
+ ds_entry_funcs: list[DSFunc],
45
+ ds_exit_funcs: list[DSFunc];
44
46
 
47
+ static can on_entry(cls: type, triggers: list[type]);
48
+ static can on_exit(cls: type, triggers: list[type]);
45
49
  can make_public_ro;
46
50
  can make_public_rw;
47
51
  can make_private;
@@ -54,15 +58,7 @@ obj ElementAnchor {
54
58
  can revoke_access(caller_id: UUID);
55
59
  }
56
60
 
57
- obj ObjectAnchor :ElementAnchor, ArchitypeProtocol: {
58
- has ds_entry_funcs: list[DSFunc],
59
- ds_exit_funcs: list[DSFunc];
60
-
61
- static can on_entry(cls: type, triggers: list[type]);
62
- static can on_exit(cls: type, triggers: list[type]);
63
- }
64
-
65
- obj NodeAnchor :ObjectAnchor: {
61
+ obj NodeAnchor :Anchor: {
66
62
  has edges: dict[EdgeDir, list[Edge]] = {EdgeDir.IN: [], EdgeDir.OUT: []};
67
63
 
68
64
  can connect_node(nd: Node, edg: Edge) -> Node;
@@ -70,7 +66,7 @@ obj NodeAnchor :ObjectAnchor: {
70
66
  can __call__(walk: Walker);
71
67
  }
72
68
 
73
- obj EdgeAnchor :ObjectAnchor: {
69
+ obj EdgeAnchor :Anchor: {
74
70
  has source: Node = None,
75
71
  target: Node = None,
76
72
  dir: EdgeDir = None;
@@ -80,7 +76,7 @@ obj EdgeAnchor :ObjectAnchor: {
80
76
  can __call__(walk: Walker);
81
77
  }
82
78
 
83
- obj WalkerAnchor :ObjectAnchor: {
79
+ obj WalkerAnchor :Anchor: {
84
80
  has path: list[Node] = [],
85
81
  next: list[Node] = [],
86
82
  ignores: list[Node] = [],
@@ -93,27 +89,27 @@ obj WalkerAnchor :ObjectAnchor: {
93
89
  }
94
90
 
95
91
  obj Root :AbsRootHook: {
96
- has _jac_: NodeAnchor | None = None;
92
+ has __jac__: NodeAnchor | None = None;
97
93
 
98
94
  can postinit {
99
- self._jac_ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
95
+ self.__jac__ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
100
96
  }
101
97
  }
102
98
 
103
99
  obj GenericEdge :ArchitypeProtocol: {
104
- has _jac_: EdgeAnchor | None = None;
100
+ has __jac__: EdgeAnchor | None = None;
105
101
 
106
102
  can postinit {
107
- self._jac_ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
103
+ self.__jac__ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
108
104
  }
109
105
  }
110
106
 
111
107
  obj Master {
112
- has _jac_: ElementAnchor | None = None;
108
+ has __jac__: Anchor | None = None;
113
109
  has root_node: Root = Root(Root);
114
110
 
115
111
  can postinit {
116
- self._jac_ = ElementAnchor(self);
112
+ self.__jac__ = Anchor(self);
117
113
  }
118
114
  }
119
115
 
@@ -203,31 +199,31 @@ obj JacPlugin {
203
199
  PRIVATE
204
200
  }
205
201
 
206
- :obj:ElementAnchor:can:make_public_ro {
202
+ :obj:Anchor:can:make_public_ro {
207
203
  self.__jinfo.access_mode = AccessMode.READ_ONLY;
208
204
  }
209
205
 
210
- :obj:ElementAnchor:can:make_public_rw {
206
+ :obj:Anchor:can:make_public_rw {
211
207
  self.__jinfo.access_mode = AccessMode.READ_WRITE;
212
208
  }
213
209
 
214
- :obj:ElementAnchor:can:make_private {
210
+ :obj:Anchor:can:make_private {
215
211
  self.__jinfo.access_mode = AccessMode.PRIVATE;
216
212
  }
217
213
 
218
- :obj:ElementAnchor:can:is_public_ro -> bool {
214
+ :obj:Anchor:can:is_public_ro -> bool {
219
215
  return self.__jinfo.access_mode == AccessMode.READ_ONLY;
220
216
  }
221
217
 
222
- :obj:ElementAnchor:can:is_public_rw -> bool {
218
+ :obj:Anchor:can:is_public_rw -> bool {
223
219
  return self.__jinfo.access_mode == AccessMode.READ_WRITE;
224
220
  }
225
221
 
226
- :obj:ElementAnchor:can:is_private -> bool {
222
+ :obj:Anchor:can:is_private -> bool {
227
223
  return self.__jinfo.access_mode == AccessMode.PRIVATE;
228
224
  }
229
225
 
230
- :obj:ElementAnchor:can:is_readable
226
+ :obj:Anchor:can:is_readable
231
227
  (caller_id: UUID) -> bool {
232
228
  return (caller_id == self.owner_id
233
229
  or |> self.is_public_read
@@ -235,14 +231,14 @@ obj JacPlugin {
235
231
  or caller_id in self.rw_access);
236
232
  }
237
233
 
238
- :obj:ElementAnchor:can:is_writable
234
+ :obj:Anchor:can:is_writable
239
235
  (caller_id: UUID) -> bool {
240
236
  return (caller_id == self.owner_id
241
237
  or |> self.is_public_write
242
238
  or caller_id in self.rw_access);
243
239
  }
244
240
 
245
- :obj:ElementAnchor:can:give_access
241
+ :obj:Anchor:can:give_access
246
242
  (caller_id: UUID, read_write: bool=False) {
247
243
  if read_write {
248
244
  caller_id |> self.rw_access.add;
@@ -251,13 +247,13 @@ obj JacPlugin {
251
247
  }
252
248
  }
253
249
 
254
- :obj:ElementAnchor:can:revoke_access
250
+ :obj:Anchor:can:revoke_access
255
251
  (caller_id: UUID) {
256
252
  caller_id |> self.ro_access.discard;
257
253
  caller_id |> self.rw_access.discard;
258
254
  }
259
255
 
260
- :obj:ObjectAnchor:can:on_entry
256
+ :obj:Anchor:can:on_entry
261
257
  (cls: type, triggers: list) {
262
258
  can decorator(func: callable) -> callable {
263
259
  cls.ds_entry_funcs.append(
@@ -271,7 +267,7 @@ obj JacPlugin {
271
267
  return decorator;
272
268
  }
273
269
 
274
- :obj:ObjectAnchor:can:on_exit
270
+ :obj:Anchor:can:on_exit
275
271
  (cls: type, triggers: list) {
276
272
  can decorator(func: callable) -> callable {
277
273
  cls.ds_exit_funcs.append(
@@ -360,7 +356,7 @@ obj JacPlugin {
360
356
 
361
357
  :obj:NodeAnchor:can:__call__
362
358
  (walk: object) {
363
- if not isinstance(walk._jac_, WalkerAnchor) {
359
+ if not isinstance(walk.__jac__, WalkerAnchor) {
364
360
  raise TypeError("Argument must be a Walker instance");
365
361
  }
366
362
  walk(self);
@@ -368,10 +364,10 @@ obj JacPlugin {
368
364
 
369
365
  :obj:EdgeAnchor:can:__call__
370
366
  (walk: EdgeInterface) {
371
- if not isinstance(walk._jac_, WalkerAnchor) {
367
+ if not isinstance(walk.__jac__, WalkerAnchor) {
372
368
  raise TypeError("Argument must be a Walker instance");
373
369
  }
374
- walk(self._jac_.target);
370
+ walk(self.__jac__.target);
375
371
  }
376
372
 
377
373
  :obj:WalkerAnchor:can:__call__
@@ -422,25 +418,25 @@ obj JacPlugin {
422
418
  (arch: AT, arch_type: str, on_entry: list[DSFunc], on_exit: list[DSFunc]) -> bool {
423
419
  match arch_type {
424
420
  case 'obj':
425
- arch._jac_ = ObjectAnchor(
421
+ arch.__jac__ = Anchor(
426
422
  ob=arch,
427
423
  ds_entry_funcs=on_entry,
428
424
  ds_exit_funcs=on_exit
429
425
  );
430
426
  case 'node':
431
- arch._jac_ = NodeAnchor(
427
+ arch.__jac__ = NodeAnchor(
432
428
  ob=arch,
433
429
  ds_entry_funcs=on_entry,
434
430
  ds_exit_funcs=on_exit
435
431
  );
436
432
  case 'edge':
437
- arch._jac_ = EdgeAnchor(
433
+ arch.__jac__ = EdgeAnchor(
438
434
  ob=arch,
439
435
  ds_entry_funcs=on_entry,
440
436
  ds_exit_funcs=on_exit
441
437
  );
442
438
  case 'walker':
443
- arch._jac_ = WalkerAnchor(
439
+ arch.__jac__ = WalkerAnchor(
444
440
  ob=arch,
445
441
  ds_entry_funcs=on_entry,
446
442
  ds_exit_funcs=on_exit
@@ -463,19 +459,19 @@ obj JacPlugin {
463
459
  edg_type = edge_spec[1];
464
460
  }
465
461
  edg = edg_type(*(edge_spec[2])) if edge_spec[2] else edg_type();
466
- edg._jac_.apply_dir(edge_spec[0]);
462
+ edg.__jac__.apply_dir(edge_spec[0]);
467
463
  return edg;
468
464
  }
469
465
 
470
466
  :obj:JacPlugin:can:connect
471
467
  (left: T, right: T, edge_spec: tuple[int, Optional[type], Optional[tuple]]) -> Architype {
472
468
  edg = JacPlugin.build_edge(edge_spec);
473
- left.connect_node(right._jac_, edg._jac_);
469
+ left.connect_node(right.__jac__, edg.__jac__);
474
470
  }
475
471
 
476
472
  :obj:JacPlugin:can:visit_node
477
473
  (walker_obj: Any, expr: Any) -> bool {
478
- return walker_obj._jac_.visit_node(expr);
474
+ return walker_obj.__jac__.visit_node(expr);
479
475
  }
480
476
 
481
477
  glob expected_area = 78.53981633974483;
@@ -0,0 +1,27 @@
1
+ can:priv hash(func: Any) {
2
+ can inner(a: Any) {
3
+ print(("#" * 20));
4
+ func(a);
5
+ print(("#" * 20));
6
+ }
7
+ return inner;
8
+ }
9
+
10
+ can:protect exclaim(func: Any) {
11
+ can inner(b: Any) {
12
+ print(("!" * 20));
13
+ func(b);
14
+ print(("!" * 20));
15
+ }
16
+ return inner;
17
+ }
18
+
19
+ @hash
20
+ @exclaim
21
+ can greeter(name: Any) {
22
+ print("Hello, " + name + "!");
23
+ }
24
+
25
+ with entry {
26
+ greeter("World");
27
+ }
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import ast
6
6
  import os
7
+ from typing import Callable, TYPE_CHECKING, TextIO
7
8
 
8
9
  from jaclang.compiler.absyntree import AstNode
9
10
  from jaclang.compiler.passes import Pass
@@ -21,13 +22,19 @@ from mypy.build import FileSystemCache
21
22
  from mypy.build import Graph
22
23
  from mypy.build import ModuleNotFound
23
24
  from mypy.build import PRI_INDIRECT
25
+ from mypy.build import Plugin
26
+ from mypy.build import SearchPaths
24
27
  from mypy.build import compute_search_paths
25
28
  from mypy.build import find_module_simple
29
+ from mypy.build import find_module_with_reason
26
30
  from mypy.build import load_plugins
27
31
  from mypy.build import process_graph
28
32
  from mypy.options import Options
29
33
  from mypy.semanal_main import semantic_analysis_for_scc
30
34
 
35
+ if TYPE_CHECKING:
36
+ from mypy.report import Reports # Avoid unconditional slow import
37
+
31
38
 
32
39
  mypy_to_jac_node_map: dict[
33
40
  tuple[int, int | None, int | None, int | None], list[AstNode]
@@ -37,6 +44,43 @@ mypy_to_jac_node_map: dict[
37
44
  class BuildManager(myb.BuildManager):
38
45
  """Overrides to mypy build manager for direct AST pass through."""
39
46
 
47
+ def __init__(
48
+ self,
49
+ data_dir: str,
50
+ search_paths: SearchPaths,
51
+ ignore_prefix: str,
52
+ source_set: BuildSourceSet,
53
+ reports: Reports | None,
54
+ options: Options,
55
+ version_id: str,
56
+ plugin: Plugin,
57
+ plugins_snapshot: dict[str, str],
58
+ errors: Errors,
59
+ flush_errors: Callable[[str | None, list[str], bool], None],
60
+ fscache: FileSystemCache,
61
+ stdout: TextIO,
62
+ stderr: TextIO,
63
+ ) -> None:
64
+ """Override mypy BuildManager constructor to initialize jac related map."""
65
+ global mypy_to_jac_node_map
66
+ super().__init__(
67
+ data_dir,
68
+ search_paths,
69
+ ignore_prefix,
70
+ source_set,
71
+ reports,
72
+ options,
73
+ version_id,
74
+ plugin,
75
+ plugins_snapshot,
76
+ errors,
77
+ flush_errors,
78
+ fscache,
79
+ stdout,
80
+ stderr,
81
+ )
82
+ mypy_to_jac_node_map = {}
83
+
40
84
  def parse_file(
41
85
  self,
42
86
  id: str,
@@ -664,6 +708,7 @@ __all__ = [
664
708
  "BuildSource",
665
709
  "BuildSourceSet",
666
710
  "FileSystemCache",
711
+ "find_module_with_reason",
667
712
  "compute_search_paths",
668
713
  "load_graph",
669
714
  "load_plugins",