From 3374dad1d9529b6c2e58eb660117df388faf8d29 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 8 Feb 2024 15:13:11 -0800 Subject: [PATCH] go/types: generate builtins_test.go from types2 source Added new conversion functions to generate_test.go to handle the translation of builtins_test.go. Simplify some existing code by using the renameMap mechanism. This CL reduces the amount of code that needs to be maintained manually by about 250 LOC. Change-Id: I1a455c1921512fb3647fd92ac7c278b1b80ea884 Reviewed-on: https://go-review.googlesource.com/c/go/+/562837 Reviewed-by: Robert Findley LUCI-TryBot-Result: Go LUCI Reviewed-by: Robert Griesemer Auto-Submit: Robert Griesemer --- src/go/types/builtins_test.go | 6 ++- src/go/types/generate_test.go | 85 +++++++++++++++++++++++++---------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/go/types/builtins_test.go b/src/go/types/builtins_test.go index 4b198ef408b..e7dd50d4b86 100644 --- a/src/go/types/builtins_test.go +++ b/src/go/types/builtins_test.go @@ -1,3 +1,5 @@ +// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. + // Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -221,12 +223,12 @@ func testBuiltinSignature(t *testing.T, name, src0, want string) { case *ast.Ident: obj := uses[p] if obj == nil { - t.Errorf("%s: no object found for %s", src0, p) + t.Errorf("%s: no object found for %s", src0, p.Name) return } bin, _ := obj.(*Builtin) if bin == nil { - t.Errorf("%s: %s does not denote a built-in", src0, p) + t.Errorf("%s: %s does not denote a built-in", src0, p.Name) return } if bin.Name() != name { diff --git a/src/go/types/generate_test.go b/src/go/types/generate_test.go index d1b98ad8e40..371106c6e6a 100644 --- a/src/go/types/generate_test.go +++ b/src/go/types/generate_test.go @@ -100,12 +100,17 @@ var filemap = map[string]action{ "api_predicates.go": nil, "basic.go": nil, "builtins.go": func(f *ast.File) { - renameImportPath(f, `"cmd/compile/internal/syntax"`, `"go/ast"`) + renameImportPath(f, `"cmd/compile/internal/syntax"->"go/ast"`) renameIdents(f, "syntax->ast") renameSelectors(f, "ArgList->Args") fixSelValue(f) fixAtPosCall(f) }, + "builtins_test.go": func(f *ast.File) { + renameImportPath(f, `"cmd/compile/internal/syntax"->"go/ast"`, `"cmd/compile/internal/types2"->"go/types"`) + renameSelectorExprs(f, "syntax.Name->ast.Ident", "p.Value->p.Name") // must happen before renaming identifiers + renameIdents(f, "syntax->ast") + }, "chan.go": nil, "const.go": func(f *ast.File) { fixTokenPos(f) }, "context.go": nil, @@ -113,17 +118,17 @@ var filemap = map[string]action{ "errsupport.go": nil, "gccgosizes.go": nil, "gcsizes.go": func(f *ast.File) { renameIdents(f, "IsSyncAtomicAlign64->_IsSyncAtomicAlign64") }, - "hilbert_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) }, + "hilbert_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"->"go/types"`) }, "infer.go": func(f *ast.File) { fixTokenPos(f); fixInferSig(f) }, // "initorder.go": fixErrErrorfCall, // disabled for now due to unresolved error_ use implications for gopls "instantiate.go": func(f *ast.File) { fixTokenPos(f); fixCheckErrorfCall(f) }, - "instantiate_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) }, + "instantiate_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"->"go/types"`) }, "lookup.go": func(f *ast.File) { fixTokenPos(f) }, "main_test.go": nil, "map.go": nil, "named.go": func(f *ast.File) { fixTokenPos(f); renameSelectors(f, "Trace->_Trace") }, "object.go": func(f *ast.File) { fixTokenPos(f); renameIdents(f, "NewTypeNameLazy->_NewTypeNameLazy") }, - "object_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"`, `"go/types"`) }, + "object_test.go": func(f *ast.File) { renameImportPath(f, `"cmd/compile/internal/types2"->"go/types"`) }, "objset.go": nil, "package.go": nil, "pointer.go": nil, @@ -150,7 +155,7 @@ var filemap = map[string]action{ // TODO(gri) We should be able to make these rewriters more configurable/composable. // For now this is a good starting point. -// A renameMap maps old names to new names. +// A renameMap maps old strings to new strings. type renameMap map[string]string // makeRenameMap returns a renameMap populates from renames entries of the form "from->to". @@ -166,10 +171,26 @@ func makeRenameMap(renames ...string) renameMap { return m } -// rename renames the given name if a corresponding rename exists in m. -func (m renameMap) rename(name *string) { - if new, ok := m[*name]; ok { - *name = new +// rename renames the given string s if a corresponding rename exists in m. +func (m renameMap) rename(s *string) { + if r, ok := m[*s]; ok { + *s = r + } +} + +// renameSel renames a selector expression of the form a.x to b.x (where a, b are identifiers) +// if m contains the ("a.x" : "b.y") key-value pair. +func (m renameMap) renameSel(n *ast.SelectorExpr) { + if a, _ := n.X.(*ast.Ident); a != nil { + a_x := a.Name + "." + n.Sel.Name + if r, ok := m[a_x]; ok { + b_y := strings.Split(r, ".") + if len(b_y) != 2 { + panic("invalid selector expression: " + r) + } + a.Name = b_y[0] + n.Sel.Name = b_y[1] + } } } @@ -201,15 +222,31 @@ func renameSelectors(f *ast.File, renames ...string) { } -// renameImportPath renames an import path. -func renameImportPath(f *ast.File, from, to string) { +// renameSelectorExprs is like renameIdents but only looks at selector expressions. +// Each renames entry must be of the form "x.a->y.b". +func renameSelectorExprs(f *ast.File, renames ...string) { + m := makeRenameMap(renames...) + ast.Inspect(f, func(n ast.Node) bool { + switch n := n.(type) { + case *ast.SelectorExpr: + m.renameSel(n) + return false + } + return true + }) +} + +// renameImportPath is like renameIdents but renames import paths. +func renameImportPath(f *ast.File, renames ...string) { + m := makeRenameMap(renames...) ast.Inspect(f, func(n ast.Node) bool { switch n := n.(type) { case *ast.ImportSpec: - if n.Path.Kind == token.STRING && n.Path.Value == from { - n.Path.Value = to - return false + if n.Path.Kind != token.STRING { + panic("invalid import path") } + m.rename(&n.Path.Value) + return false } return true }) @@ -218,24 +255,24 @@ func renameImportPath(f *ast.File, from, to string) { // fixTokenPos changes imports of "cmd/compile/internal/syntax" to "go/token", // uses of syntax.Pos to token.Pos, and calls to x.IsKnown() to x.IsValid(). func fixTokenPos(f *ast.File) { + m := makeRenameMap(`"cmd/compile/internal/syntax"->"go/token"`, "syntax.Pos->token.Pos", "IsKnown->IsValid") ast.Inspect(f, func(n ast.Node) bool { switch n := n.(type) { case *ast.ImportSpec: // rewrite import path "cmd/compile/internal/syntax" to "go/token" - if n.Path.Kind == token.STRING && n.Path.Value == `"cmd/compile/internal/syntax"` { - n.Path.Value = `"go/token"` - return false + if n.Path.Kind != token.STRING { + panic("invalid import path") } + m.rename(&n.Path.Value) + return false case *ast.SelectorExpr: // rewrite syntax.Pos to token.Pos - if x := asIdent(n.X, "syntax"); x != nil && n.Sel.Name == "Pos" { - x.Name = "token" - return false - } + m.renameSel(n) + return false case *ast.CallExpr: // rewrite x.IsKnown() to x.IsValid() - if fun, _ := n.Fun.(*ast.SelectorExpr); fun != nil && fun.Sel.Name == "IsKnown" && len(n.Args) == 0 { - fun.Sel.Name = "IsValid" + if fun, _ := n.Fun.(*ast.SelectorExpr); fun != nil && len(n.Args) == 0 { + m.rename(&fun.Sel.Name) return false } } @@ -243,7 +280,7 @@ func fixTokenPos(f *ast.File) { }) } -// fixSelValue updates the selector Sel.Value to Sel.Name. +// fixSelValue updates the selector x.Sel.Value to x.Sel.Name. func fixSelValue(f *ast.File) { ast.Inspect(f, func(n ast.Node) bool { switch n := n.(type) {