mirror of
https://github.com/golang/go
synced 2024-11-18 10:04:43 -07:00
go.tools/refactor/eg: Support promoted fields and methods.
As per http://golang.org/ref/spec#Struct_types enable eg tool to wildcard match against promoted fields and methods. LGTM=adonovan R=adonovan, gordon.klaus CC=golang-codereviews https://golang.org/cl/129260043
This commit is contained in:
parent
cd9959d796
commit
89156360f9
@ -62,6 +62,9 @@ func Test(t *testing.T) {
|
||||
"testdata/E.template",
|
||||
"testdata/E1.go",
|
||||
|
||||
"testdata/F.template",
|
||||
"testdata/F1.go",
|
||||
|
||||
"testdata/bad_type.template",
|
||||
"testdata/no_before.template",
|
||||
"testdata/no_after_return.template",
|
||||
|
@ -35,10 +35,8 @@ func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
|
||||
y = unparen(y)
|
||||
|
||||
// Is x a wildcard? (a reference to a 'before' parameter)
|
||||
if x, ok := x.(*ast.Ident); ok && x != nil && tr.allowWildcards {
|
||||
if xobj, ok := tr.info.Uses[x].(*types.Var); ok && tr.wildcards[xobj] {
|
||||
return tr.matchWildcard(xobj, y)
|
||||
}
|
||||
if xobj, ok := tr.wildcardObj(x); ok {
|
||||
return tr.matchWildcard(xobj, y)
|
||||
}
|
||||
|
||||
// Object identifiers (including pkg-qualified ones)
|
||||
@ -81,7 +79,7 @@ func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
|
||||
|
||||
case *ast.SelectorExpr:
|
||||
y := y.(*ast.SelectorExpr)
|
||||
return tr.matchExpr(x.X, y.X) &&
|
||||
return tr.matchSelectorExpr(x, y) &&
|
||||
tr.info.Selections[x].Obj() == tr.info.Selections[y].Obj()
|
||||
|
||||
case *ast.IndexExpr:
|
||||
@ -155,6 +153,28 @@ func (tr *Transformer) matchType(x, y ast.Expr) bool {
|
||||
return types.Identical(tx, ty)
|
||||
}
|
||||
|
||||
func (tr *Transformer) wildcardObj(x ast.Expr) (*types.Var, bool) {
|
||||
if x, ok := x.(*ast.Ident); ok && x != nil && tr.allowWildcards {
|
||||
if xobj, ok := tr.info.Uses[x].(*types.Var); ok && tr.wildcards[xobj] {
|
||||
return xobj, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (tr *Transformer) matchSelectorExpr(x, y *ast.SelectorExpr) bool {
|
||||
if xobj, ok := tr.wildcardObj(x.X); ok {
|
||||
field := x.Sel.Name
|
||||
yt := tr.info.TypeOf(y.X)
|
||||
o, _, _ := types.LookupFieldOrMethod(yt, tr.currentPkg, field)
|
||||
if o != nil {
|
||||
tr.env[xobj.Name()] = y.X // record binding
|
||||
return true
|
||||
}
|
||||
}
|
||||
return tr.matchExpr(x.X, y.X)
|
||||
}
|
||||
|
||||
func (tr *Transformer) matchWildcard(xobj *types.Var, y ast.Expr) bool {
|
||||
name := xobj.Name()
|
||||
|
||||
|
8
refactor/eg/testdata/F.template
vendored
Normal file
8
refactor/eg/testdata/F.template
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
package templates
|
||||
|
||||
// Test
|
||||
|
||||
import "sync"
|
||||
|
||||
func before(s sync.RWMutex) { s.Lock() }
|
||||
func after(s sync.RWMutex) { s.RLock() }
|
48
refactor/eg/testdata/F1.go
vendored
Normal file
48
refactor/eg/testdata/F1.go
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// +build ignore
|
||||
|
||||
package F1
|
||||
|
||||
import "sync"
|
||||
|
||||
func example(n int) {
|
||||
var x struct {
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
var y struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type l struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
var z struct {
|
||||
l
|
||||
}
|
||||
|
||||
var a struct {
|
||||
*l
|
||||
}
|
||||
|
||||
var b struct{ Lock func() }
|
||||
|
||||
// Match
|
||||
x.mutex.Lock()
|
||||
|
||||
// Match
|
||||
y.Lock()
|
||||
|
||||
// Match indirect
|
||||
z.Lock()
|
||||
|
||||
// Should be no match however currently matches due to:
|
||||
// https://code.google.com/p/go/issues/detail?id=8584
|
||||
// Will start failing when this is fixed then just change golden to
|
||||
// No match pointer indirect
|
||||
// a.Lock()
|
||||
a.Lock()
|
||||
|
||||
// No match
|
||||
b.Lock()
|
||||
}
|
48
refactor/eg/testdata/F1.golden
vendored
Normal file
48
refactor/eg/testdata/F1.golden
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// +build ignore
|
||||
|
||||
package F1
|
||||
|
||||
import "sync"
|
||||
|
||||
func example(n int) {
|
||||
var x struct {
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
var y struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
type l struct {
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
var z struct {
|
||||
l
|
||||
}
|
||||
|
||||
var a struct {
|
||||
*l
|
||||
}
|
||||
|
||||
var b struct{ Lock func() }
|
||||
|
||||
// Match
|
||||
x.mutex.RLock()
|
||||
|
||||
// Match
|
||||
y.RLock()
|
||||
|
||||
// Match indirect
|
||||
z.RLock()
|
||||
|
||||
// Should be no match however currently matches due to:
|
||||
// https://code.google.com/p/go/issues/detail?id=8584
|
||||
// Will start failing when this is fixed then just change golden to
|
||||
// No match pointer indirect
|
||||
// a.Lock()
|
||||
a.RLock()
|
||||
|
||||
// No match
|
||||
b.Lock()
|
||||
}
|
Loading…
Reference in New Issue
Block a user