mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Merge pull request #1528 from Microsoft/goToDefOnUnionMethod
Fix crash on go-to-def on union method
This commit is contained in:
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2598,7 +2598,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;
|
||||
@@ -3097,6 +3097,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,
|
||||
@@ -3152,83 +3229,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
|
||||
@@ -5273,7 +5273,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),
|
||||
|
||||
Reference in New Issue
Block a user