Merge pull request #9061 from Microsoft/fix-this-resolution-in-parameter-initializers

Fix this resolution in parameter initializers
This commit is contained in:
Nathan Shively-Sanders
2016-06-09 16:20:45 -07:00
committed by GitHub
5 changed files with 198 additions and 1 deletions
+12 -1
View File
@@ -8416,7 +8416,10 @@ namespace ts {
if (needToCaptureLexicalThis) {
captureLexicalThis(node, container);
}
if (isFunctionLike(container)) {
if (isFunctionLike(container) &&
(!isInParameterInitializerBeforeContainingFunction(node) || getFunctionLikeThisParameter(container))) {
// Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
// If this is a function in a JS file, it might be a class method. Check if it's the RHS
// of a x.prototype.y = function [name]() { .... }
if (container.kind === SyntaxKind.FunctionExpression &&
@@ -18507,6 +18510,14 @@ namespace ts {
}
}
function getFunctionLikeThisParameter(func: FunctionLikeDeclaration) {
if (func.parameters.length &&
func.parameters[0].name.kind === SyntaxKind.Identifier &&
(<Identifier>func.parameters[0].name).originalKeywordKind === SyntaxKind.ThisKeyword) {
return func.parameters[0];
}
}
function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) {
if (isDynamicName(node)) {
return grammarErrorOnNode(node, message);
@@ -0,0 +1,51 @@
//// [inferParameterWithMethodCallInitializer.ts]
function getNumber(): number {
return 1;
}
class Example {
getNumber(): number {
return 1;
}
doSomething(a = this.getNumber()): typeof a {
return a;
}
}
function weird(this: Example, a = this.getNumber()) {
return a;
}
class Weird {
doSomething(this: Example, a = this.getNumber()) {
return a;
}
}
//// [inferParameterWithMethodCallInitializer.js]
function getNumber() {
return 1;
}
var Example = (function () {
function Example() {
}
Example.prototype.getNumber = function () {
return 1;
};
Example.prototype.doSomething = function (a) {
if (a === void 0) { a = this.getNumber(); }
return a;
};
return Example;
}());
function weird(a) {
if (a === void 0) { a = this.getNumber(); }
return a;
}
var Weird = (function () {
function Weird() {
}
Weird.prototype.doSomething = function (a) {
if (a === void 0) { a = this.getNumber(); }
return a;
};
return Weird;
}());
@@ -0,0 +1,55 @@
=== tests/cases/compiler/inferParameterWithMethodCallInitializer.ts ===
function getNumber(): number {
>getNumber : Symbol(getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 0, 0))
return 1;
}
class Example {
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
getNumber(): number {
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
return 1;
}
doSomething(a = this.getNumber()): typeof a {
>doSomething : Symbol(Example.doSomething, Decl(inferParameterWithMethodCallInitializer.ts, 6, 5))
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
return a;
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 7, 16))
}
}
function weird(this: Example, a = this.getNumber()) {
>weird : Symbol(weird, Decl(inferParameterWithMethodCallInitializer.ts, 10, 1))
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 11, 15))
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 11, 29))
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
return a;
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 11, 29))
}
class Weird {
>Weird : Symbol(Weird, Decl(inferParameterWithMethodCallInitializer.ts, 13, 1))
doSomething(this: Example, a = this.getNumber()) {
>doSomething : Symbol(Weird.doSomething, Decl(inferParameterWithMethodCallInitializer.ts, 14, 13))
>this : Symbol(this, Decl(inferParameterWithMethodCallInitializer.ts, 15, 16))
>Example : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 15, 30))
>this.getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
>this : Symbol(Example, Decl(inferParameterWithMethodCallInitializer.ts, 2, 1))
>getNumber : Symbol(Example.getNumber, Decl(inferParameterWithMethodCallInitializer.ts, 3, 15))
return a;
>a : Symbol(a, Decl(inferParameterWithMethodCallInitializer.ts, 15, 30))
}
}
@@ -0,0 +1,60 @@
=== tests/cases/compiler/inferParameterWithMethodCallInitializer.ts ===
function getNumber(): number {
>getNumber : () => number
return 1;
>1 : number
}
class Example {
>Example : Example
getNumber(): number {
>getNumber : () => number
return 1;
>1 : number
}
doSomething(a = this.getNumber()): typeof a {
>doSomething : (a?: number) => number
>a : number
>this.getNumber() : number
>this.getNumber : () => number
>this : this
>getNumber : () => number
>a : number
return a;
>a : number
}
}
function weird(this: Example, a = this.getNumber()) {
>weird : (this: Example, a?: number) => number
>this : Example
>Example : Example
>a : number
>this.getNumber() : number
>this.getNumber : () => number
>this : Example
>getNumber : () => number
return a;
>a : number
}
class Weird {
>Weird : Weird
doSomething(this: Example, a = this.getNumber()) {
>doSomething : (this: Example, a?: number) => number
>this : Example
>Example : Example
>a : number
>this.getNumber() : number
>this.getNumber : () => number
>this : Example
>getNumber : () => number
return a;
>a : number
}
}
@@ -0,0 +1,20 @@
// @noImplicitAny: true
function getNumber(): number {
return 1;
}
class Example {
getNumber(): number {
return 1;
}
doSomething(a = this.getNumber()): typeof a {
return a;
}
}
function weird(this: Example, a = this.getNumber()) {
return a;
}
class Weird {
doSomething(this: Example, a = this.getNumber()) {
return a;
}
}