-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
parseFileSync span bug #1366
Comments
By design,just change the file name passed into the |
I think it's a bug |
It's not a bug. |
const compiler = new Compiler()
{"type":"Module","span":{"start":0,"end":11,"ctxt":0},"body":[{"type":"VariableDeclaration","span":{"start":0,"end":11,"ctxt":0},"kind":"const","declare":false,"declarations":[{"type":"VariableDeclarator","span":{"start":6,"end":11,"ctxt":0},"id":{"type":"Identifier","span":{"start":6,"end":7,"ctxt":0},"value":"a","typeAnnotation":null,"optional":false},"init":{"type":"NumericLiteral","span":{"start":10,"end":11,"ctxt":0},"value":1},"definite":false}]}],"interpreter":null}
====
{"type":"Module","span":{"start":12,"end":23,"ctxt":0},"body":[{"type":"VariableDeclaration","span":{"start":12,"end":23,"ctxt":0},"kind":"const","declare":false,"declarations":[{"type":"VariableDeclarator","span":{"start":18,"end":23,"ctxt":0},"id":{"type":"Identifier","span":{"start":18,"end":19,"ctxt":0},"value":"b","typeAnnotation":null,"optional":false},"init":{"type":"NumericLiteral","span":{"start":22,"end":23,"ctxt":0},"value":1},"definite":false}]}],"interpreter":null} second file still start with 12, not working |
Having the same issue. Any known workarounds? Here's a slightly simpler reproduction:
|
Currently, there's no workaround. I think api to convert a span from swc to line-col span is required, though. |
@kdy1 why is line-col needed? Can't \n just be consistently be used for line endings if it's a windows/unix EOL problem? |
@mikob What do you mean? line-col is about span, not line endings. |
Right, I just don't see the immediate benefit to using line-col. I thought maybe because you wanted to be explicit about line endings. I use spans to get offsets and extract pieces of the code using |
Ran into this issue too trying to make an adapter for estree AST. |
@jdalton I want to remove |
Ah cool. Will there still be a way to expose the AST? I currently have been able workaround this issue using an adapter to track the offset of the start of the root AST and smooth over the other differences with estree. |
You mean, you want to get actual offset from This API, if added, will be removed along with |
@kdy1 I've noticed some confusion around this from another user. Folks use the AST from parsers, in formats like babylon and estree, to perform source transformations. The AST usually has properties such as |
Most ast nodes already have |
Are we talking past each other? Maybe an example would help. In ast-explorer using acorn with an example of |
Now I understand it. But I'm not sure about the change. |
This bug is kind of deal breaker for switching to swc, In our product we need to invoke parser multiple times in the same process. Increasing span.start with each invocation will make swc stopped working at some point – especially when parsing huge file. |
…ogram/Module node due to SWC issue swc-project/swc#1366
- add move away from swc to roadmap because of accumalating offsets (swc-project/swc#1366) - strict requirements for doc color in keyvalue properties
For my case, I need this to convert spans to line-column values in an LSP that I am implementing. Currently, this breaks in swc when I have a file with a comment at the top, because that offsets all of the positions of my spans. |
…ogram/Module node due to SWC issue swc-project/swc#1366
There is a workaround if you run each parse call in it's own import { spawnSync } from 'node:child_process'
import { join } from 'node:path'
import type { Module } from '@swc/core'
const spawnChild = (...args: string[]) => {
const { stdout } = spawnSync('node', [join(import.meta.dirname, 'child.js'), ...args])
const ast = JSON.parse(stdout.toString()) as Module
return ast
}
export const reparse = (source: string): Module => {
return spawnChild(source)
}
const ast1 = reparse('const foo = "bar"')
const ast2 = reparse('const foo = "bar"')
console.log(ast1.span.start === ast2.span.start) // true child.js import { argv, stdout } from 'node:process'
import { parseSync } from '@swc/core'
stdout.write(JSON.stringify(parseSync(argv[2]))) I've published this to npm as |
I ran into this when unit testing a function that performed an The workaround was to always check the let parseOffset = 0
if (process.env.NODE_ENV === 'test') {
parseOffset = (await swc.parse('')).span.end
}
// Pass the offset as needed. Example function below
function insertBeforeAndAfterSWC(
content: string,
span: ModuleItem['span'],
parseOffset: number,
): string {
const { end: preOffsetEnd, start: preOffsetStart } = span
const start = preOffsetStart - parseOffset
const end = preOffsetEnd - parseOffset
const insert = (pos: number, text: string): string => {
return content.slice(0, pos) + text + content.slice(pos)
}
// Perform manipulation of code
content = insert(end - 1, ')')
content = insert(start - 1, 'withPayload(')
return content
} |
Support new `next.config.ts` config file. Had to do some weird gymnastics around `swc` in order to use it within unit tests. Had to pass through the `parsed.span.end` value of any previous iteration and account for it. Looks to be an open issue here: swc-project/swc#1366 Fixes #7318
This introduces a framework for analyzer errors that allow analysis to continue (instead of exiting immediately after the first error). It also introduces pretty-printing of errors, with an excerpt of the file where the error was encountered. Some things are still missing: * Tests that expect errors do not check the error type, just that an error happened. * A lot of errors still throw instead of continuing. * Error codes are inconsistent and overloaded. * Error messages are inconsistent in style. * Because of [an SWC bug](swc-project/swc#1366), file excerpts in imported files will be wrong. However, this PR still adds more functionality than previously existed without removing any, so I'm putting it in despite its incompleteness. See merge request dejawu/ectype!5
This PR migrates the static analyzer to the [acorn](https://github.com/acornjs/acorn) library. There's a few things that motivate this: - SWC has [a bug](swc-project/swc#1366) where span positions are not reset when scanning multiple files in the same session. - SWC's documentation is all for the Rust side, which doesn't match up 1:1 with the JS side. - SWC does not recognize comments, which I want to use later to annotate tests (e.g. for cases where an error is expected). I chose acorn because it's by far the most popular JS parsing library, and it supports all the features I need. When I found out Marijn Haverbeke was behind it, that sealed the deal for me. PR: dejawu/ectype!6
I think this get even worse now, it seems span of Module now exclude comments before first statement and after last statement, so use span.end of previous parse as offset will yield incorrect results now. |
Same issue, can we solve this by make a new Compiler here ? |
@JSerFeng Why are you using |
@kdy1 hi, what should be used instead? |
@smokeelow You should use rust APIs instead |
I'm using |
@JSerFeng |
Are all |
Yeap. |
astexplore and swc-playground are very helpful, if js api is deprecated, are those 2 tools stay available after then ? |
That's why |
Since 2022, I have noticed many issues with the |
Removing an API is a breaking change. That's the only important blocker. |
Describe the bug
same file parse twice, different output
Input code
import { parseFileSync } from '@swc/core';
const ast = parseFileSync('./test.jsx', { jsx: true, syntax: 'ecmascript', comments: true, dynamicImport: true, decorators: true, decoratorsBeforeExport: true, script: true })
const ast1 = parseFileSync('./test.jsx', { jsx: true, syntax: 'ecmascript', comments: true, dynamicImport: true, decorators: true, decoratorsBeforeExport: true, script: true })
console.log(JSON.stringify(ast))
console.log('====')
console.log(JSON.stringify(ast1))
first ast span start at 0, second start at 12
Config
{ // Please copy and paste your .swcrc file here }
Expected behavior
A clear and concise description of what you expected to happen.
Version
The version of @swc/core:
"@swc/core": "^1.2.46",
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: