Skip to content

Commit

Permalink
Merge pull request microsoft#30491 from Microsoft/fix30066-master
Browse files Browse the repository at this point in the history
Fix _superIndex emit when super access captured in async arrow
  • Loading branch information
rbuckton authored Mar 19, 2019
2 parents 84087d0 + 4e54f30 commit 4b3178c
Show file tree
Hide file tree
Showing 5 changed files with 574 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/compiler/transformers/es2017.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,10 @@ namespace ts {

const savedCapturedSuperProperties = capturedSuperProperties;
const savedHasSuperElementAccess = hasSuperElementAccess;
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
if (!isArrowFunction) {
capturedSuperProperties = createUnderscoreEscapedMap<true>();
hasSuperElementAccess = false;
}

let result: ConciseBody;
if (!isArrowFunction) {
Expand All @@ -446,9 +448,11 @@ namespace ts {

if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
if (hasEntries(capturedSuperProperties)) {
const variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
substitutedSuperAccessors[getNodeId(variableStatement)] = true;
insertStatementsAfterStandardPrologue(statements, [variableStatement]);
}
}

const block = createBlock(statements, /*multiLine*/ true);
Expand Down Expand Up @@ -485,8 +489,10 @@ namespace ts {
}

enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
if (!isArrowFunction) {
capturedSuperProperties = savedCapturedSuperProperties;
hasSuperElementAccess = savedHasSuperElementAccess;
}
return result;
}

Expand Down
141 changes: 141 additions & 0 deletions tests/baselines/reference/asyncMethodWithSuper_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,78 @@ class B extends A {

// destructuring assign with element access
({ f: super["x"] } = { f });

// property access in arrow
(() => super.x());

// element access in arrow
(() => super["x"]());

// property access in async arrow
(async () => super.x());

// element access in async arrow
(async () => super["x"]());
}

async property_access_only_read_only() {
// call with property access
super.x();

// property access (read)
const a = super.x;

// property access in arrow
(() => super.x());

// property access in async arrow
(async () => super.x());
}

async property_access_only_write_only() {
const f = () => {};

// property access (assign)
super.x = f;

// destructuring assign with property access
({ f: super.x } = { f });

// property access (assign) in arrow
(() => super.x = f);

// property access (assign) in async arrow
(async () => super.x = f);
}

async element_access_only_read_only() {
// call with element access
super["x"]();

// element access (read)
const a = super["x"];

// element access in arrow
(() => super["x"]());

// element access in async arrow
(async () => super["x"]());
}

async element_access_only_write_only() {
const f = () => {};

// element access (assign)
super["x"] = f;

// destructuring assign with element access
({ f: super["x"] } = { f });

// element access (assign) in arrow
(() => super["x"] = f);

// element access (assign) in async arrow
(async () => super["x"] = f);
}
}

Expand Down Expand Up @@ -110,6 +182,75 @@ class B extends A {
({ f: _super.x } = { f });
// destructuring assign with element access
({ f: _superIndex("x").value } = { f });
// property access in arrow
(() => _super.x.call(this));
// element access in arrow
(() => _superIndex("x").value.call(this));
// property access in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _super.x.call(this); }));
// element access in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").value.call(this); }));
});
}
property_access_only_read_only() {
const _super = Object.create(null, {
x: { get: () => super.x }
});
return __awaiter(this, void 0, void 0, function* () {
// call with property access
_super.x.call(this);
// property access (read)
const a = _super.x;
// property access in arrow
(() => _super.x.call(this));
// property access in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _super.x.call(this); }));
});
}
property_access_only_write_only() {
const _super = Object.create(null, {
x: { get: () => super.x, set: v => super.x = v }
});
return __awaiter(this, void 0, void 0, function* () {
const f = () => { };
// property access (assign)
_super.x = f;
// destructuring assign with property access
({ f: _super.x } = { f });
// property access (assign) in arrow
(() => _super.x = f);
// property access (assign) in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _super.x = f; }));
});
}
element_access_only_read_only() {
const _superIndex = name => super[name];
return __awaiter(this, void 0, void 0, function* () {
// call with element access
_superIndex("x").call(this);
// element access (read)
const a = _superIndex("x");
// element access in arrow
(() => _superIndex("x").call(this));
// element access in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").call(this); }));
});
}
element_access_only_write_only() {
const _superIndex = (function (geti, seti) {
const cache = Object.create(null);
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
})(name => super[name], (name, value) => super[name] = value);
return __awaiter(this, void 0, void 0, function* () {
const f = () => { };
// element access (assign)
_superIndex("x").value = f;
// destructuring assign with element access
({ f: _superIndex("x").value } = { f });
// element access (assign) in arrow
(() => _superIndex("x").value = f);
// element access (assign) in async arrow
(() => __awaiter(this, void 0, void 0, function* () { return _superIndex("x").value = f; }));
});
}
}
144 changes: 144 additions & 0 deletions tests/baselines/reference/asyncMethodWithSuper_es6.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,150 @@ class B extends A {
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 51, 30))

// property access in arrow
(() => super.x());
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// element access in arrow
(() => super["x"]());
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// property access in async arrow
(async () => super.x());
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// element access in async arrow
(async () => super["x"]());
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
}

async property_access_only_read_only() {
>property_access_only_read_only : Symbol(B.property_access_only_read_only, Decl(asyncMethodWithSuper_es6.ts, 64, 5))

// call with property access
super.x();
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// property access (read)
const a = super.x;
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 71, 13))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// property access in arrow
(() => super.x());
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// property access in async arrow
(async () => super.x());
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
}

async property_access_only_write_only() {
>property_access_only_write_only : Symbol(B.property_access_only_write_only, Decl(asyncMethodWithSuper_es6.ts, 78, 5))

const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))

// property access (assign)
super.x = f;
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))

// destructuring assign with property access
({ f: super.x } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 87, 10))
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 87, 27))

// property access (assign) in arrow
(() => super.x = f);
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))

// property access (assign) in async arrow
(async () => super.x = f);
>super.x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>x : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 81, 13))
}

async element_access_only_read_only() {
>element_access_only_read_only : Symbol(B.element_access_only_read_only, Decl(asyncMethodWithSuper_es6.ts, 94, 5))

// call with element access
super["x"]();
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// element access (read)
const a = super["x"];
>a : Symbol(a, Decl(asyncMethodWithSuper_es6.ts, 101, 13))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// element access in arrow
(() => super["x"]());
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))

// element access in async arrow
(async () => super["x"]());
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
}

async element_access_only_write_only() {
>element_access_only_write_only : Symbol(B.element_access_only_write_only, Decl(asyncMethodWithSuper_es6.ts, 108, 5))

const f = () => {};
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))

// element access (assign)
super["x"] = f;
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))

// destructuring assign with element access
({ f: super["x"] } = { f });
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 117, 10))
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 117, 30))

// element access (assign) in arrow
(() => super["x"] = f);
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))

// element access (assign) in async arrow
(async () => super["x"] = f);
>super : Symbol(A, Decl(asyncMethodWithSuper_es6.ts, 0, 0))
>"x" : Symbol(A.x, Decl(asyncMethodWithSuper_es6.ts, 0, 9))
>f : Symbol(f, Decl(asyncMethodWithSuper_es6.ts, 111, 13))
}
}

Loading

0 comments on commit 4b3178c

Please sign in to comment.