Skip to content

Commit

Permalink
Remove Super from Expression alias (#14750)
Browse files Browse the repository at this point in the history
  • Loading branch information
JLHwung authored Jul 13, 2022
1 parent bcf8b22 commit 0df9f62
Show file tree
Hide file tree
Showing 17 changed files with 97 additions and 37 deletions.
4 changes: 2 additions & 2 deletions packages/babel-generator/src/generators/expressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function Super(this: Printer) {
}

function isDecoratorMemberExpression(
node: t.Expression | t.V8IntrinsicIdentifier,
node: t.Expression | t.Super | t.V8IntrinsicIdentifier,
): boolean {
switch (node.type) {
case "Identifier":
Expand All @@ -129,7 +129,7 @@ function isDecoratorMemberExpression(
}
}
function shouldParenthesizeDecoratorExpression(
node: t.Expression | t.V8IntrinsicIdentifier,
node: t.Expression | t.Super | t.V8IntrinsicIdentifier,
) {
if (node.type === "CallExpression") {
node = node.callee;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type * as t from "@babel/types";

export default function (opts: {
build: (
left: t.Expression | t.PrivateName,
left: t.Expression | t.PrivateName | t.Super,
right: t.Expression,
) => t.Expression;
operator: t.BinaryExpression["operator"];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ const privateNameHandlerSpec: Handler<PrivateNameState & Receiver> & Receiver =
{
memoise(member, count) {
const { scope } = member;
const { object } = member.node;
const { object } = member.node as { object: t.Expression };

const memo = scope.maybeGenerateMemoised(object);
if (!memo) {
Expand All @@ -269,10 +269,10 @@ const privateNameHandlerSpec: Handler<PrivateNameState & Receiver> & Receiver =
},

receiver(member) {
const { object } = member.node;
const { object } = member.node as { object: t.Expression };

if (this.memoiser.has(object)) {
return t.cloneNode(this.memoiser.get(object) as t.Expression);
return t.cloneNode(this.memoiser.get(object));
}

return t.cloneNode(object);
Expand Down Expand Up @@ -466,7 +466,7 @@ const privateNameHandlerLoose: Handler<PrivateNameState> = {
boundGet(member) {
return t.callExpression(
t.memberExpression(this.get(member), t.identifier("bind")),
[t.cloneNode(member.node.object)],
[t.cloneNode(member.node.object as t.Expression)],
);
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,12 @@ const handle = {
const { object } = regular;
context = member.scope.maybeGenerateMemoised(object);
if (context) {
regular.object = assignmentExpression("=", context, object);
regular.object = assignmentExpression(
"=",
context,
// object must not be Super when `context` is an identifier
object as t.Expression,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export function skipTransparentExprWrappers(
}

export function skipTransparentExprWrapperNodes(
node: t.Expression,
): t.Expression {
node: t.Expression | t.Super,
): t.Expression | t.Super {
while (isTransparentExprWrapper(node)) {
node = node.expression;
}
Expand Down
1 change: 1 addition & 0 deletions packages/babel-plugin-proposal-function-bind/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default declare(api => {
bind.callee.object = t.assignmentExpression(
"=",
tempId,
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.foo(?)`
bind.callee.object,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export default declare(api => {
(lhs as t.MemberExpression).object = t.assignmentExpression(
"=",
t.cloneNode(memo),
object,
// object must not be Super when `memo` is an identifier
object as t.Expression,
);
}

Expand Down
26 changes: 17 additions & 9 deletions packages/babel-plugin-proposal-optional-chaining/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { willPathCastToBoolean, findOutermostTransparentParent } from "./util";
const { ast } = template.expression;

function isSimpleMemberExpression(
expression: t.Expression,
expression: t.Expression | t.Super,
): expression is t.Identifier | t.Super | t.MemberExpression {
expression = skipTransparentExprWrapperNodes(expression);
return (
Expand Down Expand Up @@ -102,6 +102,7 @@ export function transform(
}
}

// todo: Improve replacementPath typings
let replacementPath: NodePath<any> = path;
if (parentPath.isUnaryExpression({ operator: "delete" })) {
replacementPath = parentPath;
Expand Down Expand Up @@ -139,8 +140,8 @@ export function transform(
t.cloneNode(ref),
// Here `chainWithTypes` MUST NOT be cloned because it could be
// updated when generating the memoised context of a call
// expression
chainWithTypes,
// expression. It must be an Expression when `ref` is an identifier
chainWithTypes as t.Expression,
);

isCall ? (node.callee = ref) : (node.object = ref);
Expand All @@ -160,13 +161,17 @@ export function transform(
// Otherwise, we need to memoize the context object, and change the call into a Function#call.
// `a.?b.?()` translates roughly to `(_b = _a.b) != null && _b.call(_a)`
const { object } = chain;
let context: t.Expression = scope.maybeGenerateMemoised(object);
if (context) {
chain.object = t.assignmentExpression("=", context, object);
} else if (t.isSuper(object)) {
let context: t.Expression;
if (t.isSuper(object)) {
context = t.thisExpression();
} else {
context = object;
const memoized = scope.maybeGenerateMemoised(object);
if (memoized) {
context = memoized;
chain.object = t.assignmentExpression("=", memoized, object);
} else {
context = object;
}
}

node.arguments.unshift(t.cloneNode(context));
Expand All @@ -181,7 +186,10 @@ export function transform(
// i.e. `?.b` in `(a?.b.c)()`
if (i === 0 && parentIsCall) {
// `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`
const object = skipTransparentExprWrapperNodes(replacement.object);
// object must not be Super as super?.foo is invalid
const object = skipTransparentExprWrapperNodes(
replacement.object,
) as t.Expression;
let baseRef;
if (!pureGetters || !isSimpleMemberExpression(object)) {
// memoize the context object when getters are not always pure
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,12 @@ export default declare(api => {
scope.push({ id: receiverLVal });

sequenceParts.push(
t.assignmentExpression("=", t.cloneNode(receiverLVal), receiver),
t.assignmentExpression(
"=",
t.cloneNode(receiverLVal),
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.foo(?)`
receiver,
),
t.assignmentExpression(
"=",
t.cloneNode(functionLVal),
Expand Down
15 changes: 13 additions & 2 deletions packages/babel-plugin-transform-proto-to-assign/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ export default declare(api => {
file: File,
) {
return t.expressionStatement(
t.callExpression(file.addHelper("defaults"), [ref, expr.right]),
t.callExpression(file.addHelper("defaults"), [
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.__proto__ = ...`
ref,
expr.right,
]),
);
}

Expand All @@ -48,7 +52,14 @@ export default declare(api => {

if (temp) {
nodes.push(
t.expressionStatement(t.assignmentExpression("=", temp, left)),
t.expressionStatement(
t.assignmentExpression(
"=",
temp,
// left must not be Super when `temp` is an identifier
left as t.Expression,
),
),
);
}
nodes.push(
Expand Down
9 changes: 7 additions & 2 deletions packages/babel-plugin-transform-spread/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export default declare((api, options: Options) => {
"Please add '@babel/plugin-transform-classes' to your Babel configuration.",
);
}
let contextLiteral: t.Expression = scope.buildUndefinedNode();
let contextLiteral: t.Expression | t.Super = scope.buildUndefinedNode();
node.arguments = [];

let nodes: t.Expression[];
Expand Down Expand Up @@ -175,7 +175,12 @@ export default declare((api, options: Options) => {
if (t.isMemberExpression(callee)) {
const temp = scope.maybeGenerateMemoised(callee.object);
if (temp) {
callee.object = t.assignmentExpression("=", temp, callee.object);
callee.object = t.assignmentExpression(
"=",
temp,
// object must not be Super when `temp` is an identifier
callee.object as t.Expression,
);
contextLiteral = temp;
} else {
contextLiteral = t.cloneNode(callee.object);
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-traverse/test/scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ describe("scope", () => {
describe("duplicate declaration", () => {
it("should not throw error on duplicate class and function declaration", () => {
const ast = [
t.classDeclaration(t.identifier("A"), t.super(), t.classBody([]), []),
t.classDeclaration(t.identifier("A"), null, t.classBody([]), []),
t.functionDeclaration(t.identifier("A"), [], t.blockStatement([])),
];

Expand Down
6 changes: 3 additions & 3 deletions packages/babel-types/src/ast-types/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ export interface BreakStatement extends BaseNode {

export interface CallExpression extends BaseNode {
type: "CallExpression";
callee: Expression | V8IntrinsicIdentifier;
callee: Expression | Super | V8IntrinsicIdentifier;
arguments: Array<
Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder
>;
Expand Down Expand Up @@ -544,15 +544,15 @@ export interface LogicalExpression extends BaseNode {

export interface MemberExpression extends BaseNode {
type: "MemberExpression";
object: Expression;
object: Expression | Super;
property: Expression | Identifier | PrivateName;
computed: boolean;
optional?: true | false | null;
}

export interface NewExpression extends BaseNode {
type: "NewExpression";
callee: Expression | V8IntrinsicIdentifier;
callee: Expression | Super | V8IntrinsicIdentifier;
arguments: Array<
Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder
>;
Expand Down
6 changes: 3 additions & 3 deletions packages/babel-types/src/builders/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function breakStatement(
});
}
export function callExpression(
callee: t.Expression | t.V8IntrinsicIdentifier,
callee: t.Expression | t.Super | t.V8IntrinsicIdentifier,
_arguments: Array<
t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder
>,
Expand Down Expand Up @@ -314,7 +314,7 @@ export function logicalExpression(
});
}
export function memberExpression(
object: t.Expression,
object: t.Expression | t.Super,
property: t.Expression | t.Identifier | t.PrivateName,
computed: boolean = false,
optional: true | false | null = null,
Expand All @@ -328,7 +328,7 @@ export function memberExpression(
});
}
export function newExpression(
callee: t.Expression | t.V8IntrinsicIdentifier,
callee: t.Expression | t.Super | t.V8IntrinsicIdentifier,
_arguments: Array<
t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder
>,
Expand Down
15 changes: 10 additions & 5 deletions packages/babel-types/src/definitions/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ defineType("CallExpression", {
aliases: ["Expression"],
fields: {
callee: {
validate: assertNodeType("Expression", "V8IntrinsicIdentifier"),
validate: assertNodeType("Expression", "Super", "V8IntrinsicIdentifier"),
},
arguments: {
validate: chain(
Expand Down Expand Up @@ -684,7 +684,7 @@ defineType("MemberExpression", {
aliases: ["Expression", "LVal"],
fields: {
object: {
validate: assertNodeType("Expression"),
validate: assertNodeType("Expression", "Super"),
},
property: {
validate: (function () {
Expand Down Expand Up @@ -1930,9 +1930,14 @@ defineType("SpreadElement", {
},
});

defineType("Super", {
aliases: ["Expression"],
});
defineType(
"Super",
process.env.BABEL_8_BREAKING
? undefined
: {
aliases: ["Expression"],
},
);

defineType("TaggedTemplateExpression", {
visitor: ["tag", "quasi", "typeParameters"],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { memberExpression } from "../builders/generated";
import { isSuper } from "..";
import type * as t from "..";

/**
Expand All @@ -7,6 +8,11 @@ import type * as t from "..";
export default function prependToMemberExpression<
T extends Pick<t.MemberExpression, "object" | "property">,
>(member: T, prepend: t.MemberExpression["object"]): T {
if (isSuper(member.object)) {
throw new Error(
"Cannot prepend node to super property access (`super.foo`).",
);
}
member.object = memberExpression(prepend, member.object);

return member;
Expand Down
13 changes: 13 additions & 0 deletions packages/babel-types/test/modifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as t from "../lib/index.js";

describe("prependToMemberExpression", function () {
it("should throw when prepending node to super property", () => {
const object = t.super();
const memberExpression = t.memberExpression(t.super(), t.identifier("foo"));
expect(() =>
t.prependToMemberExpression(memberExpression, object),
).toThrowError(
"Cannot prepend node to super property access (`super.foo`).",
);
});
});

0 comments on commit 0df9f62

Please sign in to comment.