11import * as fs from 'fs' ;
22import * as ts from 'typescript' ;
3+ import * as url from 'url' ;
34
45import { LanguageService } from '@angular/language-service' ;
56
@@ -100,27 +101,22 @@ class ProjectLoggerImpl implements ProjectLogger {
100101 }
101102}
102103
103- function removePrefix ( value : string , ...prefixes : string [ ] ) : string {
104- for ( const prefix of prefixes ) {
105- if ( value && value . startsWith ( prefix ) ) {
106- return value . substr ( prefix . length ) ;
107- }
104+ function uriToFileName ( uri : string ) : string {
105+ const parsedUrl = url . parse ( uri ) ;
106+ switch ( parsedUrl . protocol ) {
107+ case 'file:' :
108+ case 'private:' :
109+ return parsedUrl . path
108110 }
109- return value ;
110111}
111112
112- const privateProtocol = "private:" ;
113113const fileProtocol = "file://" ;
114- function uriToFileName ( uri : string ) : string {
115- return removePrefix ( decodeURI ( uri ) , fileProtocol , privateProtocol ) ;
116- }
117-
118114function fileNameToUri ( fileName : string ) : string {
119115 return encodeURI ( fileProtocol + fileName ) ;
120116}
121117
122118export interface NgServiceInfo {
123- fileName : string ;
119+ fileName ? : string ;
124120 languageId ?: string ;
125121 service ?: LanguageService ;
126122 offset ?: number ;
@@ -155,17 +151,21 @@ export class TextDocuments {
155151 connection . onDidOpenTextDocument ( event => {
156152 // An interersting text document was opened in the client. Inform TypeScirpt's project services about it.
157153 const file = uriToFileName ( event . textDocument . uri ) ;
158- const { configFileName, configFileErrors } = this . projectService . openClientFile ( file , event . textDocument . text ) ;
159- if ( configFileErrors && configFileErrors . length ) {
160- // TODO: Report errors
161- this . logger . msg ( `Config errors encountered and need to be reported: ${ configFileErrors . length } \n ${ configFileErrors . map ( error => error . messageText ) . join ( '\n ' ) } ` ) ;
154+ if ( file ) {
155+ const { configFileName, configFileErrors } = this . projectService . openClientFile ( file , event . textDocument . text ) ;
156+ if ( configFileErrors && configFileErrors . length ) {
157+ // TODO: Report errors
158+ this . logger . msg ( `Config errors encountered and need to be reported: ${ configFileErrors . length } \n ${ configFileErrors . map ( error => error . messageText ) . join ( '\n ' ) } ` ) ;
159+ }
160+ this . languageIds . set ( event . textDocument . uri , event . textDocument . languageId ) ;
162161 }
163- this . languageIds . set ( event . textDocument . uri , event . textDocument . languageId ) ;
164162 } ) ;
165163
166164 connection . onDidCloseTextDocument ( event => {
167165 const file = uriToFileName ( event . textDocument . uri ) ;
168- this . projectService . closeClientFile ( file ) ;
166+ if ( file ) {
167+ this . projectService . closeClientFile ( file ) ;
168+ }
169169 } ) ;
170170
171171 connection . onDidChangeTextDocument ( event => {
@@ -195,16 +195,21 @@ export class TextDocuments {
195195 // If the file is saved, force the content to be reloaded from disk as the content might have changed on save.
196196 this . changeNumber ++ ;
197197 const file = uriToFileName ( event . textDocument . uri ) ;
198- const savedContent = this . host . readFile ( file ) ;
199- this . projectService . closeClientFile ( file ) ;
200- this . projectService . openClientFile ( file , savedContent ) ;
201- this . changeNumber ++ ;
198+ if ( file ) {
199+ const savedContent = this . host . readFile ( file ) ;
200+ this . projectService . closeClientFile ( file ) ;
201+ this . projectService . openClientFile ( file , savedContent ) ;
202+ this . changeNumber ++ ;
203+ }
202204 } ) ;
203205 }
204206
205207 public offsetsToPositions ( document : TextDocumentIdentifier , offsets : number [ ] ) : Position [ ] {
206208 const file = uriToFileName ( document . uri ) ;
207- return this . projectService . positionsToLineOffsets ( file , offsets ) . map ( lineOffset => Position . create ( lineOffset . line - 1 , lineOffset . col - 1 ) ) ;
209+ if ( file ) {
210+ return this . projectService . positionsToLineOffsets ( file , offsets ) . map ( lineOffset => Position . create ( lineOffset . line - 1 , lineOffset . col - 1 ) ) ;
211+ }
212+ return [ ] ;
208213 }
209214
210215 public getNgService ( document : TextDocumentIdentifier ) : LanguageService | undefined {
@@ -213,18 +218,20 @@ export class TextDocuments {
213218
214219 public getServiceInfo ( document : TextDocumentIdentifier , position ?: Position ) : NgServiceInfo {
215220 const fileName = uriToFileName ( document . uri ) ;
216- const project = this . projectService . getProjectForFile ( fileName ) ;
217- const languageId = this . languageIds . get ( document . uri ) ;
218- if ( project ) {
219- const service = project . compilerService . ngService ;
220- if ( position ) {
221- // VSCode is 0 based, editor services are 1 based.
222- const offset = this . projectService . lineOffsetsToPositions ( fileName , [ { line : position . line + 1 , col : position . character + 1 } ] ) [ 0 ] ;
223- return { fileName, service, offset, languageId} ;
221+ if ( fileName ) {
222+ const project = this . projectService . getProjectForFile ( fileName ) ;
223+ const languageId = this . languageIds . get ( document . uri ) ;
224+ if ( project ) {
225+ const service = project . compilerService . ngService ;
226+ if ( position ) {
227+ // VSCode is 0 based, editor services are 1 based.
228+ const offset = this . projectService . lineOffsetsToPositions ( fileName , [ { line : position . line + 1 , col : position . character + 1 } ] ) [ 0 ] ;
229+ return { fileName, service, offset, languageId} ;
230+ }
231+ return { fileName, service, languageId} ;
224232 }
225- return { fileName, service , languageId} ;
233+ return { fileName, languageId} ;
226234 }
227- return { fileName, languageId} ;
228235 }
229236
230237 public ifUnchanged ( f : ( ) => void ) : ( ) => void {
0 commit comments