@@ -138,16 +138,68 @@ type overrideInfo struct {
138
138
overrideSignature * ast.FuncDecl
139
139
}
140
140
141
+ // pkgOverrideInfo is the collection of overrides still needed for a package.
142
+ //
143
+ // Even after the overrides are applied to the files of a package and the
144
+ // overrides map is empty, this will be kept to indicate that a package has
145
+ // already been augmented so that the additional native information is not
146
+ // re-applied when there is a file from this package parsed after all the
147
+ // overrides are empty.
141
148
type pkgOverrideInfo struct {
149
+ // overrides is a map of identifier to overrideInfo to override
150
+ // individual named structs, interfaces, functions, and methods.
151
+ // As identifiers are used, they will be removed from this map.
142
152
overrides map [string ]overrideInfo
153
+
154
+ jsFiles []JSFile
143
155
}
144
156
157
+ // Augmentor is an on-the-fly package augmentor.
158
+ //
159
+ // When a file from a package is being parsed, the Augmentor will augment
160
+ // the AST with the changes loaded from the native overrides.
161
+ // The augmentor will hold onto the override information for additional files
162
+ // that come from the same package. This is designed to be used with
163
+ // `x/tools/go/packages.Load` as a middleware in the parse file step via
164
+ // `Config.ParseFile`.
165
+ //
166
+ // The first file from a package will have any additional methods and
167
+ // information from the natives injected into the AST. All files from a package
168
+ // will be augmented by the overrides. After augmentation of a whole package,
169
+ // the overrides should be empty, but might not be if the natives contain
170
+ // overrides for methods that no longer exist.
145
171
type Augmentor struct {
172
+ xctx XContext
173
+
174
+ // packages is a map of package import path to the package's override.
175
+ // This is used to keep track of the overrides for a package and indicate
176
+ // that additional files from the natives have already been applied.
146
177
packages map [string ]* pkgOverrideInfo
147
178
}
148
179
149
- func (aug * Augmentor ) Augment (fset * token.FileSet , filename string , src * ast.File ) error {
180
+ func (aug * Augmentor ) Augment (fileSet * token.FileSet , filename string , src * ast.File ) error {
150
181
pkgName := src .Name .Name
182
+ importPath := pkgName // TODO: Determine unique import path for the package.
183
+
184
+ pkgAug , ok := aug .packages [importPath ]
185
+ if ! ok {
186
+ if aug .packages == nil {
187
+ aug .packages = map [string ]* pkgOverrideInfo {}
188
+ }
189
+ jsFiles , overlayFiles := parseOverlayFiles (xctx , pkg , fileSet )
190
+
191
+ overrides := make (map [string ]overrideInfo )
192
+ for _ , file := range overlayFiles {
193
+ augmentOverlayFile (file , overrides )
194
+ }
195
+ delete (overrides , `init` )
196
+
197
+ pkgAug = & pkgOverrideInfo {
198
+ overrides : overrides ,
199
+ jsFiles : jsFiles ,
200
+ }
201
+ aug .packages [importPath ] = pkgAug
202
+ }
151
203
152
204
return nil
153
205
}
@@ -180,14 +232,12 @@ func (aug *Augmentor) Augment(fset *token.FileSet, filename string, src *ast.Fil
180
232
// the original is removed.
181
233
// - New identifiers that don't exist in original package get added.
182
234
func parseAndAugment (xctx XContext , pkg * PackageData , fileSet * token.FileSet ) ([]* ast.File , []JSFile , error ) {
183
- isTest := pkg .IsTest
184
- jsFiles , overlayFiles := parseOverlayFiles (xctx , pkg , isTest , fileSet )
185
-
186
235
originalFiles , err := parserOriginalFiles (pkg , fileSet )
187
236
if err != nil {
188
237
return nil , nil , err
189
238
}
190
239
240
+ jsFiles , overlayFiles := parseOverlayFiles (xctx , pkg , fileSet )
191
241
overrides := make (map [string ]overrideInfo )
192
242
for _ , file := range overlayFiles {
193
243
augmentOverlayFile (file , overrides )
@@ -209,7 +259,7 @@ func parseAndAugment(xctx XContext, pkg *PackageData, fileSet *token.FileSet) ([
209
259
210
260
// parseOverlayFiles loads and parses overlay files
211
261
// to augment the original files with.
212
- func parseOverlayFiles (xctx XContext , pkg * PackageData , isTest bool , fileSet * token.FileSet ) ([]JSFile , []* ast.File ) {
262
+ func parseOverlayFiles (xctx XContext , pkg * PackageData , fileSet * token.FileSet ) ([]JSFile , []* ast.File ) {
213
263
importPath := pkg .ImportPath
214
264
isXTest := strings .HasSuffix (importPath , "_test" )
215
265
if isXTest {
@@ -225,7 +275,7 @@ func parseOverlayFiles(xctx XContext, pkg *PackageData, isTest bool, fileSet *to
225
275
jsFiles := nativesPkg .JSFiles
226
276
var files []* ast.File
227
277
names := nativesPkg .GoFiles
228
- if isTest {
278
+ if pkg . IsTest {
229
279
names = append (names , nativesPkg .TestGoFiles ... )
230
280
}
231
281
if isXTest {
0 commit comments