hclsyntax: allow block labels to be naked identifiers
This was allowed in legacy HCL, and although it was never documented as usable in the Terraform documentation it appears that some Terraform configurations use this form anyway. While it is non-ideal to have another edge-case to support/maintain, this capability adds no ambiguity and doesn't add significant complexity, so we'll allow it to be pragmatic for existing usage.
This commit is contained in:
parent
074b73b8b5
commit
d66303f45b
@ -132,7 +132,7 @@ func (p *parser) ParseBodyItem() (Node, hcl.Diagnostics) {
|
||||
switch next.Type {
|
||||
case TokenEqual:
|
||||
return p.finishParsingBodyAttribute(ident)
|
||||
case TokenOQuote, TokenOBrace:
|
||||
case TokenOQuote, TokenOBrace, TokenIdent:
|
||||
return p.finishParsingBodyBlock(ident)
|
||||
default:
|
||||
p.recoverAfterBodyItem()
|
||||
@ -232,6 +232,12 @@ Token:
|
||||
}, diags
|
||||
}
|
||||
|
||||
case TokenIdent:
|
||||
tok = p.Read() // eat token
|
||||
label, labelRange := string(tok.Bytes), tok.Range
|
||||
labels = append(labels, label)
|
||||
labelRanges = append(labelRanges, labelRange)
|
||||
|
||||
default:
|
||||
switch tok.Type {
|
||||
case TokenEqual:
|
||||
|
@ -228,6 +228,59 @@ func TestParseConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"block foo {}\n",
|
||||
0,
|
||||
&Body{
|
||||
Attributes: Attributes{},
|
||||
Blocks: Blocks{
|
||||
&Block{
|
||||
Type: "block",
|
||||
Labels: []string{"foo"},
|
||||
Body: &Body{
|
||||
Attributes: Attributes{},
|
||||
Blocks: Blocks{},
|
||||
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
|
||||
End: hcl.Pos{Line: 1, Column: 13, Byte: 12},
|
||||
},
|
||||
EndRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 13, Byte: 12},
|
||||
End: hcl.Pos{Line: 1, Column: 13, Byte: 12},
|
||||
},
|
||||
},
|
||||
|
||||
TypeRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
},
|
||||
LabelRanges: []hcl.Range{
|
||||
{
|
||||
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
|
||||
End: hcl.Pos{Line: 1, Column: 10, Byte: 9},
|
||||
},
|
||||
},
|
||||
OpenBraceRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
|
||||
End: hcl.Pos{Line: 1, Column: 12, Byte: 11},
|
||||
},
|
||||
CloseBraceRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 12, Byte: 11},
|
||||
End: hcl.Pos{Line: 1, Column: 13, Byte: 12},
|
||||
},
|
||||
},
|
||||
},
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 13},
|
||||
},
|
||||
EndRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 2, Column: 1, Byte: 13},
|
||||
End: hcl.Pos{Line: 2, Column: 1, Byte: 13},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
`
|
||||
block "invalid" 1.2 {}
|
||||
|
@ -161,7 +161,7 @@ language-agnostic HCL information model.
|
||||
ConfigFile = Body;
|
||||
Body = (Attribute | Block)*;
|
||||
Attribute = Identifier "=" Expression Newline;
|
||||
Block = Identifier (StringLit)* "{" Newline Body "}" Newline;
|
||||
Block = Identifier (StringLit|Identifier)* "{" Newline Body "}" Newline;
|
||||
```
|
||||
|
||||
### Configuration Files
|
||||
@ -186,8 +186,10 @@ for later evaluation by the calling application.
|
||||
### Blocks
|
||||
|
||||
A _block_ creates a child body that is annotated with a block _type_ and
|
||||
zero or more optional block _labels_. Blocks create a structural heirachy
|
||||
which can be interpreted by the calling application.
|
||||
zero or more block _labels_. Blocks create a structural heirachy which can be
|
||||
interpreted by the calling application.
|
||||
|
||||
Block labels can either be quoted literal strings or naked identifiers.
|
||||
|
||||
## Expressions
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user