version.go raw

   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 types
   6  
   7  import (
   8  	"fmt"
   9  	"go/version"
  10  	"internal/goversion"
  11  )
  12  
  13  // A goVersion is a Go language version string of the form "go1.%d"
  14  // where d is the minor version number. goVersion strings don't
  15  // contain release numbers ("go1.20.1" is not a valid goVersion).
  16  type goVersion string
  17  
  18  // asGoVersion returns v as a goVersion (e.g., "go1.20.1" becomes "go1.20").
  19  // If v is not a valid Go version, the result is the empty string.
  20  func asGoVersion(v string) goVersion {
  21  	return goVersion(version.Lang(v))
  22  }
  23  
  24  // isValid reports whether v is a valid Go version.
  25  func (v goVersion) isValid() bool {
  26  	return v != ""
  27  }
  28  
  29  // cmp returns -1, 0, or +1 depending on whether x < y, x == y, or x > y,
  30  // interpreted as Go versions.
  31  func (x goVersion) cmp(y goVersion) int {
  32  	return version.Compare(string(x), string(y))
  33  }
  34  
  35  var (
  36  	// Go versions that introduced language changes
  37  	go1_9  = asGoVersion("go1.9")
  38  	go1_13 = asGoVersion("go1.13")
  39  	go1_14 = asGoVersion("go1.14")
  40  	go1_17 = asGoVersion("go1.17")
  41  	go1_18 = asGoVersion("go1.18")
  42  	go1_20 = asGoVersion("go1.20")
  43  	go1_21 = asGoVersion("go1.21")
  44  	go1_22 = asGoVersion("go1.22")
  45  	go1_23 = asGoVersion("go1.23")
  46  
  47  	// current (deployed) Go version
  48  	go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version))
  49  )
  50  
  51  // allowVersion reports whether the current effective Go version
  52  // (which may vary from one file to another) is allowed to use the
  53  // feature version (want).
  54  func (check *Checker) allowVersion(want goVersion) bool {
  55  	return !check.version.isValid() || check.version.cmp(want) >= 0
  56  }
  57  
  58  // verifyVersionf is like allowVersion but also accepts a format string and arguments
  59  // which are used to report a version error if allowVersion returns false.
  60  func (check *Checker) verifyVersionf(at positioner, v goVersion, format string, args ...interface{}) bool {
  61  	if !check.allowVersion(v) {
  62  		check.versionErrorf(at, v, format, args...)
  63  		return false
  64  	}
  65  	return true
  66  }
  67