kythe.io@v0.0.68-0.20240422202219-7225dbc01741/tools/gazelle/go/lang.go (about)

     1  package golang
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/bazelbuild/bazel-gazelle/config"
     7  	"github.com/bazelbuild/bazel-gazelle/language"
     8  	"github.com/bazelbuild/bazel-gazelle/rule"
     9  
    10  	golang "github.com/bazelbuild/bazel-gazelle/language/go"
    11  )
    12  
    13  type goLang struct {
    14  	language.Language
    15  }
    16  
    17  func NewLanguage() language.Language {
    18  	return &goLang{golang.NewLanguage()}
    19  }
    20  
    21  func (l *goLang) GenerateRules(args language.GenerateArgs) language.GenerateResult {
    22  	res := l.Language.GenerateRules(args)
    23  	moveTestEmbedToLibrary(&res)
    24  	suppressBinEmbeds(&res)
    25  	return res
    26  }
    27  
    28  func (l *goLang) Fix(c *config.Config, f *rule.File) {
    29  	// Inhibit underlying fixes for now as they include s/library/embed/ which we want to preserve.
    30  }
    31  
    32  func (l *goLang) ApparentLoads(moduleToApparentName func(string) string) []rule.LoadInfo {
    33  	loads := l.Language.(language.ModuleAwareLanguage).ApparentLoads(moduleToApparentName)
    34  	for i := range loads {
    35  		if loads[i].Name == "io_bazel_rules_go//go:def.bzl" {
    36  			loads[i].Name = "//tools:build_rules/shims.bzl"
    37  		}
    38  	}
    39  	return loads
    40  }
    41  
    42  func moveTestEmbedToLibrary(res *language.GenerateResult) {
    43  	for _, r := range res.Gen {
    44  		if r.Kind() == "go_test" && len(r.AttrStrings("embed")) == 1 {
    45  			r.SetAttr("library", r.AttrStrings("embed")[0])
    46  			r.DelAttr("embed")
    47  		}
    48  	}
    49  }
    50  
    51  func suppressBinEmbeds(res *language.GenerateResult) {
    52  	bi, bin := findEmbedBinRule(res.Gen)
    53  	if bin == nil {
    54  		return
    55  	}
    56  	li, lib := findEmbedLibRule(res.Gen, bin.AttrStrings("embed"))
    57  	if lib == nil {
    58  		return
    59  	}
    60  
    61  	// Copy the srcs and deps of the embedded library rule, then delete it.
    62  	bin.DelAttr("embed")
    63  	bin.SetAttr("srcs", lib.AttrStrings("srcs"))
    64  	res.Imports[bi] = res.Imports[li]
    65  
    66  	// This will inhibit creating the go_library rule if it doesn't already exist,
    67  	// but will not actually delete it unless in `fix` mode.
    68  	lib.Delete()
    69  }
    70  
    71  func findEmbedBinRule(gen []*rule.Rule) (int, *rule.Rule) {
    72  	for i, r := range gen {
    73  		if r.Kind() == "go_binary" && len(r.AttrStrings("embed")) > 0 {
    74  			return i, r
    75  		}
    76  	}
    77  	return -1, nil
    78  }
    79  
    80  func findEmbedLibRule(gen []*rule.Rule, embed []string) (int, *rule.Rule) {
    81  	for i, r := range gen {
    82  		if r.Kind() == "go_library" {
    83  			for _, name := range embed {
    84  				if r.Name() == strings.TrimPrefix(name, ":") {
    85  					return i, r
    86  				}
    87  			}
    88  		}
    89  	}
    90  	return -1, nil
    91  }