Skip to content

Commit 0df9f62

Browse files
authored
Remove Super from Expression alias (#14750)
1 parent bcf8b22 commit 0df9f62

File tree

17 files changed

+97
-37
lines changed

17 files changed

+97
-37
lines changed

packages/babel-generator/src/generators/expressions.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export function Super(this: Printer) {
113113
}
114114

115115
function isDecoratorMemberExpression(
116-
node: t.Expression | t.V8IntrinsicIdentifier,
116+
node: t.Expression | t.Super | t.V8IntrinsicIdentifier,
117117
): boolean {
118118
switch (node.type) {
119119
case "Identifier":
@@ -129,7 +129,7 @@ function isDecoratorMemberExpression(
129129
}
130130
}
131131
function shouldParenthesizeDecoratorExpression(
132-
node: t.Expression | t.V8IntrinsicIdentifier,
132+
node: t.Expression | t.Super | t.V8IntrinsicIdentifier,
133133
) {
134134
if (node.type === "CallExpression") {
135135
node = node.callee;

packages/babel-helper-builder-binary-assignment-operator-visitor/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type * as t from "@babel/types";
55

66
export default function (opts: {
77
build: (
8-
left: t.Expression | t.PrivateName,
8+
left: t.Expression | t.PrivateName | t.Super,
99
right: t.Expression,
1010
) => t.Expression;
1111
operator: t.BinaryExpression["operator"];

packages/babel-helper-create-class-features-plugin/src/fields.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ const privateNameHandlerSpec: Handler<PrivateNameState & Receiver> & Receiver =
258258
{
259259
memoise(member, count) {
260260
const { scope } = member;
261-
const { object } = member.node;
261+
const { object } = member.node as { object: t.Expression };
262262

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

271271
receiver(member) {
272-
const { object } = member.node;
272+
const { object } = member.node as { object: t.Expression };
273273

274274
if (this.memoiser.has(object)) {
275-
return t.cloneNode(this.memoiser.get(object) as t.Expression);
275+
return t.cloneNode(this.memoiser.get(object));
276276
}
277277

278278
return t.cloneNode(object);
@@ -466,7 +466,7 @@ const privateNameHandlerLoose: Handler<PrivateNameState> = {
466466
boundGet(member) {
467467
return t.callExpression(
468468
t.memberExpression(this.get(member), t.identifier("bind")),
469-
[t.cloneNode(member.node.object)],
469+
[t.cloneNode(member.node.object as t.Expression)],
470470
);
471471
},
472472

packages/babel-helper-member-expression-to-functions/src/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,12 @@ const handle = {
279279
const { object } = regular;
280280
context = member.scope.maybeGenerateMemoised(object);
281281
if (context) {
282-
regular.object = assignmentExpression("=", context, object);
282+
regular.object = assignmentExpression(
283+
"=",
284+
context,
285+
// object must not be Super when `context` is an identifier
286+
object as t.Expression,
287+
);
283288
}
284289
}
285290

packages/babel-helper-skip-transparent-expression-wrappers/src/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ export function skipTransparentExprWrappers(
4343
}
4444

4545
export function skipTransparentExprWrapperNodes(
46-
node: t.Expression,
47-
): t.Expression {
46+
node: t.Expression | t.Super,
47+
): t.Expression | t.Super {
4848
while (isTransparentExprWrapper(node)) {
4949
node = node.expression;
5050
}

packages/babel-plugin-proposal-function-bind/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export default declare(api => {
4444
bind.callee.object = t.assignmentExpression(
4545
"=",
4646
tempId,
47+
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.foo(?)`
4748
bind.callee.object,
4849
);
4950
}

packages/babel-plugin-proposal-logical-assignment-operators/src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export default declare(api => {
2727
(lhs as t.MemberExpression).object = t.assignmentExpression(
2828
"=",
2929
t.cloneNode(memo),
30-
object,
30+
// object must not be Super when `memo` is an identifier
31+
object as t.Expression,
3132
);
3233
}
3334

packages/babel-plugin-proposal-optional-chaining/src/transform.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { willPathCastToBoolean, findOutermostTransparentParent } from "./util";
99
const { ast } = template.expression;
1010

1111
function isSimpleMemberExpression(
12-
expression: t.Expression,
12+
expression: t.Expression | t.Super,
1313
): expression is t.Identifier | t.Super | t.MemberExpression {
1414
expression = skipTransparentExprWrapperNodes(expression);
1515
return (
@@ -102,6 +102,7 @@ export function transform(
102102
}
103103
}
104104

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

146147
isCall ? (node.callee = ref) : (node.object = ref);
@@ -160,13 +161,17 @@ export function transform(
160161
// Otherwise, we need to memoize the context object, and change the call into a Function#call.
161162
// `a.?b.?()` translates roughly to `(_b = _a.b) != null && _b.call(_a)`
162163
const { object } = chain;
163-
let context: t.Expression = scope.maybeGenerateMemoised(object);
164-
if (context) {
165-
chain.object = t.assignmentExpression("=", context, object);
166-
} else if (t.isSuper(object)) {
164+
let context: t.Expression;
165+
if (t.isSuper(object)) {
167166
context = t.thisExpression();
168167
} else {
169-
context = object;
168+
const memoized = scope.maybeGenerateMemoised(object);
169+
if (memoized) {
170+
context = memoized;
171+
chain.object = t.assignmentExpression("=", memoized, object);
172+
} else {
173+
context = object;
174+
}
170175
}
171176

172177
node.arguments.unshift(t.cloneNode(context));
@@ -181,7 +186,10 @@ export function transform(
181186
// i.e. `?.b` in `(a?.b.c)()`
182187
if (i === 0 && parentIsCall) {
183188
// `(a?.b)()` to `(a == null ? undefined : a.b.bind(a))()`
184-
const object = skipTransparentExprWrapperNodes(replacement.object);
189+
// object must not be Super as super?.foo is invalid
190+
const object = skipTransparentExprWrapperNodes(
191+
replacement.object,
192+
) as t.Expression;
185193
let baseRef;
186194
if (!pureGetters || !isSimpleMemberExpression(object)) {
187195
// memoize the context object when getters are not always pure

packages/babel-plugin-proposal-partial-application/src/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ export default declare(api => {
101101
scope.push({ id: receiverLVal });
102102

103103
sequenceParts.push(
104-
t.assignmentExpression("=", t.cloneNode(receiverLVal), receiver),
104+
t.assignmentExpression(
105+
"=",
106+
t.cloneNode(receiverLVal),
107+
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.foo(?)`
108+
receiver,
109+
),
105110
t.assignmentExpression(
106111
"=",
107112
t.cloneNode(functionLVal),

packages/babel-plugin-transform-proto-to-assign/src/index.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ export default declare(api => {
3131
file: File,
3232
) {
3333
return t.expressionStatement(
34-
t.callExpression(file.addHelper("defaults"), [ref, expr.right]),
34+
t.callExpression(file.addHelper("defaults"), [
35+
// @ts-ignore(Babel 7 vs Babel 8) Fixme: support `super.__proto__ = ...`
36+
ref,
37+
expr.right,
38+
]),
3539
);
3640
}
3741

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

4953
if (temp) {
5054
nodes.push(
51-
t.expressionStatement(t.assignmentExpression("=", temp, left)),
55+
t.expressionStatement(
56+
t.assignmentExpression(
57+
"=",
58+
temp,
59+
// left must not be Super when `temp` is an identifier
60+
left as t.Expression,
61+
),
62+
),
5263
);
5364
}
5465
nodes.push(

packages/babel-plugin-transform-spread/src/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export default declare((api, options: Options) => {
143143
"Please add '@babel/plugin-transform-classes' to your Babel configuration.",
144144
);
145145
}
146-
let contextLiteral: t.Expression = scope.buildUndefinedNode();
146+
let contextLiteral: t.Expression | t.Super = scope.buildUndefinedNode();
147147
node.arguments = [];
148148

149149
let nodes: t.Expression[];
@@ -175,7 +175,12 @@ export default declare((api, options: Options) => {
175175
if (t.isMemberExpression(callee)) {
176176
const temp = scope.maybeGenerateMemoised(callee.object);
177177
if (temp) {
178-
callee.object = t.assignmentExpression("=", temp, callee.object);
178+
callee.object = t.assignmentExpression(
179+
"=",
180+
temp,
181+
// object must not be Super when `temp` is an identifier
182+
callee.object as t.Expression,
183+
);
179184
contextLiteral = temp;
180185
} else {
181186
contextLiteral = t.cloneNode(callee.object);

packages/babel-traverse/test/scope.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ describe("scope", () => {
653653
describe("duplicate declaration", () => {
654654
it("should not throw error on duplicate class and function declaration", () => {
655655
const ast = [
656-
t.classDeclaration(t.identifier("A"), t.super(), t.classBody([]), []),
656+
t.classDeclaration(t.identifier("A"), null, t.classBody([]), []),
657657
t.functionDeclaration(t.identifier("A"), [], t.blockStatement([])),
658658
];
659659

packages/babel-types/src/ast-types/generated/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export interface BreakStatement extends BaseNode {
371371

372372
export interface CallExpression extends BaseNode {
373373
type: "CallExpression";
374-
callee: Expression | V8IntrinsicIdentifier;
374+
callee: Expression | Super | V8IntrinsicIdentifier;
375375
arguments: Array<
376376
Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder
377377
>;
@@ -544,15 +544,15 @@ export interface LogicalExpression extends BaseNode {
544544

545545
export interface MemberExpression extends BaseNode {
546546
type: "MemberExpression";
547-
object: Expression;
547+
object: Expression | Super;
548548
property: Expression | Identifier | PrivateName;
549549
computed: boolean;
550550
optional?: true | false | null;
551551
}
552552

553553
export interface NewExpression extends BaseNode {
554554
type: "NewExpression";
555-
callee: Expression | V8IntrinsicIdentifier;
555+
callee: Expression | Super | V8IntrinsicIdentifier;
556556
arguments: Array<
557557
Expression | SpreadElement | JSXNamespacedName | ArgumentPlaceholder
558558
>;

packages/babel-types/src/builders/generated/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export function breakStatement(
9696
});
9797
}
9898
export function callExpression(
99-
callee: t.Expression | t.V8IntrinsicIdentifier,
99+
callee: t.Expression | t.Super | t.V8IntrinsicIdentifier,
100100
_arguments: Array<
101101
t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder
102102
>,
@@ -314,7 +314,7 @@ export function logicalExpression(
314314
});
315315
}
316316
export function memberExpression(
317-
object: t.Expression,
317+
object: t.Expression | t.Super,
318318
property: t.Expression | t.Identifier | t.PrivateName,
319319
computed: boolean = false,
320320
optional: true | false | null = null,
@@ -328,7 +328,7 @@ export function memberExpression(
328328
});
329329
}
330330
export function newExpression(
331-
callee: t.Expression | t.V8IntrinsicIdentifier,
331+
callee: t.Expression | t.Super | t.V8IntrinsicIdentifier,
332332
_arguments: Array<
333333
t.Expression | t.SpreadElement | t.JSXNamespacedName | t.ArgumentPlaceholder
334334
>,

packages/babel-types/src/definitions/core.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ defineType("CallExpression", {
177177
aliases: ["Expression"],
178178
fields: {
179179
callee: {
180-
validate: assertNodeType("Expression", "V8IntrinsicIdentifier"),
180+
validate: assertNodeType("Expression", "Super", "V8IntrinsicIdentifier"),
181181
},
182182
arguments: {
183183
validate: chain(
@@ -684,7 +684,7 @@ defineType("MemberExpression", {
684684
aliases: ["Expression", "LVal"],
685685
fields: {
686686
object: {
687-
validate: assertNodeType("Expression"),
687+
validate: assertNodeType("Expression", "Super"),
688688
},
689689
property: {
690690
validate: (function () {
@@ -1930,9 +1930,14 @@ defineType("SpreadElement", {
19301930
},
19311931
});
19321932

1933-
defineType("Super", {
1934-
aliases: ["Expression"],
1935-
});
1933+
defineType(
1934+
"Super",
1935+
process.env.BABEL_8_BREAKING
1936+
? undefined
1937+
: {
1938+
aliases: ["Expression"],
1939+
},
1940+
);
19361941

19371942
defineType("TaggedTemplateExpression", {
19381943
visitor: ["tag", "quasi", "typeParameters"],

packages/babel-types/src/modifications/prependToMemberExpression.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { memberExpression } from "../builders/generated";
2+
import { isSuper } from "..";
23
import type * as t from "..";
34

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

1218
return member;
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as t from "../lib/index.js";
2+
3+
describe("prependToMemberExpression", function () {
4+
it("should throw when prepending node to super property", () => {
5+
const object = t.super();
6+
const memberExpression = t.memberExpression(t.super(), t.identifier("foo"));
7+
expect(() =>
8+
t.prependToMemberExpression(memberExpression, object),
9+
).toThrowError(
10+
"Cannot prepend node to super property access (`super.foo`).",
11+
);
12+
});
13+
});

0 commit comments

Comments
 (0)