diff --git a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts index 258b94b473..473d8a4734 100644 --- a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts @@ -212,9 +212,12 @@ export class DecorationAnalyzer { analyzedFile.analyzedClasses.forEach(({declaration, matches}) => { matches.forEach(({handler, analysis}) => { if ((handler.resolve !== undefined) && analysis) { - const res = handler.resolve(declaration, analysis); - if (res.reexports !== undefined) { - this.addReexports(res.reexports, declaration); + const {reexports, diagnostics} = handler.resolve(declaration, analysis); + if (reexports !== undefined) { + this.addReexports(reexports, declaration); + } + if (diagnostics !== undefined) { + diagnostics.forEach(error => this.diagnosticHandler(error)); } } }); diff --git a/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts b/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts index 9f63637619..968e5fdd4e 100644 --- a/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts +++ b/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts @@ -40,7 +40,7 @@ runInEachFileSystem(() => { let result: DecorationAnalyses; // Helpers - const createTestHandler = () => { + const createTestHandler = (options: {analyzeError: boolean, resolveError: boolean}) => { const handler = jasmine.createSpyObj('TestDecoratorHandler', [ 'detect', 'analyze', @@ -74,13 +74,20 @@ runInEachFileSystem(() => { // The "test" analysis is an object with the name of the decorator being analyzed handler.analyze.and.callFake((decl: ts.Declaration, dec: Decorator) => { logs.push(`analyze: ${(decl as any).name.text}@${dec.name}`); - return {analysis: {decoratorName: dec.name}, diagnostics: undefined}; + return { + analysis: {decoratorName: dec.name}, + diagnostics: options.analyzeError ? [makeDiagnostic(9999, decl, 'analyze diagnostic')] : + undefined + }; }); // The "test" resolution is just setting `resolved: true` on the analysis handler.resolve.and.callFake((decl: ts.Declaration, analysis: any) => { logs.push(`resolve: ${(decl as any).name.text}@${analysis.decoratorName}`); analysis.resolved = true; - return {}; + return { + diagnostics: options.resolveError ? [makeDiagnostic(9998, decl, 'resolve diagnostic')] : + undefined + }; }); // The "test" compilation result is just the name of the decorator being compiled // (suffixed with `(compiled)`) @@ -92,7 +99,10 @@ runInEachFileSystem(() => { return handler; }; - function setUpAnalyzer(testFiles: TestFile[]) { + function setUpAnalyzer( + testFiles: TestFile[], + options: {analyzeError: boolean, + resolveError: boolean} = {analyzeError: false, resolveError: false}) { logs = []; loadTestFiles(testFiles); loadFakeCore(getFileSystem()); @@ -107,7 +117,7 @@ runInEachFileSystem(() => { const analyzer = new DecorationAnalyzer( getFileSystem(), bundle, reflectionHost, referencesRegistry, (error) => diagnosticLogs.push(error)); - testHandler = createTestHandler(); + testHandler = createTestHandler(options); analyzer.handlers = [testHandler]; migrationLogs = []; const migration1 = new MockMigration('migration1', migrationLogs); @@ -362,6 +372,26 @@ runInEachFileSystem(() => { expect(diagnosticLogs[0]).toEqual(jasmine.objectContaining({code: -999999})); expect(diagnosticLogs[1]).toEqual(jasmine.objectContaining({code: -996666})); }); + + it('should report analyze and resolve diagnostics to the `diagnosticHandler` callback', + () => { + const analyzer = setUpAnalyzer( + [ + { + name: _('/node_modules/test-package/index.js'), + contents: ` + import {Component, Directive, Injectable} from '@angular/core'; + export class MyComponent {} + MyComponent.decorators = [{type: Component}]; + `, + }, + ], + {analyzeError: true, resolveError: true}); + analyzer.analyzeProgram(); + expect(diagnosticLogs.length).toEqual(2); + expect(diagnosticLogs[0]).toEqual(jasmine.objectContaining({code: -999999})); + expect(diagnosticLogs[1]).toEqual(jasmine.objectContaining({code: -999998})); + }); }); }); });