File: ConditionalExpr.py

package info (click to toggle)
python-stringtemplate3 3.1-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,392 kB
  • sloc: python: 8,819; makefile: 20
file content (119 lines) | stat: -rw-r--r-- 4,070 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

import antlr

from stringtemplate3.language import ASTExpr
from stringtemplate3.language import ActionEvaluator
from stringtemplate3.utils import deprecated


class ElseIfClauseData(object):
    def __init__(self, expr, st):
        self.expr = expr
        self.st = st


class ConditionalExpr(ASTExpr):
    """A conditional reference to an embedded subtemplate."""

    def __init__(self, enclosingTemplate, tree):
        super(ConditionalExpr, self).__init__(enclosingTemplate, tree, None)
        self.subtemplate = None
        self.elseIfSubtemplates = None
        self.elseSubtemplate = None


    @deprecated
    def setSubtemplate(self, subtemplate):
        self.subtemplate = subtemplate

    @deprecated
    def getSubtemplate(self):
        return self.subtemplate


    @deprecated
    def setElseSubtemplate(self, elseSubtemplate):
        self.elseSubtemplate = elseSubtemplate

    @deprecated
    def getElseSubtemplate(self):
        return self.elseSubtemplate


    def addElseIfSubtemplate(self, conditionalTree, subtemplate):
        if self.elseIfSubtemplates is None:
            self.elseIfSubtemplates = []

        d = ElseIfClauseData(conditionalTree, subtemplate)
        self.elseIfSubtemplates.append(d)


    def write(self, this, out):
        """
        To write out the value of a condition expr, invoke the evaluator in
        eval.g to walk the condition tree computing the boolean value.
        If result is true, then write subtemplate.
        """

        if self.exprTree is None or this is None or out is None:
            return 0
        
        evaluator = ActionEvaluator.Walker()
        evaluator.initialize(this, self, out)
        n = 0
        try:
            testedTrue = False
            # get conditional from tree and compute result
            cond = self.exprTree.getFirstChild()

            # eval and write out tree. In case the condition refers to an
            # undefined attribute, we catch the KeyError exception and proceed
            # with a False value.
            try:
                includeSubtemplate = evaluator.ifCondition(cond)
            except KeyError as ke:
                includeSubtemplate = False

            if includeSubtemplate:
                n = self.writeSubTemplate(this, out, self.subtemplate)
                testedTrue = True

            elif ( self.elseIfSubtemplates is not None and
                   len(self.elseIfSubtemplates) > 0 ):
                for elseIfClause in self.elseIfSubtemplates:
                    try:
                        includeSubtemplate = evaluator.ifCondition(elseIfClause.expr.exprTree)
                    except KeyError as ke:
                        includeSubtemplate = False
                    if includeSubtemplate:
                        n = self.writeSubTemplate(this, out, elseIfClause.st)
                        testedTrue = True
                        break

            if not testedTrue and self.elseSubtemplate is not None:
                # evaluate ELSE clause if present and IF/ELSEIF conditions
                # failed
                n = self.writeSubTemplate(this, out, self.elseSubtemplate)
                        
        except antlr.RecognitionException as re:
            this.error(
                "can't evaluate tree: " + self.exprTree.toStringList(), re
                )

        return n


    def writeSubTemplate(self, this, out, subtemplate):
        # To evaluate the IF chunk, make a new instance whose enclosingInstance
        # points at 'this' so get attribute works. Otherwise, enclosingInstance
        # points at the template used to make the precompiled code.  We need a
        # new template instance every time we exec this chunk to get the new
        # "enclosing instance" pointer.

        s = subtemplate.getInstanceOf()
        s.enclosingInstance = this
        # make sure we evaluate in context of enclosing template's
        # group so polymorphism works. :)
        s.group = this.group
        s.nativeGroup = this.nativeGroup
        return s.write(out)