@@ -125,13 +125,20 @@ func ImportDir(dir string, mode build.ImportMode, installSuffix string, buildTag
125
125
// The native packages are augmented by the contents of natives.FS in the following way.
126
126
// The file names do not matter except the usual `_test` suffix. The files for
127
127
// native overrides get added to the package (even if they have the same name
128
- // as an existing file from the standard library). For all identifiers that exist
129
- // in the original AND the overrides, the original identifier in the AST gets
130
- // replaced by `_`. New identifiers that don't exist in original package get added.
128
+ // as an existing file from the standard library). For function identifiers that exist
129
+ // in the original AND the overrides AND that include the following directive in their comment:
130
+ // //gopherjs:keep-original, the original identifier in the AST gets prefixed by
131
+ // `_gopherjs_original_`. For other identifiers that exist in the original AND the overrides,
132
+ // the original identifier gets replaced by `_`. New identifiers that don't exist in original
133
+ // package get added.
131
134
func parseAndAugment (xctx XContext , pkg * PackageData , isTest bool , fileSet * token.FileSet ) ([]* ast.File , []JSFile , error ) {
132
135
var files []* ast.File
133
- replacedDeclNames := make (map [string ]bool )
134
- pruneOriginalFuncs := make (map [string ]bool )
136
+
137
+ type overrideInfo struct {
138
+ keepOriginal bool
139
+ pruneOriginal bool
140
+ }
141
+ replacedDeclNames := make (map [string ]overrideInfo )
135
142
136
143
isXTest := strings .HasSuffix (pkg .ImportPath , "_test" )
137
144
importPath := pkg .ImportPath
@@ -170,18 +177,20 @@ func parseAndAugment(xctx XContext, pkg *PackageData, isTest bool, fileSet *toke
170
177
switch d := decl .(type ) {
171
178
case * ast.FuncDecl :
172
179
k := astutil .FuncKey (d )
173
- replacedDeclNames [k ] = true
174
- pruneOriginalFuncs [k ] = astutil .PruneOriginal (d )
180
+ replacedDeclNames [k ] = overrideInfo {
181
+ keepOriginal : astutil .KeepOriginal (d ),
182
+ pruneOriginal : astutil .PruneOriginal (d ),
183
+ }
175
184
case * ast.GenDecl :
176
185
switch d .Tok {
177
186
case token .TYPE :
178
187
for _ , spec := range d .Specs {
179
- replacedDeclNames [spec .(* ast.TypeSpec ).Name .Name ] = true
188
+ replacedDeclNames [spec .(* ast.TypeSpec ).Name .Name ] = overrideInfo {}
180
189
}
181
190
case token .VAR , token .CONST :
182
191
for _ , spec := range d .Specs {
183
192
for _ , name := range spec .(* ast.ValueSpec ).Names {
184
- replacedDeclNames [name .Name ] = true
193
+ replacedDeclNames [name .Name ] = overrideInfo {}
185
194
}
186
195
}
187
196
}
@@ -234,20 +243,26 @@ func parseAndAugment(xctx XContext, pkg *PackageData, isTest bool, fileSet *toke
234
243
switch d := decl .(type ) {
235
244
case * ast.FuncDecl :
236
245
k := astutil .FuncKey (d )
237
- if replacedDeclNames [k ] {
238
- d .Name = ast .NewIdent ("_" )
239
- if pruneOriginalFuncs [k ] {
246
+ if info , ok := replacedDeclNames [k ]; ok {
247
+ if info .pruneOriginal {
240
248
// Prune function bodies, since it may contain code invalid for
241
249
// GopherJS and pin unwanted imports.
242
250
d .Body = nil
243
251
}
252
+ if info .keepOriginal {
253
+ // Allow overridden function calls
254
+ // The standard library implementation of foo() becomes _gopherjs_original_foo()
255
+ d .Name .Name = "_gopherjs_original_" + d .Name .Name
256
+ } else {
257
+ d .Name = ast .NewIdent ("_" )
258
+ }
244
259
}
245
260
case * ast.GenDecl :
246
261
switch d .Tok {
247
262
case token .TYPE :
248
263
for _ , spec := range d .Specs {
249
264
s := spec .(* ast.TypeSpec )
250
- if replacedDeclNames [s .Name .Name ] {
265
+ if _ , ok := replacedDeclNames [s .Name .Name ]; ok {
251
266
s .Name = ast .NewIdent ("_" )
252
267
s .Type = & ast.StructType {Struct : s .Pos (), Fields : & ast.FieldList {}}
253
268
s .TypeParams = nil
@@ -257,7 +272,7 @@ func parseAndAugment(xctx XContext, pkg *PackageData, isTest bool, fileSet *toke
257
272
for _ , spec := range d .Specs {
258
273
s := spec .(* ast.ValueSpec )
259
274
for i , name := range s .Names {
260
- if replacedDeclNames [name .Name ] {
275
+ if _ , ok := replacedDeclNames [name .Name ]; ok {
261
276
s .Names [i ] = ast .NewIdent ("_" )
262
277
}
263
278
}
0 commit comments