github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/go/types/typestring_test.go (about) 1 // Copyright 2012 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 types_test 6 7 import ( 8 "go/ast" 9 "go/importer" 10 "go/parser" 11 "go/token" 12 "internal/testenv" 13 "testing" 14 15 . "go/types" 16 ) 17 18 const filename = "<src>" 19 20 func makePkg(t *testing.T, src string) (*Package, error) { 21 fset := token.NewFileSet() 22 file, err := parser.ParseFile(fset, filename, src, parser.DeclarationErrors) 23 if err != nil { 24 return nil, err 25 } 26 // use the package name as package path 27 conf := Config{Importer: importer.Default()} 28 return conf.Check(file.Name.Name, fset, []*ast.File{file}, nil) 29 } 30 31 type testEntry struct { 32 src, str string 33 } 34 35 // dup returns a testEntry where both src and str are the same. 36 func dup(s string) testEntry { 37 return testEntry{s, s} 38 } 39 40 // types that don't depend on any other type declarations 41 var independentTestTypes = []testEntry{ 42 // basic types 43 dup("int"), 44 dup("float32"), 45 dup("string"), 46 47 // arrays 48 dup("[10]int"), 49 50 // slices 51 dup("[]int"), 52 dup("[][]int"), 53 54 // structs 55 dup("struct{}"), 56 dup("struct{x int}"), 57 {`struct { 58 x, y int 59 z float32 "foo" 60 }`, `struct{x int; y int; z float32 "foo"}`}, 61 {`struct { 62 string 63 elems []complex128 64 }`, `struct{string; elems []complex128}`}, 65 66 // pointers 67 dup("*int"), 68 dup("***struct{}"), 69 dup("*struct{a int; b float32}"), 70 71 // functions 72 dup("func()"), 73 dup("func(x int)"), 74 {"func(x, y int)", "func(x int, y int)"}, 75 {"func(x, y int, z string)", "func(x int, y int, z string)"}, 76 dup("func(int)"), 77 {"func(int, string, byte)", "func(int, string, byte)"}, 78 79 dup("func() int"), 80 {"func() (string)", "func() string"}, 81 dup("func() (u int)"), 82 {"func() (u, v int, w string)", "func() (u int, v int, w string)"}, 83 84 dup("func(int) string"), 85 dup("func(x int) string"), 86 dup("func(x int) (u string)"), 87 {"func(x, y int) (u string)", "func(x int, y int) (u string)"}, 88 89 dup("func(...int) string"), 90 dup("func(x ...int) string"), 91 dup("func(x ...int) (u string)"), 92 {"func(x, y ...int) (u string)", "func(x int, y ...int) (u string)"}, 93 94 // interfaces 95 dup("interface{}"), 96 dup("interface{m()}"), 97 dup(`interface{String() string; m(int) float32}`), 98 99 // maps 100 dup("map[string]int"), 101 {"map[struct{x, y int}][]byte", "map[struct{x int; y int}][]byte"}, 102 103 // channels 104 dup("chan<- chan int"), 105 dup("chan<- <-chan int"), 106 dup("<-chan <-chan int"), 107 dup("chan (<-chan int)"), 108 dup("chan<- func()"), 109 dup("<-chan []func() int"), 110 } 111 112 // types that depend on other type declarations (src in TestTypes) 113 var dependentTestTypes = []testEntry{ 114 // interfaces 115 dup(`interface{io.Reader; io.Writer}`), 116 dup(`interface{m() int; io.Writer}`), 117 {`interface{m() interface{T}}`, `interface{m() interface{p.T}}`}, 118 } 119 120 func TestTypeString(t *testing.T) { 121 testenv.MustHaveGoBuild(t) 122 123 var tests []testEntry 124 tests = append(tests, independentTestTypes...) 125 tests = append(tests, dependentTestTypes...) 126 127 for _, test := range tests { 128 src := `package p; import "io"; type _ io.Writer; type T ` + test.src 129 pkg, err := makePkg(t, src) 130 if err != nil { 131 t.Errorf("%s: %s", src, err) 132 continue 133 } 134 typ := pkg.Scope().Lookup("T").Type().Underlying() 135 if got := typ.String(); got != test.str { 136 t.Errorf("%s: got %s, want %s", test.src, got, test.str) 137 } 138 } 139 } 140 141 func TestQualifiedTypeString(t *testing.T) { 142 p, _ := pkgFor("p.go", "package p; type T int", nil) 143 q, _ := pkgFor("q.go", "package q", nil) 144 145 pT := p.Scope().Lookup("T").Type() 146 for _, test := range []struct { 147 typ Type 148 this *Package 149 want string 150 }{ 151 {nil, nil, "<nil>"}, 152 {pT, nil, "p.T"}, 153 {pT, p, "T"}, 154 {pT, q, "p.T"}, 155 {NewPointer(pT), p, "*T"}, 156 {NewPointer(pT), q, "*p.T"}, 157 } { 158 qualifier := func(pkg *Package) string { 159 if pkg != test.this { 160 return pkg.Name() 161 } 162 return "" 163 } 164 if got := TypeString(test.typ, qualifier); got != test.want { 165 t.Errorf("TypeString(%s, %s) = %s, want %s", 166 test.this, test.typ, got, test.want) 167 } 168 } 169 }