| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0aa35ec commit 178cc51
21 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -97,6 +97,7 @@ export class DecorationAnalyzer { | |||
| 97 | 97 | this.scopeRegistry, this.scopeRegistry, new TemplateMapping(), this.isCore, | |
| 98 | 98 | this.resourceManager, this.rootDirs, !!this.compilerOptions.preserveWhitespaces, | |
| 99 | 99 | /* i18nUseExternalIds */ true, this.bundle.enableI18nLegacyMessageIdFormat, | |
| 100 | + /* usePoisonedData */ false, | ||
| 100 | 101 | /* i18nNormalizeLineEndingsInICUs */ false, this.moduleResolver, this.cycleAnalyzer, | |
| 101 | 102 | this.refEmitter, NOOP_DEFAULT_IMPORT_RECORDER, NOOP_DEPENDENCY_TRACKER, | |
| 102 | 103 | this.injectableRegistry, !!this.compilerOptions.annotateForClosureCompiler), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,6 +70,8 @@ export interface ComponentAnalysisData { | |||
| 70 | 70 | * require an Angular factory definition at runtime. | |
| 71 | 71 | */ | |
| 72 | 72 | viewProvidersRequiringFactory: Set<Reference<ClassDeclaration>>|null; | |
| 73 | + | ||
| 74 | + isPoisoned: boolean; | ||
| 73 | 75 | } | |
| 74 | 76 | ||
| 75 | 77 | export type ComponentResolutionData = Pick<R3ComponentMetadata, ComponentMetadataResolvedFields>; | |
@@ -86,7 +88,7 @@ export class ComponentDecoratorHandler implements | |||
| 86 | 88 | private templateMapping: TemplateMapping, private isCore: boolean, | |
| 87 | 89 | private resourceLoader: ResourceLoader, private rootDirs: ReadonlyArray<string>, | |
| 88 | 90 | private defaultPreserveWhitespaces: boolean, private i18nUseExternalIds: boolean, | |
| 89 | - private enableI18nLegacyMessageIdFormat: boolean, | ||
| 91 | + private enableI18nLegacyMessageIdFormat: boolean, private usePoisonedData: boolean, | ||
| 90 | 92 | private i18nNormalizeLineEndingsInICUs: boolean|undefined, | |
| 91 | 93 | private moduleResolver: ModuleResolver, private cycleAnalyzer: CycleAnalyzer, | |
| 92 | 94 | private refEmitter: ReferenceEmitter, private defaultImportRecorder: DefaultImportRecorder, | |
@@ -359,6 +361,7 @@ export class ComponentDecoratorHandler implements | |||
| 359 | 361 | template, | |
| 360 | 362 | providersRequiringFactory, | |
| 361 | 363 | viewProvidersRequiringFactory, | |
| 364 | + isPoisoned: diagnostics !== undefined && diagnostics.length > 0, | ||
| 362 | 365 | }, | |
| 363 | 366 | diagnostics, | |
| 364 | 367 | }; | |
@@ -383,6 +386,7 @@ export class ComponentDecoratorHandler implements | |||
| 383 | 386 | isComponent: true, | |
| 384 | 387 | baseClass: analysis.baseClass, | |
| 385 | 388 | ...analysis.typeCheckMeta, | |
| 389 | + isPoisoned: analysis.isPoisoned, | ||
| 386 | 390 | }); | |
| 387 | 391 | ||
| 388 | 392 | if (!analysis.template.isInline) { | |
@@ -394,15 +398,19 @@ export class ComponentDecoratorHandler implements | |||
| 394 | 398 | ||
| 395 | 399 | index( | |
| 396 | 400 | context: IndexingContext, node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>) { | |
| 401 | + if (analysis.isPoisoned && !this.usePoisonedData) { | ||
| 402 | + return null; | ||
| 403 | + } | ||
| 397 | 404 | const scope = this.scopeReader.getScopeForComponent(node); | |
| 398 | 405 | const selector = analysis.meta.selector; | |
| 399 | 406 | const matcher = new SelectorMatcher<DirectiveMeta>(); | |
| 400 | - if (scope === 'error') { | ||
| 401 | - // Don't bother indexing components which had erroneous scopes. | ||
| 402 | - return null; | ||
| 403 | - } | ||
| 404 | - | ||
| 405 | 407 | if (scope !== null) { | |
| 408 | + if ((scope.compilation.isPoisoned || scope.exported.isPoisoned) && !this.usePoisonedData) { | ||
| 409 | + // Don't bother indexing components which had erroneous scopes, unless specifically | ||
| 410 | + // requested. | ||
| 411 | + return null; | ||
| 412 | + } | ||
| 413 | + | ||
| 406 | 414 | for (const directive of scope.compilation.directives) { | |
| 407 | 415 | if (directive.selector !== null) { | |
| 408 | 416 | matcher.addSelectables(CssSelector.parse(directive.selector), directive); | |
@@ -429,9 +437,13 @@ export class ComponentDecoratorHandler implements | |||
| 429 | 437 | return; | |
| 430 | 438 | } | |
| 431 | 439 | ||
| 440 | + if (meta.isPoisoned && !this.usePoisonedData) { | ||
| 441 | + return; | ||
| 442 | + } | ||
| 443 | + | ||
| 432 | 444 | const scope = this.typeCheckScopes.getTypeCheckScope(node); | |
| 433 | - if (scope === 'error') { | ||
| 434 | - // Don't type-check components that had errors in their scopes. | ||
| 445 | + if (scope.isPoisoned && !this.usePoisonedData) { | ||
| 446 | + // Don't type-check components that had errors in their scopes, unless requested. | ||
| 435 | 447 | return; | |
| 436 | 448 | } | |
| 437 | 449 | ||
@@ -443,6 +455,10 @@ export class ComponentDecoratorHandler implements | |||
| 443 | 455 | ||
| 444 | 456 | resolve(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>): | |
| 445 | 457 | ResolveResult<ComponentResolutionData> { | |
| 458 | + if (analysis.isPoisoned && !this.usePoisonedData) { | ||
| 459 | + return {}; | ||
| 460 | + } | ||
| 461 | + | ||
| 446 | 462 | const context = node.getSourceFile(); | |
| 447 | 463 | // Check whether this component was registered with an NgModule. If so, it should be compiled | |
| 448 | 464 | // under that module's compilation scope. | |
@@ -455,7 +471,7 @@ export class ComponentDecoratorHandler implements | |||
| 455 | 471 | wrapDirectivesAndPipesInClosure: false, | |
| 456 | 472 | }; | |
| 457 | 473 | ||
| 458 | - if (scope !== null && scope !== 'error') { | ||
| 474 | + if (scope !== null && (!scope.compilation.isPoisoned || this.usePoisonedData)) { | ||
| 459 | 475 | // Replace the empty components and directives from the analyze() step with a fully expanded | |
| 460 | 476 | // scope. This is possible now because during resolve() the whole compilation unit has been | |
| 461 | 477 | // fully analyzed. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -41,6 +41,7 @@ export interface DirectiveHandlerData { | |||
| 41 | 41 | providersRequiringFactory: Set<Reference<ClassDeclaration>>|null; | |
| 42 | 42 | inputs: ClassPropertyMapping; | |
| 43 | 43 | outputs: ClassPropertyMapping; | |
| 44 | + isPoisoned: boolean; | ||
| 44 | 45 | } | |
| 45 | 46 | ||
| 46 | 47 | export class DirectiveDecoratorHandler implements | |
@@ -106,7 +107,8 @@ export class DirectiveDecoratorHandler implements | |||
| 106 | 107 | this.annotateForClosureCompiler), | |
| 107 | 108 | baseClass: readBaseClass(node, this.reflector, this.evaluator), | |
| 108 | 109 | typeCheckMeta: extractDirectiveTypeCheckMeta(node, directiveResult.inputs, this.reflector), | |
| 109 | - providersRequiringFactory | ||
| 110 | + providersRequiringFactory, | ||
| 111 | + isPoisoned: false, | ||
| 110 | 112 | } | |
| 111 | 113 | }; | |
| 112 | 114 | } | |
@@ -126,6 +128,7 @@ export class DirectiveDecoratorHandler implements | |||
| 126 | 128 | isComponent: false, | |
| 127 | 129 | baseClass: analysis.baseClass, | |
| 128 | 130 | ...analysis.typeCheckMeta, | |
| 131 | + isPoisoned: analysis.isPoisoned, | ||
| 129 | 132 | }); | |
| 130 | 133 | ||
| 131 | 134 | this.injectableRegistry.registerInjectable(node); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -336,7 +336,7 @@ export class NgModuleDecoratorHandler implements | |||
| 336 | 336 | injectorImports: [], | |
| 337 | 337 | }; | |
| 338 | 338 | ||
| 339 | - if (scope !== null && scope !== 'error') { | ||
| 339 | + if (scope !== null && !scope.compilation.isPoisoned) { | ||
| 340 | 340 | // Using the scope information, extend the injector's imports using the modules that are | |
| 341 | 341 | // specified as module exports. | |
| 342 | 342 | const context = getSourceFile(node); | |
@@ -361,7 +361,8 @@ export class NgModuleDecoratorHandler implements | |||
| 361 | 361 | return {diagnostics}; | |
| 362 | 362 | } | |
| 363 | 363 | ||
| 364 | - if (scope === null || scope === 'error' || scope.reexports === null) { | ||
| 364 | + if (scope === null || scope.compilation.isPoisoned || scope.exported.isPoisoned || | ||
| 365 | + scope.reexports === null) { | ||
| 365 | 366 | return {data}; | |
| 366 | 367 | } else { | |
| 367 | 368 | return { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,6 +33,12 @@ export interface TypeCheckScope { | |||
| 33 | 33 | * The schemas that are used in this scope. | |
| 34 | 34 | */ | |
| 35 | 35 | schemas: SchemaMetadata[]; | |
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Whether the original compilation scope which produced this `TypeCheckScope` was itself poisoned | ||
| 39 | + * (contained semantic errors during its production). | ||
| 40 | + */ | ||
| 41 | + isPoisoned: boolean; | ||
| 36 | 42 | } | |
| 37 | 43 | ||
| 38 | 44 | /** | |
@@ -57,15 +63,18 @@ export class TypeCheckScopes { | |||
| 57 | 63 | * contains an error, then 'error' is returned. If the component is not declared in any NgModule, | |
| 58 | 64 | * an empty type-check scope is returned. | |
| 59 | 65 | */ | |
| 60 | - getTypeCheckScope(node: ClassDeclaration): TypeCheckScope|'error' { | ||
| 66 | + getTypeCheckScope(node: ClassDeclaration): TypeCheckScope { | ||
| 61 | 67 | const matcher = new SelectorMatcher<DirectiveMeta>(); | |
| 62 | 68 | const pipes = new Map<string, Reference<ClassDeclaration<ts.ClassDeclaration>>>(); | |
| 63 | 69 | ||
| 64 | 70 | const scope = this.scopeReader.getScopeForComponent(node); | |
| 65 | 71 | if (scope === null) { | |
| 66 | - return {matcher, pipes, schemas: []}; | ||
| 67 | - } else if (scope === 'error') { | ||
| 68 | - return scope; | ||
| 72 | + return { | ||
| 73 | + matcher, | ||
| 74 | + pipes, | ||
| 75 | + schemas: [], | ||
| 76 | + isPoisoned: false, | ||
| 77 | + }; | ||
| 69 | 78 | } | |
| 70 | 79 | ||
| 71 | 80 | if (this.scopeCache.has(scope.ngModule)) { | |
@@ -87,7 +96,12 @@ export class TypeCheckScopes { | |||
| 87 | 96 | pipes.set(name, ref as Reference<ClassDeclaration<ts.ClassDeclaration>>); | |
| 88 | 97 | } | |
| 89 | 98 | ||
| 90 | - const typeCheckScope: TypeCheckScope = {matcher, pipes, schemas: scope.schemas}; | ||
| 99 | + const typeCheckScope: TypeCheckScope = { | ||
| 100 | + matcher, | ||
| 101 | + pipes, | ||
| 102 | + schemas: scope.schemas, | ||
| 103 | + isPoisoned: scope.compilation.isPoisoned || scope.exported.isPoisoned, | ||
| 104 | + }; | ||
| 91 | 105 | this.scopeCache.set(scope.ngModule, typeCheckScope); | |
| 92 | 106 | return typeCheckScope; | |
| 93 | 107 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -73,6 +73,7 @@ runInEachFileSystem(() => { | |||
| 73 | 73 | /* isCore */ false, new NoopResourceLoader(), /* rootDirs */[''], | |
| 74 | 74 | /* defaultPreserveWhitespaces */ false, /* i18nUseExternalIds */ true, | |
| 75 | 75 | /* enableI18nLegacyMessageIdFormat */ false, | |
| 76 | + /* usePoisonedData */ false, | ||
| 76 | 77 | /* i18nNormalizeLineEndingsInICUs */ undefined, moduleResolver, cycleAnalyzer, refEmitter, | |
| 77 | 78 | NOOP_DEFAULT_IMPORT_RECORDER, /* depTracker */ null, injectableRegistry, | |
| 78 | 79 | /* annotateForClosureCompiler */ false); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -106,6 +106,7 @@ export class NgCompiler { | |||
| 106 | 106 | private typeCheckingProgramStrategy: TypeCheckingProgramStrategy, | |
| 107 | 107 | private incrementalStrategy: IncrementalBuildStrategy, | |
| 108 | 108 | private enableTemplateTypeChecker: boolean, | |
| 109 | + private usePoisonedData: boolean, | ||
| 109 | 110 | oldProgram: ts.Program|null = null, | |
| 110 | 111 | private perfRecorder: PerfRecorder = NOOP_PERF_RECORDER, | |
| 111 | 112 | ) { | |
@@ -742,7 +743,7 @@ export class NgCompiler { | |||
| 742 | 743 | reflector, evaluator, metaRegistry, metaReader, scopeReader, scopeRegistry, | |
| 743 | 744 | templateMapping, isCore, this.resourceManager, this.adapter.rootDirs, | |
| 744 | 745 | this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false, | |
| 745 | - this.options.enableI18nLegacyMessageIdFormat !== false, | ||
| 746 | + this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, | ||
| 746 | 747 | this.options.i18nNormalizeLineEndingsInICUs, this.moduleResolver, this.cycleAnalyzer, | |
| 747 | 748 | refEmitter, defaultImportTracker, this.incrementalDriver.depGraph, injectableRegistry, | |
| 748 | 749 | this.closureCompilerEnabled), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -51,7 +51,8 @@ runInEachFileSystem(() => { | |||
| 51 | 51 | const program = ts.createProgram({host, options, rootNames: host.inputFiles}); | |
| 52 | 52 | const compiler = new NgCompiler( | |
| 53 | 53 | host, options, program, new ReusedProgramStrategy(program, host, options, []), | |
| 54 | - new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false); | ||
| 54 | + new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false, | ||
| 55 | + /* usePoisonedData */ false); | ||
| 55 | 56 | ||
| 56 | 57 | const diags = compiler.getDiagnostics(getSourceFileOrError(program, COMPONENT)); | |
| 57 | 58 | expect(diags.length).toBe(1); | |
@@ -100,7 +101,8 @@ runInEachFileSystem(() => { | |||
| 100 | 101 | const CmpC = getClass(getSourceFileOrError(program, cmpCFile), 'CmpC'); | |
| 101 | 102 | const compiler = new NgCompiler( | |
| 102 | 103 | host, options, program, new ReusedProgramStrategy(program, host, options, []), | |
| 103 | - new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false); | ||
| 104 | + new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false, | ||
| 105 | + /* usePoisonedData */ false); | ||
| 104 | 106 | const components = compiler.getComponentsWithTemplateFile(templateFile); | |
| 105 | 107 | expect(components).toEqual(new Set([CmpA, CmpC])); | |
| 106 | 108 | }); | |
@@ -129,7 +131,8 @@ runInEachFileSystem(() => { | |||
| 129 | 131 | const program = ts.createProgram({host, options, rootNames: host.inputFiles}); | |
| 130 | 132 | const compiler = new NgCompiler( | |
| 131 | 133 | host, options, program, new ReusedProgramStrategy(program, host, options, []), | |
| 132 | - new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false); | ||
| 134 | + new NoopIncrementalBuildStrategy(), /** enableTemplateTypeChecker */ false, | ||
| 135 | + /* usePoisonedData */ false); | ||
| 133 | 136 | ||
| 134 | 137 | const deps = compiler.getResourceDependencies(getSourceFileOrError(program, COMPONENT)); | |
| 135 | 138 | expect(deps.length).toBe(2); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,6 +108,12 @@ export interface DirectiveMeta extends T2DirectiveMeta, DirectiveTypeCheckMeta { | |||
| 108 | 108 | * another type, it could not statically determine the base class. | |
| 109 | 109 | */ | |
| 110 | 110 | baseClass: Reference<ClassDeclaration>|'dynamic'|null; | |
| 111 | + | ||
| 112 | + /** | ||
| 113 | + * Whether the directive had some issue with its declaration that means it might not have complete | ||
| 114 | + * and reliable metadata. | ||
| 115 | + */ | ||
| 116 | + isPoisoned: boolean; | ||
| 111 | 117 | } | |
| 112 | 118 | ||
| 113 | 119 | /** | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -92,6 +92,7 @@ export class DtsMetadataReader implements MetadataReader { | |||
| 92 | 92 | queries: readStringArrayType(def.type.typeArguments[5]), | |
| 93 | 93 | ...extractDirectiveTypeCheckMeta(clazz, inputs, this.reflector), | |
| 94 | 94 | baseClass: readBaseClass(clazz, this.checker, this.reflector), | |
| 95 | + isPoisoned: false, | ||
| 95 | 96 | }; | |
| 96 | 97 | } | |
| 97 | 98 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments