fix(volar): use ts.getTokenPosOfNode instead of node.getStart#2630
fix(volar): use ts.getTokenPosOfNode instead of node.getStart#2630posva merged 2 commits intovuejs:mainfrom
ts.getTokenPosOfNode instead of node.getStart#2630Conversation
📝 WalkthroughWalkthroughReplaced direct use of Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for vue-router canceled.
|
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2630 +/- ##
=======================================
Coverage 85.58% 85.58%
=======================================
Files 86 86
Lines 9963 9963
Branches 2285 2284 -1
=======================================
Hits 8527 8527
Misses 1423 1423
Partials 13 13 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/router/src/volar/entries/sfc-typed-router.ts`:
- Around line 78-81: Add a short explanatory comment above the (ts as
any).getTokenPosOfNode(...) usage that documents why the internal API
getTokenPosOfNode is used instead of node.getStart(), referencing the symbols
getTokenPosOfNode, node.getStart and sfc.scriptSetup!.ast; state that
node.getStart is missing on some JS AST node shapes causing the "node.getStart
is not a function" runtime error, acknowledge that getTokenPosOfNode is an
internal TypeScript API (fragile across TS versions), and note that this is an
intentional pragmatic workaround for Volar plugin behavior to be revisited if
TypeScript exposes a stable public alternative.
| const start: number = (ts as any).getTokenPosOfNode( | ||
| node, | ||
| sfc.scriptSetup!.ast | ||
| ) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
TypeScript getTokenPosOfNode internal API private unstable
💡 Result:
getTokenPosOfNode is not a supported TypeScript Compiler API: in the TypeScript source it’s explicitly marked /** @internal */ (i.e., intended for TypeScript’s own compiler/language-service code, not external consumers). It computes the “first real token” position for a node by skipping trivia (whitespace/comments) with special handling for JSDoc and SyntaxList. [1]
Because it’s @internal, it’s intentionally omitted from the supported public surface area (TypeScript has historically removed internal .d.ts surfaces and can change/remove internal helpers without notice). The TypeScript team documents that internal APIs/helpers are not intended for external use and have been cleaned up/removed in the past. [2]
If you need a stable alternative, prefer public node positioning APIs such as:
node.getStart(sourceFile?, includeJsDocComment?)node.getFullStart()node.getEnd()
These are part of the supported compiler API, unlike getTokenPosOfNode. [1]
Sources:
[1] TypeScript source (utilities.ts) showing getTokenPosOfNode is @internal and how it works.
[2] TypeScript Wiki: API breaking changes / internal helpers and removal of internal .d.ts surfaces.
🏁 Script executed:
# Check the actual file to confirm the code and context
fd "sfc-typed-router.ts" --type fRepository: vuejs/router
Length of output: 109
🏁 Script executed:
# Search for references to getTokenPosOfNode in the codebase
rg "getTokenPosOfNode" --type tsRepository: vuejs/router
Length of output: 174
🏁 Script executed:
# Look for the issue reference in commit messages or PRs
rg "language-tools#5962|node.getStart is not a function" --type ts -A 2 -B 2Repository: vuejs/router
Length of output: 38
🏁 Script executed:
# Read the full context around lines 78-81 in the file
cat -n packages/router/src/volar/entries/sfc-typed-router.ts | sed -n '60,95p'Repository: vuejs/router
Length of output: 1431
🏁 Script executed:
# Look for any comments or documentation about why internal API is used
rg -A 5 -B 5 "getTokenPosOfNode" packages/router/src/volar/entries/sfc-typed-router.tsRepository: vuejs/router
Length of output: 396
🏁 Script executed:
# Check imports and understand what `ts` object is
cat -n packages/router/src/volar/entries/sfc-typed-router.ts | sed -n '1,30p'Repository: vuejs/router
Length of output: 1398
🏁 Script executed:
# Search for any discussions or comments about the fix in the file
rg "getStart|getTokenPos" packages/router/src/volar/entries/sfc-typed-router.ts -B 3 -A 3Repository: vuejs/router
Length of output: 258
Pragmatic use of internal TypeScript API getTokenPosOfNode to fix runtime error.
This is a necessary fix for the node.getStart is not a function runtime error when processing JavaScript files. However, getTokenPosOfNode is marked @internal in TypeScript and not part of the public API surface, making it fragile against future TypeScript releases.
While Volar plugins inherently depend on TypeScript internals, consider adding a comment explaining why this internal API is necessary instead of node.getStart(), both for future maintainers and to acknowledge the trade-off:
} else {
+ // Use internal ts.getTokenPosOfNode to compute the token start position
+ // node.getStart() fails at runtime in this context when processing JS files
const start: number = (ts as any).getTokenPosOfNode(
node,
sfc.scriptSetup!.ast
)🤖 Prompt for AI Agents
In `@packages/router/src/volar/entries/sfc-typed-router.ts` around lines 78 - 81,
Add a short explanatory comment above the (ts as any).getTokenPosOfNode(...)
usage that documents why the internal API getTokenPosOfNode is used instead of
node.getStart(), referencing the symbols getTokenPosOfNode, node.getStart and
sfc.scriptSetup!.ast; state that node.getStart is missing on some JS AST node
shapes causing the "node.getStart is not a function" runtime error, acknowledge
that getTokenPosOfNode is an internal TypeScript API (fragile across TS
versions), and note that this is an intentional pragmatic workaround for Volar
plugin behavior to be revisited if TypeScript exposes a stable public
alternative.
posva
left a comment
There was a problem hiding this comment.
Thanks! Is there really no way to avoid the as any? Is this what you told me about ts internal APIs that have existed for a long time?
|
Not that but it has also been stable for many years and has been used in language tools. |
fix vuejs/language-tools#5962
Summary by CodeRabbit