Add support for extending builtins (#7020)
This commit is contained in:
committed by
Henry Zhu
parent
148fe7d3ff
commit
0c885b3200
@@ -3,6 +3,15 @@ import VanillaTransformer from "./vanilla";
|
||||
import annotateAsPure from "@babel/helper-annotate-as-pure";
|
||||
import nameFunction from "@babel/helper-function-name";
|
||||
import { types as t } from "@babel/core";
|
||||
import globals from "globals";
|
||||
|
||||
const getBuiltinClasses = category =>
|
||||
Object.keys(globals[category]).filter(name => /^[A-Z]/.test(name));
|
||||
|
||||
const builtinClasses = new Set([
|
||||
...getBuiltinClasses("builtin"),
|
||||
...getBuiltinClasses("browser"),
|
||||
]);
|
||||
|
||||
export default function(api, options) {
|
||||
const { loose } = options;
|
||||
@@ -54,7 +63,9 @@ export default function(api, options) {
|
||||
|
||||
node[VISITED] = true;
|
||||
|
||||
path.replaceWith(new Constructor(path, state.file).run());
|
||||
path.replaceWith(
|
||||
new Constructor(path, state.file, builtinClasses).run(),
|
||||
);
|
||||
|
||||
if (path.isCallExpression()) {
|
||||
annotateAsPure(path);
|
||||
|
||||
@@ -4,6 +4,8 @@ import optimiseCall from "@babel/helper-optimise-call-expression";
|
||||
import * as defineMap from "@babel/helper-define-map";
|
||||
import { traverse, template, types as t } from "@babel/core";
|
||||
|
||||
type ReadonlySet<T> = Set<T> | { has(val: T): boolean };
|
||||
|
||||
const noMethodVisitor = {
|
||||
"FunctionExpression|FunctionDeclaration"(path) {
|
||||
path.skip();
|
||||
@@ -61,7 +63,7 @@ const findThisesVisitor = traverse.visitors.merge([
|
||||
]);
|
||||
|
||||
export default class ClassTransformer {
|
||||
constructor(path: NodePath, file) {
|
||||
constructor(path: NodePath, file, builtinClasses: ReadonlySet<string>) {
|
||||
this.parent = path.parent;
|
||||
this.scope = path.scope;
|
||||
this.node = path.node;
|
||||
@@ -93,6 +95,12 @@ export default class ClassTransformer {
|
||||
|
||||
this.superName = this.node.superClass || t.identifier("Function");
|
||||
this.isDerived = !!this.node.superClass;
|
||||
|
||||
const { name } = this.superName;
|
||||
this.extendsNative =
|
||||
this.isDerived &&
|
||||
builtinClasses.has(name) &&
|
||||
!this.scope.hasBinding(name, /* noGlobals */ true);
|
||||
}
|
||||
|
||||
run() {
|
||||
@@ -112,7 +120,13 @@ export default class ClassTransformer {
|
||||
|
||||
//
|
||||
if (this.isDerived) {
|
||||
closureArgs.push(superName);
|
||||
if (this.extendsNative) {
|
||||
closureArgs.push(
|
||||
t.callExpression(this.file.addHelper("wrapNativeSuper"), [superName]),
|
||||
);
|
||||
} else {
|
||||
closureArgs.push(superName);
|
||||
}
|
||||
|
||||
superName = this.scope.generateUidIdentifierBasedOnNode(superName);
|
||||
closureParams.push(superName);
|
||||
|
||||
Reference in New Issue
Block a user