@@ -20,6 +20,7 @@ type Importer struct {
20
20
importHandler func (path , src , dir string )
21
21
isCommentLocator bool
22
22
ctx build.Context
23
+ gopath []string
23
24
}
24
25
25
26
// NewImporter creates a new importer
@@ -32,7 +33,8 @@ func NewImporter(options ...Option) *Importer {
32
33
errorHandler : func (err error ) {
33
34
return
34
35
},
35
- ctx : build .Default ,
36
+ ctx : build .Default ,
37
+ gopath : filepath .SplitList (build .Default .GOPATH ),
36
38
}
37
39
for _ , v := range options {
38
40
v (i )
@@ -46,7 +48,7 @@ func (i *Importer) ImportPackage(path string, pkg *ast.Package) (Type, error) {
46
48
if ok {
47
49
return t , nil
48
50
}
49
- np := newParser (i , i .isCommentLocator , path , false )
51
+ np := newParser (i , i .isCommentLocator , "" , path , false )
50
52
t = np .ParsePackage (pkg )
51
53
i .bufType [path ] = t
52
54
return t , nil
@@ -58,7 +60,7 @@ func (i *Importer) ImportFile(path string, f *ast.File) (Type, error) {
58
60
if ok {
59
61
return t , nil
60
62
}
61
- np := newParser (i , i .isCommentLocator , path , false )
63
+ np := newParser (i , i .isCommentLocator , "" , path , false )
62
64
t = np .ParseFile (f )
63
65
i .bufType [path ] = t
64
66
return t , nil
@@ -79,28 +81,52 @@ func (i *Importer) FileSet() *token.FileSet {
79
81
}
80
82
81
83
func (i * Importer ) importPath (path string , src string ) (string , string , error ) {
82
- if filepath .HasPrefix (path , ". " ) {
83
- pwd , err := os . Getwd ( )
84
+ if ! filepath .HasPrefix (src , "/ " ) {
85
+ abs , err := filepath . Abs ( src )
84
86
if err != nil {
85
87
return "" , "" , err
86
88
}
87
- src = pwd
88
- } else {
89
- if filepath .HasPrefix (src , "." ) {
90
- pwd , err := os .Getwd ()
91
- if err != nil {
92
- return "" , "" , err
89
+ src = abs
90
+ }
91
+
92
+ // If modules are not enabled, then the in-process code works fine and we should keep using it.
93
+ switch os .Getenv ("GO111MODULE" ) {
94
+ case "off" :
95
+ return path , src , nil
96
+ case "on" :
97
+ // ok
98
+ default : // "", "auto", anything else
99
+ // Automatic mode: no module use in $GOPATH/src.
100
+ for _ , root := range i .gopath {
101
+ if filepath .HasPrefix (src , filepath .Join (root , "src" )) {
102
+ return path , src , nil
93
103
}
94
- src = filepath .Join (pwd , src )
95
- } else {
96
- src = filepath .Clean (src )
97
104
}
98
- if ! filepath .HasPrefix (src , "/" ) {
99
- gopath := filepath .Join (i .ctx .GOPATH , "src" )
100
- src = filepath .Join (gopath , src )
105
+ }
106
+
107
+ for _ , root := range i .gopath {
108
+ if filepath .HasPrefix (src , filepath .Join (root , "pkg" , "mod" )) {
109
+ src , _ = os .Getwd ()
110
+ return path , src , nil
101
111
}
102
112
}
103
113
114
+ // Look to see if there is a go.mod.
115
+ abs := src
116
+ for {
117
+ info , err := os .Stat (filepath .Join (abs , "go.mod" ))
118
+ if err == nil && ! info .IsDir () {
119
+ break
120
+ }
121
+ d , _ := filepath .Split (abs )
122
+ if len (d ) >= len (abs ) {
123
+ return path , src , nil
124
+ }
125
+ abs = d
126
+ }
127
+
128
+ src = abs
129
+
104
130
return path , src , nil
105
131
}
106
132
@@ -171,7 +197,7 @@ func (i *Importer) Import(path string, src string) (Type, error) {
171
197
}
172
198
173
199
for _ , v := range p {
174
- np := newParser (i , i .isCommentLocator , imp .ImportPath , imp .Goroot )
200
+ np := newParser (i , i .isCommentLocator , dir , imp .ImportPath , imp .Goroot )
175
201
t := np .ParsePackage (v )
176
202
i .bufType [dir ] = t
177
203
return t , nil
0 commit comments