]> Cypherpunks.ru repositories - gostls13.git/blob - src/go/types/version.go
all: replace [0-9] with \d in regexps
[gostls13.git] / src / go / types / 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 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, _UnsupportedFeature, "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, _UnsupportedFeature, "binary literals requires go1.13 or later")
34                 return
35         }
36         if radix == 'o' || radix == 'O' {
37                 check.errorf(lit, _UnsupportedFeature, "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, _UnsupportedFeature, "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]\d*)\.(0|[1-9]\d*)$`)