|
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