jaclang 0.8.8__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 (36) hide show
  1. jaclang/cli/cli.py +64 -2
  2. jaclang/compiler/constant.py +6 -1
  3. jaclang/compiler/jac.lark +34 -41
  4. jaclang/compiler/larkparse/jac_parser.py +2 -2
  5. jaclang/compiler/parser.py +143 -27
  6. jaclang/compiler/passes/main/def_use_pass.py +1 -0
  7. jaclang/compiler/passes/main/pyast_gen_pass.py +151 -83
  8. jaclang/compiler/passes/main/pyast_load_pass.py +2 -0
  9. jaclang/compiler/passes/main/tests/test_checker_pass.py +0 -1
  10. jaclang/compiler/passes/main/tests/test_predynamo_pass.py +13 -14
  11. jaclang/compiler/passes/tool/doc_ir_gen_pass.py +104 -20
  12. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  13. jaclang/compiler/passes/tool/tests/fixtures/import_fmt.jac +7 -1
  14. jaclang/compiler/passes/tool/tests/fixtures/tagbreak.jac +135 -29
  15. jaclang/compiler/program.py +6 -2
  16. jaclang/compiler/type_system/type_evaluator.jac +959 -0
  17. jaclang/compiler/unitree.py +23 -13
  18. jaclang/lib.py +17 -0
  19. jaclang/runtimelib/archetype.py +25 -25
  20. jaclang/runtimelib/constructs.py +2 -2
  21. jaclang/runtimelib/machine.py +57 -47
  22. jaclang/settings.py +1 -2
  23. jaclang/tests/fixtures/attr_pattern_case.jac +18 -0
  24. jaclang/tests/fixtures/funccall_genexpr.jac +7 -0
  25. jaclang/tests/fixtures/funccall_genexpr.py +5 -0
  26. jaclang/tests/fixtures/py2jac_empty.py +0 -0
  27. jaclang/tests/test_cli.py +134 -18
  28. jaclang/tests/test_language.py +146 -29
  29. jaclang/tests/test_reference.py +3 -1
  30. jaclang/utils/helpers.py +20 -4
  31. jaclang/utils/tests/test_lang_tools.py +4 -15
  32. {jaclang-0.8.8.dist-info → jaclang-0.8.9.dist-info}/METADATA +1 -1
  33. {jaclang-0.8.8.dist-info → jaclang-0.8.9.dist-info}/RECORD +35 -30
  34. jaclang/compiler/type_system/type_evaluator.py +0 -844
  35. {jaclang-0.8.8.dist-info → jaclang-0.8.9.dist-info}/WHEEL +0 -0
  36. {jaclang-0.8.8.dist-info → jaclang-0.8.9.dist-info}/entry_points.txt +0 -0
@@ -4,7 +4,7 @@ import io
4
4
  import os
5
5
  import sys
6
6
 
7
- from jaclang.compiler.program import JacProgram
7
+ from jaclang.compiler.program import JacProgram, py_code_gen
8
8
  from jaclang.utils.test import TestCase
9
9
  from jaclang.settings import settings
10
10
  from jaclang.compiler.passes.main import PreDynamoPass
@@ -16,42 +16,41 @@ class PreDynamoPassTests(TestCase):
16
16
 
17
17
  def setUp(self) -> None:
18
18
  """Set up test."""
19
+ settings.predynamo_pass = True
19
20
  return super().setUp()
20
-
21
+
22
+ def tearDown(self) -> None:
23
+ """Tear down test."""
24
+ settings.predynamo_pass = False
25
+ # Remove PreDynamoPass from global py_code_gen list if it was added
26
+ if PreDynamoPass in py_code_gen:
27
+ py_code_gen.remove(PreDynamoPass)
28
+ return super().tearDown()
29
+
21
30
  def test_predynamo_where_assign(self) -> None:
22
31
  """Test torch.where transformation."""
23
32
  captured_output = io.StringIO()
24
33
  sys.stdout = captured_output
25
- os.environ["JAC_PREDYNAMO_PASS"] = "True"
26
- settings.load_env_vars()
34
+ settings.predynamo_pass = True
27
35
  code_gen = JacProgram().compile(self.fixture_abs_path("predynamo_where_assign.jac"))
28
36
  sys.stdout = sys.__stdout__
29
37
  self.assertIn("torch.where", code_gen.unparse())
30
- os.environ["JAC_PREDYNAMO_PASS"] = "false"
31
- settings.load_env_vars()
32
38
 
33
39
  def test_predynamo_where_return(self) -> None:
34
40
  """Test torch.where transformation."""
35
41
  captured_output = io.StringIO()
36
42
  sys.stdout = captured_output
37
- os.environ["JAC_PREDYNAMO_PASS"] = "True"
38
- settings.load_env_vars()
39
43
  code_gen = JacProgram().compile(self.fixture_abs_path("predynamo_where_return.jac"))
40
44
  sys.stdout = sys.__stdout__
41
45
  self.assertIn("torch.where", code_gen.unparse())
42
- os.environ["JAC_PREDYNAMO_PASS"] = "false"
43
- settings.load_env_vars()
46
+
44
47
 
45
48
  def test_predynamo_fix3(self) -> None:
46
49
  """Test torch.where transformation."""
47
50
  captured_output = io.StringIO()
48
51
  sys.stdout = captured_output
49
- os.environ["JAC_PREDYNAMO_PASS"] = "True"
50
- settings.load_env_vars()
51
52
  code_gen = JacProgram().compile(self.fixture_abs_path("predynamo_fix3.jac"))
52
53
  sys.stdout = sys.__stdout__
53
54
  unparsed_code = code_gen.unparse()
54
55
  self.assertIn("__inv_freq = torch.where(", unparsed_code)
55
56
  self.assertIn("self.register_buffer('inv_freq', __inv_freq, persistent=False);", unparsed_code)
56
- os.environ["JAC_PREDYNAMO_PASS"] = "false"
57
- settings.load_env_vars()
@@ -135,20 +135,53 @@ class DocIRGenPass(UniPass):
135
135
  def exit_import(self, node: uni.Import) -> None:
136
136
  """Exit import node."""
137
137
  parts: list[doc.DocType] = []
138
+ mod_items: list[doc.DocType] = []
139
+ has_comment: Optional[doc.DocType] = None
140
+ is_in_items: bool = False
138
141
  for i in node.kid:
139
142
  if isinstance(i, uni.Token) and i.name == Tok.COMMA:
140
- parts.pop()
141
- parts.append(i.gen.doc_ir)
142
- parts.append(self.space())
143
+ if is_in_items:
144
+ mod_items.pop()
145
+ mod_items.append(i.gen.doc_ir)
146
+ mod_items.append(self.line())
147
+ else:
148
+ parts.pop()
149
+ parts.append(i.gen.doc_ir)
150
+ parts.append(self.line())
151
+ elif (
152
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
153
+ ):
154
+ has_comment = i.gen.doc_ir
143
155
  elif isinstance(i, uni.Token) and i.name == Tok.SEMI:
144
156
  parts.pop()
145
157
  parts.append(i.gen.doc_ir)
146
158
  elif isinstance(i, uni.Token) and i.name == Tok.RBRACE:
159
+ is_in_items = False
160
+ mod_items.pop()
161
+ parts.append(
162
+ self.group(
163
+ self.concat(
164
+ [
165
+ self.indent(self.concat([self.line(), *mod_items])),
166
+ self.line(),
167
+ ]
168
+ )
169
+ )
170
+ )
147
171
  parts.append(i.gen.doc_ir)
148
- else:
172
+ elif isinstance(i, uni.Token) and i.name == Tok.LBRACE:
173
+ is_in_items = True
149
174
  parts.append(i.gen.doc_ir)
150
- parts.append(self.space())
175
+ else:
176
+ if is_in_items:
177
+ mod_items.append(i.gen.doc_ir)
178
+ mod_items.append(self.space())
179
+ else:
180
+ parts.append(i.gen.doc_ir)
181
+ parts.append(self.space())
151
182
  node.gen.doc_ir = self.group(self.concat(parts))
183
+ if has_comment:
184
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
152
185
 
153
186
  def exit_module_item(self, node: uni.ModuleItem) -> None:
154
187
  """Generate DocIR for module items."""
@@ -178,6 +211,7 @@ class DocIRGenPass(UniPass):
178
211
  """Generate DocIR for archetypes."""
179
212
  parts: list[doc.DocType] = []
180
213
  body_parts: list[doc.DocType] = []
214
+ has_comment: Optional[doc.DocType] = None
181
215
  prev_item = None
182
216
  in_body = False
183
217
  for i in node.kid:
@@ -198,6 +232,10 @@ class DocIRGenPass(UniPass):
198
232
  parts.pop()
199
233
  parts.append(i.gen.doc_ir)
200
234
  parts.append(self.space())
235
+ elif (
236
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
237
+ ):
238
+ has_comment = i.gen.doc_ir
201
239
  elif isinstance(node.body, Sequence) and i in node.body:
202
240
  if not in_body:
203
241
  body_parts.append(self.hard_line())
@@ -225,13 +263,15 @@ class DocIRGenPass(UniPass):
225
263
  else:
226
264
  parts.append(i.gen.doc_ir)
227
265
  parts.append(self.space())
228
-
229
266
  node.gen.doc_ir = self.group(self.concat(parts))
267
+ if has_comment:
268
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
230
269
 
231
270
  def exit_ability(self, node: uni.Ability) -> None:
232
271
  """Generate DocIR for abilities."""
233
272
  parts: list[doc.DocType] = []
234
273
  body_parts: list[doc.DocType] = []
274
+ has_comment: Optional[doc.DocType] = None
235
275
  in_body = False
236
276
  for i in node.kid:
237
277
  if i == node.doc or (node.decorators and i in node.decorators):
@@ -259,12 +299,18 @@ class DocIRGenPass(UniPass):
259
299
  parts.pop()
260
300
  parts.append(i.gen.doc_ir)
261
301
  parts.append(self.space())
302
+ elif (
303
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
304
+ ):
305
+ has_comment = i.gen.doc_ir
262
306
  elif not in_body and isinstance(i, uni.Token) and i.name == Tok.DECOR_OP:
263
307
  parts.append(i.gen.doc_ir)
264
308
  else:
265
309
  parts.append(i.gen.doc_ir)
266
310
  parts.append(self.space())
267
311
  node.gen.doc_ir = self.group(self.concat(parts))
312
+ if has_comment:
313
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
268
314
 
269
315
  def exit_func_signature(self, node: uni.FuncSignature) -> None:
270
316
  """Generate DocIR for function signatures."""
@@ -401,7 +447,7 @@ class DocIRGenPass(UniPass):
401
447
  ]
402
448
  )
403
449
  )
404
- parts.append(self.if_break(broken, flat))
450
+ parts.append(self.group(self.if_break(broken, flat)))
405
451
  else:
406
452
  parts.append(i.gen.doc_ir)
407
453
  parts.append(self.space())
@@ -901,16 +947,16 @@ class DocIRGenPass(UniPass):
901
947
  return [expr]
902
948
 
903
949
  exprs = __flatten_bool_expr(node)
904
- for i in range(0, len(exprs) - 1, 2):
950
+ parts += [exprs[0].gen.doc_ir, self.line()]
951
+ for i in range(1, len(exprs), 2):
905
952
  (
906
- expr,
907
953
  op,
954
+ expr,
908
955
  ) = (
909
- exprs[i],
910
956
  exprs[i + 1],
957
+ exprs[i],
911
958
  )
912
959
  parts += [expr.gen.doc_ir, self.space(), op.gen.doc_ir, self.line()]
913
- parts += [exprs[-1].gen.doc_ir, self.line()]
914
960
  parts.pop()
915
961
  flat = self.concat(parts)
916
962
  node.gen.doc_ir = self.group(flat)
@@ -1108,6 +1154,8 @@ class DocIRGenPass(UniPass):
1108
1154
  """Generate DocIR for assert statements."""
1109
1155
  parts: list[doc.DocType] = []
1110
1156
  for i in node.kid:
1157
+ if isinstance(i, uni.Token) and i.name == Tok.SEMI and len(parts):
1158
+ parts.pop()
1111
1159
  parts.append(i.gen.doc_ir)
1112
1160
  parts.append(self.space())
1113
1161
  parts.pop()
@@ -1125,6 +1173,7 @@ class DocIRGenPass(UniPass):
1125
1173
  def exit_global_vars(self, node: uni.GlobalVars) -> None:
1126
1174
  """Generate DocIR for global variables."""
1127
1175
  parts: list[doc.DocType] = []
1176
+ has_comment: Optional[doc.DocType] = None
1128
1177
  for i in node.kid:
1129
1178
  if i == node.doc:
1130
1179
  parts.append(i.gen.doc_ir)
@@ -1133,15 +1182,22 @@ class DocIRGenPass(UniPass):
1133
1182
  parts.pop()
1134
1183
  parts.append(i.gen.doc_ir)
1135
1184
  parts.append(self.space())
1185
+ elif (
1186
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1187
+ ):
1188
+ has_comment = i.gen.doc_ir
1136
1189
  else:
1137
1190
  parts.append(i.gen.doc_ir)
1138
1191
  parts.append(self.space())
1139
1192
  node.gen.doc_ir = self.group(self.concat(parts))
1193
+ if has_comment:
1194
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1140
1195
 
1141
1196
  def exit_module_code(self, node: uni.ModuleCode) -> None:
1142
1197
  """Generate DocIR for module code."""
1143
1198
  parts: list[doc.DocType] = []
1144
1199
  body_parts: list[doc.DocType] = []
1200
+ has_comment: Optional[doc.DocType] = None
1145
1201
  in_body = False
1146
1202
  for i in node.kid:
1147
1203
  if node.doc and i is node.doc:
@@ -1153,6 +1209,10 @@ class DocIRGenPass(UniPass):
1153
1209
  elif isinstance(i, uni.Token) and i.name == Tok.COLON:
1154
1210
  parts.pop()
1155
1211
  parts.append(i.gen.doc_ir)
1212
+ elif (
1213
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1214
+ ):
1215
+ has_comment = i.gen.doc_ir
1156
1216
  elif isinstance(node.body, Sequence) and i in node.body:
1157
1217
  if not in_body:
1158
1218
  parts.pop()
@@ -1175,6 +1235,8 @@ class DocIRGenPass(UniPass):
1175
1235
  parts.append(i.gen.doc_ir)
1176
1236
  parts.append(self.space())
1177
1237
  node.gen.doc_ir = self.group(self.concat(parts))
1238
+ if has_comment:
1239
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1178
1240
 
1179
1241
  def exit_global_stmt(self, node: uni.GlobalStmt) -> None:
1180
1242
  """Generate DocIR for global statements."""
@@ -1264,7 +1326,9 @@ class DocIRGenPass(UniPass):
1264
1326
  ]
1265
1327
  )
1266
1328
  )
1267
- if isinstance(node.parent, uni.Assignment):
1329
+ if isinstance(node.parent, (uni.Assignment)) or (
1330
+ isinstance(node.parent, uni.IfStmt) and isinstance(node.value, uni.BoolExpr)
1331
+ ):
1268
1332
  node.gen.doc_ir = self.if_break(
1269
1333
  flat_contents=self.group(self.concat(parts[1:-1])),
1270
1334
  break_contents=broken,
@@ -1300,6 +1364,7 @@ class DocIRGenPass(UniPass):
1300
1364
  def exit_py_inline_code(self, node: uni.PyInlineCode) -> None:
1301
1365
  """Generate DocIR for Python inline code blocks."""
1302
1366
  parts: list[doc.DocType] = []
1367
+ has_comment: Optional[doc.DocType] = None
1303
1368
  for i in node.kid:
1304
1369
  if i == node.doc:
1305
1370
  parts.append(i.gen.doc_ir)
@@ -1309,14 +1374,21 @@ class DocIRGenPass(UniPass):
1309
1374
  parts.append(i.gen.doc_ir)
1310
1375
  parts.append(self.text("::py::"))
1311
1376
  parts.append(self.hard_line())
1377
+ elif (
1378
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1379
+ ):
1380
+ has_comment = i.gen.doc_ir
1312
1381
  else:
1313
1382
  parts.append(i.gen.doc_ir)
1314
1383
  parts.append(self.space())
1315
1384
  node.gen.doc_ir = self.group(self.concat(parts))
1385
+ if has_comment:
1386
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1316
1387
 
1317
1388
  def exit_test(self, node: uni.Test) -> None:
1318
1389
  """Generate DocIR for test nodes."""
1319
1390
  parts: list[doc.DocType] = []
1391
+ has_comment: Optional[doc.DocType] = None
1320
1392
  for i in node.kid:
1321
1393
  if i == node.doc:
1322
1394
  parts.append(i.gen.doc_ir)
@@ -1325,10 +1397,16 @@ class DocIRGenPass(UniPass):
1325
1397
  if not i.value.startswith("_jac_gen_"):
1326
1398
  parts.append(i.gen.doc_ir)
1327
1399
  parts.append(self.space())
1400
+ elif (
1401
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1402
+ ):
1403
+ has_comment = i.gen.doc_ir
1328
1404
  else:
1329
1405
  parts.append(i.gen.doc_ir)
1330
1406
  parts.append(self.space())
1331
1407
  node.gen.doc_ir = self.group(self.concat(parts))
1408
+ if has_comment:
1409
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1332
1410
 
1333
1411
  def exit_match_stmt(self, node: uni.MatchStmt) -> None:
1334
1412
  """Generate DocIR for match statements."""
@@ -1512,6 +1590,7 @@ class DocIRGenPass(UniPass):
1512
1590
  """Generate DocIR for implementation definitions."""
1513
1591
  parts: list[doc.DocType] = []
1514
1592
  body_parts: list[doc.DocType] = []
1593
+ has_comment: Optional[doc.DocType] = None
1515
1594
  in_body = False
1516
1595
  for i in node.kid:
1517
1596
  if i == node.doc or (node.decorators and i in node.decorators):
@@ -1519,6 +1598,10 @@ class DocIRGenPass(UniPass):
1519
1598
  parts.append(self.hard_line())
1520
1599
  elif self.is_within(i, node.target):
1521
1600
  parts.append(i.gen.doc_ir)
1601
+ elif (
1602
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1603
+ ):
1604
+ has_comment = i.gen.doc_ir
1522
1605
  elif (
1523
1606
  in_body
1524
1607
  or isinstance(node.body, Sequence)
@@ -1546,10 +1629,13 @@ class DocIRGenPass(UniPass):
1546
1629
  parts.append(i.gen.doc_ir)
1547
1630
  parts.append(self.space())
1548
1631
  node.gen.doc_ir = self.group(self.concat(parts))
1632
+ if has_comment:
1633
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1549
1634
 
1550
1635
  def exit_sem_def(self, node: uni.SemDef) -> None:
1551
1636
  """Generate DocIR for semantic definitions."""
1552
1637
  parts: list[doc.DocType] = []
1638
+ has_comment: Optional[doc.DocType] = None
1553
1639
  for i in node.kid:
1554
1640
  if i in node.target:
1555
1641
  parts.append(i.gen.doc_ir)
@@ -1557,10 +1643,16 @@ class DocIRGenPass(UniPass):
1557
1643
  parts.pop()
1558
1644
  parts.append(i.gen.doc_ir)
1559
1645
  parts.append(self.space())
1646
+ elif (
1647
+ i == node.kid[0] and isinstance(i, uni.Token) and i.name == Tok.COMMENT
1648
+ ):
1649
+ has_comment = i.gen.doc_ir
1560
1650
  else:
1561
1651
  parts.append(i.gen.doc_ir)
1562
1652
  parts.append(self.space())
1563
1653
  node.gen.doc_ir = self.group(self.concat(parts))
1654
+ if has_comment:
1655
+ node.gen.doc_ir = self.concat([has_comment, node.gen.doc_ir])
1564
1656
 
1565
1657
  def exit_event_signature(self, node: uni.EventSignature) -> None:
1566
1658
  """Generate DocIR for event signatures."""
@@ -1614,14 +1706,6 @@ class DocIRGenPass(UniPass):
1614
1706
  and isinstance(node.parent, uni.FString)
1615
1707
  )
1616
1708
 
1617
- if "\n" in node.value:
1618
- lines = node.value.split("\n")
1619
- parts: list[doc.DocType] = [self.text(lines[0])]
1620
- for line in lines[1:]:
1621
- parts.append(self.hard_line())
1622
- parts.append(self.text(line.lstrip()))
1623
- node.gen.doc_ir = self.group(self.concat(parts))
1624
- return
1625
1709
  if is_escaped_curly:
1626
1710
  node.gen.doc_ir = self.concat(
1627
1711
  [self.text(node.value), self.text(node.value)]
@@ -51,7 +51,7 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
51
51
 
52
52
  if isinstance(cur, doc.Text):
53
53
  remaining -= len(cur.text)
54
- if remaining < 0:
54
+ if remaining <= 0:
55
55
  return False
56
56
 
57
57
  elif isinstance(cur, doc.Line):
@@ -63,7 +63,7 @@ class JacFormatPass(Transform[uni.Module, uni.Module]):
63
63
  continue
64
64
  # regular soft line becomes a single space in flat mode
65
65
  remaining -= 1
66
- if remaining < 0:
66
+ if remaining <= 0:
67
67
  return False
68
68
 
69
69
  # --- Structural nodes (walk children in LIFO) ---
@@ -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,5 +1,5 @@
1
1
  #this file is part of formatter tests and is not meant to be run
2
- class SemTokManager {
2
+ class SemTokManager {
3
3
  """Initialize semantic token manager."""
4
4
  def init(self: SemTokManager, ir: uni.Module) -> None {
5
5
  self.aaaaastatic_sem_tokens:
@@ -23,25 +23,23 @@ def walrus_example() {
23
23
  with entry {
24
24
  c = (
25
25
  a()
26
- if 1 and
27
- isinstance(a, int) and
28
- isinstance(a, int) and
29
- isinstance(a, int) and
30
- isinstance(a, int) and
31
- isinstance(a, int)
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
32
  else (
33
33
  999
34
- if isinstance(a, int) and
35
- isinstance(a, int) and
36
- isinstance(a, int) and
37
- isinstance(4, bool)
34
+ if isinstance(a, int)
35
+ and isinstance(a, int)
36
+ and isinstance(a, int)
37
+ and isinstance(4, bool)
38
38
  else 7
39
39
  )
40
40
  );
41
- print(
42
- """This is a long
43
- line of code."""
44
- );
41
+ print("""This is a long
42
+ line of code.""");
45
43
  }
46
44
 
47
45
 
@@ -95,7 +93,7 @@ class ModuleManager {
95
93
 
96
94
 
97
95
  ## expr as item extra space issue
98
- with entry {
96
+ with entry {
99
97
  with open(f"Apple{apple}.txt") as f {
100
98
  # Fix syntax highlighting
101
99
  print(
@@ -106,7 +104,7 @@ class ModuleManager {
106
104
 
107
105
 
108
106
  def func_with_very_long_params(
109
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int,
107
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: int,
110
108
  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb: int,
111
109
  ) -> None {
112
110
  print(
@@ -132,9 +130,9 @@ def func_with_short_params(a: int, b: int) -> None {
132
130
 
133
131
  with entry {
134
132
  if (
135
- node_selected and
136
- node_selected.find_parent_of_type(uni.Archetype) or
137
- node_selected.find_parent_of_type(uni.ImplDef)
133
+ node_selected
134
+ and node_selected.find_parent_of_type(uni.Archetype)
135
+ or node_selected.find_parent_of_type(uni.ImplDef)
138
136
  ) {
139
137
  self_symbol = [
140
138
  lspt.CompletionItem(label='self', kind=lspt.CompletionItemKind.Variable)
@@ -143,27 +141,35 @@ with entry {
143
141
  self_symbol = [];
144
142
  }
145
143
  x = (
146
- 1222222222 and
147
- 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
144
+ 1222222222
145
+ and 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
148
146
  );
149
147
  a = 4 if True else 4;
150
148
  }
151
149
 
152
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
+
153
159
  """Return diagnostics."""
154
160
  def gen_diagnostics(
155
161
  from_path: str, errors: list[Alert], warnings: list[Alert]
156
162
  ) -> list[lspt.Diagnostic] {
157
163
  if (
158
- isinstance(node_selected, uni.Name) and
159
- node_selected.parent and
160
- isinstance(node_selected.parent, uni.ModulePath)
164
+ isinstance(node_selected, uni.Name)
165
+ and node_selected.parent
166
+ and isinstance(node_selected.parent, uni.ModulePath)
161
167
  ) {
162
168
  node_selected = node_selected.name_of;
163
169
  } elif (
164
- isinstance(node_selected, uni.Name) and
165
- node_selected.parent and
166
- isinstance(node_selected.parent, uni.ModulePath)
170
+ isinstance(node_selected, uni.Name)
171
+ and node_selected.parent
172
+ and isinstance(node_selected.parent, uni.ModulePath)
167
173
  ) {
168
174
  spec = node_selected.parent.parent.abs_path;
169
175
  }
@@ -171,8 +177,108 @@ def gen_diagnostics(
171
177
 
172
178
 
173
179
  @decorator
174
- def x() { }
180
+ def x() {
181
+ assert gg == 7;
182
+ }
175
183
 
176
184
 
177
185
  @decorator()
178
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
+ }
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import ast as py_ast
6
6
  import marshal
7
7
  import types
8
- from typing import Optional
8
+ from typing import Optional, TYPE_CHECKING
9
9
 
10
10
  import jaclang.compiler.unitree as uni
11
11
  from jaclang.compiler.parser import JacParser
@@ -32,11 +32,13 @@ from jaclang.compiler.passes.tool import (
32
32
  FuseCommentsPass,
33
33
  JacFormatPass,
34
34
  )
35
- from jaclang.compiler.type_system.type_evaluator import TypeEvaluator
36
35
  from jaclang.runtimelib.utils import read_file_with_encoding
37
36
  from jaclang.settings import settings
38
37
  from jaclang.utils.log import logging
39
38
 
39
+ if TYPE_CHECKING:
40
+ from jaclang.compiler.type_system.type_evaluator import TypeEvaluator
41
+
40
42
 
41
43
  logger = logging.getLogger(__name__)
42
44
 
@@ -71,6 +73,8 @@ class JacProgram:
71
73
 
72
74
  def get_type_evaluator(self) -> TypeEvaluator:
73
75
  """Return the type evaluator."""
76
+ from jaclang.compiler.type_system.type_evaluator import TypeEvaluator
77
+
74
78
  if not self.type_evaluator:
75
79
  self.type_evaluator = TypeEvaluator(program=self)
76
80
  return self.type_evaluator