src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckService.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
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
81 (function) 79 (function)
82 """ 80 """
83 self.__supportedLanguages[lang] = env, getArgs, getExt 81 self.__supportedLanguages[lang] = env, getArgs, getExt
84 # Connect to the background service 82 # Connect to the background service
85 self.backgroundService.serviceConnect( 83 self.backgroundService.serviceConnect(
86 '{0}Syntax'.format(lang), env, path, module, callback, onError, 84 "{0}Syntax".format(lang),
87 onBatchDone=self.batchJobDone) 85 env,
86 path,
87 module,
88 callback,
89 onError,
90 onBatchDone=self.batchJobDone,
91 )
88 92
89 def getLanguages(self): 93 def getLanguages(self):
90 """ 94 """
91 Public method to return the supported language names. 95 Public method to return the supported language names.
92 96
93 @return list of languanges supported (list of str) 97 @return list of languanges supported (list of str)
94 """ 98 """
95 return list(self.__supportedLanguages.keys()) + ["MicroPython"] 99 return list(self.__supportedLanguages.keys()) + ["MicroPython"]
96 100
97 def removeLanguage(self, lang): 101 def removeLanguage(self, lang):
98 """ 102 """
99 Public method to remove the language from syntax check. 103 Public method to remove the language from syntax check.
100 104
101 @param lang language to remove (str) 105 @param lang language to remove (str)
102 """ 106 """
103 self.__supportedLanguages.pop(lang, None) 107 self.__supportedLanguages.pop(lang, None)
104 self.backgroundService.serviceDisconnect( 108 self.backgroundService.serviceDisconnect("{0}Syntax".format(lang), lang)
105 '{0}Syntax'.format(lang), lang)
106 109
107 def getExtensions(self): 110 def getExtensions(self):
108 """ 111 """
109 Public method to return all supported file extensions for the 112 Public method to return all supported file extensions for the
110 syntax checker dialog. 113 syntax checker dialog.
111 114
112 @return set of all supported file extensions (set of str) 115 @return set of all supported file extensions (set of str)
113 """ 116 """
114 extensions = set() 117 extensions = set()
115 for _env, _getArgs, getExt in self.__supportedLanguages.values(): 118 for _env, _getArgs, getExt in self.__supportedLanguages.values():
116 for ext in getExt(): 119 for ext in getExt():
118 return extensions 121 return extensions
119 122
120 def syntaxCheck(self, lang, filename, source): 123 def syntaxCheck(self, lang, filename, source):
121 """ 124 """
122 Public method to prepare a syntax check of one source file. 125 Public method to prepare a syntax check of one source file.
123 126
124 @param lang language of the file or None to determine by internal 127 @param lang language of the file or None to determine by internal
125 algorithm (str or None) 128 algorithm (str or None)
126 @param filename source filename (string) 129 @param filename source filename (string)
127 @param source string containing the code to check (string) 130 @param source string containing the code to check (string)
128 """ 131 """
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:

eric ide

mercurial