mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 05:07:33 +00:00
util/codegen: add AssertStructUnchanged
Refactored out from cmd/cloner. Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:

committed by
Josh Bleecher Snyder

parent
fb66ff7c78
commit
618376dbc0
@@ -6,8 +6,10 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/types"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -38,3 +40,42 @@ func WriteFormatted(code []byte, path string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssertStructUnchanged generates code that asserts at compile time that type t is unchanged.
|
||||
// tname is the named type corresponding to t.
|
||||
// ctx is a single-word context for this assertion, such as "Clone".
|
||||
// thisPkg is the package containing t.
|
||||
// If non-nil, AssertStructUnchanged will add elements to imports
|
||||
// for each package path that the caller must import for the returned code to compile.
|
||||
func AssertStructUnchanged(t *types.Struct, tname, ctx string, thisPkg *types.Package, imports map[string]struct{}) []byte {
|
||||
buf := new(bytes.Buffer)
|
||||
w := func(format string, args ...interface{}) {
|
||||
fmt.Fprintf(buf, format+"\n", args...)
|
||||
}
|
||||
w("// A compilation failure here means this code must be regenerated, with the command at the top of this file.")
|
||||
w("var _%s%sNeedsRegeneration = %s(struct {", tname, ctx, tname)
|
||||
|
||||
for i := 0; i < t.NumFields(); i++ {
|
||||
fname := t.Field(i).Name()
|
||||
ft := t.Field(i).Type()
|
||||
qname, imppath := importedName(ft, thisPkg)
|
||||
if imppath != "" && imports != nil {
|
||||
imports[imppath] = struct{}{}
|
||||
}
|
||||
w("\t%s %s", fname, qname)
|
||||
}
|
||||
|
||||
w("}{})\n")
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func importedName(t types.Type, thisPkg *types.Package) (qualifiedName, importPkg string) {
|
||||
qual := func(pkg *types.Package) string {
|
||||
if thisPkg == pkg {
|
||||
return ""
|
||||
}
|
||||
importPkg = pkg.Path()
|
||||
return pkg.Name()
|
||||
}
|
||||
return types.TypeString(t, qual), importPkg
|
||||
}
|
||||
|
Reference in New Issue
Block a user