-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Restructure virtual types validator #14799
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/52639/ |
import type * as t from "@babel/types"; | ||
const { isCompatTag } = react; | ||
import type { VirtualTypeAliases } from "./virtual-types"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this PR I have to memoize the link from typing to implementation
path.isBindingIdentifier => virtualTypes["isBindingIdentifier"].checkType
Now they are placed together. However, the typings and implementations can not be merged because TS does not support this
assertion in non-class functions, although they will be eventually injected to the NodePath
prototype.
checkPath({ node }: NodePath<t.ForOfStatement>): boolean { | ||
return node.await === true; | ||
}, | ||
checkPath: path => path.isForAwaitStatement(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we simplify Wrapper
to remove checkPath
? (I'm not sure if this is possible, I try to understand the codes but they are a bit complicated)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. The checkPath
applies additional selection logic based on Wrapper#types
.
babel/packages/babel-traverse/src/visitors.ts
Lines 285 to 287 in 029fa17
if (wrapper.checkPath(path)) { | |
return fn.apply(this, arguments); | |
} |
Say if we have a ReferencedIdentifier
visitor, Babel knows an Identifier
could be a ReferencedIdentifier
from Wrapper#types
. Then it wraps the visitor so that the wrapped visitor will first run wrapper.checkPath
, if the node is a ReferencedIdentifier
, the wrapped visitor then applies the original visitor to the Identifier
node, otherwise the visitor is inactivated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we pass nodeType
to
fns[type] = wrapCheck(wrapper, fns[type]); |
wrapCheck
function so that it doesn't rely anymore on checkPath
? Every checkPath
function just forwards the check to the .is*
method with the same name as the virtual type.
function wrapCheck(nodeType: String, fn: Function) {
const newFn = function (this: unknown, path: NodePath) {
if (path[`is${nodeType}`]()) {
return fn.apply(this, arguments);
}
};
newFn.toString = () => fn.toString();
return newFn;
}
Or, we can make checkPath
just the check method name (as a string), to avoid the unnecessary intermediate function:
import * as virtualValidators from "./virtual-types-validator.ts"
export const ForAwaitStatement: Wrapper = {
types: ["ForOfStatement"],
checkPath: virtualValidators.isForAwaitStatement,
};
function wrapCheck(wrapper: Wrapper, fn: Function) {
const newFn = function (this: unknown, path: NodePath) {
if (wrapper.checkPath.call(path)) {
return fn.apply(this, arguments);
}
};
newFn.toString = () => fn.toString();
return newFn;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR seems to expose more methods, but that's fine for me.
This PR does not expose any new methods. In current main, the virtual types validators are injected by babel/packages/babel-traverse/src/path/index.ts Lines 275 to 278 in 029fa17
which invokes In this PR we move the implementation to the explicit |
This PR is extracted from #14179. The goal is to remove
packages/babel-traverse/scripts/generators/virtual-types.js
so that the build script doesn't rely on the internalvirtualTypes
. The virtual type validator typings are moved topath/lib/virtual-types-validator.ts
, followed by implementations moved frompath/lib/virtual-types
.I think it is fine to remove the extra build step because virtual types are not frequently updated compared to AST types.