diff --git a/src/pkg/go/ast/ast.go b/src/pkg/go/ast/ast.go index f26ff6b1af3..e75df82501f 100644 --- a/src/pkg/go/ast/ast.go +++ b/src/pkg/go/ast/ast.go @@ -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() diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go index db27a25b839..d1840728dae 100644 --- a/src/pkg/go/parser/parser.go +++ b/src/pkg/go/parser/parser.go @@ -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 { diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index 7cd068e22ef..6c0234dd09b 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -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