]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: implement flexible flag-setting mechanism for tests
authorRobert Griesemer <gri@golang.org>
Thu, 17 Mar 2022 01:19:31 +0000 (18:19 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 21 Mar 2022 19:10:39 +0000 (19:10 +0000)
Use it so set the language version. Adjust relevant tests.

Fixes #49074.

Change-Id: Ida6d0002bdba65b5add6e8728a1700305de18351
Reviewed-on: https://go-review.googlesource.com/c/go/+/393514
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
18 files changed:
src/cmd/compile/internal/types2/check_test.go
src/cmd/compile/internal/types2/testdata/check/decls0.src
src/cmd/compile/internal/types2/testdata/check/go1_12.src
src/cmd/compile/internal/types2/testdata/check/go1_13.src
src/cmd/compile/internal/types2/testdata/check/go1_16.src
src/cmd/compile/internal/types2/testdata/check/go1_8.src
src/cmd/compile/internal/types2/testdata/check/issues.src
src/cmd/compile/internal/types2/testdata/fixedbugs/issue46090.go2
src/cmd/compile/internal/types2/testdata/fixedbugs/issue47818.go2
src/go/types/check_test.go
src/go/types/testdata/check/decls0.src
src/go/types/testdata/check/go1_12.src
src/go/types/testdata/check/go1_13.src
src/go/types/testdata/check/go1_16.src
src/go/types/testdata/check/go1_8.src
src/go/types/testdata/check/issues.src
src/go/types/testdata/fixedbugs/issue46090.go2
src/go/types/testdata/fixedbugs/issue47818.go2

index 5d491a3e166053905090301141e3aa71315537ae..89d2cc644cfea9de8537209eb7bfaa55da309b24 100644 (file)
 package types2_test
 
 import (
+       "bytes"
        "cmd/compile/internal/syntax"
        "flag"
+       "fmt"
        "internal/testenv"
        "os"
        "path/filepath"
@@ -79,18 +81,45 @@ func delta(x, y uint) uint {
        }
 }
 
-// goVersionRx matches a Go version string using '_', e.g. "go1_12".
-var goVersionRx = regexp.MustCompile(`^go[1-9][0-9]*_(0|[1-9][0-9]*)$`)
+// Note: parseFlags is identical to the version in go/types which is
+//       why it has a src argument even though here it is always nil.
+
+// parseFlags parses flags from the first line of the given source
+// (from src if present, or by reading from the file) if the line
+// starts with "//" (line comment) followed by "-" (possiby with
+// spaces between). Otherwise the line is ignored.
+func parseFlags(filename string, src []byte, flags *flag.FlagSet) error {
+       // If there is no src, read from the file.
+       const maxLen = 256
+       if len(src) == 0 {
+               f, err := os.Open(filename)
+               if err != nil {
+                       return err
+               }
+
+               var buf [maxLen]byte
+               n, err := f.Read(buf[:])
+               if err != nil {
+                       return err
+               }
+               src = buf[:n]
+       }
 
-// asGoVersion returns a regular Go language version string
-// if s is a Go version string using '_' rather than '.' to
-// separate the major and minor version numbers (e.g. "go1_12").
-// Otherwise it returns the empty string.
-func asGoVersion(s string) string {
-       if goVersionRx.MatchString(s) {
-               return strings.Replace(s, "_", ".", 1)
+       // we must have a line comment that starts with a "-"
+       const prefix = "//"
+       if !bytes.HasPrefix(src, []byte(prefix)) {
+               return nil // first line is not a line comment
+       }
+       src = src[len(prefix):]
+       if i := bytes.Index(src, []byte("-")); i < 0 || len(bytes.TrimSpace(src[:i])) != 0 {
+               return nil // comment doesn't start with a "-"
        }
-       return ""
+       end := bytes.Index(src, []byte("\n"))
+       if end < 0 || end > maxLen {
+               return fmt.Errorf("flags comment line too long")
+       }
+
+       return flags.Parse(strings.Fields(string(src[:end])))
 }
 
 func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
@@ -98,6 +127,14 @@ func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
                t.Fatal("no source files")
        }
 
+       var conf Config
+       flags := flag.NewFlagSet("", flag.PanicOnError)
+       flags.StringVar(&conf.GoVersion, "lang", "", "")
+       if err := parseFlags(filenames[0], nil, flags); err != nil {
+               t.Fatal(err)
+       }
+
+       // TODO(gri) remove this or use flag mechanism to set mode if still needed
        var mode syntax.Mode
        if strings.HasSuffix(filenames[0], ".go2") || manual {
                mode |= syntax.AllowGenerics | syntax.AllowMethodTypeParams
@@ -110,12 +147,6 @@ func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
                pkgName = files[0].PkgName.Value
        }
 
-       // if no Go version is given, consider the package name
-       goVersion := *goVersion
-       if goVersion == "" {
-               goVersion = asGoVersion(pkgName)
-       }
-
        listErrors := manual && !*verifyErrors
        if listErrors && len(errlist) > 0 {
                t.Errorf("--- %s:", pkgName)
@@ -125,8 +156,6 @@ func testFiles(t *testing.T, filenames []string, colDelta uint, manual bool) {
        }
 
        // typecheck and collect typechecker errors
-       var conf Config
-       conf.GoVersion = goVersion
        // special case for importC.src
        if len(filenames) == 1 && strings.HasSuffix(filenames[0], "importC.src") {
                conf.FakeImportC = true
index 09e5d5c5ad84355af0bdea8552b1de283b5cf256..aa98480b994ee9d1fc31191c0f2208f4d78a9596 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.17
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // type declarations
 
-package go1_17 // don't permit non-interface elements in interfaces
+package p // don't permit non-interface elements in interfaces
 
 import "unsafe"
 
index 75a602b8ff9bd9917ddf46180749e3a80c7ba155..56c6d5a4c9b4bc22f9f0af3554897acc4de5380e 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.12
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_12 // go1.12
+package p
 
 // numeric literals
 const (
index 93cb4c72a7e1a69cc62df8b19c8c068bfd0611a7..cc7861d616100222ffddabec24b6cc75d2e4dadc 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.13
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_13 // go1.13
+package p
 
 // interface embedding
 
index fdf5c99d7e3248f76e0bd4f7208c4c5aed6e2bc8..81b529044c5064dddd85c3e51c7f8ac527065d0b 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.16
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_16 // go1.16
+package p
 
 type Slice []byte
 type Array [8]byte
index 0f3ba9443bd5317f6ef4b235e98e74deee0db572..15462aba14aa964081ecfd9de90e98fbc739a4c8 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.8
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_8 // go1.8
+package p
 
 // type alias declarations
 type any /* ERROR type aliases requires go1.9 or later */ = interface{}
index 42c5bc8f128e891c7b14e6800022b0d406a4ee63..4ac3fc2f9df558f2753a716bfa6c790366d62d0b 100644 (file)
@@ -1,8 +1,10 @@
+// -lang=go1.17
+
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package go1_17 // don't permit non-interface elements in interfaces
+package p // don't permit non-interface elements in interfaces
 
 import (
        "fmt"
index 81b31974c8dc0207e0833d51c845b978ce26cef4..0fb92a36571100625183be779b7e527cb427df6e 100644 (file)
@@ -1,9 +1,11 @@
+// -lang=go1.17
+
 // Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // The predeclared type comparable is not visible before Go 1.18.
 
-package go1_17
+package p
 
 type _ comparable // ERROR undeclared
index 6069f1f97b4e2eb23e57f4a6fe1781fec97e82b4..58a62092b7ccaa23c6d7c15df9d1f80ea16fbe22 100644 (file)
@@ -1,3 +1,5 @@
+// -lang=go1.17
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -6,7 +8,7 @@
 // needs to report any operations that are not permitted
 // before Go 1.18.
 
-package go1_17
+package p
 
 type T[P /* ERROR type parameter requires go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ] struct{}
 
index b96158a660653f9ec6c119beaa35817d43eba5ea..6bee41d141a2e0390b3972687587f9cccb24719a 100644 (file)
@@ -23,6 +23,7 @@
 package types_test
 
 import (
+       "bytes"
        "flag"
        "fmt"
        "go/ast"
@@ -185,18 +186,42 @@ func eliminate(t *testing.T, errmap map[string][]string, errlist []error) {
        }
 }
 
-// goVersionRx matches a Go version string using '_', e.g. "go1_12".
-var goVersionRx = regexp.MustCompile(`^go[1-9][0-9]*_(0|[1-9][0-9]*)$`)
+// parseFlags parses flags from the first line of the given source
+// (from src if present, or by reading from the file) if the line
+// starts with "//" (line comment) followed by "-" (possiby with
+// spaces between). Otherwise the line is ignored.
+func parseFlags(filename string, src []byte, flags *flag.FlagSet) error {
+       // If there is no src, read from the file.
+       const maxLen = 256
+       if len(src) == 0 {
+               f, err := os.Open(filename)
+               if err != nil {
+                       return err
+               }
 
-// asGoVersion returns a regular Go language version string
-// if s is a Go version string using '_' rather than '.' to
-// separate the major and minor version numbers (e.g. "go1_12").
-// Otherwise it returns the empty string.
-func asGoVersion(s string) string {
-       if goVersionRx.MatchString(s) {
-               return strings.Replace(s, "_", ".", 1)
+               var buf [maxLen]byte
+               n, err := f.Read(buf[:])
+               if err != nil {
+                       return err
+               }
+               src = buf[:n]
        }
-       return ""
+
+       // we must have a line comment that starts with a "-"
+       const prefix = "//"
+       if !bytes.HasPrefix(src, []byte(prefix)) {
+               return nil // first line is not a line comment
+       }
+       src = src[len(prefix):]
+       if i := bytes.Index(src, []byte("-")); i < 0 || len(bytes.TrimSpace(src[:i])) != 0 {
+               return nil // comment doesn't start with a "-"
+       }
+       end := bytes.Index(src, []byte("\n"))
+       if end < 0 || end > maxLen {
+               return fmt.Errorf("flags comment line too long")
+       }
+
+       return flags.Parse(strings.Fields(string(src[:end])))
 }
 
 func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, manual bool, imp Importer) {
@@ -204,6 +229,15 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
                t.Fatal("no source files")
        }
 
+       var conf Config
+       conf.Sizes = sizes
+       flags := flag.NewFlagSet("", flag.PanicOnError)
+       flags.StringVar(&conf.GoVersion, "lang", "", "")
+       if err := parseFlags(filenames[0], srcs[0], flags); err != nil {
+               t.Fatal(err)
+       }
+
+       // TODO(gri) remove this or use flag mechanism to set mode if still needed
        if strings.HasSuffix(filenames[0], ".go1") {
                // TODO(rfindley): re-enable this test by using GoVersion.
                t.Skip("type params are enabled")
@@ -222,12 +256,6 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
                pkgName = files[0].Name.Name
        }
 
-       // if no Go version is given, consider the package name
-       goVersion := *goVersion
-       if goVersion == "" {
-               goVersion = asGoVersion(pkgName)
-       }
-
        listErrors := manual && !*verifyErrors
        if listErrors && len(errlist) > 0 {
                t.Errorf("--- %s:", pkgName)
@@ -237,10 +265,6 @@ func testFiles(t *testing.T, sizes Sizes, filenames []string, srcs [][]byte, man
        }
 
        // typecheck and collect typechecker errors
-       var conf Config
-       conf.Sizes = sizes
-       conf.GoVersion = goVersion
-
        // special case for importC.src
        if len(filenames) == 1 {
                if strings.HasSuffix(filenames[0], "importC.src") {
index 18f0d32e1b4a5a878c65a5e8253b12cd8a54a8a5..740c9b4fdf612bb85df782c87f2b486ac59bf342 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.17
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // type declarations
 
-package go1_17 // don't permit non-interface elements in interfaces
+package p // don't permit non-interface elements in interfaces
 
 import "unsafe"
 
index 1e529f18be8315a0c84b5155d50069df7972575c..14c2d58c33af401af7c9d4dcc6aab442191a1c1f 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.12
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_12 // go1.12
+package p
 
 // numeric literals
 const (
index 6aa1364e8a4732da7ffe7b2481ce4ef17c6d019a..5c52dfe6024cd9f69b0766eb59e958a261fa7bd5 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.13
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_13 // go1.13
+package p
 
 // interface embedding
 
index fdf5c99d7e3248f76e0bd4f7208c4c5aed6e2bc8..81b529044c5064dddd85c3e51c7f8ac527065d0b 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.16
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_16 // go1.16
+package p
 
 type Slice []byte
 type Array [8]byte
index 3ead1e981b71f9e1c9d9848227108b0976ec8607..5d57cdc65e5326d4f6c40781516afa5592b42a52 100644 (file)
@@ -1,10 +1,12 @@
+// -lang=go1.8
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Check Go language version-specific errors.
 
-package go1_8 // go1.8
+package p
 
 // type alias declarations
 type any = /* ERROR type aliases requires go1.9 or later */ interface{}
index 8bb4c8c5cae088a55cb8b772e7c37ff620a71cb0..6943796392b5aeeff78ec76646485fb2b742a2ab 100644 (file)
@@ -1,8 +1,10 @@
+// -lang=go1.17
+
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package go1_17 // don't permit non-interface elements in interfaces
+package p // don't permit non-interface elements in interfaces
 
 import (
        "fmt"
index 81b31974c8dc0207e0833d51c845b978ce26cef4..0fb92a36571100625183be779b7e527cb427df6e 100644 (file)
@@ -1,9 +1,11 @@
+// -lang=go1.17
+
 // Copyright 2020 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // The predeclared type comparable is not visible before Go 1.18.
 
-package go1_17
+package p
 
 type _ comparable // ERROR undeclared
index 546de1ce3134577b55c06e4810e4fd7a424e54c3..dbd532ac123981c71a4df3c0fa399671633e4700 100644 (file)
@@ -1,3 +1,5 @@
+// -lang=go1.17
+
 // Copyright 2021 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
@@ -6,7 +8,7 @@
 // needs to report any operations that are not permitted
 // before Go 1.18.
 
-package go1_17
+package p
 
 type T[P /* ERROR type parameters require go1\.18 or later */ any /* ERROR undeclared name: any \(requires version go1\.18 or later\) */ ] struct{}