[go/dev.typeparams] [dev.typeparams] test: add string quoting support to test/run.go

7 views
Skip to first unread message

Matthew Dempsky (Gerrit)

unread,
Jun 11, 2021, 2:19:16 PM6/11/21
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Matthew Dempsky has uploaded this change for review.

View Change

[dev.typeparams] test: add string quoting support to test/run.go

This CL copies go/build's splitQuoted function (used for parsing #cgo
directives within `import "C"` preambles) to parse test recipe
commands. In particular, this now allows writing "build" and "run"
tests that use -gcflags to pass multiple compiler flags.

Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
---
M test/run.go
A test/typeparam/dictionaryCapture-noinline.go
M test/typeparam/dictionaryCapture.go
3 files changed, 193 insertions(+), 3 deletions(-)

diff --git a/test/run.go b/test/run.go
index ef1e9de..ca6a0f5 100644
--- a/test/run.go
+++ b/test/run.go
@@ -573,7 +573,11 @@
singlefilepkgs := false
setpkgpaths := false
localImports := true
- f := strings.Fields(action)
+ f, err := splitQuoted(action)
+ if err != nil {
+ t.err = fmt.Errorf("invalid test recipe: %v", err)
+ return
+ }
if len(f) > 0 {
action = f[0]
args = f[1:]
@@ -2116,3 +2120,65 @@
"fixedbugs/issue7921.go": true,
"inline.go": true,
}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element. The backslash is used for escaping.
+//
+// For example, the following string:
+//
+// a b:"c d" 'e''f' "g\""
+//
+// Would be parsed as:
+//
+// []string{"a", "b:c d", "ef", `g"`}
+//
+// [copied from src/go/build/build.go]
+func splitQuoted(s string) (r []string, err error) {
+ var args []string
+ arg := make([]rune, len(s))
+ escaped := false
+ quoted := false
+ quote := '\x00'
+ i := 0
+ for _, rune := range s {
+ switch {
+ case escaped:
+ escaped = false
+ case rune == '\\':
+ escaped = true
+ continue
+ case quote != '\x00':
+ if rune == quote {
+ quote = '\x00'
+ continue
+ }
+ case rune == '"' || rune == '\'':
+ quoted = true
+ quote = rune
+ continue
+ case unicode.IsSpace(rune):
+ if quoted || i > 0 {
+ quoted = false
+ args = append(args, string(arg[:i]))
+ i = 0
+ }
+ continue
+ }
+ arg[i] = rune
+ i++
+ }
+ if quoted || i > 0 {
+ args = append(args, string(arg[:i]))
+ }
+ if quote != 0 {
+ err = errors.New("unclosed quote")
+ } else if escaped {
+ err = errors.New("unfinished escaping")
+ }
+ return args, err
+}
diff --git a/test/typeparam/dictionaryCapture-noinline.go b/test/typeparam/dictionaryCapture-noinline.go
new file mode 100644
index 0000000..4b46d5f
--- /dev/null
+++ b/test/typeparam/dictionaryCapture-noinline.go
@@ -0,0 +1,126 @@
+// run -gcflags="-G=3 -l"
+
+// 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.
+
+// Test situations where functions/methods are not
+// immediately called and we need to capture the dictionary
+// required for later invocation.
+
+package main
+
+func main() {
+ functions()
+ methodExpressions()
+ methodValues()
+ interfaceMethods()
+ globals()
+}
+
+func g0[T any](x T) {
+}
+func g1[T any](x T) T {
+ return x
+}
+func g2[T any](x T) (T, T) {
+ return x, x
+}
+
+func functions() {
+ f0 := g0[int]
+ f0(7)
+ f1 := g1[int]
+ is7(f1(7))
+ f2 := g2[int]
+ is77(f2(7))
+}
+
+func is7(x int) {
+ if x != 7 {
+ println(x)
+ panic("assertion failed")
+ }
+}
+func is77(x, y int) {
+ if x != 7 || y != 7 {
+ println(x,y)
+ panic("assertion failed")
+ }
+}
+
+type s[T any] struct {
+ a T
+}
+
+func (x s[T]) g0() {
+}
+func (x s[T]) g1() T {
+ return x.a
+}
+func (x s[T]) g2() (T, T) {
+ return x.a, x.a
+}
+
+func methodExpressions() {
+ x := s[int]{a:7}
+ f0 := s[int].g0
+ f0(x)
+ f1 := s[int].g1
+ is7(f1(x))
+ f2 := s[int].g2
+ is77(f2(x))
+}
+
+func methodValues() {
+ x := s[int]{a:7}
+ f0 := x.g0
+ f0()
+ f1 := x.g1
+ is7(f1())
+ f2 := x.g2
+ is77(f2())
+}
+
+var x interface{
+ g0()
+ g1()int
+ g2()(int,int)
+} = s[int]{a:7}
+var y interface{} = s[int]{a:7}
+
+func interfaceMethods() {
+ x.g0()
+ is7(x.g1())
+ is77(x.g2())
+ y.(interface{g0()}).g0()
+ is7(y.(interface{g1()int}).g1())
+ is77(y.(interface{g2()(int,int)}).g2())
+}
+
+// Also check for instantiations outside functions.
+var gg0 = g0[int]
+var gg1 = g1[int]
+var gg2 = g2[int]
+
+var hh0 = s[int].g0
+var hh1 = s[int].g1
+var hh2 = s[int].g2
+
+var xtop = s[int]{a:7}
+var ii0 = x.g0
+var ii1 = x.g1
+var ii2 = x.g2
+
+func globals() {
+ gg0(7)
+ is7(gg1(7))
+ is77(gg2(7))
+ x := s[int]{a:7}
+ hh0(x)
+ is7(hh1(x))
+ is77(hh2(x))
+ ii0()
+ is7(ii1())
+ is77(ii2())
+}
diff --git a/test/typeparam/dictionaryCapture.go b/test/typeparam/dictionaryCapture.go
index bb35df5..1b2ee1d 100644
--- a/test/typeparam/dictionaryCapture.go
+++ b/test/typeparam/dictionaryCapture.go
@@ -8,8 +8,6 @@
// immediately called and we need to capture the dictionary
// required for later invocation.

-// TODO: copy this test file, add -l to gcflags.
-
package main

func main() {

To view, visit change 327275. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: dev.typeparams
Gerrit-Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
Gerrit-Change-Number: 327275
Gerrit-PatchSet: 1
Gerrit-Owner: Matthew Dempsky <mdem...@google.com>
Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
Gerrit-MessageType: newchange

Cuong Manh Le (Gerrit)

unread,
Jun 12, 2021, 10:35:29 AM6/12/21
to Matthew Dempsky, goph...@pubsubhelper.golang.org, Go Bot, Keith Randall, Dan Scales, golang-co...@googlegroups.com

Attention is currently required from: Dan Scales, Matthew Dempsky, Keith Randall.

Patch set 1:Code-Review +2

View Change

    To view, visit change 327275. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: dev.typeparams
    Gerrit-Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
    Gerrit-Change-Number: 327275
    Gerrit-PatchSet: 1
    Gerrit-Owner: Matthew Dempsky <mdem...@google.com>
    Gerrit-Reviewer: Cuong Manh Le <cuong.m...@gmail.com>
    Gerrit-Reviewer: Dan Scales <dans...@google.com>
    Gerrit-Reviewer: Go Bot <go...@golang.org>
    Gerrit-Reviewer: Keith Randall <k...@golang.org>
    Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
    Gerrit-Attention: Dan Scales <dans...@google.com>
    Gerrit-Attention: Matthew Dempsky <mdem...@google.com>
    Gerrit-Attention: Keith Randall <k...@golang.org>
    Gerrit-Comment-Date: Sat, 12 Jun 2021 14:35:21 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Matthew Dempsky (Gerrit)

    unread,
    Jun 12, 2021, 10:36:31 AM6/12/21
    to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Cuong Manh Le, Go Bot, Keith Randall, Dan Scales, golang-co...@googlegroups.com

    Matthew Dempsky submitted this change.

    View Change

    Approvals: Cuong Manh Le: Looks good to me, approved Matthew Dempsky: Trusted; Run TryBots Go Bot: TryBots succeeded
    [dev.typeparams] test: add string quoting support to test/run.go

    This CL copies go/build's splitQuoted function (used for parsing #cgo
    directives within `import "C"` preambles) to parse test recipe
    commands. In particular, this now allows writing "build" and "run"
    tests that use -gcflags to pass multiple compiler flags.

    Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
    Reviewed-on: https://go-review.googlesource.com/c/go/+/327275
    Trust: Matthew Dempsky <mdem...@google.com>
    Run-TryBot: Matthew Dempsky <mdem...@google.com>
    TryBot-Result: Go Bot <go...@golang.org>
    Reviewed-by: Cuong Manh Le <cuong.m...@gmail.com>

    To view, visit change 327275. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: dev.typeparams
    Gerrit-Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
    Gerrit-Change-Number: 327275
    Gerrit-PatchSet: 2
    Gerrit-Owner: Matthew Dempsky <mdem...@google.com>
    Gerrit-Reviewer: Cuong Manh Le <cuong.m...@gmail.com>
    Gerrit-Reviewer: Dan Scales <dans...@google.com>
    Gerrit-Reviewer: Go Bot <go...@golang.org>
    Gerrit-Reviewer: Keith Randall <k...@golang.org>
    Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
    Gerrit-MessageType: merged

    Dan Scales (Gerrit)

    unread,
    Jun 12, 2021, 11:08:16 AM6/12/21
    to Matthew Dempsky, goph...@pubsubhelper.golang.org, Cuong Manh Le, Go Bot, Keith Randall, Dan Scales, golang-co...@googlegroups.com

    View Change

    1 comment:

    To view, visit change 327275. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: dev.typeparams
    Gerrit-Change-Id: I0d18a9c13a4ce24bbdfa1da8662c0498c93a6762
    Gerrit-Change-Number: 327275
    Gerrit-PatchSet: 2
    Gerrit-Owner: Matthew Dempsky <mdem...@google.com>
    Gerrit-Reviewer: Cuong Manh Le <cuong.m...@gmail.com>
    Gerrit-Reviewer: Dan Scales <dans...@google.com>
    Gerrit-Reviewer: Go Bot <go...@golang.org>
    Gerrit-Reviewer: Keith Randall <k...@golang.org>
    Gerrit-Reviewer: Matthew Dempsky <mdem...@google.com>
    Gerrit-Comment-Date: Sat, 12 Jun 2021 15:08:12 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment
    Reply all
    Reply to author
    Forward
    0 new messages