...

Source file src/go/types/version.go

Documentation: go/types

		 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/ast"
		10  	"go/token"
		11  	"regexp"
		12  	"strconv"
		13  	"strings"
		14  )
		15  
		16  // langCompat reports an error if the representation of a numeric
		17  // literal is not compatible with the current language version.
		18  func (check *Checker) langCompat(lit *ast.BasicLit) {
		19  	s := lit.Value
		20  	if len(s) <= 2 || check.allowVersion(check.pkg, 1, 13) {
		21  		return
		22  	}
		23  	// len(s) > 2
		24  	if strings.Contains(s, "_") {
		25  		check.errorf(lit, _InvalidLit, "underscores in numeric literals requires go1.13 or later")
		26  		return
		27  	}
		28  	if s[0] != '0' {
		29  		return
		30  	}
		31  	radix := s[1]
		32  	if radix == 'b' || radix == 'B' {
		33  		check.errorf(lit, _InvalidLit, "binary literals requires go1.13 or later")
		34  		return
		35  	}
		36  	if radix == 'o' || radix == 'O' {
		37  		check.errorf(lit, _InvalidLit, "0o/0O-style octal literals requires go1.13 or later")
		38  		return
		39  	}
		40  	if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
		41  		check.errorf(lit, _InvalidLit, "hexadecimal floating-point literals requires go1.13 or later")
		42  	}
		43  }
		44  
		45  // allowVersion reports whether the given package
		46  // is allowed to use version major.minor.
		47  func (check *Checker) allowVersion(pkg *Package, major, minor int) bool {
		48  	// We assume that imported packages have all been checked,
		49  	// so we only have to check for the local package.
		50  	if pkg != check.pkg {
		51  		return true
		52  	}
		53  	ma, mi := check.version.major, check.version.minor
		54  	return ma == 0 && mi == 0 || ma > major || ma == major && mi >= minor
		55  }
		56  
		57  type version struct {
		58  	major, minor int
		59  }
		60  
		61  // parseGoVersion parses a Go version string (such as "go1.12")
		62  // and returns the version, or an error. If s is the empty
		63  // string, the version is 0.0.
		64  func parseGoVersion(s string) (v version, err error) {
		65  	if s == "" {
		66  		return
		67  	}
		68  	matches := goVersionRx.FindStringSubmatch(s)
		69  	if matches == nil {
		70  		err = fmt.Errorf(`should be something like "go1.12"`)
		71  		return
		72  	}
		73  	v.major, err = strconv.Atoi(matches[1])
		74  	if err != nil {
		75  		return
		76  	}
		77  	v.minor, err = strconv.Atoi(matches[2])
		78  	return
		79  }
		80  
		81  // goVersionRx matches a Go version string, e.g. "go1.12".
		82  var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
		83  

View as plain text