Anonymous avatar Anonymous committed 758b056

finderrors: finding unresolved variables

Comments (0)

Files changed (2)

rope/contrib/finderrors.py

+from rope.base import ast, evaluate
+
+
+def find_errors(project, resource):
+    pymodule = project.pycore.resource_to_pyobject(resource)
+    finder = _BadAccessFinder(pymodule)
+    ast.walk(pymodule.get_ast(), finder)
+    return finder.errors
+
+
+class _BadAccessFinder(object):
+
+    def __init__(self, pymodule):
+        self.pymodule = pymodule
+        self.scope = pymodule.get_scope()
+        self.errors = []
+
+    def _Name(self, node):
+        if isinstance(node.ctx, (ast.Store, ast.Param)):
+            return
+        scope = self.scope.get_inner_scope_for_line(node.lineno)
+        pyname = scope.lookup(node.id)
+        if pyname is None:
+            self._add_error(node, 'Unresolved variable')
+        elif self._is_defined_after(scope, pyname, node.lineno):
+            self._add_error(node, 'Defined later')
+
+    def _add_error(self, node, msg):
+        error = Error(node.lineno, msg + ' %s' % node.id)
+        self.errors.append(error)
+
+    def _is_defined_after(self, scope, pyname, lineno):
+        location = pyname.get_definition_location()
+        if location is not None and location[1] is not None:
+            if location[0] == self.pymodule and \
+               lineno <= location[1] <= scope.get_end():
+                return True
+
+
+class Error(object):
+
+    def __init__(self, lineno, error):
+        self.lineno = lineno
+        self.error = error
+
+    def __str__(self):
+        return '%s: %s' % (self.lineno, self.error)

ropetest/contrib/finderrorstest.py

+import unittest
+
+from rope.contrib import finderrors
+from ropetest import testutils
+
+
+class FindErrorsTest(unittest.TestCase):
+
+    def setUp(self):
+        super(FindErrorsTest, self).setUp()
+        self.project = testutils.sample_project()
+        self.mod = self.project.root.create_file('mod.py')
+
+    def tearDown(self):
+        testutils.remove_project(self.project)
+        super(FindErrorsTest, self).tearDown()
+
+    def test_unresolved_variables(self):
+        self.mod.write('print(var)\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(1, len(result))
+        self.assertEquals(1, result[0].lineno)
+
+    def test_defined_later(self):
+        self.mod.write('print(var)\nvar = 1\n')
+        result = finderrors.find_errors(self.project, self.mod)
+        self.assertEquals(1, len(result))
+        self.assertEquals(1, result[0].lineno)
+
+if __name__ == '__main__':
+    unittest.main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.