jaclang 0.8.7__py3-none-any.whl → 0.8.9__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 (99) hide show
  1. jaclang/cli/cli.py +77 -29
  2. jaclang/cli/cmdreg.py +44 -0
  3. jaclang/compiler/constant.py +6 -2
  4. jaclang/compiler/jac.lark +37 -47
  5. jaclang/compiler/larkparse/jac_parser.py +2 -2
  6. jaclang/compiler/parser.py +356 -61
  7. jaclang/compiler/passes/main/__init__.py +2 -4
  8. jaclang/compiler/passes/main/def_use_pass.py +1 -4
  9. jaclang/compiler/passes/main/predynamo_pass.py +221 -0
  10. jaclang/compiler/passes/main/pyast_gen_pass.py +221 -135
  11. jaclang/compiler/passes/main/pyast_load_pass.py +54 -20
  12. jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -1
  13. jaclang/compiler/passes/main/tests/fixtures/checker/import_sym.jac +2 -0
  14. jaclang/compiler/passes/main/tests/fixtures/checker/import_sym_test.jac +6 -0
  15. jaclang/compiler/passes/main/tests/fixtures/checker/imported_sym.jac +5 -0
  16. jaclang/compiler/passes/main/tests/fixtures/checker_arg_param_match.jac +37 -0
  17. jaclang/compiler/passes/main/tests/fixtures/checker_arity.jac +18 -0
  18. jaclang/compiler/passes/main/tests/fixtures/checker_cat_is_animal.jac +18 -0
  19. jaclang/compiler/passes/main/tests/fixtures/checker_float.jac +7 -0
  20. jaclang/compiler/passes/main/tests/fixtures/checker_param_types.jac +11 -0
  21. jaclang/compiler/passes/main/tests/fixtures/checker_self_type.jac +9 -0
  22. jaclang/compiler/passes/main/tests/fixtures/checker_sym_inherit.jac +42 -0
  23. jaclang/compiler/passes/main/tests/fixtures/predynamo_fix3.jac +43 -0
  24. jaclang/compiler/passes/main/tests/fixtures/predynamo_where_assign.jac +13 -0
  25. jaclang/compiler/passes/main/tests/fixtures/predynamo_where_return.jac +11 -0
  26. jaclang/compiler/passes/main/tests/test_checker_pass.py +190 -0
  27. jaclang/compiler/passes/main/tests/test_predynamo_pass.py +56 -0
  28. jaclang/compiler/passes/main/type_checker_pass.py +29 -73
  29. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +302 -58
  30. jaclang/compiler/passes/tool/jac_formatter_pass.py +119 -69
  31. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
  32. jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/triple_quoted_string.jac +4 -5
  33. jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +7 -1
  34. jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +276 -10
  35. jaclang/compiler/passes/transform.py +12 -8
  36. jaclang/compiler/program.py +19 -7
  37. jaclang/compiler/tests/fixtures/jac_import_py_files.py +4 -0
  38. jaclang/compiler/tests/fixtures/jac_module.jac +3 -0
  39. jaclang/compiler/tests/fixtures/multiple_syntax_errors.jac +10 -0
  40. jaclang/compiler/tests/fixtures/python_module.py +1 -0
  41. jaclang/compiler/tests/test_importer.py +39 -0
  42. jaclang/compiler/tests/test_parser.py +49 -0
  43. jaclang/compiler/type_system/type_evaluator.jac +959 -0
  44. jaclang/compiler/type_system/type_utils.py +246 -0
  45. jaclang/compiler/type_system/types.py +58 -2
  46. jaclang/compiler/unitree.py +102 -107
  47. jaclang/langserve/engine.jac +138 -159
  48. jaclang/langserve/server.jac +25 -1
  49. jaclang/langserve/tests/fixtures/circle.jac +3 -3
  50. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  51. jaclang/langserve/tests/fixtures/circle_pure.test.jac +3 -3
  52. jaclang/langserve/tests/fixtures/completion_test_err.jac +10 -0
  53. jaclang/langserve/tests/server_test/circle_template.jac +80 -0
  54. jaclang/langserve/tests/server_test/glob_template.jac +4 -0
  55. jaclang/langserve/tests/server_test/test_lang_serve.py +154 -309
  56. jaclang/langserve/tests/server_test/utils.py +153 -116
  57. jaclang/langserve/tests/test_server.py +21 -84
  58. jaclang/langserve/utils.jac +12 -15
  59. jaclang/lib.py +17 -0
  60. jaclang/runtimelib/archetype.py +25 -25
  61. jaclang/runtimelib/constructs.py +2 -2
  62. jaclang/runtimelib/machine.py +63 -46
  63. jaclang/runtimelib/meta_importer.py +27 -1
  64. jaclang/runtimelib/tests/fixtures/custom_access_validation.jac +1 -1
  65. jaclang/runtimelib/tests/fixtures/savable_object.jac +2 -2
  66. jaclang/settings.py +19 -16
  67. jaclang/tests/fixtures/abc_check.jac +3 -3
  68. jaclang/tests/fixtures/arch_rel_import_creation.jac +12 -12
  69. jaclang/tests/fixtures/attr_pattern_case.jac +18 -0
  70. jaclang/tests/fixtures/chandra_bugs2.jac +3 -3
  71. jaclang/tests/fixtures/create_dynamic_archetype.jac +13 -13
  72. jaclang/tests/fixtures/funccall_genexpr.jac +7 -0
  73. jaclang/tests/fixtures/funccall_genexpr.py +5 -0
  74. jaclang/tests/fixtures/maxfail_run_test.jac +4 -4
  75. jaclang/tests/fixtures/params/param_syntax_err.jac +9 -0
  76. jaclang/tests/fixtures/params/test_complex_params.jac +42 -0
  77. jaclang/tests/fixtures/params/test_failing_kwonly.jac +207 -0
  78. jaclang/tests/fixtures/params/test_failing_posonly.jac +116 -0
  79. jaclang/tests/fixtures/params/test_failing_varargs.jac +300 -0
  80. jaclang/tests/fixtures/params/test_kwonly_params.jac +29 -0
  81. jaclang/tests/fixtures/py2jac_params.py +8 -0
  82. jaclang/tests/fixtures/run_test.jac +4 -4
  83. jaclang/tests/test_cli.py +159 -7
  84. jaclang/tests/test_language.py +213 -38
  85. jaclang/tests/test_reference.py +3 -1
  86. jaclang/utils/helpers.py +67 -6
  87. jaclang/utils/module_resolver.py +10 -0
  88. jaclang/utils/test.py +8 -0
  89. jaclang/utils/tests/test_lang_tools.py +4 -15
  90. jaclang/utils/treeprinter.py +0 -18
  91. {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/METADATA +1 -2
  92. {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/RECORD +95 -65
  93. {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/WHEEL +1 -1
  94. jaclang/compiler/passes/main/inheritance_pass.py +0 -131
  95. jaclang/compiler/type_system/type_evaluator.py +0 -560
  96. jaclang/langserve/dev_engine.jac +0 -645
  97. jaclang/langserve/dev_server.jac +0 -201
  98. /jaclang/{langserve/tests/server_test/code_test.py → tests/fixtures/py2jac_empty.py} +0 -0
  99. {jaclang-0.8.7.dist-info → jaclang-0.8.9.dist-info}/entry_points.txt +0 -0
@@ -3,7 +3,8 @@
3
3
  This is a pass for formatting Jac code.
4
4
  """
5
5
 
6
- from typing import Optional
6
+ from collections import deque
7
+ from typing import Deque, Optional, Tuple
7
8
 
8
9
  import jaclang.compiler.passes.tool.doc_ir as doc
9
10
  import jaclang.compiler.unitree as uni
@@ -19,6 +20,83 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
19
20
  self.indent_size = 4
20
21
  self.MAX_LINE_LENGTH = settings.max_line_length
21
22
 
23
+ def _probe_fits(
24
+ self,
25
+ node: doc.DocType,
26
+ indent_level: int,
27
+ width_remaining: int,
28
+ *,
29
+ max_steps: int = 2000,
30
+ ) -> bool:
31
+ """
32
+ Check if flat can be used early.
33
+
34
+ returns True if `node` could be printed *flat* on the current line within
35
+ `width_remaining` columns at `indent_level`.
36
+ Stops early on overflow or hard/literal lines.
37
+ """
38
+ # Worklist holds (node, indent_level). We only ever push FLAT in a probe.
39
+ work: Deque[Tuple[object, int]] = deque()
40
+ work.append((node, indent_level))
41
+ steps = 0
42
+ remaining = width_remaining
43
+
44
+ while work:
45
+ if steps >= max_steps:
46
+ # Safety cutoff: if it's *that* complex, assume it doesn't fit.
47
+ return False
48
+ steps += 1
49
+
50
+ cur, lvl = work.pop()
51
+
52
+ if isinstance(cur, doc.Text):
53
+ remaining -= len(cur.text)
54
+ if remaining <= 0:
55
+ return False
56
+
57
+ elif isinstance(cur, doc.Line):
58
+ if cur.hard or cur.literal:
59
+ # Any *real* newline (hard or literal) in FLAT means "doesn't fit"
60
+ return False
61
+ if cur.tight:
62
+ # tight softline disappears in flat mode
63
+ continue
64
+ # regular soft line becomes a single space in flat mode
65
+ remaining -= 1
66
+ if remaining <= 0:
67
+ return False
68
+
69
+ # --- Structural nodes (walk children in LIFO) ---
70
+ elif isinstance(cur, doc.Concat):
71
+ # push reversed so we process left-to-right as work is a stack
72
+ for p in reversed(cur.parts):
73
+ work.append((p, lvl))
74
+
75
+ elif isinstance(cur, doc.Group):
76
+ # Probe is always FLAT for groups.
77
+ work.append((cur.contents, lvl))
78
+
79
+ elif isinstance(cur, doc.Indent):
80
+ # In flat mode, indentation has no effect until a newline; keep lvl in case
81
+ # children contain Lines (which would have already returned False).
82
+ work.append((cur.contents, lvl + 1))
83
+
84
+ elif isinstance(cur, doc.Align):
85
+ # In flat mode, alignment doesn’t change width immediately (no newline),
86
+ # but we carry its virtual indent so nested (illegal) Line would be caught.
87
+ align_spaces = cur.n if cur.n is not None else self.indent_size
88
+ extra_levels = align_spaces // self.indent_size
89
+ work.append((cur.contents, lvl + extra_levels))
90
+
91
+ elif isinstance(cur, doc.IfBreak):
92
+ # Flat branch while probing
93
+ work.append((cur.flat_contents, lvl))
94
+
95
+ else:
96
+ raise ValueError(f"Unknown DocType in probe: {type(cur)}")
97
+
98
+ return True
99
+
22
100
  def transform(self, ir_in: uni.Module) -> uni.Module:
23
101
  """After pass."""
24
102
  ir_in.gen.jac = self.format_doc_ir()
@@ -52,106 +130,78 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
52
130
  return " "
53
131
 
54
132
  elif isinstance(doc_node, doc.Group):
55
- # Try to print flat first. For this attempt, the group itself isn't forced to break.
56
- flat_contents_str = self.format_doc_ir(
57
- doc_node.contents, indent_level, width_remaining, is_broken=False
133
+ fits_flat = self._probe_fits(
134
+ doc_node.contents,
135
+ indent_level=indent_level,
136
+ width_remaining=width_remaining,
137
+ )
138
+ return self.format_doc_ir(
139
+ doc_node.contents,
140
+ indent_level,
141
+ width_remaining,
142
+ is_broken=not fits_flat,
58
143
  )
59
- if (
60
- "\n" not in flat_contents_str
61
- and len(flat_contents_str) <= width_remaining
62
- ):
63
- return flat_contents_str
64
- else:
65
- full_width_for_broken_content = self.MAX_LINE_LENGTH - (
66
- indent_level * self.indent_size
67
- )
68
- return self.format_doc_ir(
69
- doc_node.contents,
70
- indent_level,
71
- full_width_for_broken_content,
72
- is_broken=True,
73
- )
74
144
 
75
145
  elif isinstance(doc_node, doc.Indent):
76
146
  new_indent_level = indent_level + 1
77
-
78
- width_for_indented_content = self.MAX_LINE_LENGTH - (
79
- new_indent_level * self.indent_size
80
- )
81
147
  return self.format_doc_ir(
82
148
  doc_node.contents,
83
149
  new_indent_level,
84
- width_for_indented_content, # Budget for lines within indent
150
+ width_remaining, # width_for_indented_content # Budget for lines within indent
85
151
  is_broken, # is_broken state propagates
86
152
  )
87
153
 
88
154
  elif isinstance(doc_node, doc.Concat):
89
- result = ""
90
- # current_line_budget is the space left on the current line for the current part.
155
+ result: list[str] = []
91
156
  current_line_budget = width_remaining
92
157
 
93
158
  for part in doc_node.parts:
94
159
  part_str = self.format_doc_ir(
95
160
  part, indent_level, current_line_budget, is_broken
96
161
  )
97
- if part_str.startswith("\n"):
98
- result = result.rstrip(" ")
99
- result += part_str
162
+
163
+ # Trim trailing spaces when a newline begins next
164
+ if part_str.startswith("\n") and result and result[-1].endswith(" "):
165
+ result[-1] = result[-1].rstrip(" ")
166
+
167
+ result.append(part_str)
100
168
 
101
169
  if "\n" in part_str:
102
- # part_str created a newline. The next part starts on a new line.
103
- # Its budget is the full width available at this indent level.
104
- current_line_budget = self.MAX_LINE_LENGTH - (
105
- indent_level * self.indent_size
170
+ # After a newline, reset budget to full width at this indent.
171
+ last_line = part_str.splitlines()[-1]
172
+ full_budget = max(
173
+ 0, self.MAX_LINE_LENGTH - indent_level * self.indent_size
106
174
  )
107
- # Subtract what the *last line* of part_str consumed from this budget.
108
- # The characters on the last line after the indent string.
109
- indent_str_len = indent_level * self.indent_size
110
- last_line_of_part = part_str.splitlines()[-1]
111
-
112
- content_on_last_line = 0
113
- if last_line_of_part.startswith(" " * indent_str_len):
114
- content_on_last_line = len(last_line_of_part) - indent_str_len
115
- else: # It was a line not starting with the full indent (e.g. literal \n)
116
- content_on_last_line = len(last_line_of_part)
117
-
118
- current_line_budget -= content_on_last_line
175
+ # Compute how many chars are already on the last line (after indent).
176
+ indent_spaces = " " * (indent_level * self.indent_size)
177
+ if last_line.startswith(indent_spaces):
178
+ used = len(last_line) - len(indent_spaces)
179
+ else:
180
+ used = len(last_line)
181
+ current_line_budget = max(0, full_budget - used)
119
182
  else:
120
- # part_str stayed on the same line. Reduce budget for next part on this line.
121
- current_line_budget -= len(part_str)
183
+ current_line_budget = max(0, current_line_budget - len(part_str))
122
184
 
123
- if current_line_budget < 0: # Ensure budget isn't negative
124
- current_line_budget = 0
125
- return result
185
+ return "".join(result)
126
186
 
127
187
  elif isinstance(doc_node, doc.IfBreak):
128
- if is_broken:
129
- return self.format_doc_ir(
130
- doc_node.break_contents, indent_level, width_remaining, is_broken
131
- )
132
- else:
133
- return self.format_doc_ir(
134
- doc_node.flat_contents, indent_level, width_remaining, is_broken
135
- )
188
+ branch = doc_node.break_contents if is_broken else doc_node.flat_contents
189
+ return self.format_doc_ir(branch, indent_level, width_remaining, is_broken)
136
190
 
137
191
  elif isinstance(doc_node, doc.Align):
138
192
  align_spaces = doc_node.n if doc_node.n is not None else self.indent_size
139
- # effective_total_indent_spaces_for_children = (
140
- # indent_level * self.indent_size
141
- # ) + align_spaces
142
- child_indent_level_for_align = indent_level + (
143
- align_spaces // self.indent_size
144
- )
193
+ extra_levels = align_spaces // self.indent_size
194
+ child_indent_level = indent_level + extra_levels
145
195
 
146
- child_width_budget = width_remaining - align_spaces
147
- if child_width_budget < 0:
148
- child_width_budget = 0
196
+ # On the same line, alignment "consumes" part of the current budget.
197
+ child_width_budget = max(0, width_remaining - align_spaces)
149
198
 
150
199
  return self.format_doc_ir(
151
200
  doc_node.contents,
152
- child_indent_level_for_align, # Approximated level for Lines inside
153
- child_width_budget, # Budget for content on first line
201
+ child_indent_level,
202
+ child_width_budget,
154
203
  is_broken,
155
204
  )
205
+
156
206
  else:
157
207
  raise ValueError(f"Unknown DocType: {type(doc_node)}")
@@ -474,15 +474,15 @@ impl JacPlugin.visit_node
474
474
  glob expected_area = 78.53981633974483;
475
475
 
476
476
  test a1 {
477
- check assertAlmostEqual(calculate_area(RAD), expected_area);
477
+ assert assertAlmostEqual(calculate_area(RAD), expected_area);
478
478
  }
479
479
 
480
480
  test a2 {
481
481
  c = Circle(RAD);
482
- check assertAlmostEqual(c.area(), expected_area);
482
+ assert assertAlmostEqual(c.area(), expected_area);
483
483
  }
484
484
 
485
485
  test a3 {
486
486
  c = Circle(RAD);
487
- check assertEqual(c.shape_type, ShapeType.CIRCLE);
487
+ assert assertEqual(c.shape_type, ShapeType.CIRCLE);
488
488
  }
@@ -1,7 +1,6 @@
1
1
  with entry {
2
- triple_quoted_string =
3
- """This is a triple quoted string.
4
- It can span multiple lines.
5
- It can contain any number of quotes or apostrophes.
6
- """;
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
+ """;
7
6
  }
@@ -1,6 +1,12 @@
1
1
  import from datetime { datetime }
2
2
  import from uuid { UUID, uuid4 }
3
3
  import from jaclang.compiler.constant { EdgeDir }
4
- import from jaclang.plugin { Archetype, ArchetypeProtocol, DSFunc, AbsRootHook, hookimpl }
4
+ import from jaclang.plugin {
5
+ Archetype,
6
+ ArchetypeProtocol,
7
+ DSFunc,
8
+ AbsRootHook,
9
+ hookimpl
10
+ }
5
11
  import math;
6
12
  import numpy as np;
@@ -1,18 +1,284 @@
1
+ #this file is part of formatter tests and is not meant to be run
1
2
  class SemTokManager {
2
3
  """Initialize semantic token manager."""
3
4
  def init(self: SemTokManager, ir: uni.Module) -> None {
4
- self.sem_tokens: List[int] = self.gen_sem_tokens(ir);
5
5
  self.aaaaastatic_sem_tokens:
6
- List[Tuple[lspt.Position, int, int, uni.AstSymbolNode]] =
7
- self.gen_sem_tok_node(ir);
6
+ List[Tuple[lspt.Position, int, int, uni.AstSymbolNode]] = self.gen_sem_tok_node(
7
+ ir
8
+ );
8
9
  }
9
10
  }
10
11
 
11
12
 
12
- def init(
13
- self: ModuleManager,
14
- program: JacProgram,
15
- sem_managers: <>dict,
16
- program2: JacProgram,
17
- sem_managers2: <>dict
18
- ) -> None { }
13
+ def walrus_example() {
14
+ if ((x := 10) > 5) {
15
+ print(x);
16
+ b = a(
17
+ 11111111111111111111111111111111111111111111111111111111111111111111111111
18
+ );
19
+ }
20
+ }
21
+
22
+
23
+ with entry {
24
+ c = (
25
+ a()
26
+ if 1
27
+ and isinstance(a, int)
28
+ and isinstance(a, int)
29
+ and isinstance(a, int)
30
+ and isinstance(a, int)
31
+ and isinstance(a, int)
32
+ else (
33
+ 999
34
+ if isinstance(a, int)
35
+ and isinstance(a, int)
36
+ and isinstance(a, int)
37
+ and isinstance(4, bool)
38
+ else 7
39
+ )
40
+ );
41
+ print("""This is a long
42
+ line of code.""");
43
+ }
44
+
45
+
46
+ class ModuleManager {
47
+ def clear_alerts_for_file(self: ModuleManager, file_path_fs: str) -> None {
48
+ #list comprehension example
49
+ self.warnings_had = [
50
+ w
51
+ for w in self.program
52
+ if w.loc.mod_path != file_path_fs
53
+ ];
54
+ self.program.errors_had = [
55
+ e
56
+ for e in self.program.errors_haddddddddd
57
+ if e.loc.mod_path != file_path_fs
58
+ ];
59
+ self.program.errors_had = [
60
+ e
61
+ for e in self.program.errors_haddddddddddddddddddddddddddddddddddddddddd
62
+ if e.loc.mod_path != file_path_fs
63
+ ];
64
+ # dict comprehension example
65
+ squares_dict = {x : x ** 2 for x in numbers};
66
+ squares_dict = {
67
+ x : x ** 2 for x in numberssssssssssssssssssssssssssssssssssssssssssssss
68
+ };
69
+ squares_dict = {
70
+ x : x ** 2
71
+ for x in numbersssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
72
+ };
73
+ # set comprehension example
74
+ squares_set = {x ** 2 for x in numbers};
75
+ squares_set = {
76
+ x ** 2 for x in numberssssssssssssssssssssssssssssssssssssssssssssssss
77
+ };
78
+ squares_set = {
79
+ x ** 2
80
+ for x in numbersssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
81
+ };
82
+ # generator comprehension example
83
+ squares_gen = (x ** 2 for x in numbers);
84
+ squares_gen = (
85
+ x ** 2 for x in numberssssssssssssssssssssssssssssssssssssssssssssssssssss
86
+ );
87
+ squares_gen = (
88
+ x ** 2
89
+ for x in numbersssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
90
+ );
91
+ }
92
+ }
93
+
94
+
95
+ ## expr as item extra space issue
96
+ with entry {
97
+ with open(f"Apple{apple}.txt") as f {
98
+ # Fix syntax highlighting
99
+ print(
100
+ f.read()
101
+ );
102
+ }
103
+ }
104
+
105
+
106
+ def func_with_very_long_params(
107
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int,
108
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int,
109
+ ) -> None {
110
+ print(
111
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,
112
+ bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
113
+ );
114
+ }
115
+
116
+
117
+ def func_with_long_params(
118
+ aaaaaaaaaaaaaaaaaaaaaa: int, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int,
119
+ ) -> None {
120
+ print(
121
+ aaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, 1111111111111
122
+ );
123
+ }
124
+
125
+
126
+ def func_with_short_params(a: int, b: int) -> None {
127
+ print(a + b + c[5:]);
128
+ }
129
+
130
+
131
+ with entry {
132
+ if (
133
+ node_selected
134
+ and node_selected.find_parent_of_type(uni.Archetype)
135
+ or node_selected.find_parent_of_type(uni.ImplDef)
136
+ ) {
137
+ self_symbol = [
138
+ lspt.CompletionItem(label='self', kind=lspt.CompletionItemKind.Variable)
139
+ ];
140
+ } else {
141
+ self_symbol = [];
142
+ }
143
+ x = (
144
+ 1222222222
145
+ and 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
146
+ );
147
+ a = 4 if True else 4;
148
+ }
149
+
150
+
151
+ import from typing { Any, Awaitable, Callable, Coroutine, Optional, ParamSpec, TypeVar }
152
+
153
+ import from jaclang.compiler.constant {
154
+ JacSemTokenModifier as SemTokMod,
155
+ JacSemTokenType as SemTokType,
156
+ }
157
+
158
+
159
+ """Return diagnostics."""
160
+ def gen_diagnostics(
161
+ from_path: str, errors: list[Alert], warnings: list[Alert]
162
+ ) -> list[lspt.Diagnostic] {
163
+ if (
164
+ isinstance(node_selected, uni.Name)
165
+ and node_selected.parent
166
+ and isinstance(node_selected.parent, uni.ModulePath)
167
+ ) {
168
+ node_selected = node_selected.name_of;
169
+ } elif (
170
+ isinstance(node_selected, uni.Name)
171
+ and node_selected.parent
172
+ and isinstance(node_selected.parent, uni.ModulePath)
173
+ ) {
174
+ spec = node_selected.parent.parent.abs_path;
175
+ }
176
+ }
177
+
178
+
179
+ @decorator
180
+ def x() {
181
+ assert gg == 7;
182
+ }
183
+
184
+
185
+ @decorator()
186
+ class KK {}
187
+
188
+
189
+ # kkk
190
+ import pygame, random, math;
191
+
192
+
193
+ # fff
194
+ with entry {
195
+ # gg
196
+ a = 9;
197
+ }
198
+
199
+
200
+ # kkk
201
+ class X {}
202
+
203
+
204
+ # comment
205
+ @decorator
206
+ def xxx() { }
207
+
208
+
209
+ # ddd
210
+ glob a = 7;
211
+ def get_node_info(self: JacLangServer, sym_node: uni.AstSymbolNode) -> Optional[str] {
212
+ try {
213
+ if isinstance(sym_node, uni.NameAtom) {
214
+ sym_node = sym_node.name_of;
215
+ }
216
+ access = (sym_node.sym.access.value + ' ') if sym_node.sym else None;
217
+ node_info = f"'('{(access if access else '')}{sym_node.sym_category.value}') '{sym_node.sym_name}";
218
+ if sym_node.name_spec.clean_type {
219
+ node_info += f"': '{sym_node.name_spec.clean_type}";
220
+ }
221
+ if (
222
+ isinstance(sym_node, uni.AstSymbolNode)
223
+ and isinstance(sym_node.name_spec.type, ClassType)
224
+ ) {
225
+ node_info += f"': '{sym_node.name_spec.type.shared.class_name}";
226
+ }
227
+ if (isinstance(sym_node, uni.AstDocNode) and sym_node.doc) {
228
+ node_info += f"'\n'{sym_node.doc.value}";
229
+ }
230
+ if (isinstance(sym_node, uni.Ability) and sym_node.signature) {
231
+ node_info += f"'\n'{sym_node.signature.unparse()}";
232
+ }
233
+ } except AttributeError as e {
234
+ self.log_warning(f"'Attribute error when accessing node attributes: '{e}");
235
+ }
236
+ return node_info.strip();
237
+ }
238
+
239
+
240
+ class foo {
241
+ """Get information about a node."""
242
+ def get_node_info(
243
+ self: JacLangServer, sym_node: uni.AstSymbolNode
244
+ ) -> Optional[str] {
245
+ if isinstance(sym_node, uni.AstVarNode) {
246
+ var_name = sym_node.name;
247
+ var_type = sym_node.var_type if sym_node.var_type else 'unknown';
248
+ return f" 'Variable: ' {var_name} ', Type: ' {var_type} ";
249
+ } elif isinstance(sym_node, uni.AstFuncNode) {
250
+ func_name = sym_node.name;
251
+ params = ', '.join(
252
+ [f" {p.name} ': ' {p.param_type} " for p in sym_node.params]
253
+ );
254
+ return f" 'Function: ' {func_name} '(' {params} ')' ";
255
+ }
256
+ }
257
+ }
258
+
259
+
260
+ def x3() {
261
+ if dest_type.is_class_instance() and src_type.is_class_instance() {
262
+ print("x");
263
+ }
264
+ if (
265
+ dest_type.is_class_instance()
266
+ and src_type.is_class_instance()
267
+ and src_type.is_class_instance()
268
+ ) {
269
+ print("x");
270
+ }
271
+ if (dest_type.is_class_instance() and src_type.is_class_instance()) {
272
+ print("x");
273
+ }
274
+ }
275
+
276
+
277
+ class HH {
278
+ def test() -> Optional[str] {
279
+ a = """!
280
+ hello
281
+ hru
282
+ """;
283
+ }
284
+ }
@@ -9,7 +9,7 @@ from typing import Generic, Optional, TYPE_CHECKING, Type, TypeVar
9
9
  from jaclang.compiler.codeinfo import CodeLocInfo
10
10
  from jaclang.compiler.unitree import UniNode
11
11
  from jaclang.settings import settings
12
- from jaclang.utils.helpers import pretty_print_source_location
12
+ from jaclang.utils.helpers import ANSIColors, pretty_print_source_location
13
13
  from jaclang.utils.log import logging
14
14
 
15
15
  if TYPE_CHECKING:
@@ -39,7 +39,7 @@ class Alert:
39
39
  """Return string representation of alert."""
40
40
  return self.as_log()
41
41
 
42
- def as_log(self) -> str:
42
+ def as_log(self, *, colors: bool = False) -> str:
43
43
  """Return the alert as a single line log as opposed to the pretty print."""
44
44
  file_path: str = self.loc.mod_path
45
45
  if file_path == "":
@@ -47,20 +47,24 @@ class Alert:
47
47
 
48
48
  line: int = self.loc.first_line
49
49
  column: int = self.loc.col_start
50
- return f"{file_path}:{line}:{column} {self.msg}"
51
50
 
52
- def pretty_print(self) -> str:
53
- """Pretty pritns the Alert to show the alert with source location."""
51
+ # TODO: Set if the alert is error or warning and color accordingly.
52
+ msg = self.msg if not colors else f"{ANSIColors.RED}{self.msg}{ANSIColors.END}"
53
+ return f"{file_path}:{line}:{column} {msg}"
54
+
55
+ def pretty_print(self, *, colors: bool = False) -> str:
56
+ """Pretty prints the Alert to show the alert with source location."""
54
57
  pretty_dump = pretty_print_source_location(
55
58
  self.loc.mod_path,
56
59
  self.loc.orig_src.code,
57
60
  self.loc.first_line,
58
61
  self.loc.pos_start,
59
62
  self.loc.pos_end,
63
+ colors=colors,
60
64
  )
61
65
  if pretty_dump != "":
62
66
  pretty_dump = "\n" + pretty_dump
63
- return self.as_log() + pretty_dump
67
+ return self.as_log(colors=colors) + pretty_dump
64
68
 
65
69
 
66
70
  class Transform(ABC, Generic[T, R]):
@@ -115,7 +119,7 @@ class Transform(ABC, Generic[T, R]):
115
119
  )
116
120
  self.errors_had.append(alrt)
117
121
  self.prog.errors_had.append(alrt)
118
- self.logger.error(alrt.as_log())
122
+ # self.logger.error(alrt.as_log())
119
123
 
120
124
  def log_warning(self, msg: str, node_override: Optional[UniNode] = None) -> None:
121
125
  """Pass Error."""
@@ -126,7 +130,7 @@ class Transform(ABC, Generic[T, R]):
126
130
  )
127
131
  self.warnings_had.append(alrt)
128
132
  self.prog.warnings_had.append(alrt)
129
- self.logger.warning(alrt.as_log())
133
+ # self.logger.warning(alrt.as_log())
130
134
 
131
135
  def log_info(self, msg: str) -> None:
132
136
  """Log info."""