@@ -41,7 +41,8 @@ var config = {};
4141 Tern = tern ;
4242 Infer = infer ;
4343
44- var ternServer = null ;
44+ var ternServer = null ,
45+ inferenceTimeout ;
4546
4647 // Save the tern callbacks for when we get the contents of the file
4748 var fileCallBacks = { } ;
@@ -63,6 +64,28 @@ var config = {};
6364 } ) ;
6465 }
6566
67+ /**
68+ * Send a log message back from the worker to the main thread
69+ * @private
70+ * @param {string } msg - the log message
71+ */
72+ function _log ( msg ) {
73+ self . postMessage ( { log : msg } ) ;
74+ }
75+
76+ /**
77+ * Report exception
78+ * @private
79+ * @param {Error } e - the error object
80+ */
81+ function _reportError ( e , file ) {
82+ if ( e instanceof Infer . TimedOut ) {
83+ _log ( "Timeout during Tern processing of " + file ) ;
84+ } else {
85+ _log ( "Error thrown in tern_worker:" + e . message + "\n" + e . stack ) ;
86+ }
87+ }
88+
6689 /**
6790 * Handle a response from the main thread providing the contents of a file
6891 * @param {string } file - the name of the file
@@ -71,7 +94,11 @@ var config = {};
7194 function handleGetFile ( file , text ) {
7295 var next = fileCallBacks [ file ] ;
7396 if ( next ) {
74- next ( null , text ) ;
97+ try {
98+ next ( null , text ) ;
99+ } catch ( e ) {
100+ _reportError ( e , file ) ;
101+ }
75102 }
76103 delete fileCallBacks [ file ] ;
77104 }
@@ -154,23 +181,14 @@ var config = {};
154181 query . expandWordForward = false ;
155182 query . lineCharPositions = true ;
156183
157- var request = { query : query , files : [ ] , offset : offset } ;
184+ var request = { query : query , files : [ ] , offset : offset , timeout : inferenceTimeout } ;
158185 if ( fileInfo . type !== MessageIds . TERN_FILE_INFO_TYPE_EMPTY ) {
159186 request . files . push ( fileInfo ) ;
160187 }
161188
162189 return request ;
163190 }
164191
165- /**
166- * Send a log message back from the worker to the main thread
167- *
168- * @param {string } msg - the log message
169- */
170- function _log ( msg ) {
171- self . postMessage ( { log : msg } ) ;
172- }
173-
174192 /**
175193 * Get definition location
176194 * @param {{type: string, name: string, offsetLines: number, text: string} } fileInfo
@@ -184,35 +202,40 @@ var config = {};
184202 function getJumptoDef ( fileInfo , offset ) {
185203 var request = buildRequest ( fileInfo , "definition" , offset ) ;
186204 // request.query.typeOnly = true; // FIXME: tern doesn't work exactly right yet.
187- ternServer . request ( request , function ( error , data ) {
188- if ( error ) {
189- _log ( "Error returned from Tern 'definition' request: " + error ) ;
190- self . postMessage ( { type : MessageIds . TERN_JUMPTODEF_MSG , file : fileInfo . name , offset : offset } ) ;
191- return ;
192- }
193- var isFunc = false ,
194- response = { type : MessageIds . TERN_JUMPTODEF_MSG ,
195- file : fileInfo . name ,
196- resultFile : data . file ,
197- offset : offset ,
198- start : data . start ,
199- end : data . end
200- } ;
201-
202- request = buildRequest ( fileInfo , "type" , offset ) ;
203- // See if we can tell if the reference is to a Function type
205+
206+ try {
204207 ternServer . request ( request , function ( error , data ) {
205- if ( ! error ) {
206- response . isFunction = data . type . length > 2 && data . type . substring ( 0 , 2 ) === "fn" ;
208+ if ( error ) {
209+ _log ( "Error returned from Tern 'definition' request: " + error ) ;
210+ self . postMessage ( { type : MessageIds . TERN_JUMPTODEF_MSG , file : fileInfo . name , offset : offset } ) ;
211+ return ;
207212 }
208-
209- // Post a message back to the main thread with the definition
210- self . postMessage ( response ) ;
211- } ) ;
213+ var isFunc = false ,
214+ response = { type : MessageIds . TERN_JUMPTODEF_MSG ,
215+ file : fileInfo . name ,
216+ resultFile : data . file ,
217+ offset : offset ,
218+ start : data . start ,
219+ end : data . end
220+ } ;
221+
222+ request = buildRequest ( fileInfo , "type" , offset ) ;
223+ // See if we can tell if the reference is to a Function type
224+ ternServer . request ( request , function ( error , data ) {
225+ if ( ! error ) {
226+ response . isFunction = data . type . length > 2 && data . type . substring ( 0 , 2 ) === "fn" ;
227+ }
212228
213- } ) ;
229+ // Post a message back to the main thread with the definition
230+ self . postMessage ( response ) ;
231+ } ) ;
232+
233+ } ) ;
234+ } catch ( e ) {
235+ _reportError ( e , fileInfo . name ) ;
236+ }
214237 }
215-
238+
216239 /**
217240 * Get all the known properties for guessing.
218241 *
@@ -230,25 +253,29 @@ var config = {};
230253 var request = buildRequest ( fileInfo , "properties" , offset ) ,
231254 i ;
232255 //_log("tern properties: request " + request.type + dir + " " + file);
233- ternServer . request ( request , function ( error , data ) {
234- var properties = [ ] ;
235- if ( error ) {
236- _log ( "Error returned from Tern 'properties' request: " + error ) ;
237- } else {
238- //_log("tern properties: completions = " + data.completions.length);
239- for ( i = 0 ; i < data . completions . length ; ++ i ) {
240- var property = data . completions [ i ] ;
241- properties . push ( { value : property , type : property . type , guess : true } ) ;
256+ try {
257+ ternServer . request ( request , function ( error , data ) {
258+ var properties = [ ] ;
259+ if ( error ) {
260+ _log ( "Error returned from Tern 'properties' request: " + error ) ;
261+ } else {
262+ //_log("tern properties: completions = " + data.completions.length);
263+ for ( i = 0 ; i < data . completions . length ; ++ i ) {
264+ var property = data . completions [ i ] ;
265+ properties . push ( { value : property , type : property . type , guess : true } ) ;
266+ }
242267 }
243- }
244-
245- // Post a message back to the main thread with the completions
246- self . postMessage ( { type : type ,
247- file : fileInfo . name ,
248- offset : offset ,
249- properties : properties
250- } ) ;
251- } ) ;
268+
269+ // Post a message back to the main thread with the completions
270+ self . postMessage ( { type : type ,
271+ file : fileInfo . name ,
272+ offset : offset ,
273+ properties : properties
274+ } ) ;
275+ } ) ;
276+ } catch ( e ) {
277+ _reportError ( e , fileInfo . name ) ;
278+ }
252279 }
253280
254281 /**
@@ -270,31 +297,35 @@ var config = {};
270297 i ;
271298
272299 //_log("request " + dir + " " + file + " " + offset /*+ " " + text */);
273- ternServer . request ( request , function ( error , data ) {
274- var completions = [ ] ;
275- if ( error ) {
276- _log ( "Error returned from Tern 'completions' request: " + error ) ;
277- } else {
278- //_log("found " + data.completions.length + " for " + file + "@" + offset);
279- for ( i = 0 ; i < data . completions . length ; ++ i ) {
280- var completion = data . completions [ i ] ;
281- completions . push ( { value : completion . name , type : completion . type , depth : completion . depth ,
282- guess : completion . guess , origin : completion . origin } ) ;
300+ try {
301+ ternServer . request ( request , function ( error , data ) {
302+ var completions = [ ] ;
303+ if ( error ) {
304+ _log ( "Error returned from Tern 'completions' request: " + error ) ;
305+ } else {
306+ //_log("found " + data.completions.length + " for " + file + "@" + offset);
307+ for ( i = 0 ; i < data . completions . length ; ++ i ) {
308+ var completion = data . completions [ i ] ;
309+ completions . push ( { value : completion . name , type : completion . type , depth : completion . depth ,
310+ guess : completion . guess , origin : completion . origin } ) ;
311+ }
283312 }
284- }
285-
286- if ( completions . length > 0 || ! isProperty ) {
287- // Post a message back to the main thread with the completions
288- self . postMessage ( { type : MessageIds . TERN_COMPLETIONS_MSG ,
289- file : fileInfo . name ,
290- offset : offset ,
291- completions : completions
292- } ) ;
293- } else {
294- // if there are no completions, then get all the properties
295- getTernProperties ( fileInfo , offset , MessageIds . TERN_COMPLETIONS_MSG ) ;
296- }
297- } ) ;
313+
314+ if ( completions . length > 0 || ! isProperty ) {
315+ // Post a message back to the main thread with the completions
316+ self . postMessage ( { type : MessageIds . TERN_COMPLETIONS_MSG ,
317+ file : fileInfo . name ,
318+ offset : offset ,
319+ completions : completions
320+ } ) ;
321+ } else {
322+ // if there are no completions, then get all the properties
323+ getTernProperties ( fileInfo , offset , MessageIds . TERN_COMPLETIONS_MSG ) ;
324+ }
325+ } ) ;
326+ } catch ( e ) {
327+ _reportError ( e , fileInfo . name ) ;
328+ }
298329 }
299330
300331 /**
@@ -512,8 +543,7 @@ var config = {};
512543 }
513544 } ) ;
514545 } catch ( e ) {
515- error = e . message ;
516- _log ( "Error thrown in tern_worker:" + error + "\n" + e . stack ) ;
546+ _reportError ( e , fileInfo . name ) ;
517547 }
518548
519549 // Post a message back to the main thread with the completions
@@ -561,15 +591,19 @@ var config = {};
561591 * @param {string } path - the path of the file
562592 */
563593 function handlePrimePump ( path ) {
564- var fileInfo = createEmptyUpdate ( path ) ;
565- var request = buildRequest ( fileInfo , "completions" , { line : 0 , ch : 0 } ) ;
566-
567- ternServer . request ( request , function ( error , data ) {
568- // Post a message back to the main thread
569- self . postMessage ( { type : MessageIds . TERN_PRIME_PUMP_MSG ,
570- path : path
571- } ) ;
572- } ) ;
594+ var fileInfo = createEmptyUpdate ( path ) ,
595+ request = buildRequest ( fileInfo , "completions" , { line : 0 , ch : 0 } ) ;
596+
597+ try {
598+ ternServer . request ( request , function ( error , data ) {
599+ // Post a message back to the main thread
600+ self . postMessage ( { type : MessageIds . TERN_PRIME_PUMP_MSG ,
601+ path : path
602+ } ) ;
603+ } ) ;
604+ } catch ( e ) {
605+ _reportError ( e , path ) ;
606+ }
573607 }
574608
575609 /**
@@ -594,6 +628,8 @@ var config = {};
594628
595629 var env = request . env ,
596630 files = request . files ;
631+ inferenceTimeout = request . timeout ;
632+
597633 initTernServer ( env , files ) ;
598634 } else if ( type === MessageIds . TERN_COMPLETIONS_MSG ) {
599635 offset = request . offset ;
0 commit comments