@@ -18,7 +18,6 @@ import (
18
18
"github.com/gopherjs/gopherjs/compiler/internal/typeparams"
19
19
"github.com/gopherjs/gopherjs/compiler/typesutil"
20
20
"github.com/gopherjs/gopherjs/internal/experiments"
21
- "github.com/neelance/astrewrite"
22
21
"golang.org/x/tools/go/gcexportdata"
23
22
"golang.org/x/tools/go/types/typeutil"
24
23
)
@@ -108,34 +107,20 @@ type flowData struct {
108
107
endCase int
109
108
}
110
109
110
+ // ImportContext provides access to information about imported packages.
111
111
type ImportContext struct {
112
+ // Mapping for an absolute import path to the package type information.
112
113
Packages map [string ]* types.Package
113
- Import func (string ) (* Archive , error )
114
- }
115
-
116
- // packageImporter implements go/types.Importer interface.
117
- type packageImporter struct {
118
- importContext * ImportContext
119
- importError * error // A pointer to importError in Compile.
120
- }
121
-
122
- func (pi packageImporter ) Import (path string ) (* types.Package , error ) {
123
- if path == "unsafe" {
124
- return types .Unsafe , nil
125
- }
126
-
127
- a , err := pi .importContext .Import (path )
128
- if err != nil {
129
- if * pi .importError == nil {
130
- // If import failed, show first error of import only (https://github.com/gopherjs/gopherjs/issues/119).
131
- * pi .importError = err
132
- }
133
- return nil , err
134
- }
135
-
136
- return pi .importContext .Packages [a .ImportPath ], nil
114
+ // Import returns a previously compiled Archive for a dependency package. If
115
+ // the Import() call was successful, the corresponding entry must be added to
116
+ // the Packages map.
117
+ Import func (importPath string ) (* Archive , error )
137
118
}
138
119
120
+ // Compile the provided Go sources as a single package.
121
+ //
122
+ // Import path must be the absolute import path for a package. Provided sources
123
+ // are always sorted by name to ensure reproducible JavaScript output.
139
124
func Compile (importPath string , files []* ast.File , fileSet * token.FileSet , importContext * ImportContext , minify bool ) (_ * Archive , err error ) {
140
125
defer func () {
141
126
e := recover ()
@@ -152,89 +137,29 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
152
137
err = bailout (fmt .Errorf ("unexpected compiler panic while building package %q: %v" , importPath , e ))
153
138
}()
154
139
155
- // Files must be in the same order to get reproducible JS
156
- sort .Slice (files , func (i , j int ) bool {
157
- return fileSet .File (files [i ].Pos ()).Name () > fileSet .File (files [j ].Pos ()).Name ()
158
- })
159
-
160
- typesInfo := & types.Info {
161
- Types : make (map [ast.Expr ]types.TypeAndValue ),
162
- Defs : make (map [* ast.Ident ]types.Object ),
163
- Uses : make (map [* ast.Ident ]types.Object ),
164
- Implicits : make (map [ast.Node ]types.Object ),
165
- Selections : make (map [* ast.SelectorExpr ]* types.Selection ),
166
- Scopes : make (map [ast.Node ]* types.Scope ),
167
- Instances : make (map [* ast.Ident ]types.Instance ),
168
- }
169
-
170
- var errList ErrorList
171
-
172
- // Extract all go:linkname compiler directives from the package source.
173
- goLinknames := []GoLinkname {}
174
- for _ , file := range files {
175
- found , err := parseGoLinknames (fileSet , importPath , file )
176
- if err != nil {
177
- if errs , ok := err .(ErrorList ); ok {
178
- errList = append (errList , errs ... )
179
- } else {
180
- errList = append (errList , err )
181
- }
182
- }
183
- goLinknames = append (goLinknames , found ... )
184
- }
140
+ srcs := sources {
141
+ ImportPath : importPath ,
142
+ Files : files ,
143
+ FileSet : fileSet ,
144
+ }.Sort ()
185
145
186
- var importError error
187
- var previousErr error
188
- config := & types.Config {
189
- Context : types .NewContext (),
190
- Importer : packageImporter {
191
- importContext : importContext ,
192
- importError : & importError ,
193
- },
194
- Sizes : sizes32 ,
195
- Error : func (err error ) {
196
- if previousErr != nil && previousErr .Error () == err .Error () {
197
- return
198
- }
199
- errList = append (errList , err )
200
- previousErr = err
201
- },
202
- }
203
- typesPkg , err := config .Check (importPath , fileSet , files , typesInfo )
204
- if importError != nil {
205
- return nil , importError
206
- }
207
- if errList != nil {
208
- if len (errList ) > 10 {
209
- pos := token .NoPos
210
- if last , ok := errList [9 ].(types.Error ); ok {
211
- pos = last .Pos
212
- }
213
- errList = append (errList [:10 ], types.Error {Fset : fileSet , Pos : pos , Msg : "too many errors" })
214
- }
215
- return nil , errList
216
- }
146
+ tContext := types .NewContext ()
147
+ typesInfo , typesPkg , err := srcs .TypeCheck (importContext , tContext )
217
148
if err != nil {
218
149
return nil , err
219
150
}
220
151
if genErr := typeparams .RequiresGenericsSupport (typesInfo ); genErr != nil && ! experiments .Env .Generics {
221
152
return nil , fmt .Errorf ("package %s requires generics support (https://github.com/gopherjs/gopherjs/issues/1013): %w" , importPath , genErr )
222
153
}
223
- importContext .Packages [importPath ] = typesPkg
154
+ importContext .Packages [srcs . ImportPath ] = typesPkg
224
155
225
- exportData := new (bytes.Buffer )
226
- if err := gcexportdata .Write (exportData , nil , typesPkg ); err != nil {
227
- return nil , fmt .Errorf ("failed to write export data: %v" , err )
228
- }
229
- encodedFileSet := new (bytes.Buffer )
230
- if err := fileSet .Write (json .NewEncoder (encodedFileSet ).Encode ); err != nil {
156
+ // Extract all go:linkname compiler directives from the package source.
157
+ goLinknames , err := srcs .ParseGoLinknames ()
158
+ if err != nil {
231
159
return nil , err
232
160
}
233
161
234
- simplifiedFiles := make ([]* ast.File , len (files ))
235
- for i , file := range files {
236
- simplifiedFiles [i ] = astrewrite .Simplify (file , typesInfo , false )
237
- }
162
+ srcs = srcs .Simplified (typesInfo )
238
163
239
164
isBlocking := func (f * types.Func ) bool {
240
165
archive , err := importContext .Import (f .Pkg ().Path ())
@@ -251,31 +176,31 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
251
176
}
252
177
253
178
tc := typeparams.Collector {
254
- TContext : config . Context ,
179
+ TContext : tContext ,
255
180
Info : typesInfo ,
256
181
Instances : & typeparams.PackageInstanceSets {},
257
182
}
258
- tc .Scan (typesPkg , simplifiedFiles ... )
183
+ tc .Scan (typesPkg , srcs . Files ... )
259
184
instancesByObj := map [types.Object ][]typeparams.Instance {}
260
185
for _ , inst := range tc .Instances .Pkg (typesPkg ).Values () {
261
186
instancesByObj [inst .Object ] = append (instancesByObj [inst .Object ], inst )
262
187
}
263
188
264
- pkgInfo := analysis .AnalyzePkg (simplifiedFiles , fileSet , typesInfo , typesPkg , isBlocking )
189
+ pkgInfo := analysis .AnalyzePkg (srcs . Files , fileSet , typesInfo , typesPkg , isBlocking )
265
190
funcCtx := & funcContext {
266
191
FuncInfo : pkgInfo .InitFuncInfo ,
267
192
pkgCtx : & pkgContext {
268
193
Info : pkgInfo ,
269
194
additionalSelections : make (map [* ast.SelectorExpr ]typesutil.Selection ),
270
195
271
- typesCtx : config . Context ,
196
+ typesCtx : tContext ,
272
197
pkgVars : make (map [string ]string ),
273
198
varPtrNames : make (map [* types.Var ]string ),
274
199
escapingVars : make (map [* types.Var ]bool ),
275
200
indentation : 1 ,
276
201
dependencies : make (map [types.Object ]bool ),
277
202
minify : minify ,
278
- fileSet : fileSet ,
203
+ fileSet : srcs . FileSet ,
279
204
instanceSet : tc .Instances ,
280
205
},
281
206
allVars : make (map [string ]int ),
@@ -315,7 +240,7 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
315
240
316
241
var functions []* ast.FuncDecl
317
242
var vars []* types.Var
318
- for _ , file := range simplifiedFiles {
243
+ for _ , file := range srcs . Files {
319
244
for _ , decl := range file .Decls {
320
245
switch d := decl .(type ) {
321
246
case * ast.FuncDecl :
@@ -669,8 +594,17 @@ func Compile(importPath string, files []*ast.File, fileSet *token.FileSet, impor
669
594
return nil , funcCtx .pkgCtx .errList
670
595
}
671
596
597
+ exportData := new (bytes.Buffer )
598
+ if err := gcexportdata .Write (exportData , nil , typesPkg ); err != nil {
599
+ return nil , fmt .Errorf ("failed to write export data: %w" , err )
600
+ }
601
+ encodedFileSet := new (bytes.Buffer )
602
+ if err := srcs .FileSet .Write (json .NewEncoder (encodedFileSet ).Encode ); err != nil {
603
+ return nil , err
604
+ }
605
+
672
606
return & Archive {
673
- ImportPath : importPath ,
607
+ ImportPath : srcs . ImportPath ,
674
608
Name : typesPkg .Name (),
675
609
Imports : importedPaths ,
676
610
ExportData : exportData .Bytes (),
0 commit comments