]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/types2/version.go
go/types: use internal/lazyregexp for goVersionRx
[gostls13.git] / 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         "internal/lazyregexp"
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 = lazyregexp.New(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)