// 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.
}
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()
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
} 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 {
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