]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor method expression detection
authorMatthew Dempsky <mdempsky@google.com>
Tue, 24 Oct 2017 21:45:41 +0000 (14:45 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 24 Oct 2017 22:21:34 +0000 (22:21 +0000)
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>

src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/export.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/typecheck.go

index 9564a59f4ae5672da3b780e27ee4decec73ba0de..9950f8b855919d4f0fab03c6be0782013f75e3b5 100644 (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
index 8175119eb8469a14fe0c904ede0b1f0b4ecd6ef9..2c44785859dd16e6074d72d75945c130a2c8670d 100644 (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
                        }
 
index 9a434601d5569076198dd904d8a75b2963d95114..1b52acde3a1e5d9c6a1eea04e799d761862583a0 100644 (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
-}
index e884ab16921c6654575c32a3517a9b850254634b..3af2460a802424f827123b031722ee5e89d5d4a8 100644 (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)
index 68067bf1b36230933a2964dac1ac9bfd6b0c7dcb..9a07f0ec12ea62a9953e2bfd3ed5733e1d8713f6 100644 (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 {
index 78c59b5dff675ff9b4b72263388b8863b1666c79..f6e3633b0eb4c5392905052ef37898e0a97f5e63 100644 (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)