Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/compile/internal/syntax/printer_test.go

Documentation: cmd/compile/internal/syntax

     1  // Copyright 2016 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 syntax
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  	"os"
    12  	"strings"
    13  	"testing"
    14  )
    15  
    16  func TestPrint(t *testing.T) {
    17  	if testing.Short() {
    18  		t.Skip("skipping test in short mode")
    19  	}
    20  
    21  	// provide a no-op error handler so parsing doesn't stop after first error
    22  	ast, err := ParseFile(*src_, func(error) {}, nil, 0)
    23  	if err != nil {
    24  		t.Error(err)
    25  	}
    26  
    27  	if ast != nil {
    28  		Fprint(testOut(), ast, LineForm)
    29  		fmt.Println()
    30  	}
    31  }
    32  
    33  type shortBuffer struct {
    34  	buf []byte
    35  }
    36  
    37  func (w *shortBuffer) Write(data []byte) (n int, err error) {
    38  	w.buf = append(w.buf, data...)
    39  	n = len(data)
    40  	if len(w.buf) > 10 {
    41  		err = io.ErrShortBuffer
    42  	}
    43  	return
    44  }
    45  
    46  func TestPrintError(t *testing.T) {
    47  	const src = "package p; var x int"
    48  	ast, err := Parse(nil, strings.NewReader(src), nil, nil, 0)
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  
    53  	var buf shortBuffer
    54  	_, err = Fprint(&buf, ast, 0)
    55  	if err == nil || err != io.ErrShortBuffer {
    56  		t.Errorf("got err = %s, want %s", err, io.ErrShortBuffer)
    57  	}
    58  }
    59  
    60  var stringTests = []string{
    61  	"package p",
    62  	"package p; type _ int; type T1 = struct{}; type ( _ *struct{}; T2 = float32 )",
    63  
    64  	// generic type declarations
    65  	"package p; type _[T any] struct{}",
    66  	"package p; type _[A, B, C interface{m()}] struct{}",
    67  	"package p; type _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}] struct{}",
    68  
    69  	// generic function declarations
    70  	"package p; func _[T any]()",
    71  	"package p; func _[A, B, C interface{m()}]()",
    72  	"package p; func _[T any, A, B, C interface{m()}, X, Y, Z interface{type int}]()",
    73  
    74  	// methods with generic receiver types
    75  	"package p; func (R[T]) _()",
    76  	"package p; func (*R[A, B, C]) _()",
    77  	"package p; func (_ *R[A, B, C]) _()",
    78  
    79  	// channels
    80  	"package p; type _ chan chan int",
    81  	"package p; type _ chan (<-chan int)",
    82  	"package p; type _ chan chan<- int",
    83  
    84  	"package p; type _ <-chan chan int",
    85  	"package p; type _ <-chan <-chan int",
    86  	"package p; type _ <-chan chan<- int",
    87  
    88  	"package p; type _ chan<- chan int",
    89  	"package p; type _ chan<- <-chan int",
    90  	"package p; type _ chan<- chan<- int",
    91  
    92  	// TODO(gri) expand
    93  }
    94  
    95  func TestPrintString(t *testing.T) {
    96  	for _, want := range stringTests {
    97  		ast, err := Parse(nil, strings.NewReader(want), nil, nil, AllowGenerics)
    98  		if err != nil {
    99  			t.Error(err)
   100  			continue
   101  		}
   102  		if got := String(ast); got != want {
   103  			t.Errorf("%q: got %q", want, got)
   104  		}
   105  	}
   106  }
   107  
   108  func testOut() io.Writer {
   109  	if testing.Verbose() {
   110  		return os.Stdout
   111  	}
   112  	return ioutil.Discard
   113  }
   114  
   115  func dup(s string) [2]string { return [2]string{s, s} }
   116  
   117  var exprTests = [][2]string{
   118  	// basic type literals
   119  	dup("x"),
   120  	dup("true"),
   121  	dup("42"),
   122  	dup("3.1415"),
   123  	dup("2.71828i"),
   124  	dup(`'a'`),
   125  	dup(`"foo"`),
   126  	dup("`bar`"),
   127  
   128  	// func and composite literals
   129  	dup("func() {}"),
   130  	dup("[]int{}"),
   131  	{"func(x int) complex128 { return 0 }", "func(x int) complex128 {…}"},
   132  	{"[]int{1, 2, 3}", "[]int{…}"},
   133  
   134  	// type expressions
   135  	dup("[1 << 10]byte"),
   136  	dup("[]int"),
   137  	dup("*int"),
   138  	dup("struct{x int}"),
   139  	dup("func()"),
   140  	dup("func(int, float32) string"),
   141  	dup("interface{m()}"),
   142  	dup("interface{m() string; n(x int)}"),
   143  	dup("interface{type int}"),
   144  	dup("interface{type int, float64, string}"),
   145  	dup("interface{type int; m()}"),
   146  	dup("interface{type int, float64, string; m() string; n(x int)}"),
   147  	dup("map[string]int"),
   148  	dup("chan E"),
   149  	dup("<-chan E"),
   150  	dup("chan<- E"),
   151  
   152  	// new interfaces
   153  	dup("interface{int}"),
   154  	dup("interface{~int}"),
   155  	dup("interface{~int}"),
   156  	dup("interface{int | string}"),
   157  	dup("interface{~int | ~string; float64; m()}"),
   158  	dup("interface{type a, b, c; ~int | ~string; float64; m()}"),
   159  	dup("interface{~T[int, string] | string}"),
   160  
   161  	// non-type expressions
   162  	dup("(x)"),
   163  	dup("x.f"),
   164  	dup("a[i]"),
   165  
   166  	dup("s[:]"),
   167  	dup("s[i:]"),
   168  	dup("s[:j]"),
   169  	dup("s[i:j]"),
   170  	dup("s[:j:k]"),
   171  	dup("s[i:j:k]"),
   172  
   173  	dup("x.(T)"),
   174  
   175  	dup("x.([10]int)"),
   176  	dup("x.([...]int)"),
   177  
   178  	dup("x.(struct{})"),
   179  	dup("x.(struct{x int; y, z float32; E})"),
   180  
   181  	dup("x.(func())"),
   182  	dup("x.(func(x int))"),
   183  	dup("x.(func() int)"),
   184  	dup("x.(func(x, y int, z float32) (r int))"),
   185  	dup("x.(func(a, b, c int))"),
   186  	dup("x.(func(x ...T))"),
   187  
   188  	dup("x.(interface{})"),
   189  	dup("x.(interface{m(); n(x int); E})"),
   190  	dup("x.(interface{m(); n(x int) T; E; F})"),
   191  
   192  	dup("x.(map[K]V)"),
   193  
   194  	dup("x.(chan E)"),
   195  	dup("x.(<-chan E)"),
   196  	dup("x.(chan<- chan int)"),
   197  	dup("x.(chan<- <-chan int)"),
   198  	dup("x.(<-chan chan int)"),
   199  	dup("x.(chan (<-chan int))"),
   200  
   201  	dup("f()"),
   202  	dup("f(x)"),
   203  	dup("int(x)"),
   204  	dup("f(x, x + y)"),
   205  	dup("f(s...)"),
   206  	dup("f(a, s...)"),
   207  
   208  	dup("*x"),
   209  	dup("&x"),
   210  	dup("x + y"),
   211  	dup("x + y << (2 * s)"),
   212  }
   213  
   214  func TestShortString(t *testing.T) {
   215  	for _, test := range exprTests {
   216  		src := "package p; var _ = " + test[0]
   217  		ast, err := Parse(nil, strings.NewReader(src), nil, nil, AllowGenerics)
   218  		if err != nil {
   219  			t.Errorf("%s: %s", test[0], err)
   220  			continue
   221  		}
   222  		x := ast.DeclList[0].(*VarDecl).Values
   223  		if got := String(x); got != test[1] {
   224  			t.Errorf("%s: got %s, want %s", test[0], got, test[1])
   225  		}
   226  	}
   227  }
   228  

View as plain text