findit.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import rope.base.codeanalyze
  2. import rope.base.evaluate
  3. import rope.base.pyobjects
  4. from rope.base import taskhandle, exceptions, worder
  5. from rope.contrib import fixsyntax
  6. from rope.refactor import occurrences
  7. def find_occurrences(project, resource, offset, unsure=False, resources=None,
  8. in_hierarchy=False, task_handle=taskhandle.NullTaskHandle()):
  9. """Return a list of `Location`\s
  10. If `unsure` is `True`, possible matches are returned, too. You
  11. can use `Location.unsure` to see which are unsure occurrences.
  12. `resources` can be a list of `rope.base.resource.File`\s that
  13. should be searched for occurrences; if `None` all python files
  14. in the project are searched.
  15. """
  16. name = worder.get_name_at(resource, offset)
  17. this_pymodule = project.pycore.resource_to_pyobject(resource)
  18. primary, pyname = rope.base.evaluate.eval_location2(
  19. this_pymodule, offset)
  20. def is_match(occurrence):
  21. return unsure
  22. finder = occurrences.create_finder(
  23. project.pycore, name, pyname, unsure=is_match,
  24. in_hierarchy=in_hierarchy, instance=primary)
  25. if resources is None:
  26. resources = project.pycore.get_python_files()
  27. job_set = task_handle.create_jobset('Finding Occurrences',
  28. count=len(resources))
  29. return _find_locations(finder, resources, job_set)
  30. def find_implementations(project, resource, offset, resources=None,
  31. task_handle=taskhandle.NullTaskHandle()):
  32. """Find the places a given method is overridden.
  33. Finds the places a method is implemented. Returns a list of
  34. `Location`\s.
  35. """
  36. name = worder.get_name_at(resource, offset)
  37. this_pymodule = project.pycore.resource_to_pyobject(resource)
  38. pyname = rope.base.evaluate.eval_location(this_pymodule, offset)
  39. if pyname is not None:
  40. pyobject = pyname.get_object()
  41. if not isinstance(pyobject, rope.base.pyobjects.PyFunction) or \
  42. pyobject.get_kind() != 'method':
  43. raise exceptions.BadIdentifierError('Not a method!')
  44. else:
  45. raise exceptions.BadIdentifierError('Cannot resolve the identifier!')
  46. def is_defined(occurrence):
  47. if not occurrence.is_defined():
  48. return False
  49. def not_self(occurrence):
  50. if occurrence.get_pyname().get_object() == pyname.get_object():
  51. return False
  52. filters = [is_defined, not_self,
  53. occurrences.InHierarchyFilter(pyname, True)]
  54. finder = occurrences.Finder(project.pycore, name, filters=filters)
  55. if resources is None:
  56. resources = project.pycore.get_python_files()
  57. job_set = task_handle.create_jobset('Finding Implementations',
  58. count=len(resources))
  59. return _find_locations(finder, resources, job_set)
  60. def find_definition(project, code, offset, resource=None, maxfixes=1):
  61. """Return the definition location of the python name at `offset`
  62. A `Location` object is returned if the definition location can be
  63. determined, otherwise ``None`` is returned.
  64. """
  65. fixer = fixsyntax.FixSyntax(project.pycore, code, resource, maxfixes)
  66. main_module = fixer.get_pymodule()
  67. pyname = fixer.pyname_at(offset)
  68. if pyname is not None:
  69. module, lineno = pyname.get_definition_location()
  70. name = rope.base.worder.Worder(code).get_word_at(offset)
  71. if lineno is not None:
  72. start = module.lines.get_line_start(lineno)
  73. def check_offset(occurrence):
  74. if occurrence.offset < start:
  75. return False
  76. pyname_filter = occurrences.PyNameFilter(pyname)
  77. finder = occurrences.Finder(project.pycore, name,
  78. [check_offset, pyname_filter])
  79. for occurrence in finder.find_occurrences(pymodule=module):
  80. return Location(occurrence)
  81. class Location(object):
  82. def __init__(self, occurrence):
  83. self.resource = occurrence.resource
  84. self.region = occurrence.get_word_range()
  85. self.offset = self.region[0]
  86. self.unsure = occurrence.is_unsure()
  87. self.lineno = occurrence.lineno
  88. def _find_locations(finder, resources, job_set):
  89. result = []
  90. for resource in resources:
  91. job_set.started_job(resource.path)
  92. for occurrence in finder.find_occurrences(resource):
  93. result.append(Location(occurrence))
  94. job_set.finished_job()
  95. return result