jaclang 0.7.14__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 (131) hide show
  1. jaclang/cli/cli.py +147 -77
  2. jaclang/cli/cmdreg.py +9 -12
  3. jaclang/compiler/__init__.py +19 -53
  4. jaclang/compiler/absyntree.py +94 -16
  5. jaclang/compiler/constant.py +8 -8
  6. jaclang/compiler/jac.lark +4 -3
  7. jaclang/compiler/parser.py +41 -25
  8. jaclang/compiler/passes/ir_pass.py +4 -13
  9. jaclang/compiler/passes/main/__init__.py +1 -1
  10. jaclang/compiler/passes/main/access_modifier_pass.py +96 -147
  11. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +155 -54
  12. jaclang/compiler/passes/main/import_pass.py +99 -75
  13. jaclang/compiler/passes/main/py_collect_dep_pass.py +70 -0
  14. jaclang/compiler/passes/main/pyast_gen_pass.py +328 -565
  15. jaclang/compiler/passes/main/pyast_load_pass.py +33 -6
  16. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -0
  17. jaclang/compiler/passes/main/registry_pass.py +37 -3
  18. jaclang/compiler/passes/main/schedules.py +9 -2
  19. jaclang/compiler/passes/main/sym_tab_build_pass.py +10 -6
  20. jaclang/compiler/passes/main/tests/__init__.py +1 -1
  21. jaclang/compiler/passes/main/tests/fixtures/autoimpl.empty.impl.jac +0 -0
  22. jaclang/compiler/passes/main/tests/fixtures/autoimpl.jac +1 -1
  23. jaclang/compiler/passes/main/tests/fixtures/py_imp_test.jac +29 -0
  24. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.py +3 -0
  25. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/color.py +3 -0
  26. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/constants.py +5 -0
  27. jaclang/compiler/passes/main/tests/fixtures/pygame_mock/display.py +2 -0
  28. jaclang/compiler/passes/main/tests/test_import_pass.py +72 -13
  29. jaclang/compiler/passes/main/type_check_pass.py +22 -5
  30. jaclang/compiler/passes/tool/jac_formatter_pass.py +135 -89
  31. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +37 -41
  32. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +37 -42
  33. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/access_mod_check.jac +27 -0
  34. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/architype_test.jac +13 -0
  35. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comment_alignment.jac +11 -0
  36. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/comments.jac +13 -0
  37. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/decorator_stack.jac +37 -0
  38. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/esc_keywords.jac +5 -0
  39. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/long_names.jac +19 -0
  40. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +6 -0
  41. jaclang/compiler/passes/tool/tests/test_jac_format_pass.py +11 -0
  42. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +33 -39
  43. jaclang/compiler/passes/transform.py +4 -0
  44. jaclang/compiler/passes/utils/mypy_ast_build.py +45 -0
  45. jaclang/compiler/semtable.py +31 -7
  46. jaclang/compiler/symtable.py +16 -11
  47. jaclang/compiler/tests/test_importer.py +25 -10
  48. jaclang/langserve/engine.py +104 -118
  49. jaclang/langserve/sem_manager.py +379 -0
  50. jaclang/langserve/server.py +24 -11
  51. jaclang/langserve/tests/fixtures/base_module_structure.jac +27 -6
  52. jaclang/langserve/tests/fixtures/circle.jac +3 -3
  53. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  54. jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
  55. jaclang/langserve/tests/fixtures/import_include_statements.jac +1 -1
  56. jaclang/langserve/tests/fixtures/rename.jac +30 -0
  57. jaclang/langserve/tests/test_sem_tokens.py +277 -0
  58. jaclang/langserve/tests/test_server.py +287 -17
  59. jaclang/langserve/utils.py +184 -98
  60. jaclang/plugin/builtin.py +1 -1
  61. jaclang/plugin/default.py +288 -92
  62. jaclang/plugin/feature.py +65 -27
  63. jaclang/plugin/spec.py +62 -23
  64. jaclang/plugin/tests/fixtures/other_root_access.jac +82 -0
  65. jaclang/plugin/tests/test_jaseci.py +414 -42
  66. jaclang/runtimelib/architype.py +650 -0
  67. jaclang/{core → runtimelib}/constructs.py +5 -8
  68. jaclang/{core → runtimelib}/context.py +86 -59
  69. jaclang/runtimelib/importer.py +361 -0
  70. jaclang/runtimelib/machine.py +158 -0
  71. jaclang/runtimelib/memory.py +158 -0
  72. jaclang/{core → runtimelib}/utils.py +30 -15
  73. jaclang/settings.py +5 -4
  74. jaclang/tests/fixtures/abc.jac +3 -3
  75. jaclang/tests/fixtures/access_checker.jac +12 -17
  76. jaclang/tests/fixtures/access_modifier.jac +88 -33
  77. jaclang/tests/fixtures/baddy.jac +3 -0
  78. jaclang/tests/fixtures/baddy.test.jac +3 -0
  79. jaclang/tests/fixtures/bar.jac +34 -0
  80. jaclang/tests/fixtures/byllmissue.jac +1 -5
  81. jaclang/tests/fixtures/chandra_bugs2.jac +11 -10
  82. jaclang/tests/fixtures/cls_method.jac +41 -0
  83. jaclang/tests/fixtures/dblhello.jac +6 -0
  84. jaclang/tests/fixtures/deep/one_lev.jac +3 -3
  85. jaclang/tests/fixtures/deep/one_lev_dup.jac +2 -3
  86. jaclang/tests/fixtures/deep_import_mods.jac +13 -0
  87. jaclang/tests/fixtures/edge_node_walk.jac +1 -1
  88. jaclang/tests/fixtures/edge_ops.jac +1 -1
  89. jaclang/tests/fixtures/edges_walk.jac +1 -1
  90. jaclang/tests/fixtures/err.impl.jac +3 -0
  91. jaclang/tests/fixtures/err.jac +4 -2
  92. jaclang/tests/fixtures/err_runtime.jac +15 -0
  93. jaclang/tests/fixtures/foo.jac +43 -0
  94. jaclang/tests/fixtures/gendot_bubble_sort.jac +1 -1
  95. jaclang/tests/fixtures/hello.jac +4 -0
  96. jaclang/tests/fixtures/impl_grab.impl.jac +2 -1
  97. jaclang/tests/fixtures/impl_grab.jac +4 -1
  98. jaclang/tests/fixtures/import.jac +9 -0
  99. jaclang/tests/fixtures/index_slice.jac +30 -0
  100. jaclang/tests/fixtures/jp_importer_auto.jac +14 -0
  101. jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
  102. jaclang/tests/fixtures/needs_import.jac +2 -2
  103. jaclang/tests/fixtures/pyfunc_1.py +1 -1
  104. jaclang/tests/fixtures/pyfunc_2.py +5 -2
  105. jaclang/tests/fixtures/pygame_mock/__init__.py +3 -0
  106. jaclang/tests/fixtures/pygame_mock/color.py +3 -0
  107. jaclang/tests/fixtures/pygame_mock/constants.py +5 -0
  108. jaclang/tests/fixtures/pygame_mock/display.py +2 -0
  109. jaclang/tests/fixtures/pygame_mock/inner/__init__.py +0 -0
  110. jaclang/tests/fixtures/pygame_mock/inner/iner_mod.py +2 -0
  111. jaclang/tests/fixtures/registry.jac +9 -0
  112. jaclang/tests/fixtures/run_test.jac +4 -4
  113. jaclang/tests/fixtures/semstr.jac +1 -4
  114. jaclang/tests/fixtures/simple_archs.jac +1 -1
  115. jaclang/tests/test_cli.py +109 -3
  116. jaclang/tests/test_language.py +170 -68
  117. jaclang/tests/test_reference.py +2 -3
  118. jaclang/utils/helpers.py +45 -21
  119. jaclang/utils/test.py +9 -0
  120. jaclang/utils/treeprinter.py +30 -7
  121. {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/METADATA +3 -2
  122. {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/RECORD +126 -90
  123. jaclang/core/architype.py +0 -502
  124. jaclang/core/importer.py +0 -344
  125. jaclang/core/memory.py +0 -99
  126. jaclang/tests/fixtures/aott_raise.jac +0 -25
  127. jaclang/tests/fixtures/package_import.jac +0 -6
  128. /jaclang/{core → runtimelib}/__init__.py +0 -0
  129. /jaclang/{core → runtimelib}/test.py +0 -0
  130. {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/WHEEL +0 -0
  131. {jaclang-0.7.14.dist-info → jaclang-0.7.17.dist-info}/entry_points.txt +0 -0
@@ -16,7 +16,6 @@ obj Memory {
16
16
  can save_obj(caller_id: UUID, item: Element);
17
17
  can del_obj(caller_id: UUID, item: Element);
18
18
  #* Utility Functions *#
19
-
20
19
  can get_object_distribution -> dict;
21
20
  can get_mem_size -> float;
22
21
  }
@@ -32,7 +31,7 @@ obj ExecutionContext {
32
31
  "Global Execution Context, should be monkey patched by the user."
33
32
  glob exec_ctx = ExecutionContext();
34
33
 
35
- obj ElementAnchor {
34
+ obj Anchor :ArchitypeProtocol: {
36
35
  has ob: object,
37
36
  jid: UUID = :> uuid4,
38
37
  timestamp: datetime = :> datetime.now,
@@ -41,8 +40,12 @@ obj ElementAnchor {
41
40
  rw_access: set = :> set,
42
41
  ro_access: set = :> set,
43
42
  owner_id: UUID = exec_ctx.master,
44
- mem: Memory = exec_ctx.memory;
43
+ mem: Memory = exec_ctx.memory,
44
+ ds_entry_funcs: list[DSFunc],
45
+ ds_exit_funcs: list[DSFunc];
45
46
 
47
+ static can on_entry(cls: type, triggers: list[type]);
48
+ static can on_exit(cls: type, triggers: list[type]);
46
49
  can make_public_ro;
47
50
  can make_public_rw;
48
51
  can make_private;
@@ -55,15 +58,7 @@ obj ElementAnchor {
55
58
  can revoke_access(caller_id: UUID);
56
59
  }
57
60
 
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: {
61
+ obj NodeAnchor :Anchor: {
67
62
  has edges: dict[EdgeDir, list[Edge]] = {EdgeDir.IN: [], EdgeDir.OUT: []};
68
63
 
69
64
  can connect_node(nd: Node, edg: Edge) -> Node;
@@ -71,7 +66,7 @@ obj NodeAnchor :ObjectAnchor: {
71
66
  can __call__(walk: Walker);
72
67
  }
73
68
 
74
- obj EdgeAnchor :ObjectAnchor: {
69
+ obj EdgeAnchor :Anchor: {
75
70
  has source: Node = None,
76
71
  target: Node = None,
77
72
  dir: EdgeDir = None;
@@ -81,7 +76,7 @@ obj EdgeAnchor :ObjectAnchor: {
81
76
  can __call__(walk: Walker);
82
77
  }
83
78
 
84
- obj WalkerAnchor :ObjectAnchor: {
79
+ obj WalkerAnchor :Anchor: {
85
80
  has path: list[Node] = [],
86
81
  next: list[Node] = [],
87
82
  ignores: list[Node] = [],
@@ -94,27 +89,27 @@ obj WalkerAnchor :ObjectAnchor: {
94
89
  }
95
90
 
96
91
  obj Root :AbsRootHook: {
97
- has _jac_: NodeAnchor | None = None;
92
+ has __jac__: NodeAnchor | None = None;
98
93
 
99
94
  can postinit {
100
- self._jac_ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
95
+ self.__jac__ = NodeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
101
96
  }
102
97
  }
103
98
 
104
99
  obj GenericEdge :ArchitypeProtocol: {
105
- has _jac_: EdgeAnchor | None = None;
100
+ has __jac__: EdgeAnchor | None = None;
106
101
 
107
102
  can postinit {
108
- self._jac_ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
103
+ self.__jac__ = EdgeAnchor(self, ds_entry_funcs=[], ds_exit_funcs=[]);
109
104
  }
110
105
  }
111
106
 
112
107
  obj Master {
113
- has _jac_: ElementAnchor | None = None;
108
+ has __jac__: Anchor | None = None;
114
109
  has root_node: Root = Root(Root);
115
110
 
116
111
  can postinit {
117
- self._jac_ = ElementAnchor(self);
112
+ self.__jac__ = Anchor(self);
118
113
  }
119
114
  }
120
115
 
@@ -204,31 +199,31 @@ obj JacPlugin {
204
199
  PRIVATE
205
200
  }
206
201
 
207
- :obj:ElementAnchor:can:make_public_ro {
202
+ :obj:Anchor:can:make_public_ro {
208
203
  self.__jinfo.access_mode = AccessMode.READ_ONLY;
209
204
  }
210
205
 
211
- :obj:ElementAnchor:can:make_public_rw {
206
+ :obj:Anchor:can:make_public_rw {
212
207
  self.__jinfo.access_mode = AccessMode.READ_WRITE;
213
208
  }
214
209
 
215
- :obj:ElementAnchor:can:make_private {
210
+ :obj:Anchor:can:make_private {
216
211
  self.__jinfo.access_mode = AccessMode.PRIVATE;
217
212
  }
218
213
 
219
- :obj:ElementAnchor:can:is_public_ro -> bool {
214
+ :obj:Anchor:can:is_public_ro -> bool {
220
215
  return self.__jinfo.access_mode == AccessMode.READ_ONLY;
221
216
  }
222
217
 
223
- :obj:ElementAnchor:can:is_public_rw -> bool {
218
+ :obj:Anchor:can:is_public_rw -> bool {
224
219
  return self.__jinfo.access_mode == AccessMode.READ_WRITE;
225
220
  }
226
221
 
227
- :obj:ElementAnchor:can:is_private -> bool {
222
+ :obj:Anchor:can:is_private -> bool {
228
223
  return self.__jinfo.access_mode == AccessMode.PRIVATE;
229
224
  }
230
225
 
231
- :obj:ElementAnchor:can:is_readable
226
+ :obj:Anchor:can:is_readable
232
227
  (caller_id: UUID) -> bool {
233
228
  return (caller_id == self.owner_id
234
229
  or |> self.is_public_read
@@ -236,14 +231,14 @@ obj JacPlugin {
236
231
  or caller_id in self.rw_access);
237
232
  }
238
233
 
239
- :obj:ElementAnchor:can:is_writable
234
+ :obj:Anchor:can:is_writable
240
235
  (caller_id: UUID) -> bool {
241
236
  return (caller_id == self.owner_id
242
237
  or |> self.is_public_write
243
238
  or caller_id in self.rw_access);
244
239
  }
245
240
 
246
- :obj:ElementAnchor:can:give_access
241
+ :obj:Anchor:can:give_access
247
242
  (caller_id: UUID, read_write: bool=False) {
248
243
  if read_write {
249
244
  caller_id |> self.rw_access.add;
@@ -252,13 +247,13 @@ obj JacPlugin {
252
247
  }
253
248
  }
254
249
 
255
- :obj:ElementAnchor:can:revoke_access
250
+ :obj:Anchor:can:revoke_access
256
251
  (caller_id: UUID) {
257
252
  caller_id |> self.ro_access.discard;
258
253
  caller_id |> self.rw_access.discard;
259
254
  }
260
255
 
261
- :obj:ObjectAnchor:can:on_entry
256
+ :obj:Anchor:can:on_entry
262
257
  (cls: type, triggers: list) {
263
258
  can decorator(func: callable) -> callable {
264
259
  cls.ds_entry_funcs.append(
@@ -272,7 +267,7 @@ obj JacPlugin {
272
267
  return decorator;
273
268
  }
274
269
 
275
- :obj:ObjectAnchor:can:on_exit
270
+ :obj:Anchor:can:on_exit
276
271
  (cls: type, triggers: list) {
277
272
  can decorator(func: callable) -> callable {
278
273
  cls.ds_exit_funcs.append(
@@ -361,7 +356,7 @@ obj JacPlugin {
361
356
 
362
357
  :obj:NodeAnchor:can:__call__
363
358
  (walk: object) {
364
- if not isinstance(walk._jac_, WalkerAnchor) {
359
+ if not isinstance(walk.__jac__, WalkerAnchor) {
365
360
  raise TypeError("Argument must be a Walker instance");
366
361
  }
367
362
  walk(self);
@@ -369,10 +364,10 @@ obj JacPlugin {
369
364
 
370
365
  :obj:EdgeAnchor:can:__call__
371
366
  (walk: EdgeInterface) {
372
- if not isinstance(walk._jac_, WalkerAnchor) {
367
+ if not isinstance(walk.__jac__, WalkerAnchor) {
373
368
  raise TypeError("Argument must be a Walker instance");
374
369
  }
375
- walk(self._jac_.target);
370
+ walk(self.__jac__.target);
376
371
  }
377
372
 
378
373
  :obj:WalkerAnchor:can:__call__
@@ -423,25 +418,25 @@ obj JacPlugin {
423
418
  (arch: AT, arch_type: str, on_entry: list[DSFunc], on_exit: list[DSFunc]) -> bool {
424
419
  match arch_type {
425
420
  case 'obj':
426
- arch._jac_ = ObjectAnchor(
421
+ arch.__jac__ = Anchor(
427
422
  ob=arch,
428
423
  ds_entry_funcs=on_entry,
429
424
  ds_exit_funcs=on_exit
430
425
  );
431
426
  case 'node':
432
- arch._jac_ = NodeAnchor(
427
+ arch.__jac__ = NodeAnchor(
433
428
  ob=arch,
434
429
  ds_entry_funcs=on_entry,
435
430
  ds_exit_funcs=on_exit
436
431
  );
437
432
  case 'edge':
438
- arch._jac_ = EdgeAnchor(
433
+ arch.__jac__ = EdgeAnchor(
439
434
  ob=arch,
440
435
  ds_entry_funcs=on_entry,
441
436
  ds_exit_funcs=on_exit
442
437
  );
443
438
  case 'walker':
444
- arch._jac_ = WalkerAnchor(
439
+ arch.__jac__ = WalkerAnchor(
445
440
  ob=arch,
446
441
  ds_entry_funcs=on_entry,
447
442
  ds_exit_funcs=on_exit
@@ -464,19 +459,19 @@ obj JacPlugin {
464
459
  edg_type = edge_spec[1];
465
460
  }
466
461
  edg = edg_type(*(edge_spec[2])) if edge_spec[2] else edg_type();
467
- edg._jac_.apply_dir(edge_spec[0]);
462
+ edg.__jac__.apply_dir(edge_spec[0]);
468
463
  return edg;
469
464
  }
470
465
 
471
466
  :obj:JacPlugin:can:connect
472
467
  (left: T, right: T, edge_spec: tuple[int, Optional[type], Optional[tuple]]) -> Architype {
473
468
  edg = JacPlugin.build_edge(edge_spec);
474
- left.connect_node(right._jac_, edg._jac_);
469
+ left.connect_node(right.__jac__, edg.__jac__);
475
470
  }
476
471
 
477
472
  :obj:JacPlugin:can:visit_node
478
473
  (walker_obj: Any, expr: Any) -> bool {
479
- return walker_obj._jac_.visit_node(expr);
474
+ return walker_obj.__jac__.visit_node(expr);
480
475
  }
481
476
 
482
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
+ }
@@ -0,0 +1,13 @@
1
+ class Animal {}
2
+
3
+ obj Domesticated {}
4
+
5
+ @print_base_classes
6
+ node Pet :Animal, Domesticated: {}
7
+
8
+ walker Person :Animal: {}
9
+
10
+ walker Feeder :Person: {}
11
+
12
+ @print_base_classes
13
+ walker Zoologist :Feeder: {}
@@ -0,0 +1,11 @@
1
+ obj inner_red {
2
+ has color22: string = 'red',
3
+ # self
4
+ doublepoint11: int = 2,
5
+ doublepoint22: float = 2.0,
6
+ # self
7
+ doublepoint33: int = 2,
8
+ # Comments explaining each attribute
9
+ # color22: represents the color, set to 'red'
10
+ point22: int = 20;
11
+ }
@@ -0,0 +1,13 @@
1
+ with entry:__main__ {
2
+ app = App();
3
+ app.run();
4
+ # ray.init_window(800, 450, "Hello");
5
+ # while not ray.window_should_close() {
6
+ # ray.begin_drawing();
7
+ # ray.clear_background(ray.WHITE);
8
+ # ray.draw_text("Hello world", 190, 200, 20, ray.VIOLET);
9
+ # ray.end_drawing();
10
+ # }
11
+
12
+ # ray.close_window();
13
+ }
@@ -0,0 +1,37 @@
1
+ can star(func: Any) {
2
+ can inner(x: Any) {
3
+ print(("*" * 30));
4
+ func(x);
5
+ print(("*" * 30));
6
+ }
7
+ return inner;
8
+ }
9
+
10
+ can percent(func: Any) {
11
+ can inner(y: Any) {
12
+ print(("%" * 30));
13
+ func(y);
14
+ print(("%" * 30));
15
+ }
16
+ return inner;
17
+ }
18
+
19
+ can percent2(func: Any) {
20
+ can inner(y: Any) {
21
+ print(("-" * 30));
22
+ func(y);
23
+ print(("+" * 30));
24
+ }
25
+ return inner;
26
+ }
27
+
28
+ @star
29
+ @percent
30
+ @percent2
31
+ can printer(msg: Any) {
32
+ print(msg);
33
+ }
34
+
35
+ with entry {
36
+ printer("Hello");
37
+ }
@@ -0,0 +1,5 @@
1
+ with entry {
2
+ <>self = 5;
3
+ <>self += <>self;
4
+ print(<>self);
5
+ }
@@ -0,0 +1,19 @@
1
+ with entry {
2
+ long_variable_name_1 = another_long_variable_name_2
3
+ = yet_another_long_variable_name_3
4
+ = still_another_long_variable_name_4
5
+ = yet_still_another_long_variable_name_5
6
+ = one_more_long_variable_name_6
7
+ = and_another_long_variable_name_7
8
+ = final_long_variable_name_8
9
+ =1.5;
10
+ result = long_variable_name_1
11
+ + another_long_variable_name_2
12
+ * yet_another_long_variable_name_3
13
+ - still_another_long_variable_name_4
14
+ / yet_still_another_long_variable_name_5
15
+ + one_more_long_variable_name_6
16
+ * and_another_long_variable_name_7
17
+ - final_long_variable_name_8;
18
+ print("The result of the ugly calculation is:", result);
19
+ }
@@ -0,0 +1,6 @@
1
+ with entry {
2
+ triple_quoted_string = """This is a triple quoted string.
3
+ It can span multiple lines.
4
+ It can contain any number of quotes or apostrophes.
5
+ """;
6
+ }
@@ -102,6 +102,17 @@ class JacFormatPassTests(TestCaseMicroSuite, AstSyncTestMixin):
102
102
  file_path = os.path.join(fixtures_dir, file_name)
103
103
  self.compare_files(file_path)
104
104
 
105
+ def test_general_format_fixtures(self) -> None:
106
+ """Tests if files in the general fixtures directory do not change after being formatted."""
107
+ fixtures_dir = os.path.join(self.fixture_abs_path(""), "general_format_checks")
108
+ fixture_files = os.listdir(fixtures_dir)
109
+ for file_name in fixture_files:
110
+ if file_name == "__jac_gen__":
111
+ continue
112
+ with self.subTest(file=file_name):
113
+ file_path = os.path.join(fixtures_dir, file_name)
114
+ self.compare_files(file_path)
115
+
105
116
  def micro_suite_test(self, filename: str) -> None:
106
117
  """Parse micro jac file."""
107
118
  code_gen_pure = jac_file_to_pass(
@@ -33,47 +33,41 @@ class JacUnparseTests(TestCaseMicroSuite, AstSyncTestMixin):
33
33
 
34
34
  def micro_suite_test(self, filename: str) -> None:
35
35
  """Parse micro jac file."""
36
- try:
37
- code_gen_pure = jac_file_to_pass(
38
- self.fixture_abs_path(filename),
39
- target=PyastGenPass,
40
- schedule=without_format,
36
+ code_gen_pure = jac_file_to_pass(
37
+ self.fixture_abs_path(filename),
38
+ target=PyastGenPass,
39
+ schedule=without_format,
40
+ )
41
+ before = ast3.dump(code_gen_pure.ir.gen.py_ast[0], indent=2)
42
+ x = code_gen_pure.ir.unparse()
43
+ # print(x)
44
+ # print(f"Testing {code_gen_pure.ir.name}")
45
+ # print(code_gen_pure.ir.pp())
46
+ code_gen_jac = jac_str_to_pass(
47
+ jac_str=x,
48
+ file_path=filename,
49
+ target=PyastGenPass,
50
+ schedule=without_format,
51
+ )
52
+ after = ast3.dump(code_gen_jac.ir.gen.py_ast[0], indent=2)
53
+ if "circle_clean_tests.jac" in filename:
54
+ self.assertEqual(
55
+ len(
56
+ [
57
+ i
58
+ for i in unified_diff(
59
+ before.splitlines(), after.splitlines(), n=0
60
+ )
61
+ if "test" not in i
62
+ ]
63
+ ),
64
+ 5,
41
65
  )
42
- before = ast3.dump(code_gen_pure.ir.gen.py_ast[0], indent=2)
43
- x = code_gen_pure.ir.unparse()
44
- # print(x)
45
- # print(f"Testing {code_gen_pure.ir.name}")
46
- # print(code_gen_pure.ir.pp())
47
- code_gen_jac = jac_str_to_pass(
48
- jac_str=x,
49
- file_path=filename,
50
- target=PyastGenPass,
51
- schedule=without_format,
66
+ else:
67
+ self.assertEqual(
68
+ len("\n".join(unified_diff(before.splitlines(), after.splitlines()))),
69
+ 0,
52
70
  )
53
- after = ast3.dump(code_gen_jac.ir.gen.py_ast[0], indent=2)
54
- if "circle_clean_tests.jac" in filename:
55
- self.assertEqual(
56
- len(
57
- [
58
- i
59
- for i in unified_diff(
60
- before.splitlines(), after.splitlines(), n=0
61
- )
62
- if "test" not in i
63
- ]
64
- ),
65
- 5,
66
- )
67
- else:
68
- self.assertEqual(
69
- len(
70
- "\n".join(unified_diff(before.splitlines(), after.splitlines()))
71
- ),
72
- 0,
73
- )
74
-
75
- except Exception as e:
76
- raise e
77
71
 
78
72
 
79
73
  JacUnparseTests.self_attach_micro_tests()
@@ -70,3 +70,7 @@ class Transform(ABC, Generic[T]):
70
70
  )
71
71
  self.warnings_had.append(alrt)
72
72
  self.logger.warning(str(alrt))
73
+
74
+ def log_info(self, msg: str) -> None:
75
+ """Log info."""
76
+ self.logger.info(msg)
@@ -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",
@@ -6,14 +6,24 @@ semantic information.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from typing import Optional
9
+ from typing import Optional, TYPE_CHECKING
10
+
11
+ if TYPE_CHECKING:
12
+ import jaclang.compiler.absyntree as ast
10
13
 
11
14
 
12
15
  class SemInfo:
13
16
  """Semantic information class."""
14
17
 
15
- def __init__(self, name: str, type: Optional[str] = None, semstr: str = "") -> None:
18
+ def __init__(
19
+ self,
20
+ node: ast.AstNode,
21
+ name: str,
22
+ type: Optional[str] = None,
23
+ semstr: str = "",
24
+ ) -> None:
16
25
  """Initialize the class."""
26
+ self.node = node
17
27
  self.name = name
18
28
  self.type = type
19
29
  self.semstr = semstr
@@ -22,6 +32,17 @@ class SemInfo:
22
32
  """Return the string representation of the class."""
23
33
  return f"{self.semstr} ({self.type}) ({self.name})"
24
34
 
35
+ def get_children(
36
+ self, sem_registry: SemRegistry, filter: Optional[type[ast.AstNode]] = None
37
+ ) -> list[SemInfo]:
38
+ """Get the children of the SemInfo."""
39
+ scope, _ = sem_registry.lookup(name=self.name)
40
+ self_scope = str(scope) + f".{self.name}({self.type})"
41
+ _, children = sem_registry.lookup(scope=SemScope.get_scope_from_str(self_scope))
42
+ if filter and children and isinstance(children, list):
43
+ return [i for i in children if isinstance(i.node, filter)]
44
+ return children if children and isinstance(children, list) else []
45
+
25
46
 
26
47
  class SemScope:
27
48
  """Scope class."""
@@ -38,7 +59,8 @@ class SemScope:
38
59
  """Return the string representation of the class."""
39
60
  if self.parent:
40
61
  return f"{self.parent}.{self.scope}({self.type})"
41
- return f"{self.scope}({self.type})"
62
+ else:
63
+ return f"{self.scope}({self.type})"
42
64
 
43
65
  def __repr__(self) -> str:
44
66
  """Return the string representation of the class."""
@@ -57,7 +79,7 @@ class SemScope:
57
79
 
58
80
  @property
59
81
  def as_type_str(self) -> Optional[str]:
60
- """Return the type string representation of the SemsScope."""
82
+ """Return the type string representation of the SemScope."""
61
83
  if self.type not in ["class", "node", "obj"]:
62
84
  return None
63
85
  type_str = self.scope
@@ -127,9 +149,11 @@ class SemRegistry:
127
149
  break
128
150
  return i
129
151
 
130
- def pp(self) -> None:
152
+ def pp(self) -> str:
131
153
  """Pretty print the registry."""
154
+ ret_str = ""
132
155
  for k, v in self.registry.items():
133
- print(k)
156
+ ret_str += f"{k}\n"
134
157
  for i in v:
135
- print(f" {i.name} {i.type} {i.semstr}")
158
+ ret_str += f" {i.name} {i.type} {i.semstr}\n"
159
+ return ret_str