hclsyntax: produce stub body when block parsing fails
The contract for our parser is that in the case of errors our result is stil valid, though possibly incomplete, so that development tools can still do analysis of the parts of the result we _were_ able to parse. However, we were previously failing to meet that contract in the presence of certain syntax errors during block parsing, where we were producing a nil body instead of a valid empty one. Now we'll produce an empty placeholder body if for any reason we don't have a real one before we return from block parsing, which then allows analysis tools to see that the containing block was present but makes its content appear totally empty. This is always done in conjunction with returning an error, so a calling application will not be mislead into thinking it is a complete result even though parts are missing.
This commit is contained in:
parent
640445e163
commit
6a61d80ae3
@ -417,6 +417,17 @@ Token:
|
||||
p.recoverAfterBodyItem()
|
||||
}
|
||||
|
||||
// We must never produce a nil body, since the caller may attempt to
|
||||
// do analysis of a partial result when there's an error, so we'll
|
||||
// insert a placeholder if we otherwise failed to produce a valid
|
||||
// body due to one of the syntax error paths above.
|
||||
if body == nil && diags.HasErrors() {
|
||||
body = &Body{
|
||||
SrcRange: hcl.RangeBetween(oBrace.Range, cBraceRange),
|
||||
EndRange: cBraceRange,
|
||||
}
|
||||
}
|
||||
|
||||
return &Block{
|
||||
Type: blockType,
|
||||
Labels: labels,
|
||||
|
@ -179,6 +179,51 @@ func TestParseConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"block { block {} }\n",
|
||||
1, // can't nest another block in the single-line block syntax
|
||||
&Body{
|
||||
Attributes: Attributes{},
|
||||
Blocks: Blocks{
|
||||
&Block{
|
||||
Type: "block",
|
||||
Labels: nil,
|
||||
Body: &Body{
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
},
|
||||
EndRange: hcl.Range{ // Parser recovery behavior leaves us after this whole construct, on the next line
|
||||
Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
},
|
||||
},
|
||||
|
||||
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{ // Parser recovery behavior leaves us after this whole construct, on the next line
|
||||
Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
},
|
||||
},
|
||||
},
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
},
|
||||
EndRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 19},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"block \"foo\" {}\n",
|
||||
0,
|
||||
|
Loading…
Reference in New Issue
Block a user