mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into removeDotToken
This commit is contained in:
@@ -1961,7 +1961,7 @@ namespace ts {
|
||||
classPrototype.parent = leftSideOfAssignment;
|
||||
|
||||
const funcSymbol = container.locals[constructorFunction.text];
|
||||
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function)) {
|
||||
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -11495,8 +11495,12 @@ namespace ts {
|
||||
// When resolved signature is a call signature (and not a construct signature) the result type is any, unless
|
||||
// the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations
|
||||
// in a JS file
|
||||
const funcSymbol = checkExpression(node.expression).symbol;
|
||||
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function)) {
|
||||
// Note:JS inferred classes might come from a variable declaration instead of a function declaration.
|
||||
// In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration.
|
||||
const funcSymbol = node.expression.kind === SyntaxKind.Identifier ?
|
||||
getResolvedSymbol(node.expression as Identifier) :
|
||||
checkExpression(node.expression).symbol;
|
||||
if (funcSymbol && funcSymbol.members && (funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
|
||||
return getInferredClassType(funcSymbol);
|
||||
}
|
||||
else if (compilerOptions.noImplicitAny) {
|
||||
|
||||
@@ -1264,6 +1264,18 @@ namespace ts {
|
||||
return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is a variable declaration whose initializer is a function expression.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function isDeclarationOfFunctionExpression(s: Symbol) {
|
||||
if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = s.valueDeclaration as VariableDeclaration;
|
||||
return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getSpecialPropertyAssignmentKind(expression: Node): SpecialPropertyAssignmentKind {
|
||||
|
||||
@@ -730,7 +730,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean) {
|
||||
public verifyReferencesAtPositionListContains(fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
|
||||
const references = this.getReferencesAtCaret();
|
||||
|
||||
if (!references || references.length === 0) {
|
||||
@@ -743,11 +743,14 @@ namespace FourSlash {
|
||||
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
|
||||
this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`);
|
||||
}
|
||||
if (typeof isDefinition !== "undefined" && reference.isDefinition !== isDefinition) {
|
||||
this.raiseError(`verifyReferencesAtPositionListContains failed - item isDefinition value does not match, actual: ${reference.isDefinition}, expected: ${isDefinition}.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
|
||||
const missingItem = { fileName, start, end, isWriteAccess, isDefinition };
|
||||
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
|
||||
}
|
||||
|
||||
@@ -2837,8 +2840,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyReferencesCountIs(count, /*localFilesOnly*/ false);
|
||||
}
|
||||
|
||||
public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean) {
|
||||
this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess);
|
||||
public referencesAtPositionContains(range: FourSlash.Range, isWriteAccess?: boolean, isDefinition?: boolean) {
|
||||
this.state.verifyReferencesAtPositionListContains(range.fileName, range.start, range.end, isWriteAccess, isDefinition);
|
||||
}
|
||||
|
||||
public signatureHelpPresent() {
|
||||
|
||||
@@ -376,6 +376,7 @@ namespace ts.server {
|
||||
fileName: fileName,
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
isWriteAccess: entry.isWriteAccess,
|
||||
isDefinition: entry.isDefinition,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -536,6 +537,7 @@ namespace ts.server {
|
||||
fileName,
|
||||
textSpan: ts.createTextSpanFromBounds(start, end),
|
||||
isWriteAccess: entry.isWriteAccess,
|
||||
isDefinition: false
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+5
@@ -304,6 +304,11 @@ declare namespace ts.server.protocol {
|
||||
* True if reference is a write location, false otherwise.
|
||||
*/
|
||||
isWriteAccess: boolean;
|
||||
|
||||
/**
|
||||
* True if reference is a definition, false otherwise.
|
||||
*/
|
||||
isDefinition: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -379,7 +379,7 @@ namespace ts.server {
|
||||
start,
|
||||
end,
|
||||
file: fileName,
|
||||
isWriteAccess
|
||||
isWriteAccess,
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -555,7 +555,8 @@ namespace ts.server {
|
||||
start: start,
|
||||
lineText: lineText,
|
||||
end: compilerService.host.positionToLineOffset(ref.fileName, ts.textSpanEnd(ref.textSpan)),
|
||||
isWriteAccess: ref.isWriteAccess
|
||||
isWriteAccess: ref.isWriteAccess,
|
||||
isDefinition: ref.isDefinition
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1209,6 +1209,7 @@ namespace ts {
|
||||
textSpan: TextSpan;
|
||||
fileName: string;
|
||||
isWriteAccess: boolean;
|
||||
isDefinition: boolean;
|
||||
}
|
||||
|
||||
export interface DocumentHighlights {
|
||||
@@ -5753,7 +5754,8 @@ namespace ts {
|
||||
result.push({
|
||||
fileName: entry.fileName,
|
||||
textSpan: highlightSpan.textSpan,
|
||||
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference
|
||||
isWriteAccess: highlightSpan.kind === HighlightSpanKind.writtenReference,
|
||||
isDefinition: false
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -6187,7 +6189,8 @@ namespace ts {
|
||||
references: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textSpan: createTextSpan(position, searchText.length),
|
||||
isWriteAccess: false
|
||||
isWriteAccess: false,
|
||||
isDefinition: false
|
||||
}]
|
||||
});
|
||||
}
|
||||
@@ -6741,7 +6744,8 @@ namespace ts {
|
||||
return {
|
||||
fileName: node.getSourceFile().fileName,
|
||||
textSpan: createTextSpanFromBounds(start, end),
|
||||
isWriteAccess: isWriteAccess(node)
|
||||
isWriteAccess: isWriteAccess(node),
|
||||
isDefinition: isDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Returns a JSON-encoded value of the type:
|
||||
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean }[]
|
||||
* { fileName: string; textSpan: { start: number; length: number}; isWriteAccess: boolean, isDefinition?: boolean }[]
|
||||
*/
|
||||
getReferencesAtPosition(fileName: string, position: number): string;
|
||||
|
||||
@@ -1141,4 +1141,4 @@ namespace TypeScript.Services {
|
||||
/* @internal */
|
||||
const toolsVersion = "1.9";
|
||||
|
||||
/* tslint:enable:no-unused-variable */
|
||||
/* tslint:enable:no-unused-variable */
|
||||
|
||||
@@ -125,7 +125,7 @@ declare namespace FourSlashInterface {
|
||||
completionListAllowsNewIdentifier(): void;
|
||||
memberListIsEmpty(): void;
|
||||
referencesCountIs(count: number): void;
|
||||
referencesAtPositionContains(range: Range, isWriteAccess?: boolean): void;
|
||||
referencesAtPositionContains(range: Range, isWriteAccess?: boolean, isDefinition?: boolean): void;
|
||||
signatureHelpPresent(): void;
|
||||
errorExistsBetweenMarkers(startMarker: string, endMarker: string): void;
|
||||
errorExistsAfterMarker(markerName?: string): void;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////var [|{| "isDefinition": true |}f|] = x => x + 1;
|
||||
////[|{| "isDefinition": false |}f|](12);
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////const { [|{| "isDefinition": true |}x|], y } = { x: 1, y: 2 };
|
||||
////const z = [|{| "isDefinition": false |}x|];
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////class [|{| "isDefinition": true |}C|] {
|
||||
//// n: number;
|
||||
//// constructor() {
|
||||
//// this.n = 12;
|
||||
//// }
|
||||
////}
|
||||
////let c = new [|{| "isDefinition": false |}C|]();
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////let o = { ["[|{| "isDefinition": true |}foo|]"]: 12 };
|
||||
////let y = o.[|{| "isDefinition": false |}foo|];
|
||||
////let z = o['[|{| "isDefinition": false |}foo|]'];
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////enum [|{| "isDefinition": true |}E|] {
|
||||
//// First,
|
||||
//// Second
|
||||
////}
|
||||
////let first = [|{| "isDefinition": false |}E|].First;
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
// @Filename: m.ts
|
||||
////export var [|{| "isDefinition": true |}x|] = 12;
|
||||
// @Filename: main.ts
|
||||
////import { [|{| "isDefinition": true |}x|] } from "./m";
|
||||
////const y = [|{| "isDefinition": false |}x|];
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////function [|{| "isDefinition": true |}func|](x: number) {
|
||||
////}
|
||||
////[|{| "isDefinition": false |}func|](x)
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////interface [|{| "isDefinition": true |}I|] {
|
||||
//// p: number;
|
||||
////}
|
||||
////let i: [|{| "isDefinition": false |}I|] = { p: 12 };
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////interface [|{| "isDefinition": true |}Numbers|] {
|
||||
//// p: number;
|
||||
////}
|
||||
////interface [|{| "isDefinition": true |}Numbers|] {
|
||||
//// m: number;
|
||||
////}
|
||||
////class [|{| "isDefinition": true |}Numbers|] {
|
||||
//// f(n: number) {
|
||||
//// return this.p + this.m + n;
|
||||
//// }
|
||||
////}
|
||||
////let i: [|{| "isDefinition": false |}Numbers|] = new [|{| "isDefinition": false |}Numbers|]();
|
||||
////let x = i.f(i.p + i.m);
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////namespace [|{| "isDefinition": true |}Numbers|] {
|
||||
//// export var n = 12;
|
||||
////}
|
||||
////let x = [|{| "isDefinition": false |}Numbers|].n + 1;
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////let o = { [|{| "isDefinition": true |}1|]: 12 };
|
||||
////let y = o[[|{| "isDefinition": false |}1|]];
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////function f([|{| "isDefinition": true |}x|]: number) {
|
||||
//// return [|{| "isDefinition": false |}x|] + 1
|
||||
////}
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////let o = { "[|{| "isDefinition": true |}x|]": 12 };
|
||||
////let y = o.[|{| "isDefinition": false |}x|];
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////type [|{| "isDefinition": true |}Alias|]= number;
|
||||
////let n: [|{| "isDefinition": false |}Alias|] = 12;
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////var [|{| "isDefinition": true |}x|] = 0;
|
||||
////var assignmentRightHandSide = [|{| "isDefinition": false |}x|];
|
||||
////var assignmentRightHandSide2 = 1 + [|{| "isDefinition": false |}x|];
|
||||
////
|
||||
////[|{| "isDefinition": false |}x|] = 1;
|
||||
////[|{| "isDefinition": false |}x|] = [|{| "isDefinition": false |}x|] + [|{| "isDefinition": false |}x|];
|
||||
////
|
||||
////[|{| "isDefinition": false |}x|] == 1;
|
||||
////[|{| "isDefinition": false |}x|] <= 1;
|
||||
////
|
||||
////var preIncrement = ++[|{| "isDefinition": false |}x|];
|
||||
////var postIncrement = [|{| "isDefinition": false |}x|]++;
|
||||
////var preDecrement = --[|{| "isDefinition": false |}x|];
|
||||
////var postDecrement = [|{| "isDefinition": false |}x|]--;
|
||||
////
|
||||
////[|{| "isDefinition": false |}x|] += 1;
|
||||
////[|{| "isDefinition": false |}x|] <<= 1;
|
||||
var firstRange = test.ranges()[0];
|
||||
goTo.position(firstRange.start, firstRange.fileName);
|
||||
test.ranges().forEach(range => {
|
||||
verify.referencesAtPositionContains(range, undefined, range.marker.data.isDefinition);
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
// @allowJs: true
|
||||
// @Filename: something.js
|
||||
////var C = function () { }
|
||||
/////**
|
||||
//// * The prototype method.
|
||||
//// * @param {string} a Parameter definition.
|
||||
//// */
|
||||
////function f(a) {}
|
||||
////C.prototype.m = f;
|
||||
////
|
||||
////var x = new C();
|
||||
////x/*1*/./*2*/m();
|
||||
goTo.marker('1');
|
||||
verify.quickInfoIs('var x: {\n m: (a: string) => void;\n}');
|
||||
goTo.marker('2');
|
||||
verify.completionListContains('m', '(property) C.m: (a: string) => void', 'The prototype method.');
|
||||
Reference in New Issue
Block a user