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 }