Source file src/cmd/compile/internal/types2/version.go

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

View as plain text