mirror of
https://github.com/golang/go
synced 2024-11-22 10:04:42 -07:00
go/ast: correct end position for Index and TypeAssert expressions
- added position information for [ and ] brackets of Index and Slice expression nodes - removed a TODO in go/printer R=r, rsc CC=golang-dev https://golang.org/cl/3867045
This commit is contained in:
parent
2b0a276129
commit
23410ced69
@ -232,14 +232,18 @@ type (
|
|||||||
// An IndexExpr node represents an expression followed by an index.
|
// An IndexExpr node represents an expression followed by an index.
|
||||||
IndexExpr struct {
|
IndexExpr struct {
|
||||||
X Expr // expression
|
X Expr // expression
|
||||||
|
Lbrack token.Pos // position of "["
|
||||||
Index Expr // index expression
|
Index Expr // index expression
|
||||||
|
Rbrack token.Pos // position of "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
// An SliceExpr node represents an expression followed by slice indices.
|
// An SliceExpr node represents an expression followed by slice indices.
|
||||||
SliceExpr struct {
|
SliceExpr struct {
|
||||||
X Expr // expression
|
X Expr // expression
|
||||||
|
Lbrack token.Pos // position of "["
|
||||||
Low Expr // begin of slice range; or nil
|
Low Expr // begin of slice range; or nil
|
||||||
High Expr // end of slice range; or nil
|
High Expr // end of slice range; or nil
|
||||||
|
Rbrack token.Pos // position of "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
// A TypeAssertExpr node represents an expression followed by a
|
// A TypeAssertExpr node represents an expression followed by a
|
||||||
@ -401,9 +405,14 @@ func (x *FuncLit) End() token.Pos { return x.Body.End() }
|
|||||||
func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
|
func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
|
||||||
func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
|
func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
|
||||||
func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
|
func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
|
||||||
func (x *IndexExpr) End() token.Pos { return x.Index.End() }
|
func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
|
||||||
func (x *SliceExpr) End() token.Pos { return x.High.End() }
|
func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
|
||||||
func (x *TypeAssertExpr) End() token.Pos { return x.Type.End() }
|
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 *CallExpr) End() token.Pos { return x.Rparen + 1 }
|
||||||
func (x *StarExpr) End() token.Pos { return x.X.End() }
|
func (x *StarExpr) End() token.Pos { return x.X.End() }
|
||||||
func (x *UnaryExpr) End() token.Pos { return x.X.End() }
|
func (x *UnaryExpr) End() token.Pos { return x.X.End() }
|
||||||
|
@ -867,26 +867,27 @@ func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
|
|||||||
defer un(trace(p, "IndexOrSlice"))
|
defer un(trace(p, "IndexOrSlice"))
|
||||||
}
|
}
|
||||||
|
|
||||||
p.expect(token.LBRACK)
|
lbrack := p.expect(token.LBRACK)
|
||||||
p.exprLev++
|
p.exprLev++
|
||||||
var index ast.Expr
|
var low, high ast.Expr
|
||||||
|
isSlice := false
|
||||||
if p.tok != token.COLON {
|
if p.tok != token.COLON {
|
||||||
index = p.parseExpr()
|
low = p.parseExpr()
|
||||||
}
|
}
|
||||||
if p.tok == token.COLON {
|
if p.tok == token.COLON {
|
||||||
|
isSlice = true
|
||||||
p.next()
|
p.next()
|
||||||
var end ast.Expr
|
|
||||||
if p.tok != token.RBRACK {
|
if p.tok != token.RBRACK {
|
||||||
end = p.parseExpr()
|
high = p.parseExpr()
|
||||||
}
|
}
|
||||||
x = &ast.SliceExpr{x, index, end}
|
|
||||||
} else {
|
|
||||||
x = &ast.IndexExpr{x, index}
|
|
||||||
}
|
}
|
||||||
p.exprLev--
|
p.exprLev--
|
||||||
p.expect(token.RBRACK)
|
rbrack := p.expect(token.RBRACK)
|
||||||
|
|
||||||
return x
|
if isSlice {
|
||||||
|
return &ast.SliceExpr{x, lbrack, low, high, rbrack}
|
||||||
|
}
|
||||||
|
return &ast.IndexExpr{x, lbrack, low, rbrack}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,13 +139,7 @@ func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exp
|
|||||||
prev := p.fset.Position(prev0)
|
prev := p.fset.Position(prev0)
|
||||||
next := p.fset.Position(next0)
|
next := p.fset.Position(next0)
|
||||||
line := p.fset.Position(list[0].Pos()).Line
|
line := p.fset.Position(list[0].Pos()).Line
|
||||||
endLine := next.Line
|
endLine := p.fset.Position(list[len(list)-1].End()).Line
|
||||||
if endLine == 0 {
|
|
||||||
// TODO(gri): endLine may be incorrect as it is really the beginning
|
|
||||||
// of the last list entry. There may be only one, very long
|
|
||||||
// entry in which case line == endLine.
|
|
||||||
endLine = p.fset.Position(list[len(list)-1].Pos()).Line
|
|
||||||
}
|
|
||||||
|
|
||||||
if prev.IsValid() && prev.Line == line && line == endLine {
|
if prev.IsValid() && prev.Line == line && line == endLine {
|
||||||
// all list entries on a single line
|
// all list entries on a single line
|
||||||
@ -708,13 +702,13 @@ func splitSelector(expr ast.Expr) (body, suffix ast.Expr) {
|
|||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
body, suffix = splitSelector(x.X)
|
body, suffix = splitSelector(x.X)
|
||||||
if body != nil {
|
if body != nil {
|
||||||
suffix = &ast.IndexExpr{suffix, x.Index}
|
suffix = &ast.IndexExpr{suffix, x.Lbrack, x.Index, x.Rbrack}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case *ast.SliceExpr:
|
case *ast.SliceExpr:
|
||||||
body, suffix = splitSelector(x.X)
|
body, suffix = splitSelector(x.X)
|
||||||
if body != nil {
|
if body != nil {
|
||||||
suffix = &ast.SliceExpr{suffix, x.Low, x.High}
|
suffix = &ast.SliceExpr{suffix, x.Lbrack, x.Low, x.High, x.Rbrack}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case *ast.TypeAssertExpr:
|
case *ast.TypeAssertExpr:
|
||||||
@ -837,14 +831,14 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, ctxt exprContext, multi
|
|||||||
case *ast.IndexExpr:
|
case *ast.IndexExpr:
|
||||||
// TODO(gri): should treat[] like parentheses and undo one level of depth
|
// TODO(gri): should treat[] like parentheses and undo one level of depth
|
||||||
p.expr1(x.X, token.HighestPrec, 1, 0, multiLine)
|
p.expr1(x.X, token.HighestPrec, 1, 0, multiLine)
|
||||||
p.print(token.LBRACK)
|
p.print(x.Lbrack, token.LBRACK)
|
||||||
p.expr0(x.Index, depth+1, multiLine)
|
p.expr0(x.Index, depth+1, multiLine)
|
||||||
p.print(token.RBRACK)
|
p.print(x.Rbrack, token.RBRACK)
|
||||||
|
|
||||||
case *ast.SliceExpr:
|
case *ast.SliceExpr:
|
||||||
// TODO(gri): should treat[] like parentheses and undo one level of depth
|
// TODO(gri): should treat[] like parentheses and undo one level of depth
|
||||||
p.expr1(x.X, token.HighestPrec, 1, 0, multiLine)
|
p.expr1(x.X, token.HighestPrec, 1, 0, multiLine)
|
||||||
p.print(token.LBRACK)
|
p.print(x.Lbrack, token.LBRACK)
|
||||||
if x.Low != nil {
|
if x.Low != nil {
|
||||||
p.expr0(x.Low, depth+1, multiLine)
|
p.expr0(x.Low, depth+1, multiLine)
|
||||||
}
|
}
|
||||||
@ -857,7 +851,7 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, ctxt exprContext, multi
|
|||||||
if x.High != nil {
|
if x.High != nil {
|
||||||
p.expr0(x.High, depth+1, multiLine)
|
p.expr0(x.High, depth+1, multiLine)
|
||||||
}
|
}
|
||||||
p.print(token.RBRACK)
|
p.print(x.Rbrack, token.RBRACK)
|
||||||
|
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
if len(x.Args) > 1 {
|
if len(x.Args) > 1 {
|
||||||
|
Loading…
Reference in New Issue
Block a user