Repository navigation
feat: use tokens for more accurate sourcemaps (alternative approach) - #235
Conversation
The root visitor maps every node's start and end, which covers tokens that open a node. Tokens inside a node have no node boundary to anchor them: the brackets of a computed key, the parentheses of parameter lists, calls and control-flow heads, the braces of import and export lists, static blocks, switch and enum bodies, template interpolations, and every keyword written after a node's first token (`function` after `async`, `else`, `finally`, `while` in `do … while`, `default` after `export`, `type` after `import`, class and member modifiers, `extends`, `implements`, `in`, `of`, `as`, `satisfies`). A new `tokens` option takes the parser's token list (Acorn's `onToken`, Babel's `tokens`, ESLint-style `ast.tokens`). The tokens of interest are indexed once, sorted if the parser emitted them out of order, and each one is found by a bounded binary search from a position the AST does know. Without tokens they stay unmapped. Closing delimiters that end a node (`)` of a call, `]` of an array or computed member, `}` of an object, switch, enum or interface body) are mapped from the node's end without tokens, as BlockStatement already does. Printed output is unchanged; 61 sample maps gain segments. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A decorated class's decorators are printed before `export`, so the root visitor cannot map the export node's start where it is written. Emit that start once the decorators are out: the export node begins at `export` with both Acorn and typescript-estree, whichever side of it the decorators were written on. Instead of clearing the declaration's decorators and location while it is printed, remember that its decorators were printed. The root visitor then maps its start when that start is the `class` keyword (typescript-estree, decorators written before `export`) and skips it when it is a decorator (Acorn, see sveltejs/acorn-typescript#117), and the keyword lookup can locate `class`, `abstract` and the rest from the tokens because the node keeps its location. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Deferred from the first version of this branch until #212 gave the catch clause its own visitor. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Install the latest version of pnpm add https://pkg.svelte.dev/esrap/c/0353368b17cefa5577abc245b88f8dbd6d011151Open in |
🦋 Changeset detectedLatest commit: 0353368 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
yeah, this is definitely a better direction 👍 |
| this.#commands.push(content); | ||
| this.location(node.loc.end.line, node.loc.end.column); | ||
| } else if (token && value) { | ||
| const start = content.indexOf(value); |
There was a problem hiding this comment.
Is it not possible for this to false positive and exit early if the same string appears more than once in the source?
There was a problem hiding this comment.
no, this is purely about handling whitespace — content can be a string like " potato " in which case value is "potato", and this just yoinks out the leading " " so that they're treated separately (and potato is treated as a token) despite it being a single context.write(...) call. is just for convenience
This is an alternative to #213, designed to be a bit less labour-intensive — rather than all the visitor code in
tsneeding to be token-aware, it stores token state on the context, and extracts tokens (if provided) insidecontext.write.There's a little bit of footwork involved in matching openers with closers, but other than that it's fairly simple — on visiting a node with a
locproperty, we set the current frame to that node's boundaries, and advance through the array within that frame each time we consume a token. If visiting a node withoutloc, token extraction is disabled.I prefer this because if we update visitor code we don't need to remember to carefully use
write_atandwrite_beforeandlocateandenclosingetc — it's all taken care of us. As far as I can tell it's equivalently reliable. @leonidaz thoughts?