-
Notifications
You must be signed in to change notification settings - Fork 19
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
Scoping issue #32
Comments
I assume the issue here is related to For my own background knowledge/context, it seems that
I wonder if the root issue lies in
I haven't looked closely at the code here and how it's used, but would something like
Looking at the linked issue (facebook/jscodeshift#263), it seems that a 'raw' block will lead to scope issues currently. Example code that breaks: const x = 42
{
const x = 47
console.log(x)
}
console.log(x) Reviewing
I was playing around with some PoC code with Running $ node espree-eslint-scope_2.js
-= SCOPE INFO =-
Scope: type=global (block.type=Program) block.id?.name=undefined implicit=x,x,console,x,console,x
Variable: x [
{ type: 'Variable', kind: 'const' },
{ type: 'Variable', kind: 'const' }
] References: 4
-= ANALYSIS RESULT =-
{
"type": "global",
"implicitGlobals": [
"x",
"x",
"console",
"x",
"console",
"x"
],
"identifiers": [
{
"name": "x",
"types": [
{
"type": "Variable",
"kind": "const"
},
{
"type": "Variable",
"kind": "const"
}
]
}
],
"childScopes": []
} I think this may mean that It seems ChatGPT agrees with that: DetailsMe:
ChatGPT:
I've opened a bug for this on Edit: Seems I was wrong about that, see my below comment for updates: These tools may also be useful for checking how |
I just did another test in the REPL, this time just using PoC Codeconst parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const code = `
const x = 42;
{
const x = 47;
console.log(x);
}
console.log(x);
`;
const ast = parser.parse(code, {
sourceType: 'module',
// plugins: [
// // Add any necessary plugins
// ],
});
const scopes = new Set();
function collectScopes(path) {
if (path.scope && !scopes.has(path.scope)) {
scopes.add(path.scope);
path.scope.parent && collectScopes(path.findParent((p) => p.scope));
}
}
traverse(ast, {
enter(path) {
collectScopes(path);
},
});
console.log("\n-= Scopes and Bindings =-\n");
scopes.forEach((scope) => {
console.group(
`Scope (uid=${scope.uid}, path.type=${scope.path.type})`
);
console.log(
'Bindings:',
JSON.stringify(Object.keys(scope.bindings), null, 2)
);
// console.log(scope);
console.groupEnd();
console.log();
}); This seems to have correctly output the 2 scopes as expected: $ node babel-scopes.js
-= Scopes and Bindings =-
Scope (uid=0, path.type=Program)
Bindings: [
"x"
]
Scope (uid=1, path.type=BlockStatement)
Bindings: [
"x"
] |
It seems I was just using There are some useful docs links and discoveries in my comment on the above issue:
And I also updated my REPL to fix the code and make it work properly now: With the very basic minimal example being: const espree = require('espree');
const eslintScope = require('eslint-scope');
const exampleJSCode = `
const x = 42
{
const x = 47
console.log(x)
}
console.log(x)
`
const commonParserOptions = {
ecmaVersion: 2020,
sourceType: 'module', // script, module, commonjs
}
// Parse the JavaScript code into an AST with range information
const ast = espree.parse(jsCode, {
...commonParserOptions,
range: true // Include range information
});
// Analyze the scopes in the AST
// See the .analyze options in the source for more details
// https://github.com/eslint/eslint-scope/blob/957748e7fb741dd23f521af0c124ce6da0848997/lib/index.js#L111-L131
// See the following for more details on the ScopeManager interface:
// https://eslint.org/docs/latest/extend/scope-manager-interface
// https://github.com/eslint/eslint-scope/blob/main/lib/scope-manager.js
const scopeManager = eslintScope.analyze(
ast,
{
...commonParserOptions,
nodejsScope: false,
}
);
console.log('ScopeManager.scopes=', scopeManager.scopes) See the |
Babel and eslint are handling it correctly; the issue is from ast-types. The reason why I didn't use them is to maintain only one ast tool been used. We can either fix ast-types ourselves, and potentially PR back to the upstream. Using Babel or other tools for scoping is doable, but it will be hard to maintain, and there will be some performance punishment. I will check some references you provided this weekend to see what can we do. |
@pionxzh Yup. I just wanted to test/ensure that the other suggestions I was making actually handled it properly.
@pionxzh Yeah, that definitely makes sense. I wasn't suggesting them so much in a 'use multiple ast tools' way. More in a 'if we need to replace the current choice, what are some alternatives that handle it properly'
@pionxzh nods Part of the reason I was looking at some of the alternatives is that the upstream
So my thinking was more in the space of "if the current underlying tools are unmaintained and buggy, what are the 'best modern alternative' choices we can use; and particularly ones that are quite heavily used by others, and so are likely to stay maintained/updated.
@pionxzh When you say hard to maintain/performance punishment; do you just mean if we were using multiple AST tools at the same time? Or do you mean by switching to one of those at all?
@pionxzh Sounds good :) |
I mean it would be hard to maintain with multiple AST tools. |
Yup, makes sense. I'd definitely also recommend sticking to 1 for that reason. |
I'm curious, what benefits does I asked ChatGPT, and it seemed to suggest that there is a 'higher level API' from I'm curious whether that 'higher level API' from ChatGPT ResponseQuestion:
Response:
Edit: For my own reference, here are the code locations currently referencing
I also note that there is a And it might also potentially make sense to refactor some of these utils into that ast-utils package as well maybe? Edit 2: Raised a new issue for the 'refactor into |
|
nods that makes sense, and I suspected it was likely going to be something like that, but I wanted to confirm my assumptions (given that the current I was basically thinking about what the 'main advantages' are that are being gained from each of the AST related libs; as that then makes it easier to think about whether there is a 'better' solution that still meets those needs/constraints. |
I think jscodeshift's README provides a quite detailed description of each part of the components. 🤔 |
@pionxzh Yeah, in terms of |
The current identifier renaming is not 100% accurate. By inspecting the unpacking snapshot, you can tell that some variable was wrongly renamed to
export
orrequire
during the unpacking process. Mostly becauseast-types
are giving us wrong scope information, and it's no longer well-maintained. We need to either patch it or find an alternative.renameTo
and block scope facebook/jscodeshift#263)The best solution would be to fix it in the upstream.
Let's track the progress at facebook/jscodeshift#500
The text was updated successfully, but these errors were encountered: