From 51e3d70dba460925d04c98e1b26f7c4b272bdf8b Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 10 Jun 2020 13:05:41 -0700 Subject: [PATCH] go/packages: use go115UsesCgo instead of UsesCgo x/tools half of golang.org/cl/237417. Updates #16623. Updates #39072. Change-Id: Ic31c2cf64dc1b71b70912b9641cf468f60d116f8 Reviewed-on: https://go-review.googlesource.com/c/tools/+/237418 Run-TryBot: Matthew Dempsky Reviewed-by: Heschi Kreinick --- go/packages/packages.go | 8 ++------ internal/lsp/cache/check.go | 6 ++---- internal/lsp/cache/snapshot.go | 4 ++-- internal/typesinternal/types.go | 28 ++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 internal/typesinternal/types.go diff --git a/go/packages/packages.go b/go/packages/packages.go index 4d6c147287a..675682a3609 100644 --- a/go/packages/packages.go +++ b/go/packages/packages.go @@ -19,7 +19,6 @@ import ( "log" "os" "path/filepath" - "reflect" "strings" "sync" "time" @@ -27,6 +26,7 @@ import ( "golang.org/x/tools/go/gcexportdata" "golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/packagesinternal" + "golang.org/x/tools/internal/typesinternal" ) // A LoadMode controls the amount of detail to return when loading. @@ -922,17 +922,13 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) { Sizes: ld.sizes, } if (ld.Mode & TypecheckCgo) != 0 { - // TODO: remove this when we stop supporting 1.14. - rtc := reflect.ValueOf(tc).Elem() - usesCgo := rtc.FieldByName("UsesCgo") - if !usesCgo.IsValid() { + if !typesinternal.SetUsesCgo(tc) { appendError(Error{ Msg: "TypecheckCgo requires Go 1.15+", Kind: ListError, }) return } - usesCgo.SetBool(true) } types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go index 166d1a64e7f..ac186231336 100644 --- a/internal/lsp/cache/check.go +++ b/internal/lsp/cache/check.go @@ -12,7 +12,6 @@ import ( "go/token" "go/types" "path" - "reflect" "sort" "strings" "sync" @@ -23,6 +22,7 @@ import ( "golang.org/x/tools/internal/lsp/source" "golang.org/x/tools/internal/memoize" "golang.org/x/tools/internal/span" + "golang.org/x/tools/internal/typesinternal" errors "golang.org/x/xerrors" ) @@ -404,9 +404,7 @@ func typeCheck(ctx context.Context, fset *token.FileSet, m *metadata, mode sourc } // We want to type check cgo code if go/types supports it. // We passed TypecheckCgo to go/packages when we Loaded. - if usescgo := reflect.ValueOf(cfg).Elem().FieldByName("UsesCgo"); usescgo.IsValid() { - usescgo.SetBool(true) - } + typesinternal.SetUsesCgo(cfg) check := types.NewChecker(cfg, fset, pkg.types, pkg.typesInfo) diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go index e8b2ced4ff1..c5bc080dcbc 100644 --- a/internal/lsp/cache/snapshot.go +++ b/internal/lsp/cache/snapshot.go @@ -12,7 +12,6 @@ import ( "go/types" "os" "path/filepath" - "reflect" "sort" "strings" "sync" @@ -24,6 +23,7 @@ import ( "golang.org/x/tools/internal/lsp/source" "golang.org/x/tools/internal/packagesinternal" "golang.org/x/tools/internal/span" + "golang.org/x/tools/internal/typesinternal" errors "golang.org/x/xerrors" ) @@ -122,7 +122,7 @@ func (s *snapshot) Config(ctx context.Context) *packages.Config { Tests: true, } // We want to type check cgo code if go/types supports it. - if reflect.ValueOf(&types.Config{}).Elem().FieldByName("UsesCgo").IsValid() { + if typesinternal.SetUsesCgo(&types.Config{}) { cfg.Mode |= packages.TypecheckCgo } packagesinternal.SetGoCmdRunner(cfg, s.view.gocmdRunner) diff --git a/internal/typesinternal/types.go b/internal/typesinternal/types.go new file mode 100644 index 00000000000..a5bb408e2f1 --- /dev/null +++ b/internal/typesinternal/types.go @@ -0,0 +1,28 @@ +// Copyright 2020 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 typesinternal + +import ( + "go/types" + "reflect" + "unsafe" +) + +func SetUsesCgo(conf *types.Config) bool { + v := reflect.ValueOf(conf).Elem() + + f := v.FieldByName("go115UsesCgo") + if !f.IsValid() { + f = v.FieldByName("UsesCgo") + if !f.IsValid() { + return false + } + } + + addr := unsafe.Pointer(f.UnsafeAddr()) + *(*bool)(addr) = true + + return true +}