github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/go/internal/gcimporter/iexport_go118_test.go (about) 1 // Copyright 2021 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 //go:build go1.18 6 // +build go1.18 7 8 package gcimporter_test 9 10 import ( 11 "bytes" 12 "go/ast" 13 "go/importer" 14 "go/parser" 15 "go/token" 16 "go/types" 17 "os" 18 "path/filepath" 19 "runtime" 20 "strings" 21 "testing" 22 23 "github.com/jhump/golang-x-tools/go/internal/gcimporter" 24 ) 25 26 // TODO(rfindley): migrate this to testdata, as has been done in the standard library. 27 func TestGenericExport(t *testing.T) { 28 const src = ` 29 package generic 30 31 type Any any 32 33 type T[A, B any] struct { Left A; Right B } 34 35 func (T[P, Q]) m() {} 36 37 var X T[int, string] = T[int, string]{1, "hi"} 38 39 func ToInt[P interface{ ~int }](p P) int { return int(p) } 40 41 var IntID = ToInt[int] 42 43 type G[C comparable] int 44 45 func ImplicitFunc[T ~int]() {} 46 47 type ImplicitType[T ~int] int 48 49 // Exercise constant import/export 50 const C1 = 42 51 const C2 int = 42 52 const C3 float64 = 42 53 54 type Constraint[T any] interface { 55 m(T) 56 } 57 58 // TODO(rfindley): revert to multiple blanks once the restriction on multiple 59 // blanks is removed from the type checker. 60 // type Blanks[_ any, _ Constraint[int]] int 61 // func (Blanks[_, _]) m() {} 62 type Blanks[_ any] int 63 func (Blanks[_]) m() {} 64 ` 65 testExportSrc(t, []byte(src)) 66 } 67 68 func testExportSrc(t *testing.T, src []byte) { 69 // This package only handles gc export data. 70 if runtime.Compiler != "gc" { 71 t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler) 72 } 73 74 // Test at both stages of the 1.18 export data format change. 75 tests := []struct { 76 name string 77 version int 78 }{ 79 {"legacy generics", gcimporter.IExportVersionGenerics}, 80 {"go1.18", gcimporter.IExportVersionGo1_18}, 81 } 82 83 for _, test := range tests { 84 t.Run(test.name, func(t *testing.T) { 85 fset := token.NewFileSet() 86 f, err := parser.ParseFile(fset, "g.go", src, 0) 87 if err != nil { 88 t.Fatal(err) 89 } 90 conf := types.Config{ 91 Importer: importer.Default(), 92 } 93 pkg, err := conf.Check("", fset, []*ast.File{f}, nil) 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 // export 99 data, err := iexport(fset, test.version, pkg) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 testPkgData(t, fset, test.version, pkg, data) 105 }) 106 } 107 } 108 109 func TestImportTypeparamTests(t *testing.T) { 110 // Check go files in test/typeparam. 111 rootDir := filepath.Join(runtime.GOROOT(), "test", "typeparam") 112 list, err := os.ReadDir(rootDir) 113 if err != nil { 114 t.Fatal(err) 115 } 116 117 if isUnifiedBuilder() { 118 t.Skip("unified export data format is currently unsupported") 119 } 120 121 skip := map[string]string{ 122 "issue48424.go": "go/types support missing", // TODO: need to implement this if #48424 is accepted 123 } 124 125 for _, entry := range list { 126 if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") { 127 // For now, only consider standalone go files. 128 continue 129 } 130 131 t.Run(entry.Name(), func(t *testing.T) { 132 if reason, ok := skip[entry.Name()]; ok { 133 t.Skip(reason) 134 } 135 136 filename := filepath.Join(rootDir, entry.Name()) 137 src, err := os.ReadFile(filename) 138 if err != nil { 139 t.Fatal(err) 140 } 141 142 if !bytes.HasPrefix(src, []byte("// run")) && !bytes.HasPrefix(src, []byte("// compile")) { 143 // We're bypassing the logic of run.go here, so be conservative about 144 // the files we consider in an attempt to make this test more robust to 145 // changes in test/typeparams. 146 t.Skipf("not detected as a run test") 147 } 148 149 testExportSrc(t, src) 150 }) 151 } 152 }