feat(ivy): enable processing of esm5 format in ngcc ()

PR Close 
This commit is contained in:
George Kalpakas 2018-07-25 13:06:32 +03:00 committed by Matias Niemelä
parent 9e179cb311
commit 9081efa961
3 changed files with 64 additions and 33 deletions
packages/compiler-cli
src
ngcc/src/transform
ngtsc/annotations/src
test/ngcc

@ -81,6 +81,7 @@ export class PackageTransformer {
case 'esm2015':
case 'fesm2015':
return new Esm2015ReflectionHost(program.getTypeChecker());
case 'esm5':
case 'fesm5':
return new Esm5ReflectionHost(program.getTypeChecker());
default:
@ -93,6 +94,7 @@ export class PackageTransformer {
case 'esm2015':
case 'fesm2015':
return new Esm2015FileParser(program, host);
case 'esm5':
case 'fesm5':
return new Esm5FileParser(program, host);
default:
@ -105,6 +107,7 @@ export class PackageTransformer {
case 'esm2015':
case 'fesm2015':
return new Esm2015Renderer(host);
case 'esm5':
case 'fesm5':
return new Esm5Renderer(host);
default:

@ -64,21 +64,21 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
if (ngModule.has('declarations')) {
const declarationMeta =
staticallyResolve(ngModule.get('declarations') !, this.reflector, this.checker);
declarations = resolveTypeList(declarationMeta, 'declarations');
declarations = this.resolveTypeList(declarationMeta, 'declarations');
}
let imports: Reference[] = [];
if (ngModule.has('imports')) {
const importsMeta = staticallyResolve(
ngModule.get('imports') !, this.reflector, this.checker,
ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
imports = resolveTypeList(importsMeta, 'imports');
imports = this.resolveTypeList(importsMeta, 'imports');
}
let exports: Reference[] = [];
if (ngModule.has('exports')) {
const exportsMeta = staticallyResolve(
ngModule.get('exports') !, this.reflector, this.checker,
ref => this._extractModuleFromModuleWithProvidersFn(ref.node));
exports = resolveTypeList(exportsMeta, 'exports');
exports = this.resolveTypeList(exportsMeta, 'exports');
}
// Register this module's information with the SelectorScopeRegistry. This ensures that during
@ -181,39 +181,39 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
return arg.typeName;
}
}
/**
* Compute a list of `Reference`s from a resolved metadata value.
*/
function resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[] {
const refList: Reference[] = [];
if (!Array.isArray(resolvedList)) {
throw new Error(`Expected array when reading property ${name}`);
}
resolvedList.forEach((entry, idx) => {
// Unwrap ModuleWithProviders for modules that are locally declared (and thus static resolution
// was able to descend into the function and return an object literal, a Map).
if (entry instanceof Map && entry.has('ngModule')) {
entry = entry.get('ngModule') !;
/**
* Compute a list of `Reference`s from a resolved metadata value.
*/
private resolveTypeList(resolvedList: ResolvedValue, name: string): Reference[] {
const refList: Reference[] = [];
if (!Array.isArray(resolvedList)) {
throw new Error(`Expected array when reading property ${name}`);
}
if (Array.isArray(entry)) {
// Recurse into nested arrays.
refList.push(...resolveTypeList(entry, name));
} else if (entry instanceof Reference) {
if (!entry.expressable) {
throw new Error(`Value at position ${idx} in ${name} array is not expressable`);
} else if (!ts.isClassDeclaration(entry.node)) {
throw new Error(`Value at position ${idx} in ${name} array is not a class declaration`);
resolvedList.forEach((entry, idx) => {
// Unwrap ModuleWithProviders for modules that are locally declared (and thus static
// resolution was able to descend into the function and return an object literal, a Map).
if (entry instanceof Map && entry.has('ngModule')) {
entry = entry.get('ngModule') !;
}
refList.push(entry);
} else {
// TODO(alxhub): expand ModuleWithProviders.
throw new Error(`Value at position ${idx} in ${name} array is not a reference: ${entry}`);
}
});
return refList;
if (Array.isArray(entry)) {
// Recurse into nested arrays.
refList.push(...this.resolveTypeList(entry, name));
} else if (entry instanceof Reference) {
if (!entry.expressable) {
throw new Error(`Value at position ${idx} in ${name} array is not expressable`);
} else if (!this.reflector.isClass(entry.node)) {
throw new Error(`Value at position ${idx} in ${name} array is not a class declaration`);
}
refList.push(entry);
} else {
// TODO(alxhub): expand ModuleWithProviders.
throw new Error(`Value at position ${idx} in ${name} array is not a reference: ${entry}`);
}
});
return refList;
}
}

@ -86,6 +86,20 @@ describe('ngcc behavioral tests', () => {
expect(exitCode).toBe(0);
});
it('should run ngcc without errors for fesm5', () => {
const nodeModulesPath = path.join(basePath, 'node_modules');
console.error(nodeModulesPath);
const commonPath = path.join(nodeModulesPath, '@angular/common');
const exitCode = mainNgcc([commonPath, 'fesm5']);
console.warn(find('node_modules_ngtsc').filter(p => p.endsWith('.js') || p.endsWith('map')));
console.warn(cat('node_modules_ngtsc/@angular/common/fesm5/common.js').stdout);
console.warn(cat('node_modules_ngtsc/@angular/common/fesm5/common.js.map').stdout);
expect(exitCode).toBe(0);
});
it('should run ngcc without errors for esm2015', () => {
const nodeModulesPath = path.join(basePath, 'node_modules');
console.error(nodeModulesPath);
@ -99,4 +113,18 @@ describe('ngcc behavioral tests', () => {
expect(exitCode).toBe(0);
});
it('should run ngcc without errors for esm5', () => {
const nodeModulesPath = path.join(basePath, 'node_modules');
console.error(nodeModulesPath);
const commonPath = path.join(nodeModulesPath, '@angular/common');
const exitCode = mainNgcc([commonPath, 'esm5']);
console.warn(find('node_modules_ngtsc').filter(p => p.endsWith('.js') || p.endsWith('map')));
console.warn(cat('node_modules_ngtsc/@angular/common/esm5/src/directives/ng_if.js').stdout);
console.warn(cat('node_modules_ngtsc/@angular/common/esm5/http/src/module.js').stdout);
expect(exitCode).toBe(0);
});
});