fix(compiler-cli): do not error with prepocessing if component has no inline styles (#41602)

The asynchronous preprocessing check was not accounting for components that did not have any inline styles. In that case, the cache did not have an entry which then allowed the asynchronous check to run and fail the compilation. The caching during the asynchronous analysis phase now handles components without inline styles.

PR Close #41602
This commit is contained in:
Charles Lyding 2021-04-13 13:46:49 -04:00 committed by Zach Arend
parent a63cf7221b
commit 1b43158af6
2 changed files with 70 additions and 0 deletions

View File

@ -302,6 +302,8 @@ export class ComponentDecoratorHandler implements
this.preanalyzeStylesCache.set(node, styles);
});
}
} else {
this.preanalyzeStylesCache.set(node, null);
}
// Wait for both the template and all styleUrl resources to resolve.

View File

@ -302,6 +302,74 @@ runInEachFileSystem(() => {
const {analysis} = handler.analyze(TestCmp, detected.metadata);
expect(analysis?.inlineStyles).toEqual(jasmine.arrayWithExactContents(['.xyz {}']));
});
it('should error if canPreprocess is true and async analyze is not used', async () => {
const {program, options, host} = makeProgram([
{
name: _('/node_modules/@angular/core/index.d.ts'),
contents: 'export const Component: any;',
},
{
name: _('/entry.ts'),
contents: `
import {Component} from '@angular/core';
@Component({
template: '',
styles: ['.abc {}']
}) class TestCmp {}
`
},
]);
const {reflectionHost, handler, resourceLoader} = setup(program, options, host);
resourceLoader.canPreload = true;
resourceLoader.canPreprocess = true;
const TestCmp = getDeclaration(program, _('/entry.ts'), 'TestCmp', isNamedClassDeclaration);
const detected = handler.detect(TestCmp, reflectionHost.getDecoratorsOfDeclaration(TestCmp));
if (detected === undefined) {
return fail('Failed to recognize @Component');
}
expect(() => handler.analyze(TestCmp, detected.metadata))
.toThrowError('Inline resource processing requires asynchronous preanalyze.');
});
it('should not error if component has no inline styles and canPreprocess is true', async () => {
const {program, options, host} = makeProgram([
{
name: _('/node_modules/@angular/core/index.d.ts'),
contents: 'export const Component: any;',
},
{
name: _('/entry.ts'),
contents: `
import {Component} from '@angular/core';
@Component({
template: '',
}) class TestCmp {}
`
},
]);
const {reflectionHost, handler, resourceLoader} = setup(program, options, host);
resourceLoader.canPreload = true;
resourceLoader.canPreprocess = true;
resourceLoader.preprocessInline = async function(data, context) {
fail('preprocessInline should not have been called.');
return data;
};
const TestCmp = getDeclaration(program, _('/entry.ts'), 'TestCmp', isNamedClassDeclaration);
const detected = handler.detect(TestCmp, reflectionHost.getDecoratorsOfDeclaration(TestCmp));
if (detected === undefined) {
return fail('Failed to recognize @Component');
}
await handler.preanalyze(TestCmp, detected.metadata);
expect(() => handler.analyze(TestCmp, detected.metadata)).not.toThrow();
});
});
function ivyCode(code: ErrorCode): number {