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
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 type Node interface {
31 fmt.Stringer
32 Position() *tokens.Token
33 }
34
35
36 type Expression interface {
37 Node
38 }
39
40
41 type Statement interface {
42 Node
43 }
44
45
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
81 }
82
83 func (d *Data) Position() *tokens.Token { return d.Data }
84
85
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
92 type Comment struct {
93 Start *tokens.Token
94 Text string
95 End *tokens.Token
96 Trim *Trim
97 }
98
99 func (c *Comment) Position() *tokens.Token { return c.Start }
100
101
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
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
135 }
136
137 type FilterCall struct {
138 Token *tokens.Token
139
140 Name string
141 Args []Expression
142 Kwargs map[string]Expression
143
144
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
158
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
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
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