1.1 --- a/inspector.py Thu Sep 08 18:39:38 2016 +0200
1.2 +++ b/inspector.py Thu Sep 08 21:36:58 2016 +0200
1.3 @@ -23,6 +23,7 @@
1.4 from branching import BranchTracker
1.5 from common import get_argnames, init_item, predefined_constants
1.6 from modules import BasicModule, CacheWritingModule, InspectionNaming
1.7 +from errors import InspectError
1.8 from referencing import Reference
1.9 from resolving import NameResolving
1.10 from results import AccessRef, InstanceRef, InvocationRef, LiteralSequenceRef, \
1.11 @@ -44,11 +45,6 @@
1.12 self.in_conditional = False
1.13 self.global_attr_accesses = {}
1.14
1.15 - # Nested scope handling.
1.16 -
1.17 - self.parent_function = None
1.18 - self.propagated_names = {}
1.19 -
1.20 # Usage tracking.
1.21
1.22 self.trackers = []
1.23 @@ -300,13 +296,16 @@
1.24 elif isinstance(n, compiler.ast.Tuple):
1.25 return self.get_literal_instance(n, "tuple")
1.26
1.27 - # List comprehensions and if expressions.
1.28 + # Unsupported nodes.
1.29 +
1.30 + elif isinstance(n, compiler.ast.GenExpr):
1.31 + raise InspectError("Generator expressions are not supported.", self.get_namespace_path(), n)
1.32 +
1.33 + elif isinstance(n, compiler.ast.IfExp):
1.34 + raise InspectError("If-else expressions are not supported.", self.get_namespace_path(), n)
1.35
1.36 elif isinstance(n, compiler.ast.ListComp):
1.37 - self.process_listcomp_node(n)
1.38 -
1.39 - elif isinstance(n, compiler.ast.IfExp):
1.40 - self.process_ifexp_node(n)
1.41 + raise InspectError("List comprehensions are not supported.", self.get_namespace_path(), n)
1.42
1.43 # All other nodes are processed depth-first.
1.44
1.45 @@ -580,9 +579,6 @@
1.46
1.47 # Reset conditional tracking to focus on the function contents.
1.48
1.49 - parent_function = self.parent_function
1.50 - self.parent_function = self.in_function and self.get_namespace_path() or None
1.51 -
1.52 in_conditional = self.in_conditional
1.53 self.in_conditional = False
1.54
1.55 @@ -594,34 +590,19 @@
1.56 # Track attribute usage within the namespace.
1.57
1.58 path = self.get_namespace_path()
1.59 - init_item(self.propagated_names, path, set)
1.60
1.61 self.start_tracking(locals)
1.62 self.process_structure_node(n.code)
1.63 self.stop_tracking()
1.64
1.65 - # Propagate names from parent scopes.
1.66 -
1.67 - for local in self.propagated_names[path]:
1.68 - if not local in argnames and self.trackers[-1].have_name(local):
1.69 - argnames.append(local)
1.70 - defaults.append((local, Reference("<var>")))
1.71 - self.set_function_local(local)
1.72 -
1.73 - # Exit to the parent and note propagated names.
1.74 + # Exit to the parent.
1.75
1.76 self.exit_namespace()
1.77
1.78 - parent = self.get_namespace_path()
1.79 - if self.propagated_names.has_key(parent):
1.80 - for local in self.propagated_names[path]:
1.81 - self.propagated_names[parent].add(local)
1.82 -
1.83 # Update flags.
1.84
1.85 self.in_function = in_function
1.86 self.in_conditional = in_conditional
1.87 - self.parent_function = parent_function
1.88
1.89 # Define the function using the appropriate name.
1.90
1.91 @@ -673,18 +654,6 @@
1.92
1.93 tracker.merge_branches()
1.94
1.95 - def process_ifexp_node(self, n):
1.96 -
1.97 - "Process the given if expression node 'n'."
1.98 -
1.99 - name_ref = self.process_structure_node(self.convert_ifexp_node(n))
1.100 -
1.101 - path = self.get_namespace_path()
1.102 - self.allocate_arguments(path, self.function_defaults[name_ref.get_origin()])
1.103 - self.deallocate_arguments(path, self.function_defaults[name_ref.get_origin()])
1.104 -
1.105 - return InvocationRef(name_ref)
1.106 -
1.107 def process_import_node(self, n):
1.108
1.109 "Process the given import node 'n'."
1.110 @@ -743,18 +712,6 @@
1.111 origin = self.get_object_path(name)
1.112 return ResolvedNameRef(name, Reference("<function>", origin))
1.113
1.114 - def process_listcomp_node(self, n):
1.115 -
1.116 - "Process the given list comprehension node 'n'."
1.117 -
1.118 - name_ref = self.process_structure_node(self.convert_listcomp_node(n))
1.119 -
1.120 - path = self.get_namespace_path()
1.121 - self.allocate_arguments(path, self.function_defaults[name_ref.get_origin()])
1.122 - self.deallocate_arguments(path, self.function_defaults[name_ref.get_origin()])
1.123 -
1.124 - return InvocationRef(name_ref)
1.125 -
1.126 def process_logical_node(self, n):
1.127
1.128 "Process the given operator node 'n'."
1.129 @@ -820,14 +777,7 @@
1.130
1.131 branches = tracker.tracking_name(n.name)
1.132
1.133 - # Find names inherited from a parent scope.
1.134 -
1.135 - if not branches and self.parent_function:
1.136 - branches = tracker.have_name(n.name)
1.137 - if branches:
1.138 - self.propagate_name(n.name)
1.139 -
1.140 - # Local or inherited name.
1.141 + # Local name.
1.142
1.143 if branches:
1.144 self.record_branches_for_access(branches, n.name, None)
1.145 @@ -990,12 +940,6 @@
1.146 tracker = BranchTracker()
1.147 self.trackers.append(tracker)
1.148
1.149 - # For functions created from expressions or for functions within
1.150 - # functions, propagate usage to the new namespace.
1.151 -
1.152 - if self.parent_function:
1.153 - tracker.inherit_branches(parent, names)
1.154 -
1.155 # Record the given names established as new branches.
1.156
1.157 tracker.assign_names(names)
1.158 @@ -1037,13 +981,6 @@
1.159 self.attr_usage[self.name] = tracker.get_all_usage()
1.160 self.name_initialisers[self.name] = tracker.get_all_values()
1.161
1.162 - def propagate_name(self, name):
1.163 -
1.164 - "Propagate the given 'name' into the current namespace."
1.165 -
1.166 - path = self.get_namespace_path()
1.167 - self.propagated_names[path].add(name)
1.168 -
1.169 def record_assignments_for_access(self, tracker):
1.170
1.171 """