hclsyntax: allow missing newline at EOF
Due to some earlier limitations of the parser we required each attribute and block to end with a newline, even if it appeared at the end of a file. In effect, this required all files to end with a newline character. This is no longer required and so we'll tolerate that missing newline for pragmatic reasons.
This commit is contained in:
parent
998a3053e2
commit
386ab3257c
@ -167,17 +167,8 @@ func (p *parser) finishParsingBodyAttribute(ident Token) (Node, hcl.Diagnostics)
|
|||||||
p.recoverAfterBodyItem()
|
p.recoverAfterBodyItem()
|
||||||
} else {
|
} else {
|
||||||
end := p.Peek()
|
end := p.Peek()
|
||||||
if end.Type != TokenNewline {
|
if end.Type != TokenNewline && end.Type != TokenEOF {
|
||||||
if !p.recovery {
|
if !p.recovery {
|
||||||
if end.Type == TokenEOF {
|
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Missing newline after attribute definition",
|
|
||||||
Detail: "A newline is required after an attribute definition at the end of a file.",
|
|
||||||
Subject: &end.Range,
|
|
||||||
Context: hcl.RangeBetween(ident.Range, end.Range).Ptr(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Missing newline after attribute definition",
|
Summary: "Missing newline after attribute definition",
|
||||||
@ -186,7 +177,6 @@ func (p *parser) finishParsingBodyAttribute(ident Token) (Node, hcl.Diagnostics)
|
|||||||
Context: hcl.RangeBetween(ident.Range, end.Range).Ptr(),
|
Context: hcl.RangeBetween(ident.Range, end.Range).Ptr(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
endRange = p.PrevRange()
|
endRange = p.PrevRange()
|
||||||
p.recoverAfterBodyItem()
|
p.recoverAfterBodyItem()
|
||||||
} else {
|
} else {
|
||||||
@ -294,19 +284,10 @@ Token:
|
|||||||
cBraceRange := p.PrevRange()
|
cBraceRange := p.PrevRange()
|
||||||
|
|
||||||
eol := p.Peek()
|
eol := p.Peek()
|
||||||
if eol.Type == TokenNewline {
|
if eol.Type == TokenNewline || eol.Type == TokenEOF {
|
||||||
p.Read() // eat newline
|
p.Read() // eat newline
|
||||||
} else {
|
} else {
|
||||||
if !p.recovery {
|
if !p.recovery {
|
||||||
if eol.Type == TokenEOF {
|
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
|
||||||
Severity: hcl.DiagError,
|
|
||||||
Summary: "Missing newline after block definition",
|
|
||||||
Detail: "A newline is required after a block definition at the end of a file.",
|
|
||||||
Subject: &eol.Range,
|
|
||||||
Context: hcl.RangeBetween(ident.Range, eol.Range).Ptr(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
diags = append(diags, &hcl.Diagnostic{
|
diags = append(diags, &hcl.Diagnostic{
|
||||||
Severity: hcl.DiagError,
|
Severity: hcl.DiagError,
|
||||||
Summary: "Missing newline after block definition",
|
Summary: "Missing newline after block definition",
|
||||||
@ -315,7 +296,6 @@ Token:
|
|||||||
Context: hcl.RangeBetween(ident.Range, eol.Range).Ptr(),
|
Context: hcl.RangeBetween(ident.Range, eol.Range).Ptr(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
p.recoverAfterBodyItem()
|
p.recoverAfterBodyItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,54 @@ func TestParseConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"block {}",
|
||||||
|
0,
|
||||||
|
&Body{
|
||||||
|
Attributes: Attributes{},
|
||||||
|
Blocks: Blocks{
|
||||||
|
&Block{
|
||||||
|
Type: "block",
|
||||||
|
Labels: nil,
|
||||||
|
Body: &Body{
|
||||||
|
Attributes: Attributes{},
|
||||||
|
Blocks: Blocks{},
|
||||||
|
|
||||||
|
SrcRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
},
|
||||||
|
EndRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
TypeRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
},
|
||||||
|
LabelRanges: nil,
|
||||||
|
OpenBraceRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
||||||
|
},
|
||||||
|
CloseBraceRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
SrcRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
},
|
||||||
|
EndRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 9, Byte: 8},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"block {}block {}\n",
|
"block {}block {}\n",
|
||||||
1, // missing newline after block definition
|
1, // missing newline after block definition
|
||||||
@ -405,6 +453,47 @@ block "valid" {}
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"a = 1",
|
||||||
|
0,
|
||||||
|
&Body{
|
||||||
|
Attributes: Attributes{
|
||||||
|
"a": {
|
||||||
|
Name: "a",
|
||||||
|
Expr: &LiteralValueExpr{
|
||||||
|
Val: cty.NumberIntVal(1),
|
||||||
|
|
||||||
|
SrcRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
SrcRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
},
|
||||||
|
NameRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 2, Byte: 1},
|
||||||
|
},
|
||||||
|
EqualsRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Blocks: Blocks{},
|
||||||
|
SrcRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
},
|
||||||
|
EndRange: hcl.Range{
|
||||||
|
Start: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"a = \"hello ${true}\"\n",
|
"a = \"hello ${true}\"\n",
|
||||||
0,
|
0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user