mirror of
https://github.com/golang/go
synced 2024-11-05 15:06:09 -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/E.template",
|
||||||
"testdata/E1.go",
|
"testdata/E1.go",
|
||||||
|
|
||||||
|
"testdata/F.template",
|
||||||
|
"testdata/F1.go",
|
||||||
|
|
||||||
"testdata/bad_type.template",
|
"testdata/bad_type.template",
|
||||||
"testdata/no_before.template",
|
"testdata/no_before.template",
|
||||||
"testdata/no_after_return.template",
|
"testdata/no_after_return.template",
|
||||||
|
@ -35,11 +35,9 @@ func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
|
|||||||
y = unparen(y)
|
y = unparen(y)
|
||||||
|
|
||||||
// Is x a wildcard? (a reference to a 'before' parameter)
|
// 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.wildcardObj(x); ok {
|
||||||
if xobj, ok := tr.info.Uses[x].(*types.Var); ok && tr.wildcards[xobj] {
|
|
||||||
return tr.matchWildcard(xobj, y)
|
return tr.matchWildcard(xobj, y)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Object identifiers (including pkg-qualified ones)
|
// Object identifiers (including pkg-qualified ones)
|
||||||
// are handled semantically, not syntactically.
|
// are handled semantically, not syntactically.
|
||||||
@ -81,7 +79,7 @@ func (tr *Transformer) matchExpr(x, y ast.Expr) bool {
|
|||||||
|
|
||||||
case *ast.SelectorExpr:
|
case *ast.SelectorExpr:
|
||||||
y := y.(*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()
|
tr.info.Selections[x].Obj() == tr.info.Selections[y].Obj()
|
||||||
|
|
||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
@ -155,6 +153,28 @@ func (tr *Transformer) matchType(x, y ast.Expr) bool {
|
|||||||
return types.Identical(tx, ty)
|
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 {
|
func (tr *Transformer) matchWildcard(xobj *types.Var, y ast.Expr) bool {
|
||||||
name := xobj.Name()
|
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