internal/lsp: fix godef for embedded type aliases

In

    type myAlias = someType
    type _ struct {
      myAlias
    }

Previously running "definition" on the "myAlias" field would take you
to the definition of "someType" instead of "myAlias". This is because
we were using the field's (*types.Var).Type() which has already
forgotten it is an alias. Fix by instead looking up the field name
ident in types.Info.Uses which yields the *types.TypeName (for the
type alias).

Fixes golang/go#42254.

Change-Id: Idbbd0c49ba6f701f52568b3ab1143d8e24037c69
Reviewed-on: https://go-review.googlesource.com/c/tools/+/272186
Run-TryBot: Muir Manders <muir@mnd.rs>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Muir Manders <muir@mnd.rs>
Trust: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
diff --git a/internal/lsp/source/identifier.go b/internal/lsp/source/identifier.go
index 753d12b..362604e 100644
--- a/internal/lsp/source/identifier.go
+++ b/internal/lsp/source/identifier.go
@@ -157,14 +157,6 @@
 		enclosing: searchForEnclosing(pkg.GetTypesInfo(), path),
 	}
 
-	var wasEmbeddedField bool
-	for _, n := range path[1:] {
-		if field, ok := n.(*ast.Field); ok {
-			wasEmbeddedField = len(field.Names) == 0
-			break
-		}
-	}
-
 	result.Name = result.ident.Name
 	var err error
 	if result.MappedRange, err = posToMappedRange(snapshot, pkg, result.ident.Pos(), result.ident.End()); err != nil {
@@ -253,13 +245,12 @@
 		}
 	}
 
-	if wasEmbeddedField {
-		// The original position was on the embedded field declaration, so we
-		// try to dig out the type and jump to that instead.
-		if v, ok := result.Declaration.obj.(*types.Var); ok {
-			if typObj := typeToObject(v.Type()); typObj != nil {
-				result.Declaration.obj = typObj
-			}
+	// If the original position was an embedded field, we want to jump
+	// to the field's type definition, not the field's definition.
+	if v, ok := result.Declaration.obj.(*types.Var); ok && v.Embedded() {
+		// types.Info.Uses contains the embedded field's *types.TypeName.
+		if typeName := pkg.GetTypesInfo().Uses[ident]; typeName != nil {
+			result.Declaration.obj = typeName
 		}
 	}
 
diff --git a/internal/lsp/testdata/godef/a/a.go.golden b/internal/lsp/testdata/godef/a/a.go.golden
index 139a177..08a1882 100644
--- a/internal/lsp/testdata/godef/a/a.go.golden
+++ b/internal/lsp/testdata/godef/a/a.go.golden
@@ -74,10 +74,6 @@
 ```
 
 [`a.Random2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#Random2)
--- a-hover --
-```go
-
-```
 -- aPackage-hover --
 Package a is a package for testing go to definition\.
 -- err-definition --
diff --git a/internal/lsp/testdata/godef/b/b.go b/internal/lsp/testdata/godef/b/b.go
index a510a45..23d908f 100644
--- a/internal/lsp/testdata/godef/b/b.go
+++ b/internal/lsp/testdata/godef/b/b.go
@@ -22,10 +22,13 @@
 	e.Goodbye() //@hover("Goodbye", AGoodbye)
 }
 
+type aAlias = a.A //@mark(aAlias, "aAlias")
+
 type S1 struct { //@S1
-	F1  int //@mark(S1F1, "F1")
-	S2      //@godef("S2", S2),mark(S1S2, "S2")
-	a.A     //@godef("A", AString)
+	F1     int //@mark(S1F1, "F1")
+	S2         //@godef("S2", S2),mark(S1S2, "S2")
+	a.A        //@godef("A", AString)
+	aAlias     //@godef("a", aAlias)
 }
 
 type S2 struct { //@S2
diff --git a/internal/lsp/testdata/godef/b/b.go.golden b/internal/lsp/testdata/godef/b/b.go.golden
index ad8a98b..19ece5d 100644
--- a/internal/lsp/testdata/godef/b/b.go.golden
+++ b/internal/lsp/testdata/godef/b/b.go.golden
@@ -143,11 +143,12 @@
 
 [`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#AStuff)
 -- S1-definition --
-godef/b/b.go:25:6-8: defined here as ```go
+godef/b/b.go:27:6-8: defined here as ```go
 type S1 struct {
-	F1  int //@mark(S1F1, "F1")
-	S2      //@godef("S2", S2),mark(S1S2, "S2")
-	a.A     //@godef("A", AString)
+	F1     int //@mark(S1F1, "F1")
+	S2         //@godef("S2", S2),mark(S1S2, "S2")
+	a.A        //@godef("A", AString)
+	aAlias     //@godef("a", aAlias)
 }
 ```
 
@@ -157,31 +158,32 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 25,
+			"line": 27,
 			"column": 6,
-			"offset": 521
+			"offset": 566
 		},
 		"end": {
-			"line": 25,
+			"line": 27,
 			"column": 8,
-			"offset": 523
+			"offset": 568
 		}
 	},
-	"description": "```go\ntype S1 struct {\n\tF1  int //@mark(S1F1, \"F1\")\n\tS2      //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A     //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
+	"description": "```go\ntype S1 struct {\n\tF1     int //@mark(S1F1, \"F1\")\n\tS2         //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A        //@godef(\"A\", AString)\n\taAlias     //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
 }
 
 -- S1-hover --
 ```go
 type S1 struct {
-	F1  int //@mark(S1F1, "F1")
-	S2      //@godef("S2", S2),mark(S1S2, "S2")
-	a.A     //@godef("A", AString)
+	F1     int //@mark(S1F1, "F1")
+	S2         //@godef("S2", S2),mark(S1S2, "S2")
+	a.A        //@godef("A", AString)
+	aAlias     //@godef("a", aAlias)
 }
 ```
 
 [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)
 -- S1F1-definition --
-godef/b/b.go:26:2-4: defined here as ```go
+godef/b/b.go:28:2-4: defined here as ```go
 field F1 int
 ```
 
@@ -193,14 +195,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 26,
+			"line": 28,
 			"column": 2,
-			"offset": 540
+			"offset": 585
 		},
 		"end": {
-			"line": 26,
+			"line": 28,
 			"column": 4,
-			"offset": 542
+			"offset": 587
 		}
 	},
 	"description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)"
@@ -215,7 +217,7 @@
 
 \@mark\(S1F1, \"F1\"\)
 -- S1S2-definition --
-godef/b/b.go:27:2-4: defined here as ```go
+godef/b/b.go:29:2-4: defined here as ```go
 field S2 S2
 ```
 
@@ -227,14 +229,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 27,
+			"line": 29,
 			"column": 2,
-			"offset": 569
+			"offset": 617
 		},
 		"end": {
-			"line": 27,
+			"line": 29,
 			"column": 4,
-			"offset": 571
+			"offset": 619
 		}
 	},
 	"description": "```go\nfield S2 S2\n```\n\n[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.S2)\n\n\\@godef\\(\\\"S2\\\", S2\\),mark\\(S1S2, \\\"S2\\\"\\)"
@@ -249,7 +251,7 @@
 
 \@godef\(\"S2\", S2\),mark\(S1S2, \"S2\"\)
 -- S2-definition --
-godef/b/b.go:31:6-8: defined here as ```go
+godef/b/b.go:34:6-8: defined here as ```go
 type S2 struct {
 	F1   string //@mark(S2F1, "F1")
 	F2   int    //@mark(S2F2, "F2")
@@ -263,14 +265,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 31,
+			"line": 34,
 			"column": 6,
-			"offset": 653
+			"offset": 741
 		},
 		"end": {
-			"line": 31,
+			"line": 34,
 			"column": 8,
-			"offset": 655
+			"offset": 743
 		}
 	},
 	"description": "```go\ntype S2 struct {\n\tF1   string //@mark(S2F1, \"F1\")\n\tF2   int    //@mark(S2F2, \"F2\")\n\t*a.A        //@godef(\"A\", AString),godef(\"a\",AImport)\n}\n```\n\n[`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2)"
@@ -287,7 +289,7 @@
 
 [`b.S2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2)
 -- S2F1-definition --
-godef/b/b.go:32:2-4: defined here as ```go
+godef/b/b.go:35:2-4: defined here as ```go
 field F1 string
 ```
 
@@ -299,14 +301,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 32,
+			"line": 35,
 			"column": 2,
-			"offset": 672
+			"offset": 760
 		},
 		"end": {
-			"line": 32,
+			"line": 35,
 			"column": 4,
-			"offset": 674
+			"offset": 762
 		}
 	},
 	"description": "```go\nfield F1 string\n```\n\n[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F1)\n\n\\@mark\\(S2F1, \\\"F1\\\"\\)"
@@ -321,7 +323,7 @@
 
 \@mark\(S2F1, \"F1\"\)
 -- S2F2-definition --
-godef/b/b.go:33:2-4: defined here as ```go
+godef/b/b.go:36:2-4: defined here as ```go
 field F2 int
 ```
 
@@ -333,14 +335,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 33,
+			"line": 36,
 			"column": 2,
-			"offset": 705
+			"offset": 793
 		},
 		"end": {
-			"line": 33,
+			"line": 36,
 			"column": 4,
-			"offset": 707
+			"offset": 795
 		}
 	},
 	"description": "```go\nfield F2 int\n```\n\n[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F2)\n\n\\@mark\\(S2F2, \\\"F2\\\"\\)"
@@ -354,8 +356,36 @@
 [`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S2.F2)
 
 \@mark\(S2F2, \"F2\"\)
+-- aAlias-definition --
+godef/b/b.go:25:6-12: defined here as ```go
+type aAlias = a.A //@mark(aAlias, "aAlias")
+
+```
+-- aAlias-definition-json --
+{
+	"span": {
+		"uri": "file://godef/b/b.go",
+		"start": {
+			"line": 25,
+			"column": 6,
+			"offset": 521
+		},
+		"end": {
+			"line": 25,
+			"column": 12,
+			"offset": 527
+		}
+	},
+	"description": "```go\ntype aAlias = a.A //@mark(aAlias, \"aAlias\")\n\n```"
+}
+
+-- aAlias-hover --
+```go
+type aAlias = a.A //@mark(aAlias, "aAlias")
+
+```
 -- bX-definition --
-godef/b/b.go:54:7-8: defined here as ```go
+godef/b/b.go:57:7-8: defined here as ```go
 const X untyped int = 0
 ```
 
@@ -367,14 +397,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 54,
+			"line": 57,
 			"column": 7,
-			"offset": 1140
+			"offset": 1228
 		},
 		"end": {
-			"line": 54,
+			"line": 57,
 			"column": 8,
-			"offset": 1141
+			"offset": 1229
 		}
 	},
 	"description": "```go\nconst X untyped int = 0\n```\n\n[`b.X` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#X)\n\n\\@mark\\(bX, \\\"X\\\"\\),godef\\(\\\"X\\\", bX\\)"
diff --git a/internal/lsp/testdata/godef/b/c.go.golden b/internal/lsp/testdata/godef/b/c.go.golden
index 7852da7..9554c0d 100644
--- a/internal/lsp/testdata/godef/b/c.go.golden
+++ b/internal/lsp/testdata/godef/b/c.go.golden
@@ -1,9 +1,10 @@
 -- S1-definition --
-godef/b/b.go:25:6-8: defined here as ```go
+godef/b/b.go:27:6-8: defined here as ```go
 type S1 struct {
-	F1  int //@mark(S1F1, "F1")
-	S2      //@godef("S2", S2),mark(S1S2, "S2")
-	a.A     //@godef("A", AString)
+	F1     int //@mark(S1F1, "F1")
+	S2         //@godef("S2", S2),mark(S1S2, "S2")
+	a.A        //@godef("A", AString)
+	aAlias     //@godef("a", aAlias)
 }
 ```
 
@@ -13,31 +14,32 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 25,
+			"line": 27,
 			"column": 6,
-			"offset": 521
+			"offset": 566
 		},
 		"end": {
-			"line": 25,
+			"line": 27,
 			"column": 8,
-			"offset": 523
+			"offset": 568
 		}
 	},
-	"description": "```go\ntype S1 struct {\n\tF1  int //@mark(S1F1, \"F1\")\n\tS2      //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A     //@godef(\"A\", AString)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
+	"description": "```go\ntype S1 struct {\n\tF1     int //@mark(S1F1, \"F1\")\n\tS2         //@godef(\"S2\", S2),mark(S1S2, \"S2\")\n\ta.A        //@godef(\"A\", AString)\n\taAlias     //@godef(\"a\", aAlias)\n}\n```\n\n[`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)"
 }
 
 -- S1-hover --
 ```go
 type S1 struct {
-	F1  int //@mark(S1F1, "F1")
-	S2      //@godef("S2", S2),mark(S1S2, "S2")
-	a.A     //@godef("A", AString)
+	F1     int //@mark(S1F1, "F1")
+	S2         //@godef("S2", S2),mark(S1S2, "S2")
+	a.A        //@godef("A", AString)
+	aAlias     //@godef("a", aAlias)
 }
 ```
 
 [`b.S1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1)
 -- S1F1-definition --
-godef/b/b.go:26:2-4: defined here as ```go
+godef/b/b.go:28:2-4: defined here as ```go
 field F1 int
 ```
 
@@ -49,14 +51,14 @@
 	"span": {
 		"uri": "file://godef/b/b.go",
 		"start": {
-			"line": 26,
+			"line": 28,
 			"column": 2,
-			"offset": 540
+			"offset": 585
 		},
 		"end": {
-			"line": 26,
+			"line": 28,
 			"column": 4,
-			"offset": 542
+			"offset": 587
 		}
 	},
 	"description": "```go\nfield F1 int\n```\n\n[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/b?utm_source=gopls#S1.F1)\n\n\\@mark\\(S1F1, \\\"F1\\\"\\)"
diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden
index f10805c..a8a3799 100644
--- a/internal/lsp/testdata/summary.txt.golden
+++ b/internal/lsp/testdata/summary.txt.golden
@@ -15,7 +15,7 @@
 SemanticTokenCount = 2
 SuggestedFixCount = 38
 FunctionExtractionCount = 12
-DefinitionsCount = 63
+DefinitionsCount = 64
 TypeDefinitionsCount = 2
 HighlightsCount = 69
 ReferencesCount = 25