mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 01:39:28 -06:00
Merge branch 'master' into layering
This commit is contained in:
commit
ef2087add5
@ -1515,6 +1515,14 @@ module FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifyDefinitionsCount(negative: boolean, expectedCount: number) {
|
||||
var assertFn = negative ? assert.notEqual : assert.equal;
|
||||
|
||||
var definitions = this.languageService.getDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
|
||||
assertFn(definitions.length, expectedCount, this.messageAtLastKnownMarker("Definitions Count"));
|
||||
}
|
||||
|
||||
public verifyDefinitionsName(negative: boolean, expectedName: string, expectedContainerName: string) {
|
||||
this.taoInvalidReason = 'verifyDefinititionsInfo NYI';
|
||||
|
||||
@ -1523,10 +1531,10 @@ module FourSlash {
|
||||
var actualDefinitionContainerName = definitions && definitions.length ? definitions[0].containerName : "";
|
||||
if (negative) {
|
||||
assert.notEqual(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name"));
|
||||
assert.notEqual(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Container Name"));
|
||||
assert.notEqual(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name"));
|
||||
} else {
|
||||
assert.equal(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Name"));
|
||||
assert.equal(actualDefinitionName, expectedName, this.messageAtLastKnownMarker("Definition Info Container Name"));
|
||||
assert.equal(actualDefinitionContainerName, expectedContainerName, this.messageAtLastKnownMarker("Definition Info Container Name"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2585,7 +2585,7 @@ module ts {
|
||||
}
|
||||
|
||||
// TODO(drosen): use contextual SemanticMeaning.
|
||||
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker, location?: Node): string {
|
||||
function getSymbolKind(symbol: Symbol, typeResolver: TypeChecker, location: Node): string {
|
||||
var flags = symbol.getFlags();
|
||||
|
||||
if (flags & SymbolFlags.Class) return ScriptElementKind.classElement;
|
||||
@ -3084,6 +3084,83 @@ module ts {
|
||||
|
||||
/// Goto definition
|
||||
function getDefinitionAtPosition(filename: string, position: number): DefinitionInfo[] {
|
||||
synchronizeHostData();
|
||||
|
||||
filename = normalizeSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Labels
|
||||
if (isJumpStatementTarget(node)) {
|
||||
var labelName = (<Identifier>node).text;
|
||||
var label = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
|
||||
return label ? [getDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
|
||||
}
|
||||
|
||||
/// Triple slash reference comments
|
||||
var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined);
|
||||
if (comment) {
|
||||
var referenceFile = tryResolveScriptReference(program, sourceFile, comment);
|
||||
if (referenceFile) {
|
||||
return [{
|
||||
fileName: referenceFile.filename,
|
||||
textSpan: createTextSpanFromBounds(0, 0),
|
||||
kind: ScriptElementKind.scriptElement,
|
||||
name: comment.filename,
|
||||
containerName: undefined,
|
||||
containerKind: undefined
|
||||
}];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var symbol = typeInfoResolver.getSymbolAtLocation(node);
|
||||
|
||||
// Could not find a symbol e.g. node is string or number keyword,
|
||||
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var result: DefinitionInfo[] = [];
|
||||
|
||||
// Because name in short-hand property assignment has two different meanings: property name and property value,
|
||||
// using go-to-definition at such position should go to the variable declaration of the property value rather than
|
||||
// go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
|
||||
// is performed at the location of property access, we would like to go to definition of the property in the short-hand
|
||||
// assignment. This case and others are handled by the following code.
|
||||
if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
var shorthandSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
|
||||
var shorthandDeclarations = shorthandSymbol.getDeclarations();
|
||||
var shorthandSymbolKind = getSymbolKind(shorthandSymbol, typeInfoResolver, node);
|
||||
var shorthandSymbolName = typeInfoResolver.symbolToString(shorthandSymbol);
|
||||
var shorthandContainerName = typeInfoResolver.symbolToString(symbol.parent, node);
|
||||
forEach(shorthandDeclarations, declaration => {
|
||||
result.push(getDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
|
||||
});
|
||||
return result
|
||||
}
|
||||
|
||||
var declarations = symbol.getDeclarations();
|
||||
var symbolName = typeInfoResolver.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
|
||||
var symbolKind = getSymbolKind(symbol, typeInfoResolver, node);
|
||||
var containerSymbol = symbol.parent;
|
||||
var containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : "";
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
// Just add all the declarations.
|
||||
forEach(declarations, declaration => {
|
||||
result.push(getDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
function getDefinitionInfo(node: Node, symbolKind: string, symbolName: string, containerName: string): DefinitionInfo {
|
||||
return {
|
||||
fileName: node.getSourceFile().filename,
|
||||
@ -3139,83 +3216,6 @@ module ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronizeHostData();
|
||||
|
||||
filename = normalizeSlashes(filename);
|
||||
var sourceFile = getSourceFile(filename);
|
||||
|
||||
var node = getTouchingPropertyName(sourceFile, position);
|
||||
if (!node) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Labels
|
||||
if (isJumpStatementTarget(node)) {
|
||||
var labelName = (<Identifier>node).text;
|
||||
var label = getTargetLabel((<BreakOrContinueStatement>node.parent), (<Identifier>node).text);
|
||||
return label ? [getDefinitionInfo(label, ScriptElementKind.label, labelName, /*containerName*/ undefined)] : undefined;
|
||||
}
|
||||
|
||||
/// Triple slash reference comments
|
||||
var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined);
|
||||
if (comment) {
|
||||
var referenceFile = tryResolveScriptReference(program, sourceFile, comment);
|
||||
if (referenceFile) {
|
||||
return [{
|
||||
fileName: referenceFile.filename,
|
||||
textSpan: createTextSpanFromBounds(0, 0),
|
||||
kind: ScriptElementKind.scriptElement,
|
||||
name: comment.filename,
|
||||
containerName: undefined,
|
||||
containerKind: undefined
|
||||
}];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var symbol = typeInfoResolver.getSymbolAtLocation(node);
|
||||
|
||||
// Could not find a symbol e.g. node is string or number keyword,
|
||||
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var result: DefinitionInfo[] = [];
|
||||
|
||||
// Because name in short-hand property assignment has two different meanings: property name and property value,
|
||||
// using go-to-definition at such position should go to the variable declaration of the property value rather than
|
||||
// go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
|
||||
// is performed at the location of property access, we would like to go to definition of the property in the short-hand
|
||||
// assignment. This case and others are handled by the following code.
|
||||
if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
var shorthandSymbol = typeInfoResolver.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
|
||||
var shorthandDeclarations = shorthandSymbol.getDeclarations();
|
||||
var shorthandSymbolKind = getSymbolKind(shorthandSymbol, typeInfoResolver);
|
||||
var shorthandSymbolName = typeInfoResolver.symbolToString(shorthandSymbol);
|
||||
var shorthandContainerName = typeInfoResolver.symbolToString(symbol.parent, node);
|
||||
forEach(shorthandDeclarations, declaration => {
|
||||
result.push(getDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
|
||||
});
|
||||
return result
|
||||
}
|
||||
|
||||
var declarations = symbol.getDeclarations();
|
||||
var symbolName = typeInfoResolver.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
|
||||
var symbolKind = getSymbolKind(symbol, typeInfoResolver);
|
||||
var containerSymbol = symbol.parent;
|
||||
var containerName = containerSymbol ? typeInfoResolver.symbolToString(containerSymbol, node) : "";
|
||||
|
||||
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
|
||||
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
|
||||
// Just add all the declarations.
|
||||
forEach(declarations, declaration => {
|
||||
result.push(getDefinitionInfo(declaration, symbolKind, symbolName, containerName));
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// References and Occurrences
|
||||
@ -5259,7 +5259,7 @@ module ts {
|
||||
|
||||
// Only allow a symbol to be renamed if it actually has at least one declaration.
|
||||
if (symbol && symbol.getDeclarations() && symbol.getDeclarations().length > 0) {
|
||||
var kind = getSymbolKind(symbol, typeInfoResolver);
|
||||
var kind = getSymbolKind(symbol, typeInfoResolver, node);
|
||||
if (kind) {
|
||||
return getRenameInfo(symbol.name, typeInfoResolver.getFullyQualifiedName(symbol), kind,
|
||||
getSymbolModifiers(symbol),
|
||||
|
||||
@ -217,6 +217,10 @@ module FourSlashInterface {
|
||||
FourSlash.currentTestState.verifyQuickInfoExists(this.negative);
|
||||
}
|
||||
|
||||
public definitionCountIs(expectedCount: number) {
|
||||
FourSlash.currentTestState.verifyDefinitionsCount(this.negative, expectedCount);
|
||||
}
|
||||
|
||||
public definitionLocationExists() {
|
||||
FourSlash.currentTestState.verifyDefinitionLocationExists(this.negative);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// @Filename: b.ts
|
||||
////import n = require('unknown/*1*/');
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*functionOverload1*/function /*functionOverload*/functionOverload();
|
||||
/////*functionOverload2*/function functionOverload(value: string);
|
||||
/////*functionOverloadDefinition*/function functionOverload() {}
|
||||
////
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/////*functionOverload1*/function /*functionOverload*/functionOverload();
|
||||
/////*functionOverload2*/function functionOverload(value: string);
|
||||
/////*functionOverloadDefinition*/function functionOverload() {}
|
||||
////
|
||||
/////*functionOverloadReference1*/functionOverload();
|
||||
/////*functionOverloadReference2*/functionOverload("123");
|
||||
|
||||
goTo.marker('functionOverloadReference1');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverloadReference2');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverload');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
goTo.marker('functionOverloadReference1');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverloadReference2');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverload');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class clsInOverload {
|
||||
//// static fnOverload();
|
||||
//// static /*staticFunctionOverload*/fnOverload(foo: string);
|
||||
//// /*staticFunctionOverloadDefinition*/static fnOverload(foo: any) { }
|
||||
//// public /*functionOverload*/fnOverload(): any;
|
||||
//// public fnOverload(foo: string);
|
||||
//// /*functionOverloadDefinition*/public fnOverload(foo: any) { return "foo" }
|
||||
////
|
||||
//// constructor() { }
|
||||
////}
|
||||
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////class clsInOverload {
|
||||
//// static fnOverload();
|
||||
//// static /*staticFunctionOverload*/fnOverload(foo: string);
|
||||
//// /*staticFunctionOverloadDefinition*/static fnOverload(foo: any) { }
|
||||
//// public /*functionOverload*/fnOverload(): any;
|
||||
//// public fnOverload(foo: string);
|
||||
//// /*functionOverloadDefinition*/public fnOverload(foo: any) { return "foo" }
|
||||
////
|
||||
//// constructor() { }
|
||||
////}
|
||||
|
||||
// this line triggers a semantic/syntactic error check, remove line when 788570 is fixed
|
||||
edit.insert('');
|
||||
|
||||
goTo.marker('staticFunctionOverload');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('staticFunctionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverload');
|
||||
goTo.definition();
|
||||
edit.insert('');
|
||||
|
||||
goTo.marker('staticFunctionOverload');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('staticFunctionOverloadDefinition');
|
||||
|
||||
goTo.marker('functionOverload');
|
||||
goTo.definition();
|
||||
verify.caretAtMarker('functionOverloadDefinition');
|
||||
@ -1,5 +1,5 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface One {
|
||||
//// /*propertyDefinition1*/commonProperty: number;
|
||||
//// commonFunction(): number;
|
||||
@ -13,12 +13,14 @@
|
||||
////var x : One | Two;
|
||||
////
|
||||
////x./*propertyReference*/commonProperty;
|
||||
////x./*3*/commonFunction;
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(0);
|
||||
verify.caretAtMarker("propertyDefinition1");
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(1);
|
||||
verify.caretAtMarker("propertyDefinition2");
|
||||
////x./*3*/commonFunction;
|
||||
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
verify.definitionCountIs(2);
|
||||
goTo.definition(0);
|
||||
verify.caretAtMarker("propertyDefinition1");
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(1);
|
||||
verify.caretAtMarker("propertyDefinition2");
|
||||
@ -1,9 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
////interface HasAOrB {
|
||||
//// /*propertyDefinition1*/a: string;
|
||||
//// b: string;
|
||||
////}
|
||||
////
|
||||
/// <reference path='fourslash.ts' />
|
||||
////interface HasAOrB {
|
||||
//// /*propertyDefinition1*/a: string;
|
||||
//// b: string;
|
||||
////}
|
||||
////
|
||||
////interface One {
|
||||
//// common: { /*propertyDefinition2*/a : number; };
|
||||
////}
|
||||
@ -15,11 +15,12 @@
|
||||
////var x : One | Two;
|
||||
////
|
||||
////x.common./*propertyReference*/a;
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(0);
|
||||
verify.caretAtMarker("propertyDefinition2");
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(1);
|
||||
verify.caretAtMarker("propertyDefinition1");
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
verify.definitionCountIs(2);
|
||||
goTo.definition(0);
|
||||
verify.caretAtMarker("propertyDefinition2");
|
||||
|
||||
goTo.marker("propertyReference");
|
||||
goTo.definition(1);
|
||||
verify.caretAtMarker("propertyDefinition1");
|
||||
|
||||
15
tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts
Normal file
15
tests/cases/fourslash/goToDefinitionUnionTypeProperty3.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface Array<T> {
|
||||
//// /*definition*/specialPop(): T
|
||||
////}
|
||||
////
|
||||
////var strings: string[];
|
||||
////var numbers: number[];
|
||||
////
|
||||
////var x = (strings || numbers)./*usage*/specialPop()
|
||||
|
||||
goTo.marker("usage");
|
||||
verify.definitionCountIs(1);
|
||||
goTo.definition();
|
||||
verify.caretAtMarker("definition");
|
||||
32
tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts
Normal file
32
tests/cases/fourslash/goToDefinitionUnionTypeProperty4.ts
Normal file
@ -0,0 +1,32 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////interface SnapCrackle {
|
||||
//// /*def1*/pop(): string;
|
||||
////}
|
||||
////
|
||||
////interface Magnitude {
|
||||
//// /*def2*/pop(): number;
|
||||
////}
|
||||
////
|
||||
////interface Art {
|
||||
//// /*def3*/pop(): boolean;
|
||||
////}
|
||||
////
|
||||
////var art: Art;
|
||||
////var magnitude: Magnitude;
|
||||
////var snapcrackle: SnapCrackle;
|
||||
////
|
||||
////var x = (snapcrackle || magnitude || art)./*usage*/pop;
|
||||
|
||||
goTo.marker("usage");
|
||||
verify.definitionCountIs(3);
|
||||
goTo.definition(0);
|
||||
verify.caretAtMarker("def1");
|
||||
|
||||
goTo.marker("usage");
|
||||
goTo.definition(1);
|
||||
verify.caretAtMarker("def2");
|
||||
|
||||
goTo.marker("usage");
|
||||
goTo.definition(2);
|
||||
verify.caretAtMarker("def3");
|
||||
Loading…
x
Reference in New Issue
Block a user