| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import * as ts from 'typescript/lib/tsserverlibrary'; | 
					
						
							| 
									
										
										
										
											2021-02-02 14:20:40 -08:00
										 |  |  | import {LanguageService} from '../../language_service'; | 
					
						
							| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {extractCursorInfo} from './util'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * A file that is currently open in the `ts.Project`, with a cursor position. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export class OpenBuffer { | 
					
						
							|  |  |  |   private _cursor: number = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor( | 
					
						
							| 
									
										
										
										
											2021-02-02 14:20:40 -08:00
										 |  |  |       private ngLS: LanguageService, private projectFileName: string, | 
					
						
							| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  |       private scriptInfo: ts.server.ScriptInfo) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get cursor(): number { | 
					
						
							|  |  |  |     return this._cursor; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get contents(): string { | 
					
						
							|  |  |  |     const snapshot = this.scriptInfo.getSnapshot(); | 
					
						
							|  |  |  |     return snapshot.getText(0, snapshot.getLength()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   set contents(newContents: string) { | 
					
						
							|  |  |  |     const snapshot = this.scriptInfo.getSnapshot(); | 
					
						
							|  |  |  |     this.scriptInfo.editContent(0, snapshot.getLength(), newContents); | 
					
						
							|  |  |  |     // If the cursor goes beyond the new length of the buffer, clamp it to the end of the buffer.
 | 
					
						
							|  |  |  |     if (this._cursor > newContents.length) { | 
					
						
							|  |  |  |       this._cursor = newContents.length; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Find a snippet of text within the given buffer and position the cursor within it. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * @param snippetWithCursor a snippet of text which contains the '¦' symbol, representing where | 
					
						
							|  |  |  |    *     the cursor should be placed within the snippet when located in the larger buffer. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   moveCursorToText(snippetWithCursor: string): void { | 
					
						
							|  |  |  |     const {text: snippet, cursor} = extractCursorInfo(snippetWithCursor); | 
					
						
							|  |  |  |     const snippetIndex = this.contents.indexOf(snippet); | 
					
						
							|  |  |  |     if (snippetIndex === -1) { | 
					
						
							| 
									
										
										
										
											2021-02-02 14:20:40 -08:00
										 |  |  |       throw new Error(`Snippet '${snippet}' not found in ${this.projectFileName}`); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (this.contents.indexOf(snippet, snippetIndex + 1) !== -1) { | 
					
						
							|  |  |  |       throw new Error(`Snippet '${snippet}' is not unique within ${this.projectFileName}`); | 
					
						
							| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  |     } | 
					
						
							|  |  |  |     this._cursor = snippetIndex + cursor; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Execute the `getDefinitionAndBoundSpan` operation in the Language Service at the cursor | 
					
						
							|  |  |  |    * location in this buffer. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan|undefined { | 
					
						
							| 
									
										
										
										
											2021-02-02 14:20:40 -08:00
										 |  |  |     return this.ngLS.getDefinitionAndBoundSpan(this.scriptInfo.fileName, this._cursor); | 
					
						
							| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-04 17:45:51 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getCompletionsAtPosition(options?: ts.GetCompletionsAtPositionOptions): | 
					
						
							|  |  |  |       ts.WithMetadata<ts.CompletionInfo>|undefined { | 
					
						
							|  |  |  |     return this.ngLS.getCompletionsAtPosition(this.scriptInfo.fileName, this._cursor, options); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getCompletionEntryDetails( | 
					
						
							|  |  |  |       entryName: string, formatOptions?: ts.FormatCodeOptions|ts.FormatCodeSettings, | 
					
						
							|  |  |  |       preferences?: ts.UserPreferences): ts.CompletionEntryDetails|undefined { | 
					
						
							|  |  |  |     return this.ngLS.getCompletionEntryDetails( | 
					
						
							|  |  |  |         this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-08 10:11:39 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getTcb() { | 
					
						
							|  |  |  |     return this.ngLS.getTcb(this.scriptInfo.fileName, this._cursor); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-02 14:11:52 -08:00
										 |  |  | } |