@@ -34,14 +34,14 @@ export class InitMessage extends TypeCheckerMessage {
3434 public compilerOptions : ts . CompilerOptions ,
3535 public basePath : string ,
3636 public jitMode : boolean ,
37- public tsFilenames : string [ ] ,
37+ public rootNames : string [ ] ,
3838 ) {
3939 super ( MESSAGE_KIND . Init ) ;
4040 }
4141}
4242
4343export class UpdateMessage extends TypeCheckerMessage {
44- constructor ( public changedTsFiles : string [ ] ) {
44+ constructor ( public rootNames : string [ ] , public changedCompilationFiles : string [ ] ) {
4545 super ( MESSAGE_KIND . Update ) ;
4646 }
4747}
@@ -51,90 +51,89 @@ let lastCancellationToken: CancellationToken;
5151
5252process . on ( 'message' , ( message : TypeCheckerMessage ) => {
5353 time ( 'TypeChecker.message' ) ;
54- try {
55- switch ( message . kind ) {
56- case MESSAGE_KIND . Init :
57- const initMessage = message as InitMessage ;
58- typeChecker = new TypeChecker (
59- initMessage . compilerOptions ,
60- initMessage . basePath ,
61- initMessage . jitMode ,
62- initMessage . tsFilenames ,
63- ) ;
64- break ;
65- case MESSAGE_KIND . Update :
66- if ( ! typeChecker ) {
67- throw new Error ( 'TypeChecker: update message received before initialization' ) ;
68- }
69- if ( lastCancellationToken ) {
70- // This cancellation token doesn't seem to do much, messages don't seem to be processed
71- // before the diagnostics finish.
72- lastCancellationToken . requestCancellation ( ) ;
73- }
74- const updateMessage = message as UpdateMessage ;
75- lastCancellationToken = new CancellationToken ( ) ;
76- typeChecker . update ( updateMessage . changedTsFiles , lastCancellationToken ) ;
77- break ;
78- default :
79- throw new Error ( `TypeChecker: Unexpected message received: ${ message } .` ) ;
80- }
81- } catch ( error ) {
82- // Ignore errors in the TypeChecker.
83- // Anything that would throw here will error out the compilation as well.
54+ switch ( message . kind ) {
55+ case MESSAGE_KIND . Init :
56+ const initMessage = message as InitMessage ;
57+ typeChecker = new TypeChecker (
58+ initMessage . compilerOptions ,
59+ initMessage . basePath ,
60+ initMessage . jitMode ,
61+ initMessage . rootNames ,
62+ ) ;
63+ break ;
64+ case MESSAGE_KIND . Update :
65+ if ( ! typeChecker ) {
66+ throw new Error ( 'TypeChecker: update message received before initialization' ) ;
67+ }
68+ if ( lastCancellationToken ) {
69+ // This cancellation token doesn't seem to do much, messages don't seem to be processed
70+ // before the diagnostics finish.
71+ lastCancellationToken . requestCancellation ( ) ;
72+ }
73+ const updateMessage = message as UpdateMessage ;
74+ lastCancellationToken = new CancellationToken ( ) ;
75+ typeChecker . update ( updateMessage . rootNames , updateMessage . changedCompilationFiles ,
76+ lastCancellationToken ) ;
77+ break ;
78+ default :
79+ throw new Error ( `TypeChecker: Unexpected message received: ${ message } .` ) ;
8480 }
8581 timeEnd ( 'TypeChecker.message' ) ;
8682} ) ;
8783
8884
8985class TypeChecker {
9086 private _program : ts . Program | Program ;
91- private _angularCompilerHost : WebpackCompilerHost & CompilerHost ;
87+ private _compilerHost : WebpackCompilerHost & CompilerHost ;
9288
9389 constructor (
94- private _angularCompilerOptions : CompilerOptions ,
90+ private _compilerOptions : CompilerOptions ,
9591 _basePath : string ,
9692 private _JitMode : boolean ,
97- private _tsFilenames : string [ ] ,
93+ private _rootNames : string [ ] ,
9894 ) {
9995 time ( 'TypeChecker.constructor' ) ;
100- const compilerHost = new WebpackCompilerHost ( _angularCompilerOptions , _basePath ) ;
96+ const compilerHost = new WebpackCompilerHost ( _compilerOptions , _basePath ) ;
10197 compilerHost . enableCaching ( ) ;
102- this . _angularCompilerHost = createCompilerHost ( {
103- options : this . _angularCompilerOptions ,
98+ // We don't set a async resource loader on the compiler host because we only support
99+ // html templates, which are the only ones that can throw errors, and those can be loaded
100+ // synchronously.
101+ // If we need to also report errors on styles then we'll need to ask the main thread
102+ // for these resources.
103+ this . _compilerHost = createCompilerHost ( {
104+ options : this . _compilerOptions ,
104105 tsHost : compilerHost
105106 } ) as CompilerHost & WebpackCompilerHost ;
106107 timeEnd ( 'TypeChecker.constructor' ) ;
107108 }
108109
109- private _updateTsFilenames ( changedTsFiles : string [ ] ) {
110- time ( 'TypeChecker._updateTsFilenames' ) ;
111- changedTsFiles . forEach ( ( fileName ) => {
112- this . _angularCompilerHost . invalidate ( fileName ) ;
113- if ( ! this . _tsFilenames . includes ( fileName ) ) {
114- this . _tsFilenames . push ( fileName ) ;
115- }
110+ private _update ( rootNames : string [ ] , changedCompilationFiles : string [ ] ) {
111+ time ( 'TypeChecker._update' ) ;
112+ this . _rootNames = rootNames ;
113+ changedCompilationFiles . forEach ( ( fileName ) => {
114+ this . _compilerHost . invalidate ( fileName ) ;
116115 } ) ;
117- timeEnd ( 'TypeChecker._updateTsFilenames ' ) ;
116+ timeEnd ( 'TypeChecker._update ' ) ;
118117 }
119118
120119 private _createOrUpdateProgram ( ) {
121120 if ( this . _JitMode ) {
122121 // Create the TypeScript program.
123122 time ( 'TypeChecker._createOrUpdateProgram.ts.createProgram' ) ;
124123 this . _program = ts . createProgram (
125- this . _tsFilenames ,
126- this . _angularCompilerOptions ,
127- this . _angularCompilerHost ,
124+ this . _rootNames ,
125+ this . _compilerOptions ,
126+ this . _compilerHost ,
128127 this . _program as ts . Program
129128 ) as ts . Program ;
130129 timeEnd ( 'TypeChecker._createOrUpdateProgram.ts.createProgram' ) ;
131130 } else {
132131 time ( 'TypeChecker._createOrUpdateProgram.ng.createProgram' ) ;
133132 // Create the Angular program.
134133 this . _program = createProgram ( {
135- rootNames : this . _tsFilenames ,
136- options : this . _angularCompilerOptions ,
137- host : this . _angularCompilerHost ,
134+ rootNames : this . _rootNames ,
135+ options : this . _compilerOptions ,
136+ host : this . _compilerHost ,
138137 oldProgram : this . _program as Program
139138 } ) as Program ;
140139 timeEnd ( 'TypeChecker._createOrUpdateProgram.ng.createProgram' ) ;
@@ -153,6 +152,9 @@ class TypeChecker {
153152 if ( errors . length > 0 ) {
154153 const message = formatDiagnostics ( errors ) ;
155154 console . error ( bold ( red ( 'ERROR in ' + message ) ) ) ;
155+ } else {
156+ // Reset the changed file tracker only if there are no errors.
157+ this . _compilerHost . resetChangedFileTracker ( ) ;
156158 }
157159
158160 if ( warnings . length > 0 ) {
@@ -162,8 +164,9 @@ class TypeChecker {
162164 }
163165 }
164166
165- public update ( changedTsFiles : string [ ] , cancellationToken : CancellationToken ) {
166- this . _updateTsFilenames ( changedTsFiles ) ;
167+ public update ( rootNames : string [ ] , changedCompilationFiles : string [ ] ,
168+ cancellationToken : CancellationToken ) {
169+ this . _update ( rootNames , changedCompilationFiles ) ;
167170 this . _createOrUpdateProgram ( ) ;
168171 this . _diagnose ( cancellationToken ) ;
169172 }
0 commit comments