jaclang 0.7.2__py3-none-any.whl → 0.7.6__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 (92) hide show
  1. jaclang/cli/cli.py +2 -2
  2. jaclang/compiler/absyntree.py +499 -294
  3. jaclang/compiler/codeloc.py +2 -2
  4. jaclang/compiler/constant.py +100 -2
  5. jaclang/compiler/jac.lark +27 -19
  6. jaclang/compiler/parser.py +119 -92
  7. jaclang/compiler/passes/main/access_modifier_pass.py +20 -12
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +28 -14
  9. jaclang/compiler/passes/main/def_use_pass.py +59 -40
  10. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +65 -43
  11. jaclang/compiler/passes/main/import_pass.py +8 -6
  12. jaclang/compiler/passes/main/pyast_gen_pass.py +97 -42
  13. jaclang/compiler/passes/main/pyast_load_pass.py +47 -12
  14. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +19 -10
  15. jaclang/compiler/passes/main/registry_pass.py +6 -6
  16. jaclang/compiler/passes/main/sub_node_tab_pass.py +0 -5
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +43 -235
  18. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +21 -4
  19. jaclang/compiler/passes/main/tests/test_def_use_pass.py +5 -10
  20. jaclang/compiler/passes/main/type_check_pass.py +2 -1
  21. jaclang/compiler/passes/tool/jac_formatter_pass.py +30 -9
  22. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +16 -0
  23. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +16 -0
  24. jaclang/compiler/passes/tool/tests/fixtures/genai/essay_review.jac +1 -1
  25. jaclang/compiler/passes/tool/tests/fixtures/genai/expert_answer.jac +1 -1
  26. jaclang/compiler/passes/tool/tests/fixtures/genai/joke_gen.jac +1 -1
  27. jaclang/compiler/passes/tool/tests/fixtures/genai/odd_word_out.jac +1 -1
  28. jaclang/compiler/passes/tool/tests/fixtures/genai/personality_finder.jac +1 -1
  29. jaclang/compiler/passes/tool/tests/fixtures/genai/text_to_type.jac +1 -1
  30. jaclang/compiler/passes/tool/tests/fixtures/genai/translator.jac +1 -1
  31. jaclang/compiler/passes/tool/tests/fixtures/genai/wikipedia.jac +1 -1
  32. jaclang/compiler/passes/transform.py +2 -4
  33. jaclang/{core/registry.py → compiler/semtable.py} +1 -3
  34. jaclang/compiler/symtable.py +142 -101
  35. jaclang/compiler/tests/test_parser.py +2 -2
  36. jaclang/core/aott.py +15 -11
  37. jaclang/core/{construct.py → architype.py} +25 -240
  38. jaclang/core/constructs.py +44 -0
  39. jaclang/core/context.py +157 -0
  40. jaclang/core/importer.py +18 -9
  41. jaclang/core/memory.py +99 -0
  42. jaclang/core/test.py +90 -0
  43. jaclang/core/utils.py +2 -2
  44. jaclang/langserve/engine.py +127 -50
  45. jaclang/langserve/server.py +34 -61
  46. jaclang/langserve/tests/fixtures/base_module_structure.jac +28 -0
  47. jaclang/langserve/tests/fixtures/circle.jac +16 -12
  48. jaclang/langserve/tests/fixtures/circle_err.jac +3 -3
  49. jaclang/langserve/tests/fixtures/circle_pure.test.jac +15 -0
  50. jaclang/langserve/tests/fixtures/import_include_statements.jac +6 -0
  51. jaclang/langserve/tests/fixtures/py_import.py +26 -0
  52. jaclang/langserve/tests/test_server.py +93 -18
  53. jaclang/langserve/utils.py +124 -10
  54. jaclang/plugin/builtin.py +1 -1
  55. jaclang/plugin/default.py +23 -9
  56. jaclang/plugin/feature.py +25 -7
  57. jaclang/plugin/spec.py +18 -20
  58. jaclang/settings.py +3 -0
  59. jaclang/tests/fixtures/abc.jac +16 -12
  60. jaclang/tests/fixtures/aott_raise.jac +1 -1
  61. jaclang/tests/fixtures/byllmissue.jac +9 -0
  62. jaclang/tests/fixtures/edgetypeissue.jac +10 -0
  63. jaclang/tests/fixtures/hello.jac +1 -1
  64. jaclang/tests/fixtures/impl_match_confused.impl.jac +1 -0
  65. jaclang/tests/fixtures/impl_match_confused.jac +5 -0
  66. jaclang/tests/fixtures/maxfail_run_test.jac +17 -5
  67. jaclang/tests/fixtures/run_test.jac +17 -5
  68. jaclang/tests/fixtures/with_llm_function.jac +1 -1
  69. jaclang/tests/fixtures/with_llm_lower.jac +1 -1
  70. jaclang/tests/fixtures/with_llm_method.jac +1 -1
  71. jaclang/tests/fixtures/with_llm_type.jac +1 -1
  72. jaclang/tests/fixtures/with_llm_vision.jac +1 -1
  73. jaclang/tests/test_bugs.py +19 -0
  74. jaclang/tests/test_cli.py +1 -1
  75. jaclang/tests/test_language.py +161 -96
  76. jaclang/tests/test_reference.py +1 -1
  77. jaclang/utils/lang_tools.py +5 -4
  78. jaclang/utils/test.py +2 -1
  79. jaclang/utils/treeprinter.py +22 -8
  80. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/METADATA +1 -1
  81. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/RECORD +83 -80
  82. jaclang/core/llms/__init__.py +0 -20
  83. jaclang/core/llms/anthropic.py +0 -90
  84. jaclang/core/llms/base.py +0 -206
  85. jaclang/core/llms/groq.py +0 -70
  86. jaclang/core/llms/huggingface.py +0 -76
  87. jaclang/core/llms/ollama.py +0 -81
  88. jaclang/core/llms/openai.py +0 -65
  89. jaclang/core/llms/togetherai.py +0 -63
  90. jaclang/core/llms/utils.py +0 -9
  91. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/WHEEL +0 -0
  92. {jaclang-0.7.2.dist-info → jaclang-0.7.6.dist-info}/entry_points.txt +0 -0
@@ -3,25 +3,38 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import ast as ast3
6
+ import builtins
6
7
  import os
7
8
  from hashlib import md5
8
9
  from types import EllipsisType
9
- from typing import Any, Callable, Generic, Optional, Sequence, Type, TypeVar
10
+ from typing import (
11
+ Any,
12
+ Callable,
13
+ Generic,
14
+ Optional,
15
+ Sequence,
16
+ TYPE_CHECKING,
17
+ Type,
18
+ TypeVar,
19
+ )
20
+
10
21
 
11
22
  from jaclang.compiler import TOKEN_MAP
12
23
  from jaclang.compiler.codeloc import CodeGenTarget, CodeLocInfo
13
- from jaclang.compiler.constant import Constants as Con, EdgeDir
14
- from jaclang.compiler.constant import DELIM_MAP, Tokens as Tok
15
- from jaclang.compiler.symtable import (
16
- Symbol,
17
- SymbolAccess,
18
- SymbolInfo,
19
- SymbolTable,
24
+ from jaclang.compiler.constant import (
25
+ Constants as Con,
26
+ EdgeDir,
27
+ JacSemTokenModifier as SemTokMod,
28
+ JacSemTokenType as SemTokType,
20
29
  SymbolType,
21
30
  )
22
- from jaclang.core.registry import SemRegistry
31
+ from jaclang.compiler.constant import DELIM_MAP, SymbolAccess, Tokens as Tok
32
+ from jaclang.compiler.semtable import SemRegistry
23
33
  from jaclang.utils.treeprinter import dotgen_ast_tree, print_ast_tree
24
34
 
35
+ if TYPE_CHECKING:
36
+ from jaclang.compiler.symtable import Symbol, SymbolTable
37
+
25
38
 
26
39
  class AstNode:
27
40
  """Abstract syntax tree node for Jac."""
@@ -30,12 +43,35 @@ class AstNode:
30
43
  """Initialize ast."""
31
44
  self.parent: Optional[AstNode] = None
32
45
  self.kid: list[AstNode] = [x.set_parent(self) for x in kid]
33
- self.sym_tab: Optional[SymbolTable] = None
46
+ self._sym_tab: Optional[SymbolTable] = None
34
47
  self._sub_node_tab: dict[type, list[AstNode]] = {}
48
+ self._in_mod_nodes: list[AstNode] = []
35
49
  self.gen: CodeGenTarget = CodeGenTarget()
36
50
  self.meta: dict[str, str] = {}
37
51
  self.loc: CodeLocInfo = CodeLocInfo(*self.resolve_tok_range())
38
52
 
53
+ @property
54
+ def sym_tab(self) -> SymbolTable:
55
+ """Get symbol table."""
56
+ # sym_tab should never be accessed without being set in codebase
57
+ if not self._sym_tab:
58
+ import traceback
59
+
60
+ if self.parent:
61
+ print(f"Parent: {self.parent.pp()}")
62
+ print("Node: ", self.pp())
63
+ stack_trace = traceback.format_stack()
64
+ print("".join(stack_trace))
65
+ raise ValueError(
66
+ f"Symbol table not set for {type(self).__name__}. Impossible."
67
+ )
68
+ return self._sym_tab
69
+
70
+ @sym_tab.setter
71
+ def sym_tab(self, sym_tab: SymbolTable) -> None:
72
+ """Set symbol table."""
73
+ self._sym_tab = sym_tab
74
+
39
75
  def add_kids_left(
40
76
  self, nodes: Sequence[AstNode], pos_update: bool = True
41
77
  ) -> AstNode:
@@ -58,6 +94,17 @@ class AstNode:
58
94
  self.loc.update_last_token(self.kid[-1].loc.last_tok)
59
95
  return self
60
96
 
97
+ def insert_kids_at_pos(
98
+ self, nodes: Sequence[AstNode], pos: int, pos_update: bool = True
99
+ ) -> AstNode:
100
+ """Insert kids at position."""
101
+ self.kid = [*self.kid[:pos], *nodes, *self.kid[pos:]]
102
+ if pos_update:
103
+ for i in nodes:
104
+ i.parent = self
105
+ self.loc.update_token_range(*self.resolve_tok_range())
106
+ return self
107
+
61
108
  def set_kids(self, nodes: Sequence[AstNode]) -> AstNode:
62
109
  """Set kids."""
63
110
  self.kid = [*nodes]
@@ -101,6 +148,7 @@ class AstNode:
101
148
  col_start=self.loc.col_start,
102
149
  col_end=0,
103
150
  line=self.loc.first_line,
151
+ end_line=self.loc.last_line,
104
152
  pos_start=0,
105
153
  pos_end=0,
106
154
  )
@@ -176,17 +224,56 @@ class AstSymbolNode(AstNode):
176
224
  """Nodes that have link to a symbol in symbol table."""
177
225
 
178
226
  def __init__(
179
- self, sym_name: str, sym_name_node: AstNode, sym_type: SymbolType
227
+ self, sym_name: str, name_spec: NameAtom, sym_category: SymbolType
180
228
  ) -> None:
181
229
  """Initialize ast."""
182
- self.sym_link: Optional[Symbol] = None
183
- self.sym_name: str = sym_name
184
- self.sym_name_node = sym_name_node
185
- if isinstance(self.sym_name_node, NameSpec):
186
- self.sym_name_node.name_of = self
187
- self.sym_type: SymbolType = sym_type
188
- self.sym_info: SymbolInfo = SymbolInfo()
189
- self.py_ctx_func: Type[ast3.AST] = ast3.Load
230
+ self.name_spec = name_spec
231
+ self.name_spec.name_of = self
232
+ self.name_spec._sym_name = sym_name
233
+ self.name_spec._sym_category = sym_category
234
+
235
+ @property
236
+ def sym(self) -> Optional[Symbol]:
237
+ """Get symbol."""
238
+ return self.name_spec.sym
239
+
240
+ @property
241
+ def sym_name(self) -> str:
242
+ """Get symbol name."""
243
+ return self.name_spec.sym_name
244
+
245
+ @property
246
+ def sym_category(self) -> SymbolType:
247
+ """Get symbol category."""
248
+ return self.name_spec.sym_category
249
+
250
+ @property
251
+ def py_ctx_func(self) -> Type[ast3.AST]:
252
+ """Get python context function."""
253
+ return self.name_spec.py_ctx_func
254
+
255
+ @property
256
+ def sym_type(self) -> str:
257
+ """Get symbol type."""
258
+ return self.name_spec.sym_type
259
+
260
+ @property
261
+ def type_sym_tab(self) -> Optional[SymbolTable]:
262
+ """Get type symbol table."""
263
+ return self.name_spec.type_sym_tab
264
+
265
+
266
+ class AstSymbolStubNode(AstSymbolNode):
267
+ """Nodes that have link to a symbol in symbol table."""
268
+
269
+ def __init__(self, sym_type: SymbolType) -> None:
270
+ """Initialize ast."""
271
+ AstSymbolNode.__init__(
272
+ self,
273
+ sym_name=f"[{self.__class__.__name__}]",
274
+ name_spec=Name.gen_stub_from_node(self, f"[{self.__class__.__name__}]"),
275
+ sym_category=sym_type,
276
+ )
190
277
 
191
278
 
192
279
  class AstAccessNode(AstNode):
@@ -261,7 +348,31 @@ class WalkerStmtOnlyNode(AstNode):
261
348
  self.from_walker: bool = False
262
349
 
263
350
 
264
- class AstImplOnlyNode(AstNode):
351
+ class Expr(AstNode):
352
+ """Expr node type for Jac Ast."""
353
+
354
+
355
+ class AtomExpr(Expr, AstSymbolStubNode):
356
+ """AtomExpr node type for Jac Ast."""
357
+
358
+
359
+ class ElementStmt(AstDocNode):
360
+ """ElementStmt node type for Jac Ast."""
361
+
362
+
363
+ class ArchBlockStmt(AstNode):
364
+ """ArchBlockStmt node type for Jac Ast."""
365
+
366
+
367
+ class EnumBlockStmt(AstNode):
368
+ """EnumBlockStmt node type for Jac Ast."""
369
+
370
+
371
+ class CodeBlockStmt(AstNode):
372
+ """CodeBlockStmt node type for Jac Ast."""
373
+
374
+
375
+ class AstImplOnlyNode(CodeBlockStmt, ElementStmt, AstSymbolNode):
265
376
  """ImplOnly node type for Jac Ast."""
266
377
 
267
378
  def __init__(
@@ -271,6 +382,39 @@ class AstImplOnlyNode(AstNode):
271
382
  self.target = target
272
383
  self.body = body
273
384
  self.decl_link = decl_link
385
+ AstSymbolNode.__init__(
386
+ self,
387
+ sym_name=self.target.py_resolve_name(),
388
+ name_spec=self.create_impl_name_node(),
389
+ sym_category=SymbolType.IMPL,
390
+ )
391
+
392
+ @property
393
+ def sym_tab(self) -> SymbolTable:
394
+ """Get symbol table."""
395
+ return super().sym_tab
396
+
397
+ @sym_tab.setter
398
+ def sym_tab(self, sym_tab: SymbolTable) -> None:
399
+ """Set symbol table."""
400
+ self._sym_tab = sym_tab
401
+ self.name_spec._sym_tab = sym_tab
402
+
403
+ def create_impl_name_node(self) -> Name:
404
+ """Create impl name."""
405
+ ret = Name(
406
+ file_path=self.target.archs[-1].loc.mod_path,
407
+ name=Tok.NAME.value,
408
+ value=self.target.py_resolve_name(),
409
+ col_start=self.target.archs[0].loc.col_start,
410
+ col_end=self.target.archs[-1].loc.col_end,
411
+ line=self.target.archs[0].loc.first_line,
412
+ end_line=self.target.archs[-1].loc.last_line,
413
+ pos_start=self.target.archs[0].loc.pos_start,
414
+ pos_end=self.target.archs[-1].loc.pos_end,
415
+ )
416
+ ret.name_of = self
417
+ return ret
274
418
 
275
419
 
276
420
  class AstImplNeedingNode(AstSymbolNode, Generic[T]):
@@ -286,36 +430,109 @@ class AstImplNeedingNode(AstSymbolNode, Generic[T]):
286
430
  return self.body is None
287
431
 
288
432
 
289
- class Expr(AstNode):
290
- """Expr node type for Jac Ast."""
433
+ class NameAtom(AtomExpr, EnumBlockStmt):
434
+ """NameSpec node type for Jac Ast."""
291
435
 
436
+ def __init__(self) -> None:
437
+ """Initialize name spec node."""
438
+ self.name_of: AstSymbolNode = self
439
+ self._sym: Optional[Symbol] = None
440
+ self._sym_name: str = ""
441
+ self._sym_category: SymbolType = SymbolType.UNKNOWN
442
+ self._py_ctx_func: Type[ast3.AST] = ast3.Load
443
+ self._sym_type: str = "NoType"
444
+ self._type_sym_tab: Optional[SymbolTable] = None
292
445
 
293
- class AtomExpr(Expr, AstSymbolNode):
294
- """AtomExpr node type for Jac Ast."""
446
+ @property
447
+ def sym(self) -> Optional[Symbol]:
448
+ """Get symbol."""
449
+ return self._sym
295
450
 
451
+ @sym.setter
452
+ def sym(self, sym: Symbol) -> None:
453
+ """Set symbol."""
454
+ self._sym = sym
296
455
 
297
- class ElementStmt(AstDocNode):
298
- """ElementStmt node type for Jac Ast."""
456
+ @property
457
+ def sym_name(self) -> str:
458
+ """Get symbol name."""
459
+ return self._sym_name
299
460
 
461
+ @property
462
+ def sym_category(self) -> SymbolType:
463
+ """Get symbol category."""
464
+ return self._sym_category
300
465
 
301
- class ArchBlockStmt(AstNode):
302
- """ArchBlockStmt node type for Jac Ast."""
466
+ @property
467
+ def clean_type(self) -> str:
468
+ """Get clean type."""
469
+ ret_type = self.sym_type.replace("builtins.", "").replace("NoType", "")
470
+ return ret_type
303
471
 
472
+ @property
473
+ def py_ctx_func(self) -> Type[ast3.AST]:
474
+ """Get python context function."""
475
+ return self._py_ctx_func
304
476
 
305
- class EnumBlockStmt(AstNode):
306
- """EnumBlockStmt node type for Jac Ast."""
477
+ @py_ctx_func.setter
478
+ def py_ctx_func(self, py_ctx_func: Type[ast3.AST]) -> None:
479
+ """Set python context function."""
480
+ self._py_ctx_func = py_ctx_func
307
481
 
482
+ @property
483
+ def sym_type(self) -> str:
484
+ """Get symbol type."""
485
+ return self._sym_type
308
486
 
309
- class CodeBlockStmt(AstNode):
310
- """CodeBlockStmt node type for Jac Ast."""
487
+ @sym_type.setter
488
+ def sym_type(self, sym_type: str) -> None:
489
+ """Set symbol type."""
490
+ self._sym_type = sym_type
311
491
 
492
+ @property
493
+ def type_sym_tab(self) -> Optional[SymbolTable]:
494
+ """Get type symbol table."""
495
+ return self._type_sym_tab
312
496
 
313
- class NameSpec(AtomExpr, EnumBlockStmt):
314
- """NameSpec node type for Jac Ast."""
497
+ @type_sym_tab.setter
498
+ def type_sym_tab(self, type_sym_tab: SymbolTable) -> None:
499
+ """Set type symbol table."""
500
+ self._type_sym_tab = type_sym_tab
315
501
 
316
- def __init__(self) -> None:
317
- """Initialize name spec node."""
318
- self.name_of: AstSymbolNode = self
502
+ @property
503
+ def sem_token(self) -> Optional[tuple[SemTokType, SemTokMod]]:
504
+ """Resolve semantic token."""
505
+ if isinstance(self.name_of, BuiltinType):
506
+ return SemTokType.CLASS, SemTokMod.DECLARATION
507
+ name_of = (
508
+ self.sym.decl.name_of
509
+ if self.sym and not isinstance(self.sym.decl.name_of, Name)
510
+ else self.name_of
511
+ )
512
+ if isinstance(name_of, ModulePath):
513
+ return SemTokType.NAMESPACE, SemTokMod.DEFINITION
514
+ if isinstance(name_of, Architype):
515
+ return SemTokType.CLASS, SemTokMod.DECLARATION
516
+ if isinstance(name_of, Enum):
517
+ return SemTokType.ENUM, SemTokMod.DECLARATION
518
+ if isinstance(name_of, Ability) and name_of.is_method:
519
+ return SemTokType.METHOD, SemTokMod.DECLARATION
520
+ if isinstance(name_of, (Ability, Test)):
521
+ return SemTokType.FUNCTION, SemTokMod.DECLARATION
522
+ if isinstance(name_of, ParamVar):
523
+ return SemTokType.PARAMETER, SemTokMod.DECLARATION
524
+ if self.sym and self.sym_name.isupper():
525
+ return SemTokType.VARIABLE, SemTokMod.READONLY
526
+ if (
527
+ self.sym
528
+ and self.sym.decl.name_of == self.sym.decl
529
+ and self.sym_name in dir(builtins)
530
+ and callable(getattr(builtins, self.sym_name))
531
+ ):
532
+ return SemTokType.FUNCTION, SemTokMod.DEFINITION
533
+ if self.sym:
534
+ return SemTokType.PROPERTY, SemTokMod.DEFINITION
535
+ return None
319
536
 
320
537
 
321
538
  class ArchSpec(ElementStmt, CodeBlockStmt, AstSymbolNode, AstDocNode, AstSemStrNode):
@@ -424,7 +641,10 @@ class Module(AstDocNode):
424
641
  @property
425
642
  def annexable_by(self) -> Optional[str]:
426
643
  """Get annexable by."""
427
- if not self.stub_only and self.loc.mod_path.endswith("impl.jac"):
644
+ if not self.stub_only and (
645
+ self.loc.mod_path.endswith("impl.jac")
646
+ or self.loc.mod_path.endswith("test.jac")
647
+ ):
428
648
  head_mod_name = self.name.split(".")[0]
429
649
  potential_path = os.path.join(
430
650
  os.path.dirname(self.loc.mod_path),
@@ -432,7 +652,8 @@ class Module(AstDocNode):
432
652
  )
433
653
  if os.path.exists(potential_path):
434
654
  return potential_path
435
- if os.path.split(os.path.dirname(self.loc.mod_path))[-1].endswith(".impl"):
655
+ annex_dir = os.path.split(os.path.dirname(self.loc.mod_path))[-1]
656
+ if annex_dir.endswith(".impl") or annex_dir.endswith(".test"):
436
657
  head_mod_name = os.path.split(os.path.dirname(self.loc.mod_path))[
437
658
  -1
438
659
  ].split(".")[0]
@@ -522,26 +743,31 @@ class Test(AstSymbolNode, ElementStmt):
522
743
  if isinstance(name, Name)
523
744
  else Name(
524
745
  file_path=name.file_path,
525
- name="NAME",
526
- value=f"test_t{Test.TEST_COUNT}",
746
+ name=Tok.NAME.value,
747
+ value=f"_jac_gen_{Test.TEST_COUNT}",
527
748
  col_start=name.loc.col_start,
528
749
  col_end=name.loc.col_end,
529
750
  line=name.loc.first_line,
751
+ end_line=name.loc.last_line,
530
752
  pos_start=name.pos_start,
531
753
  pos_end=name.pos_end,
532
754
  )
533
755
  )
534
756
  self.name.parent = self
535
- # kid[0] = self.name # Index is 0 since Doc string is inserted after init
757
+ self.name._sym_name = (
758
+ f"test_{self.name.value}"
759
+ if not self.name.value.startswith("test_")
760
+ else self.name.value
761
+ )
536
762
  self.body = body
537
763
  AstNode.__init__(self, kid=kid)
538
764
  if self.name not in self.kid:
539
- self.add_kids_left([self.name], pos_update=False)
765
+ self.insert_kids_at_pos([self.name], pos=1, pos_update=False)
540
766
  AstSymbolNode.__init__(
541
767
  self,
542
768
  sym_name=self.name.sym_name,
543
- sym_name_node=self.name,
544
- sym_type=SymbolType.TEST,
769
+ name_spec=self.name,
770
+ sym_category=SymbolType.TEST,
545
771
  )
546
772
  AstDocNode.__init__(self, doc=doc)
547
773
 
@@ -682,20 +908,22 @@ class ModulePath(AstSymbolNode):
682
908
  level: int,
683
909
  alias: Optional[Name],
684
910
  kid: Sequence[AstNode],
685
- sub_module: Optional[Module] = None,
686
911
  ) -> None:
687
912
  """Initialize module path node."""
688
913
  self.path = path
689
914
  self.level = level
690
915
  self.alias = alias
691
- self.sub_module = sub_module
916
+ self.sub_module: Optional[Module] = None
692
917
 
918
+ name_spec = alias if alias else path[0] if path else None
919
+ if not isinstance(name_spec, Name):
920
+ raise ValueError("ModulePath should have a name spec. Impossible.")
693
921
  AstNode.__init__(self, kid=kid)
694
922
  AstSymbolNode.__init__(
695
923
  self,
696
- sym_name=alias.sym_name if alias else self.path_str,
697
- sym_name_node=alias if alias else self,
698
- sym_type=SymbolType.MODULE,
924
+ sym_name=name_spec.sym_name,
925
+ name_spec=name_spec,
926
+ sym_category=SymbolType.MODULE,
699
927
  )
700
928
 
701
929
  @property
@@ -738,20 +966,37 @@ class ModuleItem(AstSymbolNode):
738
966
  name: Name,
739
967
  alias: Optional[Name],
740
968
  kid: Sequence[AstNode],
741
- sub_module: Optional[Module] = None,
742
969
  ) -> None:
743
970
  """Initialize module item node."""
744
971
  self.name = name
745
972
  self.alias = alias
746
- self.sub_module = sub_module
973
+ self.sub_module: Optional[Module] = None
747
974
  AstNode.__init__(self, kid=kid)
748
975
  AstSymbolNode.__init__(
749
976
  self,
750
977
  sym_name=alias.sym_name if alias else name.sym_name,
751
- sym_name_node=alias if alias else name,
752
- sym_type=SymbolType.MOD_VAR,
978
+ name_spec=alias if alias else name,
979
+ sym_category=SymbolType.MOD_VAR,
753
980
  )
754
981
 
982
+ @property
983
+ def from_parent(self) -> Import:
984
+ """Get import parent."""
985
+ if (
986
+ not self.parent
987
+ or not self.parent.parent
988
+ or not isinstance(self.parent.parent, Import)
989
+ ):
990
+ raise ValueError("Import parent not found. Not Possible.")
991
+ return self.parent.parent
992
+
993
+ @property
994
+ def from_mod_path(self) -> ModulePath:
995
+ """Get relevant module path."""
996
+ if not self.from_parent.from_loc:
997
+ raise ValueError("Module items should have module path. Not Possible.")
998
+ return self.from_parent.from_loc
999
+
755
1000
  def normalize(self, deep: bool = False) -> bool:
756
1001
  """Normalize module item node."""
757
1002
  res = True
@@ -789,8 +1034,8 @@ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt, AstImplNeedingNode):
789
1034
  AstSymbolNode.__init__(
790
1035
  self,
791
1036
  sym_name=name.value,
792
- sym_name_node=name,
793
- sym_type=(
1037
+ name_spec=name,
1038
+ sym_category=(
794
1039
  SymbolType.OBJECT_ARCH
795
1040
  if arch_type.name == Tok.KW_OBJECT
796
1041
  else (
@@ -865,7 +1110,7 @@ class Architype(ArchSpec, AstAccessNode, ArchBlockStmt, AstImplNeedingNode):
865
1110
  return res
866
1111
 
867
1112
 
868
- class ArchDef(ArchSpec, AstImplOnlyNode):
1113
+ class ArchDef(AstImplOnlyNode):
869
1114
  """ArchDef node type for Jac Ast."""
870
1115
 
871
1116
  def __init__(
@@ -879,14 +1124,7 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
879
1124
  ) -> None:
880
1125
  """Initialize arch def node."""
881
1126
  AstNode.__init__(self, kid=kid)
882
- AstSymbolNode.__init__(
883
- self,
884
- sym_name=target.py_resolve_name(),
885
- sym_name_node=target,
886
- sym_type=SymbolType.IMPL,
887
- )
888
1127
  AstDocNode.__init__(self, doc=doc)
889
- ArchSpec.__init__(self, decorators=decorators)
890
1128
  AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
891
1129
 
892
1130
  def normalize(self, deep: bool = False) -> bool:
@@ -896,7 +1134,6 @@ class ArchDef(ArchSpec, AstImplOnlyNode):
896
1134
  res = self.target.normalize(deep)
897
1135
  res = res and self.body.normalize(deep)
898
1136
  res = res and self.doc.normalize(deep) if self.doc else res
899
- res = res and self.decorators.normalize(deep) if self.decorators else res
900
1137
  new_kid: list[AstNode] = []
901
1138
  if self.doc:
902
1139
  new_kid.append(self.doc)
@@ -927,8 +1164,8 @@ class Enum(ArchSpec, AstAccessNode, AstImplNeedingNode, ArchBlockStmt):
927
1164
  AstSymbolNode.__init__(
928
1165
  self,
929
1166
  sym_name=name.value,
930
- sym_name_node=name,
931
- sym_type=SymbolType.ENUM_ARCH,
1167
+ name_spec=name,
1168
+ sym_category=SymbolType.ENUM_ARCH,
932
1169
  )
933
1170
  AstImplNeedingNode.__init__(self, body=body)
934
1171
  AstAccessNode.__init__(self, access=access)
@@ -975,7 +1212,7 @@ class Enum(ArchSpec, AstAccessNode, AstImplNeedingNode, ArchBlockStmt):
975
1212
  return res
976
1213
 
977
1214
 
978
- class EnumDef(ArchSpec, AstImplOnlyNode):
1215
+ class EnumDef(AstImplOnlyNode):
979
1216
  """EnumDef node type for Jac Ast."""
980
1217
 
981
1218
  def __init__(
@@ -989,14 +1226,7 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
989
1226
  ) -> None:
990
1227
  """Initialize arch def node."""
991
1228
  AstNode.__init__(self, kid=kid)
992
- AstSymbolNode.__init__(
993
- self,
994
- sym_name=target.py_resolve_name(),
995
- sym_name_node=target,
996
- sym_type=SymbolType.IMPL,
997
- )
998
1229
  AstDocNode.__init__(self, doc=doc)
999
- ArchSpec.__init__(self, decorators=decorators)
1000
1230
  AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
1001
1231
 
1002
1232
  def normalize(self, deep: bool = False) -> bool:
@@ -1006,7 +1236,6 @@ class EnumDef(ArchSpec, AstImplOnlyNode):
1006
1236
  res = self.target.normalize(deep)
1007
1237
  res = res and self.body.normalize(deep)
1008
1238
  res = res and self.doc.normalize(deep) if self.doc else res
1009
- res = res and self.decorators.normalize(deep) if self.decorators else res
1010
1239
  new_kid: list[AstNode] = []
1011
1240
  if self.doc:
1012
1241
  new_kid.append(self.doc)
@@ -1023,6 +1252,7 @@ class Ability(
1023
1252
  ElementStmt,
1024
1253
  AstAsyncNode,
1025
1254
  ArchBlockStmt,
1255
+ EnumBlockStmt,
1026
1256
  CodeBlockStmt,
1027
1257
  AstSemStrNode,
1028
1258
  AstImplNeedingNode,
@@ -1031,7 +1261,7 @@ class Ability(
1031
1261
 
1032
1262
  def __init__(
1033
1263
  self,
1034
- name_ref: NameSpec,
1264
+ name_ref: NameAtom,
1035
1265
  is_async: bool,
1036
1266
  is_override: bool,
1037
1267
  is_static: bool,
@@ -1057,17 +1287,28 @@ class Ability(
1057
1287
  AstSymbolNode.__init__(
1058
1288
  self,
1059
1289
  sym_name=self.py_resolve_name(),
1060
- sym_name_node=name_ref,
1061
- sym_type=SymbolType.ABILITY,
1290
+ name_spec=name_ref,
1291
+ sym_category=SymbolType.ABILITY,
1062
1292
  )
1063
1293
  AstAccessNode.__init__(self, access=access)
1064
1294
  AstDocNode.__init__(self, doc=doc)
1065
1295
  AstAsyncNode.__init__(self, is_async=is_async)
1066
1296
 
1067
1297
  @property
1068
- def is_func(self) -> bool:
1298
+ def is_method(self) -> bool:
1069
1299
  """Check if is func."""
1070
- return isinstance(self.body, FuncSignature)
1300
+ return self.signature.is_method
1301
+
1302
+ @property
1303
+ def owner_method(self) -> Optional[Architype | Enum]:
1304
+ """Check if is owner method."""
1305
+ return (
1306
+ self.parent.parent
1307
+ if self.parent
1308
+ and self.parent.parent
1309
+ and isinstance(self.parent.parent, (Architype, Enum))
1310
+ else None
1311
+ )
1071
1312
 
1072
1313
  @property
1073
1314
  def is_genai_ability(self) -> bool:
@@ -1132,7 +1373,7 @@ class Ability(
1132
1373
  return res
1133
1374
 
1134
1375
 
1135
- class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
1376
+ class AbilityDef(AstImplOnlyNode):
1136
1377
  """AbilityDef node type for Jac Ast."""
1137
1378
 
1138
1379
  def __init__(
@@ -1149,12 +1390,6 @@ class AbilityDef(AstSymbolNode, ElementStmt, AstImplOnlyNode, CodeBlockStmt):
1149
1390
  self.signature = signature
1150
1391
  self.decorators = decorators
1151
1392
  AstNode.__init__(self, kid=kid)
1152
- AstSymbolNode.__init__(
1153
- self,
1154
- sym_name=target.py_resolve_name(),
1155
- sym_name_node=target,
1156
- sym_type=SymbolType.IMPL,
1157
- )
1158
1393
  AstDocNode.__init__(self, doc=doc)
1159
1394
  AstImplOnlyNode.__init__(self, target=target, body=body, decl_link=decl_link)
1160
1395
 
@@ -1192,6 +1427,7 @@ class FuncSignature(AstSemStrNode):
1192
1427
  """Initialize method signature node."""
1193
1428
  self.params = params
1194
1429
  self.return_type = return_type
1430
+ self.is_method = False
1195
1431
  AstNode.__init__(self, kid=kid)
1196
1432
  AstSemStrNode.__init__(self, semstr=semstr)
1197
1433
 
@@ -1240,6 +1476,7 @@ class EventSignature(AstSemStrNode):
1240
1476
  self.event = event
1241
1477
  self.arch_tag_info = arch_tag_info
1242
1478
  self.return_type = return_type
1479
+ self.is_method = False
1243
1480
  AstNode.__init__(self, kid=kid)
1244
1481
  AstSemStrNode.__init__(self, semstr=semstr)
1245
1482
 
@@ -1298,11 +1535,11 @@ class ArchRefChain(AstNode):
1298
1535
  def get_tag(x: ArchRef) -> str:
1299
1536
  return (
1300
1537
  "en"
1301
- if x.arch.value == "enum"
1302
- else "cls" if x.arch.value == "class" else x.arch.value[1]
1538
+ if x.arch_type.value == "enum"
1539
+ else "cls" if x.arch_type.value == "class" else x.arch_type.value[1]
1303
1540
  )
1304
1541
 
1305
- return ".".join([f"({get_tag(x)}){x.py_resolve_name()}" for x in self.archs])
1542
+ return ".".join([f"({get_tag(x)}){x.sym_name}" for x in self.archs])
1306
1543
 
1307
1544
  def flat_name(self) -> str:
1308
1545
  """Resolve name for python gen."""
@@ -1331,8 +1568,8 @@ class ParamVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
1331
1568
  AstSymbolNode.__init__(
1332
1569
  self,
1333
1570
  sym_name=name.value,
1334
- sym_name_node=name,
1335
- sym_type=SymbolType.VAR,
1571
+ name_spec=name,
1572
+ sym_category=SymbolType.VAR,
1336
1573
  )
1337
1574
  AstTypedVarNode.__init__(self, type_tag=type_tag)
1338
1575
  AstSemStrNode.__init__(self, semstr=semstr)
@@ -1427,8 +1664,8 @@ class HasVar(AstSymbolNode, AstTypedVarNode, AstSemStrNode):
1427
1664
  AstSymbolNode.__init__(
1428
1665
  self,
1429
1666
  sym_name=name.value,
1430
- sym_name_node=name,
1431
- sym_type=SymbolType.HAS_VAR,
1667
+ name_spec=name,
1668
+ sym_category=SymbolType.HAS_VAR,
1432
1669
  )
1433
1670
  AstTypedVarNode.__init__(self, type_tag=type_tag)
1434
1671
  AstSemStrNode.__init__(self, semstr=semstr)
@@ -1943,6 +2180,32 @@ class AssertStmt(CodeBlockStmt):
1943
2180
  return res
1944
2181
 
1945
2182
 
2183
+ class CheckStmt(CodeBlockStmt):
2184
+ """DeleteStmt node type for Jac Ast."""
2185
+
2186
+ def __init__(
2187
+ self,
2188
+ target: Expr,
2189
+ kid: Sequence[AstNode],
2190
+ ) -> None:
2191
+ """Initialize delete statement node."""
2192
+ self.target = target
2193
+ AstNode.__init__(self, kid=kid)
2194
+
2195
+ def normalize(self, deep: bool = False) -> bool:
2196
+ """Normalize delete statement node."""
2197
+ res = True
2198
+ if deep:
2199
+ res = self.target.normalize(deep)
2200
+ new_kid: list[AstNode] = [
2201
+ self.gen_token(Tok.KW_CHECK),
2202
+ self.target,
2203
+ self.gen_token(Tok.SEMI),
2204
+ ]
2205
+ self.set_kids(nodes=new_kid)
2206
+ return res
2207
+
2208
+
1946
2209
  class CtrlStmt(CodeBlockStmt):
1947
2210
  """CtrlStmt node type for Jac Ast."""
1948
2211
 
@@ -2192,7 +2455,7 @@ class GlobalStmt(CodeBlockStmt):
2192
2455
 
2193
2456
  def __init__(
2194
2457
  self,
2195
- target: SubNodeList[NameSpec],
2458
+ target: SubNodeList[NameAtom],
2196
2459
  kid: Sequence[AstNode],
2197
2460
  ) -> None:
2198
2461
  """Initialize global statement node."""
@@ -2485,12 +2748,7 @@ class MultiString(AtomExpr):
2485
2748
  """Initialize multi string expression node."""
2486
2749
  self.strings = strings
2487
2750
  AstNode.__init__(self, kid=kid)
2488
- AstSymbolNode.__init__(
2489
- self,
2490
- sym_name=f"[{self.__class__.__name__}]",
2491
- sym_name_node=self,
2492
- sym_type=SymbolType.STRING,
2493
- )
2751
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.STRING)
2494
2752
 
2495
2753
  def normalize(self, deep: bool = False) -> bool:
2496
2754
  """Normalize ast node."""
@@ -2516,12 +2774,7 @@ class FString(AtomExpr):
2516
2774
  """Initialize fstring expression node."""
2517
2775
  self.parts = parts
2518
2776
  AstNode.__init__(self, kid=kid)
2519
- AstSymbolNode.__init__(
2520
- self,
2521
- sym_name=f"[{self.__class__.__name__}]",
2522
- sym_name_node=self,
2523
- sym_type=SymbolType.STRING,
2524
- )
2777
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.STRING)
2525
2778
 
2526
2779
  def normalize(self, deep: bool = False) -> bool:
2527
2780
  """Normalize ast node."""
@@ -2551,12 +2804,7 @@ class ListVal(AtomExpr):
2551
2804
  """Initialize value node."""
2552
2805
  self.values = values
2553
2806
  AstNode.__init__(self, kid=kid)
2554
- AstSymbolNode.__init__(
2555
- self,
2556
- sym_name=f"[{self.__class__.__name__}]",
2557
- sym_name_node=self,
2558
- sym_type=SymbolType.SEQUENCE,
2559
- )
2807
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2560
2808
 
2561
2809
  def normalize(self, deep: bool = False) -> bool:
2562
2810
  """Normalize ast node."""
@@ -2584,12 +2832,7 @@ class SetVal(AtomExpr):
2584
2832
  """Initialize value node."""
2585
2833
  self.values = values
2586
2834
  AstNode.__init__(self, kid=kid)
2587
- AstSymbolNode.__init__(
2588
- self,
2589
- sym_name=f"[{self.__class__.__name__}]",
2590
- sym_name_node=self,
2591
- sym_type=SymbolType.SEQUENCE,
2592
- )
2835
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2593
2836
 
2594
2837
  def normalize(self, deep: bool = False) -> bool:
2595
2838
  """Normalize ast node."""
@@ -2617,12 +2860,7 @@ class TupleVal(AtomExpr):
2617
2860
  """Initialize tuple value node."""
2618
2861
  self.values = values
2619
2862
  AstNode.__init__(self, kid=kid)
2620
- AstSymbolNode.__init__(
2621
- self,
2622
- sym_name=f"[{self.__class__.__name__}]",
2623
- sym_name_node=self,
2624
- sym_type=SymbolType.SEQUENCE,
2625
- )
2863
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2626
2864
 
2627
2865
  def normalize(self, deep: bool = False) -> bool:
2628
2866
  """Normalize ast node."""
@@ -2665,12 +2903,7 @@ class DictVal(AtomExpr):
2665
2903
  """Initialize dict expression node."""
2666
2904
  self.kv_pairs = kv_pairs
2667
2905
  AstNode.__init__(self, kid=kid)
2668
- AstSymbolNode.__init__(
2669
- self,
2670
- sym_name=f"[{self.__class__.__name__}]",
2671
- sym_name_node=self,
2672
- sym_type=SymbolType.SEQUENCE,
2673
- )
2906
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2674
2907
 
2675
2908
  def normalize(self, deep: bool = False) -> bool:
2676
2909
  """Normalize ast node."""
@@ -2726,7 +2959,7 @@ class KWPair(AstNode):
2726
2959
 
2727
2960
  def __init__(
2728
2961
  self,
2729
- key: Optional[NameSpec], # is **value if blank
2962
+ key: Optional[NameAtom], # is **value if blank
2730
2963
  value: Expr,
2731
2964
  kid: Sequence[AstNode],
2732
2965
  ) -> None:
@@ -2803,12 +3036,7 @@ class ListCompr(AtomExpr):
2803
3036
  self.out_expr = out_expr
2804
3037
  self.compr = compr
2805
3038
  AstNode.__init__(self, kid=kid)
2806
- AstSymbolNode.__init__(
2807
- self,
2808
- sym_name=f"[{self.__class__.__name__}]",
2809
- sym_name_node=self,
2810
- sym_type=SymbolType.SEQUENCE,
2811
- )
3039
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2812
3040
 
2813
3041
  def normalize(self, deep: bool = False) -> bool:
2814
3042
  """Normalize ast node."""
@@ -2883,12 +3111,7 @@ class DictCompr(AtomExpr):
2883
3111
  self.kv_pair = kv_pair
2884
3112
  self.compr = compr
2885
3113
  AstNode.__init__(self, kid=kid)
2886
- AstSymbolNode.__init__(
2887
- self,
2888
- sym_name=f"[{self.__class__.__name__}]",
2889
- sym_name_node=self,
2890
- sym_type=SymbolType.SEQUENCE,
2891
- )
3114
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2892
3115
 
2893
3116
  def normalize(self, deep: bool = False) -> bool:
2894
3117
  """Normalize ast node."""
@@ -2943,6 +3166,22 @@ class AtomTrailer(Expr):
2943
3166
  self.set_kids(nodes=new_kid)
2944
3167
  return res
2945
3168
 
3169
+ @property
3170
+ def as_attr_list(self) -> list[AstSymbolNode]:
3171
+ """Unwind trailer into list of ast symbol nodes."""
3172
+ left = self.right if isinstance(self.right, AtomTrailer) else self.target
3173
+ right = self.target if isinstance(self.right, AtomTrailer) else self.right
3174
+ trag_list: list[AstSymbolNode] = (
3175
+ [right] if isinstance(right, AstSymbolNode) else []
3176
+ )
3177
+ while isinstance(left, AtomTrailer) and left.is_attr:
3178
+ if isinstance(left.right, AstSymbolNode):
3179
+ trag_list.insert(0, left.right)
3180
+ left = left.target
3181
+ if isinstance(left, AstSymbolNode):
3182
+ trag_list.insert(0, left)
3183
+ return trag_list
3184
+
2946
3185
 
2947
3186
  class AtomUnit(Expr):
2948
3187
  """AtomUnit node type for Jac Ast."""
@@ -3047,12 +3286,7 @@ class IndexSlice(AtomExpr):
3047
3286
  self.step = step
3048
3287
  self.is_range = is_range
3049
3288
  AstNode.__init__(self, kid=kid)
3050
- AstSymbolNode.__init__(
3051
- self,
3052
- sym_name=f"[{self.__class__.__name__}]",
3053
- sym_type=SymbolType.SEQUENCE,
3054
- sym_name_node=self,
3055
- )
3289
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3056
3290
 
3057
3291
  def normalize(self, deep: bool = True) -> bool:
3058
3292
  """Normalize ast node."""
@@ -3081,91 +3315,35 @@ class IndexSlice(AtomExpr):
3081
3315
  return res
3082
3316
 
3083
3317
 
3084
- class ArchRef(NameSpec):
3318
+ class ArchRef(AtomExpr):
3085
3319
  """ArchRef node type for Jac Ast."""
3086
3320
 
3087
3321
  def __init__(
3088
3322
  self,
3089
- name_ref: NameSpec,
3090
- arch: Token,
3323
+ arch_name: NameAtom,
3324
+ arch_type: Token,
3091
3325
  kid: Sequence[AstNode],
3092
3326
  ) -> None:
3093
3327
  """Initialize architype reference expression node."""
3094
- self.name_ref = name_ref
3095
- self.arch = arch
3096
- AstNode.__init__(self, kid=kid)
3097
- AstSymbolNode.__init__(
3098
- self,
3099
- sym_name=self.py_resolve_name(),
3100
- sym_name_node=name_ref,
3101
- sym_type=SymbolType.TYPE,
3102
- )
3103
- NameSpec.__init__(self)
3104
-
3105
- def normalize(self, deep: bool = False) -> bool:
3106
- """Normalize ast node."""
3107
- res = True
3108
- if deep:
3109
- res = self.name_ref.normalize(deep)
3110
- new_kid: list[AstNode] = [self.arch, self.name_ref]
3111
- self.set_kids(nodes=new_kid)
3112
- return res
3113
-
3114
- def py_resolve_name(self) -> str:
3115
- """Resolve name."""
3116
- if isinstance(self.name_ref, Name):
3117
- return self.name_ref.value
3118
- elif isinstance(self.name_ref, SpecialVarRef):
3119
- return self.name_ref.py_resolve_name()
3120
- else:
3121
- raise NotImplementedError
3122
-
3123
-
3124
- class SpecialVarRef(NameSpec):
3125
- """HereRef node type for Jac Ast."""
3126
-
3127
- def __init__(
3128
- self,
3129
- var: Token,
3130
- kid: Sequence[AstNode],
3131
- ) -> None:
3132
- """Initialize special var reference expression node."""
3133
- self.var = var
3328
+ self.arch_name = arch_name
3329
+ self.arch_type = arch_type
3134
3330
  AstNode.__init__(self, kid=kid)
3135
3331
  AstSymbolNode.__init__(
3136
3332
  self,
3137
- sym_name=self.py_resolve_name(),
3138
- sym_name_node=var,
3139
- sym_type=SymbolType.VAR,
3333
+ sym_name=arch_name.sym_name,
3334
+ name_spec=arch_name,
3335
+ sym_category=SymbolType.TYPE,
3140
3336
  )
3141
- NameSpec.__init__(self)
3142
3337
 
3143
3338
  def normalize(self, deep: bool = False) -> bool:
3144
3339
  """Normalize ast node."""
3145
3340
  res = True
3146
3341
  if deep:
3147
- res = self.var.normalize(deep)
3148
- new_kid: list[AstNode] = [self.var]
3342
+ res = self.arch_name.normalize(deep)
3343
+ new_kid: list[AstNode] = [self.arch_type, self.arch_name]
3149
3344
  self.set_kids(nodes=new_kid)
3150
3345
  return res
3151
3346
 
3152
- def py_resolve_name(self) -> str:
3153
- """Resolve name."""
3154
- if self.var.name == Tok.KW_SELF:
3155
- return "self"
3156
- elif self.var.name == Tok.KW_SUPER:
3157
- return "super()"
3158
- elif self.var.name == Tok.KW_ROOT:
3159
- return Con.ROOT.value
3160
- elif self.var.name == Tok.KW_HERE:
3161
- return Con.HERE.value
3162
- elif self.var.name == Tok.KW_INIT:
3163
- return "__init__"
3164
- elif self.var.name == Tok.KW_POST_INIT:
3165
- return "__post_init__"
3166
- else:
3167
- raise NotImplementedError("ICE: Special var reference not implemented")
3168
-
3169
3347
 
3170
3348
  class EdgeRefTrailer(Expr):
3171
3349
  """EdgeRefTrailer node type for Jac Ast."""
@@ -3210,12 +3388,7 @@ class EdgeOpRef(WalkerStmtOnlyNode, AtomExpr):
3210
3388
  self.edge_dir = edge_dir
3211
3389
  AstNode.__init__(self, kid=kid)
3212
3390
  WalkerStmtOnlyNode.__init__(self)
3213
- AstSymbolNode.__init__(
3214
- self,
3215
- sym_name=f"[{self.__class__.__name__}]",
3216
- sym_name_node=self,
3217
- sym_type=SymbolType.SEQUENCE,
3218
- )
3391
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3219
3392
 
3220
3393
  def normalize(self, deep: bool = False) -> bool:
3221
3394
  """Normalize ast node."""
@@ -3344,12 +3517,7 @@ class FilterCompr(AtomExpr):
3344
3517
  self.f_type = f_type
3345
3518
  self.compares = compares
3346
3519
  AstNode.__init__(self, kid=kid)
3347
- AstSymbolNode.__init__(
3348
- self,
3349
- sym_name=f"[{self.__class__.__name__}]",
3350
- sym_name_node=self,
3351
- sym_type=SymbolType.SEQUENCE,
3352
- )
3520
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3353
3521
 
3354
3522
  def normalize(self, deep: bool = False) -> bool:
3355
3523
  """Normalize ast node."""
@@ -3386,12 +3554,7 @@ class AssignCompr(AtomExpr):
3386
3554
  """Initialize assign compr expression node."""
3387
3555
  self.assigns = assigns
3388
3556
  AstNode.__init__(self, kid=kid)
3389
- AstSymbolNode.__init__(
3390
- self,
3391
- sym_name=f"[{self.__class__.__name__}]",
3392
- sym_name_node=self,
3393
- sym_type=SymbolType.SEQUENCE,
3394
- )
3557
+ AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3395
3558
 
3396
3559
  def normalize(self, deep: bool = False) -> bool:
3397
3560
  """Normalize ast node."""
@@ -3515,7 +3678,7 @@ class MatchAs(MatchPattern):
3515
3678
 
3516
3679
  def __init__(
3517
3680
  self,
3518
- name: NameSpec,
3681
+ name: NameAtom,
3519
3682
  pattern: Optional[MatchPattern],
3520
3683
  kid: Sequence[AstNode],
3521
3684
  ) -> None:
@@ -3554,6 +3717,7 @@ class MatchWild(MatchPattern):
3554
3717
  col_start=self.loc.col_start,
3555
3718
  col_end=self.loc.col_end,
3556
3719
  line=self.loc.first_line,
3720
+ end_line=self.loc.last_line,
3557
3721
  pos_start=self.loc.pos_start,
3558
3722
  pos_end=self.loc.pos_end,
3559
3723
  )
@@ -3663,7 +3827,7 @@ class MatchKVPair(MatchPattern):
3663
3827
 
3664
3828
  def __init__(
3665
3829
  self,
3666
- key: MatchPattern | NameSpec,
3830
+ key: MatchPattern | NameAtom,
3667
3831
  value: MatchPattern,
3668
3832
  kid: Sequence[AstNode],
3669
3833
  ) -> None:
@@ -3691,7 +3855,7 @@ class MatchStar(MatchPattern):
3691
3855
 
3692
3856
  def __init__(
3693
3857
  self,
3694
- name: NameSpec,
3858
+ name: NameAtom,
3695
3859
  is_list: bool,
3696
3860
  kid: Sequence[AstNode],
3697
3861
  ) -> None:
@@ -3718,7 +3882,7 @@ class MatchArch(MatchPattern):
3718
3882
 
3719
3883
  def __init__(
3720
3884
  self,
3721
- name: AtomTrailer | NameSpec,
3885
+ name: AtomTrailer | NameAtom,
3722
3886
  arg_patterns: Optional[SubNodeList[MatchPattern]],
3723
3887
  kw_patterns: Optional[SubNodeList[MatchKVPair]],
3724
3888
  kid: Sequence[AstNode],
@@ -3761,6 +3925,7 @@ class Token(AstNode):
3761
3925
  name: str,
3762
3926
  value: str,
3763
3927
  line: int,
3928
+ end_line: int,
3764
3929
  col_start: int,
3765
3930
  col_end: int,
3766
3931
  pos_start: int,
@@ -3771,6 +3936,7 @@ class Token(AstNode):
3771
3936
  self.name = name
3772
3937
  self.value = value
3773
3938
  self.line_no = line
3939
+ self.end_line = end_line
3774
3940
  self.c_start = col_start
3775
3941
  self.c_end = col_end
3776
3942
  self.pos_start = pos_start
@@ -3786,7 +3952,7 @@ class Token(AstNode):
3786
3952
  return self.value
3787
3953
 
3788
3954
 
3789
- class Name(Token, NameSpec):
3955
+ class Name(Token, NameAtom):
3790
3956
  """Name node type for Jac Ast."""
3791
3957
 
3792
3958
  def __init__(
@@ -3795,6 +3961,7 @@ class Name(Token, NameSpec):
3795
3961
  name: str,
3796
3962
  value: str,
3797
3963
  line: int,
3964
+ end_line: int,
3798
3965
  col_start: int,
3799
3966
  col_end: int,
3800
3967
  pos_start: int,
@@ -3811,18 +3978,19 @@ class Name(Token, NameSpec):
3811
3978
  name=name,
3812
3979
  value=value,
3813
3980
  line=line,
3981
+ end_line=end_line,
3814
3982
  col_start=col_start,
3815
3983
  col_end=col_end,
3816
3984
  pos_start=pos_start,
3817
3985
  pos_end=pos_end,
3818
3986
  )
3987
+ NameAtom.__init__(self)
3819
3988
  AstSymbolNode.__init__(
3820
3989
  self,
3821
3990
  sym_name=value,
3822
- sym_name_node=self,
3823
- sym_type=SymbolType.VAR,
3991
+ name_spec=self,
3992
+ sym_category=SymbolType.VAR,
3824
3993
  )
3825
- NameSpec.__init__(self)
3826
3994
 
3827
3995
  def unparse(self) -> str:
3828
3996
  """Unparse name."""
@@ -3831,6 +3999,74 @@ class Name(Token, NameSpec):
3831
3999
  ",\n" if self.is_enum_singleton else ""
3832
4000
  )
3833
4001
 
4002
+ @staticmethod
4003
+ def gen_stub_from_node(
4004
+ node: AstSymbolNode, name_str: str, set_name_of: Optional[AstSymbolNode] = None
4005
+ ) -> Name:
4006
+ """Generate name from node."""
4007
+ ret = Name(
4008
+ file_path=node.loc.mod_path,
4009
+ name=Tok.NAME.value,
4010
+ value=name_str,
4011
+ col_start=node.loc.col_start,
4012
+ col_end=node.loc.col_end,
4013
+ line=node.loc.first_line,
4014
+ end_line=node.loc.last_line,
4015
+ pos_start=node.loc.pos_start,
4016
+ pos_end=node.loc.pos_end,
4017
+ )
4018
+ ret.name_of = set_name_of if set_name_of else ret
4019
+ if node._sym_tab:
4020
+ ret.sym_tab = node.sym_tab
4021
+ return ret
4022
+
4023
+
4024
+ class SpecialVarRef(Name):
4025
+ """HereRef node type for Jac Ast."""
4026
+
4027
+ def __init__(
4028
+ self,
4029
+ var: Name,
4030
+ ) -> None:
4031
+ """Initialize special var reference expression node."""
4032
+ self.orig = var
4033
+ Name.__init__(
4034
+ self,
4035
+ file_path=var.file_path,
4036
+ name=var.name,
4037
+ value=self.py_resolve_name(), # TODO: This shouldnt be necessary
4038
+ line=var.line_no,
4039
+ end_line=var.end_line,
4040
+ col_start=var.c_start,
4041
+ col_end=var.c_end,
4042
+ pos_start=var.pos_start,
4043
+ pos_end=var.pos_end,
4044
+ )
4045
+ NameAtom.__init__(self)
4046
+ AstSymbolNode.__init__(
4047
+ self,
4048
+ sym_name=self.py_resolve_name(),
4049
+ name_spec=self,
4050
+ sym_category=SymbolType.VAR,
4051
+ )
4052
+
4053
+ def py_resolve_name(self) -> str:
4054
+ """Resolve name."""
4055
+ if self.orig.name == Tok.KW_SELF:
4056
+ return "self"
4057
+ elif self.orig.name == Tok.KW_SUPER:
4058
+ return "super"
4059
+ elif self.orig.name == Tok.KW_ROOT:
4060
+ return Con.ROOT.value
4061
+ elif self.orig.name == Tok.KW_HERE:
4062
+ return Con.HERE.value
4063
+ elif self.orig.name == Tok.KW_INIT:
4064
+ return "__init__"
4065
+ elif self.orig.name == Tok.KW_POST_INIT:
4066
+ return "__post_init__"
4067
+ else:
4068
+ raise NotImplementedError("ICE: Special var reference not implemented")
4069
+
3834
4070
 
3835
4071
  class Literal(Token, AtomExpr):
3836
4072
  """Literal node type for Jac Ast."""
@@ -3856,6 +4092,7 @@ class Literal(Token, AtomExpr):
3856
4092
  name: str,
3857
4093
  value: str,
3858
4094
  line: int,
4095
+ end_line: int,
3859
4096
  col_start: int,
3860
4097
  col_end: int,
3861
4098
  pos_start: int,
@@ -3868,17 +4105,13 @@ class Literal(Token, AtomExpr):
3868
4105
  name=name,
3869
4106
  value=value,
3870
4107
  line=line,
4108
+ end_line=end_line,
3871
4109
  col_start=col_start,
3872
4110
  col_end=col_end,
3873
4111
  pos_start=pos_start,
3874
4112
  pos_end=pos_end,
3875
4113
  )
3876
- AstSymbolNode.__init__(
3877
- self,
3878
- sym_name=f"[{self.__class__.__name__}]",
3879
- sym_name_node=self,
3880
- sym_type=self.SYMBOL_TYPE,
3881
- )
4114
+ AstSymbolStubNode.__init__(self, sym_type=self.SYMBOL_TYPE)
3882
4115
 
3883
4116
  @property
3884
4117
  def lit_value(
@@ -3888,43 +4121,7 @@ class Literal(Token, AtomExpr):
3888
4121
  raise NotImplementedError
3889
4122
 
3890
4123
 
3891
- class TokenSymbol(Token, AstSymbolNode):
3892
- """TokenSymbol node type for Jac Ast."""
3893
-
3894
- SYMBOL_TYPE = SymbolType.VAR
3895
-
3896
- def __init__(
3897
- self,
3898
- file_path: str,
3899
- name: str,
3900
- value: str,
3901
- line: int,
3902
- col_start: int,
3903
- col_end: int,
3904
- pos_start: int,
3905
- pos_end: int,
3906
- ) -> None:
3907
- """Initialize token."""
3908
- Token.__init__(
3909
- self,
3910
- file_path=file_path,
3911
- name=name,
3912
- value=value,
3913
- line=line,
3914
- col_start=col_start,
3915
- col_end=col_end,
3916
- pos_start=pos_start,
3917
- pos_end=pos_end,
3918
- )
3919
- AstSymbolNode.__init__(
3920
- self,
3921
- sym_name=f"[{self.__class__.__name__}]",
3922
- sym_name_node=self,
3923
- sym_type=self.SYMBOL_TYPE,
3924
- )
3925
-
3926
-
3927
- class BuiltinType(Name, Literal, NameSpec):
4124
+ class BuiltinType(Name, Literal, NameAtom):
3928
4125
  """Type node type for Jac Ast."""
3929
4126
 
3930
4127
  SYMBOL_TYPE = SymbolType.VAR
@@ -4037,6 +4234,7 @@ class EmptyToken(Token):
4037
4234
  file_path="",
4038
4235
  value="",
4039
4236
  line=0,
4237
+ end_line=0,
4040
4238
  col_start=0,
4041
4239
  col_end=0,
4042
4240
  pos_start=0,
@@ -4057,6 +4255,7 @@ class CommentToken(Token):
4057
4255
  name: str,
4058
4256
  value: str,
4059
4257
  line: int,
4258
+ end_line: int,
4060
4259
  col_start: int,
4061
4260
  col_end: int,
4062
4261
  pos_start: int,
@@ -4065,15 +4264,21 @@ class CommentToken(Token):
4065
4264
  is_inline: bool = False,
4066
4265
  ) -> None:
4067
4266
  """Initialize token."""
4068
- self.file_path = file_path
4069
- self.name = name
4070
- self.value = value
4071
- self.line_no = line
4072
- self.c_start = col_start
4073
- self.c_end = col_end
4074
- self.pos_start = pos_start
4075
- self.pos_end = pos_end
4076
4267
  self.is_inline = is_inline
4268
+
4269
+ Token.__init__(
4270
+ self,
4271
+ file_path=file_path,
4272
+ name=name,
4273
+ value=value,
4274
+ line=line,
4275
+ end_line=end_line,
4276
+ col_start=col_start,
4277
+ col_end=col_end,
4278
+ pos_start=pos_start,
4279
+ pos_end=pos_end,
4280
+ )
4281
+
4077
4282
  AstNode.__init__(self, kid=kid)
4078
4283
 
4079
4284