xref: /aosp_15_r20/external/bazelbuild-rules_go/go/tools/builders/filter.go (revision 9bb1b549b6a84214c53be0924760be030e66b93a)
1// Copyright 2017 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package main
16
17import (
18	"fmt"
19	"go/ast"
20	"go/build"
21	"go/token"
22	"os"
23	"path/filepath"
24	"strings"
25)
26
27type fileInfo struct {
28	filename string
29	ext      ext
30	header   []byte
31	fset     *token.FileSet
32	parsed   *ast.File
33	parseErr error
34	matched  bool
35	isCgo    bool
36	pkg      string
37	imports  []fileImport
38	embeds   []fileEmbed
39}
40
41type ext int
42
43const (
44	goExt ext = iota
45	cExt
46	cxxExt
47	objcExt
48	objcxxExt
49	sExt
50	hExt
51)
52
53type fileImport struct {
54	path string
55	pos  token.Pos
56	doc  *ast.CommentGroup
57}
58
59type fileEmbed struct {
60	pattern string
61	pos     token.Position
62}
63
64type archiveSrcs struct {
65	goSrcs, cSrcs, cxxSrcs, objcSrcs, objcxxSrcs, sSrcs, hSrcs []fileInfo
66}
67
68// filterAndSplitFiles filters files using build constraints and collates
69// them by extension.
70func filterAndSplitFiles(fileNames []string) (archiveSrcs, error) {
71	var res archiveSrcs
72	for _, s := range fileNames {
73		src, err := readFileInfo(build.Default, s)
74		if err != nil {
75			return archiveSrcs{}, err
76		}
77		if !src.matched {
78			continue
79		}
80		var srcs *[]fileInfo
81		switch src.ext {
82		case goExt:
83			srcs = &res.goSrcs
84		case cExt:
85			srcs = &res.cSrcs
86		case cxxExt:
87			srcs = &res.cxxSrcs
88		case objcExt:
89			srcs = &res.objcSrcs
90		case objcxxExt:
91			srcs = &res.objcxxSrcs
92		case sExt:
93			srcs = &res.sSrcs
94		case hExt:
95			srcs = &res.hSrcs
96		}
97		*srcs = append(*srcs, src)
98	}
99	return res, nil
100}
101
102// readFileInfo applies build constraints to an input file and returns whether
103// it should be compiled.
104func readFileInfo(bctx build.Context, input string) (fileInfo, error) {
105	fi := fileInfo{filename: input}
106	if ext := filepath.Ext(input); ext == ".C" {
107		fi.ext = cxxExt
108	} else {
109		switch strings.ToLower(ext) {
110		case ".go":
111			fi.ext = goExt
112		case ".c":
113			fi.ext = cExt
114		case ".cc", ".cxx", ".cpp":
115			fi.ext = cxxExt
116		case ".m":
117			fi.ext = objcExt
118		case ".mm":
119			fi.ext = objcxxExt
120		case ".s":
121			fi.ext = sExt
122		case ".h", ".hh", ".hpp", ".hxx":
123			fi.ext = hExt
124		default:
125			return fileInfo{}, fmt.Errorf("unrecognized file extension: %s", ext)
126		}
127	}
128
129	dir, base := filepath.Split(input)
130	// Check build constraints on non-cgo files.
131	// Skip cgo files, since they get rejected (due to leading '_') and won't
132	// have any build constraints anyway.
133	if strings.HasPrefix(base, "_cgo") {
134		fi.matched = true
135	} else {
136		match, err := bctx.MatchFile(dir, base)
137		if err != nil {
138			return fi, err
139		}
140		fi.matched = match
141	}
142	// If it's not a go file, there's nothing more to read.
143	if fi.ext != goExt {
144		return fi, nil
145	}
146
147	// Scan the file for imports and embeds.
148	f, err := os.Open(input)
149	if err != nil {
150		return fileInfo{}, err
151	}
152	defer f.Close()
153	fi.fset = token.NewFileSet()
154	if err := readGoInfo(f, &fi); err != nil {
155		return fileInfo{}, err
156	}
157
158	// Exclude cgo files if cgo is not enabled.
159	for _, imp := range fi.imports {
160		if imp.path == "C" {
161			fi.isCgo = true
162			break
163		}
164	}
165	fi.matched = fi.matched && (bctx.CgoEnabled || !fi.isCgo)
166
167	return fi, nil
168}
169