// setup and syntax error reporting
files := make([]*syntax.File, len(noders))
- // posBaseMap maps all file pos bases back to *syntax.File
+ // fileBaseMap maps all file pos bases back to *syntax.File
// for checking Go version mismatched.
- posBaseMap := make(map[*syntax.PosBase]*syntax.File)
+ fileBaseMap := make(map[*syntax.PosBase]*syntax.File)
for i, p := range noders {
files[i] = p.file
// The file.Pos() is the position of the package clause.
// Make sure to consistently map back to file base, here and
// when we look for a file in the conf.Error handler below,
// otherwise the file may not be found (was go.dev/issue/67141).
- posBaseMap[fileBase(p.file.Pos())] = p.file
+ fileBaseMap[p.file.Pos().FileBase()] = p.file
}
// typechecking
terr := err.(types2.Error)
msg := terr.Msg
if versionErrorRx.MatchString(msg) {
- posBase := fileBase(terr.Pos)
- fileVersion := info.FileVersions[posBase]
- file := posBaseMap[posBase]
+ fileBase := terr.Pos.FileBase()
+ fileVersion := info.FileVersions[fileBase]
+ file := fileBaseMap[fileBase]
if file == nil {
// This should never happen, but be careful and don't crash.
} else if file.GoVersion == fileVersion {
return pkg, info
}
-// fileBase returns a file's position base given a position in the file.
-func fileBase(pos syntax.Pos) *syntax.PosBase {
- base := pos.Base()
- for !base.IsFileBase() { // line directive base
- base = base.Pos().Base()
- }
- return base
-}
-
// A cycleFinder detects anonymous interface cycles (go.dev/issue/56103).
type cycleFinder struct {
cyclic map[*types2.Interface]bool
func (pos Pos) Line() uint { return uint(pos.line) }
func (pos Pos) Col() uint { return uint(pos.col) }
+// FileBase returns the PosBase of the file containing pos,
+// skipping over intermediate PosBases from //line directives.
+// The result is nil if pos doesn't have a file base.
+func (pos Pos) FileBase() *PosBase {
+ b := pos.base
+ for b != nil && b != b.pos.base {
+ b = b.pos.base
+ }
+ // b == nil || b == b.pos.base
+ return b
+}
+
func (pos Pos) RelFilename() string { return pos.base.Filename() }
func (pos Pos) RelLine() uint {
package types2
import (
- "cmd/compile/internal/syntax"
"fmt"
"go/version"
"internal/goversion"
func (check *Checker) allowVersion(at poser, v goVersion) bool {
fileVersion := check.conf.GoVersion
if pos := at.Pos(); pos.IsKnown() {
- fileVersion = check.versions[base(pos)]
+ fileVersion = check.versions[pos.FileBase()]
}
// We need asGoVersion (which calls version.Lang) below
}
return true
}
-
-// base finds the underlying PosBase of the source file containing pos,
-// skipping over intermediate PosBase layers created by //line directives.
-// The positions must be known.
-func base(pos syntax.Pos) *syntax.PosBase {
- assert(pos.IsKnown())
- b := pos.Base()
- for {
- bb := b.Pos().Base()
- if bb == nil || bb == b {
- break
- }
- b = bb
- }
- return b
-}