zclsyntax: parsing of attributes within bodies
This commit is contained in:
parent
a1368a4d4d
commit
4d6dbdbb37
@ -151,7 +151,46 @@ func (p *parser) ParseBodyItem() (Node, zcl.Diagnostics) {
|
||||
}
|
||||
|
||||
func (p *parser) finishParsingBodyAttribute(ident Token) (Node, zcl.Diagnostics) {
|
||||
panic("attribute parsing not yet implemented")
|
||||
eqTok := p.Read() // eat equals token
|
||||
if eqTok.Type != TokenEqual {
|
||||
// should never happen if caller behaves
|
||||
panic("finishParsingBodyAttribute called with next not equals")
|
||||
}
|
||||
|
||||
expr, diags := p.ParseExpression()
|
||||
if p.recovery && diags.HasErrors() {
|
||||
// recovery within expressions tends to be tricky, so we've probably
|
||||
// landed somewhere weird. We'll try to reset to the start of a body
|
||||
// item so parsing can continue.
|
||||
p.recoverAfterBodyItem()
|
||||
} else {
|
||||
end := p.Peek()
|
||||
if end.Type != TokenNewline && end.Type != TokenEOF {
|
||||
if !p.recovery {
|
||||
diags = append(diags, &zcl.Diagnostic{
|
||||
Severity: zcl.DiagError,
|
||||
Summary: "Missing newline in attribute definition",
|
||||
Detail: "An attribute definition must end with a newline.",
|
||||
Subject: &end.Range,
|
||||
Context: zcl.RangeBetween(ident.Range, end.Range).Ptr(),
|
||||
})
|
||||
}
|
||||
p.recoverAfterBodyItem()
|
||||
} else {
|
||||
p.Read() // eat newline
|
||||
}
|
||||
}
|
||||
|
||||
endRange := p.PrevRange()
|
||||
|
||||
return &Attribute{
|
||||
Name: string(ident.Bytes),
|
||||
Expr: expr,
|
||||
|
||||
SrcRange: zcl.RangeBetween(ident.Range, endRange),
|
||||
NameRange: ident.Range,
|
||||
EqualsRange: eqTok.Range,
|
||||
}, diags
|
||||
}
|
||||
|
||||
func (p *parser) finishParsingBodyBlock(ident Token) (Node, zcl.Diagnostics) {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-zcl/zcl"
|
||||
)
|
||||
|
||||
@ -313,6 +314,48 @@ block "valid" {}
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
`a = 1`,
|
||||
0,
|
||||
&Body{
|
||||
Attributes: Attributes{
|
||||
"a": {
|
||||
Name: "a",
|
||||
Expr: &LiteralValueExpr{
|
||||
Val: cty.NumberIntVal(1),
|
||||
|
||||
SrcRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 5, Byte: 4},
|
||||
End: zcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
},
|
||||
},
|
||||
|
||||
SrcRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: zcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
},
|
||||
NameRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: zcl.Pos{Line: 1, Column: 2, Byte: 1},
|
||||
},
|
||||
EqualsRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 3, Byte: 2},
|
||||
End: zcl.Pos{Line: 1, Column: 4, Byte: 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
Blocks: Blocks{},
|
||||
SrcRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 1, Byte: 0},
|
||||
End: zcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
},
|
||||
EndRange: zcl.Range{
|
||||
Start: zcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
End: zcl.Pos{Line: 1, Column: 6, Byte: 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
prettyConfig := &pretty.Config{
|
||||
|
@ -92,6 +92,7 @@ type Attribute struct {
|
||||
Name string
|
||||
Expr Expression
|
||||
|
||||
SrcRange zcl.Range
|
||||
NameRange zcl.Range
|
||||
EqualsRange zcl.Range
|
||||
}
|
||||
@ -101,7 +102,7 @@ func (a *Attribute) walkChildNodes(w internalWalkFunc) {
|
||||
}
|
||||
|
||||
func (a *Attribute) Range() zcl.Range {
|
||||
return zcl.RangeBetween(a.NameRange, a.Expr.Range())
|
||||
return a.SrcRange
|
||||
}
|
||||
|
||||
// Blocks is the list of nested blocks within a body.
|
||||
|
Loading…
Reference in New Issue
Block a user