...

Source file src/golang.org/x/tools/go/ssa/const_test.go

Documentation: golang.org/x/tools/go/ssa

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

View as plain text