mirror of
https://github.com/golang/go
synced 2024-11-24 04:10:14 -07: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:
parent
6a223b82a4
commit
fcd32885df
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user