Skip to content

Commit

Permalink
perf: Improve merger.Mergefile
Browse files Browse the repository at this point in the history
  • Loading branch information
dzbarsky committed Sep 12, 2024
1 parent 0890963 commit b73ab36
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
18 changes: 17 additions & 1 deletion merger/merger.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func MergeFile(oldFile *rule.File, emptyRules, genRules []*rule.Rule, phase Phas

// Merge empty rules into the file and delete any rules which become empty.
for _, emptyRule := range emptyRules {
if oldRule, _ := Match(oldFile.Rules, emptyRule, kinds[emptyRule.Kind()]); oldRule != nil {
if oldRule, _ := match(oldFile.Rules, emptyRule, kinds[emptyRule.Kind()], false); oldRule != nil {
if oldRule.ShouldKeep() {
continue
}
Expand Down Expand Up @@ -211,6 +211,10 @@ func substituteRule(r *rule.Rule, substitutions map[string]string, info rule.Kin
// order that attributes are listed). If disambiguation is successful,
// the rule and nil are returned. Otherwise, nil and an error are returned.
func Match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo) (*rule.Rule, error) {
return match(rules, x, info, true)
}

func match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo, wantError bool) (*rule.Rule, error) {
xname := x.Name()
xkind := x.Kind()
var nameMatches []*rule.Rule
Expand All @@ -227,11 +231,17 @@ func Match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo) (*rule.Rule, er
if len(nameMatches) == 1 {
y := nameMatches[0]
if xkind != y.Kind() {
if !wantError {
return nil, nil
}
return nil, fmt.Errorf("could not merge %s(%s): a rule of the same name has kind %s", xkind, xname, y.Kind())
}
return y, nil
}
if len(nameMatches) > 1 {
if !wantError {
return nil, nil
}
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same name", xkind, xname)
}

Expand All @@ -245,6 +255,9 @@ func Match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo) (*rule.Rule, er
if len(attrMatches) == 1 {
return attrMatches[0], nil
} else if len(attrMatches) > 1 {
if !wantError {
return nil, nil
}
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same attribute %s", xkind, xname, key)
}
}
Expand All @@ -253,6 +266,9 @@ func Match(rules []*rule.Rule, x *rule.Rule, info rule.KindInfo) (*rule.Rule, er
if len(kindMatches) == 1 {
return kindMatches[0], nil
} else if len(kindMatches) > 1 {
if !wantError {
return nil, nil
}
return nil, fmt.Errorf("could not merge %s(%s): multiple rules have the same kind but different names", xkind, xname)
}
}
Expand Down
10 changes: 5 additions & 5 deletions rule/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ func (l *Load) sync() {
// Rule represents a rule statement within a build file.
type Rule struct {
stmt
kind bzl.Expr
kind string
args []bzl.Expr
attrs map[string]attrValue
private map[string]interface{}
Expand All @@ -748,7 +748,7 @@ func NewRule(kind, name string) *Rule {

r := &Rule{
stmt: stmt{expr: call},
kind: kindIdent,
kind: kind,
attrs: map[string]attrValue{},
private: map[string]interface{}{},
sortedAttrs: []string{"deps", "srcs"},
Expand Down Expand Up @@ -850,7 +850,7 @@ func ruleFromExpr(index int, expr bzl.Expr) *Rule {
expr: call,
comments: commentsFromExpr(expr),
},
kind: kind,
kind: bzl.FormatString(kind),
args: args,
attrs: attrs,
private: map[string]interface{}{},
Expand All @@ -866,12 +866,12 @@ func (r *Rule) ShouldKeep() bool {

// Kind returns the kind of rule this is (for example, "go_library").
func (r *Rule) Kind() string {
return bzl.FormatString(r.kind)
return r.kind
}

// SetKind changes the kind of rule this is.
func (r *Rule) SetKind(kind string) {
r.kind = &bzl.Ident{Name: kind}
r.kind = kind
r.updated = true
}

Expand Down

0 comments on commit b73ab36

Please sign in to comment.