@@ -34,14 +34,14 @@ export class InitMessage extends TypeCheckerMessage {
34
34
public compilerOptions : ts . CompilerOptions ,
35
35
public basePath : string ,
36
36
public jitMode : boolean ,
37
- public tsFilenames : string [ ] ,
37
+ public rootNames : string [ ] ,
38
38
) {
39
39
super ( MESSAGE_KIND . Init ) ;
40
40
}
41
41
}
42
42
43
43
export class UpdateMessage extends TypeCheckerMessage {
44
- constructor ( public changedTsFiles : string [ ] ) {
44
+ constructor ( public rootNames : string [ ] , public changedCompilationFiles : string [ ] ) {
45
45
super ( MESSAGE_KIND . Update ) ;
46
46
}
47
47
}
@@ -51,90 +51,89 @@ let lastCancellationToken: CancellationToken;
51
51
52
52
process . on ( 'message' , ( message : TypeCheckerMessage ) => {
53
53
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 } .` ) ;
84
80
}
85
81
timeEnd ( 'TypeChecker.message' ) ;
86
82
} ) ;
87
83
88
84
89
85
class TypeChecker {
90
86
private _program : ts . Program | Program ;
91
- private _angularCompilerHost : WebpackCompilerHost & CompilerHost ;
87
+ private _compilerHost : WebpackCompilerHost & CompilerHost ;
92
88
93
89
constructor (
94
- private _angularCompilerOptions : CompilerOptions ,
90
+ private _compilerOptions : CompilerOptions ,
95
91
_basePath : string ,
96
92
private _JitMode : boolean ,
97
- private _tsFilenames : string [ ] ,
93
+ private _rootNames : string [ ] ,
98
94
) {
99
95
time ( 'TypeChecker.constructor' ) ;
100
- const compilerHost = new WebpackCompilerHost ( _angularCompilerOptions , _basePath ) ;
96
+ const compilerHost = new WebpackCompilerHost ( _compilerOptions , _basePath ) ;
101
97
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 ,
104
105
tsHost : compilerHost
105
106
} ) as CompilerHost & WebpackCompilerHost ;
106
107
timeEnd ( 'TypeChecker.constructor' ) ;
107
108
}
108
109
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 ) ;
116
115
} ) ;
117
- timeEnd ( 'TypeChecker._updateTsFilenames ' ) ;
116
+ timeEnd ( 'TypeChecker._update ' ) ;
118
117
}
119
118
120
119
private _createOrUpdateProgram ( ) {
121
120
if ( this . _JitMode ) {
122
121
// Create the TypeScript program.
123
122
time ( 'TypeChecker._createOrUpdateProgram.ts.createProgram' ) ;
124
123
this . _program = ts . createProgram (
125
- this . _tsFilenames ,
126
- this . _angularCompilerOptions ,
127
- this . _angularCompilerHost ,
124
+ this . _rootNames ,
125
+ this . _compilerOptions ,
126
+ this . _compilerHost ,
128
127
this . _program as ts . Program
129
128
) as ts . Program ;
130
129
timeEnd ( 'TypeChecker._createOrUpdateProgram.ts.createProgram' ) ;
131
130
} else {
132
131
time ( 'TypeChecker._createOrUpdateProgram.ng.createProgram' ) ;
133
132
// Create the Angular program.
134
133
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 ,
138
137
oldProgram : this . _program as Program
139
138
} ) as Program ;
140
139
timeEnd ( 'TypeChecker._createOrUpdateProgram.ng.createProgram' ) ;
@@ -153,6 +152,9 @@ class TypeChecker {
153
152
if ( errors . length > 0 ) {
154
153
const message = formatDiagnostics ( errors ) ;
155
154
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 ( ) ;
156
158
}
157
159
158
160
if ( warnings . length > 0 ) {
@@ -162,8 +164,9 @@ class TypeChecker {
162
164
}
163
165
}
164
166
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 ) ;
167
170
this . _createOrUpdateProgram ( ) ;
168
171
this . _diagnose ( cancellationToken ) ;
169
172
}
0 commit comments