Skip to content

Commit 30b3871

Browse files
committed
Merge branch 'master' into removeDotToken
2 parents 5ea469a + 7890fd5 commit 30b3871

26 files changed

+227
-15
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ namespace ts {
19611961
classPrototype.parent = leftSideOfAssignment;
19621962

19631963
const funcSymbol = container.locals[constructorFunction.text];
1964-
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function)) {
1964+
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
19651965
return;
19661966
}
19671967

src/compiler/checker.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11495,8 +11495,12 @@ namespace ts {
1149511495
// When resolved signature is a call signature (and not a construct signature) the result type is any, unless
1149611496
// the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
1149711497
// in a JS file
11498-
const funcSymbol = checkExpression(node.expression).symbol;
11499-
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function)) {
11498+
// Note:JS inferred classes might come from a variable declaration instead of a function declaration.
11499+
// In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
11500+
const funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
11501+
getResolvedSymbol(node.expression as Identifier) :
11502+
checkExpression(node.expression).symbol;
11503+
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
1150011504
return getInferredClassType(funcSymbol);
1150111505
}
1150211506
else if (compilerOptions.noImplicitAny) {

src/compiler/utilities.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,18 @@ namespace ts {
12641264
return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote;
12651265
}
12661266

1267+
/**
1268+
* Returns true if the node is a variable declaration whose initializer is a function expression.
1269+
* This function does not test if the node is in a JavaScript file or not.
1270+
*/
1271+
export function isDeclarationOfFunctionExpression(s: Symbol) {
1272+
if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
1273+
const declaration = s.valueDeclaration as VariableDeclaration;
1274+
return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression;
1275+
}
1276+
return false;
1277+
}
1278+
12671279
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
12681280
/// assignments we treat as special in the binder
12691281
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {

src/harness/fourslash.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ namespace FourSlash {
730730
}
731731
}
732732

733-
public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) {
733+
public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
734734
const references = this.getReferencesAtCaret();
735735

736736
if (!references || references.length === 0) {
@@ -743,11 +743,14 @@ namespace FourSlash {
743743
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
744744
this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`);
745745
}
746+
if (typeof isDefinition !== "undefined" && reference.isDefinition !== isDefinition) {
747+
this.raiseError(`verifyReferencesAtPositionListContains failed - item isDefinition value does not match, actual: ${reference.isDefinition}, expected: ${isDefinition}.`);
748+
}
746749
return;
747750
}
748751
}
749752

750-
const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
753+
const missingItem = { fileName, start, end, isWriteAccess, isDefinition };
751754
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
752755
}
753756

@@ -2837,8 +2840,8 @@ namespace FourSlashInterface {
28372840
this.state.verifyReferencesCountIs(count, /*localFilesOnly*/ false);
28382841
}
28392842

2840-
public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean) {
2841-
this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
2843+
public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean, isDefinition?: boolean) {
2844+
this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess, isDefinition);
28422845
}
28432846

28442847
public signatureHelpPresent() {

src/server/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ namespace ts.server {
376376
fileName: fileName,
377377
textSpan: ts.createTextSpanFromBounds(start, end),
378378
isWriteAccess: entry.isWriteAccess,
379+
isDefinition: entry.isDefinition,
379380
};
380381
});
381382
}
@@ -536,6 +537,7 @@ namespace ts.server {
536537
fileName,
537538
textSpan: ts.createTextSpanFromBounds(start, end),
538539
isWriteAccess: entry.isWriteAccess,
540+
isDefinition: false
539541
};
540542
});
541543
}

src/server/protocol.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,11 @@ declare namespace ts.server.protocol {
304304
* True if reference is a write location, false otherwise.
305305
*/
306306
isWriteAccess: boolean;
307+
308+
/**
309+
* True if reference is a definition, false otherwise.
310+
*/
311+
isDefinition: boolean;
307312
}
308313

309314
/**

src/server/session.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ namespace ts.server {
379379
start,
380380
end,
381381
file: fileName,
382-
isWriteAccess
382+
isWriteAccess,
383383
};
384384
});
385385
}
@@ -555,7 +555,8 @@ namespace ts.server {
555555
start: start,
556556
lineText: lineText,
557557
end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)),
558-
isWriteAccess: ref.isWriteAccess
558+
isWriteAccess: ref.isWriteAccess,
559+
isDefinition: ref.isDefinition
559560
};
560561
});
561562
},

src/services/services.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,7 @@ namespace ts {
12091209
textSpan: TextSpan;
12101210
fileName: string;
12111211
isWriteAccess: boolean;
1212+
isDefinition: boolean;
12121213
}
12131214

12141215
export interface DocumentHighlights {
@@ -5753,7 +5754,8 @@ namespace ts {
57535754
result.push({
57545755
fileName: entry.fileName,
57555756
textSpan: highlightSpan.textSpan,
5756-
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference
5757+
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
5758+
isDefinition: false
57575759
});
57585760
}
57595761
}
@@ -6187,7 +6189,8 @@ namespace ts {
61876189
references: [{
61886190
fileName: sourceFile.fileName,
61896191
textSpan: createTextSpan(position, searchText.length),
6190-
isWriteAccess: false
6192+
isWriteAccess: false,
6193+
isDefinition: false
61916194
}]
61926195
});
61936196
}
@@ -6741,7 +6744,8 @@ namespace ts {
67416744
return {
67426745
fileName: node.getSourceFile().fileName,
67436746
textSpan: createTextSpanFromBounds(start, end),
6744-
isWriteAccess: isWriteAccess(node)
6747+
isWriteAccess: isWriteAccess(node),
6748+
isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node)
67456749
};
67466750
}
67476751

src/services/shims.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ namespace ts {
164164

165165
/**
166166
* Returns a JSON-encoded value of the type:
167-
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
167+
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[]
168168
*/
169169
getReferencesAtPosition(fileName: string, position: number): string;
170170

@@ -1141,4 +1141,4 @@ namespace TypeScript.Services {
11411141
/* @internal */
11421142
const toolsVersion = "1.9";
11431143

1144-
/* tslint:enable:no-unused-variable */
1144+
/* tslint:enable:no-unused-variable */

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ declare namespace FourSlashInterface {
125125
completionListAllowsNewIdentifier(): void;
126126
memberListIsEmpty(): void;
127127
referencesCountIs(count: number): void;
128-
referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
128+
referencesAtPositionContains(range: Range, isWriteAccess?: boolean, isDefinition?: boolean): void;
129129
signatureHelpPresent(): void;
130130
errorExistsBetweenMarkers(startMarker: string, endMarker: string): void;
131131
errorExistsAfterMarker(markerName?: string): void;

0 commit comments

Comments
 (0)