summaryrefslogtreecommitdiff
path: root/node_modules/@babel/plugin-transform-classes/lib/transformClass.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@babel/plugin-transform-classes/lib/transformClass.js')
-rw-r--r--node_modules/@babel/plugin-transform-classes/lib/transformClass.js80
1 files changed, 46 insertions, 34 deletions
diff --git a/node_modules/@babel/plugin-transform-classes/lib/transformClass.js b/node_modules/@babel/plugin-transform-classes/lib/transformClass.js
index 460fef5a..57811677 100644
--- a/node_modules/@babel/plugin-transform-classes/lib/transformClass.js
+++ b/node_modules/@babel/plugin-transform-classes/lib/transformClass.js
@@ -35,7 +35,6 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
hasConstructor: false,
body: [],
superThises: [],
- pushedConstructor: false,
pushedInherits: false,
pushedCreateClass: false,
protoAlias: null,
@@ -169,7 +168,7 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
if (!_core.types.isNullLiteral(args[i])) lastNonNullIndex = i;
}
args = args.slice(0, lastNonNullIndex + 1);
- body.push(_core.types.expressionStatement(createClassHelper(args)));
+ body.push(_core.types.returnStatement(createClassHelper(args)));
classState.pushedCreateClass = true;
}
}
@@ -215,25 +214,18 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
if (!classState.isDerived) return;
const path = classState.userConstructorPath;
const body = path.get("body");
+ const constructorBody = path.get("body");
+ let maxGuaranteedSuperBeforeIndex = constructorBody.node.body.length;
path.traverse(findThisesVisitor);
let thisRef = function () {
const ref = path.scope.generateDeclaredUidIdentifier("this");
+ maxGuaranteedSuperBeforeIndex++;
thisRef = () => _core.types.cloneNode(ref);
return ref;
};
- for (const thisPath of classState.superThises) {
- const {
- node,
- parentPath
- } = thisPath;
- if (parentPath.isMemberExpression({
- object: node
- })) {
- thisPath.replaceWith(thisRef());
- continue;
- }
- thisPath.replaceWith(_core.types.callExpression(classState.file.addHelper("assertThisInitialized"), [thisRef()]));
- }
+ const buildAssertThisInitialized = function () {
+ return _core.types.callExpression(classState.file.addHelper("assertThisInitialized"), [thisRef()]);
+ };
const bareSupers = [];
path.traverse(_core.traverse.visitors.merge([_helperEnvironmentVisitor.default, {
Super(path) {
@@ -248,25 +240,51 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
}
}
}]));
- let guaranteedSuperBeforeFinish = !!bareSupers.length;
for (const bareSuper of bareSupers) {
wrapSuperCall(bareSuper, classState.superName, thisRef, body);
- if (guaranteedSuperBeforeFinish) {
+ if (maxGuaranteedSuperBeforeIndex >= 0) {
+ let lastParentPath;
bareSuper.find(function (parentPath) {
- if (parentPath === path) {
+ if (parentPath === constructorBody) {
+ maxGuaranteedSuperBeforeIndex = Math.min(maxGuaranteedSuperBeforeIndex, lastParentPath.key);
return true;
}
if (parentPath.isLoop() || parentPath.isConditional() || parentPath.isArrowFunctionExpression()) {
- guaranteedSuperBeforeFinish = false;
+ maxGuaranteedSuperBeforeIndex = -1;
return true;
}
+ lastParentPath = parentPath;
});
}
}
+ for (const thisPath of classState.superThises) {
+ const {
+ node,
+ parentPath
+ } = thisPath;
+ if (parentPath.isMemberExpression({
+ object: node
+ })) {
+ thisPath.replaceWith(thisRef());
+ continue;
+ }
+ let thisIndex;
+ thisPath.find(function (parentPath) {
+ if (parentPath.parentPath === constructorBody) {
+ thisIndex = parentPath.key;
+ return true;
+ }
+ });
+ if (maxGuaranteedSuperBeforeIndex !== -1 && thisIndex > maxGuaranteedSuperBeforeIndex) {
+ thisPath.replaceWith(thisRef());
+ } else {
+ thisPath.replaceWith(buildAssertThisInitialized());
+ }
+ }
let wrapReturn;
if (classState.isLoose) {
wrapReturn = returnArg => {
- const thisExpr = _core.types.callExpression(classState.file.addHelper("assertThisInitialized"), [thisRef()]);
+ const thisExpr = buildAssertThisInitialized();
return returnArg ? _core.types.logicalExpression("||", returnArg, thisExpr) : thisExpr;
};
} else {
@@ -279,8 +297,9 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
};
}
const bodyPaths = body.get("body");
+ const guaranteedSuperBeforeFinish = maxGuaranteedSuperBeforeIndex !== -1 && maxGuaranteedSuperBeforeIndex < bodyPaths.length;
if (!bodyPaths.length || !bodyPaths.pop().isReturnStatement()) {
- body.pushContainer("body", _core.types.returnStatement(guaranteedSuperBeforeFinish ? thisRef() : wrapReturn()));
+ body.pushContainer("body", _core.types.returnStatement(guaranteedSuperBeforeFinish ? thisRef() : buildAssertThisInitialized()));
}
for (const returnPath of classState.superReturns) {
returnPath.get("argument").replaceWith(wrapReturn(returnPath.node.argument));
@@ -381,15 +400,9 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
construct.params = method.params;
_core.types.inherits(construct.body, method.body);
construct.body.directives = method.body.directives;
- pushConstructorToBody();
- }
- function pushConstructorToBody() {
- if (classState.pushedConstructor) return;
- classState.pushedConstructor = true;
if (classState.hasInstanceDescriptors || classState.hasStaticDescriptors) {
pushDescriptors();
}
- classState.body.push(classState.construct);
pushInheritsToBody();
}
function pushInheritsToBody() {
@@ -480,7 +493,7 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
constructorBody.body.unshift(_core.types.expressionStatement(_core.types.callExpression(classState.file.addHelper("classCallCheck"), [_core.types.thisExpression(), _core.types.cloneNode(classState.classRef)])));
}
const isStrict = path.isInStrictMode();
- let constructorOnly = classState.classId && body.length === 1;
+ let constructorOnly = classState.classId && body.length === 0;
if (constructorOnly && !isStrict) {
for (const param of classState.construct.params) {
if (!_core.types.isIdentifier(param)) {
@@ -489,19 +502,18 @@ function transformClass(path, file, builtinClasses, isLoose, assumptions, suppor
}
}
}
- const directives = constructorOnly ? body[0].body.directives : [];
+ const directives = constructorOnly ? classState.construct.body.directives : [];
if (!isStrict) {
directives.push(_core.types.directive(_core.types.directiveLiteral("use strict")));
}
if (constructorOnly) {
- const expr = _core.types.toExpression(body[0]);
+ const expr = _core.types.toExpression(classState.construct);
return classState.isLoose ? expr : createClassHelper([expr]);
}
- let returnArg = _core.types.cloneNode(classState.classRef);
- if (!classState.pushedCreateClass && !classState.isLoose) {
- returnArg = createClassHelper([returnArg]);
+ if (!classState.pushedCreateClass) {
+ body.push(_core.types.returnStatement(classState.isLoose ? _core.types.cloneNode(classState.classRef) : createClassHelper([_core.types.cloneNode(classState.classRef)])));
}
- body.push(_core.types.returnStatement(returnArg));
+ body.unshift(classState.construct);
const container = _core.types.arrowFunctionExpression(closureParams, _core.types.blockStatement(body, directives));
return _core.types.callExpression(container, closureArgs);
}