mirror of
https://github.com/danog/liquid.git
synced 2024-11-30 09:59:02 +01:00
Embed the Chunk in the AST nodes
This commit is contained in:
parent
20e4df31d3
commit
089a0c8125
@ -9,29 +9,34 @@ type ASTNode interface {
|
||||
Render(io.Writer, Context) error
|
||||
}
|
||||
|
||||
// ASTSeq is a sequence of nodes.
|
||||
type ASTSeq struct {
|
||||
Children []ASTNode
|
||||
}
|
||||
|
||||
// TODO probably safe to remove this type and method, once the test suite is larger
|
||||
type ASTChunks struct {
|
||||
chunks []Chunk
|
||||
}
|
||||
|
||||
// ASTGenericTag renders itself via a render function that is created during parsing.
|
||||
type ASTGenericTag struct {
|
||||
chunk Chunk
|
||||
render func(io.Writer, Context) error
|
||||
}
|
||||
|
||||
// ASTText is a text chunk, that is rendered verbatim.
|
||||
type ASTText struct {
|
||||
chunk Chunk
|
||||
Chunk
|
||||
}
|
||||
|
||||
// ASTObject is an {{ object }} object.
|
||||
type ASTObject struct {
|
||||
chunk Chunk
|
||||
Chunk
|
||||
}
|
||||
|
||||
// ASTControlTag is a control tag.
|
||||
type ASTControlTag struct {
|
||||
chunk Chunk
|
||||
Chunk
|
||||
cd *ControlTagDefinition
|
||||
body []ASTNode
|
||||
branches []*ASTControlTag
|
||||
|
@ -100,7 +100,7 @@ func (ct *ControlTagDefinition) Action(fn ControlTagAction) {
|
||||
|
||||
func ifTagAction(polarity bool) func(*ASTControlTag) func(io.Writer, Context) error {
|
||||
return func(n *ASTControlTag) func(io.Writer, Context) error {
|
||||
expr, err := makeExpressionValueFn(n.chunk.Args)
|
||||
expr, err := makeExpressionValueFn(n.Args)
|
||||
if err != nil {
|
||||
return func(io.Writer, Context) error { return err }
|
||||
}
|
||||
@ -117,11 +117,11 @@ func ifTagAction(polarity bool) func(*ASTControlTag) func(io.Writer, Context) er
|
||||
return renderASTSequence(w, n.body, ctx)
|
||||
case nil, false:
|
||||
for _, c := range n.branches {
|
||||
switch c.chunk.Tag {
|
||||
switch c.Tag {
|
||||
case "else":
|
||||
val = true
|
||||
case "elsif":
|
||||
val, err = ctx.EvaluateExpr(c.chunk.Args)
|
||||
val, err = ctx.EvaluateExpr(c.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (n ASTChunks) MarshalYAML() (interface{}, error) {
|
||||
func (n ASTControlTag) MarshalYAML() (interface{}, error) {
|
||||
return map[string]map[string]interface{}{
|
||||
n.cd.Name: {
|
||||
"args": n.chunk.Args,
|
||||
"args": n.Args,
|
||||
"body": n.body,
|
||||
"branches": n.branches,
|
||||
}}, nil
|
||||
@ -46,10 +46,10 @@ func (n ASTControlTag) MarshalYAML() (interface{}, error) {
|
||||
|
||||
// MarshalYAML marshalls a chunk for debugging.
|
||||
func (n ASTText) MarshalYAML() (interface{}, error) {
|
||||
return n.chunk.MarshalYAML()
|
||||
return n.Chunk.MarshalYAML()
|
||||
}
|
||||
|
||||
// MarshalYAML marshalls a chunk for debugging.
|
||||
func (n ASTObject) MarshalYAML() (interface{}, error) {
|
||||
return n.chunk.MarshalYAML()
|
||||
return n.Chunk.MarshalYAML()
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ func Parse(chunks []Chunk) (ASTNode, error) {
|
||||
for _, c := range chunks {
|
||||
switch c.Type {
|
||||
case ObjChunkType:
|
||||
*ap = append(*ap, &ASTObject{chunk: c})
|
||||
*ap = append(*ap, &ASTObject{Chunk: c})
|
||||
case TextChunkType:
|
||||
*ap = append(*ap, &ASTText{chunk: c})
|
||||
*ap = append(*ap, &ASTText{Chunk: c})
|
||||
case TagChunkType:
|
||||
if cd, ok := FindControlDefinition(c.Tag); ok {
|
||||
switch {
|
||||
@ -35,11 +35,11 @@ func Parse(chunks []Chunk) (ASTNode, error) {
|
||||
return nil, fmt.Errorf("%s not inside %s%s", cd.Name, cd.Parent.Name, suffix)
|
||||
case cd.IsStartTag():
|
||||
stack = append(stack, frame{cd: ccd, cn: ccn, ap: ap})
|
||||
ccd, ccn = cd, &ASTControlTag{chunk: c, cd: cd}
|
||||
ccd, ccn = cd, &ASTControlTag{Chunk: c, cd: cd}
|
||||
*ap = append(*ap, ccn)
|
||||
ap = &ccn.body
|
||||
case cd.IsBranchTag:
|
||||
n := &ASTControlTag{chunk: c, cd: cd}
|
||||
n := &ASTControlTag{Chunk: c, cd: cd}
|
||||
ccn.branches = append(ccn.branches, n)
|
||||
ap = &n.body
|
||||
case cd.IsEndTag:
|
||||
@ -51,7 +51,7 @@ func Parse(chunks []Chunk) (ASTNode, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*ap = append(*ap, &ASTGenericTag{chunk: c, render: f})
|
||||
*ap = append(*ap, &ASTGenericTag{render: f})
|
||||
} else {
|
||||
return nil, fmt.Errorf("unknown tag: %s", c.Tag)
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ func (n *ASTGenericTag) Render(w io.Writer, ctx Context) error {
|
||||
|
||||
// Render evaluates an AST node and writes the result to an io.Writer.
|
||||
func (n *ASTText) Render(w io.Writer, _ Context) error {
|
||||
_, err := w.Write([]byte(n.chunk.Source))
|
||||
_, err := w.Write([]byte(n.Source))
|
||||
return err
|
||||
}
|
||||
|
||||
@ -45,9 +45,9 @@ func renderASTSequence(w io.Writer, seq []ASTNode, ctx Context) error {
|
||||
|
||||
// Render evaluates an AST node and writes the result to an io.Writer.
|
||||
func (n *ASTControlTag) Render(w io.Writer, ctx Context) error {
|
||||
cd, ok := FindControlDefinition(n.chunk.Tag)
|
||||
cd, ok := FindControlDefinition(n.Tag)
|
||||
if !ok {
|
||||
return fmt.Errorf("unimplemented tag: %s", n.chunk.Tag)
|
||||
return fmt.Errorf("unimplemented tag: %s", n.Tag)
|
||||
}
|
||||
f := cd.action(n)
|
||||
return f(w, ctx)
|
||||
@ -56,7 +56,7 @@ func (n *ASTControlTag) Render(w io.Writer, ctx Context) error {
|
||||
// Render evaluates an AST node and writes the result to an io.Writer.
|
||||
func (n *ASTObject) Render(w io.Writer, ctx Context) error {
|
||||
// TODO separate this into parse and evaluate stages.
|
||||
val, err := ctx.EvaluateExpr(n.chunk.Args)
|
||||
val, err := ctx.EvaluateExpr(n.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user