Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions parser/v2/ifexpressionparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,26 @@ func (ifExpressionParser) Parse(pi *parse.Input) (n Node, matched bool, err erro
}

// Read the optional 'Else' Nodes.
var elseNodes Nodes
if elseNodes, _, err = elseExpression.Parse(pi); err != nil {
// Populate the nodes anyway, so that the LSP can use them.
r.Else = elseNodes.Nodes
elseIdx := pi.Index()
var elseMatched bool
if _, elseMatched, err = elseKeyword.Parse(pi); err != nil {
return r, true, err
}
r.Else = elseNodes.Nodes
if elseMatched {
r.ElseRange = NewRange(pi.PositionAt(elseIdx), pi.Position())
if _, _, err = parse.OptionalWhitespace.Parse(pi); err != nil {
return r, true, err
}
var elseNodes Nodes
np := newTemplateNodeParser(closeBraceWithOptionalPadding, "else expression closing brace")
if elseNodes, _, err = np.Parse(pi); err != nil {
r.Else = elseNodes.Nodes
return r, true, err
}
r.Else = elseNodes.Nodes
} else {
pi.Seek(elseIdx)
}

// Read the required closing brace.
if _, matched, err = closeBraceWithOptionalPadding.Parse(pi); err != nil || !matched {
Expand Down Expand Up @@ -113,6 +126,15 @@ func (elseIfExpressionParser) Parse(pi *parse.Input) (r ElseIfExpression, matche
return r, true, nil
}

// elseKeyword matches "} else {" without consuming trailing whitespace, so the
// caller can record its precise source range before the body begins.
var elseKeyword = parse.All(
parse.Rune('}'),
parse.OptionalWhitespace,
parse.String("else"),
parse.OptionalWhitespace,
parse.Rune('{'))

var endElseParser = parse.All(
parse.Rune('}'),
parse.OptionalWhitespace,
Expand Down
78 changes: 78 additions & 0 deletions parser/v2/ifexpressionparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ func TestIfExpression(t *testing.T) {
},
},
},
ElseRange: Range{
From: Position{Index: 18, Line: 2, Col: 0},
To: Position{Index: 26, Line: 2, Col: 8},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 37, Line: 4, Col: 1},
Expand Down Expand Up @@ -404,12 +408,78 @@ func TestIfExpression(t *testing.T) {
},
},
},
ElseRange: Range{
From: Position{Index: 17, Line: 2, Col: 0},
To: Position{Index: 25, Line: 2, Col: 8},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 36, Line: 4, Col: 1},
},
},
},
{
name: "if: else, keyword spans multiple lines",
input: `if p.A {
{ "A" }
}
else {
{ "B" }
}`,
expected: &IfExpression{
Expression: Expression{
Value: `p.A`,
Range: Range{
From: Position{Index: 3, Line: 0, Col: 3},
To: Position{Index: 6, Line: 0, Col: 6},
},
},
Then: []Node{
&Whitespace{Range: Range{
From: Position{Index: 9, Line: 1, Col: 0},
To: Position{Index: 10, Line: 1, Col: 1},
}, Value: "\t"},
&StringExpression{
Expression: Expression{
Value: `"A"`,
Range: Range{
From: Position{Index: 12, Line: 1, Col: 3},
To: Position{Index: 15, Line: 1, Col: 6},
},
},
TrailingSpace: SpaceVertical,
Range: Range{
From: Position{Index: 10, Line: 1, Col: 1},
To: Position{Index: 18, Line: 2, Col: 0},
},
},
},
Else: []Node{
&StringExpression{
Expression: Expression{
Value: `"B"`,
Range: Range{
From: Position{Index: 30, Line: 4, Col: 3},
To: Position{Index: 33, Line: 4, Col: 6},
},
},
TrailingSpace: SpaceVertical,
Range: Range{
From: Position{Index: 28, Line: 4, Col: 1},
To: Position{Index: 36, Line: 5, Col: 0},
},
},
},
ElseRange: Range{
From: Position{Index: 18, Line: 2, Col: 0},
To: Position{Index: 26, Line: 3, Col: 6},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 37, Line: 5, Col: 1},
},
},
},
{
name: "if: nested",
input: `if p.A {
Expand Down Expand Up @@ -921,6 +991,10 @@ func TestIfExpression(t *testing.T) {
},
},
},
ElseRange: Range{
From: Position{Index: 68, Line: 6, Col: 0},
To: Position{Index: 76, Line: 6, Col: 8},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 87, Line: 8, Col: 1},
Expand Down Expand Up @@ -1010,6 +1084,10 @@ func TestIfExpression(t *testing.T) {
},
},
},
ElseRange: Range{
From: Position{Index: 33, Line: 2, Col: 1},
To: Position{Index: 41, Line: 2, Col: 9},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 54, Line: 4, Col: 2},
Expand Down
2 changes: 2 additions & 0 deletions parser/v2/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ func (p rawElementParser) Parse(pi *parse.Input) (n Node, ok bool, err error) {

// Once we've got an open tag, parse anything until the end tag as the tag contents.
// It's going to be rendered out raw.
contentsStart := pi.Position()
end := parse.All(parse.String("</"), parse.String(p.name), parse.String(">"))
if e.Contents, ok, err = parse.StringUntil(end).Parse(pi); err != nil || !ok {
err = parse.Error(fmt.Sprintf("<%s>: expected end tag not present", e.Name), pi.Position())
return
}
e.ContentsRange = NewRange(contentsStart, pi.Position())
// Cut the end element.
_, _, _ = end.Parse(pi)

Expand Down
8 changes: 8 additions & 0 deletions parser/v2/raw_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ func TestRawElementParser(t *testing.T) {
},
},
Contents: "contents",
ContentsRange: Range{
From: Position{Index: 23, Line: 0, Col: 23},
To: Position{Index: 31, Line: 0, Col: 31},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 39, Line: 0, Col: 39},
Expand Down Expand Up @@ -76,6 +80,10 @@ func TestRawElementParser(t *testing.T) {
},
},
Contents: ignoredContent,
ContentsRange: Range{
From: Position{Index: 23, Line: 0, Col: 23},
To: Position{Index: 44, Line: 3, Col: 1},
},
Range: Range{
From: Position{Index: 0, Line: 0, Col: 0},
To: Position{Index: 52, Line: 3, Col: 9},
Expand Down
10 changes: 6 additions & 4 deletions parser/v2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,10 +795,11 @@ func writeStrings(w io.Writer, ss ...string) error {
}

type RawElement struct {
Name string
Attributes []Attribute
Contents string
Range Range
Name string
Attributes []Attribute
Contents string
ContentsRange Range
Range Range
}

func (e *RawElement) IsNode() bool { return true }
Expand Down Expand Up @@ -1335,6 +1336,7 @@ type IfExpression struct {
Then []Node
ElseIfs []ElseIfExpression
Else []Node
ElseRange Range // source position of the "} else {" keyword; zero if no else clause
Range Range
}

Expand Down
Loading