]> Cypherpunks repositories - gostls13.git/commitdiff
go/ast: add {L,R}paren token.Pos field to ast.TypeAssertExpr.
authorAlan Donovan <adonovan@google.com>
Thu, 13 Jun 2013 18:41:44 +0000 (14:41 -0400)
committerAlan Donovan <adonovan@google.com>
Thu, 13 Jun 2013 18:41:44 +0000 (14:41 -0400)
These are required to correctly determine the End() of the node.

Also set these fields in go/parser and use them in go/printer.

This is a backward-compatible API change.

R=gri, r
CC=golang-dev
https://golang.org/cl/10189043

src/pkg/go/ast/ast.go
src/pkg/go/parser/parser.go
src/pkg/go/printer/nodes.go

index f26ff6b1af3ae3e940775d5b8801eab6efa0ceed..e75df82501f77ca6b5ae84a120b0cd4ba15e9f36 100644 (file)
@@ -304,8 +304,10 @@ type (
        // type assertion.
        //
        TypeAssertExpr struct {
-               X    Expr // expression
-               Type Expr // asserted type; nil means type switch X.(type)
+               X      Expr      // expression
+               Lparen token.Pos // position of "("
+               Type   Expr      // asserted type; nil means type switch X.(type)
+               Rparen token.Pos // position of ")"
        }
 
        // A CallExpr node represents an expression followed by an argument list.
@@ -456,26 +458,21 @@ func (x *Ellipsis) End() token.Pos {
        }
        return x.Ellipsis + 3 // len("...")
 }
-func (x *BasicLit) End() token.Pos     { return token.Pos(int(x.ValuePos) + len(x.Value)) }
-func (x *FuncLit) End() token.Pos      { return x.Body.End() }
-func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
-func (x *ParenExpr) End() token.Pos    { return x.Rparen + 1 }
-func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
-func (x *IndexExpr) End() token.Pos    { return x.Rbrack + 1 }
-func (x *SliceExpr) End() token.Pos    { return x.Rbrack + 1 }
-func (x *TypeAssertExpr) End() token.Pos {
-       if x.Type != nil {
-               return x.Type.End()
-       }
-       return x.X.End()
-}
-func (x *CallExpr) End() token.Pos     { return x.Rparen + 1 }
-func (x *StarExpr) End() token.Pos     { return x.X.End() }
-func (x *UnaryExpr) End() token.Pos    { return x.X.End() }
-func (x *BinaryExpr) End() token.Pos   { return x.Y.End() }
-func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
-func (x *ArrayType) End() token.Pos    { return x.Elt.End() }
-func (x *StructType) End() token.Pos   { return x.Fields.End() }
+func (x *BasicLit) End() token.Pos       { return token.Pos(int(x.ValuePos) + len(x.Value)) }
+func (x *FuncLit) End() token.Pos        { return x.Body.End() }
+func (x *CompositeLit) End() token.Pos   { return x.Rbrace + 1 }
+func (x *ParenExpr) End() token.Pos      { return x.Rparen + 1 }
+func (x *SelectorExpr) End() token.Pos   { return x.Sel.End() }
+func (x *IndexExpr) End() token.Pos      { return x.Rbrack + 1 }
+func (x *SliceExpr) End() token.Pos      { return x.Rbrack + 1 }
+func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
+func (x *CallExpr) End() token.Pos       { return x.Rparen + 1 }
+func (x *StarExpr) End() token.Pos       { return x.X.End() }
+func (x *UnaryExpr) End() token.Pos      { return x.X.End() }
+func (x *BinaryExpr) End() token.Pos     { return x.Y.End() }
+func (x *KeyValueExpr) End() token.Pos   { return x.Value.End() }
+func (x *ArrayType) End() token.Pos      { return x.Elt.End() }
+func (x *StructType) End() token.Pos     { return x.Fields.End() }
 func (x *FuncType) End() token.Pos {
        if x.Results != nil {
                return x.Results.End()
index db27a25b8392c82c5757de5d4865fa9117f7d50c..d1840728dae22d418536f42e7a27bfe3199a7c9e 100644 (file)
@@ -1150,7 +1150,7 @@ func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
                defer un(trace(p, "TypeAssertion"))
        }
 
-       p.expect(token.LPAREN)
+       lparen := p.expect(token.LPAREN)
        var typ ast.Expr
        if p.tok == token.TYPE {
                // type switch: typ == nil
@@ -1158,9 +1158,9 @@ func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
        } else {
                typ = p.parseType()
        }
-       p.expect(token.RPAREN)
+       rparen := p.expect(token.RPAREN)
 
-       return &ast.TypeAssertExpr{X: x, Type: typ}
+       return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
 }
 
 func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
index 7cd068e22ef45f754a9bec7a31c154b9715a248a..6c0234dd09bc0821b8543f7e3bf1d4cc74b3d43d 100644 (file)
@@ -754,13 +754,13 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
 
        case *ast.TypeAssertExpr:
                p.expr1(x.X, token.HighestPrec, depth)
-               p.print(token.PERIOD, token.LPAREN)
+               p.print(token.PERIOD, x.Lparen, token.LPAREN)
                if x.Type != nil {
                        p.expr(x.Type)
                } else {
                        p.print(token.TYPE)
                }
-               p.print(token.RPAREN)
+               p.print(x.Rparen, token.RPAREN)
 
        case *ast.IndexExpr:
                // TODO(gri): should treat[] like parentheses and undo one level of depth