Anonymous avatar Anonymous committed 261cb6d

findit: added findit.find_definition()

Comments (0)

Files changed (2)

rope/contrib/findit.py

     return _find_locations(finder, resources, job_set)
 
 
+def find_definition(project, code, offset, resource=None):
+    """Return the definition location of the python name at `offset`
+
+    A `Location` object is returned if the definition location can be
+    determined, otherwise ``None`` is returned.
+    """
+    pymodule = project.pycore.get_string_module(code, resource)
+    pyname = rope.base.evaluate.eval_location(pymodule, offset)
+    if pyname is not None:
+        module, lineno = pyname.get_definition_location()
+        name = rope.base.worder.Worder(code).get_word_at(offset)
+        if lineno is not None:
+            start = pymodule.lines.get_line_start(lineno)
+            def myfilter(occurrence):
+                if occurrence.offset < start:
+                    return False
+            pyname_filter = occurrences.PyNameFilter(pyname)
+            finder = occurrences.Finder(project.pycore, name,
+                                        [myfilter, pyname_filter])
+            for occurrence in finder.find_occurrences(pymodule=pymodule):
+                return Location(occurrence)
+
+
 class Location(object):
 
-    resource = None
-    offset = None
-    lineno = None
-    unsure = False
+    def __init__(self, occurrence):
+        self.resource = occurrence.resource
+        self.offset = occurrence.get_word_range()[0]
+        self.unsure = occurrence.is_unsure()
+        self.lineno = occurrence.lineno
 
 
 def _find_locations(finder, resources, job_set):
     for resource in resources:
         job_set.started_job(resource.path)
         for occurrence in finder.find_occurrences(resource):
-            location = Location()
-            location.resource = resource
-            location.offset = occurrence.get_word_range()[0]
-            location.unsure = occurrence.is_unsure()
-            location.lineno = occurrence.lineno
+            location = Location(occurrence)
             result.append(location)
         job_set.finished_job()
     return result

ropetest/contrib/findittest.py

 from rope.base import exceptions
 import unittest
 
-from rope.contrib.findit import find_occurrences, find_implementations
+from rope.contrib.findit import (find_occurrences, find_implementations,
+                                 find_definition)
 from ropetest import testutils
 
 
         offset = mod1.read().index('A')
         result = find_implementations(self.project, mod1, offset)
 
+    def test_trivial_find_definition(self):
+        code = 'def a_func():\n    pass\na_func()'
+        result = find_definition(self.project, code, len(code) - 3)
+        self.assertEquals(code.index('a_func'), result.offset)
+        self.assertEquals(None, result.resource)
+        self.assertEquals(1, result.lineno)
+
 
 def suite():
     result = unittest.TestSuite()
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.