Changed syntax check to report error position within the line.

Sat, 26 Feb 2011 14:28:21 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 26 Feb 2011 14:28:21 +0100
changeset 915
c1e052773c08
parent 914
01ae5102cd3d
child 917
746c54b643eb

Changed syntax check to report error position within the line.

APIs/Python3/eric5.api file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.Editor.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.Utilities.__init__.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.UtilitiesPython2.Py2SyntaxChecker.html file | annotate | diff | comparison | revisions
Documentation/Source/index-eric5.html file | annotate | diff | comparison | revisions
Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py file | annotate | diff | comparison | revisions
QScintilla/Editor.py file | annotate | diff | comparison | revisions
Utilities/__init__.py file | annotate | diff | comparison | revisions
UtilitiesPython2/Py2SyntaxChecker.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
--- a/APIs/Python3/eric5.api	Sat Feb 26 14:26:59 2011 +0100
+++ b/APIs/Python3/eric5.api	Sat Feb 26 14:28:21 2011 +0100
@@ -2740,6 +2740,7 @@
 eric5.Plugins.CheckerPlugins.Pep8.pep8.whitespace_before_parameters?4(logical_line, tokens)
 eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.errorRole?7
 eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.filenameRole?7
+eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.indexRole?7
 eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.lineRole?7
 eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.on_buttonBox_clicked?4(button)
 eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.SyntaxCheckerDialog.on_resultList_itemActivated?4(itm, col)
@@ -5121,7 +5122,7 @@
 eric5.QScintilla.Editor.Editor.taskMarkersUpdated?7
 eric5.QScintilla.Editor.Editor.toggleBookmark?4(line)
 eric5.QScintilla.Editor.Editor.toggleFlakesWarning?4(line, warning, msg = "")
-eric5.QScintilla.Editor.Editor.toggleSyntaxError?4(line, error, msg = "")
+eric5.QScintilla.Editor.Editor.toggleSyntaxError?4(line, index, error, msg = "", show = False)
 eric5.QScintilla.Editor.Editor.uncommentLine?4()
 eric5.QScintilla.Editor.Editor.uncommentLineOrSelection?4()
 eric5.QScintilla.Editor.Editor.uncommentSelection?4()
@@ -6805,13 +6806,6 @@
 eric5.compileUiFiles.compile_ui?4(ui_dir, ui_file)
 eric5.compileUiFiles.main?4(argv)
 eric5.compileUiFiles.pyName?4(py_dir, py_file)
-eric5.eric5-api.main?4()
-eric5.eric5-api.usage?4()
-eric5.eric5-api.version?4()
-eric5.eric5-doc.main?4()
-eric5.eric5-doc.supportedExtensions?7
-eric5.eric5-doc.usage?4()
-eric5.eric5-doc.version?4()
 eric5.eric5.args?7
 eric5.eric5.excepthook?4(excType, excValue, tracebackobj)
 eric5.eric5.handleSingleApplication?4(ddindex)
@@ -6821,12 +6815,19 @@
 eric5.eric5.restartArgsList?7
 eric5.eric5.splash?7
 eric5.eric5.uiStartUp?4()
+eric5.eric5_api.main?4()
+eric5.eric5_api.usage?4()
+eric5.eric5_api.version?4()
 eric5.eric5_compare.createMainWidget?4(argv)
 eric5.eric5_compare.main?4()
 eric5.eric5_configure.createMainWidget?4(argv)
 eric5.eric5_configure.main?4()
 eric5.eric5_diff.createMainWidget?4(argv)
 eric5.eric5_diff.main?4()
+eric5.eric5_doc.main?4()
+eric5.eric5_doc.supportedExtensions?7
+eric5.eric5_doc.usage?4()
+eric5.eric5_doc.version?4()
 eric5.eric5_editor.createMainWidget?4(argv)
 eric5.eric5_editor.main?4()
 eric5.eric5_iconeditor.createMainWidget?4(argv)
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Help/source.qhp	Sat Feb 26 14:28:21 2011 +0100
@@ -769,11 +769,11 @@
           </section>
           <section title="eric5.compileUiFiles" ref="eric5.compileUiFiles.html" />
           <section title="eric5.eric5" ref="eric5.eric5.html" />
-          <section title="eric5.eric5-api" ref="eric5.eric5-api.html" />
-          <section title="eric5.eric5-doc" ref="eric5.eric5-doc.html" />
+          <section title="eric5.eric5_api" ref="eric5.eric5_api.html" />
           <section title="eric5.eric5_compare" ref="eric5.eric5_compare.html" />
           <section title="eric5.eric5_configure" ref="eric5.eric5_configure.html" />
           <section title="eric5.eric5_diff" ref="eric5.eric5_diff.html" />
+          <section title="eric5.eric5_doc" ref="eric5.eric5_doc.html" />
           <section title="eric5.eric5_editor" ref="eric5.eric5_editor.html" />
           <section title="eric5.eric5_iconeditor" ref="eric5.eric5_iconeditor.html" />
           <section title="eric5.eric5_plugininstall" ref="eric5.eric5_plugininstall.html" />
@@ -800,14 +800,6 @@
       <keyword name="eric5_unittest (Module)" id="eric5_unittest (Module)" ref="eric5.eric5_unittest.html" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric5.eric5_unittest.html#createMainWidget" />
       <keyword name="main" id="main" ref="eric5.eric5_unittest.html#main" />
-      <keyword name="eric5-api (Module)" id="eric5-api (Module)" ref="eric5.eric5-api.html" />
-      <keyword name="main" id="main" ref="eric5.eric5-api.html#main" />
-      <keyword name="usage" id="usage" ref="eric5.eric5-api.html#usage" />
-      <keyword name="version" id="version" ref="eric5.eric5-api.html#version" />
-      <keyword name="eric5-doc (Module)" id="eric5-doc (Module)" ref="eric5.eric5-doc.html" />
-      <keyword name="main" id="main" ref="eric5.eric5-doc.html#main" />
-      <keyword name="usage" id="usage" ref="eric5.eric5-doc.html#usage" />
-      <keyword name="version" id="version" ref="eric5.eric5-doc.html#version" />
       <keyword name="uninstall (Module)" id="uninstall (Module)" ref="eric5.uninstall.html" />
       <keyword name="initGlobals" id="initGlobals" ref="eric5.uninstall.html#initGlobals" />
       <keyword name="main" id="main" ref="eric5.uninstall.html#main" />
@@ -833,6 +825,14 @@
       <keyword name="main" id="main" ref="eric5.eric5_qregexp.html#main" />
       <keyword name="eric5config (Module)" id="eric5config (Module)" ref="eric5.eric5config.html" />
       <keyword name="getConfig" id="getConfig" ref="eric5.eric5config.html#getConfig" />
+      <keyword name="eric5_api (Module)" id="eric5_api (Module)" ref="eric5.eric5_api.html" />
+      <keyword name="main" id="main" ref="eric5.eric5_api.html#main" />
+      <keyword name="usage" id="usage" ref="eric5.eric5_api.html#usage" />
+      <keyword name="version" id="version" ref="eric5.eric5_api.html#version" />
+      <keyword name="eric5_doc (Module)" id="eric5_doc (Module)" ref="eric5.eric5_doc.html" />
+      <keyword name="main" id="main" ref="eric5.eric5_doc.html#main" />
+      <keyword name="usage" id="usage" ref="eric5.eric5_doc.html#usage" />
+      <keyword name="version" id="version" ref="eric5.eric5_doc.html#version" />
       <keyword name="eric5_sqlbrowser (Module)" id="eric5_sqlbrowser (Module)" ref="eric5.eric5_sqlbrowser.html" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric5.eric5_sqlbrowser.html#createMainWidget" />
       <keyword name="main" id="main" ref="eric5.eric5_sqlbrowser.html#main" />
@@ -10798,12 +10798,12 @@
       <file>eric5.ViewManager.ViewManager.html</file>
       <file>eric5.ViewManager.__init__.html</file>
       <file>eric5.compileUiFiles.html</file>
-      <file>eric5.eric5-api.html</file>
-      <file>eric5.eric5-doc.html</file>
       <file>eric5.eric5.html</file>
+      <file>eric5.eric5_api.html</file>
       <file>eric5.eric5_compare.html</file>
       <file>eric5.eric5_configure.html</file>
       <file>eric5.eric5_diff.html</file>
+      <file>eric5.eric5_doc.html</file>
       <file>eric5.eric5_editor.html</file>
       <file>eric5.eric5_iconeditor.html</file>
       <file>eric5.eric5_plugininstall.html</file>
--- a/Documentation/Source/eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.html	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Source/eric5.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog.html	Sat Feb 26 14:28:21 2011 +0100
@@ -49,7 +49,7 @@
 QDialog, Ui_SyntaxCheckerDialog
 <h3>Class Attributes</h3>
 <table>
-<tr><td>errorRole</td></tr><tr><td>filenameRole</td></tr><tr><td>lineRole</td></tr><tr><td>warningRole</td></tr>
+<tr><td>errorRole</td></tr><tr><td>filenameRole</td></tr><tr><td>indexRole</td></tr><tr><td>lineRole</td></tr><tr><td>warningRole</td></tr>
 </table>
 <h3>Methods</h3>
 <table>
@@ -105,16 +105,19 @@
         Private method to clear all error markers of open editors.
 </p><a NAME="SyntaxCheckerDialog.__createResultItem" ID="SyntaxCheckerDialog.__createResultItem"></a>
 <h4>SyntaxCheckerDialog.__createResultItem</h4>
-<b>__createResultItem</b>(<i>file, line, error, sourcecode, isWarning = False</i>)
+<b>__createResultItem</b>(<i>file, line, index, error, sourcecode, isWarning = False</i>)
 <p>
         Private method to create an entry in the result list.
 </p><dl>
 <dt><i>file</i></dt>
 <dd>
-filename of file (string)
+file name of file (string)
 </dd><dt><i>line</i></dt>
 <dd>
-linenumber of faulty source (integer or string)
+line number of faulty source (integer or string)
+</dd><dt><i>index</i></dt>
+<dd>
+index number of fault (integer)
 </dd><dt><i>error</i></dt>
 <dd>
 error text (string)
--- a/Documentation/Source/eric5.QScintilla.Editor.html	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Source/eric5.QScintilla.Editor.html	Sat Feb 26 14:28:21 2011 +0100
@@ -1910,7 +1910,8 @@
 <h4>Editor.__showSyntaxError</h4>
 <b>__showSyntaxError</b>(<i>line = -1</i>)
 <p>
-        Private slot to handle the 'Show syntax error message' context menu action.
+        Private slot to handle the 'Show syntax error message'
+        context menu action.
 </p><dl>
 <dt><i>line</i></dt>
 <dd>
@@ -3230,13 +3231,16 @@
 </dd>
 </dl><a NAME="Editor.toggleSyntaxError" ID="Editor.toggleSyntaxError"></a>
 <h4>Editor.toggleSyntaxError</h4>
-<b>toggleSyntaxError</b>(<i>line, error, msg = ""</i>)
+<b>toggleSyntaxError</b>(<i>line, index, error, msg = "", show = False</i>)
 <p>
         Public method to toggle a syntax error indicator.
 </p><dl>
 <dt><i>line</i></dt>
 <dd>
-line number of the syntax error
+line number of the syntax error (integer)
+</dd><dt><i>index</i></dt>
+<dd>
+index number of the syntax error (integer)
 </dd><dt><i>error</i></dt>
 <dd>
 flag indicating if the error marker should be
@@ -3244,6 +3248,10 @@
 </dd><dt><i>msg</i></dt>
 <dd>
 error message (string)
+</dd><dt><i>show=</i></dt>
+<dd>
+flag indicating to set the cursor to the error position
+            (boolean)
 </dd>
 </dl><a NAME="Editor.uncommentLine" ID="Editor.uncommentLine"></a>
 <h4>Editor.uncommentLine</h4>
--- a/Documentation/Source/eric5.Utilities.__init__.html	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Source/eric5.Utilities.__init__.html	Sat Feb 26 14:28:21 2011 +0100
@@ -380,9 +380,9 @@
 <dt>Returns:</dt>
 <dd>
 A tuple indicating status (True = an error was found), the
-        filename, the linenumber, the code string and the error message
-        (boolean, string, string, string, string). The values are only
-        valid, if the status is True.
+        file name, the line number, the index number, the code string
+        and the error message (boolean, string, string, string, string,
+        string). The values are only valid, if the status is True.
 </dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
@@ -1247,12 +1247,12 @@
 <dt>Returns:</dt>
 <dd>
 A tuple indicating status (True = an error was found), the
-        file name, the line number, the code string, the error message
-        and a list of tuples of pyflakes warnings indicating file name,
-        line number and message (boolean, string, string, string, string, 
-        list of (string, string, string)). The syntax error values are only
-        valid, if the status is True. The pyflakes list will be empty, if a
-        syntax error was detected by the syntax checker.
+        file name, the line number, the index number, the code string,
+        the error message and a list of tuples of pyflakes warnings indicating
+        file name, line number and message (boolean, string, string, string,
+        string, string, list of (string, string, string)). The syntax error
+        values are only valid, if the status is True. The pyflakes list will
+        be empty, if a syntax error was detected by the syntax checker.
 </dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
--- a/Documentation/Source/eric5.UtilitiesPython2.Py2SyntaxChecker.html	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Source/eric5.UtilitiesPython2.Py2SyntaxChecker.html	Sat Feb 26 14:28:21 2011 +0100
@@ -59,10 +59,10 @@
 </dl><dl>
 <dt>Returns:</dt>
 <dd>
-A tuple indicating status (1 = an error was found), the
-        filename, the linenumber, the code string and the error message
-        (boolean, string, string, string, string). The values are only 
-        valid, if the status equals 1.
+A tuple indicating status (True = an error was found), the
+        file name, the line number, the index number, the code string
+        and the error message (boolean, string, string, string, string,
+        string). The values are only valid, if the status equals 1.
 </dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
--- a/Documentation/Source/index-eric5.html	Sat Feb 26 14:26:59 2011 +0100
+++ b/Documentation/Source/index-eric5.html	Sat Feb 26 14:28:21 2011 +0100
@@ -129,12 +129,9 @@
 <td><a href="eric5.eric5.html">eric5</a></td>
 <td>Eric5 Python IDE</td>
 </tr><tr>
-<td><a href="eric5.eric5-api.html">eric5-api</a></td>
+<td><a href="eric5.eric5_api.html">eric5_api</a></td>
 <td>Eric5 API Generator</td>
 </tr><tr>
-<td><a href="eric5.eric5-doc.html">eric5-doc</a></td>
-<td>Eric5 Documentation Generator</td>
-</tr><tr>
 <td><a href="eric5.eric5_compare.html">eric5_compare</a></td>
 <td>Eric5 Compare</td>
 </tr><tr>
@@ -144,6 +141,9 @@
 <td><a href="eric5.eric5_diff.html">eric5_diff</a></td>
 <td>Eric5 Diff</td>
 </tr><tr>
+<td><a href="eric5.eric5_doc.html">eric5_doc</a></td>
+<td>Eric5 Documentation Generator</td>
+</tr><tr>
 <td><a href="eric5.eric5_editor.html">eric5_editor</a></td>
 <td>Eric5 Editor</td>
 </tr><tr>
--- a/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Sat Feb 26 14:26:59 2011 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Sat Feb 26 14:28:21 2011 +0100
@@ -29,8 +29,9 @@
     """
     filenameRole = Qt.UserRole + 1
     lineRole     = Qt.UserRole + 2
-    errorRole    = Qt.UserRole + 3
-    warningRole  = Qt.UserRole + 4
+    indexRole    = Qt.UserRole + 3
+    errorRole    = Qt.UserRole + 4
+    warningRole  = Qt.UserRole + 5
     
     def __init__(self, parent = None):
         """
@@ -68,13 +69,14 @@
                                   self.resultList.header().sortIndicatorOrder()
                                  )
         
-    def __createResultItem(self, file, line, error, sourcecode, 
+    def __createResultItem(self, file, line, index, error, sourcecode, 
                            isWarning = False):
         """
         Private method to create an entry in the result list.
         
-        @param file filename of file (string)
-        @param line linenumber of faulty source (integer or string)
+        @param file file name of file (string)
+        @param line line number of faulty source (integer or string)
+        @param index index number of fault (integer)
         @param error error text (string)
         @param sourcecode faulty line of code (string)
         @param isWarning flag indicating a warning message (boolean)
@@ -94,6 +96,7 @@
             itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError.png"))
         itm.setData(0, self.filenameRole, file)
         itm.setData(0, self.lineRole, int(line))
+        itm.setData(0, self.indexRole, index)
         itm.setData(0, self.errorRole, error)
         itm.setData(0, self.warningRole, isWarning)
         
@@ -185,7 +188,7 @@
                         source = Utilities.convertLineEnds(source, "\n")
                     except (UnicodeError, IOError) as msg:
                         self.noResults = False
-                        self.__createResultItem(file, "1", 
+                        self.__createResultItem(file, "1", 0, 
                             self.trUtf8("Error: {0}").format(str(msg))\
                                 .rstrip()[1:-1], "")
                         progress += 1
@@ -203,17 +206,17 @@
                     self.__project.getProjectLanguage() in ["Python", 
                                                             "Python2"]):
                     isPy3 = False
-                    nok, fname, line, code, error, warnings = \
+                    nok, fname, line, index, code, error, warnings = \
                         Utilities.py2compile(file, 
                             checkFlakes = \
                                 Preferences.getFlakes("IncludeInSyntaxCheck"))
                 else:
                     isPy3 = True
-                    nok, fname, line, code, error = \
+                    nok, fname, line, index, code, error = \
                         Utilities.compile(file, source)
                 if nok:
                     self.noResults = False
-                    self.__createResultItem(fname, line, error, code)
+                    self.__createResultItem(fname, line, index, error, code)
                 else:
                     if Preferences.getFlakes("IncludeInSyntaxCheck"):
                         if isPy3:
@@ -231,7 +234,7 @@
                                        .endswith("__IGNORE_WARNING__"):
                                         self.noResults = False
                                         self.__createResultItem(
-                                            fname, lineno, message, "", 
+                                            fname, lineno, 0, message, "", 
                                             isWarning = True)
                             except SyntaxError as err:
                                 if err.text.strip():
@@ -239,12 +242,12 @@
                                 else:
                                     msg = err.msg
                                 self.__createResultItem(
-                                    err.filename, err.lineno, msg, "")
+                                    err.filename, err.lineno, 0, msg, "")
                         else:
                             for warning in warnings:
                                 self.noResults = False
                                 self.__createResultItem(
-                                    warning[0], int(warning[1]), 
+                                    warning[0], int(warning[1]), 0, 
                                     warning[2], "", isWarning = True)
                 progress += 1
             self.checkProgress.setValue(progress)
@@ -326,6 +329,7 @@
         if itm.parent():
             fn = Utilities.normabspath(itm.data(0, self.filenameRole))
             lineno = itm.data(0, self.lineRole)
+            index = itm.data(0, self.indexRole)
             error = itm.data(0, self.errorRole)
             
             vm = e5App().getObject("ViewManager")
@@ -335,7 +339,7 @@
             if itm.data(0, self.warningRole):
                 editor.toggleFlakesWarning(lineno, True, error)
             else:
-                editor.toggleSyntaxError(lineno, True, error)
+                editor.toggleSyntaxError(lineno, index, True, error, show=True)
         
     @pyqtSlot()
     def on_showButton_clicked(self):
--- a/QScintilla/Editor.py	Sat Feb 26 14:26:59 2011 +0100
+++ b/QScintilla/Editor.py	Sat Feb 26 14:28:21 2011 +0100
@@ -167,7 +167,7 @@
         self.bookmarks = []         # bookmarks are just a list of handles to the
                                     # bookmark markers
         self.syntaxerrors = {}      # key:   marker handle
-                                    # value: error message
+                                    # value: error message, error index
         self.warnings = {}          # key:   marker handle
                                     # value: list of warning messages
         self.notcoveredMarkers = [] # just a list of marker handles
@@ -4074,7 +4074,7 @@
                 self.marginMenuActs["ShowWarning"].setEnabled(False)
         else:
             self.marginMenuActs["NextWarningMarker"].setEnabled(False)
-            self.marginMenuActs["PreviousWarningMarker"].setEnabled(True)
+            self.marginMenuActs["PreviousWarningMarker"].setEnabled(False)
             self.marginMenuActs["ClearWarnings"].setEnabled(False)
             self.marginMenuActs["ShowWarning"].setEnabled(False)
         
@@ -4218,16 +4218,19 @@
             self.clearSyntaxError()
             self.clearFlakesWarnings()
             if self.isPy3File():
-                syntaxError, _fn, errorline, _code, _error = \
+                syntaxError, _fn, errorline, errorindex, _code, _error = \
                     Utilities.compile(self.fileName, self.text())
                 if syntaxError:
-                    self.toggleSyntaxError(int(errorline), True, _error)
+                    self.toggleSyntaxError(
+                        int(errorline), int(errorindex), True, _error)
                 else:
                     if Preferences.getFlakes("IncludeInSyntaxCheck"):
                         ignoreStarImportWarnings = \
                             Preferences.getFlakes("IgnoreStarImportWarnings")
                         try:
-                            txt = self.text().replace("\r\n", "\n").replace("\r", "\n")
+                            txt = self.text()\
+                                .replace("\r\n", "\n")\
+                                .replace("\r", "\n")
                             warnings = Checker(txt, self.fileName)
                             warnings.messages.sort(key = lambda a: a.lineno)
                             for warning in warnings.messages:
@@ -4238,7 +4241,8 @@
                                 _fn, lineno, message = warning.getMessageData()
                                 if not self.text(lineno - 1).strip()\
                                    .endswith("__IGNORE_WARNING__"):
-                                    self.toggleFlakesWarning(lineno, True, message)
+                                    self.toggleFlakesWarning(
+                                        lineno, True, message)
                         except SyntaxError as err:
                             if err.text.strip():
                                 msg = err.text.strip()
@@ -4246,15 +4250,17 @@
                                 msg = err.msg
                             self.toggleSyntaxError(err.lineno, True, msg)
             elif self.isPy2File():
-                syntaxError, _fn, errorline, _code, _error, warnings = \
-                    Utilities.py2compile(
-                        self.fileName, 
-                        checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck"))
+                syntaxError, _fn, errorline, errorindex, _code, _error, \
+                warnings = Utilities.py2compile(
+                    self.fileName, 
+                    checkFlakes=Preferences.getFlakes("IncludeInSyntaxCheck"))
                 if syntaxError:
-                    self.toggleSyntaxError(int(errorline), True, _error)
+                    self.toggleSyntaxError(
+                        int(errorline), int(errorindex), True, _error)
                 else:
                     for warning in warnings:
-                        self.toggleFlakesWarning(int(warning[1]), True, warning[2])
+                        self.toggleFlakesWarning(
+                            int(warning[1]), True, warning[2])
         
     def __showCodeMetrics(self):
         """
@@ -4480,14 +4486,17 @@
     ## Syntax error handling methods below
     ############################################################################
 
-    def toggleSyntaxError(self, line, error, msg = ""):
+    def toggleSyntaxError(self, line, index, error, msg = "", show = False):
         """
         Public method to toggle a syntax error indicator.
         
-        @param line line number of the syntax error
+        @param line line number of the syntax error (integer)
+        @param index index number of the syntax error (integer)
         @param error flag indicating if the error marker should be
             set or deleted (boolean)
         @param msg error message (string)
+        @keyparam show flag indicating to set the cursor to the error position
+            (boolean)
         """
         if line == 0:
             line = 1
@@ -4497,8 +4506,12 @@
             markers = self.markersAtLine(line - 1)
             if not (markers & (1 << self.syntaxerror)):
                 handle = self.markerAdd(line - 1, self.syntaxerror)
-                self.syntaxerrors[handle] = msg
+                index += self.indentation(line - 1)
+                self.syntaxerrors[handle] = (msg, index)
                 self.syntaxerrorToggled.emit(self)
+                if show:
+                    self.setCursorPosition(line - 1, index)
+                    self.ensureLineVisible(line - 1)
         else:
             for handle in list(self.syntaxerrors.keys()):
                 if self.markerLine(handle) == line - 1:
@@ -4536,8 +4549,12 @@
         """
         seline = self.markerFindNext(0, 1 << self.syntaxerror)
         if seline >= 0:
-            self.setCursorPosition(seline, 0)
-            self.ensureLineVisible(seline)
+            index = 0
+            for handle in self.syntaxerrors.keys():
+                if self.markerLine(handle) == seline:
+                    index = self.syntaxerrors[handle][1]
+            self.setCursorPosition(seline, index)
+        self.ensureLineVisible(seline)
         
     def clearSyntaxError(self):
         """
@@ -4545,11 +4562,12 @@
         """
         for handle in list(self.syntaxerrors.keys()):
             line = self.markerLine(handle) + 1
-            self.toggleSyntaxError(line, False)
+            self.toggleSyntaxError(line, 0, False)
         
     def __showSyntaxError(self, line = -1):
         """
-        Private slot to handle the 'Show syntax error message' context menu action.
+        Private slot to handle the 'Show syntax error message'
+        context menu action.
         
         @param line line number to show the syntax error for (integer)
         """
@@ -4560,7 +4578,7 @@
             if self.markerLine(handle) == line:
                 E5MessageBox.critical(self,
                     self.trUtf8("Syntax Error"),
-                    self.syntaxerrors[handle])
+                    self.syntaxerrors[handle][0])
                 break
         else:
             E5MessageBox.critical(self,
@@ -4739,7 +4757,8 @@
             for handle in list(self.syntaxerrors.keys()):
                 if self.markerLine(handle) == line:
                     errorAnnotations.append(
-                        self.trUtf8("Error: {0}").format(self.syntaxerrors[handle]))
+                        self.trUtf8("Error: {0}").format(
+                            self.syntaxerrors[handle][0]))
             
             wLen = len(warningAnnotations)
             eLen = len(errorAnnotations)
--- a/Utilities/__init__.py	Sat Feb 26 14:26:59 2011 +0100
+++ b/Utilities/__init__.py	Sat Feb 26 14:28:21 2011 +0100
@@ -1041,9 +1041,9 @@
     @param file source filename (string)
     @param codestring string containing the code to compile (string)
     @return A tuple indicating status (True = an error was found), the
-        filename, the linenumber, the code string and the error message
-        (boolean, string, string, string, string). The values are only
-        valid, if the status is True.
+        file name, the line number, the index number, the code string
+        and the error message (boolean, string, string, string, string,
+        string). The values are only valid, if the status is True.
     """
     import builtins
     if not codestring:
@@ -1078,19 +1078,24 @@
             if lines[1].startswith('SyntaxError:'):
                 code = ""
                 error = re.match('SyntaxError: (.+)', lines[1]).group(1)
+                index = "0"
             else:
                 code = re.match('(.+)', lines[1]).group(1)
                 error = ""
+                index = "0"
                 for seLine in lines[2:]:
                     if seLine.startswith('SyntaxError:'):
                         error = re.match('SyntaxError: (.+)', seLine).group(1)
+                    elif seLine.rstrip().endswith('^'):
+                        index = len(seLine.rstrip()) - 4
         else:
             fn = detail.filename
             line = detail.lineno and detail.lineno or 1
             code = ""
             error = detail.msg
-        return (True, fn, line, code, error)
+        return (True, fn, line, index, code, error)
     except ValueError as detail:
+        index = "0"
         try:
             fn = detail.filename
             line = detail.lineno
@@ -1100,18 +1105,19 @@
             line = 1
             error = str(detail)
         code = ""
-        return (True, fn, line, code, error)
+        return (True, fn, line, index, code, error)
     except Exception as detail:
         try:
             fn = detail.filename
             line = detail.lineno
             code = ""
             error = detail.msg
-            return (True, fn, line, code, error)
+            index = "0"
+            return (True, fn, line, index, code, error)
         except:         # this catchall is intentional
             pass
     
-    return (False, None, None, None, None)
+    return (False, None, None, None, None, None)
 
 def py2compile(file, checkFlakes = False):
     """
@@ -1120,12 +1126,12 @@
     @param file source filename (string)
     @keyparam checkFlakes flag indicating to do a pyflakes check (boolean)
     @return A tuple indicating status (True = an error was found), the
-        file name, the line number, the code string, the error message
-        and a list of tuples of pyflakes warnings indicating file name,
-        line number and message (boolean, string, string, string, string, 
-        list of (string, string, string)). The syntax error values are only
-        valid, if the status is True. The pyflakes list will be empty, if a
-        syntax error was detected by the syntax checker.
+        file name, the line number, the index number, the code string,
+        the error message and a list of tuples of pyflakes warnings indicating
+        file name, line number and message (boolean, string, string, string,
+        string, string, list of (string, string, string)). The syntax error
+        values are only valid, if the status is True. The pyflakes list will
+        be empty, if a syntax error was detected by the syntax checker.
     """
     interpreter = Preferences.getDebugger("PythonInterpreter")
     if interpreter == "" or not isExecutable(interpreter):
@@ -1157,11 +1163,12 @@
         if syntaxerror:
             fn = output[1]
             line = output[2]
-            code = output[3]
-            error = output[4]
-            return (True, fn, line, code, error, [])
+            index = output[3]
+            code = output[4]
+            error = output[5]
+            return (True, fn, line, index, code, error, [])
         else:
-            index = 5
+            index = 6
             warnings = []
             while index < len(output):
                 if output[index] == "FLAKES_ERROR":
@@ -1172,9 +1179,9 @@
                                      output[index + 3]))
                 index += 4
             
-            return (False, None, None, None, None, warnings)
+            return (False, None, None, None, None, None, warnings)
     
-    return (True, file, "1", "", 
+    return (True, file, "1", "0", "", 
         QCoreApplication.translate("Utilities",
                                    "Python2 interpreter did not finish within 30s."), 
         [])
--- a/UtilitiesPython2/Py2SyntaxChecker.py	Sat Feb 26 14:26:59 2011 +0100
+++ b/UtilitiesPython2/Py2SyntaxChecker.py	Sat Feb 26 14:28:21 2011 +0100
@@ -23,10 +23,10 @@
     
     @param file source filename (string)
     @param codestring source code (string)
-    @return A tuple indicating status (1 = an error was found), the
-        filename, the linenumber, the code string and the error message
-        (boolean, string, string, string, string). The values are only 
-        valid, if the status equals 1.
+    @return A tuple indicating status (True = an error was found), the
+        file name, the line number, the index number, the code string
+        and the error message (boolean, string, string, string, string,
+        string). The values are only valid, if the status equals 1.
     """
     import __builtin__
     
@@ -52,19 +52,24 @@
             if lines[1].startswith('SyntaxError:'):
                 code = ""
                 error = re.match('SyntaxError: (.+)', lines[1]).group(1)
+                index = "0"
             else:
                 code = re.match('(.+)', lines[1]).group(1)
                 error = ""
+                index = "0"
                 for seLine in lines[2:]:
                     if seLine.startswith('SyntaxError:'):
                         error = re.match('SyntaxError: (.+)', seLine).group(1)
+                    elif seLine.rstrip().endswith('^'):
+                        index = len(seLine.rstrip()) - 4
         else:
             fn = detail.filename
             line = detail.lineno and detail.lineno or 1
             code = ""
             error = detail.msg
-        return (1, fn, line, code, error)
+        return (1, fn, line, index, code, error)
     except ValueError, detail:
+        index = "0"
         try:
             fn = detail.filename
             line = detail.lineno
@@ -74,18 +79,19 @@
             line = 1
             error = unicode(detail)
         code = ""
-        return (1, fn, line, code, error)
+        return (1, fn, line, index, code, error)
     except StandardError, detail:
         try:
             fn = detail.filename
             line = detail.lineno
             code = ""
             error = detail.msg
-            return (1, fn, line, code, error)
+            index = "0"
+            return (1, fn, line, index, code, error)
         except:         # this catchall is intentional
             pass
     
-    return (0, None, None, None, None)
+    return (0, None, None, None, None, None)
 
 def flakesCheck(fileName, codestring, ignoreStarImportWarnings):
     """
@@ -129,6 +135,7 @@
         print ""
         print ""
         print ""
+        print ""
         print "No file name given."
     else:
         filename = sys.argv[-1]
@@ -136,11 +143,12 @@
             codestring = readEncodedFile(filename)[0]
             codestring = normalizeCode(codestring)
             
-            syntaxerror, fname, line, code, error = compile(filename, codestring)
+            syntaxerror, fname, line, index, code, error = \
+                compile(filename, codestring)
         except IOError, msg:
             # fake a syntax error
-            syntaxerror, fname, line, code, error = \
-                1, filename, "1", "", "I/O Error: %s" % unicode(msg)
+            syntaxerror, fname, line, index, code, error = \
+                1, filename, "1", "0", "", "I/O Error: %s" % unicode(msg)
         
         if syntaxerror:
             print "ERROR"
@@ -148,6 +156,7 @@
             print "NO_ERROR"
         print fname
         print line
+        print index
         print code
         print error
         
--- a/changelog	Sat Feb 26 14:26:59 2011 +0100
+++ b/changelog	Sat Feb 26 14:28:21 2011 +0100
@@ -5,6 +5,7 @@
 - added menu entry for the icon editor to the tray starter
 - added capability to filter out unwanted items in the file browsers
   (s. config dialog, interface page)
+- changed syntax check to report error position within the line
 
 Version 5.1-snapshot-20110123:
 - bug fixes

eric ide

mercurial