golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/go/gcexportdata/example_test.go (about) 1 // Copyright 2016 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.7 && gc && !android && !ios && (unix || aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || plan9 || windows) 6 // +build go1.7 7 // +build gc 8 // +build !android 9 // +build !ios 10 // +build unix aix darwin dragonfly freebsd linux netbsd openbsd solaris plan9 windows 11 12 package gcexportdata_test 13 14 import ( 15 "fmt" 16 "go/ast" 17 "go/parser" 18 "go/token" 19 "go/types" 20 "log" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "golang.org/x/tools/go/gcexportdata" 26 ) 27 28 // ExampleRead uses gcexportdata.Read to load type information for the 29 // "fmt" package from the fmt.a file produced by the gc compiler. 30 func ExampleRead() { 31 // Find the export data file. 32 filename, path := gcexportdata.Find("fmt", "") 33 if filename == "" { 34 log.Fatalf("can't find export data for fmt") 35 } 36 fmt.Printf("Package path: %s\n", path) 37 38 // Open and read the file. 39 f, err := os.Open(filename) 40 if err != nil { 41 log.Fatal(err) 42 } 43 defer f.Close() 44 r, err := gcexportdata.NewReader(f) 45 if err != nil { 46 log.Fatalf("reading export data %s: %v", filename, err) 47 } 48 49 // Decode the export data. 50 fset := token.NewFileSet() 51 imports := make(map[string]*types.Package) 52 pkg, err := gcexportdata.Read(r, fset, imports, path) 53 if err != nil { 54 log.Fatal(err) 55 } 56 57 // We can see all the names in Names. 58 members := pkg.Scope().Names() 59 foundPrintln := false 60 for _, member := range members { 61 if member == "Println" { 62 foundPrintln = true 63 break 64 } 65 } 66 fmt.Print("Package members: ") 67 if foundPrintln { 68 fmt.Println("Println found") 69 } else { 70 fmt.Println("Println not found") 71 } 72 73 // We can also look up a name directly using Lookup. 74 println := pkg.Scope().Lookup("Println") 75 // go 1.18+ uses the 'any' alias 76 typ := strings.ReplaceAll(println.Type().String(), "interface{}", "any") 77 fmt.Printf("Println type: %s\n", typ) 78 posn := fset.Position(println.Pos()) 79 // make example deterministic 80 posn.Line = 123 81 fmt.Printf("Println location: %s\n", slashify(posn)) 82 83 // Output: 84 // 85 // Package path: fmt 86 // Package members: Println found 87 // Println type: func(a ...any) (n int, err error) 88 // Println location: $GOROOT/src/fmt/print.go:123:1 89 } 90 91 // ExampleNewImporter demonstrates usage of NewImporter to provide type 92 // information for dependencies when type-checking Go source code. 93 func ExampleNewImporter() { 94 const src = `package myrpc 95 96 // choosing a package that doesn't change across releases 97 import "net/rpc" 98 99 const serverError rpc.ServerError = "" 100 ` 101 fset := token.NewFileSet() 102 f, err := parser.ParseFile(fset, "myrpc.go", src, 0) 103 if err != nil { 104 log.Fatal(err) 105 } 106 107 packages := make(map[string]*types.Package) 108 imp := gcexportdata.NewImporter(fset, packages) 109 conf := types.Config{Importer: imp} 110 pkg, err := conf.Check("myrpc", fset, []*ast.File{f}, nil) 111 if err != nil { 112 log.Fatal(err) 113 } 114 115 // object from imported package 116 pi := packages["net/rpc"].Scope().Lookup("ServerError") 117 fmt.Printf("type %s.%s %s // %s\n", 118 pi.Pkg().Path(), 119 pi.Name(), 120 pi.Type().Underlying(), 121 slashify(fset.Position(pi.Pos())), 122 ) 123 124 // object in source package 125 twopi := pkg.Scope().Lookup("serverError") 126 fmt.Printf("const %s %s = %s // %s\n", 127 twopi.Name(), 128 twopi.Type(), 129 twopi.(*types.Const).Val(), 130 slashify(fset.Position(twopi.Pos())), 131 ) 132 133 // Output: 134 // 135 // type net/rpc.ServerError string // $GOROOT/src/net/rpc/client.go:20:1 136 // const serverError net/rpc.ServerError = "" // myrpc.go:6:7 137 } 138 139 func slashify(posn token.Position) token.Position { 140 posn.Filename = filepath.ToSlash(posn.Filename) // for MS Windows portability 141 return posn 142 }