10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 import os |
12 import os |
13 |
13 |
14 from PyQt4.QtCore import QObject |
14 from PyQt4.QtCore import QObject |
15 |
15 from PyQt4.QtGui import QApplication |
|
16 |
|
17 from E5Gui.E5Action import E5Action |
16 from E5Gui.E5Application import e5App |
18 from E5Gui.E5Application import e5App |
17 |
19 from eric5config import getConfig |
18 from E5Gui.E5Action import E5Action |
|
19 |
20 |
20 import Preferences |
21 import Preferences |
21 |
22 |
22 # Start-Of-Header |
23 # Start-Of-Header |
23 name = "Syntax Checker Plugin" |
24 name = "Syntax Checker Plugin" |
49 """ |
50 """ |
50 super(SyntaxCheckerPlugin, self).__init__(ui) |
51 super(SyntaxCheckerPlugin, self).__init__(ui) |
51 self.__ui = ui |
52 self.__ui = ui |
52 self.__initialize() |
53 self.__initialize() |
53 |
54 |
|
55 from Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheckService import \ |
|
56 SyntaxCheckService |
|
57 self.syntaxCheckService = SyntaxCheckService() |
|
58 e5App().registerObject("SyntaxCheckService", self.syntaxCheckService) |
|
59 |
|
60 ericPath = getConfig('ericDir') |
|
61 path = os.path.join(ericPath, 'Plugins', 'CheckerPlugins', |
|
62 'SyntaxChecker') |
|
63 |
|
64 self.syntaxCheckService.addLanguage( |
|
65 'Python2', path, 'SyntaxCheck', |
|
66 self.__getPythonOptions, |
|
67 lambda: Preferences.getPython("PythonExtensions"), |
|
68 self.__translateSyntaxCheck, |
|
69 lambda fx, lng, fn, msg: |
|
70 self.syntaxCheckService.syntaxChecked.emit( |
|
71 fn, {'error': (fn, 0, 0, '', msg)})) |
|
72 |
|
73 self.syntaxCheckService.addLanguage( |
|
74 'Python3', path, 'SyntaxCheck', |
|
75 self.__getPythonOptions, |
|
76 lambda: Preferences.getPython("Python3Extensions"), |
|
77 self.__translateSyntaxCheck, |
|
78 lambda fx, lng, fn, msg: |
|
79 self.syntaxCheckService.syntaxChecked.emit( |
|
80 fn, {'error': (fn, 0, 0, '', msg)})) |
|
81 |
54 def __initialize(self): |
82 def __initialize(self): |
55 """ |
83 """ |
56 Private slot to (re)initialize the plugin. |
84 Private slot to (re)initialize the plugin. |
57 """ |
85 """ |
58 self.__projectAct = None |
86 self.__projectAct = None |
63 self.__projectBrowserSyntaxCheckerDialog = None |
91 self.__projectBrowserSyntaxCheckerDialog = None |
64 |
92 |
65 self.__editors = [] |
93 self.__editors = [] |
66 self.__editorAct = None |
94 self.__editorAct = None |
67 self.__editorSyntaxCheckerDialog = None |
95 self.__editorSyntaxCheckerDialog = None |
|
96 |
|
97 def __getPythonOptions(self): |
|
98 """ |
|
99 Private methode to determine the syntax check options. |
|
100 |
|
101 @return state of checkFlakes and ignoreStarImportWarnings (bool, bool) |
|
102 """ |
|
103 checkFlakes = Preferences.getFlakes("IncludeInSyntaxCheck") |
|
104 ignoreStarImportWarnings = Preferences.getFlakes( |
|
105 "IgnoreStarImportWarnings") |
|
106 return checkFlakes, ignoreStarImportWarnings |
|
107 |
|
108 def __translateSyntaxCheck(self, fn, problems): |
|
109 """ |
|
110 Slot to translate the resulting messages. |
|
111 |
|
112 If checkFlakes is True, warnings contains a list of strings containing |
|
113 the warnings (marker, file name, line number, message) |
|
114 The values are only valid, if nok is False. |
|
115 |
|
116 @param fn filename of the checked file (str) |
|
117 @param problems dictionary with the keys 'error' and 'warnings' which |
|
118 hold a list containing details about the error/ warnings |
|
119 (file name, line number, column, codestring (only at syntax |
|
120 errors), the message, a list with arguments for the message) |
|
121 """ |
|
122 warnings = problems.get('warnings', []) |
|
123 for warning in warnings: |
|
124 # Translate messages |
|
125 msg_args = warning.pop() |
|
126 translated = QApplication.translate( |
|
127 'py3Flakes', warning[4]).format(*msg_args) |
|
128 # Avoid leading "u" at Python2 unicode strings |
|
129 if translated.startswith("u'"): |
|
130 translated = translated[1:] |
|
131 warning[4] = translated.replace(" u'", " '") |
|
132 |
|
133 problems['warnings'] = warnings |
|
134 self.syntaxCheckService.syntaxChecked.emit(fn, problems) |
68 |
135 |
69 def activate(self): |
136 def activate(self): |
70 """ |
137 """ |
71 Public method to activate this plugin. |
138 Public method to activate this plugin. |
72 |
139 |
150 @param menu reference to the menu (QMenu) |
217 @param menu reference to the menu (QMenu) |
151 """ |
218 """ |
152 if menuName == "Checks" and self.__projectAct is not None: |
219 if menuName == "Checks" and self.__projectAct is not None: |
153 self.__projectAct.setEnabled( |
220 self.__projectAct.setEnabled( |
154 e5App().getObject("Project").getProjectLanguage() in |
221 e5App().getObject("Project").getProjectLanguage() in |
155 ["Python3", "Python2", "Python"]) |
222 self.syntaxCheckService.getLanguages()) |
156 |
223 |
157 def __projectBrowserShowMenu(self, menuName, menu): |
224 def __projectBrowserShowMenu(self, menuName, menu): |
158 """ |
225 """ |
159 Private slot called, when the the project browser menu or a submenu is |
226 Private slot called, when the the project browser menu or a submenu is |
160 about to be shown. |
227 about to be shown. |
162 @param menuName name of the menu to be shown (string) |
229 @param menuName name of the menu to be shown (string) |
163 @param menu reference to the menu (QMenu) |
230 @param menu reference to the menu (QMenu) |
164 """ |
231 """ |
165 if menuName == "Checks" and \ |
232 if menuName == "Checks" and \ |
166 e5App().getObject("Project").getProjectLanguage() in \ |
233 e5App().getObject("Project").getProjectLanguage() in \ |
167 ["Python3", "Python2", "Python"]: |
234 self.syntaxCheckService.getLanguages(): |
168 self.__projectBrowserMenu = menu |
235 self.__projectBrowserMenu = menu |
169 if self.__projectBrowserAct is None: |
236 if self.__projectBrowserAct is None: |
170 self.__projectBrowserAct = E5Action( |
237 self.__projectBrowserAct = E5Action( |
171 self.trUtf8('Check Syntax'), |
238 self.trUtf8('Check Syntax'), |
172 self.trUtf8('&Syntax...'), 0, 0, |
239 self.trUtf8('&Syntax...'), 0, 0, |
185 Public slot used to check the project files for syntax errors. |
252 Public slot used to check the project files for syntax errors. |
186 """ |
253 """ |
187 project = e5App().getObject("Project") |
254 project = e5App().getObject("Project") |
188 project.saveAllScripts() |
255 project.saveAllScripts() |
189 ppath = project.getProjectPath() |
256 ppath = project.getProjectPath() |
|
257 extensions = tuple(self.syntaxCheckService.getExtensions()) |
190 files = [os.path.join(ppath, file) |
258 files = [os.path.join(ppath, file) |
191 for file in project.pdata["SOURCES"] |
259 for file in project.pdata["SOURCES"] |
192 if file.endswith( |
260 if file.endswith(extensions)] |
193 tuple(Preferences.getPython("Python3Extensions")) + |
|
194 tuple(Preferences.getPython("PythonExtensions")))] |
|
195 |
261 |
196 from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ |
262 from CheckerPlugins.SyntaxChecker.SyntaxCheckerDialog import \ |
197 SyntaxCheckerDialog |
263 SyntaxCheckerDialog |
198 self.__projectSyntaxCheckerDialog = SyntaxCheckerDialog() |
264 self.__projectSyntaxCheckerDialog = SyntaxCheckerDialog() |
199 self.__projectSyntaxCheckerDialog.show() |
265 self.__projectSyntaxCheckerDialog.show() |
252 """ |
318 """ |
253 if menuName == "Checks": |
319 if menuName == "Checks": |
254 if not self.__editorAct in menu.actions(): |
320 if not self.__editorAct in menu.actions(): |
255 menu.addAction(self.__editorAct) |
321 menu.addAction(self.__editorAct) |
256 self.__editorAct.setEnabled( |
322 self.__editorAct.setEnabled( |
257 editor.isPy3File() or editor.isPy2File()) |
323 editor.getLanguage() in self.syntaxCheckService.getLanguages()) |
258 |
324 |
259 def __editorSyntaxCheck(self): |
325 def __editorSyntaxCheck(self): |
260 """ |
326 """ |
261 Private slot to handle the syntax check context menu action of the |
327 Private slot to handle the syntax check context menu action of the |
262 editors. |
328 editors. |