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

115 statements  

1# Copyright (c) 2013 Huan Do, http://huan.do 

2 

3import ast 

4from collections import deque 

5 

6class VariableFinder(ast.NodeVisitor): 

7 

8 def __init__(self, env): 

9 self.env = env 

10 self.visit_queue = deque() 

11 self._conditional_stack = [] 

12 self._global = False 

13 

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) 

22 

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) 

30 

31 def visit_Assign(self, node): 

32 for target in node.targets: 

33 self.generic_declare(target) 

34 ast.NodeVisitor.generic_visit(self, node) 

35 

36 def visit_Lambda(self, node): 

37 with self.env.extend_frame(node): 

38 self.visit_queue.append(node) 

39 

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) 

44 

45 visit_ClassDef = visit_FunctionDef = new_scope 

46 

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) 

51 

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() 

57 

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 

63 

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) 

73 

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) 

86 

87 def visit_If(self, node): 

88 self._conditional_stack.append(node) 

89 self.generic_visit(node) 

90 assert node == self._conditional_stack.pop() 

91 

92 visit_While = visit_TryExcept = visit_If 

93 

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) 

99 

100 if hasattr(node, 'optional_vars'): 

101 self.generic_declare(node.optional_vars) 

102 

103 self.generic_visit(node) 

104 

105 visit_withitem = visit_With 

106 

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) 

114 

115 def visit_Delete(self, node): 

116 for target in node.targets: 

117 if isinstance(target, ast.Name): 

118 self.notify_delete(target) 

119 

120 def notify_delete(self, node): 

121 decl = self.env.current_frame.declarations.get(node.id) 

122 if decl: 

123 decl.delete = True 

124 

125 def visit_Comprehensions(self, node): 

126 self.scope_generators(node.generators) 

127 

128 visit_DictComp = visit_ListComp = visit_SetComp = visit_Comprehensions 

129 

130 def visit_comprehension(self, node): 

131 self.generic_declare(node.target) 

132 

133 def generic_declare(self, target): 

134 specific_declare = 'declare_' + type(target).__name__ 

135 getattr(self, specific_declare)(target) 

136 

137 def declare_str(self, name): 

138 self.env.current_frame.add( 

139 name, 

140 self._global, 

141 bool(self._conditional_stack)) 

142 

143 def declare_Name(self, node): 

144 self.generic_declare(node.id) 

145 

146 def declare_arg(self, node): 

147 self.generic_declare(node.arg) 

148 

149 def declare_Subscript(self, node): 

150 ast.NodeVisitor.generic_visit(self, node) 

151 

152 declare_Attribute = declare_Subscript 

153 

154 def declare_Tuple(self, node): 

155 for element in node.elts: 

156 self.generic_declare(element) 

157 

158 declare_List = declare_Tuple