...

Source file src/github.com/noirbizarre/gonja/nodes/nodes.go

Documentation: github.com/noirbizarre/gonja/nodes

     1  package nodes
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/noirbizarre/gonja/tokens"
     9  	u "github.com/noirbizarre/gonja/utils"
    10  )
    11  
    12  // ----------------------------------------------------------------------------
    13  // Interfaces
    14  //
    15  // There are 3 main classes of nodes: Expressions and type nodes,
    16  // statement nodes, and declaration nodes. The node names usually
    17  // match the corresponding Go spec production names to which they
    18  // correspond. The node fields correspond to the individual parts
    19  // of the respective productions.
    20  //
    21  // All nodes contain position information marking the beginning of
    22  // the corresponding source text segment; it is accessible via the
    23  // Pos accessor method. Nodes may contain additional position info
    24  // for language constructs where comments may be found between parts
    25  // of the construct (typically any larger, parenthesized subpart).
    26  // That position information is needed to properly position comments
    27  // when printing the construct.
    28  
    29  // All node types implement the Node interface.
    30  type Node interface {
    31  	fmt.Stringer
    32  	Position() *tokens.Token
    33  }
    34  
    35  // Expression represents an evaluable expression part
    36  type Expression interface {
    37  	Node
    38  }
    39  
    40  // Statement represents a statement block "{% %}"
    41  type Statement interface {
    42  	Node
    43  }
    44  
    45  // Template is the root node of any template
    46  type Template struct {
    47  	Name   string
    48  	Nodes  []Node
    49  	Blocks BlockSet
    50  	Macros map[string]*Macro
    51  	Parent *Template
    52  }
    53  
    54  func (t *Template) Position() *tokens.Token { return t.Nodes[0].Position() }
    55  func (t *Template) String() string {
    56  	tok := t.Position()
    57  	return fmt.Sprintf("Template(Name=%s Line=%d Col=%d)", t.Name, tok.Line, tok.Col)
    58  }
    59  
    60  func (tpl *Template) GetBlocks(name string) []*Wrapper {
    61  	var blocks []*Wrapper
    62  	if tpl.Parent != nil {
    63  		blocks = tpl.Parent.GetBlocks(name)
    64  	} else {
    65  		blocks = []*Wrapper{}
    66  	}
    67  	block, exists := tpl.Blocks[name]
    68  	if exists {
    69  		blocks = append([]*Wrapper{block}, blocks...)
    70  	}
    71  	return blocks
    72  }
    73  
    74  type Trim struct {
    75  	Left  bool
    76  	Right bool
    77  }
    78  
    79  type Data struct {
    80  	Data *tokens.Token // data token
    81  }
    82  
    83  func (d *Data) Position() *tokens.Token { return d.Data }
    84  
    85  // func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
    86  func (c *Data) String() string {
    87  	return fmt.Sprintf("Data(text=%s Line=%d Col=%d)",
    88  		u.Ellipsis(c.Data.Val, 20), c.Data.Line, c.Data.Col)
    89  }
    90  
    91  // A Comment node represents a single {# #} comment.
    92  type Comment struct {
    93  	Start *tokens.Token // Opening token
    94  	Text  string        // Comment text
    95  	End   *tokens.Token // Closing token
    96  	Trim  *Trim
    97  }
    98  
    99  func (c *Comment) Position() *tokens.Token { return c.Start }
   100  
   101  // func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
   102  func (c *Comment) String() string {
   103  	return fmt.Sprintf("Comment(text=%s Line=%d Col=%d)",
   104  		u.Ellipsis(c.Text, 20), c.Start.Line, c.Start.Col)
   105  }
   106  
   107  // Ouput represents a printable expression node {{ }}
   108  type Output struct {
   109  	Start      *tokens.Token
   110  	Expression Expression
   111  	End        *tokens.Token
   112  	Trim       *Trim
   113  }
   114  
   115  func (o *Output) Position() *tokens.Token { return o.Start }
   116  func (o *Output) String() string {
   117  	return fmt.Sprintf("Output(Expression=%s Line=%d Col=%d)",
   118  		o.Expression, o.Start.Line, o.End.Col)
   119  }
   120  
   121  type FilteredExpression struct {
   122  	Expression Expression
   123  	Filters    []*FilterCall
   124  }
   125  
   126  func (expr *FilteredExpression) Position() *tokens.Token {
   127  	return expr.Expression.Position()
   128  }
   129  func (expr *FilteredExpression) String() string {
   130  	t := expr.Expression.Position()
   131  
   132  	return fmt.Sprintf("FilteredExpression(Expression=%s Line=%d Col=%d)",
   133  		expr.Expression, t.Line, t.Col)
   134  	// return fmt.Sprintf("<FilteredExpression Expression=%s", expr.Expression)
   135  }
   136  
   137  type FilterCall struct {
   138  	Token *tokens.Token
   139  
   140  	Name   string
   141  	Args   []Expression
   142  	Kwargs map[string]Expression
   143  
   144  	// filterFunc FilterFunction
   145  }
   146  
   147  type TestExpression struct {
   148  	Expression Expression
   149  	Test       *TestCall
   150  }
   151  
   152  func (expr *TestExpression) String() string {
   153  	t := expr.Position()
   154  
   155  	return fmt.Sprintf("TestExpression(Expression=%s Test=%s Line=%d Col=%d)",
   156  		expr.Expression, expr.Test, t.Line, t.Col)
   157  	// return fmt.Sprintf("TestExpression(Expression=%s Test=%s)",
   158  	// 	expr.Expression, expr.Test)
   159  }
   160  func (expr *TestExpression) Position() *tokens.Token {
   161  	return expr.Expression.Position()
   162  }
   163  
   164  type TestCall struct {
   165  	Token *tokens.Token
   166  
   167  	Name   string
   168  	Args   []Expression
   169  	Kwargs map[string]Expression
   170  
   171  	// testFunc TestFunction
   172  }
   173  
   174  func (tc *TestCall) String() string {
   175  	return fmt.Sprintf("TestCall(name=%s Line=%d Col=%d)",
   176  		tc.Name, tc.Token.Line, tc.Token.Col)
   177  }
   178  
   179  type String struct {
   180  	Location *tokens.Token
   181  	Val      string
   182  }
   183  
   184  func (s *String) Position() *tokens.Token { return s.Location }
   185  func (s *String) String() string          { return s.Location.Val }
   186  
   187  type Integer struct {
   188  	Location *tokens.Token
   189  	Val      int
   190  }
   191  
   192  func (i *Integer) Position() *tokens.Token { return i.Location }
   193  func (i *Integer) String() string          { return i.Location.Val }
   194  
   195  type Float struct {
   196  	Location *tokens.Token
   197  	Val      float64
   198  }
   199  
   200  func (f *Float) Position() *tokens.Token { return f.Location }
   201  func (f *Float) String() string          { return f.Location.Val }
   202  
   203  type Bool struct {
   204  	Location *tokens.Token
   205  	Val      bool
   206  }
   207  
   208  func (b *Bool) Position() *tokens.Token { return b.Location }
   209  func (b *Bool) String() string          { return b.Location.Val }
   210  
   211  type Name struct {
   212  	Name *tokens.Token
   213  }
   214  
   215  func (n *Name) Position() *tokens.Token { return n.Name }
   216  func (n *Name) String() string {
   217  	t := n.Position()
   218  	return fmt.Sprintf("Name(Val=%s Line=%d Col=%d)", t.Val, t.Line, t.Col)
   219  }
   220  
   221  type List struct {
   222  	Location *tokens.Token
   223  	Val      []Expression
   224  }
   225  
   226  func (l *List) Position() *tokens.Token { return l.Location }
   227  func (l *List) String() string          { return l.Location.Val }
   228  
   229  type Tuple struct {
   230  	Location *tokens.Token
   231  	Val      []Expression
   232  }
   233  
   234  func (t *Tuple) Position() *tokens.Token { return t.Location }
   235  func (t *Tuple) String() string          { return t.Location.Val }
   236  
   237  type Dict struct {
   238  	Token *tokens.Token
   239  	Pairs []*Pair
   240  }
   241  
   242  func (d *Dict) Position() *tokens.Token { return d.Token }
   243  func (d *Dict) String() string          { return d.Token.Val }
   244  
   245  type Pair struct {
   246  	Key   Expression
   247  	Value Expression
   248  }
   249  
   250  func (p *Pair) Position() *tokens.Token { return p.Key.Position() }
   251  func (p *Pair) String() string {
   252  	t := p.Position()
   253  	return fmt.Sprintf("Pair(Key=%s Value=%s Line=%d Col=%d)", p.Key, p.Value, t.Line, t.Col)
   254  }
   255  
   256  type Variable struct {
   257  	Location *tokens.Token
   258  
   259  	Parts []*VariablePart
   260  }
   261  
   262  func (v *Variable) Position() *tokens.Token { return v.Location }
   263  func (v *Variable) String() string {
   264  	parts := make([]string, 0, len(v.Parts))
   265  	for _, p := range v.Parts {
   266  		switch p.Type {
   267  		case VarTypeInt:
   268  			parts = append(parts, strconv.Itoa(p.I))
   269  		case VarTypeIdent:
   270  			parts = append(parts, p.S)
   271  		default:
   272  			panic("unimplemented")
   273  		}
   274  	}
   275  	return strings.Join(parts, ".")
   276  }
   277  
   278  const (
   279  	VarTypeInt = iota
   280  	VarTypeIdent
   281  )
   282  
   283  type VariablePart struct {
   284  	Type int
   285  	S    string
   286  	I    int
   287  
   288  	IsFunctionCall bool
   289  	// callingArgs    []functionCallArgument // needed for a function call, represents all argument nodes (Node supports nested function calls)
   290  	Args   []Expression
   291  	Kwargs map[string]Expression
   292  }
   293  
   294  func (vp *VariablePart) String() string {
   295  	return fmt.Sprintf("VariablePart(S=%s I=%d)", vp.S, vp.I)
   296  }
   297  
   298  type Call struct {
   299  	Location *tokens.Token
   300  	Func     Node
   301  	Args     []Expression
   302  	Kwargs   map[string]Expression
   303  }
   304  
   305  func (c *Call) Position() *tokens.Token { return c.Location }
   306  func (c *Call) String() string {
   307  	t := c.Position()
   308  	return fmt.Sprintf("Call(Args=%s Kwargs=%s Line=%d Col=%d)", c.Args, c.Kwargs, t.Line, t.Col)
   309  }
   310  
   311  type Getitem struct {
   312  	Location *tokens.Token
   313  	Node     Node
   314  	Arg      string
   315  	Index    int
   316  }
   317  
   318  func (g *Getitem) Position() *tokens.Token { return g.Location }
   319  func (g *Getitem) String() string {
   320  	t := g.Position()
   321  	var param string
   322  	if g.Arg != "" {
   323  		param = fmt.Sprintf(`Arg=%s`, g.Arg)
   324  	} else {
   325  		param = fmt.Sprintf(`Index=%s`, strconv.Itoa(g.Index))
   326  	}
   327  	return fmt.Sprintf("Getitem(Node=%s %s Line=%d Col=%d)", g.Node, param, t.Line, t.Col)
   328  }
   329  
   330  type Getattr struct {
   331  	Location *tokens.Token
   332  	Node     Node
   333  	Attr     string
   334  	Index    int
   335  }
   336  
   337  func (g *Getattr) Position() *tokens.Token { return g.Location }
   338  func (g *Getattr) String() string {
   339  	t := g.Position()
   340  	var param string
   341  	if g.Attr != "" {
   342  		param = fmt.Sprintf(`Attr=%s`, g.Attr)
   343  	} else {
   344  		param = fmt.Sprintf(`Index=%s`, strconv.Itoa(g.Index))
   345  	}
   346  	return fmt.Sprintf("Getattr(Node=%s %s Line=%d Col=%d)", g.Node, param, t.Line, t.Col)
   347  }
   348  
   349  type Negation struct {
   350  	Term     Expression
   351  	Operator *tokens.Token
   352  }
   353  
   354  func (n *Negation) Position() *tokens.Token { return n.Operator }
   355  func (n *Negation) String() string {
   356  	t := n.Operator
   357  	return fmt.Sprintf("Negation(term=%s Line=%d Col=%d)", n.Term, t.Line, t.Col)
   358  }
   359  
   360  type UnaryExpression struct {
   361  	Negative bool
   362  	Term     Expression
   363  	Operator *tokens.Token
   364  }
   365  
   366  func (u *UnaryExpression) Position() *tokens.Token { return u.Operator }
   367  func (u *UnaryExpression) String() string {
   368  	t := u.Operator
   369  
   370  	return fmt.Sprintf("UnaryExpression(sign=%s term=%s Line=%d Col=%d)",
   371  		t.Val, u.Term, t.Line, t.Col)
   372  }
   373  
   374  type BinaryExpression struct {
   375  	Left     Expression
   376  	Right    Expression
   377  	Operator *BinOperator
   378  }
   379  
   380  func (b *BinaryExpression) Position() *tokens.Token { return b.Left.Position() }
   381  func (expr *BinaryExpression) String() string {
   382  	t := expr.Position()
   383  
   384  	return fmt.Sprintf("BinaryExpression(operator=%s left=%s right=%s Line=%d Col=%d)",
   385  		expr.Operator.Token.Val, expr.Left, expr.Right, t.Line, t.Col)
   386  }
   387  
   388  type BinOperator struct {
   389  	Token *tokens.Token
   390  }
   391  
   392  func (op BinOperator) Position() *tokens.Token { return op.Token }
   393  func (op BinOperator) String() string          { return op.Token.String() }
   394  
   395  type StatementBlock struct {
   396  	Location *tokens.Token
   397  	Name     string
   398  	Stmt     Statement
   399  	Trim     *Trim
   400  	LStrip   bool
   401  }
   402  
   403  func (s StatementBlock) Position() *tokens.Token { return s.Location }
   404  func (s StatementBlock) String() string {
   405  	t := s.Position()
   406  
   407  	return fmt.Sprintf("StatementBlock(Name=%s Impl=%s Line=%d Col=%d)",
   408  		s.Name, s.Stmt, t.Line, t.Col)
   409  }
   410  
   411  type Wrapper struct {
   412  	Location *tokens.Token
   413  	Nodes    []Node
   414  	EndTag   string
   415  	Trim     *Trim
   416  	LStrip   bool
   417  }
   418  
   419  func (w Wrapper) Position() *tokens.Token { return w.Location }
   420  func (w Wrapper) String() string {
   421  	t := w.Position()
   422  
   423  	return fmt.Sprintf("Wrapper(Nodes=%s EndTag=%s Line=%d Col=%d)",
   424  		w.Nodes, w.EndTag, t.Line, t.Col)
   425  }
   426  
   427  type Macro struct {
   428  	Location *tokens.Token
   429  	Name     string
   430  	Args     []string
   431  	Kwargs   []*Pair
   432  	Wrapper  *Wrapper
   433  }
   434  
   435  func (m *Macro) Position() *tokens.Token { return m.Location }
   436  func (m *Macro) String() string {
   437  	t := m.Position()
   438  	return fmt.Sprintf("Macro(Name=%s Args=%s Kwargs=%s Line=%d Col=%d)", m.Name, m.Args, m.Kwargs, t.Line, t.Col)
   439  }
   440  

View as plain text