Coverage for /pythoncovmergedfiles/medio/medio/src/underscore/underscore/variable_finder.py: 98%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Copyright (c) 2013 Huan Do, http://huan.do
3import ast
4from collections import deque
6class VariableFinder(ast.NodeVisitor):
8 def __init__(self, env):
9 self.env = env
10 self.visit_queue = deque()
11 self._conditional_stack = []
12 self._global = False
14 def visit(self, node):
15 """Does a bfs, visit_queue will elements put inside of it
16 as it visits."""
17 ast.NodeVisitor.visit(self, node)
18 while self.visit_queue:
19 node = self.visit_queue.popleft()
20 with self.env.Frame(node):
21 ast.NodeVisitor.generic_visit(self, node)
23 def visit_arguments(self, node):
24 for arg in node.args:
25 self.generic_declare(arg)
26 if node.vararg:
27 self.generic_declare(node.vararg)
28 if node.kwarg:
29 self.generic_declare(node.kwarg)
31 def visit_Assign(self, node):
32 for target in node.targets:
33 self.generic_declare(target)
34 ast.NodeVisitor.generic_visit(self, node)
36 def visit_Lambda(self, node):
37 with self.env.extend_frame(node):
38 self.visit_queue.append(node)
40 def new_scope(self, node):
41 self.generic_declare(node.name)
42 with self.env.extend_frame(node):
43 self.visit_queue.append(node)
45 visit_ClassDef = visit_FunctionDef = new_scope
47 def visit_ExceptHandler(self, node):
48 if isinstance(node.name, ast.Name):
49 self.generic_declare(node.name)
50 ast.NodeVisitor.generic_visit(self, node)
52 def visit_For(self, node):
53 self._conditional_stack.append(node)
54 self.generic_declare(node.target)
55 ast.NodeVisitor.generic_visit(self, node)
56 assert node == self._conditional_stack.pop()
58 def visit_Global(self, node):
59 for name in node.names:
60 self._global = True
61 self.generic_declare(name)
62 self._global = False
64 def visit_ImportFrom(self, node):
65 if node.module != '__future__':
66 for alias in node.names:
67 if alias.name == '*':
68 self.env.starred = True
69 continue
70 if alias.asname is None:
71 alias.asname = alias.name
72 self.generic_declare(alias.asname)
74 def visit_Import(self, node):
75 for alias in node.names:
76 if '.' in alias.name:
77 name = alias.name[:alias.name.index('.')]
78 self.env.current_frame.add(
79 name,
80 False,
81 bool(self._conditional_stack))
82 continue
83 if alias.asname is None:
84 alias.asname = alias.name
85 self.generic_declare(alias.asname)
87 def visit_If(self, node):
88 self._conditional_stack.append(node)
89 self.generic_visit(node)
90 assert node == self._conditional_stack.pop()
92 visit_While = visit_TryExcept = visit_If
94 def visit_With(self, node):
95 # XXX: Python >= 3, each with statement can have multiple with items
96 if hasattr(node, 'items'):
97 for with_item in node.items:
98 self.generic_visit(with_item)
100 if hasattr(node, 'optional_vars'):
101 self.generic_declare(node.optional_vars)
103 self.generic_visit(node)
105 visit_withitem = visit_With
107 def scope_generators(self, generators):
108 if generators:
109 first = generators[0]
110 rest = generators[1:]
111 with self.env.extend_frame(first):
112 self.visit_comprehension(first)
113 self.scope_generators(rest)
115 def visit_Delete(self, node):
116 for target in node.targets:
117 if isinstance(target, ast.Name):
118 self.notify_delete(target)
120 def notify_delete(self, node):
121 decl = self.env.current_frame.declarations.get(node.id)
122 if decl:
123 decl.delete = True
125 def visit_Comprehensions(self, node):
126 self.scope_generators(node.generators)
128 visit_DictComp = visit_ListComp = visit_SetComp = visit_Comprehensions
130 def visit_comprehension(self, node):
131 self.generic_declare(node.target)
133 def generic_declare(self, target):
134 specific_declare = 'declare_' + type(target).__name__
135 getattr(self, specific_declare)(target)
137 def declare_str(self, name):
138 self.env.current_frame.add(
139 name,
140 self._global,
141 bool(self._conditional_stack))
143 def declare_Name(self, node):
144 self.generic_declare(node.id)
146 def declare_arg(self, node):
147 self.generic_declare(node.arg)
149 def declare_Subscript(self, node):
150 ast.NodeVisitor.generic_visit(self, node)
152 declare_Attribute = declare_Subscript
154 def declare_Tuple(self, node):
155 for element in node.elts:
156 self.generic_declare(element)
158 declare_List = declare_Tuple