Fix class properties after nested class' bare super (#7671)
* Fix class properties after nested class' bare super Fixes #7371. * Fix node 4 test * This damn node 4 test * All of the ClassBody, but not the methods or field inits * tmp * tmp * Use common class environment visitor * Tests * Use skipKey to avoid recursive traversal * Remove old state * Use jest expect
This commit is contained in:
parent
39b05598a0
commit
668358c4d0
@ -197,8 +197,8 @@ In an `exec.js` test, we run or check that the code actually does what it's supp
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// exec.js
|
// exec.js
|
||||||
assert.equal(8, 2 ** 3);
|
expect(2 ** 3).toBe(8);
|
||||||
assert.equal(24, 3 * 2 ** 3);
|
expect(3 * 2 ** 3).toBe(24);
|
||||||
```
|
```
|
||||||
|
|
||||||
If you need to check for an error that is thrown you can add to the `options.json`
|
If you need to check for an error that is thrown you can add to the `options.json`
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import type { NodePath, Scope } from "@babel/traverse";
|
import type { NodePath, Scope } from "@babel/traverse";
|
||||||
|
import traverse from "@babel/traverse";
|
||||||
import optimiseCall from "@babel/helper-optimise-call-expression";
|
import optimiseCall from "@babel/helper-optimise-call-expression";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
@ -25,35 +26,44 @@ function getPrototypeOfExpression(objectRef, isStatic, file) {
|
|||||||
return t.callExpression(file.addHelper("getPrototypeOf"), [targetRef]);
|
return t.callExpression(file.addHelper("getPrototypeOf"), [targetRef]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const visitor = {
|
function skipAllButComputedKey(path) {
|
||||||
|
// If the path isn't computed, just skip everything.
|
||||||
|
if (!path.node.computed) {
|
||||||
|
path.skip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// So it's got a computed key. Make sure to skip every other key the
|
||||||
|
// traversal would visit.
|
||||||
|
const keys = t.VISITOR_KEYS[path.type];
|
||||||
|
for (const key of keys) {
|
||||||
|
if (key !== "key") path.skipKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const environmentVisitor = {
|
||||||
Function(path) {
|
Function(path) {
|
||||||
|
// Methods will be handled by the Method visit
|
||||||
if (path.isMethod()) return;
|
if (path.isMethod()) return;
|
||||||
|
// Arrow functions inherit their parent's environment
|
||||||
if (path.isArrowFunctionExpression()) return;
|
if (path.isArrowFunctionExpression()) return;
|
||||||
path.skip();
|
path.skip();
|
||||||
},
|
},
|
||||||
|
|
||||||
Method(path, state) {
|
Method(path) {
|
||||||
// Don't traverse ClassMethod's body
|
skipAllButComputedKey(path);
|
||||||
path.skip();
|
|
||||||
|
|
||||||
// We do have to traverse the key, since it's evaluated in the outer class
|
|
||||||
// context.
|
|
||||||
if (path.node.computed) {
|
|
||||||
path.get("key").traverse(visitor, state);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"ClassProperty|ClassPrivateProperty"(path, state) {
|
"ClassProperty|ClassPrivateProperty"(path) {
|
||||||
// Don't traverse the ClassProp's value.
|
// If the property is computed, we need to visit everything.
|
||||||
if (!path.node.static) path.skip();
|
if (path.node.static) return;
|
||||||
|
skipAllButComputedKey(path);
|
||||||
// We do have to traverse the key, since it's evaluated in the outer class
|
|
||||||
// context.
|
|
||||||
if (path.node.computed) {
|
|
||||||
path.get("key").traverse(visitor, state);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const visitor = traverse.visitors.merge([
|
||||||
|
environmentVisitor,
|
||||||
|
{
|
||||||
ReturnStatement(path, state) {
|
ReturnStatement(path, state) {
|
||||||
if (!path.getFunctionParent().isArrowFunctionExpression()) {
|
if (!path.getFunctionParent().isArrowFunctionExpression()) {
|
||||||
state.returns.push(path);
|
state.returns.push(path);
|
||||||
@ -76,7 +86,8 @@ const visitor = {
|
|||||||
}
|
}
|
||||||
state[state.isLoose ? "looseHandle" : "specHandle"](path);
|
state[state.isLoose ? "looseHandle" : "specHandle"](path);
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
export default class ReplaceSupers {
|
export default class ReplaceSupers {
|
||||||
constructor(opts: Object, inClass?: boolean = false) {
|
constructor(opts: Object, inClass?: boolean = false) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-function-name": "7.0.0-beta.44",
|
"@babel/helper-function-name": "7.0.0-beta.44",
|
||||||
"@babel/helper-plugin-utils": "7.0.0-beta.44",
|
"@babel/helper-plugin-utils": "7.0.0-beta.44",
|
||||||
|
"@babel/helper-replace-supers": "7.0.0-beta.44",
|
||||||
"@babel/plugin-syntax-class-properties": "7.0.0-beta.44"
|
"@babel/plugin-syntax-class-properties": "7.0.0-beta.44"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@ -1,25 +1,31 @@
|
|||||||
import { declare } from "@babel/helper-plugin-utils";
|
import { declare } from "@babel/helper-plugin-utils";
|
||||||
import nameFunction from "@babel/helper-function-name";
|
import nameFunction from "@babel/helper-function-name";
|
||||||
import syntaxClassProperties from "@babel/plugin-syntax-class-properties";
|
import syntaxClassProperties from "@babel/plugin-syntax-class-properties";
|
||||||
import { template, types as t } from "@babel/core";
|
import { template, traverse, types as t } from "@babel/core";
|
||||||
|
import { environmentVisitor } from "@babel/helper-replace-supers";
|
||||||
|
|
||||||
export default declare((api, options) => {
|
export default declare((api, options) => {
|
||||||
api.assertVersion(7);
|
api.assertVersion(7);
|
||||||
|
|
||||||
const { loose } = options;
|
const { loose } = options;
|
||||||
|
|
||||||
const findBareSupers = {
|
const findBareSupers = traverse.visitors.merge([
|
||||||
|
{
|
||||||
Super(path) {
|
Super(path) {
|
||||||
if (path.parentPath.isCallExpression({ callee: path.node })) {
|
const { node, parentPath } = path;
|
||||||
this.push(path.parentPath);
|
if (parentPath.isCallExpression({ callee: node })) {
|
||||||
|
this.push(parentPath);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
|
environmentVisitor,
|
||||||
|
]);
|
||||||
|
|
||||||
const referenceVisitor = {
|
const referenceVisitor = {
|
||||||
"TSTypeAnnotation|TypeAnnotation"(path) {
|
"TSTypeAnnotation|TypeAnnotation"(path) {
|
||||||
path.skip();
|
path.skip();
|
||||||
},
|
},
|
||||||
|
|
||||||
ReferencedIdentifier(path) {
|
ReferencedIdentifier(path) {
|
||||||
if (this.scope.hasOwnBinding(path.node.name)) {
|
if (this.scope.hasOwnBinding(path.node.name)) {
|
||||||
this.scope.rename(path.node.name);
|
this.scope.rename(path.node.name);
|
||||||
@ -28,13 +34,8 @@ export default declare((api, options) => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClassFieldDefinitionEvaluationTDZVisitor = {
|
const classFieldDefinitionEvaluationTDZVisitor = traverse.visitors.merge([
|
||||||
Expression(path) {
|
{
|
||||||
if (path === this.shouldSkip) {
|
|
||||||
path.skip();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
ReferencedIdentifier(path) {
|
ReferencedIdentifier(path) {
|
||||||
if (this.classRef === path.scope.getBinding(path.node.name)) {
|
if (this.classRef === path.scope.getBinding(path.node.name)) {
|
||||||
const classNameTDZError = this.file.addHelper("classNameTDZError");
|
const classNameTDZError = this.file.addHelper("classNameTDZError");
|
||||||
@ -46,7 +47,9 @@ export default declare((api, options) => {
|
|||||||
path.skip();
|
path.skip();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
|
environmentVisitor,
|
||||||
|
]);
|
||||||
|
|
||||||
const buildClassPropertySpec = (ref, { key, value, computed }, scope) => {
|
const buildClassPropertySpec = (ref, { key, value, computed }, scope) => {
|
||||||
return template.statement`
|
return template.statement`
|
||||||
@ -122,10 +125,9 @@ export default declare((api, options) => {
|
|||||||
// Make sure computed property names are only evaluated once (upon class definition)
|
// Make sure computed property names are only evaluated once (upon class definition)
|
||||||
// and in the right order in combination with static properties
|
// and in the right order in combination with static properties
|
||||||
if (!computedPath.get("key").isConstantExpression()) {
|
if (!computedPath.get("key").isConstantExpression()) {
|
||||||
computedPath.traverse(ClassFieldDefinitionEvaluationTDZVisitor, {
|
computedPath.traverse(classFieldDefinitionEvaluationTDZVisitor, {
|
||||||
classRef: path.scope.getBinding(ref.name),
|
classRef: path.scope.getBinding(ref.name),
|
||||||
file: this.file,
|
file: this.file,
|
||||||
shouldSkip: computedPath.get("value"),
|
|
||||||
});
|
});
|
||||||
const ident = path.scope.generateUidIdentifierBasedOnNode(
|
const ident = path.scope.generateUidIdentifierBasedOnNode(
|
||||||
computedNode.key,
|
computedNode.key,
|
||||||
|
|||||||
99
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/exec.js
vendored
Normal file
99
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/exec.js
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"use strict";
|
||||||
|
class C {
|
||||||
|
}
|
||||||
|
|
||||||
|
class A extends C {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
class B extends C {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new A();
|
||||||
|
|
||||||
|
class Obj {
|
||||||
|
constructor() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure superClass is still transformed
|
||||||
|
class SuperClass extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends (super(), Obj) {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new SuperClass();
|
||||||
|
|
||||||
|
// ensure ComputedKey Method is still transformed
|
||||||
|
class ComputedMethod extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
[super()]() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedMethod();
|
||||||
|
|
||||||
|
|
||||||
|
// ensure ComputedKey Field is still transformed
|
||||||
|
class ComputedField extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
[super()] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedField();
|
||||||
99
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/input.js
vendored
Normal file
99
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/input.js
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"use strict";
|
||||||
|
class C {
|
||||||
|
}
|
||||||
|
|
||||||
|
class A extends C {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
class B extends C {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new A();
|
||||||
|
|
||||||
|
class Obj {
|
||||||
|
constructor() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure superClass is still transformed
|
||||||
|
class SuperClass extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends (super(), Obj) {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new SuperClass();
|
||||||
|
|
||||||
|
// ensure ComputedKey Method is still transformed
|
||||||
|
class ComputedMethod extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
[super()]() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedMethod();
|
||||||
|
|
||||||
|
|
||||||
|
// ensure ComputedKey Field is still transformed
|
||||||
|
class ComputedField extends Obj {
|
||||||
|
field = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
expect(this.field).toBeUndefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
[super()] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1)
|
||||||
|
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedField();
|
||||||
3
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/options.json
vendored
Normal file
3
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["external-helpers", "proposal-class-properties", "transform-arrow-functions"]
|
||||||
|
}
|
||||||
122
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/output.js
vendored
Normal file
122
packages/babel-plugin-proposal-class-properties/test/fixtures/regression/7371/output.js
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
class A extends C {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
Object.defineProperty(this, "field", {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
class B extends C {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1);
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new A();
|
||||||
|
|
||||||
|
class Obj {
|
||||||
|
constructor() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // ensure superClass is still transformed
|
||||||
|
|
||||||
|
|
||||||
|
class SuperClass extends Obj {
|
||||||
|
constructor() {
|
||||||
|
var _temp;
|
||||||
|
|
||||||
|
class B extends ((_temp = super(), Object.defineProperty(this, "field", {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
}), _temp), Obj) {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1);
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new SuperClass(); // ensure ComputedKey Method is still transformed
|
||||||
|
|
||||||
|
class ComputedMethod extends Obj {
|
||||||
|
constructor() {
|
||||||
|
var _temp2;
|
||||||
|
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
[(_temp2 = super(), Object.defineProperty(this, "field", {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
}), _temp2)]() {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1);
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedMethod(); // ensure ComputedKey Field is still transformed
|
||||||
|
|
||||||
|
class ComputedField extends Obj {
|
||||||
|
constructor() {
|
||||||
|
var _temp3;
|
||||||
|
|
||||||
|
var _ref = (_temp3 = super(), Object.defineProperty(this, "field", {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
}), _temp3);
|
||||||
|
|
||||||
|
class B extends Obj {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
Object.defineProperty(this, _ref, {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
writable: true,
|
||||||
|
value: 1
|
||||||
|
});
|
||||||
|
expect(this.field).toBeUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(this.field).toBe(1);
|
||||||
|
new B();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new ComputedField();
|
||||||
@ -1,22 +1,14 @@
|
|||||||
import type { NodePath } from "@babel/traverse";
|
import type { NodePath } from "@babel/traverse";
|
||||||
import nameFunction from "@babel/helper-function-name";
|
import nameFunction from "@babel/helper-function-name";
|
||||||
import ReplaceSupers from "@babel/helper-replace-supers";
|
import ReplaceSupers, {
|
||||||
|
environmentVisitor,
|
||||||
|
} from "@babel/helper-replace-supers";
|
||||||
import optimiseCall from "@babel/helper-optimise-call-expression";
|
import optimiseCall from "@babel/helper-optimise-call-expression";
|
||||||
import * as defineMap from "@babel/helper-define-map";
|
import * as defineMap from "@babel/helper-define-map";
|
||||||
import { traverse, template, types as t } from "@babel/core";
|
import { traverse, template, types as t } from "@babel/core";
|
||||||
|
|
||||||
type ReadonlySet<T> = Set<T> | { has(val: T): boolean };
|
type ReadonlySet<T> = Set<T> | { has(val: T): boolean };
|
||||||
|
|
||||||
const noMethodVisitor = {
|
|
||||||
"FunctionExpression|FunctionDeclaration"(path) {
|
|
||||||
path.skip();
|
|
||||||
},
|
|
||||||
|
|
||||||
Method(path) {
|
|
||||||
path.skip();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function buildConstructor(classRef, constructorBody, node) {
|
function buildConstructor(classRef, constructorBody, node) {
|
||||||
const func = t.functionDeclaration(
|
const func = t.functionDeclaration(
|
||||||
t.cloneNode(classRef),
|
t.cloneNode(classRef),
|
||||||
@ -78,7 +70,7 @@ export default function transformClass(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const verifyConstructorVisitor = traverse.visitors.merge([
|
const verifyConstructorVisitor = traverse.visitors.merge([
|
||||||
noMethodVisitor,
|
environmentVisitor,
|
||||||
{
|
{
|
||||||
CallExpression: {
|
CallExpression: {
|
||||||
exit(path) {
|
exit(path) {
|
||||||
@ -115,7 +107,7 @@ export default function transformClass(
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const findThisesVisitor = traverse.visitors.merge([
|
const findThisesVisitor = traverse.visitors.merge([
|
||||||
noMethodVisitor,
|
environmentVisitor,
|
||||||
{
|
{
|
||||||
ThisExpression(path) {
|
ThisExpression(path) {
|
||||||
classState.superThises.push(path);
|
classState.superThises.push(path);
|
||||||
|
|||||||
@ -22,8 +22,6 @@ function (_Hello) {
|
|||||||
babelHelpers.inherits(Outer, _Hello);
|
babelHelpers.inherits(Outer, _Hello);
|
||||||
|
|
||||||
function Outer() {
|
function Outer() {
|
||||||
var _this2 = this;
|
|
||||||
|
|
||||||
var _this;
|
var _this;
|
||||||
|
|
||||||
babelHelpers.classCallCheck(this, Outer);
|
babelHelpers.classCallCheck(this, Outer);
|
||||||
@ -37,7 +35,7 @@ function (_Hello) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
babelHelpers.createClass(Inner, [{
|
babelHelpers.createClass(Inner, [{
|
||||||
key: babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this2)).call(_this2),
|
key: babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this)).call(_this),
|
||||||
value: function value() {
|
value: function value() {
|
||||||
return 'hello';
|
return 'hello';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ function (_Hello) {
|
|||||||
babelHelpers.classCallCheck(this, Outer);
|
babelHelpers.classCallCheck(this, Outer);
|
||||||
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Outer).call(this));
|
_this = babelHelpers.possibleConstructorReturn(this, babelHelpers.getPrototypeOf(Outer).call(this));
|
||||||
var Inner = {
|
var Inner = {
|
||||||
[babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(this)).call(this)]() {
|
[babelHelpers.get(babelHelpers.getPrototypeOf(Outer.prototype), "toString", babelHelpers.assertThisInitialized(_this)).call(_this)]() {
|
||||||
return 'hello';
|
return 'hello';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,18 +14,20 @@ export function insertBefore(nodes) {
|
|||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
nodes = this._verifyNodeList(nodes);
|
||||||
|
|
||||||
|
const { parentPath } = this;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.parentPath.isExpressionStatement() ||
|
parentPath.isExpressionStatement() ||
|
||||||
this.parentPath.isLabeledStatement() ||
|
parentPath.isLabeledStatement() ||
|
||||||
this.parentPath.isExportNamedDeclaration() ||
|
parentPath.isExportNamedDeclaration() ||
|
||||||
(this.parentPath.isExportDefaultDeclaration() && this.isDeclaration())
|
(parentPath.isExportDefaultDeclaration() && this.isDeclaration())
|
||||||
) {
|
) {
|
||||||
return this.parentPath.insertBefore(nodes);
|
return parentPath.insertBefore(nodes);
|
||||||
} else if (
|
} else if (
|
||||||
(this.isNodeType("Expression") &&
|
(this.isNodeType("Expression") &&
|
||||||
this.listKey !== "params" &&
|
this.listKey !== "params" &&
|
||||||
this.listKey !== "arguments") ||
|
this.listKey !== "arguments") ||
|
||||||
(this.parentPath.isForStatement() && this.key === "init")
|
(parentPath.isForStatement() && this.key === "init")
|
||||||
) {
|
) {
|
||||||
if (this.node) nodes.push(this.node);
|
if (this.node) nodes.push(this.node);
|
||||||
return this.replaceExpressionWithStatements(nodes);
|
return this.replaceExpressionWithStatements(nodes);
|
||||||
@ -96,19 +98,26 @@ export function insertAfter(nodes) {
|
|||||||
|
|
||||||
nodes = this._verifyNodeList(nodes);
|
nodes = this._verifyNodeList(nodes);
|
||||||
|
|
||||||
|
const { parentPath } = this;
|
||||||
if (
|
if (
|
||||||
this.parentPath.isExpressionStatement() ||
|
parentPath.isExpressionStatement() ||
|
||||||
this.parentPath.isLabeledStatement() ||
|
parentPath.isLabeledStatement() ||
|
||||||
this.parentPath.isExportNamedDeclaration() ||
|
parentPath.isExportNamedDeclaration() ||
|
||||||
(this.parentPath.isExportDefaultDeclaration() && this.isDeclaration())
|
(parentPath.isExportDefaultDeclaration() && this.isDeclaration())
|
||||||
) {
|
) {
|
||||||
return this.parentPath.insertAfter(nodes);
|
return parentPath.insertAfter(nodes);
|
||||||
} else if (
|
} else if (
|
||||||
this.isNodeType("Expression") ||
|
this.isNodeType("Expression") ||
|
||||||
(this.parentPath.isForStatement() && this.key === "init")
|
(parentPath.isForStatement() && this.key === "init")
|
||||||
) {
|
) {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
const temp = this.scope.generateDeclaredUidIdentifier();
|
let { scope } = this;
|
||||||
|
// Inserting after the computed key of a method should insert the
|
||||||
|
// temporary binding in the method's parent's scope.
|
||||||
|
if (parentPath.isMethod({ computed: true, key: this.node })) {
|
||||||
|
scope = scope.parent;
|
||||||
|
}
|
||||||
|
const temp = scope.generateDeclaredUidIdentifier();
|
||||||
nodes.unshift(
|
nodes.unshift(
|
||||||
t.expressionStatement(
|
t.expressionStatement(
|
||||||
t.assignmentExpression("=", t.cloneNode(temp), this.node),
|
t.assignmentExpression("=", t.cloneNode(temp), this.node),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user