11/// <reference path="session.ts" />
2-
2+
33namespace ts . server {
44
55 export interface SessionClientHost extends LanguageServiceHost {
@@ -25,23 +25,23 @@ namespace ts.server {
2525 private lineMaps : ts . Map < number [ ] > = { } ;
2626 private messages : string [ ] = [ ] ;
2727 private lastRenameEntry : RenameEntry ;
28-
28+
2929 constructor ( private host : SessionClientHost ) {
3030 }
3131
32- public onMessage ( message : string ) : void {
32+ public onMessage ( message : string ) : void {
3333 this . messages . push ( message ) ;
3434 }
3535
36- private writeMessage ( message : string ) : void {
36+ private writeMessage ( message : string ) : void {
3737 this . host . writeMessage ( message ) ;
3838 }
3939
40- private getLineMap ( fileName : string ) : number [ ] {
40+ private getLineMap ( fileName : string ) : number [ ] {
4141 var lineMap = ts . lookUp ( this . lineMaps , fileName ) ;
4242 if ( ! lineMap ) {
4343 var scriptSnapshot = this . host . getScriptSnapshot ( fileName ) ;
44- lineMap = this . lineMaps [ fileName ] = ts . computeLineStarts ( scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) ) ;
44+ lineMap = this . lineMaps [ fileName ] = ts . computeLineStarts ( scriptSnapshot . getText ( 0 , scriptSnapshot . getLength ( ) ) ) ;
4545 }
4646 return lineMap ;
4747 }
@@ -82,34 +82,29 @@ namespace ts.server {
8282 }
8383
8484 private processResponse < T extends protocol . Response > ( request : protocol . Request ) : T {
85- var lastMessage = this . messages . shift ( ) ;
86- Debug . assert ( ! ! lastMessage , "Did not receive any responses." ) ;
87-
88- // Read the content length
89- var contentLengthPrefix = "Content-Length: " ;
90- var lines = lastMessage . split ( "\r\n" ) ;
91- Debug . assert ( lines . length >= 2 , "Malformed response: Expected 3 lines in the response." ) ;
92-
93- var contentLengthText = lines [ 0 ] ;
94- Debug . assert ( contentLengthText . indexOf ( contentLengthPrefix ) === 0 , "Malformed response: Response text did not contain content-length header." ) ;
95- var contentLength = parseInt ( contentLengthText . substring ( contentLengthPrefix . length ) ) ;
96-
97- // Read the body
98- var responseBody = lines [ 2 ] ;
99-
100- // Verify content length
101- Debug . assert ( responseBody . length + 1 === contentLength , "Malformed response: Content length did not match the response's body length." ) ;
102-
103- try {
104- var response : T = JSON . parse ( responseBody ) ;
105- }
106- catch ( e ) {
107- throw new Error ( "Malformed response: Failed to parse server response: " + lastMessage + ". \r\n Error details: " + e . message ) ;
85+ let foundResponseMessage = false ;
86+ let lastMessage : string ;
87+ let response : T ;
88+ while ( ! foundResponseMessage ) {
89+ lastMessage = this . messages . shift ( ) ;
90+ Debug . assert ( ! ! lastMessage , "Did not receive any responses." ) ;
91+ const responseBody = processMessage ( lastMessage ) ;
92+ try {
93+ response = JSON . parse ( responseBody ) ;
94+ // the server may emit events before emitting the response. We
95+ // want to ignore these events for testing purpose.
96+ if ( response . type === "response" ) {
97+ foundResponseMessage = true ;
98+ }
99+ }
100+ catch ( e ) {
101+ throw new Error ( "Malformed response: Failed to parse server response: " + lastMessage + ". \r\n Error details: " + e . message ) ;
102+ }
108103 }
109104
110105 // verify the sequence numbers
111106 Debug . assert ( response . request_seq === request . seq , "Malformed response: response sequence number did not match request sequence number." ) ;
112-
107+
113108 // unmarshal errors
114109 if ( ! response . success ) {
115110 throw new Error ( "Error " + response . message ) ;
@@ -118,9 +113,27 @@ namespace ts.server {
118113 Debug . assert ( ! ! response . body , "Malformed response: Unexpected empty response body." ) ;
119114
120115 return response ;
116+
117+ function processMessage ( message : string ) {
118+ // Read the content length
119+ const contentLengthPrefix = "Content-Length: " ;
120+ const lines = message . split ( "\r\n" ) ;
121+ Debug . assert ( lines . length >= 2 , "Malformed response: Expected 3 lines in the response." ) ;
122+
123+ const contentLengthText = lines [ 0 ] ;
124+ Debug . assert ( contentLengthText . indexOf ( contentLengthPrefix ) === 0 , "Malformed response: Response text did not contain content-length header." ) ;
125+ const contentLength = parseInt ( contentLengthText . substring ( contentLengthPrefix . length ) ) ;
126+
127+ // Read the body
128+ const responseBody = lines [ 2 ] ;
129+
130+ // Verify content length
131+ Debug . assert ( responseBody . length + 1 === contentLength , "Malformed response: Content length did not match the response's body length." ) ;
132+ return responseBody ;
133+ }
121134 }
122135
123- openFile ( fileName : string , content ?: string , scriptKindName ?: "TS" | "JS" | "TSX" | "JSX" ) : void {
136+ openFile ( fileName : string , content ?: string , scriptKindName ?: "TS" | "JS" | "TSX" | "JSX" ) : void {
124137 var args : protocol . OpenRequestArgs = { file : fileName , fileContent : content , scriptKindName } ;
125138 this . processRequest ( CommandNames . Open , args ) ;
126139 }
@@ -186,7 +199,7 @@ namespace ts.server {
186199 fileNames : response . body . fileNames
187200 } ;
188201 }
189-
202+
190203 getCompletionsAtPosition ( fileName : string , position : number ) : CompletionInfo {
191204 var lineOffset = this . positionToOneBasedLineOffset ( fileName , position ) ;
192205 var args : protocol . CompletionsRequestArgs = {
@@ -199,13 +212,13 @@ namespace ts.server {
199212 var request = this . processRequest < protocol . CompletionsRequest > ( CommandNames . Completions , args ) ;
200213 var response = this . processResponse < protocol . CompletionsResponse > ( request ) ;
201214
202- return {
215+ return {
203216 isMemberCompletion : false ,
204217 isNewIdentifierLocation : false ,
205218 entries : response . body
206219 } ;
207220 }
208-
221+
209222 getCompletionEntryDetails ( fileName : string , position : number , entryName : string ) : CompletionEntryDetails {
210223 var lineOffset = this . positionToOneBasedLineOffset ( fileName , position ) ;
211224 var args : protocol . CompletionDetailsRequestArgs = {
@@ -234,7 +247,7 @@ namespace ts.server {
234247 var fileName = entry . file ;
235248 var start = this . lineOffsetToPosition ( fileName , entry . start ) ;
236249 var end = this . lineOffsetToPosition ( fileName , entry . end ) ;
237-
250+
238251 return {
239252 name : entry . name ,
240253 containerName : entry . containerName || "" ,
@@ -264,7 +277,7 @@ namespace ts.server {
264277 var request = this . processRequest < protocol . FormatRequest > ( CommandNames . Format , args ) ;
265278 var response = this . processResponse < protocol . FormatResponse > ( request ) ;
266279
267- return response . body . map ( entry => this . convertCodeEditsToTextChange ( fileName , entry ) ) ;
280+ return response . body . map ( entry => this . convertCodeEditsToTextChange ( fileName , entry ) ) ;
268281 }
269282
270283 getFormattingEditsForDocument ( fileName : string , options : ts . FormatCodeOptions ) : ts . TextChange [ ] {
@@ -284,7 +297,7 @@ namespace ts.server {
284297 var request = this . processRequest < protocol . FormatOnKeyRequest > ( CommandNames . Formatonkey , args ) ;
285298 var response = this . processResponse < protocol . FormatResponse > ( request ) ;
286299
287- return response . body . map ( entry => this . convertCodeEditsToTextChange ( fileName , entry ) ) ;
300+ return response . body . map ( entry => this . convertCodeEditsToTextChange ( fileName , entry ) ) ;
288301 }
289302
290303 getDefinitionAtPosition ( fileName : string , position : number ) : DefinitionInfo [ ] {
@@ -339,7 +352,7 @@ namespace ts.server {
339352 } ) ;
340353 }
341354
342- findReferences ( fileName : string , position : number ) : ReferencedSymbol [ ] {
355+ findReferences ( fileName : string , position : number ) : ReferencedSymbol [ ] {
343356 // Not yet implemented.
344357 return [ ] ;
345358 }
@@ -444,7 +457,7 @@ namespace ts.server {
444457 text : item . text ,
445458 kind : item . kind ,
446459 kindModifiers : item . kindModifiers || "" ,
447- spans : item . spans . map ( span => createTextSpanFromBounds ( this . lineOffsetToPosition ( fileName , span . start ) , this . lineOffsetToPosition ( fileName , span . end ) ) ) ,
460+ spans : item . spans . map ( span => createTextSpanFromBounds ( this . lineOffsetToPosition ( fileName , span . start ) , this . lineOffsetToPosition ( fileName , span . end ) ) ) ,
448461 childItems : this . decodeNavigationBarItems ( item . childItems , fileName ) ,
449462 indent : 0 ,
450463 bolded : false ,
@@ -478,10 +491,10 @@ namespace ts.server {
478491 line : lineOffset . line ,
479492 offset : lineOffset . offset
480493 } ;
481-
494+
482495 var request = this . processRequest < protocol . SignatureHelpRequest > ( CommandNames . SignatureHelp , args ) ;
483496 var response = this . processResponse < protocol . SignatureHelpResponse > ( request ) ;
484-
497+
485498 if ( ! response . body ) {
486499 return undefined ;
487500 }
@@ -490,7 +503,7 @@ namespace ts.server {
490503 var span = helpItems . applicableSpan ;
491504 var start = this . lineOffsetToPosition ( fileName , span . start ) ;
492505 var end = this . lineOffsetToPosition ( fileName , span . end ) ;
493-
506+
494507 var result : SignatureHelpItems = {
495508 items : helpItems . items ,
496509 applicableSpan : {
@@ -499,7 +512,7 @@ namespace ts.server {
499512 } ,
500513 selectedItemIndex : helpItems . selectedItemIndex ,
501514 argumentIndex : helpItems . argumentIndex ,
502- argumentCount : helpItems . argumentCount ,
515+ argumentCount : helpItems . argumentCount ,
503516 }
504517 return result ;
505518 }
@@ -561,15 +574,15 @@ namespace ts.server {
561574 }
562575
563576 getTodoComments ( fileName : string , descriptors : TodoCommentDescriptor [ ] ) : TodoComment [ ] {
564- throw new Error ( "Not Implemented Yet." ) ;
577+ throw new Error ( "Not Implemented Yet." ) ;
565578 }
566-
579+
567580 getDocCommentTemplateAtPosition ( fileName : string , position : number ) : TextInsertion {
568- throw new Error ( "Not Implemented Yet." ) ;
581+ throw new Error ( "Not Implemented Yet." ) ;
569582 }
570583
571584 isValidBraceCompletionAtPostion ( fileName : string , position : number , openingBrace : number ) : boolean {
572- throw new Error ( "Not Implemented Yet." ) ;
585+ throw new Error ( "Not Implemented Yet." ) ;
573586 }
574587
575588 getBraceMatchingAtPosition ( fileName : string , position : number ) : TextSpan [ ] {
0 commit comments