Improve handling of generated source files.
Previously, the query-based analyzer looked for the dep providing a generated source file by walking up the graph of generating rules, which relied on generated files only happening in macros and the ts_library in the macro sharing a label with the macro. Instead, generated sources should be handled like any other source - the analyzer should look for the generated file (or the generating rule) in the srcs attribute of some other rule.
PiperOrigin-RevId: 231693464
diff --git a/ts_auto_deps/analyze/loader.go b/ts_auto_deps/analyze/loader.go
index cdfee61..ab82fce 100644
--- a/ts_auto_deps/analyze/loader.go
+++ b/ts_auto_deps/analyze/loader.go
@@ -167,7 +167,7 @@
if err != nil {
return nil, err
}
- var sourceFileLabels, generators []string
+ var fileLabels, generators []string
generatorsToFiles := make(map[string][]*appb.GeneratedFile)
for _, target := range r.GetTarget() {
label, err := q.fileLabel(target)
@@ -179,40 +179,21 @@
file := target.GetGeneratedFile()
generator := file.GetGeneratingRule()
+ // a generated file can be included as a source by referencing the label
+ // of the generated file, or the label of the generating rule, so check
+ // for both
+ fileLabels = append(fileLabels, file.GetName())
generators = append(generators, generator)
generatorsToFiles[generator] = append(generatorsToFiles[generator], file)
case appb.Target_SOURCE_FILE:
- sourceFileLabels = append(sourceFileLabels, label)
+ fileLabels = append(fileLabels, label)
}
}
labelToRule := make(map[string]*appb.Rule)
- for len(generators) > 0 {
- generatorToRule, err := q.LoadRules(currentPkg, generators)
- if err != nil {
- return nil, err
- }
- var newGenerators []string
- for label, rule := range generatorToRule {
- _, _, target := edit.ParseLabel(label)
- if generator := stringAttribute(rule, "generator_name"); generator != "" && generator != target {
- // Located rule is also a generated rule. Look for the rule
- // that generates it.
- _, pkg, _ := edit.ParseLabel(label)
- newLabel := "//" + pkg + ":" + generator
- newGenerators = append(newGenerators, newLabel)
- generatorsToFiles[newLabel] = generatorsToFiles[label]
- } else {
- for _, generated := range generatorsToFiles[label] {
- labelToRule[generated.GetName()] = rule
- }
- }
- }
- generators = newGenerators
- }
-
- sourceLabelToRule, err := q.loadRulesIncludingSourceFiles(workspaceRoot, sourceFileLabels)
+ // load all the rules with file srcs (either literal or generated)
+ sourceLabelToRule, err := q.loadRulesWithSources(workspaceRoot, fileLabels)
if err != nil {
return nil, err
}
@@ -220,6 +201,17 @@
labelToRule[label] = rule
}
+ // load all the rules with generator rule srcs
+ generatorLabelToRule, err := q.loadRulesWithSources(workspaceRoot, generators)
+ if err != nil {
+ return nil, err
+ }
+ for label, rule := range generatorLabelToRule {
+ for _, generated := range generatorsToFiles[label] {
+ labelToRule[generated.GetName()] = rule
+ }
+ }
+
for label, rule := range labelToRule {
_, pkg, file := edit.ParseLabel(label)
// Trim "/index" suffixes that were added to path in the queries above.
@@ -279,13 +271,14 @@
}
}
-// loadRuleIncludingSourceFiles loads all rules which include labels in
-// sourceFileLabels, Returns a map from source file label to the rule which
-// includes it.
-func (q *QueryBasedTargetLoader) loadRulesIncludingSourceFiles(workspaceRoot string, sourceFileLabels []string) (map[string]*appb.Rule, error) {
+// loadRulesWithSources loads all rules which include the labels in sources as
+// srcs attributes. Returns a map from source label to the rule which includes
+// it. A source label can be the label of a source file or a generated file or
+// a generating rule.
+func (q *QueryBasedTargetLoader) loadRulesWithSources(workspaceRoot string, sources []string) (map[string]*appb.Rule, error) {
pkgToLabels := make(map[string][]string)
- queries := make([]string, 0, len(sourceFileLabels))
- for _, label := range sourceFileLabels {
+ queries := make([]string, 0, len(sources))
+ for _, label := range sources {
_, pkg, file := edit.ParseLabel(label)
pkgToLabels[pkg] = append(pkgToLabels[pkg], label)
// Query for all targets in the package which use file.