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) {
|
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) {
|
func (p *parser) finishParsingBodyBlock(ident Token) (Node, zcl.Diagnostics) {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
"github.com/zclconf/go-zcl/zcl"
|
"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{
|
prettyConfig := &pretty.Config{
|
||||||
|
@ -92,6 +92,7 @@ type Attribute struct {
|
|||||||
Name string
|
Name string
|
||||||
Expr Expression
|
Expr Expression
|
||||||
|
|
||||||
|
SrcRange zcl.Range
|
||||||
NameRange zcl.Range
|
NameRange zcl.Range
|
||||||
EqualsRange zcl.Range
|
EqualsRange zcl.Range
|
||||||
}
|
}
|
||||||
@ -101,7 +102,7 @@ func (a *Attribute) walkChildNodes(w internalWalkFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Attribute) Range() zcl.Range {
|
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.
|
// Blocks is the list of nested blocks within a body.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user