@@ -26,7 +26,6 @@ import (
26
26
"golang.org/x/tools/go/internal/packagesdriver"
27
27
"golang.org/x/tools/internal/gopathwalk"
28
28
"golang.org/x/tools/internal/semver"
29
- "golang.org/x/tools/internal/span"
30
29
)
31
30
32
31
// debug controls verbose logging.
@@ -287,42 +286,43 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
287
286
return fmt .Errorf ("could not determine absolute path of file= query path %q: %v" , query , err )
288
287
}
289
288
dirResponse , err := driver (cfg , pattern )
290
- if err != nil {
289
+ if err != nil || (len (dirResponse .Packages ) == 1 && len (dirResponse .Packages [0 ].Errors ) == 1 ) {
290
+ // There was an error loading the package. Try to load the file as an ad-hoc package.
291
+ // Usually the error will appear in a returned package, but may not if we're in modules mode
292
+ // and the ad-hoc is located outside a module.
291
293
var queryErr error
292
- if dirResponse , queryErr = adHocPackage (cfg , driver , pattern , query ); queryErr != nil {
293
- return err // return the original error
294
+ dirResponse , queryErr = driver (cfg , query )
295
+ if queryErr != nil {
296
+ // Return the original error if the attempt to fall back failed.
297
+ return err
294
298
}
295
- }
296
- // `go list` can report errors for files that are not listed as part of a package's GoFiles.
297
- // In the case of an invalid Go file, we should assume that it is part of package if only
298
- // one package is in the response. The file may have valid contents in an overlay.
299
- if len (dirResponse .Packages ) == 1 {
300
- pkg := dirResponse .Packages [0 ]
301
- for i , err := range pkg .Errors {
302
- s := errorSpan (err )
303
- if ! s .IsValid () {
304
- break
305
- }
306
- if len (pkg .CompiledGoFiles ) == 0 {
307
- break
308
- }
309
- dir := filepath .Dir (pkg .CompiledGoFiles [0 ])
310
- filename := filepath .Join (dir , filepath .Base (s .URI ().Filename ()))
311
- if info , err := os .Stat (filename ); err != nil || info .IsDir () {
312
- break
313
- }
314
- if ! contains (pkg .CompiledGoFiles , filename ) {
315
- pkg .CompiledGoFiles = append (pkg .CompiledGoFiles , filename )
316
- pkg .GoFiles = append (pkg .GoFiles , filename )
317
- pkg .Errors = append (pkg .Errors [:i ], pkg .Errors [i + 1 :]... )
318
- }
299
+ // If we get nothing back from `go list`, try to make this file into its own ad-hoc package.
300
+ if len (dirResponse .Packages ) == 0 && queryErr == nil {
301
+ dirResponse .Packages = append (dirResponse .Packages , & Package {
302
+ ID : "command-line-arguments" ,
303
+ PkgPath : query ,
304
+ GoFiles : []string {query },
305
+ CompiledGoFiles : []string {query },
306
+ Imports : make (map [string ]* Package ),
307
+ })
308
+ dirResponse .Roots = append (dirResponse .Roots , "command-line-arguments" )
319
309
}
320
- }
321
- // A final attempt to construct an ad-hoc package.
322
- if len (dirResponse .Packages ) == 1 && len (dirResponse .Packages [0 ].Errors ) == 1 {
323
- var queryErr error
324
- if dirResponse , queryErr = adHocPackage (cfg , driver , pattern , query ); queryErr != nil {
325
- return err // return the original error
310
+ // Special case to handle issue #33482:
311
+ // If this is a file= query for ad-hoc packages where the file only exists on an overlay,
312
+ // and exists outside of a module, add the file in for the package.
313
+ if len (dirResponse .Packages ) == 1 && (dirResponse .Packages [0 ].ID == "command-line-arguments" ||
314
+ filepath .ToSlash (dirResponse .Packages [0 ].PkgPath ) == filepath .ToSlash (query )) {
315
+ if len (dirResponse .Packages [0 ].GoFiles ) == 0 {
316
+ filename := filepath .Join (pattern , filepath .Base (query )) // avoid recomputing abspath
317
+ // TODO(matloob): check if the file is outside of a root dir?
318
+ for path := range cfg .Overlay {
319
+ if path == filename {
320
+ dirResponse .Packages [0 ].Errors = nil
321
+ dirResponse .Packages [0 ].GoFiles = []string {path }
322
+ dirResponse .Packages [0 ].CompiledGoFiles = []string {path }
323
+ }
324
+ }
325
+ }
326
326
}
327
327
}
328
328
isRoot := make (map [string ]bool , len (dirResponse .Roots ))
@@ -350,74 +350,6 @@ func runContainsQueries(cfg *Config, driver driver, response *responseDeduper, q
350
350
return nil
351
351
}
352
352
353
- // adHocPackage attempts to construct an ad-hoc package given a query that failed.
354
- func adHocPackage (cfg * Config , driver driver , pattern , query string ) (* driverResponse , error ) {
355
- // There was an error loading the package. Try to load the file as an ad-hoc package.
356
- // Usually the error will appear in a returned package, but may not if we're in modules mode
357
- // and the ad-hoc is located outside a module.
358
- dirResponse , err := driver (cfg , query )
359
- if err != nil {
360
- return nil , err
361
- }
362
- // If we get nothing back from `go list`, try to make this file into its own ad-hoc package.
363
- if len (dirResponse .Packages ) == 0 && err == nil {
364
- dirResponse .Packages = append (dirResponse .Packages , & Package {
365
- ID : "command-line-arguments" ,
366
- PkgPath : query ,
367
- GoFiles : []string {query },
368
- CompiledGoFiles : []string {query },
369
- Imports : make (map [string ]* Package ),
370
- })
371
- dirResponse .Roots = append (dirResponse .Roots , "command-line-arguments" )
372
- }
373
- // Special case to handle issue #33482:
374
- // If this is a file= query for ad-hoc packages where the file only exists on an overlay,
375
- // and exists outside of a module, add the file in for the package.
376
- if len (dirResponse .Packages ) == 1 && (dirResponse .Packages [0 ].ID == "command-line-arguments" || dirResponse .Packages [0 ].PkgPath == filepath .ToSlash (query )) {
377
- if len (dirResponse .Packages [0 ].GoFiles ) == 0 {
378
- filename := filepath .Join (pattern , filepath .Base (query )) // avoid recomputing abspath
379
- // TODO(matloob): check if the file is outside of a root dir?
380
- for path := range cfg .Overlay {
381
- if path == filename {
382
- dirResponse .Packages [0 ].Errors = nil
383
- dirResponse .Packages [0 ].GoFiles = []string {path }
384
- dirResponse .Packages [0 ].CompiledGoFiles = []string {path }
385
- }
386
- }
387
- }
388
- }
389
- return dirResponse , nil
390
- }
391
-
392
- func contains (files []string , filename string ) bool {
393
- for _ , f := range files {
394
- if f == filename {
395
- return true
396
- }
397
- }
398
- return false
399
- }
400
-
401
- // errorSpan attempts to parse a standard `go list` error message
402
- // by stripping off the trailing error message.
403
- //
404
- // It works only on errors whose message is prefixed by colon,
405
- // followed by a space (": "). For example:
406
- //
407
- // attributes.go:13:1: expected 'package', found 'type'
408
- //
409
- func errorSpan (err Error ) span.Span {
410
- if err .Pos == "" {
411
- input := strings .TrimSpace (err .Msg )
412
- msgIndex := strings .Index (input , ": " )
413
- if msgIndex < 0 {
414
- return span .Parse (input )
415
- }
416
- return span .Parse (input [:msgIndex ])
417
- }
418
- return span .Parse (err .Pos )
419
- }
420
-
421
353
// modCacheRegexp splits a path in a module cache into module, module version, and package.
422
354
var modCacheRegexp = regexp .MustCompile (`(.*)@([^/\\]*)(.*)` )
423
355
0 commit comments