github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/go/ssa/const_test.go (about)

     1  // Copyright 2022 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 ssa_test
     6  
     7  import (
     8  	"go/ast"
     9  	"go/constant"
    10  	"go/parser"
    11  	"go/token"
    12  	"go/types"
    13  	"math/big"
    14  	"strings"
    15  	"testing"
    16  
    17  	"golang.org/x/tools/go/ssa"
    18  	"golang.org/x/tools/internal/typeparams"
    19  )
    20  
    21  func TestConstString(t *testing.T) {
    22  	if !typeparams.Enabled {
    23  		t.Skip("TestConstString requires type parameters.")
    24  	}
    25  
    26  	const source = `
    27  	package P
    28  
    29  	type Named string
    30  
    31  	func fn() (int, bool, string) 
    32  	func gen[T int]() {}
    33  	`
    34  	fset := token.NewFileSet()
    35  	f, err := parser.ParseFile(fset, "p.go", source, 0)
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	var conf types.Config
    41  	pkg, err := conf.Check("P", fset, []*ast.File{f}, nil)
    42  	if err != nil {
    43  		t.Fatal(err)
    44  	}
    45  
    46  	for _, test := range []struct {
    47  		expr     string      // type expression
    48  		constant interface{} // constant value
    49  		want     string      // expected String() value
    50  	}{
    51  		{"int", int64(0), "0:int"},
    52  		{"int64", int64(0), "0:int64"},
    53  		{"float32", int64(0), "0:float32"},
    54  		{"float32", big.NewFloat(1.5), "1.5:float32"},
    55  		{"bool", false, "false:bool"},
    56  		{"string", "", `"":string`},
    57  		{"Named", "", `"":P.Named`},
    58  		{"struct{x string}", nil, "struct{x string}{}:struct{x string}"},
    59  		{"[]int", nil, "nil:[]int"},
    60  		{"[3]int", nil, "[3]int{}:[3]int"},
    61  		{"*int", nil, "nil:*int"},
    62  		{"interface{}", nil, "nil:interface{}"},
    63  		{"interface{string}", nil, `"":interface{string}`},
    64  		{"interface{int|int64}", nil, "0:interface{int|int64}"},
    65  		{"interface{bool}", nil, "false:interface{bool}"},
    66  		{"interface{bool|int}", nil, "nil:interface{bool|int}"},
    67  		{"interface{int|string}", nil, "nil:interface{int|string}"},
    68  		{"interface{bool|string}", nil, "nil:interface{bool|string}"},
    69  		{"interface{struct{x string}}", nil, "nil:interface{struct{x string}}"},
    70  		{"interface{int|int64}", int64(1), "1:interface{int|int64}"},
    71  		{"interface{~bool}", true, "true:interface{~bool}"},
    72  		{"interface{Named}", "lorem ipsum", `"lorem ipsum":interface{P.Named}`},
    73  		{"func() (int, bool, string)", nil, "nil:func() (int, bool, string)"},
    74  	} {
    75  		// Eval() expr for its type.
    76  		tv, err := types.Eval(fset, pkg, 0, test.expr)
    77  		if err != nil {
    78  			t.Fatalf("Eval(%s) failed: %v", test.expr, err)
    79  		}
    80  		var val constant.Value
    81  		if test.constant != nil {
    82  			val = constant.Make(test.constant)
    83  		}
    84  		c := ssa.NewConst(val, tv.Type)
    85  		got := strings.ReplaceAll(c.String(), " | ", "|") // Accept both interface{a | b} and interface{a|b}.
    86  		if got != test.want {
    87  			t.Errorf("ssa.NewConst(%v, %s).String() = %v, want %v", val, tv.Type, got, test.want)
    88  		}
    89  	}
    90  
    91  	// Test tuples
    92  	fn := pkg.Scope().Lookup("fn")
    93  	tup := fn.Type().(*types.Signature).Results()
    94  	if got, want := ssa.NewConst(nil, tup).String(), `(0, false, ""):(int, bool, string)`; got != want {
    95  		t.Errorf("ssa.NewConst(%v, %s).String() = %v, want %v", nil, tup, got, want)
    96  	}
    97  
    98  	// Test type-param
    99  	gen := pkg.Scope().Lookup("gen")
   100  	tp := typeparams.ForSignature(gen.Type().(*types.Signature)).At(0)
   101  	if got, want := ssa.NewConst(nil, tp).String(), "0:T"; got != want {
   102  		t.Errorf("ssa.NewConst(%v, %s).String() = %v, want %v", nil, tup, got, want)
   103  	}
   104  }