@@ -15,20 +15,19 @@ import {FileSystem, LogicalFileSystem, absoluteFrom, dirname, resolve} from '../
15
15
import { AbsoluteModuleStrategy , LocalIdentifierStrategy , LogicalProjectStrategy , ModuleResolver , NOOP_DEFAULT_IMPORT_RECORDER , PrivateExportAliasingHost , Reexport , ReferenceEmitter } from '../../../src/ngtsc/imports' ;
16
16
import { CompoundMetadataReader , CompoundMetadataRegistry , DtsMetadataReader , InjectableClassRegistry , LocalMetadataRegistry } from '../../../src/ngtsc/metadata' ;
17
17
import { PartialEvaluator } from '../../../src/ngtsc/partial_evaluator' ;
18
- import { ClassDeclaration } from '../../../src/ngtsc/reflection' ;
19
18
import { LocalModuleScopeRegistry , MetadataDtsModuleScopeResolver } from '../../../src/ngtsc/scope' ;
20
- import { CompileResult , DecoratorHandler } from '../../../src/ngtsc/transform' ;
21
- import { NgccClassSymbol , NgccReflectionHost } from '../host/ngcc_host' ;
19
+ import { DecoratorHandler } from '../../../src/ngtsc/transform' ;
20
+ import { NgccReflectionHost } from '../host/ngcc_host' ;
22
21
import { Migration } from '../migrations/migration' ;
23
22
import { MissingInjectableMigration } from '../migrations/missing_injectable_migration' ;
24
23
import { UndecoratedChildMigration } from '../migrations/undecorated_child_migration' ;
25
24
import { UndecoratedParentMigration } from '../migrations/undecorated_parent_migration' ;
26
25
import { EntryPointBundle } from '../packages/entry_point_bundle' ;
27
- import { isDefined } from '../utils' ;
28
26
29
27
import { DefaultMigrationHost } from './migration_host' ;
30
- import { AnalyzedClass , AnalyzedFile , CompiledClass , CompiledFile , DecorationAnalyses } from './types' ;
31
- import { NOOP_DEPENDENCY_TRACKER , analyzeDecorators , isWithinPackage } from './util' ;
28
+ import { NgccTraitCompiler } from './ngcc_trait_compiler' ;
29
+ import { CompiledClass , CompiledFile , DecorationAnalyses } from './types' ;
30
+ import { NOOP_DEPENDENCY_TRACKER , isWithinPackage } from './util' ;
32
31
33
32
34
33
@@ -57,10 +56,6 @@ export class DecorationAnalyzer {
57
56
private packagePath = this . bundle . entryPoint . package ;
58
57
private isCore = this . bundle . isCore ;
59
58
60
- /**
61
- * Map of NgModule declarations to the re-exports for that NgModule.
62
- */
63
- private reexportMap = new Map < ts . Declaration , Map < string , [ string , string ] > > ( ) ;
64
59
moduleResolver =
65
60
new ModuleResolver ( this . program , this . options , this . host , /* moduleResolutionCache */ null ) ;
66
61
resourceManager = new NgccResourceLoader ( this . fs ) ;
@@ -118,6 +113,7 @@ export class DecorationAnalyzer {
118
113
/* factoryTracker */ null , NOOP_DEFAULT_IMPORT_RECORDER ,
119
114
/* annotateForClosureCompiler */ false , this . injectableRegistry ) ,
120
115
] ;
116
+ compiler = new NgccTraitCompiler ( this . handlers , this . reflectionHost ) ;
121
117
migrations : Migration [ ] = [
122
118
new UndecoratedParentMigration ( ) ,
123
119
new UndecoratedChildMigration ( ) ,
@@ -135,56 +131,54 @@ export class DecorationAnalyzer {
135
131
* @returns a map of the source files to the analysis for those files.
136
132
*/
137
133
analyzeProgram ( ) : DecorationAnalyses {
138
- const decorationAnalyses = new DecorationAnalyses ( ) ;
139
- const analyzedFiles = this . program . getSourceFiles ( )
140
- . filter ( sourceFile => ! sourceFile . isDeclarationFile )
141
- . filter ( sourceFile => isWithinPackage ( this . packagePath , sourceFile ) )
142
- . map ( sourceFile => this . analyzeFile ( sourceFile ) )
143
- . filter ( isDefined ) ;
134
+ for ( const sourceFile of this . program . getSourceFiles ( ) ) {
135
+ if ( ! sourceFile . isDeclarationFile && isWithinPackage ( this . packagePath , sourceFile ) ) {
136
+ this . compiler . analyzeFile ( sourceFile ) ;
137
+ }
138
+ }
144
139
145
- this . applyMigrations ( analyzedFiles ) ;
140
+ this . applyMigrations ( ) ;
146
141
147
- analyzedFiles . forEach ( analyzedFile => this . resolveFile ( analyzedFile ) ) ;
148
- const compiledFiles = analyzedFiles . map ( analyzedFile => this . compileFile ( analyzedFile ) ) ;
149
- compiledFiles . forEach (
150
- compiledFile => decorationAnalyses . set ( compiledFile . sourceFile , compiledFile ) ) ;
151
- return decorationAnalyses ;
152
- }
142
+ this . compiler . resolve ( ) ;
153
143
154
- protected analyzeFile ( sourceFile : ts . SourceFile ) : AnalyzedFile | undefined {
155
- const analyzedClasses = this . reflectionHost . findClassSymbols ( sourceFile )
156
- . map ( symbol => this . analyzeClass ( symbol ) )
157
- . filter ( isDefined ) ;
158
- return analyzedClasses . length ? { sourceFile, analyzedClasses} : undefined ;
159
- }
144
+ this . reportDiagnostics ( ) ;
160
145
161
- protected analyzeClass ( symbol : NgccClassSymbol ) : AnalyzedClass | null {
162
- const decorators = this . reflectionHost . getDecoratorsOfSymbol ( symbol ) ;
163
- const analyzedClass = analyzeDecorators ( symbol , decorators , this . handlers ) ;
164
- if ( analyzedClass !== null && analyzedClass . diagnostics !== undefined ) {
165
- for ( const diagnostic of analyzedClass . diagnostics ) {
166
- this . diagnosticHandler ( diagnostic ) ;
167
- }
146
+ const decorationAnalyses = new DecorationAnalyses ( ) ;
147
+ for ( const analyzedFile of this . compiler . analyzedFiles ) {
148
+ const compiledFile = this . compileFile ( analyzedFile ) ;
149
+ decorationAnalyses . set ( compiledFile . sourceFile , compiledFile ) ;
168
150
}
169
- return analyzedClass ;
151
+ return decorationAnalyses ;
170
152
}
171
153
172
- protected applyMigrations ( analyzedFiles : AnalyzedFile [ ] ) : void {
154
+ protected applyMigrations ( ) : void {
173
155
const migrationHost = new DefaultMigrationHost (
174
- this . reflectionHost , this . fullMetaReader , this . evaluator , this . handlers ,
175
- this . bundle . entryPoint . path , analyzedFiles , this . diagnosticHandler ) ;
156
+ this . reflectionHost , this . fullMetaReader , this . evaluator , this . compiler ,
157
+ this . bundle . entryPoint . path ) ;
176
158
177
159
this . migrations . forEach ( migration => {
178
- analyzedFiles . forEach ( analyzedFile => {
179
- analyzedFile . analyzedClasses . forEach ( ( { declaration} ) => {
160
+ this . compiler . analyzedFiles . forEach ( analyzedFile => {
161
+ const records = this . compiler . recordsFor ( analyzedFile ) ;
162
+ if ( records === null ) {
163
+ throw new Error ( 'Assertion error: file to migrate must have records.' ) ;
164
+ }
165
+
166
+ records . forEach ( record => {
167
+ const addDiagnostic = ( diagnostic : ts . Diagnostic ) => {
168
+ if ( record . metaDiagnostics === null ) {
169
+ record . metaDiagnostics = [ ] ;
170
+ }
171
+ record . metaDiagnostics . push ( diagnostic ) ;
172
+ } ;
173
+
180
174
try {
181
- const result = migration . apply ( declaration , migrationHost ) ;
175
+ const result = migration . apply ( record . node , migrationHost ) ;
182
176
if ( result !== null ) {
183
- this . diagnosticHandler ( result ) ;
177
+ addDiagnostic ( result ) ;
184
178
}
185
179
} catch ( e ) {
186
180
if ( isFatalDiagnosticError ( e ) ) {
187
- this . diagnosticHandler ( e . toDiagnostic ( ) ) ;
181
+ addDiagnostic ( e . toDiagnostic ( ) ) ;
188
182
} else {
189
183
throw e ;
190
184
}
@@ -194,67 +188,45 @@ export class DecorationAnalyzer {
194
188
} ) ;
195
189
}
196
190
197
- protected compileFile ( analyzedFile : AnalyzedFile ) : CompiledFile {
198
- const constantPool = new ConstantPool ( ) ;
199
- const compiledClasses : CompiledClass [ ] = analyzedFile . analyzedClasses . map ( analyzedClass => {
200
- const compilation = this . compileClass ( analyzedClass , constantPool ) ;
201
- const declaration = analyzedClass . declaration ;
202
- const reexports : Reexport [ ] = this . getReexportsForClass ( declaration ) ;
203
- return { ...analyzedClass , compilation, reexports} ;
204
- } ) ;
205
- return { constantPool, sourceFile : analyzedFile . sourceFile , compiledClasses} ;
206
- }
191
+ protected reportDiagnostics ( ) { this . compiler . diagnostics . forEach ( this . diagnosticHandler ) ; }
207
192
208
- protected compileClass ( clazz : AnalyzedClass , constantPool : ConstantPool ) : CompileResult [ ] {
209
- const compilations : CompileResult [ ] = [ ] ;
210
- for ( const { handler, analysis, resolution} of clazz . matches ) {
211
- const result = handler . compile ( clazz . declaration , analysis , resolution , constantPool ) ;
212
- if ( Array . isArray ( result ) ) {
213
- result . forEach ( current => {
214
- if ( ! compilations . some ( compilation => compilation . name === current . name ) ) {
215
- compilations . push ( current ) ;
216
- }
217
- } ) ;
218
- } else if ( ! compilations . some ( compilation => compilation . name === result . name ) ) {
219
- compilations . push ( result ) ;
220
- }
193
+ protected compileFile ( sourceFile : ts . SourceFile ) : CompiledFile {
194
+ const constantPool = new ConstantPool ( ) ;
195
+ const records = this . compiler . recordsFor ( sourceFile ) ;
196
+ if ( records === null ) {
197
+ throw new Error ( 'Assertion error: file to compile must have records.' ) ;
221
198
}
222
- return compilations ;
223
- }
224
199
225
- protected resolveFile ( analyzedFile : AnalyzedFile ) : void {
226
- for ( const { declaration, matches} of analyzedFile . analyzedClasses ) {
227
- for ( const match of matches ) {
228
- const { handler, analysis} = match ;
229
- if ( ( handler . resolve !== undefined ) && analysis ) {
230
- const { reexports, diagnostics, data} = handler . resolve ( declaration , analysis ) ;
231
- if ( reexports !== undefined ) {
232
- this . addReexports ( reexports , declaration ) ;
233
- }
234
- if ( diagnostics !== undefined ) {
235
- diagnostics . forEach ( error => this . diagnosticHandler ( error ) ) ;
236
- }
237
- match . resolution = data as Readonly < unknown > ;
238
- }
200
+ const compiledClasses : CompiledClass [ ] = [ ] ;
201
+
202
+ for ( const record of records ) {
203
+ const compilation = this . compiler . compile ( record . node , constantPool ) ;
204
+ if ( compilation === null ) {
205
+ continue ;
239
206
}
240
- }
241
- }
242
207
243
- private getReexportsForClass ( declaration : ClassDeclaration < ts . Declaration > ) {
244
- const reexports : Reexport [ ] = [ ] ;
245
- if ( this . reexportMap . has ( declaration ) ) {
246
- this . reexportMap . get ( declaration ) ! . forEach ( ( [ fromModule , symbolName ] , asAlias ) => {
247
- reexports . push ( { asAlias, fromModule, symbolName} ) ;
208
+ compiledClasses . push ( {
209
+ name : record . node . name . text ,
210
+ decorators : this . compiler . getAllDecorators ( record . node ) ,
211
+ declaration : record . node , compilation
248
212
} ) ;
249
213
}
250
- return reexports ;
214
+
215
+ const reexports = this . getReexportsForSourceFile ( sourceFile ) ;
216
+ return { constantPool, sourceFile : sourceFile , compiledClasses, reexports} ;
251
217
}
252
218
253
- private addReexports ( reexports : Reexport [ ] , declaration : ClassDeclaration < ts . Declaration > ) {
254
- const map = new Map < string , [ string , string ] > ( ) ;
255
- for ( const reexport of reexports ) {
256
- map . set ( reexport . asAlias , [ reexport . fromModule , reexport . symbolName ] ) ;
219
+ private getReexportsForSourceFile ( sf : ts . SourceFile ) : Reexport [ ] {
220
+ const exportStatements = this . compiler . exportStatements ;
221
+ if ( ! exportStatements . has ( sf . fileName ) ) {
222
+ return [ ] ;
257
223
}
258
- this . reexportMap . set ( declaration , map ) ;
224
+ const exports = exportStatements . get ( sf . fileName ) ! ;
225
+
226
+ const reexports : Reexport [ ] = [ ] ;
227
+ exports . forEach ( ( [ fromModule , symbolName ] , asAlias ) => {
228
+ reexports . push ( { asAlias, fromModule, symbolName} ) ;
229
+ } ) ;
230
+ return reexports ;
259
231
}
260
232
}
0 commit comments