Anonymous avatar Anonymous committed dac7ce4

Throwing RopeSyntaxError exception when file has syntax errors
Ignoring errors in current line
Not proposing variables in current line

Comments (0)

Files changed (4)

docs/workingon.txt

 *** Auto-complete imports names @ 3 ***
 
+- Throwing Exceptions when encountering errors
+- What if current line has errors
+- Test not proposing the variables in current line
 
-- Proposing a name at most once? Use dicts instead of lists
-
+* What if the statement in current line is spread in more than one line
 * Extract listbox; duplicates in editor and core
 * Complete as you type (updating proposal list while typing)
-* Test not proposing the variables in current line
-* What if current line has errors
 * Applying the completion
 ? The connection between ASTs and Type Hierarchies
 

rope/codeassist.py

 import compiler
 
+import rope.core
+
+
+class RopeSyntaxError(rope.core.RopeException):
+    pass
+
 class CompletionProposal(object):
     global_variable = 'global_variable'
 
 
 
 class CodeAssist(ICodeAssist):
-    def complete_code(self, source_code, offset):
-        if offset > len(source_code):
-            return []
+    def _find_starting(self, source_code, offset):
         starting = ''
         current_offset = offset - 1
         while current_offset >= 0 and (source_code[current_offset].isalnum() or
                                        source_code[current_offset] == '_'):
             starting = source_code[current_offset] + starting
             current_offset -= 1;
+        return starting
+
+    def _comment_current_line(self, source_code, offset):
+        line_beginning = offset - 1
+        while line_beginning >= 0 and source_code[line_beginning] != '\n':
+            line_beginning -= 1
+        line_ending = offset
+        while line_ending < len(source_code) and source_code[line_ending] != '\n':
+            line_ending += 1
+        result = source_code
+        if line_beginning != -1 and line_beginning < line_ending - 1:
+            result = source_code[:line_beginning] + '#' + source_code[line_beginning + 2:]
+        return result
+
+    def complete_code(self, source_code, offset):
+        if offset > len(source_code):
+            return []
+        starting = self._find_starting(source_code, offset)
+        commented_source_code = self._comment_current_line(source_code, offset)
         result = {}
-        code_ast = compiler.parse(source_code)
+        try:
+            code_ast = compiler.parse(commented_source_code)
+        except SyntaxError, e:
+            raise RopeSyntaxError(e)
         visitor = _GlobalVisitor(starting)
         compiler.walk(code_ast, visitor)
         result.update(visitor.result)
 from rope.editor import GraphicalEditor
 from rope.project import Project, FileFinder, PythonFileRunner
 
+
+class RopeException(Exception):
+    '''Base exception for rope'''
+    pass
+
+
 class EditorManager(object):
     def __init__(self, editor_panel, core):
         self.core = core
             Core._core = Core()
         return Core._core
 
-
-class RopeException(Exception):
-    '''Base exception for rope'''
-    pass

ropetest/codeassisttest.py

 import unittest
 
-from rope.codeassist import CodeAssist
+from rope.codeassist import CodeAssist, RopeSyntaxError
 
 class CodeAssistTest(unittest.TestCase):
     def setUp(self):
         count = len([x for x in result if x.completion == 'variable' and x.kind == 'global_variable'])
         self.assertEquals(1, count)
 
+    def test_throwing_exception_in_case_of_syntax_errors(self):
+        code = 'sample (sdf\n'
+        self.assertRaises(RopeSyntaxError, 
+                          lambda: self.assist.complete_code(code, len(code)))
+    
+    def test_ignoring_errors_in_current_line(self):
+        code = 'def my_func():    return 2\nt = '
+        result = self.assist.complete_code(code, len(code))
+        self.assert_proposal_in_result('my_func', 'function', result)
+
+    def test_not_reporting_variables_in_current_line(self):
+        code = 'def my_func():    return 2\nt = my_'
+        result = self.assist.complete_code(code, len(code))
+        self.assert_proposal_not_in_result('my_', 'global_variable', result)
+
 
 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.