Skip to content

Commit 443abe6

Browse files
committed
Adds ThisType to SyntaxKind, to distinguish between a 'this' expression and a 'this' type. Needed for transforms
1 parent 5ac4b78 commit 443abe6

9 files changed

Lines changed: 42 additions & 26 deletions

File tree

src/compiler/binder.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ namespace ts {
189189
}
190190
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
191191
const nameExpression = (<ComputedPropertyName>node.name).expression;
192-
// treat computed property names where expression is string/numeric literal as just string/numeric literal
192+
// treat computed property names where expression is string/numeric literal as just string/numeric literal
193193
if (isStringOrNumericLiteral(nameExpression.kind)) {
194194
return (<LiteralExpression>nameExpression).text;
195195
}
@@ -450,7 +450,7 @@ namespace ts {
450450

451451
/**
452452
* Returns true if node and its subnodes were successfully traversed.
453-
* Returning false means that node was not examined and caller needs to dive into the node himself.
453+
* Returning false means that node was not examined and caller needs to dive into the node himself.
454454
*/
455455
function bindReachableStatement(node: Node): void {
456456
if (checkUnreachable(node)) {
@@ -560,7 +560,7 @@ namespace ts {
560560
}
561561

562562
function bindIfStatement(n: IfStatement): void {
563-
// denotes reachability state when entering 'thenStatement' part of the if statement:
563+
// denotes reachability state when entering 'thenStatement' part of the if statement:
564564
// i.e. if condition is false then thenStatement is unreachable
565565
const ifTrueState = n.expression.kind === SyntaxKind.FalseKeyword ? Reachability.Unreachable : currentReachabilityState;
566566
// denotes reachability state when entering 'elseStatement':
@@ -1179,7 +1179,7 @@ namespace ts {
11791179
return checkStrictModePrefixUnaryExpression(<PrefixUnaryExpression>node);
11801180
case SyntaxKind.WithStatement:
11811181
return checkStrictModeWithStatement(<WithStatement>node);
1182-
case SyntaxKind.ThisKeyword:
1182+
case SyntaxKind.ThisType:
11831183
seenThisKeyword = true;
11841184
return;
11851185

@@ -1528,7 +1528,7 @@ namespace ts {
15281528

15291529
// unreachable code is reported if
15301530
// - user has explicitly asked about it AND
1531-
// - statement is in not ambient context (statements in ambient context is already an error
1531+
// - statement is in not ambient context (statements in ambient context is already an error
15321532
// so we should not report extras) AND
15331533
// - node is not variable statement OR
15341534
// - node is block scoped variable statement OR

src/compiler/checker.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,7 +4541,7 @@ namespace ts {
45414541
return esSymbolType;
45424542
case SyntaxKind.VoidKeyword:
45434543
return voidType;
4544-
case SyntaxKind.ThisKeyword:
4544+
case SyntaxKind.ThisType:
45454545
return getTypeFromThisTypeNode(node);
45464546
case SyntaxKind.StringLiteral:
45474547
return getTypeFromStringLiteral(<StringLiteral>node);
@@ -10157,7 +10157,7 @@ namespace ts {
1015710157
checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
1015810158
}
1015910159
else {
10160-
// non-shorthand property assignments should always have initializers
10160+
// non-shorthand property assignments should always have initializers
1016110161
checkDestructuringAssignment((<PropertyAssignment>p).initializer, type);
1016210162
}
1016310163
}
@@ -14620,6 +14620,9 @@ namespace ts {
1462014620
const type = isExpression(node) ? checkExpression(<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
1462114621
return type.symbol;
1462214622

14623+
case SyntaxKind.ThisType:
14624+
return getTypeFromTypeNode(<TypeNode>node).symbol;
14625+
1462314626
case SyntaxKind.ConstructorKeyword:
1462414627
// constructor keyword for an overload, should take us to the definition if it exist
1462514628
const constructorDeclaration = node.parent;

src/compiler/declarationEmitter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ namespace ts {
378378
case SyntaxKind.BooleanKeyword:
379379
case SyntaxKind.SymbolKeyword:
380380
case SyntaxKind.VoidKeyword:
381-
case SyntaxKind.ThisKeyword:
381+
case SyntaxKind.ThisType:
382382
case SyntaxKind.StringLiteral:
383383
return writeTextOfNode(currentText, type);
384384
case SyntaxKind.ExpressionWithTypeArguments:

src/compiler/emitter.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,18 +428,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
428428
* var loop = function(x) { <code where 'arguments' is replaced witg 'arguments_1'> }
429429
* var arguments_1 = arguments
430430
* for (var x;;) loop(x);
431-
* otherwise semantics of the code will be different since 'arguments' inside converted loop body
431+
* otherwise semantics of the code will be different since 'arguments' inside converted loop body
432432
* will refer to function that holds converted loop.
433433
* This value is set on demand.
434434
*/
435435
argumentsName?: string;
436436

437437
/*
438438
* list of non-block scoped variable declarations that appear inside converted loop
439-
* such variable declarations should be moved outside the loop body
439+
* such variable declarations should be moved outside the loop body
440440
* for (let x;;) {
441441
* var y = 1;
442-
* ...
442+
* ...
443443
* }
444444
* should be converted to
445445
* var loop = function(x) {
@@ -2651,7 +2651,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
26512651
}
26522652

26532653
function emitCallTarget(node: Expression): Expression {
2654-
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword) {
2654+
if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || /*node.kind === SyntaxKind.ThisType ||*/ node.kind === SyntaxKind.SuperKeyword) {
26552655
emit(node);
26562656
return node;
26572657
}
@@ -3226,7 +3226,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
32263226
}
32273227

32283228
if (convertedLoopState && (getCombinedNodeFlags(decl) & NodeFlags.BlockScoped) === 0) {
3229-
// we are inside a converted loop - this can only happen in downlevel scenarios
3229+
// we are inside a converted loop - this can only happen in downlevel scenarios
32303230
// record names for all variable declarations
32313231
for (const varDecl of decl.declarations) {
32323232
hoistVariableDeclarationFromLoop(convertedLoopState, varDecl);
@@ -3551,7 +3551,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
35513551
write(`case "${labelMarker}": `);
35523552
// if there are no outer converted loop or outer label in question is located inside outer converted loop
35533553
// then emit labeled break\continue
3554-
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
3554+
// otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
35553555
if (!outerLoop || (outerLoop.labels && outerLoop.labels[labelText])) {
35563556
if (isBreak) {
35573557
write("break ");
@@ -7868,6 +7868,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
78687868
case SyntaxKind.GetAccessor:
78697869
case SyntaxKind.SetAccessor:
78707870
return emitAccessor(<AccessorDeclaration>node);
7871+
// case SyntaxKind.ThisType:
7872+
// console.log("ThisType: emitJavaScriptWorker");
78717873
case SyntaxKind.ThisKeyword:
78727874
return emitThis(node);
78737875
case SyntaxKind.SuperKeyword:

src/compiler/parser.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,12 @@ namespace ts {
19561956
return finishNode(node);
19571957
}
19581958

1959+
function parseThisTypeNode(): TypeNode {
1960+
const node = <TypeNode>createNode(SyntaxKind.ThisType);
1961+
nextToken();
1962+
return finishNode(node);
1963+
}
1964+
19591965
function parseTypeQuery(): TypeQueryNode {
19601966
const node = <TypeQueryNode>createNode(SyntaxKind.TypeQuery);
19611967
parseExpected(SyntaxKind.TypeOfKeyword);
@@ -2388,8 +2394,9 @@ namespace ts {
23882394
case SyntaxKind.StringLiteral:
23892395
return <StringLiteral>parseLiteralNode(/*internName*/ true);
23902396
case SyntaxKind.VoidKeyword:
2391-
case SyntaxKind.ThisKeyword:
23922397
return parseTokenNode<TypeNode>();
2398+
case SyntaxKind.ThisKeyword:
2399+
return parseThisTypeNode();
23932400
case SyntaxKind.TypeOfKeyword:
23942401
return parseTypeQuery();
23952402
case SyntaxKind.OpenBraceToken:

src/compiler/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ namespace ts {
204204
UnionType,
205205
IntersectionType,
206206
ParenthesizedType,
207+
ThisType,
207208
// Binding patterns
208209
ObjectBindingPattern,
209210
ArrayBindingPattern,
@@ -349,7 +350,7 @@ namespace ts {
349350
FirstFutureReservedWord = ImplementsKeyword,
350351
LastFutureReservedWord = YieldKeyword,
351352
FirstTypeNode = TypePredicate,
352-
LastTypeNode = ParenthesizedType,
353+
LastTypeNode = ThisType,
353354
FirstPunctuation = OpenBraceToken,
354355
LastPunctuation = CaretEqualsToken,
355356
FirstToken = Unknown,
@@ -726,6 +727,7 @@ namespace ts {
726727
// @kind(SyntaxKind.StringKeyword)
727728
// @kind(SyntaxKind.SymbolKeyword)
728729
// @kind(SyntaxKind.VoidKeyword)
730+
// @kind(SyntaxKind.ThisType)
729731
export interface TypeNode extends Node {
730732
_typeNodeBrand: any;
731733
}

src/services/services.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ namespace ts {
23142314

23152315
return true;
23162316
}
2317-
2317+
23182318
return false;
23192319
}
23202320

@@ -2333,7 +2333,7 @@ namespace ts {
23332333
}
23342334
return false;
23352335
}
2336-
2336+
23372337
function tryConsumeDefine(): boolean {
23382338
let token = scanner.getToken();
23392339
if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") {
@@ -2359,7 +2359,7 @@ namespace ts {
23592359
if (token !== SyntaxKind.OpenBracketToken) {
23602360
return true;
23612361
}
2362-
2362+
23632363
// skip open bracket
23642364
token = scanner.scan();
23652365
let i = 0;
@@ -2374,7 +2374,7 @@ namespace ts {
23742374
token = scanner.scan();
23752375
}
23762376
return true;
2377-
2377+
23782378
}
23792379
return false;
23802380
}
@@ -3976,7 +3976,7 @@ namespace ts {
39763976
let sourceFile = getValidSourceFile(fileName);
39773977

39783978
let entries: CompletionEntry[] = [];
3979-
3979+
39803980
if (isRightOfDot && isSourceFileJavaScript(sourceFile)) {
39813981
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries);
39823982
addRange(entries, getJavaScriptCompletionEntries(sourceFile, uniqueNames));
@@ -4595,6 +4595,7 @@ namespace ts {
45954595
case SyntaxKind.PropertyAccessExpression:
45964596
case SyntaxKind.QualifiedName:
45974597
case SyntaxKind.ThisKeyword:
4598+
case SyntaxKind.ThisType:
45984599
case SyntaxKind.SuperKeyword:
45994600
// For the identifiers/this/super etc get the type at position
46004601
let type = typeChecker.getTypeAtLocation(node);
@@ -4866,6 +4867,7 @@ namespace ts {
48664867
function getSemanticDocumentHighlights(node: Node): DocumentHighlights[] {
48674868
if (node.kind === SyntaxKind.Identifier ||
48684869
node.kind === SyntaxKind.ThisKeyword ||
4870+
node.kind === SyntaxKind.ThisType ||
48694871
node.kind === SyntaxKind.SuperKeyword ||
48704872
isLiteralNameOfPropertyDeclarationOrIndexAccess(node) ||
48714873
isNameOfExternalModuleImportOrDeclaration(node)) {
@@ -5561,7 +5563,7 @@ namespace ts {
55615563
}
55625564
}
55635565

5564-
if (node.kind === SyntaxKind.ThisKeyword) {
5566+
if (node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.ThisType) {
55655567
return getReferencesForThisKeyword(node, sourceFiles);
55665568
}
55675569

@@ -6043,7 +6045,7 @@ namespace ts {
60436045
cancellationToken.throwIfCancellationRequested();
60446046

60456047
let node = getTouchingWord(sourceFile, position);
6046-
if (!node || node.kind !== SyntaxKind.ThisKeyword) {
6048+
if (!node || (node.kind !== SyntaxKind.ThisKeyword && node.kind !== SyntaxKind.ThisType)) {
60476049
return;
60486050
}
60496051

@@ -6405,7 +6407,8 @@ namespace ts {
64056407

64066408
return node.parent.kind === SyntaxKind.TypeReference ||
64076409
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent)) ||
6408-
node.kind === SyntaxKind.ThisKeyword && !isExpression(node);
6410+
(node.kind === SyntaxKind.ThisKeyword && !isExpression(node)) ||
6411+
node.kind === SyntaxKind.ThisType;
64096412
}
64106413

64116414
function isNamespaceReference(node: Node): boolean {
@@ -6525,6 +6528,7 @@ namespace ts {
65256528
case SyntaxKind.NullKeyword:
65266529
case SyntaxKind.SuperKeyword:
65276530
case SyntaxKind.ThisKeyword:
6531+
case SyntaxKind.ThisType:
65286532
case SyntaxKind.Identifier:
65296533
break;
65306534

tests/baselines/reference/thisTypeInClasses.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class C5 {
9292
let f1 = (x: this): this => this;
9393
>f1 : Symbol(f1, Decl(thisTypeInClasses.ts, 34, 11))
9494
>x : Symbol(x, Decl(thisTypeInClasses.ts, 34, 18))
95-
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
9695
>this : Symbol(C5, Decl(thisTypeInClasses.ts, 30, 1))
9796

9897
let f2 = (x: this) => this;

tests/baselines/reference/thisTypeInClasses.types

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ class C5 {
9393
>f1 : (x: this) => this
9494
>(x: this): this => this : (x: this) => this
9595
>x : this
96-
>this : this
9796
>this : this
9897

9998
let f2 = (x: this) => this;

0 commit comments

Comments
 (0)