func readFileInfo()

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
}