125 lines
4.2 KiB
Python
125 lines
4.2 KiB
Python
import rope.base.codeanalyze
|
|
import rope.base.evaluate
|
|
import rope.base.pyobjects
|
|
from rope.base import taskhandle, exceptions, worder
|
|
from rope.contrib import fixsyntax
|
|
from rope.refactor import occurrences
|
|
|
|
|
|
def find_occurrences(
|
|
project,
|
|
resource,
|
|
offset,
|
|
unsure=False,
|
|
resources=None,
|
|
in_hierarchy=False,
|
|
task_handle=taskhandle.NullTaskHandle(),
|
|
):
|
|
"""Return a list of `Location`
|
|
|
|
If `unsure` is `True`, possible matches are returned, too. You
|
|
can use `Location.unsure` to see which are unsure occurrences.
|
|
`resources` can be a list of `rope.base.resource.File` that
|
|
should be searched for occurrences; if `None` all python files
|
|
in the project are searched.
|
|
|
|
"""
|
|
name = worder.get_name_at(resource, offset)
|
|
this_pymodule = project.get_pymodule(resource)
|
|
primary, pyname = rope.base.evaluate.eval_location2(this_pymodule, offset)
|
|
|
|
def is_match(occurrence):
|
|
return unsure
|
|
|
|
finder = occurrences.create_finder(
|
|
project,
|
|
name,
|
|
pyname,
|
|
unsure=is_match,
|
|
in_hierarchy=in_hierarchy,
|
|
instance=primary,
|
|
)
|
|
if resources is None:
|
|
resources = project.get_python_files()
|
|
job_set = task_handle.create_jobset("Finding Occurrences", count=len(resources))
|
|
return _find_locations(finder, resources, job_set)
|
|
|
|
|
|
def find_implementations(
|
|
project, resource, offset, resources=None, task_handle=taskhandle.NullTaskHandle()
|
|
):
|
|
"""Find the places a given method is overridden.
|
|
|
|
Finds the places a method is implemented. Returns a list of
|
|
`Location`.
|
|
"""
|
|
name = worder.get_name_at(resource, offset)
|
|
this_pymodule = project.get_pymodule(resource)
|
|
pyname = rope.base.evaluate.eval_location(this_pymodule, offset)
|
|
if pyname is not None:
|
|
pyobject = pyname.get_object()
|
|
if (
|
|
not isinstance(pyobject, rope.base.pyobjects.PyFunction)
|
|
or pyobject.get_kind() != "method"
|
|
):
|
|
raise exceptions.BadIdentifierError("Not a method!")
|
|
else:
|
|
raise exceptions.BadIdentifierError("Cannot resolve the identifier!")
|
|
|
|
def is_defined(occurrence):
|
|
if not occurrence.is_defined():
|
|
return False
|
|
|
|
def not_self(occurrence):
|
|
if occurrence.get_pyname().get_object() == pyname.get_object():
|
|
return False
|
|
|
|
filters = [is_defined, not_self, occurrences.InHierarchyFilter(pyname, True)]
|
|
finder = occurrences.Finder(project, name, filters=filters)
|
|
if resources is None:
|
|
resources = project.get_python_files()
|
|
job_set = task_handle.create_jobset("Finding Implementations", count=len(resources))
|
|
return _find_locations(finder, resources, job_set)
|
|
|
|
|
|
def find_definition(project, code, offset, resource=None, maxfixes=1):
|
|
"""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.
|
|
"""
|
|
fixer = fixsyntax.FixSyntax(project, code, resource, maxfixes)
|
|
pyname = fixer.pyname_at(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 = module.lines.get_line_start(lineno)
|
|
|
|
def check_offset(occurrence):
|
|
if occurrence.offset < start:
|
|
return False
|
|
|
|
pyname_filter = occurrences.PyNameFilter(pyname)
|
|
finder = occurrences.Finder(project, name, [check_offset, pyname_filter])
|
|
for occurrence in finder.find_occurrences(pymodule=module):
|
|
return Location(occurrence)
|
|
|
|
|
|
class Location(object):
|
|
def __init__(self, occurrence):
|
|
self.resource = occurrence.resource
|
|
self.region = occurrence.get_word_range()
|
|
self.offset = self.region[0]
|
|
self.unsure = occurrence.is_unsure()
|
|
self.lineno = occurrence.lineno
|
|
|
|
|
|
def _find_locations(finder, resources, job_set):
|
|
result = []
|
|
for resource in resources:
|
|
job_set.started_job(resource.path)
|
|
for occurrence in finder.find_occurrences(resource):
|
|
result.append(Location(occurrence))
|
|
job_set.finished_job()
|
|
return result
|