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

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9279
e252f827aaa7
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
14 14
15 15
16 def initService(): 16 def initService():
17 """ 17 """
18 Initialize the service and return the entry point. 18 Initialize the service and return the entry point.
19 19
20 @return the entry point for the background client (function) 20 @return the entry point for the background client (function)
21 """ 21 """
22 path = __file__ 22 path = __file__
23 for _ in range(4): 23 for _ in range(4):
24 path = os.path.dirname(path) 24 path = os.path.dirname(path)
27 27
28 28
29 def initBatchService(): 29 def initBatchService():
30 """ 30 """
31 Initialize the batch service and return the entry point. 31 Initialize the batch service and return the entry point.
32 32
33 @return the entry point for the background client (function) 33 @return the entry point for the background client (function)
34 """ 34 """
35 return jsSyntaxBatchCheck 35 return jsSyntaxBatchCheck
36 36
37 37
38 def normalizeCode(codestring): 38 def normalizeCode(codestring):
39 """ 39 """
40 Function to normalize the given code. 40 Function to normalize the given code.
41 41
42 @param codestring code to be normalized (string) 42 @param codestring code to be normalized (string)
43 @return normalized code (string) 43 @return normalized code (string)
44 """ 44 """
45 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n") 45 codestring = codestring.replace("\r\n", "\n").replace("\r", "\n")
46 46
47 if codestring and codestring[-1] != '\n': 47 if codestring and codestring[-1] != "\n":
48 codestring += '\n' 48 codestring += "\n"
49 49
50 return codestring 50 return codestring
51 51
52 52
53 def jsSyntaxCheck(file, codestring): 53 def jsSyntaxCheck(file, codestring):
54 """ 54 """
55 Function to check a Javascript source file for syntax errors. 55 Function to check a Javascript source file for syntax errors.
56 56
57 @param file source filename (string) 57 @param file source filename (string)
58 @param codestring string containing the code to check (string) 58 @param codestring string containing the code to check (string)
59 @return dictionary with the keys 'error' and 'warnings' which 59 @return dictionary with the keys 'error' and 'warnings' which
60 hold a list containing details about the error/ warnings 60 hold a list containing details about the error/ warnings
61 (file name, line number, column, codestring (only at syntax 61 (file name, line number, column, codestring (only at syntax
65 65
66 66
67 def jsSyntaxBatchCheck(argumentsList, send, fx, cancelled, maxProcesses=0): 67 def jsSyntaxBatchCheck(argumentsList, send, fx, cancelled, maxProcesses=0):
68 """ 68 """
69 Module function to check syntax for a batch of files. 69 Module function to check syntax for a batch of files.
70 70
71 @param argumentsList list of arguments tuples as given for jsSyntaxCheck 71 @param argumentsList list of arguments tuples as given for jsSyntaxCheck
72 @type list 72 @type list
73 @param send reference to send function 73 @param send reference to send function
74 @type func 74 @type func
75 @param fx registered service name 75 @param fx registered service name
99 for task in argumentsList[:initialTasks]: 99 for task in argumentsList[:initialTasks]:
100 taskQueue.put(task) 100 taskQueue.put(task)
101 101
102 # Start worker processes 102 # Start worker processes
103 workers = [ 103 workers = [
104 multiprocessing.Process( 104 multiprocessing.Process(target=workerTask, args=(taskQueue, doneQueue))
105 target=workerTask, args=(taskQueue, doneQueue) 105 for _ in range(NumberOfProcesses)
106 ) for _ in range(NumberOfProcesses)
107 ] 106 ]
108 for worker in workers: 107 for worker in workers:
109 worker.start() 108 worker.start()
110 109
111 # Get and send results 110 # Get and send results
112 endIndex = len(argumentsList) - initialTasks 111 endIndex = len(argumentsList) - initialTasks
113 for i in range(len(argumentsList)): 112 for i in range(len(argumentsList)):
114 resultSent = False 113 resultSent = False
115 wasCancelled = False 114 wasCancelled = False
116 115
117 while not resultSent: 116 while not resultSent:
118 try: 117 try:
119 # get result (waiting max. 3 seconds and send it to frontend 118 # get result (waiting max. 3 seconds and send it to frontend
120 filename, result = doneQueue.get() 119 filename, result = doneQueue.get()
121 send(fx, filename, result) 120 send(fx, filename, result)
123 except queue.Empty: 122 except queue.Empty:
124 # ignore empty queue, just carry on 123 # ignore empty queue, just carry on
125 if cancelled(): 124 if cancelled():
126 wasCancelled = True 125 wasCancelled = True
127 break 126 break
128 127
129 if wasCancelled or cancelled(): 128 if wasCancelled or cancelled():
130 # just exit the loop ignoring the results of queued tasks 129 # just exit the loop ignoring the results of queued tasks
131 break 130 break
132 131
133 if i < endIndex: 132 if i < endIndex:
134 taskQueue.put(argumentsList[i + initialTasks]) 133 taskQueue.put(argumentsList[i + initialTasks])
135 134
136 # Tell child processes to stop 135 # Tell child processes to stop
137 for _ in range(NumberOfProcesses): 136 for _ in range(NumberOfProcesses):
138 taskQueue.put('STOP') 137 taskQueue.put("STOP")
139 138
140 for worker in workers: 139 for worker in workers:
141 worker.join() 140 worker.join()
142 worker.close() 141 worker.close()
143 142
144 143
145 def workerTask(inputQueue, outputQueue): 144 def workerTask(inputQueue, outputQueue):
146 """ 145 """
147 Module function acting as the parallel worker for the syntax check. 146 Module function acting as the parallel worker for the syntax check.
148 147
149 @param inputQueue input queue (multiprocessing.Queue) 148 @param inputQueue input queue (multiprocessing.Queue)
150 @param outputQueue output queue (multiprocessing.Queue) 149 @param outputQueue output queue (multiprocessing.Queue)
151 """ 150 """
152 for filename, args in iter(inputQueue.get, 'STOP'): 151 for filename, args in iter(inputQueue.get, "STOP"):
153 source = args[0] 152 source = args[0]
154 result = __jsSyntaxCheck(filename, source) 153 result = __jsSyntaxCheck(filename, source)
155 outputQueue.put((filename, result)) 154 outputQueue.put((filename, result))
156 155
157 156
158 def __jsSyntaxCheck(file, codestring): 157 def __jsSyntaxCheck(file, codestring):
159 """ 158 """
160 Function to check a Javascript source file for syntax errors. 159 Function to check a Javascript source file for syntax errors.
161 160
162 @param file source filename (string) 161 @param file source filename (string)
163 @param codestring string containing the code to check (string) 162 @param codestring string containing the code to check (string)
164 @return dictionary with the keys 'error' and 'warnings' which 163 @return dictionary with the keys 'error' and 'warnings' which
165 hold a list containing details about the error/ warnings 164 hold a list containing details about the error/ warnings
166 (file name, line number, column, codestring (only at syntax 165 (file name, line number, column, codestring (only at syntax
167 errors), the message, a list with arguments for the message) 166 errors), the message, a list with arguments for the message)
168 """ 167 """
169 import jasy.script.parse.Parser as jsParser 168 import jasy.script.parse.Parser as jsParser
170 import jasy.script.tokenize.Tokenizer as jsTokenizer 169 import jasy.script.tokenize.Tokenizer as jsTokenizer
171 170
172 codestring = normalizeCode(codestring) 171 codestring = normalizeCode(codestring)
173 172
174 try: 173 try:
175 jsParser.parse(codestring, file) 174 jsParser.parse(codestring, file)
176 except (jsParser.SyntaxError, jsTokenizer.ParseError) as exc: 175 except (jsParser.SyntaxError, jsTokenizer.ParseError) as exc:
177 details = exc.args[0] 176 details = exc.args[0]
178 error, details = details.splitlines() 177 error, details = details.splitlines()
179 fn, line = details.strip().rsplit(":", 1) 178 fn, line = details.strip().rsplit(":", 1)
180 error = error.split(":", 1)[1].strip() 179 error = error.split(":", 1)[1].strip()
181 180
182 cline = min(len(codestring.splitlines()), int(line)) - 1 181 cline = min(len(codestring.splitlines()), int(line)) - 1
183 code = codestring.splitlines()[cline] 182 code = codestring.splitlines()[cline]
184 return [{'error': (fn, int(line), 0, code, error)}] 183 return [{"error": (fn, int(line), 0, code, error)}]
185 except IndexError: 184 except IndexError:
186 error = "Incomplete source file" 185 error = "Incomplete source file"
187 splittedCode = codestring.splitlines() 186 splittedCode = codestring.splitlines()
188 return [{'error': (file, len(splittedCode) + 1, len(splittedCode[-1]), 187 return [
189 splittedCode[-1], error)}] 188 {
190 189 "error": (
190 file,
191 len(splittedCode) + 1,
192 len(splittedCode[-1]),
193 splittedCode[-1],
194 error,
195 )
196 }
197 ]
198
191 return [{}] 199 return [{}]

eric ide

mercurial