jaclang 0.7.23__py3-none-any.whl → 0.7.25__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 (50) hide show
  1. jaclang/cli/cli.py +46 -29
  2. jaclang/compiler/__init__.py +2 -2
  3. jaclang/compiler/absyntree.py +87 -48
  4. jaclang/compiler/codeloc.py +7 -2
  5. jaclang/compiler/compile.py +10 -3
  6. jaclang/compiler/parser.py +26 -23
  7. jaclang/compiler/passes/ir_pass.py +2 -2
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +46 -0
  9. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  10. jaclang/compiler/passes/main/import_pass.py +6 -2
  11. jaclang/compiler/passes/main/pyast_load_pass.py +36 -35
  12. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  13. jaclang/compiler/passes/main/registry_pass.py +3 -12
  14. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  15. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  16. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +59 -0
  17. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  18. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  19. jaclang/compiler/passes/transform.py +27 -3
  20. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  21. jaclang/compiler/symtable.py +6 -0
  22. jaclang/compiler/tests/test_importer.py +2 -2
  23. jaclang/langserve/engine.py +14 -12
  24. jaclang/langserve/server.py +7 -2
  25. jaclang/langserve/tests/test_server.py +1 -1
  26. jaclang/langserve/utils.py +17 -3
  27. jaclang/plugin/default.py +32 -32
  28. jaclang/plugin/feature.py +2 -2
  29. jaclang/plugin/plugin.md +471 -0
  30. jaclang/plugin/spec.py +2 -1
  31. jaclang/runtimelib/context.py +2 -0
  32. jaclang/runtimelib/importer.py +7 -2
  33. jaclang/runtimelib/machine.py +21 -6
  34. jaclang/settings.py +3 -0
  35. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  36. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  37. jaclang/tests/fixtures/expr_type.jac +54 -0
  38. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  39. jaclang/tests/fixtures/registry.jac +20 -8
  40. jaclang/tests/foo/__init__.jac +0 -0
  41. jaclang/tests/main.jac +2 -0
  42. jaclang/tests/test_cli.py +68 -4
  43. jaclang/tests/test_language.py +60 -27
  44. jaclang/utils/helpers.py +92 -14
  45. jaclang/utils/lang_tools.py +6 -2
  46. jaclang/utils/treeprinter.py +4 -2
  47. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/METADATA +2 -1
  48. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/RECORD +50 -44
  49. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/WHEEL +1 -1
  50. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/entry_points.txt +0 -0
@@ -22,6 +22,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
22
22
  def __init__(self, input_ir: ast.PythonModuleAst) -> None:
23
23
  """Initialize parser."""
24
24
  self.mod_path = input_ir.loc.mod_path
25
+ self.orig_src = input_ir.loc.orig_src
25
26
  Pass.__init__(self, input_ir=input_ir, prior=None)
26
27
 
27
28
  def nu(self, node: T) -> T:
@@ -151,7 +152,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
151
152
 
152
153
  value = node.name if node.name not in reserved_keywords else f"<>{node.name}"
153
154
  name = ast.Name(
154
- file_path=self.mod_path,
155
+ orig_src=self.orig_src,
155
156
  name=Tok.NAME,
156
157
  value=value,
157
158
  line=node.lineno,
@@ -264,7 +265,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
264
265
  type_params: list[type_param]
265
266
  """
266
267
  name = ast.Name(
267
- file_path=self.mod_path,
268
+ orig_src=self.orig_src,
268
269
  name=Tok.NAME,
269
270
  value=node.name,
270
271
  line=node.lineno,
@@ -275,7 +276,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
275
276
  pos_end=0,
276
277
  )
277
278
  arch_type = ast.Token(
278
- file_path=self.mod_path,
279
+ orig_src=self.orig_src,
279
280
  name=Tok.KW_CLASS,
280
281
  value="class",
281
282
  line=node.lineno,
@@ -293,7 +294,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
293
294
  and body_stmt.name_ref.value == "__init__"
294
295
  ):
295
296
  tok = ast.Name(
296
- file_path=self.mod_path,
297
+ orig_src=self.orig_src,
297
298
  name=Tok.KW_INIT,
298
299
  value="init",
299
300
  line=node.lineno,
@@ -383,7 +384,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
383
384
  ):
384
385
  continue
385
386
  pintok = ast.Token(
386
- file_path=self.mod_path,
387
+ orig_src=self.orig_src,
387
388
  name=Tok.PYNLINE,
388
389
  value=py_ast.unparse(class_body_stmt),
389
390
  line=node.lineno,
@@ -914,7 +915,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
914
915
  and value.target.value == "super"
915
916
  ):
916
917
  tok = ast.Name(
917
- file_path=self.mod_path,
918
+ orig_src=self.orig_src,
918
919
  name=Tok.KW_SUPER,
919
920
  value="super",
920
921
  line=node.lineno,
@@ -927,7 +928,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
927
928
  value = ast.SpecialVarRef(var=tok)
928
929
  # exit()
929
930
  attribute = ast.Name(
930
- file_path=self.mod_path,
931
+ orig_src=self.orig_src,
931
932
  name=Tok.NAME,
932
933
  value=(
933
934
  ("<>" + node.attr)
@@ -1038,7 +1039,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1038
1039
  def proc_break(self, node: py_ast.Break) -> ast.CtrlStmt:
1039
1040
  """Process python node."""
1040
1041
  break_tok = ast.Token(
1041
- file_path=self.mod_path,
1042
+ orig_src=self.orig_src,
1042
1043
  name=Tok.KW_BREAK,
1043
1044
  value="break",
1044
1045
  line=0,
@@ -1155,7 +1156,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1155
1156
  else:
1156
1157
  value = str(node.value)
1157
1158
  return type_mapping[value_type](
1158
- file_path=self.mod_path,
1159
+ orig_src=self.orig_src,
1159
1160
  name=token_type,
1160
1161
  value=value,
1161
1162
  line=node.lineno,
@@ -1167,7 +1168,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1167
1168
  )
1168
1169
  elif node.value == Ellipsis:
1169
1170
  return ast.Ellipsis(
1170
- file_path=self.mod_path,
1171
+ orig_src=self.orig_src,
1171
1172
  name=Tok.ELLIPSIS,
1172
1173
  value="...",
1173
1174
  line=node.lineno,
@@ -1183,7 +1184,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1183
1184
  def proc_continue(self, node: py_ast.Continue) -> ast.CtrlStmt:
1184
1185
  """Process python node."""
1185
1186
  continue_tok = ast.Token(
1186
- file_path=self.mod_path,
1187
+ orig_src=self.orig_src,
1187
1188
  name=Tok.KW_CONTINUE,
1188
1189
  value="continue",
1189
1190
  line=0,
@@ -1260,7 +1261,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1260
1261
  name: ast.Name | None = None
1261
1262
  if not type and not node.name:
1262
1263
  type = ast.Name(
1263
- file_path=self.mod_path,
1264
+ orig_src=self.orig_src,
1264
1265
  name=Tok.NAME,
1265
1266
  value="Exception",
1266
1267
  line=node.lineno,
@@ -1271,7 +1272,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1271
1272
  pos_end=0,
1272
1273
  )
1273
1274
  name = ast.Name(
1274
- file_path=self.mod_path,
1275
+ orig_src=self.orig_src,
1275
1276
  name=Tok.NAME,
1276
1277
  value="e",
1277
1278
  line=node.lineno,
@@ -1283,7 +1284,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1283
1284
  )
1284
1285
  else:
1285
1286
  # type = ast.Name(
1286
- # file_path=self.mod_path,
1287
+ # orig_src=self.orig_src,
1287
1288
  # name=Tok.NAME,
1288
1289
  # value=no,
1289
1290
  # line=node.lineno,
@@ -1295,7 +1296,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1295
1296
  # )
1296
1297
  name = (
1297
1298
  ast.Name(
1298
- file_path=self.mod_path,
1299
+ orig_src=self.orig_src,
1299
1300
  name=Tok.NAME,
1300
1301
  value=node.name,
1301
1302
  line=node.lineno,
@@ -1395,7 +1396,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1395
1396
  for id in node.names:
1396
1397
  names.append(
1397
1398
  ast.Name(
1398
- file_path=self.mod_path,
1399
+ orig_src=self.orig_src,
1399
1400
  name=Tok.NAME,
1400
1401
  value=id,
1401
1402
  line=node.lineno,
@@ -1458,7 +1459,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1458
1459
  else:
1459
1460
  raise self.ice()
1460
1461
  lang = ast.Name(
1461
- file_path=self.mod_path,
1462
+ orig_src=self.orig_src,
1462
1463
  name=Tok.NAME,
1463
1464
  value="py",
1464
1465
  line=node.lineno,
@@ -1488,7 +1489,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1488
1489
  level: int
1489
1490
  """
1490
1491
  lang = ast.Name(
1491
- file_path=self.mod_path,
1492
+ orig_src=self.orig_src,
1492
1493
  name=Tok.NAME,
1493
1494
  value="py",
1494
1495
  line=node.lineno,
@@ -1503,7 +1504,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1503
1504
  for i in node.module.split("."):
1504
1505
  modpaths.append(
1505
1506
  ast.Name(
1506
- file_path=self.mod_path,
1507
+ orig_src=self.orig_src,
1507
1508
  name=Tok.NAME,
1508
1509
  value=i,
1509
1510
  line=node.lineno,
@@ -1667,7 +1668,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1667
1668
  """
1668
1669
  pattern = self.convert(node.pattern) if node.pattern else None
1669
1670
  name = ast.Name(
1670
- file_path=self.mod_path,
1671
+ orig_src=self.orig_src,
1671
1672
  name=Tok.NAME,
1672
1673
  value=node.name if node.name else "_",
1673
1674
  line=node.lineno,
@@ -1721,7 +1722,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1721
1722
  for kwd_attrs in node.kwd_attrs:
1722
1723
  names.append(
1723
1724
  ast.Name(
1724
- file_path=self.mod_path,
1725
+ orig_src=self.orig_src,
1725
1726
  name=Tok.NAME,
1726
1727
  value=kwd_attrs,
1727
1728
  line=node.lineno,
@@ -1781,7 +1782,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1781
1782
  values.append(kv_pair)
1782
1783
  if node.rest:
1783
1784
  name = ast.Name(
1784
- file_path=self.mod_path,
1785
+ orig_src=self.orig_src,
1785
1786
  name=Tok.NAME,
1786
1787
  value=node.rest,
1787
1788
  line=node.lineno,
@@ -1826,7 +1827,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1826
1827
  type = Tok.NULL if node.value is None else Tok.BOOL
1827
1828
  ret_type = ast.Null if node.value is None else ast.Bool
1828
1829
  value = ret_type(
1829
- file_path=self.mod_path,
1830
+ orig_src=self.orig_src,
1830
1831
  name=type,
1831
1832
  value=str(node.value),
1832
1833
  line=node.lineno,
@@ -1848,7 +1849,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1848
1849
  name: _Identifier | None
1849
1850
  """
1850
1851
  name = ast.Name(
1851
- file_path=self.mod_path,
1852
+ orig_src=self.orig_src,
1852
1853
  name=Tok.NAME,
1853
1854
  value=node.name if node.name else "_",
1854
1855
  line=node.lineno,
@@ -1891,7 +1892,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1891
1892
 
1892
1893
  value = node.id if node.id not in reserved_keywords else f"<>{node.id}"
1893
1894
  ret = ast.Name(
1894
- file_path=self.mod_path,
1895
+ orig_src=self.orig_src,
1895
1896
  name=Tok.NAME,
1896
1897
  value=value,
1897
1898
  line=node.lineno,
@@ -1937,7 +1938,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1937
1938
  value = name if name not in reserved_keywords else f"<>{name}"
1938
1939
  names.append(
1939
1940
  ast.Name(
1940
- file_path=self.mod_path,
1941
+ orig_src=self.orig_src,
1941
1942
  name=Tok.NAME,
1942
1943
  value=value,
1943
1944
  line=node.lineno,
@@ -1954,7 +1955,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
1954
1955
  def proc_pass(self, node: py_ast.Pass) -> ast.Semi:
1955
1956
  """Process python node."""
1956
1957
  return ast.Semi(
1957
- file_path=self.mod_path,
1958
+ orig_src=self.orig_src,
1958
1959
  name=Tok.SEMI,
1959
1960
  value=";",
1960
1961
  line=0,
@@ -2222,7 +2223,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2222
2223
  asname: _Identifier | None
2223
2224
  """
2224
2225
  name = ast.Name(
2225
- file_path=self.mod_path,
2226
+ orig_src=self.orig_src,
2226
2227
  name=Tok.NAME,
2227
2228
  value=node.name,
2228
2229
  line=node.lineno,
@@ -2234,7 +2235,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2234
2235
  )
2235
2236
  asname = (
2236
2237
  ast.Name(
2237
- file_path=self.mod_path,
2238
+ orig_src=self.orig_src,
2238
2239
  name=Tok.NAME,
2239
2240
  value=node.asname,
2240
2241
  line=node.lineno,
@@ -2268,7 +2269,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2268
2269
 
2269
2270
  value = node.arg if node.arg not in reserved_keywords else f"<>{node.arg}"
2270
2271
  name = ast.Name(
2271
- file_path=self.mod_path,
2272
+ orig_src=self.orig_src,
2272
2273
  name=Tok.NAME,
2273
2274
  value=value,
2274
2275
  line=node.lineno,
@@ -2282,7 +2283,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2282
2283
  self.convert(node.annotation)
2283
2284
  if node.annotation
2284
2285
  else ast.Name(
2285
- file_path=self.mod_path,
2286
+ orig_src=self.orig_src,
2286
2287
  name=Tok.NAME,
2287
2288
  value="Any",
2288
2289
  line=node.lineno,
@@ -2316,7 +2317,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2316
2317
  vararg = self.convert(node.vararg) if node.vararg else None
2317
2318
  if vararg and isinstance(vararg, ast.ParamVar):
2318
2319
  vararg.unpack = ast.Token(
2319
- file_path=self.mod_path,
2320
+ orig_src=self.orig_src,
2320
2321
  name=Tok.STAR_MUL,
2321
2322
  value="*",
2322
2323
  line=vararg.loc.first_line,
@@ -2342,7 +2343,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2342
2343
  kwarg = self.convert(node.kwarg) if node.kwarg else None
2343
2344
  if kwarg and isinstance(kwarg, ast.ParamVar):
2344
2345
  kwarg.unpack = ast.Token(
2345
- file_path=self.mod_path,
2346
+ orig_src=self.orig_src,
2346
2347
  name=Tok.STAR_POW,
2347
2348
  value="**",
2348
2349
  line=kwarg.loc.first_line,
@@ -2388,7 +2389,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2388
2389
  def operator(self, tok: Tok, value: str) -> ast.Token:
2389
2390
  """Create an operator token."""
2390
2391
  return ast.Token(
2391
- file_path=self.mod_path,
2392
+ orig_src=self.orig_src,
2392
2393
  name=tok,
2393
2394
  value=value,
2394
2395
  line=0,
@@ -2553,7 +2554,7 @@ class PyastBuildPass(Pass[ast.PythonModuleAst]):
2553
2554
  value: expr
2554
2555
  """
2555
2556
  arg = ast.Name(
2556
- file_path=self.mod_path,
2557
+ orig_src=self.orig_src,
2557
2558
  name=Tok.NAME,
2558
2559
  value=node.arg if node.arg else "_",
2559
2560
  line=node.lineno,
@@ -134,14 +134,14 @@ class PyJacAstLinkPass(Pass):
134
134
  py_nodes=i.name_spec.name_of.sym.decl.gen.py_ast,
135
135
  )
136
136
 
137
- if isinstance(node.parent, ast.Ability) and node.parent.signature:
137
+ if isinstance(node.decl_link, ast.Ability) and node.decl_link.signature:
138
138
  if isinstance(node.signature, ast.FuncSignature) and node.signature.params:
139
139
  for src_prm in node.signature.params.items:
140
140
  if (
141
- isinstance(node.parent.signature, ast.FuncSignature)
142
- and node.parent.signature.params
141
+ isinstance(node.decl_link.signature, ast.FuncSignature)
142
+ and node.decl_link.signature.params
143
143
  ):
144
- for trg_prm in node.parent.signature.params.items:
144
+ for trg_prm in node.decl_link.signature.params.items:
145
145
  if src_prm.name.sym_name == trg_prm.name.sym_name:
146
146
  self.link_jac_py_nodes(
147
147
  jac_node=src_prm, py_nodes=trg_prm.gen.py_ast
@@ -154,12 +154,12 @@ class PyJacAstLinkPass(Pass):
154
154
  isinstance(node.signature, ast.FuncSignature)
155
155
  and node.signature.return_type
156
156
  ) and (
157
- isinstance(node.parent.signature, ast.FuncSignature)
158
- and node.parent.signature.return_type
157
+ isinstance(node.decl_link.signature, ast.FuncSignature)
158
+ and node.decl_link.signature.return_type
159
159
  ):
160
160
  self.link_jac_py_nodes(
161
161
  jac_node=node.signature.return_type,
162
- py_nodes=node.parent.signature.return_type.gen.py_ast,
162
+ py_nodes=node.decl_link.signature.return_type.gen.py_ast,
163
163
  )
164
164
 
165
165
  if isinstance(node.decl_link, ast.Ability) and isinstance(
@@ -6,11 +6,7 @@ semstrings after PyASTGen pass. So we create those as a pickled file for
6
6
  each module
7
7
  """
8
8
 
9
- import os
10
- import pickle
11
-
12
9
  import jaclang.compiler.absyntree as ast
13
- from jaclang.compiler.constant import Constants as Con
14
10
  from jaclang.compiler.passes import Pass
15
11
  from jaclang.compiler.semtable import SemInfo, SemRegistry
16
12
  from jaclang.runtimelib.utils import get_sem_scope
@@ -33,15 +29,10 @@ class RegistryPass(Pass):
33
29
  def exit_module(self, node: ast.Module) -> None:
34
30
  """Save registry for each module."""
35
31
  module_name = node.name
36
- module_dir = os.path.join(
37
- os.path.abspath(os.path.dirname(node.source.file_path)), Con.JAC_GEN_DIR
38
- )
39
32
  try:
40
- os.makedirs(module_dir, exist_ok=True)
41
- with open(
42
- os.path.join(module_dir, f"{module_name}.registry.pkl"), "wb"
43
- ) as f:
44
- pickle.dump(node.registry, f)
33
+ from jaclang.runtimelib.machine import JacMachine
34
+
35
+ JacMachine.get().get_sem_ir(node.registry)
45
36
  except Exception as e:
46
37
  self.warning(f"Can't save registry for {module_name}: {e}")
47
38
  self.modules_visited.pop()
@@ -0,0 +1,19 @@
1
+
2
+
3
+ obj SomeObj {
4
+ can foo(param1: str, param2:int) -> str;
5
+ can bar(param1: str, param2:int) -> str;
6
+ }
7
+
8
+
9
+ # Miss match parameter count.
10
+ :obj:SomeObj:can:foo(param1: str) -> str {
11
+ return "foo";
12
+ }
13
+
14
+
15
+ # Mis matching parameter name.
16
+ :obj:SomeObj:can:bar(param1: str, praam2:int) -> str {
17
+ return "bar";
18
+ }
19
+
@@ -42,6 +42,8 @@ with entry {
42
42
  len(f_s1), len(f_s2)
43
43
  ) ;
44
44
  """sdfsdf\nsdfsdfsdfsd dffgdfgd.""" ;
45
+ c1 = '''hello klkl"""''';
46
+ print(c1) ;
45
47
  }
46
48
  can func() {;
47
49
  }
@@ -13,6 +13,65 @@ class DeclImplMatchPassTests(TestCase):
13
13
  """Set up test."""
14
14
  return super().setUp()
15
15
 
16
+ def test_parameter_count_mismatch(self) -> None:
17
+ """Basic test for pass."""
18
+ state = jac_file_to_pass(
19
+ self.fixture_abs_path("defn_decl_mismatch.jac"), DeclImplMatchPass
20
+ )
21
+
22
+ expected_stdout_values = (
23
+ "Parameter count mismatch for ability (o)SomeObj.(c)foo.",
24
+ " 8 |",
25
+ " 9 | # Miss match parameter count.",
26
+ " 10 | :obj:SomeObj:can:foo(param1: str) -> str {",
27
+ " | ^^^^^^^^^^^^^^^^^^^^",
28
+ ' 11 | return "foo";',
29
+ " 12 | }",
30
+ "From the declaration of foo.",
31
+ " 2 |",
32
+ " 3 | obj SomeObj {",
33
+ " 4 | can foo(param1: str, param2:int) -> str;",
34
+ " | ^^^",
35
+ " 5 | can bar(param1: str, param2:int) -> str;",
36
+ " 6 | }",
37
+ )
38
+
39
+ errors_output = ""
40
+ for error in state.errors_had:
41
+ errors_output += error.pretty_print() + "\n"
42
+
43
+ for exp in expected_stdout_values:
44
+ self.assertIn(exp, errors_output)
45
+
46
+ def test_parameter_name_mismatch(self) -> None:
47
+ """Basic test for pass."""
48
+ state = jac_file_to_pass(
49
+ self.fixture_abs_path("defn_decl_mismatch.jac"), DeclImplMatchPass
50
+ )
51
+
52
+ expected_stdout_values = (
53
+ "Parameter name mismatch for ability (o)SomeObj.(c)bar.",
54
+ " 14 |",
55
+ " 15 | # Mis matching parameter name.",
56
+ " 16 | :obj:SomeObj:can:bar(param1: str, praam2:int) -> str {",
57
+ " | ^^^^^^",
58
+ ' 17 | return "bar";',
59
+ " 18 | }",
60
+ "From the declaration of bar.",
61
+ " 3 | obj SomeObj {",
62
+ " 4 | can foo(param1: str, param2:int) -> str;",
63
+ " 5 | can bar(param1: str, param2:int) -> str;",
64
+ " | ^^^^^^",
65
+ " 6 | }",
66
+ )
67
+
68
+ errors_output = ""
69
+ for error in state.errors_had:
70
+ errors_output += error.pretty_print() + "\n"
71
+
72
+ for exp in expected_stdout_values:
73
+ self.assertIn(exp, errors_output)
74
+
16
75
  def test_ability_connected_to_decl(self) -> None:
17
76
  """Basic test for pass."""
18
77
  state = jac_file_to_pass(self.fixture_abs_path("base.jac"), DeclImplMatchPass)
@@ -10,6 +10,7 @@ from jaclang.utils.test import TestCase
10
10
  class RegistryPassTests(TestCase):
11
11
  """Test pass module."""
12
12
 
13
+ # Need change
13
14
  def setUp(self) -> None:
14
15
  """Set up test."""
15
16
  return super().setUp()
@@ -18,7 +19,7 @@ class RegistryPassTests(TestCase):
18
19
  """Basic test for pass."""
19
20
  state = jac_file_to_pass(self.fixture_abs_path("registry.jac"), RegistryPass)
20
21
  self.assertFalse(state.errors_had)
21
- self.assertTrue(
22
+ self.assertFalse(
22
23
  os.path.exists(
23
24
  os.path.join(
24
25
  os.path.dirname(self.fixture_abs_path("registry.jac")),
@@ -27,13 +28,4 @@ class RegistryPassTests(TestCase):
27
28
  )
28
29
  )
29
30
  )
30
- self.assertTrue(
31
- os.path.exists(
32
- os.path.join(
33
- os.path.dirname(self.fixture_abs_path("registry.jac")),
34
- "__jac_gen__",
35
- "fstrings.registry.pkl",
36
- )
37
- )
38
- )
39
31
  self.assertIn("109", str(state.ir.to_dict()))
@@ -59,6 +59,6 @@ class MypyTypeCheckPassTests(TestCase):
59
59
  self.assertIn("HasVar - species - Type: builtins.str", out)
60
60
  self.assertIn("myDog - Type: type_info.Dog", out)
61
61
  self.assertIn("Body - Type: type_info.Dog.Body", out)
62
- self.assertEqual(out.count("Type: builtins.str"), 34)
62
+ self.assertEqual(out.count("Type: builtins.str"), 35)
63
63
  for i in lis:
64
64
  self.assertNotIn(i, out)
@@ -7,6 +7,7 @@ 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
10
+ from jaclang.utils.helpers import pretty_print_source_location
10
11
  from jaclang.utils.log import logging
11
12
 
12
13
 
@@ -28,7 +29,30 @@ class Alert:
28
29
 
29
30
  def __repr__(self) -> str:
30
31
  """Return string representation of alert."""
31
- return self.__str__()
32
+ return self.as_log()
33
+
34
+ def as_log(self) -> str:
35
+ """Return the alert as a single line log as opposed to the pretty print."""
36
+ file_path: str = self.loc.mod_path
37
+ if file_path == "":
38
+ return self.msg # There are error messages without file references.
39
+
40
+ line: int = self.loc.first_line
41
+ column: int = self.loc.col_start
42
+ return f"{file_path}:{line}:{column} {self.msg}"
43
+
44
+ def pretty_print(self) -> str:
45
+ """Pretty pritns the Alert to show the alert with source location."""
46
+ pretty_dump = pretty_print_source_location(
47
+ self.loc.mod_path,
48
+ self.loc.orig_src.code,
49
+ self.loc.first_line,
50
+ self.loc.pos_start,
51
+ self.loc.pos_end,
52
+ )
53
+ if pretty_dump != "":
54
+ pretty_dump = "\n" + pretty_dump
55
+ return self.as_log() + pretty_dump
32
56
 
33
57
 
34
58
  class Transform(ABC, Generic[T]):
@@ -59,7 +83,7 @@ class Transform(ABC, Generic[T]):
59
83
  self.__class__,
60
84
  )
61
85
  self.errors_had.append(alrt)
62
- self.logger.error(str(alrt))
86
+ self.logger.error(alrt.as_log())
63
87
 
64
88
  def log_warning(self, msg: str, node_override: Optional[AstNode] = None) -> None:
65
89
  """Pass Error."""
@@ -69,7 +93,7 @@ class Transform(ABC, Generic[T]):
69
93
  self.__class__,
70
94
  )
71
95
  self.warnings_had.append(alrt)
72
- self.logger.warning(str(alrt))
96
+ self.logger.warning(alrt.as_log())
73
97
 
74
98
  def log_info(self, msg: str) -> None:
75
99
  """Log info."""