From a0bac154aa17ef9c2e3ce60e3be46977b01e32b8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:28:52 +0000 Subject: [PATCH 1/4] Initial plan From b66f18b04b46c6da60c62a880006970adcf82811 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:37:34 +0000 Subject: [PATCH 2/4] Add test showing current go-to-def behavior on shorthand property Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- ...horthandObjectLiteralWithInterface_test.go | 23 +++++++++++++++++++ ...dObjectLiteralWithInterface.baseline.jsonc | 9 ++++++++ 2 files changed, 32 insertions(+) create mode 100644 internal/fourslash/tests/goToDefinitionShorthandObjectLiteralWithInterface_test.go create mode 100644 testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc diff --git a/internal/fourslash/tests/goToDefinitionShorthandObjectLiteralWithInterface_test.go b/internal/fourslash/tests/goToDefinitionShorthandObjectLiteralWithInterface_test.go new file mode 100644 index 0000000000..6b7c02d319 --- /dev/null +++ b/internal/fourslash/tests/goToDefinitionShorthandObjectLiteralWithInterface_test.go @@ -0,0 +1,23 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGoToDefinitionShorthandObjectLiteralWithInterface(t *testing.T) { + t.Parallel() + + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `interface Something { + [|foo|]: string; +} + +function makeSomething([|foo|]: string): Something { + return { [|f/*1*/oo|] }; +}` + f := fourslash.NewFourslash(t, nil /*capabilities*/, content) + f.VerifyBaselineGoToDefinition(t, true, "1") +} diff --git a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc new file mode 100644 index 0000000000..ecc8e3eeb1 --- /dev/null +++ b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc @@ -0,0 +1,9 @@ +// === goToDefinition === +// === /goToDefinitionShorthandObjectLiteralWithInterface.ts === +// interface Something { +// foo: string; +// } +// +// function makeSomething([|foo|]: string): Something { +// return { f/*GOTO DEF*/oo }; +// } \ No newline at end of file From 3078d6e005acafaf78b80c2af21b59d06fea8e68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:46:04 +0000 Subject: [PATCH 3/4] Fix go-to-def to return both parameter and interface property for shorthand Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- internal/ls/definition.go | 30 ++++++++++++++++++- ...dObjectLiteralWithInterface.baseline.jsonc | 2 +- ...finitionShorthandProperty04.baseline.jsonc | 2 +- ...finitionShorthandProperty05.baseline.jsonc | 2 +- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/internal/ls/definition.go b/internal/ls/definition.go index 9f0d231fc7..8570e6f33a 100644 --- a/internal/ls/definition.go +++ b/internal/ls/definition.go @@ -167,7 +167,12 @@ func (l *LanguageService) createLocationFromFileAndRange(file *ast.SourceFile, t func getDeclarationsFromLocation(c *checker.Checker, node *ast.Node) []*ast.Node { if ast.IsIdentifier(node) && ast.IsShorthandPropertyAssignment(node.Parent) { - return c.GetResolvedSymbol(node).Declarations + // For shorthand property assignments, return both the value symbol's declarations + // and the contextual type's property declarations + shorthandSymbol := c.GetResolvedSymbol(node) + declarations := shorthandSymbol.Declarations + contextualDeclarations := getDeclarationsFromObjectLiteralElement(c, node) + return core.Concatenate(declarations, contextualDeclarations) } node = getDeclarationNameForKeyword(node) if symbol := c.GetSymbolAtLocation(node); symbol != nil { @@ -196,6 +201,29 @@ func getDeclarationsFromLocation(c *checker.Checker, node *ast.Node) []*ast.Node return nil } +// getDeclarationsFromObjectLiteralElement returns declarations from the contextual type +// of an object literal element, if available. +func getDeclarationsFromObjectLiteralElement(c *checker.Checker, node *ast.Node) []*ast.Node { + element := getContainingObjectLiteralElement(node) + if element == nil { + return nil + } + + // Get the contextual type of the object literal + objectLiteral := element.Parent + if objectLiteral == nil || !ast.IsObjectLiteralExpression(objectLiteral) { + return nil + } + + // Get the name of the property + name := ast.GetTextOfPropertyName(element.Name()) + if name == "" { + return nil + } + + return c.GetContextualDeclarationsForObjectLiteralElement(objectLiteral, name) +} + // Returns a CallLikeExpression where `node` is the target being invoked. func getAncestorCallLikeExpression(node *ast.Node) *ast.Node { target := ast.FindAncestor(node, func(n *ast.Node) bool { diff --git a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc index ecc8e3eeb1..4789a67848 100644 --- a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandObjectLiteralWithInterface.baseline.jsonc @@ -1,7 +1,7 @@ // === goToDefinition === // === /goToDefinitionShorthandObjectLiteralWithInterface.ts === // interface Something { -// foo: string; +// [|foo|]: string; // } // // function makeSomething([|foo|]: string): Something { diff --git a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty04.baseline.jsonc b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty04.baseline.jsonc index 6e7f8d7b70..578a54e263 100644 --- a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty04.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty04.baseline.jsonc @@ -1,7 +1,7 @@ // === goToDefinition === // === /goToDefinitionShorthandProperty04.ts === // interface Foo { -// foo(): void +// [|foo|](): void // } // // let x: Foo = { diff --git a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty05.baseline.jsonc b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty05.baseline.jsonc index 414558d93d..87f5d5917c 100644 --- a/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty05.baseline.jsonc +++ b/testdata/baselines/reference/fourslash/goToDefinition/goToDefinitionShorthandProperty05.baseline.jsonc @@ -1,7 +1,7 @@ // === goToDefinition === // === /goToDefinitionShorthandProperty05.ts === // interface Foo { -// foo(): void +// [|foo|](): void // } // const [|foo|] = 1; // let x: Foo = { From ce55d64117b202054c75967292ccee0a6706a98d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:51:21 +0000 Subject: [PATCH 4/4] Add nil check for GetResolvedSymbol in shorthand property handling Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com> --- internal/ls/definition.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/ls/definition.go b/internal/ls/definition.go index 8570e6f33a..56e555c7cd 100644 --- a/internal/ls/definition.go +++ b/internal/ls/definition.go @@ -170,7 +170,10 @@ func getDeclarationsFromLocation(c *checker.Checker, node *ast.Node) []*ast.Node // For shorthand property assignments, return both the value symbol's declarations // and the contextual type's property declarations shorthandSymbol := c.GetResolvedSymbol(node) - declarations := shorthandSymbol.Declarations + var declarations []*ast.Node + if shorthandSymbol != nil { + declarations = shorthandSymbol.Declarations + } contextualDeclarations := getDeclarationsFromObjectLiteralElement(c, node) return core.Concatenate(declarations, contextualDeclarations) }