fix(compiler-cli): track poisoned scopes with a flag (#39967) · angular/angular@178cc51

@@ -70,6 +70,8 @@ export interface ComponentAnalysisData {

7070

* require an Angular factory definition at runtime.

7171

*/

7272

viewProvidersRequiringFactory: Set<Reference<ClassDeclaration>>|null;

73+74+

isPoisoned: boolean;

7375

}

74767577

export type ComponentResolutionData = Pick<R3ComponentMetadata, ComponentMetadataResolvedFields>;

@@ -86,7 +88,7 @@ export class ComponentDecoratorHandler implements

8688

private templateMapping: TemplateMapping, private isCore: boolean,

8789

private resourceLoader: ResourceLoader, private rootDirs: ReadonlyArray<string>,

8890

private defaultPreserveWhitespaces: boolean, private i18nUseExternalIds: boolean,

89-

private enableI18nLegacyMessageIdFormat: boolean,

91+

private enableI18nLegacyMessageIdFormat: boolean, private usePoisonedData: boolean,

9092

private i18nNormalizeLineEndingsInICUs: boolean|undefined,

9193

private moduleResolver: ModuleResolver, private cycleAnalyzer: CycleAnalyzer,

9294

private refEmitter: ReferenceEmitter, private defaultImportRecorder: DefaultImportRecorder,

@@ -359,6 +361,7 @@ export class ComponentDecoratorHandler implements

359361

template,

360362

providersRequiringFactory,

361363

viewProvidersRequiringFactory,

364+

isPoisoned: diagnostics !== undefined && diagnostics.length > 0,

362365

},

363366

diagnostics,

364367

};

@@ -383,6 +386,7 @@ export class ComponentDecoratorHandler implements

383386

isComponent: true,

384387

baseClass: analysis.baseClass,

385388

...analysis.typeCheckMeta,

389+

isPoisoned: analysis.isPoisoned,

386390

});

387391388392

if (!analysis.template.isInline) {

@@ -394,15 +398,19 @@ export class ComponentDecoratorHandler implements

394398395399

index(

396400

context: IndexingContext, node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>) {

401+

if (analysis.isPoisoned && !this.usePoisonedData) {

402+

return null;

403+

}

397404

const scope = this.scopeReader.getScopeForComponent(node);

398405

const selector = analysis.meta.selector;

399406

const matcher = new SelectorMatcher<DirectiveMeta>();

400-

if (scope === 'error') {

401-

// Don't bother indexing components which had erroneous scopes.

402-

return null;

403-

}

404-405407

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+406414

for (const directive of scope.compilation.directives) {

407415

if (directive.selector !== null) {

408416

matcher.addSelectables(CssSelector.parse(directive.selector), directive);

@@ -429,9 +437,13 @@ export class ComponentDecoratorHandler implements

429437

return;

430438

}

431439440+

if (meta.isPoisoned && !this.usePoisonedData) {

441+

return;

442+

}

443+432444

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.

435447

return;

436448

}

437449

@@ -443,6 +455,10 @@ export class ComponentDecoratorHandler implements

443455444456

resolve(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>):

445457

ResolveResult<ComponentResolutionData> {

458+

if (analysis.isPoisoned && !this.usePoisonedData) {

459+

return {};

460+

}

461+446462

const context = node.getSourceFile();

447463

// Check whether this component was registered with an NgModule. If so, it should be compiled

448464

// under that module's compilation scope.

@@ -455,7 +471,7 @@ export class ComponentDecoratorHandler implements

455471

wrapDirectivesAndPipesInClosure: false,

456472

};

457473458-

if (scope !== null && scope !== 'error') {

474+

if (scope !== null && (!scope.compilation.isPoisoned || this.usePoisonedData)) {

459475

// Replace the empty components and directives from the analyze() step with a fully expanded

460476

// scope. This is possible now because during resolve() the whole compilation unit has been

461477

// fully analyzed.