Source file src/cmd/vendor/golang.org/x/tools/internal/analysis/analyzerutil/version.go
1 // Copyright 2025 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 analyzerutil 6 7 import ( 8 "go/ast" 9 "strings" 10 11 "golang.org/x/tools/go/analysis" 12 "golang.org/x/tools/internal/packagepath" 13 "golang.org/x/tools/internal/stdlib" 14 "golang.org/x/tools/internal/versions" 15 ) 16 17 // FileUsesGoVersion reports whether the specified file may use features of the 18 // specified version of Go (e.g. "go1.24"). 19 // 20 // Tip: we recommend using this check "late", just before calling 21 // pass.Report, rather than "early" (when entering each ast.File, or 22 // each candidate node of interest, during the traversal), because the 23 // operation is not free, yet is not a highly selective filter: the 24 // fraction of files that pass most version checks is high and 25 // increases over time. 26 func FileUsesGoVersion(pass *analysis.Pass, file *ast.File, version string) (_res bool) { 27 fileVersion := pass.TypesInfo.FileVersions[file] 28 29 // Standard packages that are part of toolchain bootstrapping 30 // are not considered to use a version of Go later than the 31 // current bootstrap toolchain version. 32 // The bootstrap rule does not cover tests, 33 // and some tests (e.g. debug/elf/file_test.go) rely on this. 34 pkgpath := pass.Pkg.Path() 35 if packagepath.IsStdPackage(pkgpath) && 36 stdlib.IsBootstrapPackage(pkgpath) && // (excludes "*_test" external test packages) 37 !strings.HasSuffix(pass.Fset.File(file.Pos()).Name(), "_test.go") { // (excludes all tests) 38 fileVersion = stdlib.BootstrapVersion.String() // package must bootstrap 39 } 40 41 return !versions.Before(fileVersion, version) 42 } 43