diff --git a/src/services/services.ts b/src/services/services.ts index 540a4b0b6c3..12f4c49dd56 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3351,6 +3351,23 @@ module ts { 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); diff --git a/tests/cases/fourslash/goToDefinitionShorthandProperty.ts b/tests/cases/fourslash/goToDefinitionShorthandProperty.ts new file mode 100644 index 00000000000..07ea82c03e1 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionShorthandProperty.ts @@ -0,0 +1,25 @@ +/// + +//// var /*valueDeclaration1*/name = "hello"; +//// var /*valueDeclaration2*/id = 100000; +//// declare var /*valueDeclaration3*/id; +//// var obj = {/*valueDefinition1*/name, /*valueDefinition2*/id}; +//// obj./*valueReference1*/name; +//// obj./*valueReference2*/id; + +goTo.marker("valueDefinition1"); +goTo.definition(); +verify.caretAtMarker("valueDeclaration1"); + +goTo.marker("valueDefinition2"); +goTo.definition(0); +verify.caretAtMarker("valueDeclaration2"); +goTo.definition(1); +verify.caretAtMarker("valueDeclaration3"); + +goTo.marker("valueReference1"); +goTo.definition(); +verify.caretAtMarker("valueDefinition1"); +goTo.marker("valueReference2"); +goTo.definition(); +verify.caretAtMarker("valueDefinition2");