1
2
3
4
5
6 package gcimporter
7
8 import (
9 "bufio"
10 "fmt"
11 "go/token"
12 "go/types"
13 "internal/exportdata"
14 "internal/pkgbits"
15 "internal/saferio"
16 "io"
17 "os"
18 "strings"
19 )
20
21
22
23
24 func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
25 var rc io.ReadCloser
26 var id string
27 if lookup != nil {
28
29
30 if path == "unsafe" {
31 return types.Unsafe, nil
32 }
33 id = path
34
35
36 if pkg = packages[id]; pkg != nil && pkg.Complete() {
37 return
38 }
39 f, err := lookup(path)
40 if err != nil {
41 return nil, err
42 }
43 rc = f
44 } else {
45 var filename string
46 filename, id, err = exportdata.FindPkg(path, srcDir)
47 if filename == "" {
48 if path == "unsafe" {
49 return types.Unsafe, nil
50 }
51 return nil, err
52 }
53
54
55 if pkg = packages[id]; pkg != nil && pkg.Complete() {
56 return
57 }
58
59
60 f, err := os.Open(filename)
61 if err != nil {
62 return nil, err
63 }
64 defer func() {
65 if err != nil {
66
67 err = fmt.Errorf("%s: %v", filename, err)
68 }
69 }()
70 rc = f
71 }
72 defer rc.Close()
73
74 buf := bufio.NewReader(rc)
75 hdr, size, err := exportdata.FindExportData(buf)
76 if err != nil {
77 return
78 }
79
80 switch hdr {
81 case "$$\n":
82 err = fmt.Errorf("import %q: old textual export format no longer supported (recompile package)", path)
83
84 case "$$B\n":
85 var exportFormat byte
86 if exportFormat, err = buf.ReadByte(); err != nil {
87 return
88 }
89 size--
90
91
92
93
94
95 switch exportFormat {
96 case 'u':
97 var data []byte
98 var r io.Reader = buf
99 if size >= 0 {
100 if data, err = saferio.ReadData(r, uint64(size)); err != nil {
101 return
102 }
103 } else if data, err = io.ReadAll(r); err != nil {
104 return
105 }
106 s := string(data)
107 s = s[:strings.LastIndex(s, "\n$$\n")]
108
109 input := pkgbits.NewPkgDecoder(id, s)
110 pkg = readUnifiedPackage(fset, nil, packages, input)
111 default:
112 err = fmt.Errorf("import %q: binary export format %q is no longer supported (recompile package)", path, exportFormat)
113 }
114
115 default:
116 err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr)
117 }
118
119 return
120 }
121
View as plain text