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
|
from multimethods import multimethod
from ql.ast.nodes.expressions.binary_operators.binary_operator import BinaryOperatorNode
from ql.ast.nodes.expressions.literals.literal import LiteralNode
from ql.ast.nodes.expressions.unary_operators.unary_operator import UnaryOperatorNode
from ql.ast.nodes.expressions.variable import VariableNode
from ql.ast.nodes.statements.form_statement import FormNode
from ql.ast.nodes.statements.if_statement import IfNode
from ql.ast.nodes.statements.question_statement import QuestionNode
class ReferenceVisitor:
def __init__(self):
self.__current_block = []
self.__current_scope = {}
@property
def identifier_scopes(self):
return self.__current_scope
@multimethod(FormNode)
def visit(self, node):
self.__current_scope = {
'content': [],
'children': [],
}
self.__current_block = []
for child in node.block:
child.accept(self)
self.__current_scope['content'] = self.__current_block
@multimethod(IfNode)
def visit(self, node):
node.condition.accept(self)
self.__current_scope['content'] += self.__current_block
previous_scope = self.__current_scope
previous_block = self.__current_block
self.__current_block = []
self.__current_scope = {
'content': [],
'children': [],
}
for child in node.block:
child.accept(self)
self.__current_scope['content'] = self.__current_block
previous_scope['children'].append(self.__current_scope)
self.__current_block = previous_block
self.__current_scope = previous_scope
@multimethod(QuestionNode)
def visit(self, node):
self.__current_block.append(dict({
'name': node.identifier,
'type': node.answer_type,
'line': node.metadata.line,
}))
if node.computed:
node.answer.accept(self)
@multimethod(BinaryOperatorNode)
def visit(self, node):
node.left_expression.accept(self)
node.right_expression.accept(self)
@multimethod(UnaryOperatorNode)
def visit(self, node):
node.expression.accept(self)
@multimethod(VariableNode)
def visit(self, node):
name = node.identifier
self.__current_block.append({
'name': name,
'type': [],
'line': node.metadata.line,
})
@multimethod(LiteralNode)
def visit(self, node):
pass
|