in go/tools/builders/filter.go [104:168]
func readFileInfo(bctx build.Context, input string) (fileInfo, error) {
fi := fileInfo{filename: input}
if ext := filepath.Ext(input); ext == ".C" {
fi.ext = cxxExt
} else {
switch strings.ToLower(ext) {
case ".go":
fi.ext = goExt
case ".c":
fi.ext = cExt
case ".cc", ".cxx", ".cpp":
fi.ext = cxxExt
case ".m":
fi.ext = objcExt
case ".mm":
fi.ext = objcxxExt
case ".s":
fi.ext = sExt
case ".h", ".hh", ".hpp", ".hxx":
fi.ext = hExt
default:
return fileInfo{}, fmt.Errorf("unrecognized file extension: %s", ext)
}
}
dir, base := filepath.Split(input)
// Check build constraints on non-cgo files.
// Skip cgo files, since they get rejected (due to leading '_') and won't
// have any build constraints anyway.
if strings.HasPrefix(base, "_cgo") {
fi.matched = true
} else {
match, err := bctx.MatchFile(dir, base)
if err != nil {
return fi, err
}
fi.matched = match
}
// If it's not a go file, there's nothing more to read.
if fi.ext != goExt {
return fi, nil
}
// Scan the file for imports and embeds.
f, err := os.Open(input)
if err != nil {
return fileInfo{}, err
}
defer f.Close()
fi.fset = token.NewFileSet()
if err := readGoInfo(f, &fi); err != nil {
return fileInfo{}, err
}
// Exclude cgo files if cgo is not enabled.
for _, imp := range fi.imports {
if imp.path == "C" {
fi.isCgo = true
break
}
}
fi.matched = fi.matched && (bctx.CgoEnabled || !fi.isCgo)
return fi, nil
}