mirror of https://github.com/golang/go.git
72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package source_test
|
|
|
|
import (
|
|
"go/token"
|
|
"go/types"
|
|
"testing"
|
|
|
|
"golang.org/x/tools/go/packages"
|
|
)
|
|
|
|
// This test reports any unexpected uses of (*go/token.File).Offset within
|
|
// the gopls codebase to ensure that we don't check in more code that is prone
|
|
// to panicking. All calls to (*go/token.File).Offset should be replaced with
|
|
// calls to source.Offset.
|
|
func TestTokenOffset(t *testing.T) {
|
|
fset := token.NewFileSet()
|
|
pkgs, err := packages.Load(&packages.Config{
|
|
Fset: fset,
|
|
Mode: packages.NeedName | packages.NeedModule | packages.NeedCompiledGoFiles | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedImports | packages.NeedDeps,
|
|
}, "go/token", "golang.org/x/tools/internal/lsp/...", "golang.org/x/tools/gopls/...")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var tokPkg *packages.Package
|
|
for _, pkg := range pkgs {
|
|
if pkg.PkgPath == "go/token" {
|
|
tokPkg = pkg
|
|
break
|
|
}
|
|
}
|
|
typname, ok := tokPkg.Types.Scope().Lookup("File").(*types.TypeName)
|
|
if !ok {
|
|
t.Fatal("expected go/token.File typename, got none")
|
|
}
|
|
named, ok := typname.Type().(*types.Named)
|
|
if !ok {
|
|
t.Fatalf("expected named type, got %T", typname.Type)
|
|
}
|
|
var offset *types.Func
|
|
for i := 0; i < named.NumMethods(); i++ {
|
|
meth := named.Method(i)
|
|
if meth.Name() == "Offset" {
|
|
offset = meth
|
|
break
|
|
}
|
|
}
|
|
for _, pkg := range pkgs {
|
|
for ident, obj := range pkg.TypesInfo.Uses {
|
|
if ident.Name != "Offset" {
|
|
continue
|
|
}
|
|
if pkg.PkgPath == "go/token" {
|
|
continue
|
|
}
|
|
if !types.Identical(offset.Type(), obj.Type()) {
|
|
continue
|
|
}
|
|
// The only permitted use is in golang.org/x/tools/internal/lsp/source.Offset,
|
|
// so check the enclosing function.
|
|
sourceOffset := pkg.Types.Scope().Lookup("Offset").(*types.Func)
|
|
if sourceOffset.Pos() <= ident.Pos() && ident.Pos() <= sourceOffset.Scope().End() {
|
|
continue // accepted usage
|
|
}
|
|
t.Errorf(`%s: Unexpected use of (*go/token.File).Offset. Please use golang.org/x/tools/internal/lsp/source.Offset instead.`, fset.Position(ident.Pos()))
|
|
}
|
|
}
|
|
}
|