1
0
mirror of https://github.com/golang/go synced 2024-09-24 13:20:12 -06:00

cmd/compile: refactor method expression detection

Eliminates lots of ad hoc code for recognizing the same thing in
different ways.

Passes toolstash-check.

Change-Id: Ic0bb005308e96331b4ef30f455b860e476725b61
Reviewed-on: https://go-review.googlesource.com/73190
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Matthew Dempsky 2017-10-24 14:45:41 -07:00
parent 6a223b82a4
commit fcd32885df
6 changed files with 13 additions and 12 deletions

View File

@ -1192,7 +1192,7 @@ func (p *exporter) expr(n *Node) {
// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
// but for export, this should be rendered as (*pkg.T).meth.
// These nodes have the special property that they are names with a left OTYPE and a right ONAME.
if n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME {
if n.isMethodExpression() {
p.op(OXDOT)
p.pos(n)
p.expr(n.Left) // n.Left.Op == OTYPE

View File

@ -112,10 +112,10 @@ func reexportdep(n *Node) {
switch n.Op {
case ONAME:
switch n.Class() {
// methods will be printed along with their type
// nodes for T.Method expressions
case PFUNC:
if n.Left != nil && n.Left.Op == OTYPE {
// methods will be printed along with their type
// nodes for T.Method expressions
if n.isMethodExpression() {
break
}

View File

@ -244,7 +244,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
break
}
if n.isMethodCalledAsFunction() {
if n.Left.isMethodExpression() {
if d := asNode(n.Left.Sym.Def); d != nil && d.Func.Inl.Len() != 0 {
v.budget -= d.Func.InlCost
break
@ -536,7 +536,7 @@ func inlnode(n *Node) *Node {
}
if n.Left.Func != nil && n.Left.Func.Inl.Len() != 0 && !isIntrinsicCall(n) { // normal case
n = mkinlcall(n, n.Left, n.Isddd())
} else if n.isMethodCalledAsFunction() && asNode(n.Left.Sym.Def) != nil {
} else if n.Left.isMethodExpression() && asNode(n.Left.Sym.Def) != nil {
n = mkinlcall(n, asNode(n.Left.Sym.Def), n.Isddd())
} else if n.Left.Op == OCLOSURE {
if f := inlinableClosure(n.Left); f != nil {
@ -1095,7 +1095,3 @@ func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
pos.SetBase(newbase)
return Ctxt.PosTable.XPos(pos)
}
func (n *Node) isMethodCalledAsFunction() bool {
return n.Left.Op == ONAME && n.Left.Left != nil && n.Left.Left.Op == OTYPE && n.Left.Right != nil && n.Left.Right.Op == ONAME
}

View File

@ -44,7 +44,7 @@ func init1(n *Node, out *[]*Node) {
init1(n1, out)
}
if n.Left != nil && n.Type != nil && n.Left.Op == OTYPE && n.Class() == PFUNC {
if n.isMethodExpression() {
// Methods called as Type.Method(receiver, ...).
// Definitions for method expressions are stored in type->nname.
init1(asNode(n.Type.FuncType().Nname), out)

View File

@ -209,6 +209,11 @@ func (n *Node) mayBeShared() bool {
return false
}
// isMethodExpression reports whether n represents a method expression T.M.
func (n *Node) isMethodExpression() bool {
return n.Op == ONAME && n.Left != nil && n.Left.Op == OTYPE && n.Right != nil && n.Right.Op == ONAME
}
// funcname returns the name of the function n.
func (n *Node) funcname() string {
if n == nil || n.Func == nil || n.Func.Nname == nil {

View File

@ -2709,7 +2709,7 @@ notenough:
// call is the expression being called, not the overall call.
// Method expressions have the form T.M, and the compiler has
// rewritten those to ONAME nodes but left T in Left.
if call.Op == ONAME && call.Left != nil && call.Left.Op == OTYPE {
if call.isMethodExpression() {
yyerror("not enough arguments in call to method expression %v%s", call, details)
} else {
yyerror("not enough arguments in call to %v%s", call, details)