1
2
3
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
43 constant interface{}
44 want string
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
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(), " | ", "|")
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
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
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