Commits

Anonymous committed 828c47b

Showing unsure occurrences in find occurrences

Comments (0)

Files changed (12)

docs/dev/issues.txt

 every change.
 
 
+Separating Ropeide
+==================
+
+* New package structure::
+
+    rope/
+      base
+      refactor
+    ropeide/
+      ide
+      ui
+
+* ``rope.py`` -> ``ropeide.py``
+* ``rope`` -> ``ropeide``
+* ``~/.rope`` -> ``~/.ropeide.py``
+
+Problems:
+
+* Changing rope requires changing ropeide
+* Ropeide needs to work with multiple versions of rope?
+* Ropeide uses lots of internal things from rope
+
+
 Better Concluded Data
 =====================
 

docs/dev/workingon.txt

 Small Stories
 =============
 
+- Adding unsure occurrences to find occurrences
+
+* Moving codeassist from editingtools to core?
+* Caching last pymodule in `codeassist.get_pymodule()`?
+* Refactor codeanalyze
+
 * Adding an option to inline not to remove the definition
 * Renaming ``rope.py`` to ``ropeide.py`` and ``~/.rope`` to
   ``~/.ropeide.py``?
 ===========
 
 
+- Showing unsure occurrences in show occurrences : August 17, 2007
+
+
 - Sorting scopes : August 9, 2007
 
 

rope/base/builtins.py

                   argnames=['self', 'index', 'value'])
         collector('insert', function=self._list_add,
                   argnames=['self', 'index', 'value'])
-        collector('extend', function=self._self_set, 
+        collector('extend', function=self._self_set,
                   argnames=['self', 'iterable'])
 
         # Getting methods

rope/ide/codeassist.py

 from rope.base.codeanalyze import (StatementRangeFinder, ArrayLinesAdapter,
                                    WordRangeFinder, ScopeNameFinder,
                                    SourceLinesAdapter, BadIdentifierError)
-from rope.base.exceptions import RopeError
 from rope.ide import pydoc
-from rope.refactor import occurrences, functionutils
+from rope.refactor import occurrences
+
+
+class PythonCodeAssist(object):
+
+    def __init__(self, project):
+        self.project = project
+        import keyword
+        self.keywords = keyword.kwlist
+        self.templates = []
+        self.templates.extend(PythonCodeAssist._get_default_templates())
+
+    builtins = [str(name) for name in dir(__builtin__)
+                if not name.startswith('_')]
+
+    @staticmethod
+    def _get_default_templates():
+        templates = {}
+        templates['main'] = Template("if __name__ == '__main__':\n    ${cursor}\n")
+        test_case_template = \
+            ('import unittest\n\n\n'
+             'class ${TestClass}(unittest.TestCase):\n\n'
+             '    def setUp(self):\n        super(${TestClass}, self).setUp()\n\n'
+             '    def tearDown(self):\n        super(${TestClass}, self).tearDown()\n\n'
+             '    def test_trivial_case${cursor}(self):\n        pass\n\n\n'
+             'if __name__ == \'__main__\':\n'
+             '    unittest.main()\n')
+        templates['testcase'] = Template(test_case_template)
+        templates['hash'] = Template('\n    def __hash__(self):\n' +
+                                     '        return 1${cursor}\n')
+        templates['eq'] = Template('\n    def __eq__(self, obj):\n' +
+                                   '        ${cursor}return obj is self\n')
+        templates['super'] = Template('super(${class}, self)')
+        templates.update(PythonCodeAssist.default_templates)
+        result = []
+        for name, template in templates.items():
+            result.append(TemplateProposal(name, template))
+        return result
+
+    default_templates = {}
+
+    @staticmethod
+    def add_default_template(name, definition):
+        PythonCodeAssist.default_templates[name] = Template(definition)
+
+    def _find_starting_offset(self, source_code, offset):
+        current_offset = offset - 1
+        while current_offset >= 0 and (source_code[current_offset].isalnum() or
+                                       source_code[current_offset] in '_'):
+            current_offset -= 1;
+        return current_offset + 1
+
+    def _get_matching_builtins(self, starting):
+        result = {}
+        for builtin in self.builtins:
+            if builtin.startswith(starting):
+                result[builtin] = CompletionProposal(builtin, 'builtin')
+        return result
+
+    def _get_matching_keywords(self, starting):
+        result = {}
+        for kw in self.keywords:
+            if kw.startswith(starting):
+                result[kw] = CompletionProposal(kw, 'keyword')
+        return result
+
+    def add_template(self, name, definition):
+        self.templates.append(TemplateProposal(name, Template(definition)))
+
+    def _get_template_proposals(self, starting):
+        result = []
+        for template in self.templates:
+            if template.name.startswith(starting):
+                result.append(template)
+        return result
+
+    def _get_code_completions(self, source_code, offset,
+                              expression, starting, resource):
+        collector = _CodeCompletionCollector(self.project, source_code, offset,
+                                             expression, starting, resource)
+        return collector.get_code_completions()
+
+    def assist(self, source_code, offset, resource=None):
+        if offset > len(source_code):
+            return Proposals()
+        word_finder = WordRangeFinder(source_code)
+        expression, starting, starting_offset = \
+            word_finder.get_splitted_primary_before(offset)
+        completions = self._get_code_completions(
+            source_code, offset, expression, starting, resource)
+        templates = []
+        if expression.strip() == '' and starting.strip() != '':
+            completions.update(self._get_matching_builtins(starting))
+            completions.update(self._get_matching_keywords(starting))
+            templates = self._get_template_proposals(starting)
+        return Proposals(completions.values(), templates,
+                         starting_offset)
+
+def get_doc(project, source_code, offset, resource=None):
+    pymodule = get_pymodule(project.pycore, source_code, resource)
+    scope_finder = ScopeNameFinder(pymodule)
+    element = scope_finder.get_pyname_at(offset)
+    if element is None:
+        return None
+    pyobject = element.get_object()
+    return pydoc.get_doc(pyobject)
+
+
+def get_definition_location(project, source_code, offset, resource=None):
+    pymodule = project.pycore.get_string_module(source_code, resource)
+    scope_finder = ScopeNameFinder(pymodule)
+    element = scope_finder.get_pyname_at(offset)
+    if element is not None:
+        module, lineno = element.get_definition_location()
+        if module is not None:
+            return module.get_module().get_resource(), lineno
+    return (None, None)
+
+
+def find_occurrences(project, resource, offset, unsure=False,
+                     task_handle=taskhandle.NullTaskHandle()):
+    name = rope.base.codeanalyze.get_name_at(resource, offset)
+    pyname = rope.base.codeanalyze.get_pyname_at(project.get_pycore(),
+                                                 resource, offset)
+    finder = occurrences.FilteredFinder(
+        project.get_pycore(), name, [pyname], unsure=unsure)
+    files = project.get_pycore().get_python_files()
+    job_set = task_handle.create_jobset('Finding Occurrences',
+                                        count=len(files))
+    result = []
+    for resource in files:
+        job_set.started_job('Working On <%s>' % resource.path)
+        for occurrence in finder.find_occurrences(resource):
+            result.append((resource, occurrence.get_word_range()[0],
+                           occurrence.is_unsure()))
+        job_set.finished_job()
+    return result
+
+
+class Proposals(object):
+    """A CodeAssist result.
+
+    Attribute:
+    completions -- A list of `CompletionProposal`\s
+    templates -- A list of `TemplateProposal`\s
+    start_offset -- completion start offset
+
+    """
+
+    def __init__(self, completions=[], templates=[], start_offset=0):
+        self.completions = completions
+        self.templates = templates
+        self.start_offset = start_offset
 
 
 class CodeAssistProposal(object):
         return start
 
 
-class Proposals(object):
-    """A CodeAssist result.
-
-    Attribute:
-    completions -- A list of `CompletionProposal`\s
-    templates -- A list of `TemplateProposal`\s
-    start_offset -- completion start offset
-
-    """
-
-    def __init__(self, completions=[], templates=[], start_offset=0):
-        self.completions = completions
-        self.templates = templates
-        self.start_offset = start_offset
-
-
 class _CodeCompletionCollector(object):
 
     def __init__(self, project, source_code,
                     pyobject = pyobject.get_attribute('__call__').get_object()
                 if isinstance(pyobject, pyobjects.AbstractFunction):
                     param_names = []
-                    if isinstance(pyobject, pyobjects.PyFunction):
-                        function_info = functionutils.DefinitionInfo.read(pyobject)
-                        param_names.extend([name for name, default
-                                            in function_info.args_with_defaults])
-                    else:
-                        param_names = pyobject.get_param_names()
+                    param_names.extend(
+                        pyobject.get_param_names(special_args=False))
                     result = {}
                     for name in param_names:
                         if name.startswith(self.starting):
         return {}
 
 
-class PythonCodeAssist(object):
-
-    def __init__(self, project):
-        self.project = project
-        import keyword
-        self.keywords = keyword.kwlist
-        self.templates = []
-        self.templates.extend(PythonCodeAssist._get_default_templates())
-
-    builtins = [str(name) for name in dir(__builtin__)
-                if not name.startswith('_')]
-
-    @staticmethod
-    def _get_default_templates():
-        templates = {}
-        templates['main'] = Template("if __name__ == '__main__':\n    ${cursor}\n")
-        test_case_template = \
-            ('import unittest\n\n\n'
-             'class ${TestClass}(unittest.TestCase):\n\n'
-             '    def setUp(self):\n        super(${TestClass}, self).setUp()\n\n'
-             '    def tearDown(self):\n        super(${TestClass}, self).tearDown()\n\n'
-             '    def test_trivial_case${cursor}(self):\n        pass\n\n\n'
-             'if __name__ == \'__main__\':\n'
-             '    unittest.main()\n')
-        templates['testcase'] = Template(test_case_template)
-        templates['hash'] = Template('\n    def __hash__(self):\n' +
-                                     '        return 1${cursor}\n')
-        templates['eq'] = Template('\n    def __eq__(self, obj):\n' +
-                                   '        ${cursor}return obj is self\n')
-        templates['super'] = Template('super(${class}, self)')
-        templates.update(PythonCodeAssist.default_templates)
-        result = []
-        for name, template in templates.items():
-            result.append(TemplateProposal(name, template))
-        return result
-
-    default_templates = {}
-
-    @staticmethod
-    def add_default_template(name, definition):
-        PythonCodeAssist.default_templates[name] = Template(definition)
-
-    def _find_starting_offset(self, source_code, offset):
-        current_offset = offset - 1
-        while current_offset >= 0 and (source_code[current_offset].isalnum() or
-                                       source_code[current_offset] in '_'):
-            current_offset -= 1;
-        return current_offset + 1
-
-    def _get_matching_builtins(self, starting):
-        result = {}
-        for builtin in self.builtins:
-            if builtin.startswith(starting):
-                result[builtin] = CompletionProposal(builtin, 'builtin')
-        return result
-
-    def _get_matching_keywords(self, starting):
-        result = {}
-        for kw in self.keywords:
-            if kw.startswith(starting):
-                result[kw] = CompletionProposal(kw, 'keyword')
-        return result
-
-    def add_template(self, name, definition):
-        self.templates.append(TemplateProposal(name, Template(definition)))
-
-    def _get_template_proposals(self, starting):
-        result = []
-        for template in self.templates:
-            if template.name.startswith(starting):
-                result.append(template)
-        return result
-
-    def _get_code_completions(self, source_code, offset,
-                              expression, starting, resource):
-        collector = _CodeCompletionCollector(self.project, source_code, offset,
-                                             expression, starting, resource)
-        return collector.get_code_completions()
-
-    def assist(self, source_code, offset, resource=None):
-        if offset > len(source_code):
-            return Proposals()
-        word_finder = WordRangeFinder(source_code)
-        expression, starting, starting_offset = \
-            word_finder.get_splitted_primary_before(offset)
-        completions = self._get_code_completions(
-            source_code, offset, expression, starting, resource)
-        templates = []
-        if expression.strip() == '' and starting.strip() != '':
-            completions.update(self._get_matching_builtins(starting))
-            completions.update(self._get_matching_keywords(starting))
-            templates = self._get_template_proposals(starting)
-        return Proposals(completions.values(), templates,
-                         starting_offset)
-
-    def get_definition_location(self, source_code, offset, resource=None):
-        return _GetDefinitionLocation(self.project, source_code, offset,
-                                      resource).get_definition_location()
-
-    def get_doc(self, source_code, offset, resource=None):
-        pymodule = get_pymodule(self.project.pycore, source_code, resource)
-        scope_finder = ScopeNameFinder(pymodule)
-        element = scope_finder.get_pyname_at(offset)
-        if element is None:
-            return None
-        pyobject = element.get_object()
-        return pydoc.get_doc(pyobject)
-
-    def find_occurrences(self, resource, offset, unsure=False,
-                         task_handle=taskhandle.NullTaskHandle()):
-        name = rope.base.codeanalyze.get_name_at(resource, offset)
-        pyname = rope.base.codeanalyze.get_pyname_at(self.project.get_pycore(),
-                                                     resource, offset)
-        finder = occurrences.FilteredFinder(
-            self.project.get_pycore(), name, [pyname], unsure=unsure)
-        files = self.project.get_pycore().get_python_files()
-        job_set = task_handle.create_jobset('Finding Occurrences',
-                                             count=len(files))
-        result = []
-        for resource in files:
-            job_set.started_job('Working On <%s>' % resource.path)
-            for occurrence in finder.find_occurrences(resource):
-                result.append((resource, occurrence.get_word_range()[0]))
-            job_set.finished_job()
-        return result
-
-
 def get_pymodule(pycore, source_code, resource):
     if resource and resource.exists() and source_code == resource.read():
         return pycore.resource_to_pyobject(resource)
     return pycore.get_string_module(source_code, resource=resource)
 
 
-class _GetDefinitionLocation(object):
-
-    def __init__(self, project, source_code, offset, resource):
-        self.project = project
-        self.offset = offset
-        self.source_code = source_code
-        self.resource = resource
-
-    def get_definition_location(self):
-        pymodule = self.project.pycore.get_string_module(self.source_code,
-                                                         self.resource)
-        scope_finder = ScopeNameFinder(pymodule)
-        element = scope_finder.get_pyname_at(self.offset)
-        if element is not None:
-            module, lineno = element.get_definition_location()
-            if module is not None:
-                return module.get_module().get_resource(), lineno
-        return (None, None)
-
-
 class ProposalSorter(object):
 
     def __init__(self, code_assist_proposals):

rope/refactor/occurrences.py

 from rope.base import pynames, pyobjects, codeanalyze
 
 
-class OccurrenceFinder(object):
-    """For finding textual occurrences of a name"""
+class FilteredFinder(object):
+    """For finding occurrences of a name"""
 
-    def __init__(self, pycore, name, docs=False):
+    def __init__(self, pycore, name, pynames, only_calls=False,
+                 imports=True, unsure=False, docs=False):
         self.pycore = pycore
+        self.pynames = pynames
+        self.name = name
+        self.only_calls = only_calls
+        self.imports = imports
+        self.unsure = unsure
+        self.occurrence_finder = _TextualFinder(name, docs=docs)
+
+    def find_occurrences(self, resource=None, pymodule=None):
+        """Generate `Occurrence` instances"""
+        tools = _OccurrenceToolsCreator(self.pycore, resource=resource,
+                                        pymodule=pymodule)
+        for offset in self.occurrence_finder.find_offsets(tools.source_code):
+            occurrence = Occurrence(tools, offset)
+            if self._is_a_match(occurrence):
+                yield occurrence
+
+    def _is_a_match(self, occurrence):
+        if self.only_calls and not occurrence.is_called():
+            return False
+        if not self.imports and occurrence.is_in_import_statement():
+            return False
+        new_pyname = occurrence.get_pyname()
+        for pyname in self.pynames:
+            if same_pyname(pyname, new_pyname):
+                return True
+            elif self.unsure and self._unsure_match(pyname, new_pyname):
+                occurrence._unsure = True
+                return True
+
+        return False
+
+    def _unsure_match(self, expected, pyname):
+        if pyname is None:
+            return True
+        if isinstance(pyname, pynames.UnboundName) and \
+           pyname.get_object() == pyobjects.get_unknown():
+            return True
+
+
+class Occurrence(object):
+
+    def __init__(self, tools, offset):
+        self.tools = tools
+        self.offset = offset
+
+    _unsure = False
+
+    def get_word_range(self):
+        return self.tools.word_finder.get_word_range(self.offset)
+
+    def get_primary_range(self):
+        return self.tools.word_finder.get_primary_range(self.offset)
+
+    def get_pyname(self):
+        return self.tools.name_finder.get_pyname_at(self.offset)
+
+    def get_primary_and_pyname(self):
+        return self.tools.name_finder.get_primary_and_pyname_at(self.offset)
+
+    def is_in_import_statement(self):
+        return (self.tools.word_finder.is_from_statement(self.offset) or
+                self.tools.word_finder.is_import_statement(self.offset))
+
+    def is_called(self):
+        return self.tools.word_finder.is_a_function_being_called(self.offset)
+
+    def is_defined(self):
+        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset)
+
+    def is_a_fixed_primary(self):
+        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset) or \
+               self.tools.word_finder.is_a_name_after_from_import(self.offset)
+
+    def is_written(self):
+        return self.tools.word_finder.is_assigned_here(self.offset)
+
+    def is_unsure(self):
+        return self._unsure
+
+
+class MultipleFinders(object):
+
+    def __init__(self, finders):
+        self.finders = finders
+
+    def find_occurrences(self, resource=None, pymodule=None):
+        all_occurrences = []
+        for finder in self.finders:
+            all_occurrences.extend(finder.find_occurrences(resource, pymodule))
+        all_occurrences.sort(self._cmp_occurrences)
+        return all_occurrences
+
+    def _cmp_occurrences(self, o1, o2):
+        return cmp(o1.get_primary_range(), o2.get_primary_range())
+
+
+def same_pyname(expected, pyname):
+    """Check whether `expected` and `pyname` are the same"""
+    if expected is None or pyname is None:
+        return False
+    if expected == pyname:
+        return True
+    if type(expected) not in (pynames.ImportedModule, pynames.ImportedName) and \
+       type(pyname) not in (pynames.ImportedModule, pynames.ImportedName):
+        return False
+    return expected.get_definition_location() == pyname.get_definition_location() and \
+           expected.get_object() == pyname.get_object()
+
+
+class _TextualFinder(object):
+
+    def __init__(self, name, docs=False):
         self.name = name
         self.docs = docs
-        self.comment_pattern = OccurrenceFinder.any('comment', [r'#[^\n]*'])
-        self.string_pattern = OccurrenceFinder.any(
+        self.comment_pattern = _TextualFinder.any('comment', [r'#[^\n]*'])
+        self.string_pattern = _TextualFinder.any(
             'string', [codeanalyze.get_string_pattern()])
         self.pattern = self._get_occurrence_pattern(self.name)
 
-    def find_occurrences(self, resource=None, pymodule=None):
-        """Generate `Occurrence` instances"""
-        tools = _OccurrenceToolsCreator(self.pycore, resource, pymodule)
-        if not self._fast_file_query(tools.source_code):
+    def find_offsets(self, source):
+        if not self._fast_file_query(source):
             return
         if self.docs:
             searcher = self._normal_search
         else:
             searcher = self._re_search
-        for matched in searcher(tools.source_code):
-            yield Occurrence(tools, matched + 1)
+        for matched in searcher(source):
+            yield matched + 1
 
     def _re_search(self, source):
         for match in self.pattern.finditer(source):
             return pymodule.source_code
 
     def _get_occurrence_pattern(self, name):
-        occurrence_pattern = OccurrenceFinder.any('occurrence',
+        occurrence_pattern = _TextualFinder.any('occurrence',
                                                  ['\\b' + name + '\\b'])
         pattern = re.compile(occurrence_pattern + '|' + self.comment_pattern +
                              '|' + self.string_pattern)
         return '(?P<%s>' % name + '|'.join(list_) + ')'
 
 
-class Occurrence(object):
-
-    def __init__(self, tools, offset):
-        self.tools = tools
-        self.offset = offset
-
-    def get_word_range(self):
-        return self.tools.word_finder.get_word_range(self.offset)
-
-    def get_primary_range(self):
-        return self.tools.word_finder.get_primary_range(self.offset)
-
-    def get_pyname(self):
-        return self.tools.name_finder.get_pyname_at(self.offset)
-
-    def get_primary_and_pyname(self):
-        return self.tools.name_finder.get_primary_and_pyname_at(self.offset)
-
-    def is_in_import_statement(self):
-        return (self.tools.word_finder.is_from_statement(self.offset) or
-                self.tools.word_finder.is_import_statement(self.offset))
-
-    def is_called(self):
-        return self.tools.word_finder.is_a_function_being_called(self.offset)
-
-    def is_defined(self):
-        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset)
-
-    def is_a_fixed_primary(self):
-        return self.tools.word_finder.is_a_class_or_function_name_in_header(self.offset) or \
-               self.tools.word_finder.is_a_name_after_from_import(self.offset)
-
-    def is_written(self):
-        return self.tools.word_finder.is_assigned_here(self.offset)
-
-
-class FilteredFinder(object):
-
-    def __init__(self, pycore, name, pynames, only_calls=False,
-                 imports=True, unsure=False, docs=False):
-        self.pycore = pycore
-        self.pynames = pynames
-        self.name = name
-        self.only_calls = only_calls
-        self.imports = imports
-        self.unsure = unsure
-        self.occurrence_finder = OccurrenceFinder(pycore, name, docs=docs)
-
-    def find_occurrences(self, resource=None, pymodule=None):
-        for occurrence in self.occurrence_finder.find_occurrences(
-            resource, pymodule):
-            if self._is_a_match(occurrence):
-                yield occurrence
-
-    def _is_a_match(self, occurrence):
-        if self.only_calls and not occurrence.is_called():
-            return False
-        if not self.imports and occurrence.is_in_import_statement():
-            return False
-        new_pyname = occurrence.get_pyname()
-        for pyname in self.pynames:
-            if FilteredFinder.same_pyname(pyname, new_pyname):
-                return True
-            elif self.unsure and self._unsure_match(pyname, new_pyname):
-                return True
-                
-        return False
-
-    @staticmethod
-    def same_pyname(expected, pyname):
-        if expected is None or pyname is None:
-            return False
-        if expected == pyname:
-            return True
-        if type(expected) not in (pynames.ImportedModule, pynames.ImportedName) and \
-           type(pyname) not in (pynames.ImportedModule, pynames.ImportedName):
-            return False
-        return expected.get_definition_location() == pyname.get_definition_location() and \
-               expected.get_object() == pyname.get_object()
-
-    def _unsure_match(self, expected, pyname):
-        if pyname is None:
-            return True
-        if isinstance(pyname, pynames.UnboundName) and \
-           pyname.get_object() == pyobjects.get_unknown():
-            return True
-
-
-class MultipleFinders(object):
-
-    def __init__(self, finders):
-        self.finders = finders
-
-    def find_occurrences(self, resource=None, pymodule=None):
-        all_occurrences = []
-        for finder in self.finders:
-            all_occurrences.extend(finder.find_occurrences(resource, pymodule))
-        all_occurrences.sort(self._cmp_occurrences)
-        return all_occurrences
-
-    def _cmp_occurrences(self, o1, o2):
-        return cmp(o1.get_primary_range(), o2.get_primary_range())
-
-
 class _OccurrenceToolsCreator(object):
 
     def __init__(self, pycore, resource=None, pymodule=None):

rope/refactor/similarfinder.py

         return expected == pyobject
 
     def _same_pyname(self, expected, pyname):
-        return occurrences.FilteredFinder.same_pyname(expected, pyname)
+        return occurrences.same_pyname(expected, pyname)
 
     def _split_name(self, name):
         parts = name.split('.')
 
     def __init__(self):
         self.root = Tk()
-        self.root.title('Rope')
+        self.root.title('ropeide')
         editingcontexts.init_contexts(self)
         for context in editingcontexts.contexts.values():
             context.menu = Menu(self.root, relief=RAISED, borderwidth=1)

rope/ui/editingtools.py

                 self._code_assist.add_template(name, template)
         return self._code_assist
 
-    def _get_outline(self):
-        if self._outline is None:
-            self._outline = rope.ide.outline.PythonOutline(self.project)
-        return self._outline
-
     codeassist = property(_get_code_assist)
-    outline = property(_get_outline)
 
 
 class ReSTEditingTools(EditingTools):

rope/ui/fileeditor.py

         self.file = file_
         self.project = project
         editingcontext = None
-        if self.file.name.endswith('.py') or mode == 'python':
+        if self._has_extension(self.file, 'py') or mode == 'python':
             editingcontext = editingcontexts.python
-        elif self.file.name.endswith('.txt') or mode == 'rst':
+        elif self._has_extension(self.file, 'txt', 'rst') or mode == 'rst':
             editingcontext = editingcontexts.rst
         else:
             editingcontext = editingcontexts.others
         #if readonly:
         #    self.editor.getWidget()['state'] = Tkinter.DISABLED
 
+    def _has_extension(self, resource, *extensions):
+        name = resource.name
+        for extension in extensions:
+            if name.endswith('.' + extension):
+                return True
+        return False
+
     def _register_observers(self):
         modified = self._file_was_modified
         moved = self._file_was_removed

rope/ui/sourceactions.py

 import rope.ui.core
 import rope.ui.testview
 from rope.base import codeanalyze
-from rope.ide import formatter, notes, generate, sort
+from rope.ide import formatter, notes, generate, sort, outline
 from rope.ui import spelldialog, registers
 from rope.ui.actionhelpers import ConfirmEditorsAreSaved, StoppableTaskRunner
 from rope.ui.extension import SimpleAction
     toplevel.title('Quick Outline')
     tree_view = TreeView(toplevel, _OutlineViewHandle(editor, toplevel),
                          title='Quick Outline')
-    for node in context.editingtools.outline.get_root_nodes(editor.get_text()):
+    for node in (outline.PythonOutline(context.project).\
+                 get_root_nodes(editor.get_text())):
         tree_view.add_entry(node)
     toplevel.grab_set()
 
     def focus_went_out(self):
         self.canceled()
 
+
 def do_code_assist(context):
     editor = context.get_active_editor().get_editor()
     result = context.editingtools.codeassist.assist(
 
 def do_goto_definition(context):
     editor = context.get_active_editor().get_editor()
-    resource, lineno = context.editingtools.codeassist.get_definition_location(
-        editor.get_text(), editor.get_current_offset(), context.resource)
+    resource, lineno = rope.ide.codeassist.get_definition_location(
+        context.project, editor.get_text(),
+        editor.get_current_offset(), context.resource)
     if resource is not None:
         new_editor = context.core.get_editor_manager().\
                      get_resource_editor(resource).get_editor()
     if not context.get_active_editor():
         return
     editor = context.get_active_editor().get_editor()
-    doc = context.editingtools.codeassist.get_doc(editor.get_text(),
-                                                  editor.get_current_offset(),
-                                                  context.resource)
+    doc = rope.ide.codeassist.get_doc(
+        context.project, editor.get_text(),
+        editor.get_current_offset(), context.resource)
     if doc is not None:
         toplevel = Tkinter.Toplevel()
         toplevel.title('Show Doc')
         self.focus_set = focus_set
 
     def entry_to_string(self, entry):
-        return entry[0].path + ' : ' + str(entry[1])
+        result = entry[0].path + ' : ' + str(entry[1])
+        if entry[2]:
+            result += ' ?'
+        return result
 
     def canceled(self):
         self.toplevel.destroy()
     resource = context.resource
     offset = context.editor.get_current_offset()
     def calculate(handle):
-        return context.editingtools.codeassist.find_occurrences(
-            resource, offset, task_handle=handle)
+        return rope.ide.codeassist.find_occurrences(
+            context.project, resource, offset,
+            unsure=True, task_handle=handle)
     result = StoppableTaskRunner(calculate, title='Finding Occurrences')()
     enhanced_list = None
     def focus_set():

ropetest/projecttest.py

         sample_file.write(contents)
         self.assertEquals(contents, sample_file.read())
 
+    # TODO: Detecting utf-16 encoding
+    def xxx_test_using_utf16(self):
+        sample_file = self.project.root.create_file('my_file.txt')
+        contents = '# -*- coding: utf-16 -*-\n# This is a sample file ...\n'
+        file = open(sample_file.real_path, 'w')
+        file.write(contents.encode('utf-16'))
+        file.close()
+        sample_file.write(contents)
+        self.assertEquals(contents, sample_file.read())
+
     # XXX: supporting utf_8_sig
     def xxx_test_file_encoding_reading_for_notepad_styles(self):
         sample_file = self.project.root.create_file('my_file.txt')