diff --git a/flake.nix b/flake.nix index 6bf2e9be..1be911ee 100644 --- a/flake.nix +++ b/flake.nix @@ -26,7 +26,7 @@ pname = "scip-go"; inherit version; src = ./.; - vendorHash = "sha256-V+A5nMSnAAk+FBoMX1frf5eZUETvLb2BCE81WuEx33c="; + vendorHash = "sha256-AdEvJ4KxxzNaaBiewwv2IRpasQotF4P08aDEF1ownW0="; subPackages = [ "cmd/scip-go" ]; env.CGO_ENABLED = 0; checkPhase = "go test ./..."; diff --git a/go.mod b/go.mod index 8e37f90e..367c7e4d 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.25.0 require ( github.com/alecthomas/kong v1.15.0 - github.com/scip-code/scip/bindings/go/scip v0.8.1 + github.com/scip-code/scip/bindings/go/scip v0.9.0 golang.org/x/mod v0.37.0 golang.org/x/tools v0.47.0 golang.org/x/tools/go/vcs v0.1.0-deprecated diff --git a/go.sum b/go.sum index 5b7e5096..ce72976e 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ github.com/scip-code/scip/bindings/go/scip v0.8.0 h1:WdmhYzDbzgCe8D1PhS61VtFsa+/ github.com/scip-code/scip/bindings/go/scip v0.8.0/go.mod h1:QhuSgP19HyWJIU/bvfBGn/RmkL/BX2IPoZWTNQ9M5wY= github.com/scip-code/scip/bindings/go/scip v0.8.1 h1:ZkyT9RDgkbd6ffvMbi9nYdwh7+gLoz8Z9ftFMxgUiVs= github.com/scip-code/scip/bindings/go/scip v0.8.1/go.mod h1:QhuSgP19HyWJIU/bvfBGn/RmkL/BX2IPoZWTNQ9M5wY= +github.com/scip-code/scip/bindings/go/scip v0.9.0 h1:C0LVhTl9Gw+2UC4d7RZdvB0iWUkaOyRA1fQW1CrhsMA= +github.com/scip-code/scip/bindings/go/scip v0.9.0/go.mod h1:QhuSgP19HyWJIU/bvfBGn/RmkL/BX2IPoZWTNQ9M5wY= github.com/sourcegraph/beaut v0.0.0-20240611013027-627e4c25335a h1:j/CQ27s679M9wRGBRJYyXGrfkYuQA6VMnD7R08mHD9c= github.com/sourcegraph/beaut v0.0.0-20240611013027-627e4c25335a/go.mod h1:JG1sdvGTKWwe/oH3/3UKQ26vfcHIN//7fwEJhoqaBcM= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= diff --git a/internal/index/scip.go b/internal/index/scip.go index b3061bac..b42e9edd 100644 --- a/internal/index/scip.go +++ b/internal/index/scip.go @@ -236,7 +236,7 @@ func indexVisitPackages( position := pkg.Fset.Position(f.Name.NamePos) doc.PackageOccurrence = &scip.Occurrence{ - Range: symbols.RangeFromName(position, f.Name.Name, false), + TypedRange: symbols.RangeFromName(position, f.Name.Name, false).AsTypedRange(), Symbol: pkgSymbol, SymbolRoles: int32(scip.SymbolRole_Definition), } diff --git a/internal/index/scip_test.go b/internal/index/scip_test.go index aebb7c12..db096f39 100644 --- a/internal/index/scip_test.go +++ b/internal/index/scip_test.go @@ -82,6 +82,7 @@ func TestSnapshots(t *testing.T) { filteredDocs = append(filteredDocs, doc) } scipIndex.Documents = filteredDocs + assertTypedOccurrenceRanges(t, &scipIndex) symbolFormatter := scip.SymbolFormatter{ OnError: func(err error) error { return err }, @@ -105,6 +106,29 @@ func TestSnapshots(t *testing.T) { ) } +func assertTypedOccurrenceRanges(t *testing.T, scipIndex *scip.Index) { + t.Helper() + for _, doc := range scipIndex.Documents { + for i, occ := range doc.Occurrences { + if occ == nil { + t.Fatalf("%s: nil occurrence at index %d", doc.RelativePath, i) + } + if occ.GetTypedRange() == nil { + t.Fatalf("%s: occurrence %q has no typed range", doc.RelativePath, occ.GetSymbol()) + } + if _, ok := occ.SourceRange(); !ok { + t.Fatalf("%s: occurrence %q has malformed typed range", doc.RelativePath, occ.GetSymbol()) + } + if len(occ.GetRange()) != 0 { + t.Fatalf("%s: occurrence %q set deprecated range: %v", doc.RelativePath, occ.GetSymbol(), occ.GetRange()) + } + if len(occ.GetEnclosingRange()) != 0 { + t.Fatalf("%s: occurrence %q set deprecated enclosing_range: %v", doc.RelativePath, occ.GetSymbol(), occ.GetEnclosingRange()) + } + } + } +} + // getTestdataRoot returns the absolute path to the testdata directory of this repository. func getTestdataRoot(t *testing.T) string { testdata, err := filepath.Abs("../testdata") diff --git a/internal/symbols/symbols.go b/internal/symbols/symbols.go index 23df9ec6..fd7a80ec 100644 --- a/internal/symbols/symbols.go +++ b/internal/symbols/symbols.go @@ -24,7 +24,7 @@ func FromDescriptors(pkg *packages.Package, descriptors ...*scip.Descriptor) str }) } -func RangeFromName(position token.Position, name string, adjust bool) []int32 { +func RangeFromName(position token.Position, name string, adjust bool) scip.Range { var adjustment int32 = 0 if adjust { adjustment = 1 @@ -34,7 +34,10 @@ func RangeFromName(position token.Position, name string, adjust bool) []int32 { column := int32(position.Column - 1) n := int32(len(name)) - return []int32{line, column + adjustment, column + n + adjustment} + return scip.Range{ + Start: scip.Position{Line: line, Character: column + adjustment}, + End: scip.Position{Line: line, Character: column + n + adjustment}, + } } func FormatCode(v string) string { diff --git a/internal/visitors/visitor_file.go b/internal/visitors/visitor_file.go index 625150ff..9e5fb637 100644 --- a/internal/visitors/visitor_file.go +++ b/internal/visitors/visitor_file.go @@ -116,12 +116,9 @@ func (v *fileVisitor) Visit(n ast.Node) ast.Visitor { } if node.Name != nil && node.Name.Name != "." && node.Name.Name != "_" { - rangeFromName := symbols.RangeFromName( - v.pkg.Fset.Position(node.Name.Pos()), node.Name.Name, false) - if rangeFromName != nil { - if sym, ok := v.globalSymbols.GetPkgSymbol(importedPackage); ok { - v.newReference(sym, rangeFromName, false) - } + if sym, ok := v.globalSymbols.GetPkgSymbol(importedPackage); ok { + v.newReference(sym, symbols.RangeFromName( + v.pkg.Fset.Position(node.Name.Pos()), node.Name.Name, false), false) } } @@ -279,31 +276,27 @@ func (v *fileVisitor) emitImportReference( position token.Position, importedPackage *packages.Package, ) { - scipRange := symbols.RangeFromName(position, importedPackage.PkgPath, true) - if scipRange == nil { - slog.Debug(fmt.Sprintf("Missing symbol for package path: %s", importedPackage.ID)) - return - } - sym, ok := globalSymbols.GetPkgSymbol(importedPackage) if !ok { slog.Debug(fmt.Sprintf("Missing symbol information for package: %s", importedPackage.ID)) return } - v.newReference(sym, scipRange, false) + v.newReference(sym, symbols.RangeFromName(position, importedPackage.PkgPath, true), false) } // newDefinition emits a scip.Occurence ONLY. This will not emit a // new symbol. You must do that using DeclareNewSymbol[ForPos] func (v *fileVisitor) newDefinition( - symbol string, rng []int32, enclRng []int32, deprecated bool, + symbol string, rng scip.Range, enclRng *scip.Range, deprecated bool, ) { occ := &scip.Occurrence{ - Range: rng, - Symbol: symbol, - SymbolRoles: int32(scip.SymbolRole_Definition), - EnclosingRange: enclRng, + TypedRange: rng.AsTypedRange(), + Symbol: symbol, + SymbolRoles: int32(scip.SymbolRole_Definition), + } + if enclRng != nil { + occ.TypedEnclosingRange = enclRng.AsTypedEnclosingRange() } if deprecated { occ.Diagnostics = deprecatedDiagnostics() @@ -312,10 +305,10 @@ func (v *fileVisitor) newDefinition( } func (v *fileVisitor) newReference( - symbol string, rng []int32, deprecated bool, + symbol string, rng scip.Range, deprecated bool, ) { occ := &scip.Occurrence{ - Range: rng, + TypedRange: rng.AsTypedRange(), Symbol: symbol, SymbolRoles: int32(scip.SymbolRole_ReadAccess), } @@ -364,13 +357,14 @@ func (v *fileVisitor) ToScipDocument() *scip.Document { } } -func (v *fileVisitor) enclosingRange(n *ast.Ident) []int32 { +func (v *fileVisitor) enclosingRange(n *ast.Ident) *scip.Range { if v.currentFuncDecl == nil || v.currentFuncDecl.Name != n { return nil } startPosition := v.pkg.Fset.Position(v.currentFuncDecl.Pos()) endPosition := v.pkg.Fset.Position(v.currentFuncDecl.End()) - return scipRange(startPosition, endPosition, v.pkg.TypesInfo.Defs[n]) + rng := scipRange(startPosition, endPosition, v.pkg.TypesInfo.Defs[n]) + return &rng } func deprecatedDiagnostics() []*scip.Diagnostic { diff --git a/internal/visitors/visitors.go b/internal/visitors/visitors.go index c30fe3f1..525092c4 100644 --- a/internal/visitors/visitors.go +++ b/internal/visitors/visitors.go @@ -95,7 +95,7 @@ func descriptorTerm(name string) *scip.Descriptor { } } -func scipRange(start, end token.Position, obj types.Object) []int32 { +func scipRange(start, end token.Position, obj types.Object) scip.Range { var adjustment int32 = 0 if pkgName, ok := obj.(*types.PkgName); ok && strings.HasPrefix(pkgName.Name(), `"`) { adjustment = 1 @@ -105,10 +105,10 @@ func scipRange(start, end token.Position, obj types.Object) []int32 { startColumn := int32(start.Column - 1) endLine := int32(end.Line - 1) endColumn := int32(end.Column - 1) - if startLine != endLine { - return []int32{startLine, startColumn + adjustment, endLine, endColumn - adjustment} + return scip.Range{ + Start: scip.Position{Line: startLine, Character: startColumn + adjustment}, + End: scip.Position{Line: endLine, Character: endColumn - adjustment}, } - return []int32{startLine, startColumn + adjustment, endColumn - adjustment} } func getIdentOfTypeExpr(pkg *packages.Package, ty ast.Expr) []*ast.Ident {