1
0
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:
Oliver Steele 2017-06-27 11:19:12 -04:00
parent 20e4df31d3
commit 089a0c8125
5 changed files with 24 additions and 19 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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()
}

View File

@ -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)
}

View File

@ -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
}