@@ -2,15 +2,13 @@ package ruleguard
22
33import (
44 "fmt"
5- "go/ast "
5+ "go/build "
66 "go/importer"
7- "go/parser"
87 "go/token"
98 "go/types"
10- "path/filepath"
119 "runtime"
1210
13- "github.com/quasilyte/go-ruleguard/internal/golist "
11+ "github.com/quasilyte/go-ruleguard/internal/xsrcimporter "
1412)
1513
1614// goImporter is a `types.Importer` that tries to load a package no matter what.
@@ -23,7 +21,8 @@ type goImporter struct {
2321 defaultImporter types.Importer
2422 srcImporter types.Importer
2523
26- fset * token.FileSet
24+ fset * token.FileSet
25+ buildContext * build.Context
2726
2827 debugImports bool
2928 debugPrint func (string )
@@ -33,17 +32,20 @@ type goImporterConfig struct {
3332 fset * token.FileSet
3433 debugImports bool
3534 debugPrint func (string )
35+ buildContext * build.Context
3636}
3737
3838func newGoImporter (state * engineState , config goImporterConfig ) * goImporter {
39- return & goImporter {
39+ imp := & goImporter {
4040 state : state ,
4141 fset : config .fset ,
4242 debugImports : config .debugImports ,
4343 debugPrint : config .debugPrint ,
4444 defaultImporter : importer .Default (),
45- srcImporter : importer . ForCompiler ( config .fset , "source" , nil ) ,
45+ buildContext : config .buildContext ,
4646 }
47+ imp .initSourceImporter ()
48+ return imp
4749}
4850
4951func (imp * goImporter ) Import (path string ) (* types.Package , error ) {
@@ -54,63 +56,40 @@ func (imp *goImporter) Import(path string) (*types.Package, error) {
5456 return pkg , nil
5557 }
5658
57- pkg , err1 := imp .srcImporter .Import (path )
58- if err1 == nil {
59+ pkg , srcErr := imp .srcImporter .Import (path )
60+ if srcErr == nil {
5961 imp .state .AddCachedPackage (path , pkg )
6062 if imp .debugImports {
6163 imp .debugPrint (fmt .Sprintf (`imported "%s" from source importer` , path ))
6264 }
6365 return pkg , nil
6466 }
6567
66- pkg , err2 := imp .defaultImporter .Import (path )
67- if err2 == nil {
68+ pkg , defaultErr := imp .defaultImporter .Import (path )
69+ if defaultErr == nil {
6870 imp .state .AddCachedPackage (path , pkg )
6971 if imp .debugImports {
7072 imp .debugPrint (fmt .Sprintf (`imported "%s" from %s importer` , path , runtime .Compiler ))
7173 }
7274 return pkg , nil
7375 }
7476
75- // Fallback to `go list` as a last resort.
76- pkg , err3 := imp .golistImport (path )
77- if err3 == nil {
78- imp .state .AddCachedPackage (path , pkg )
79- if imp .debugImports {
80- imp .debugPrint (fmt .Sprintf (`imported "%s" from golist importer` , path ))
81- }
82- return pkg , nil
83- }
84-
8577 if imp .debugImports {
8678 imp .debugPrint (fmt .Sprintf (`failed to import "%s":` , path ))
87- imp .debugPrint (fmt .Sprintf (" source importer: %v" , err1 ))
88- imp .debugPrint (fmt .Sprintf (" %s importer: %v" , runtime . Compiler , err2 ))
89- imp .debugPrint (fmt .Sprintf (" golist importer: %v " , err3 ))
79+ imp .debugPrint (fmt .Sprintf (" %s importer: %v" , runtime . Compiler , defaultErr ))
80+ imp .debugPrint (fmt .Sprintf (" source importer: %v" , srcErr ))
81+ imp .debugPrint (fmt .Sprintf (" GOROOT=%q GOPATH=%q " , imp . buildContext . GOROOT , imp . buildContext . GOPATH ))
9082 }
9183
92- return nil , err2
84+ return nil , defaultErr
9385}
9486
95- func (imp * goImporter ) golistImport (path string ) (* types.Package , error ) {
96- golistPkg , err := golist .JSON (path )
97- if err != nil {
98- return nil , err
99- }
100-
101- files := make ([]* ast.File , 0 , len (golistPkg .GoFiles ))
102- for _ , filename := range golistPkg .GoFiles {
103- fullname := filepath .Join (golistPkg .Dir , filename )
104- f , err := parser .ParseFile (imp .fset , fullname , nil , 0 )
105- if err != nil {
106- return nil , err
87+ func (imp * goImporter ) initSourceImporter () {
88+ if imp .buildContext == nil {
89+ if imp .debugImports {
90+ imp .debugPrint ("using build.Default context" )
10791 }
108- files = append ( files , f )
92+ imp . buildContext = & build . Default
10993 }
110-
111- // TODO: do we want to assign imp as importer for this nested typecherker?
112- // Otherwise it won't be able to resolve imports.
113- var typecheker types.Config
114- var info types.Info
115- return typecheker .Check (path , imp .fset , files , & info )
94+ imp .srcImporter = xsrcimporter .New (imp .buildContext , imp .fset )
11695}
0 commit comments