github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/internal/lsp/source/offset_test.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package source_test 6 7 import ( 8 "go/token" 9 "go/types" 10 "testing" 11 12 "github.com/jhump/golang-x-tools/go/packages" 13 ) 14 15 // This test reports any unexpected uses of (*go/token.File).Offset within 16 // the gopls codebase to ensure that we don't check in more code that is prone 17 // to panicking. All calls to (*go/token.File).Offset should be replaced with 18 // calls to source.Offset. 19 func TestTokenOffset(t *testing.T) { 20 fset := token.NewFileSet() 21 pkgs, err := packages.Load(&packages.Config{ 22 Fset: fset, 23 Mode: packages.NeedName | packages.NeedModule | packages.NeedCompiledGoFiles | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedImports | packages.NeedDeps, 24 }, "go/token", "github.com/jhump/golang-x-tools/internal/lsp/...", "github.com/jhump/golang-x-tools/gopls/...") 25 if err != nil { 26 t.Fatal(err) 27 } 28 var tokPkg *packages.Package 29 for _, pkg := range pkgs { 30 if pkg.PkgPath == "go/token" { 31 tokPkg = pkg 32 break 33 } 34 } 35 typname, ok := tokPkg.Types.Scope().Lookup("File").(*types.TypeName) 36 if !ok { 37 t.Fatal("expected go/token.File typename, got none") 38 } 39 named, ok := typname.Type().(*types.Named) 40 if !ok { 41 t.Fatalf("expected named type, got %T", typname.Type) 42 } 43 var offset *types.Func 44 for i := 0; i < named.NumMethods(); i++ { 45 meth := named.Method(i) 46 if meth.Name() == "Offset" { 47 offset = meth 48 break 49 } 50 } 51 for _, pkg := range pkgs { 52 for ident, obj := range pkg.TypesInfo.Uses { 53 if ident.Name != "Offset" { 54 continue 55 } 56 if pkg.PkgPath == "go/token" { 57 continue 58 } 59 if !types.Identical(offset.Type(), obj.Type()) { 60 continue 61 } 62 // The only permitted use is in golang.org/x/tools/internal/lsp/source.Offset, 63 // so check the enclosing function. 64 sourceOffset := pkg.Types.Scope().Lookup("Offset").(*types.Func) 65 if sourceOffset.Pos() <= ident.Pos() && ident.Pos() <= sourceOffset.Scope().End() { 66 continue // accepted usage 67 } 68 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())) 69 } 70 } 71 }