@ttsc/wasm 0.30.4 → 0.31.1

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.
Files changed (174) hide show
  1. package/README.md +3 -3
  2. package/build/build-wasm.cjs +5 -4
  3. package/build/go-build-cache.cjs +347 -0
  4. package/build/pack-prepare.cjs +3 -2
  5. package/cmd/ttsc-wasm/main.go +22 -10
  6. package/cmd/ttsc-wasm/main_wasm.go +2 -2
  7. package/dist/.ttsc-wasm-build.json +138 -58
  8. package/dist/go.mod +7 -5
  9. package/dist/ttsc.wasm +2 -2
  10. package/go.mod +7 -5
  11. package/go.sum +10 -10
  12. package/host/api.go +34 -41
  13. package/host/doc.go +7 -6
  14. package/host/expose.go +42 -0
  15. package/host/fountain.go +192 -22
  16. package/host/host.go +10 -25
  17. package/host/host_native.go +3 -5
  18. package/host/invoke.go +133 -0
  19. package/host/plugin.go +37 -72
  20. package/host/result.go +108 -0
  21. package/lib/src/BootTtscWorkerTerminationError.d.ts +20 -0
  22. package/lib/src/BootTtscWorkerTerminationError.js +20 -0
  23. package/lib/src/BootTtscWorkerTerminationError.js.map +1 -1
  24. package/lib/src/MemFSError.d.ts +21 -2
  25. package/lib/src/MemFSError.js +25 -2
  26. package/lib/src/MemFSError.js.map +1 -1
  27. package/lib/src/bootTtsc.d.ts +49 -2
  28. package/lib/src/bootTtsc.js +89 -23
  29. package/lib/src/bootTtsc.js.map +1 -1
  30. package/lib/src/createMemFS.d.ts +45 -0
  31. package/lib/src/createMemFS.js +269 -66
  32. package/lib/src/createMemFS.js.map +1 -1
  33. package/lib/src/parseResult.d.ts +19 -0
  34. package/lib/src/parseResult.js +19 -0
  35. package/lib/src/parseResult.js.map +1 -1
  36. package/lib/src/structures/IBootResult.d.ts +20 -2
  37. package/lib/src/structures/IBootTtscOptions.d.ts +28 -6
  38. package/lib/src/structures/IFileStats.d.ts +51 -0
  39. package/lib/src/structures/IMemFSHost.d.ts +89 -0
  40. package/lib/src/structures/ITtscApi.d.ts +154 -9
  41. package/lib/src/structures/ITtscBuildOpts.d.ts +18 -1
  42. package/lib/src/structures/ITtscCompileResult.d.ts +20 -2
  43. package/lib/src/structures/ITtscDiagnostic.d.ts +25 -1
  44. package/lib/src/structures/ITtscFileQuery.d.ts +19 -1
  45. package/lib/src/structures/ITtscFountainDiagnosticsResult.d.ts +20 -1
  46. package/lib/src/structures/ITtscNodeAtPositionResult.d.ts +18 -1
  47. package/lib/src/structures/ITtscNodeInfo.d.ts +23 -2
  48. package/lib/src/structures/ITtscPluginOpts.d.ts +24 -3
  49. package/lib/src/structures/ITtscPositionQuery.d.ts +21 -4
  50. package/lib/src/structures/ITtscReleaseSnapshotResult.d.ts +22 -2
  51. package/lib/src/structures/ITtscResult.d.ts +31 -5
  52. package/lib/src/structures/ITtscSnapshotHandle.d.ts +19 -1
  53. package/lib/src/structures/ITtscSnapshotResult.d.ts +22 -1
  54. package/lib/src/structures/ITtscSnapshotsResult.d.ts +19 -1
  55. package/lib/src/structures/ITtscSourceFileTextResult.d.ts +19 -1
  56. package/lib/src/structures/ITtscSourceFilesResult.d.ts +23 -2
  57. package/lib/src/structures/ITtscSymbolAtPositionResult.d.ts +18 -1
  58. package/lib/src/structures/ITtscSymbolDeclaration.d.ts +25 -2
  59. package/lib/src/structures/ITtscSymbolInfo.d.ts +19 -1
  60. package/lib/src/structures/ITtscTransformResult.d.ts +21 -3
  61. package/lib/src/structures/ITtscTypeAtPositionResult.d.ts +18 -1
  62. package/lib/src/structures/ITtscTypeInfo.d.ts +19 -1
  63. package/lib/src/structures/ITtscVersion.d.ts +28 -1
  64. package/lib/src/structures/IWasmExecFS.d.ts +310 -0
  65. package/package.json +4 -2
  66. package/shim-vendor/shim/ast/enums_gen.go +4 -2
  67. package/shim-vendor/shim/ast/go.mod +5 -5
  68. package/shim-vendor/shim/ast/go.sum +10 -10
  69. package/shim-vendor/shim/ast/lint.go +1088 -20
  70. package/shim-vendor/shim/ast/parent.go +38 -22
  71. package/shim-vendor/shim/ast/safe_text.go +48 -26
  72. package/shim-vendor/shim/ast/shim.go +1307 -20
  73. package/shim-vendor/shim/ast/test/next_jsdoc_comment_location_reaches_variable_statement_test.go +51 -0
  74. package/shim-vendor/shim/ast/test/node_text_joins_multi_hop_qualified_name_test.go +24 -9
  75. package/shim-vendor/shim/ast/test/node_text_joins_one_hop_qualified_name_test.go +9 -5
  76. package/shim-vendor/shim/ast/test/node_text_returns_empty_for_nil_test.go +13 -5
  77. package/shim-vendor/shim/ast/test/node_text_returns_identifier_text_test.go +12 -5
  78. package/shim-vendor/shim/ast/test/node_text_skips_empty_qualified_left_test.go +35 -5
  79. package/shim-vendor/shim/astnav/go.mod +5 -5
  80. package/shim-vendor/shim/astnav/go.sum +12 -10
  81. package/shim-vendor/shim/astnav/shim.go +9 -0
  82. package/shim-vendor/shim/bundled/go.mod +7 -1
  83. package/shim-vendor/shim/bundled/go.sum +12 -0
  84. package/shim-vendor/shim/checker/enums_gen.go +4 -2
  85. package/shim-vendor/shim/checker/extra-shim.json +6 -0
  86. package/shim-vendor/shim/checker/go.mod +5 -5
  87. package/shim-vendor/shim/checker/go.sum +10 -10
  88. package/shim-vendor/shim/checker/node_builder_fields_gen.go +19 -0
  89. package/shim-vendor/shim/checker/shim.go +827 -114
  90. package/shim-vendor/shim/compiler/emit_sourcemap.go +68 -29
  91. package/shim-vendor/shim/compiler/emitassemble.go +36 -2
  92. package/shim-vendor/shim/compiler/emithook.go +13 -3
  93. package/shim-vendor/shim/compiler/go.mod +5 -5
  94. package/shim-vendor/shim/compiler/go.sum +10 -10
  95. package/shim-vendor/shim/compiler/incremental.go +56 -20
  96. package/shim-vendor/shim/compiler/resolution.go +92 -9
  97. package/shim-vendor/shim/core/enums_gen.go +2 -2
  98. package/shim-vendor/shim/core/go.mod +6 -1
  99. package/shim-vendor/shim/core/go.sum +10 -0
  100. package/shim-vendor/shim/core/modulekind.go +9 -0
  101. package/shim-vendor/shim/core/shim.go +157 -6
  102. package/shim-vendor/shim/diagnosticwriter/go.mod +10 -1
  103. package/shim-vendor/shim/diagnosticwriter/go.sum +20 -0
  104. package/shim-vendor/shim/diagnosticwriter/lint.go +188 -10
  105. package/shim-vendor/shim/diagnosticwriter/shim.go +14 -0
  106. package/shim-vendor/shim/lsp/go.mod +5 -5
  107. package/shim-vendor/shim/lsp/go.sum +10 -10
  108. package/shim-vendor/shim/lsp/shim.go +78 -2
  109. package/shim-vendor/shim/parser/go.mod +10 -1
  110. package/shim-vendor/shim/parser/go.sum +22 -0
  111. package/shim-vendor/shim/printer/emithost.go +46 -1
  112. package/shim-vendor/shim/printer/go.mod +5 -5
  113. package/shim-vendor/shim/printer/go.sum +10 -10
  114. package/shim-vendor/shim/printer/shim.go +114 -7
  115. package/shim-vendor/shim/printer/sourcemap.go +55 -0
  116. package/shim-vendor/shim/scanner/go.mod +10 -1
  117. package/shim-vendor/shim/scanner/go.sum +20 -0
  118. package/shim-vendor/shim/scanner/regexp.go +19 -4
  119. package/shim-vendor/shim/scanner/shim.go +3 -0
  120. package/shim-vendor/shim/stringutil/extra-shim.json +1 -0
  121. package/shim-vendor/shim/stringutil/go.mod +5 -0
  122. package/shim-vendor/shim/stringutil/go.sum +2 -0
  123. package/shim-vendor/shim/stringutil/shim.go +119 -0
  124. package/shim-vendor/shim/transformers/go.mod +5 -5
  125. package/shim-vendor/shim/transformers/go.sum +12 -10
  126. package/shim-vendor/shim/transformers/shim.go +12 -3
  127. package/shim-vendor/shim/tsoptions/command_line_raw.go +44 -0
  128. package/shim-vendor/shim/tsoptions/go.mod +10 -1
  129. package/shim-vendor/shim/tsoptions/go.sum +22 -0
  130. package/shim-vendor/shim/tsoptions/shim.go +1 -1
  131. package/shim-vendor/shim/tspath/go.mod +1 -1
  132. package/shim-vendor/shim/tspath/go.sum +6 -0
  133. package/shim-vendor/shim/vfs/cachedvfs/go.mod +3 -1
  134. package/shim-vendor/shim/vfs/cachedvfs/go.sum +12 -0
  135. package/shim-vendor/shim/vfs/decode.go +26 -0
  136. package/shim-vendor/shim/vfs/decode_test.go +42 -0
  137. package/shim-vendor/shim/vfs/go.mod +7 -1
  138. package/shim-vendor/shim/vfs/go.sum +12 -0
  139. package/shim-vendor/shim/vfs/osvfs/go.mod +7 -1
  140. package/shim-vendor/shim/vfs/osvfs/go.sum +12 -0
  141. package/src/BootTtscWorkerTerminationError.ts +22 -0
  142. package/src/MemFSError.ts +29 -2
  143. package/src/bootTtsc.ts +104 -28
  144. package/src/createMemFS.ts +291 -64
  145. package/src/parseResult.ts +19 -0
  146. package/src/structures/IBootResult.ts +21 -2
  147. package/src/structures/IBootTtscOptions.ts +32 -6
  148. package/src/structures/IFileStats.ts +65 -0
  149. package/src/structures/IMemFSHost.ts +97 -0
  150. package/src/structures/ITtscApi.ts +154 -9
  151. package/src/structures/ITtscBuildOpts.ts +19 -1
  152. package/src/structures/ITtscCompileResult.ts +21 -2
  153. package/src/structures/ITtscDiagnostic.ts +32 -1
  154. package/src/structures/ITtscFileQuery.ts +19 -1
  155. package/src/structures/ITtscFountainDiagnosticsResult.ts +20 -1
  156. package/src/structures/ITtscNodeAtPositionResult.ts +18 -1
  157. package/src/structures/ITtscNodeInfo.ts +27 -2
  158. package/src/structures/ITtscPluginOpts.ts +28 -3
  159. package/src/structures/ITtscPositionQuery.ts +21 -4
  160. package/src/structures/ITtscReleaseSnapshotResult.ts +22 -2
  161. package/src/structures/ITtscResult.ts +34 -5
  162. package/src/structures/ITtscSnapshotHandle.ts +19 -1
  163. package/src/structures/ITtscSnapshotResult.ts +22 -1
  164. package/src/structures/ITtscSnapshotsResult.ts +19 -1
  165. package/src/structures/ITtscSourceFileTextResult.ts +19 -1
  166. package/src/structures/ITtscSourceFilesResult.ts +23 -2
  167. package/src/structures/ITtscSymbolAtPositionResult.ts +18 -1
  168. package/src/structures/ITtscSymbolDeclaration.ts +27 -2
  169. package/src/structures/ITtscSymbolInfo.ts +23 -1
  170. package/src/structures/ITtscTransformResult.ts +22 -3
  171. package/src/structures/ITtscTypeAtPositionResult.ts +18 -1
  172. package/src/structures/ITtscTypeInfo.ts +20 -1
  173. package/src/structures/ITtscVersion.ts +33 -1
  174. package/src/structures/IWasmExecFS.ts +336 -0
@@ -2,37 +2,53 @@ package ast
2
2
 
3
3
  import innerast "github.com/microsoft/typescript-go/internal/ast"
4
4
 
5
- // SetParentInChildren recursively sets each descendant node's Parent pointer to
6
- // its containing node.
5
+ // SetParentInChildren sets Parent pointers along the compiler's ForEachChild
6
+ // traversal to each child's containing node.
7
7
  //
8
8
  // A transform that splices freshly built (synthetic) nodes onto a SourceFile
9
- // must call this before emit, because the passes that then walk the spliced tree
10
- // dereference Parent and would hit nil on a synthetic node. The printer is the
11
- // example that holds up: getContainingNodeArray reads node.Parent unguarded for
12
- // a parameter, template span, decorator, and heritage clause.
9
+ // must establish valid parent relationships before a pass that relies on them;
10
+ // this overwrite operation is one way to do so. The printer's
11
+ // getContainingNodeArray first permits a nil parent, then uses parent-kind and
12
+ // payload relationships to select a containing list. A wrong existing parent
13
+ // can therefore select the wrong list or fail a payload assertion.
13
14
  //
14
- // Two earlier examples were dropped rather than the rule. The emit resolver's
15
- // reference marking no longer walks the spliced tree at all in ttsc's plugin
16
- // emit lane, which builds the builtin chain from the parse tree (see
17
- // driver.EmitWithPluginTransformers). The module transform's own Parent reads
18
- // carry upstream //nolint:customlint notes saying they deliberately inspect
19
- // parse-tree parents.
15
+ // This overwrites existing parent links. Use SetParentInChildrenUnset when a
16
+ // transform reuses parse-tree children whose original ancestry must survive.
17
+ // The root must be nonnil with valid compiler payloads and an acyclic child
18
+ // tree. Callers must own the parent mutations without concurrent tree access.
19
+ //
20
+ // @evidence contracts/common.md#principled-implementation Recursive upstream child traversal assigns each child's immediate containing node, matching the AST parent relation for an acyclic tree.
21
+ // @evidence contracts/common.md#clear-and-simple-design The wrapper exposes upstream's overwrite operation separately from the preserve-existing-parent operation, so callers choose ownership explicitly.
22
+ // @evidence contracts/common.md#prohibited-implementation-shortcuts The only mutation is the requested AST parent wiring through the compiler's own traversal API; it does not replace foreign methods or globals.
23
+ // @evidence contracts/common.md#meaningful-documentation Native prose states the overwrite effect, emit motivation, alternative for reused parse nodes, and nonnil acyclic-tree premise with separated paragraphs.
24
+ // @evidenceExclude contracts/performance.md#bound-retention-and-release-resources The shim controls no independent traversal-state lifetime. Upstream checks a setter closure out of sync.Pool and defers returning it; normal traversal restores its parent reference. The pool has no numeric cap, and an invalid-tree panic can leave captured parent state until the pool entry is discarded. Mutated Parent links remain owned by the caller's tree.
25
+ // @evidenceExclude contracts/performance.md#efficient-algorithms The shim chooses no independent parent-traversal algorithm. Upstream visits V traversed nodes with O(V) work and up to O(H) stack for child depth H, without collecting all descendants; caller graphs must be valid trees.
26
+ // @evidence contracts/performance.md#reuse-equivalent-work Upstream shares reusable setter closures through sync.Pool, checking one out for a traversal and returning it with defer. Normal completion restores the mutable parent cursor before reuse; this pools traversal machinery, not a cached result that could skip required parent mutations.
27
+ // @evidenceExclude contracts/portability.md#os-neutral-implementation SetParentInChildren computes from its arguments only; it opens no file, builds no path and calls no platform or process API.
20
28
  func SetParentInChildren(node *Node) {
21
29
  innerast.SetParentInChildren(node)
22
30
  }
23
31
 
24
- // SetParentInChildrenUnset sets Parent only on nodes that don't already have
25
- // one, recursing through the whole tree. Unlike SetParentInChildren it does NOT
32
+ // SetParentInChildrenUnset sets Parent only on visited children that do not
33
+ // already have one, using the compiler's ForEachChild traversal. Unlike
34
+ // SetParentInChildren it does not
26
35
  // overwrite the parent of original parse-tree nodes that a transform reused
27
- // inside a rebuilt SourceFile — overwriting those (e.g. an `export namespace`
28
- // kept verbatim while sibling statements were rewritten) makes tsgo's
29
- // runtime-syntax/printer mis-resolve the declaration and drop it from emit.
30
- // Only freshly built (synthetic) nodes need a parent wired, and those start nil.
36
+ // inside a rebuilt SourceFile. Changing preserved ancestry can change how
37
+ // downstream parent-sensitive passes interpret those declarations. Nil parent
38
+ // links are wired regardless of whether a node is marked synthetic.
39
+ //
40
+ // Supply a nonnil root with valid compiler payloads and an acyclic child tree.
41
+ // Existing links remain authoritative even if they point outside the rebuilt
42
+ // tree; callers must own mutations without concurrent tree access.
31
43
  //
32
- // This is the form ttsc's plugin emit lane calls. How much it currently carries
33
- // is unproven: stubbing the call out leaves the whole driver suite green, which
34
- // measures the suite's coverage of parent-dependent emit rather than the hazard.
35
- // Keep it for the reason above, not on the strength of a failing test.
44
+ // @evidence contracts/common.md#principled-implementation Every traversed child receives its containing node only when Parent is nil, preserving reused parse-tree ancestry while wiring synthetic descendants in an acyclic tree.
45
+ // @evidence contracts/common.md#clear-and-simple-design A single recursive child traversal owns the nil-only assignment; the overwrite variant remains a separate explicit operation.
46
+ // @evidence contracts/common.md#prohibited-implementation-shortcuts The nil check is the requested preservation policy, not synthetic-flag inference or a fixture exception; no foreign method is replaced and existing parents are preserved deliberately.
47
+ // @evidence contracts/common.md#meaningful-documentation Native prose explains why existing parents survive, the synthetic-node case, and the nonnil acyclic-tree premise without relying on test history.
48
+ // @evidenceExclude contracts/performance.md#bound-retention-and-release-resources This traversal acquires no native handle, task or independently retained cache. Assigned and preserved Parent references remain in the caller-owned tree and can keep ancestor objects reachable, including ancestors outside the rebuilt root; tree owners control that lifetime.
49
+ // @evidence contracts/performance.md#efficient-algorithms One recursive ForEachChild traversal visits V nodes and tests each child parent once, costing O(V) time and O(H) stack for depth H. Already-parented subtrees are still traversed because their deeper children can have nil parents; no full descendant collection is allocated.
50
+ // @evidenceExclude contracts/performance.md#reuse-equivalent-work The traversal coordinates no cached result or in-flight work. Existing nonnil Parent values are preserved as caller-authoritative state, while descendants still require inspection for missing links.
51
+ // @evidenceExclude contracts/portability.md#os-neutral-implementation SetParentInChildrenUnset computes from its arguments only; it opens no file, builds no path and calls no platform or process API.
36
52
  func SetParentInChildrenUnset(node *Node) {
37
53
  node.ForEachChild(func(child *Node) bool {
38
54
  if child.Parent == nil {
@@ -1,14 +1,13 @@
1
1
  // gen_shims:hand-maintained
2
2
  //
3
- // Total-function replacement for upstream `(*Node).Text()`.
3
+ // Text accessor for valid compiler nodes beyond upstream `(*Node).Text()`.
4
4
  //
5
- // Upstream panics for any Kind missing from its switch — most notably
5
+ // Upstream panics for any Kind missing from its switch, most notably
6
6
  // KindQualifiedName, which surfaces in JSDoc parameter names (`@param
7
7
  // obj.field`) and dotted entity references. NodeText handles
8
- // QualifiedName by recursing on the left subtree and joining with the
9
- // right identifier, and falls back to the source-text slice for any
10
- // other Kind so downstream code can treat the helper as a total
11
- // function over *Node instead of guarding each call site.
8
+ // QualifiedName by collecting the left chain and joining nonempty components,
9
+ // and falls back to the checked source-text slice for other kinds. Payloads
10
+ // must match their kinds and parent/qualified-name chains must terminate.
12
11
 
13
12
  package ast
14
13
 
@@ -22,6 +21,21 @@ import (
22
21
  // upstream `(*Node).Text()` where upstream has an arm, adds a
23
22
  // QualifiedName arm that joins `left.right`, and falls back to the
24
23
  // node's source slice for any other Kind. Returns "" for nil.
24
+ //
25
+ // A node's payload must match its Kind, present qualified-name right nodes must
26
+ // be valid text-bearing names, and parent/qualified-name chains must terminate.
27
+ // Unsupported kinds without a valid containing source range return "" instead
28
+ // of synthesizing spelling. This is not a total function for malformed cycles
29
+ // or mismatched payloads.
30
+ //
31
+ // @evidence contracts/common.md#principled-implementation Known text-bearing kinds use their upstream payload accessor, qualified names concatenate their identifier components, and other kinds use checked source byte ranges; nodes must have payloads matching their Kind.
32
+ // @evidence contracts/common.md#clear-and-simple-design One kind dispatch separates semantic token text from qualified-name composition and the private source-range fallback, keeping the safety policy local.
33
+ // @evidence contracts/common.md#prohibited-implementation-shortcuts Kind-specific cases reflect actual AST representations missing from upstream Text, and the range fallback does not patch that foreign method or special-case consumers.
34
+ // @evidence contracts/common.md#meaningful-documentation Native prose distinguishes token text from source spelling, documents nil and unavailable ranges, and states the payload premise using separated body and tag sections.
35
+ // @evidence contracts/performance.md#bound-retention-and-release-resources Qualified-name assembly uses temporary O(H) component references and transfers the assembled string to the caller; no handle or task is acquired. Direct payload and source-slice results may keep their backing text reachable, including a whole source string for a small slice. Caller references determine that lifetime; no independent cache or retained-byte cap is owned here.
36
+ // @evidence contracts/performance.md#efficient-algorithms A qualified chain of H links is collected once and its B output bytes are appended once with a builder, costing O(H+B) time and O(H+B) temporary/output space instead of repeatedly copying growing prefixes. Other valid kinds delegate text access; source fallback walks P parent links and trims W range bytes in O(P+W). Upstream composed text such as JSX namespace names retains its own byte-copy cost.
37
+ // @evidenceExclude contracts/performance.md#reuse-equivalent-work This text query coordinates no completed-result cache or in-flight work; compiler-tree owners establish validity when sharing node spelling and source ranges across calls.
38
+ // @evidenceExclude contracts/portability.md#os-neutral-implementation NodeText computes from its arguments only; it opens no file, builds no path and calls no platform or process API.
25
39
  func NodeText(n *Node) string {
26
40
  if n == nil {
27
41
  return ""
@@ -45,33 +59,41 @@ func NodeText(n *Node) string {
45
59
  innerast.KindMetaProperty:
46
60
  return n.Text()
47
61
  case KindQualifiedName:
48
- qn := n.AsQualifiedName()
49
- if qn == nil {
50
- return ""
62
+ var parts []string
63
+ for n != nil && n.Kind == KindQualifiedName {
64
+ qn := n.AsQualifiedName()
65
+ if qn == nil {
66
+ n = nil
67
+ break
68
+ }
69
+ if qn.Right != nil {
70
+ if text := qn.Right.Text(); text != "" {
71
+ parts = append(parts, text)
72
+ }
73
+ }
74
+ n = qn.Left
51
75
  }
52
- left := NodeText(qn.Left)
53
- right := ""
54
- if qn.Right != nil {
55
- right = qn.Right.Text()
56
- }
57
- switch {
58
- case left == "" && right == "":
59
- return ""
60
- case left == "":
61
- return right
62
- case right == "":
76
+ left := NodeText(n)
77
+ if len(parts) == 0 {
63
78
  return left
64
- default:
65
- return left + "." + right
66
79
  }
80
+ var result strings.Builder
81
+ result.WriteString(left)
82
+ for i := len(parts) - 1; i >= 0; i-- {
83
+ if result.Len() != 0 {
84
+ result.WriteByte('.')
85
+ }
86
+ result.WriteString(parts[i])
87
+ }
88
+ return result.String()
67
89
  }
68
90
  return nodeSourceText(n)
69
91
  }
70
92
 
71
- // nodeSourceText returns the verbatim source slice covered by the node's
72
- // position range, trimmed of surrounding whitespace. Same byte range
73
- // scanner.GetTextOfNode would read; safe for any Kind because it does
74
- // not inspect per-Kind data fields.
93
+ // nodeSourceText checks the containing source range and trims surrounding
94
+ // whitespace. It does not perform scanner.GetTextOfNode's SkipTrivia step, so
95
+ // leading comments may remain. Kind-specific payloads are not inspected here;
96
+ // source ownership still requires a terminating, valid parent chain.
75
97
  func nodeSourceText(n *innerast.Node) string {
76
98
  file := innerast.GetSourceFileOfNode(n)
77
99
  if file == nil {