Skip to content

Commit f47a913

Browse files
committed
gopls: Refactor goasm.References function.
Modify the file index logic for asmfile in xrefs.go. Adjust the overall code logic flow in references. When parsing asm files, add the original symbol name length, return the original position, and update the test files. Updates golang/go#71754
1 parent 8503359 commit f47a913

File tree

5 files changed

+49
-46
lines changed

5 files changed

+49
-46
lines changed

gopls/internal/cache/xrefs/xrefs.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ package xrefs
1111
import (
1212
"go/ast"
1313
"go/types"
14-
"slices"
1514
"sort"
1615

1716
"golang.org/x/tools/go/types/objectpath"
@@ -118,6 +117,9 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info, asmFiles
118117
// For each asm file, record references to identifiers.
119118
for fileIndex, af := range asmFiles {
120119
for _, id := range af.Idents {
120+
if id.Kind != asm.Data && id.Kind != asm.Text {
121+
continue
122+
}
121123
_, name, ok := morestrings.CutLast(id.Name, ".")
122124
if !ok {
123125
continue
@@ -131,6 +133,7 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info, asmFiles
131133
objects := getObjects(pkg)
132134
gobObj, ok := objects[obj]
133135
if !ok {
136+
// obj is a package-level symbol, so its objectpath is just its name.
134137
gobObj = &gobObject{Path: objectpath.Path(obj.Name())}
135138
objects[obj] = gobObj
136139
}
@@ -171,14 +174,25 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info, asmFiles
171174
// to any object in the target set. Each object is denoted by a pair
172175
// of (package path, object path).
173176
func Lookup(mp *metadata.Package, data []byte, targets map[metadata.PackagePath]map[objectpath.Path]struct{}) (locs []protocol.Location) {
174-
var packages []*gobPackage
177+
var (
178+
packages []*gobPackage
179+
goFilesLen = len(mp.CompiledGoFiles)
180+
goAsmFilesLen = len(mp.AsmFiles)
181+
)
175182
packageCodec.Decode(data, &packages)
176183
for _, gp := range packages {
177184
if objectSet, ok := targets[gp.PkgPath]; ok {
178185
for _, gobObj := range gp.Objects {
179186
if _, ok := objectSet[gobObj.Path]; ok {
180187
for _, ref := range gobObj.Refs {
181-
uri := slices.Concat(mp.CompiledGoFiles, mp.AsmFiles)[ref.FileIndex]
188+
var uri protocol.DocumentURI
189+
if ref.FileIndex < goFilesLen {
190+
uri = mp.CompiledGoFiles[ref.FileIndex]
191+
} else if ref.FileIndex < goFilesLen+goAsmFilesLen {
192+
uri = mp.AsmFiles[ref.FileIndex]
193+
} else {
194+
continue // out of bounds
195+
}
182196
locs = append(locs, protocol.Location{
183197
URI: uri,
184198
Range: ref.Range,

gopls/internal/goasm/references.go

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,8 @@ func References(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, p
6464
return nil, fmt.Errorf("not an identifier")
6565
}
6666

67-
sym := found.Name
6867
var locations []protocol.Location
69-
_, name, ok := morestrings.CutLast(sym, ".")
68+
_, name, ok := morestrings.CutLast(found.Name, ".")
7069
if !ok {
7170
return nil, fmt.Errorf("not found")
7271
}
@@ -76,25 +75,12 @@ func References(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, p
7675
// Refer to the global search logic in golang.References, and add corresponding test cases for verification.
7776
obj := pkg.Types().Scope().Lookup(name)
7877
matches := func(curObj types.Object) bool {
79-
if curObj == nil {
80-
return false
81-
}
82-
if curObj.Name() != obj.Name() {
83-
return false
84-
}
85-
return true
78+
return curObj != nil && curObj.Name() == obj.Name()
8679
}
8780
for _, pgf := range pkg.CompiledGoFiles() {
8881
for curId := range pgf.Cursor.Preorder((*ast.Ident)(nil)) {
8982
id := curId.Node().(*ast.Ident)
90-
curObj, ok := pkg.TypesInfo().Defs[id]
91-
if !ok {
92-
curObj, ok = pkg.TypesInfo().Uses[id]
93-
if !ok {
94-
continue
95-
}
96-
}
97-
if !matches(curObj) {
83+
if !matches(pkg.TypesInfo().ObjectOf(id)) {
9884
continue
9985
}
10086
loc, err := pgf.NodeLocation(id)
@@ -105,21 +91,17 @@ func References(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, p
10591
}
10692
}
10793

108-
// If includeDeclaration is false, return only reference locations (exclude declarations).
109-
if !includeDeclaration {
110-
return locations, nil
111-
}
112-
113-
for _, asmFile := range pkg.AsmFiles() {
114-
for _, id := range asmFile.Idents {
115-
if id.Name != sym {
116-
continue
117-
}
118-
if loc, err := asmFile.NodeLocation(id); err == nil {
119-
locations = append(locations, loc)
94+
if includeDeclaration {
95+
for _, asmFile := range pkg.AsmFiles() {
96+
for _, id := range asmFile.Idents {
97+
if id.Name == found.Name &&
98+
(id.Kind == asm.Text || id.Kind == asm.Global || id.Kind == asm.Label) {
99+
if loc, err := asmFile.NodeLocation(id); err == nil {
100+
locations = append(locations, loc)
101+
}
102+
}
120103
}
121104
}
122105
}
123-
124106
return locations, nil
125107
}

gopls/internal/golang/references.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"golang.org/x/tools/gopls/internal/cache/parsego"
3333
"golang.org/x/tools/gopls/internal/file"
3434
"golang.org/x/tools/gopls/internal/protocol"
35+
"golang.org/x/tools/gopls/internal/util/asm"
3536
"golang.org/x/tools/gopls/internal/util/morestrings"
3637
"golang.org/x/tools/gopls/internal/util/safetoken"
3738
"golang.org/x/tools/internal/event"
@@ -615,6 +616,9 @@ func localReferences(pkg *cache.Package, targets map[types.Object]bool, correspo
615616
// Iterate over all assembly files and find all references to the target object.
616617
for _, pgf := range pkg.AsmFiles() {
617618
for _, id := range pgf.Idents {
619+
if id.Kind != asm.Data && id.Kind != asm.Text {
620+
continue
621+
}
618622
_, name, ok := morestrings.CutLast(id.Name, ".")
619623
if !ok {
620624
continue

gopls/internal/test/marker/testdata/references/asm.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ var _ = sub //@loc(refSub, "sub"), refs("sub", useSub, defSub, refSub)
2525
// portable assembly
2626
#include "textflag.h"
2727

28-
TEXT ·Add(SB), NOSPLIT, $0-24 //@ loc(def, "Add"), refs("Add", def, use)
28+
TEXT ·Add(SB), NOSPLIT, $0-24 //@ loc(def, "·Add"), refs("Add", def, use)
2929
MOVQ a+0(FP), AX
3030
ADDQ b+8(FP), AX
3131
RET
3232

33-
TEXT ·sub(SB), NOSPLIT, $0-24 //@ loc(defSub, "sub"), refs("sub", defSub, useSub, refSub)
33+
TEXT ·sub(SB), NOSPLIT, $0-24 //@ loc(defSub, "·sub"), refs("sub", defSub, useSub, refSub)
3434
MOVQ a+0(FP), AX
3535
SUBQ b+8(FP), AX
3636
RET

gopls/internal/util/asm/parse.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,20 @@ type File struct {
5555
}
5656

5757
func (f *File) NodeRange(ident Ident) (protocol.Range, error) {
58-
return f.Mapper.OffsetRange(ident.Offset+2, ident.End()+1)
58+
return f.Mapper.OffsetRange(ident.Offset, ident.Offset+ident.OrigLen)
5959
}
6060

6161
// NodeLocation returns a protocol Location for the ast.Node interval in this file.
6262
func (f *File) NodeLocation(ident Ident) (protocol.Location, error) {
63-
return f.Mapper.OffsetLocation(ident.Offset+2, ident.End()+1)
63+
return f.Mapper.OffsetLocation(ident.Offset, ident.Offset+ident.OrigLen)
6464
}
6565

6666
// Ident represents an identifier in an assembly file.
6767
type Ident struct {
68-
Name string // symbol name (after correcting [·∕]); Name[0]='.' => current package
69-
Offset int // zero-based byte offset
70-
Kind Kind
68+
Name string // symbol name (after correcting [·∕]); Name[0]='.' => current package
69+
Offset int // zero-based byte offset
70+
OrigLen int // original length of the symbol name (before cleanup)
71+
Kind Kind
7172
}
7273

7374
// End returns the identifier's end offset.
@@ -136,9 +137,10 @@ func Parse(uri protocol.DocumentURI, content []byte) *File {
136137
if isIdent(sym) {
137138
// (The Index call assumes sym is not itself "TEXT" etc.)
138139
idents = append(idents, Ident{
139-
Name: cleanup(sym),
140-
Kind: kind,
141-
Offset: offset + strings.Index(line, sym),
140+
Name: cleanup(sym),
141+
Kind: kind,
142+
Offset: offset + strings.Index(line, sym),
143+
OrigLen: len(sym),
142144
})
143145
}
144146
continue
@@ -196,9 +198,10 @@ func Parse(uri protocol.DocumentURI, content []byte) *File {
196198
sym = cutBefore(sym, "<") // "sym<ABIInternal>" =>> "sym"
197199
if isIdent(sym) {
198200
idents = append(idents, Ident{
199-
Name: cleanup(sym),
200-
Kind: Ref,
201-
Offset: offset + tokenPos,
201+
Name: cleanup(sym),
202+
Kind: Ref,
203+
Offset: offset + tokenPos,
204+
OrigLen: len(sym),
202205
})
203206
}
204207
}

0 commit comments

Comments
 (0)