16 |
16 |
17 |
17 |
18 class SyntaxCheckService(QObject): |
18 class SyntaxCheckService(QObject): |
19 """ |
19 """ |
20 Implement the syntax check service. |
20 Implement the syntax check service. |
21 |
21 |
22 Plugins can add other languages to the syntax check by calling addLanguage |
22 Plugins can add other languages to the syntax check by calling addLanguage |
23 and support of an extra checker module on the client side which has to |
23 and support of an extra checker module on the client side which has to |
24 connect directly to the background service. |
24 connect directly to the background service. |
25 |
25 |
26 @signal syntaxChecked(str, dict) emitted when the syntax check was done for |
26 @signal syntaxChecked(str, dict) emitted when the syntax check was done for |
27 one file |
27 one file |
28 @signal batchFinished() emitted when a syntax check batch is done |
28 @signal batchFinished() emitted when a syntax check batch is done |
29 @signal error(str, str) emitted in case of an error |
29 @signal error(str, str) emitted in case of an error |
30 """ |
30 """ |
|
31 |
31 syntaxChecked = pyqtSignal(str, dict) |
32 syntaxChecked = pyqtSignal(str, dict) |
32 batchFinished = pyqtSignal() |
33 batchFinished = pyqtSignal() |
33 error = pyqtSignal(str, str) |
34 error = pyqtSignal(str, str) |
34 |
35 |
35 def __init__(self): |
36 def __init__(self): |
36 """ |
37 """ |
37 Constructor |
38 Constructor |
38 """ |
39 """ |
39 super().__init__() |
40 super().__init__() |
40 self.backgroundService = ericApp().getObject("BackgroundService") |
41 self.backgroundService = ericApp().getObject("BackgroundService") |
41 self.__supportedLanguages = {} |
42 self.__supportedLanguages = {} |
42 |
43 |
43 self.queuedBatches = [] |
44 self.queuedBatches = [] |
44 self.batchesFinished = True |
45 self.batchesFinished = True |
45 |
46 |
46 def __determineLanguage(self, filename, source): |
47 def __determineLanguage(self, filename, source): |
47 """ |
48 """ |
48 Private method to determine the language of the file. |
49 Private method to determine the language of the file. |
49 |
50 |
50 @param filename of the sourcefile (str) |
51 @param filename of the sourcefile (str) |
51 @param source code of the file (str) |
52 @param source code of the file (str) |
52 @return language of the file or None if not found (str or None) |
53 @return language of the file or None if not found (str or None) |
53 """ |
54 """ |
54 pyVer = determinePythonVersion(filename, source) |
55 pyVer = determinePythonVersion(filename, source) |
55 if pyVer: |
56 if pyVer: |
56 return 'Python{0}'.format(pyVer) |
57 return "Python{0}".format(pyVer) |
57 |
58 |
58 for lang, (_env, _getArgs, getExt) in ( |
59 for lang, (_env, _getArgs, getExt) in self.__supportedLanguages.items(): |
59 self.__supportedLanguages.items() |
|
60 ): |
|
61 if filename.endswith(tuple(getExt())): |
60 if filename.endswith(tuple(getExt())): |
62 return lang |
61 return lang |
63 |
62 |
64 return None |
63 return None |
65 |
64 |
66 def addLanguage( |
65 def addLanguage(self, lang, env, path, module, getArgs, getExt, callback, onError): |
67 self, lang, env, path, module, getArgs, getExt, callback, onError): |
|
68 """ |
66 """ |
69 Public method to register a new language to the supported languages. |
67 Public method to register a new language to the supported languages. |
70 |
68 |
71 @param lang new language to check syntax (str) |
69 @param lang new language to check syntax (str) |
72 @param env the environment in which the checker is implemented (str) |
70 @param env the environment in which the checker is implemented (str) |
73 @param path full path to the module (str) |
71 @param path full path to the module (str) |
74 @param module name to import (str) |
72 @param module name to import (str) |
75 @param getArgs function to collect the required arguments to call the |
73 @param getArgs function to collect the required arguments to call the |
130 lang = self.__determineLanguage(filename, source) |
133 lang = self.__determineLanguage(filename, source) |
131 if lang not in self.getLanguages(): |
134 if lang not in self.getLanguages(): |
132 return |
135 return |
133 if lang == "MicroPython": |
136 if lang == "MicroPython": |
134 lang = "Python3" |
137 lang = "Python3" |
135 |
138 |
136 data = [source] |
139 data = [source] |
137 # Call the getArgs function to get the required arguments |
140 # Call the getArgs function to get the required arguments |
138 env, args, getExt = self.__supportedLanguages[lang] |
141 env, args, getExt = self.__supportedLanguages[lang] |
139 data.extend(args()) |
142 data.extend(args()) |
140 self.backgroundService.enqueueRequest( |
143 self.backgroundService.enqueueRequest( |
141 '{0}Syntax'.format(lang), env, filename, data) |
144 "{0}Syntax".format(lang), env, filename, data |
142 |
145 ) |
|
146 |
143 def syntaxBatchCheck(self, argumentsList): |
147 def syntaxBatchCheck(self, argumentsList): |
144 """ |
148 """ |
145 Public method to prepare a syntax check on multiple source files. |
149 Public method to prepare a syntax check on multiple source files. |
146 |
150 |
147 @param argumentsList list of arguments tuples with each tuple |
151 @param argumentsList list of arguments tuples with each tuple |
148 containing filename and source (string, string) |
152 containing filename and source (string, string) |
149 """ |
153 """ |
150 data = { |
154 data = {} |
151 } |
|
152 for lang in self.getLanguages(): |
155 for lang in self.getLanguages(): |
153 data[lang] = [] |
156 data[lang] = [] |
154 |
157 |
155 for filename, source in argumentsList: |
158 for filename, source in argumentsList: |
156 lang = self.__determineLanguage(filename, source) |
159 lang = self.__determineLanguage(filename, source) |
157 if lang not in self.getLanguages(): |
160 if lang not in self.getLanguages(): |
158 continue |
161 continue |
159 else: |
162 else: |
160 jobData = [source] |
163 jobData = [source] |
161 # Call the getArgs function to get the required arguments |
164 # Call the getArgs function to get the required arguments |
162 args = self.__supportedLanguages[lang][1] |
165 args = self.__supportedLanguages[lang][1] |
163 jobData.extend(args()) |
166 jobData.extend(args()) |
164 data[lang].append((filename, jobData)) |
167 data[lang].append((filename, jobData)) |
165 |
168 |
166 self.queuedBatches = [] |
169 self.queuedBatches = [] |
167 for lang in self.getLanguages(): |
170 for lang in self.getLanguages(): |
168 if data[lang]: |
171 if data[lang]: |
169 self.queuedBatches.append(lang) |
172 self.queuedBatches.append(lang) |
170 env = self.__supportedLanguages[lang][0] |
173 env = self.__supportedLanguages[lang][0] |
171 self.backgroundService.enqueueRequest( |
174 self.backgroundService.enqueueRequest( |
172 'batch_{0}Syntax'.format(lang), env, "", data[lang]) |
175 "batch_{0}Syntax".format(lang), env, "", data[lang] |
|
176 ) |
173 self.batchesFinished = False |
177 self.batchesFinished = False |
174 |
178 |
175 def cancelSyntaxBatchCheck(self): |
179 def cancelSyntaxBatchCheck(self): |
176 """ |
180 """ |
177 Public method to cancel all batch jobs. |
181 Public method to cancel all batch jobs. |
178 """ |
182 """ |
179 for lang in self.getLanguages(): |
183 for lang in self.getLanguages(): |
180 try: |
184 try: |
181 env = self.__supportedLanguages[lang][0] |
185 env = self.__supportedLanguages[lang][0] |
182 self.backgroundService.requestCancel( |
186 self.backgroundService.requestCancel( |
183 'batch_{0}Syntax'.format(lang), env) |
187 "batch_{0}Syntax".format(lang), env |
|
188 ) |
184 except KeyError: |
189 except KeyError: |
185 continue |
190 continue |
186 |
191 |
187 def __serviceError(self, fn, msg): |
192 def __serviceError(self, fn, msg): |
188 """ |
193 """ |
189 Private slot handling service errors. |
194 Private slot handling service errors. |
190 |
195 |
191 @param fn file name (string) |
196 @param fn file name (string) |
192 @param msg message text (string) |
197 @param msg message text (string) |
193 """ |
198 """ |
194 self.error.emit(fn, msg) |
199 self.error.emit(fn, msg) |
195 |
200 |
196 def serviceErrorPy3(self, fx, lang, fn, msg): |
201 def serviceErrorPy3(self, fx, lang, fn, msg): |
197 """ |
202 """ |
198 Public method handling service errors for Python 3. |
203 Public method handling service errors for Python 3. |
199 |
204 |
200 @param fx service name (string) |
205 @param fx service name (string) |
201 @param lang language (string) |
206 @param lang language (string) |
202 @param fn file name (string) |
207 @param fn file name (string) |
203 @param msg message text (string) |
208 @param msg message text (string) |
204 """ |
209 """ |
205 if fx in ['Python3Syntax', 'batch_Python3Syntax']: |
210 if fx in ["Python3Syntax", "batch_Python3Syntax"]: |
206 if fx == 'Python3Syntax': |
211 if fx == "Python3Syntax": |
207 self.__serviceError(fn, msg) |
212 self.__serviceError(fn, msg) |
208 else: |
213 else: |
209 self.__serviceError(self.tr("Python 3 batch check"), msg) |
214 self.__serviceError(self.tr("Python 3 batch check"), msg) |
210 self.batchJobDone(fx, lang) |
215 self.batchJobDone(fx, lang) |
211 |
216 |
212 def serviceErrorJavaScript(self, fx, lang, fn, msg): |
217 def serviceErrorJavaScript(self, fx, lang, fn, msg): |
213 """ |
218 """ |
214 Public method handling service errors for JavaScript. |
219 Public method handling service errors for JavaScript. |
215 |
220 |
216 @param fx service name (string) |
221 @param fx service name (string) |
217 @param lang language (string) |
222 @param lang language (string) |
218 @param fn file name (string) |
223 @param fn file name (string) |
219 @param msg message text (string) |
224 @param msg message text (string) |
220 """ |
225 """ |
221 if fx in ['JavaScriptSyntax', 'batch_JavaScriptSyntax']: |
226 if fx in ["JavaScriptSyntax", "batch_JavaScriptSyntax"]: |
222 if fx == 'JavaScriptSyntax': |
227 if fx == "JavaScriptSyntax": |
223 self.__serviceError(fn, msg) |
228 self.__serviceError(fn, msg) |
224 else: |
229 else: |
225 self.__serviceError(self.tr("JavaScript batch check"), msg) |
230 self.__serviceError(self.tr("JavaScript batch check"), msg) |
226 self.batchJobDone(fx, lang) |
231 self.batchJobDone(fx, lang) |
227 |
232 |
228 def serviceErrorYAML(self, fx, lang, fn, msg): |
233 def serviceErrorYAML(self, fx, lang, fn, msg): |
229 """ |
234 """ |
230 Public method handling service errors for YAML. |
235 Public method handling service errors for YAML. |
231 |
236 |
232 @param fx service name (string) |
237 @param fx service name (string) |
233 @param lang language (string) |
238 @param lang language (string) |
234 @param fn file name (string) |
239 @param fn file name (string) |
235 @param msg message text (string) |
240 @param msg message text (string) |
236 """ |
241 """ |
237 if fx in ['YAMLSyntax', 'batch_YAMLSyntax']: |
242 if fx in ["YAMLSyntax", "batch_YAMLSyntax"]: |
238 if fx == 'YAMLSyntax': |
243 if fx == "YAMLSyntax": |
239 self.__serviceError(fn, msg) |
244 self.__serviceError(fn, msg) |
240 else: |
245 else: |
241 self.__serviceError(self.tr("YAML batch check"), msg) |
246 self.__serviceError(self.tr("YAML batch check"), msg) |
242 self.batchJobDone(fx, lang) |
247 self.batchJobDone(fx, lang) |
243 |
248 |
244 def serviceErrorJSON(self, fx, lang, fn, msg): |
249 def serviceErrorJSON(self, fx, lang, fn, msg): |
245 """ |
250 """ |
246 Public method handling service errors for JSON. |
251 Public method handling service errors for JSON. |
247 |
252 |
248 @param fx service name (string) |
253 @param fx service name (string) |
249 @param lang language (string) |
254 @param lang language (string) |
250 @param fn file name (string) |
255 @param fn file name (string) |
251 @param msg message text (string) |
256 @param msg message text (string) |
252 """ |
257 """ |
253 if fx in ['JSONSyntax', 'batch_JSONSyntax']: |
258 if fx in ["JSONSyntax", "batch_JSONSyntax"]: |
254 if fx == 'JSONSyntax': |
259 if fx == "JSONSyntax": |
255 self.__serviceError(fn, msg) |
260 self.__serviceError(fn, msg) |
256 else: |
261 else: |
257 self.__serviceError(self.tr("JSON batch check"), msg) |
262 self.__serviceError(self.tr("JSON batch check"), msg) |
258 self.batchJobDone(fx, lang) |
263 self.batchJobDone(fx, lang) |
259 |
264 |
260 def serviceErrorTOML(self, fx, lang, fn, msg): |
265 def serviceErrorTOML(self, fx, lang, fn, msg): |
261 """ |
266 """ |
262 Public method handling service errors for TOML. |
267 Public method handling service errors for TOML. |
263 |
268 |
264 @param fx service name (string) |
269 @param fx service name (string) |
265 @param lang language (string) |
270 @param lang language (string) |
266 @param fn file name (string) |
271 @param fn file name (string) |
267 @param msg message text (string) |
272 @param msg message text (string) |
268 """ |
273 """ |
269 if fx in ['TOMLSyntax', 'batch_TOMLSyntax']: |
274 if fx in ["TOMLSyntax", "batch_TOMLSyntax"]: |
270 if fx == 'TOMLSyntax': |
275 if fx == "TOMLSyntax": |
271 self.__serviceError(fn, msg) |
276 self.__serviceError(fn, msg) |
272 else: |
277 else: |
273 self.__serviceError(self.tr("TOML batch check"), msg) |
278 self.__serviceError(self.tr("TOML batch check"), msg) |
274 self.batchJobDone(fx, lang) |
279 self.batchJobDone(fx, lang) |
275 |
280 |
276 def batchJobDone(self, fx, lang): |
281 def batchJobDone(self, fx, lang): |
277 """ |
282 """ |
278 Public slot handling the completion of a batch job. |
283 Public slot handling the completion of a batch job. |
279 |
284 |
280 @param fx service name (string) |
285 @param fx service name (string) |
281 @param lang language (string) |
286 @param lang language (string) |
282 """ |
287 """ |
283 if fx in [ |
288 if fx in [ |
284 'Python3Syntax', 'batch_Python3Syntax', |
289 "Python3Syntax", |
285 'JavaScriptSyntax', 'batch_JavaScriptSyntax', |
290 "batch_Python3Syntax", |
286 'YAMLSyntax', 'batch_YAMLSyntax', |
291 "JavaScriptSyntax", |
287 'JSONSyntax', 'batch_JSONSyntax', |
292 "batch_JavaScriptSyntax", |
288 'TOMLSyntax', 'batch_TOMLSyntax', |
293 "YAMLSyntax", |
|
294 "batch_YAMLSyntax", |
|
295 "JSONSyntax", |
|
296 "batch_JSONSyntax", |
|
297 "TOMLSyntax", |
|
298 "batch_TOMLSyntax", |
289 ]: |
299 ]: |
290 if lang in self.queuedBatches: |
300 if lang in self.queuedBatches: |
291 self.queuedBatches.remove(lang) |
301 self.queuedBatches.remove(lang) |
292 # prevent sending the signal multiple times |
302 # prevent sending the signal multiple times |
293 if len(self.queuedBatches) == 0 and not self.batchesFinished: |
303 if len(self.queuedBatches) == 0 and not self.batchesFinished: |