jaclang 0.2.5__py3-none-any.whl → 0.3.0__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 (72) hide show
  1. jaclang/__init__.py +3 -3
  2. jaclang/cli/__init__.py +0 -1
  3. jaclang/cli/__jac_gen__/cli.py +4 -4
  4. jaclang/cli/__jac_gen__/cmds.py +1 -1
  5. jaclang/cli/__jac_gen__/cmds_impl.py +1 -1
  6. jaclang/core/__init__.py +5 -11
  7. jaclang/core/__jac_gen__/corelib.py +289 -0
  8. jaclang/core/__jac_gen__/corelib_impl.py +220 -0
  9. jaclang/core/corelib.jac +21 -34
  10. jaclang/core/corelib_impl.jac +317 -0
  11. jaclang/jac/__init__.py +1 -0
  12. jaclang/jac/__jac_gen__/jac_parser.py +2 -2
  13. jaclang/jac/absyntree.py +28 -8
  14. jaclang/jac/constant.py +3 -7
  15. jaclang/jac/parser.py +13 -9
  16. jaclang/jac/passes/main/__init__.py +2 -0
  17. jaclang/jac/passes/main/def_use_pass.py +3 -2
  18. jaclang/jac/passes/main/pyast_gen_pass.py +99 -34
  19. jaclang/jac/passes/main/schedules.py +6 -0
  20. jaclang/jac/passes/main/sym_tab_build_pass.py +3 -5
  21. jaclang/jac/passes/main/tests/test_jac_format_pass.py +22 -4
  22. jaclang/jac/passes/main/tests/test_type_check_pass.py +42 -0
  23. jaclang/jac/passes/main/type_check_pass.py +103 -0
  24. jaclang/jac/passes/tool/fuse_comments_pass.py +57 -39
  25. jaclang/jac/passes/tool/jac_formatter_pass.py +419 -192
  26. jaclang/jac/passes/transform.py +0 -39
  27. jaclang/jac/passes/utils/__init__.py +1 -0
  28. jaclang/jac/passes/utils/mypy_ast_build.py +302 -0
  29. jaclang/jac/plugin/__init__.py +5 -2
  30. jaclang/jac/plugin/default.py +20 -4
  31. jaclang/jac/plugin/feature.py +15 -6
  32. jaclang/jac/plugin/spec.py +34 -6
  33. jaclang/jac/tests/test_workspace.py +45 -5
  34. jaclang/jac/transpiler.py +4 -9
  35. jaclang/utils/helpers.py +0 -33
  36. jaclang/utils/lang_tools.py +3 -0
  37. jaclang/utils/test.py +3 -1
  38. jaclang/vendor/lark/py.typed +0 -0
  39. jaclang/vendor/mypy/checker.py +19 -12
  40. jaclang/vendor/mypy/checkexpr.py +31 -10
  41. jaclang/vendor/mypy/constraints.py +56 -38
  42. jaclang/vendor/mypy/expandtype.py +1 -0
  43. jaclang/vendor/mypy/meet.py +10 -1
  44. jaclang/vendor/mypy/messages.py +16 -4
  45. jaclang/vendor/mypy/moduleinspect.py +10 -4
  46. jaclang/vendor/mypy/py.typed +1 -0
  47. jaclang/vendor/mypy/semanal.py +18 -17
  48. jaclang/vendor/mypy/semanal_enum.py +7 -4
  49. jaclang/vendor/mypy/semanal_namedtuple.py +11 -1
  50. jaclang/vendor/mypy/semanal_typeddict.py +25 -11
  51. jaclang/vendor/mypy/stubdoc.py +18 -4
  52. jaclang/vendor/mypy/stubgen.py +80 -1
  53. jaclang/vendor/mypy/stubgenc.py +47 -5
  54. jaclang/vendor/mypy/stubtest.py +53 -3
  55. jaclang/vendor/mypy/stubutil.py +9 -9
  56. jaclang/vendor/mypy/test/testipc.py +16 -7
  57. jaclang/vendor/mypy/test/teststubtest.py +20 -2
  58. jaclang/vendor/mypy/types.py +1 -1
  59. jaclang/vendor/mypyc/irbuild/prebuildvisitor.py +2 -1
  60. jaclang/vendor/mypyc/test/test_run.py +2 -4
  61. jaclang/vendor/pluggy/py.typed +0 -0
  62. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/METADATA +1 -1
  63. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/RECORD +67 -62
  64. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/WHEEL +1 -1
  65. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/entry_points.txt +3 -0
  66. jaclang/core/arch_impl.jac +0 -131
  67. jaclang/core/element_impl.jac +0 -109
  68. jaclang/core/exec_ctx_impl.jac +0 -14
  69. jaclang/core/memory_impl.jac +0 -57
  70. jaclang/jac/tests/fixtures/__jac_gen__/hello_world.py +0 -5
  71. /jaclang/{jac/tests/fixtures → core}/__jac_gen__/__init__.py +0 -0
  72. {jaclang-0.2.5.dist-info → jaclang-0.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,42 @@
1
+ """Test pass module."""
2
+ from typing import List
3
+
4
+ from jaclang.jac.passes.main import JacTypeCheckPass
5
+ from jaclang.jac.passes.main.schedules import py_code_gen_typed
6
+ from jaclang.jac.transpiler import jac_file_to_pass
7
+ from jaclang.utils.test import TestCase
8
+
9
+
10
+ class MypyTypeCheckPassTests(TestCase):
11
+ """Test pass module."""
12
+
13
+ def setUp(self) -> None:
14
+ """Set up test."""
15
+ self.__messages: List[str] = []
16
+ return super().setUp()
17
+
18
+ def __message_cb(
19
+ self, filename: str | None, new_messages: list[str], is_serious: bool
20
+ ) -> None:
21
+ for message in new_messages:
22
+ self.__messages.append(
23
+ message.replace(self.fixture_abs_path("func.jac"), "")
24
+ )
25
+
26
+ def test_type_errors(self) -> None:
27
+ """Basic test for pass."""
28
+ JacTypeCheckPass.message_cb = self.__message_cb
29
+
30
+ jac_file_to_pass(
31
+ file_path=self.fixture_abs_path("func.jac"),
32
+ schedule=py_code_gen_typed,
33
+ )
34
+
35
+ errs = "\n".join(self.__messages)
36
+ for i in [
37
+ "File::4",
38
+ "File::12",
39
+ '(got "int", expected "str")',
40
+ '(got "str", expected "int")',
41
+ ]:
42
+ self.assertIn(i, errs)
@@ -0,0 +1,103 @@
1
+ """Integrate mypy infrastructure into Jac.
2
+
3
+ This is used to call mypy type checking into Jac files by integrating
4
+ mypy apis into Jac and use jac py ast in it.
5
+ """
6
+ import os
7
+ import pathlib
8
+ import sys
9
+ from typing import Callable, List, Optional
10
+
11
+
12
+ import jaclang.jac.absyntree as ast
13
+ import jaclang.jac.passes.utils.mypy_ast_build as myab
14
+ from jaclang.jac.passes import Pass
15
+
16
+
17
+ class JacTypeCheckPass(Pass):
18
+ """Python and bytecode file printing pass."""
19
+
20
+ message_cb: Optional[Callable[[str | None, List[str], bool], None]] = None
21
+
22
+ def before_pass(self) -> None:
23
+ """Before pass."""
24
+ self.__path = (
25
+ pathlib.Path(os.path.dirname(__file__)).parent.parent.parent
26
+ / "vendor"
27
+ / "mypy"
28
+ )
29
+ return super().before_pass()
30
+
31
+ def enter_module(self, node: ast.Module) -> None:
32
+ """Call mypy checks on module level only."""
33
+ self.api(node, node.loc.mod_path)
34
+ self.terminate()
35
+
36
+ def default_message_cb(
37
+ self, filename: str | None, new_messages: list[str], is_serious: bool
38
+ ) -> None:
39
+ """Mypy errors reporter."""
40
+ for msg in new_messages:
41
+ self.warning(msg)
42
+
43
+ def api(self, node: ast.Module, mod_path: str) -> None:
44
+ """Call mypy APIs to implement type checking in Jac."""
45
+ # Creating mypy api obbjects
46
+ options = myab.Options()
47
+ errors = myab.Errors(options)
48
+ fs_cache = myab.FileSystemCache()
49
+ search_paths = myab.compute_search_paths([], options, str(self.__path))
50
+ plugin, snapshot = myab.load_plugins(options, errors, sys.stdout, [])
51
+
52
+ if self.message_cb is not None:
53
+ message_cb = self.message_cb
54
+ else:
55
+ message_cb = self.default_message_cb
56
+
57
+ manager = myab.BuildManager(
58
+ data_dir=".",
59
+ search_paths=search_paths,
60
+ ignore_prefix=os.getcwd(),
61
+ source_set=myab.BuildSourceSet([]),
62
+ reports=None,
63
+ options=options,
64
+ version_id="1.8.0+dev",
65
+ plugin=plugin,
66
+ plugins_snapshot=snapshot,
67
+ errors=errors,
68
+ flush_errors=message_cb,
69
+ fscache=fs_cache,
70
+ stdout=sys.stdout,
71
+ stderr=sys.stderr,
72
+ )
73
+
74
+ tree = myab.ASTConverter(
75
+ options=options,
76
+ is_stub=False,
77
+ errors=errors,
78
+ ignore_errors=False,
79
+ strip_function_bodies=False,
80
+ ).visit(node.gen.py_ast)
81
+
82
+ st = myab.State(
83
+ id="Jac Module",
84
+ path="File:" + mod_path,
85
+ source="",
86
+ manager=manager,
87
+ root_source=False,
88
+ ast_override=tree,
89
+ )
90
+
91
+ graph = myab.load_graph(
92
+ [
93
+ myab.BuildSource(
94
+ path=str(self.__path / "typeshed" / "stdlib" / "builtins.pyi"),
95
+ module="builtins",
96
+ )
97
+ ],
98
+ manager,
99
+ old_graph={"JacTree": st},
100
+ )
101
+ myab.process_graph(graph, manager)
102
+
103
+ myab.semantic_analysis_for_scc(graph, ["JacTree"], errors)
@@ -13,7 +13,7 @@ class FuseCommentsPass(Pass):
13
13
  def before_pass(self) -> None:
14
14
  """Before pass."""
15
15
  self.all_tokens: list[ast.Token] = []
16
- self.comments: list[ast.Token] = (
16
+ self.comments: list[ast.CommentToken] = (
17
17
  self.ir.source.comments if isinstance(self.ir, ast.Module) else []
18
18
  )
19
19
  return super().before_pass()
@@ -25,44 +25,62 @@ class FuseCommentsPass(Pass):
25
25
 
26
26
  def after_pass(self) -> None:
27
27
  """Insert comment tokens into all_tokens."""
28
- chomp: list[ast.CommentToken] = [*self.comments]
29
- new_tokens: list[ast.Token] = []
30
- if not len(chomp):
31
- return
32
- for i in range(len(self.all_tokens)):
33
- chomp[0].is_inline = chomp[0].is_inline or (
34
- self.all_tokens[i].loc.first_line == chomp[0].loc.first_line
35
- )
36
- if i == len(self.all_tokens) - 1:
37
- if len(chomp):
38
- new_tokens.append(self.all_tokens[i])
39
- new_tokens += chomp
40
- break
41
- while (i < len(self.all_tokens) - 1) and (
42
- (
43
- self.all_tokens[i].loc.first_line == chomp[0].loc.first_line
44
- and self.all_tokens[i].loc.col_start > chomp[0].loc.col_start
45
- )
46
- or (self.all_tokens[i].loc.first_line > chomp[0].loc.first_line)
28
+ comment_stream = iter(self.comments) # Iterator for comments
29
+ code_stream = iter(self.all_tokens) # Iterator for code tokens
30
+ new_stream = [] # New stream to hold ordered tokens
31
+
32
+ try:
33
+ next_comment = next(comment_stream) # Get the first comment
34
+ except StopIteration:
35
+ next_comment = None
36
+
37
+ try:
38
+ next_code = next(code_stream) # Get the first code token
39
+ except StopIteration:
40
+ next_code = None
41
+
42
+ while next_comment or next_code:
43
+ if next_comment and (
44
+ not next_code or is_comment_next(next_comment, next_code)
47
45
  ):
48
- new_tokens.append(chomp[0])
49
- chomp = chomp[1:]
50
- if not len(chomp):
51
- new_tokens.extend(self.all_tokens[i + 1 :])
52
- break
53
- new_tokens.append(self.all_tokens[i])
54
- if not len(chomp):
55
- break
56
- for i in range(len(new_tokens)):
57
- if isinstance(new_tokens[i], ast.CommentToken):
46
+ # Add the comment to the new stream
47
+ new_stream.append(next_comment)
48
+ try:
49
+ next_comment = next(comment_stream)
50
+ except StopIteration:
51
+ next_comment = None
52
+ elif next_code:
53
+ # Add the code token to the new stream
54
+ new_stream.append(next_code)
55
+ try:
56
+ next_code = next(code_stream)
57
+ except StopIteration:
58
+ next_code = None
59
+
60
+ # Insert the tokens back into the AST
61
+ for i, token in enumerate(new_stream):
62
+ if isinstance(token, ast.CommentToken):
58
63
  if i == 0:
59
- self.ir.add_kids_left([new_tokens[i]])
60
- continue
61
- new_val = new_tokens[i - 1]
62
- if new_val.parent is not None:
63
- new_kids = new_val.parent.kid
64
- new_kids.insert(new_kids.index(new_val) + 1, new_tokens[i])
65
- new_val.parent.set_kids(new_kids)
64
+ self.ir.add_kids_left([token])
66
65
  else:
67
- new_val.pp()
68
- raise self.ice("Token without parent in AST should be impossible")
66
+ prev_token = new_stream[i - 1]
67
+ if prev_token.parent is not None:
68
+ parent_kids = prev_token.parent.kid
69
+ insert_index = parent_kids.index(prev_token) + 1
70
+ parent_kids.insert(insert_index, token)
71
+ prev_token.parent.set_kids(parent_kids)
72
+ else:
73
+ prev_token.pp()
74
+ raise self.ice(
75
+ "Token without parent in AST should be impossible"
76
+ )
77
+
78
+
79
+ def is_comment_next(cmt: ast.CommentToken, code: ast.Token) -> bool:
80
+ """Compare two CodeLocInfo objects."""
81
+ if cmt.loc.first_line < code.loc.first_line:
82
+ return True
83
+ elif cmt.loc.first_line == code.loc.first_line:
84
+ cmt.is_inline = True
85
+ return cmt.loc.col_start < code.loc.col_start
86
+ return False