|
6 | 6 | "go/build"
|
7 | 7 | "go/parser"
|
8 | 8 | "go/token"
|
| 9 | + "math" |
9 | 10 | "os"
|
10 | 11 | "path/filepath"
|
11 | 12 | "sort"
|
@@ -150,12 +151,16 @@ func findFileCreator(rootDir string) func(file string) (string, string, bool) {
|
150 | 151 | files := listAllFiles(rootDir)
|
151 | 152 | findFsSearch := func(file string) (string, string, bool) {
|
152 | 153 | noPrefixName := stripPrefix(file, prefix)
|
153 |
| - fPath := hasFile(files, noPrefixName) |
| 154 | + fPath := findFilePathMatchingSearch(&files, noPrefixName) |
154 | 155 |
|
155 | 156 | return path.NormalizeForOS(fPath), noPrefixName, fPath != ""
|
156 | 157 | }
|
157 | 158 |
|
158 | 159 | return func(fileName string) (string, string, bool) {
|
| 160 | + if fileName == "" { |
| 161 | + return "", "", false |
| 162 | + } |
| 163 | + |
159 | 164 | if path, name, found := findFsSearch(fileName); found {
|
160 | 165 | return path, name, found
|
161 | 166 | }
|
@@ -205,22 +210,41 @@ func listAllFiles(rootDir string) []fileInfo {
|
205 | 210 | return files
|
206 | 211 | }
|
207 | 212 |
|
208 |
| -func hasFile(files []fileInfo, search string) string { |
209 |
| - var result string |
210 |
| - |
211 |
| - for _, f := range files { |
212 |
| - if strings.HasSuffix(f.name, search) { |
213 |
| - if result != "" { |
214 |
| - // when multiple files are found with same suffix |
215 |
| - // assume file is not found (fallback mechanism will be used) |
216 |
| - return "" |
| 213 | +func findFilePathMatchingSearch(files *[]fileInfo, search string) string { |
| 214 | + // Finds file that best matches search. For example search file "foo.go" |
| 215 | + // matches files "bar/foo.go", "bar/baz/foo.go" and "foo.go", but it's the |
| 216 | + // best match with "foo.go". |
| 217 | + bestMatch := func() int { |
| 218 | + fIndex, searchPos := -1, math.MaxInt64 |
| 219 | + |
| 220 | + for i, f := range *files { |
| 221 | + pos := strings.LastIndex(f.name, search) |
| 222 | + if pos == -1 { |
| 223 | + continue |
217 | 224 | }
|
218 | 225 |
|
219 |
| - result = f.path |
| 226 | + if searchPos > pos { |
| 227 | + searchPos = pos |
| 228 | + fIndex = i |
| 229 | + |
| 230 | + if searchPos == 0 { // 100% match |
| 231 | + return fIndex |
| 232 | + } |
| 233 | + } |
220 | 234 | }
|
| 235 | + |
| 236 | + return fIndex |
221 | 237 | }
|
222 | 238 |
|
223 |
| - return result |
| 239 | + i := bestMatch() |
| 240 | + if i == -1 { |
| 241 | + return "" |
| 242 | + } |
| 243 | + |
| 244 | + path := (*files)[i].path |
| 245 | + *files = append((*files)[:i], (*files)[i+1:]...) |
| 246 | + |
| 247 | + return path |
224 | 248 | }
|
225 | 249 |
|
226 | 250 | func findAnnotations(source []byte) ([]extent, error) {
|
|
0 commit comments