fix(compiler): allow to use lowering with `export *`.
Previously, we generated incorrect code when a file had lowerings and also exported another file via `export *` that also had lowerings in it.
This commit is contained in:
parent
3799f43c71
commit
e31a76ce24
|
@ -711,6 +711,38 @@ describe('ngc transformer command-line', () => {
|
||||||
expect(main(['-p', basePath], errorSpy)).toBe(0);
|
expect(main(['-p', basePath], errorSpy)).toBe(0);
|
||||||
shouldExist('module.js');
|
shouldExist('module.js');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow to use lowering with export *', () => {
|
||||||
|
write('mymodule.ts', `
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
export * from './util';
|
||||||
|
|
||||||
|
// Note: the lamda will be lowered into an exported expression
|
||||||
|
@NgModule({providers: [{provide: 'aToken', useValue: () => 2}]})
|
||||||
|
export class MyModule {}
|
||||||
|
`);
|
||||||
|
write('util.ts', `
|
||||||
|
// Note: The lamda will be lowered into an exported expression
|
||||||
|
const x = () => 2;
|
||||||
|
|
||||||
|
export const y = x;
|
||||||
|
`);
|
||||||
|
|
||||||
|
expect(compile()).toEqual(0);
|
||||||
|
|
||||||
|
const mymoduleSource = fs.readFileSync(path.resolve(outDir, 'mymodule.js'), 'utf8');
|
||||||
|
expect(mymoduleSource).toContain('ɵ0');
|
||||||
|
|
||||||
|
const utilSource = fs.readFileSync(path.resolve(outDir, 'util.js'), 'utf8');
|
||||||
|
expect(utilSource).toContain('ɵ0');
|
||||||
|
|
||||||
|
const mymoduleNgFactoryJs =
|
||||||
|
fs.readFileSync(path.resolve(outDir, 'mymodule.ngfactory.js'), 'utf8');
|
||||||
|
// check that the generated code refers to ɵ0 from mymodule, and not from util!
|
||||||
|
expect(mymoduleNgFactoryJs).toContain(`import * as i1 from "./mymodule"`);
|
||||||
|
expect(mymoduleNgFactoryJs).toContain(`"aToken", i1.ɵ0`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function writeFlatModule(outFile: string) {
|
function writeFlatModule(outFile: string) {
|
||||||
|
|
|
@ -292,34 +292,6 @@ export class StaticSymbolResolver {
|
||||||
this.resolvedFilePaths.add(filePath);
|
this.resolvedFilePaths.add(filePath);
|
||||||
const resolvedSymbols: ResolvedStaticSymbol[] = [];
|
const resolvedSymbols: ResolvedStaticSymbol[] = [];
|
||||||
const metadata = this.getModuleMetadata(filePath);
|
const metadata = this.getModuleMetadata(filePath);
|
||||||
if (metadata['metadata']) {
|
|
||||||
// handle direct declarations of the symbol
|
|
||||||
const topLevelSymbolNames =
|
|
||||||
new Set<string>(Object.keys(metadata['metadata']).map(unescapeIdentifier));
|
|
||||||
const origins: {[index: string]: string} = metadata['origins'] || {};
|
|
||||||
Object.keys(metadata['metadata']).forEach((metadataKey) => {
|
|
||||||
const symbolMeta = metadata['metadata'][metadataKey];
|
|
||||||
const name = unescapeIdentifier(metadataKey);
|
|
||||||
|
|
||||||
const symbol = this.getStaticSymbol(filePath, name);
|
|
||||||
|
|
||||||
const origin = origins.hasOwnProperty(metadataKey) && origins[metadataKey];
|
|
||||||
if (origin) {
|
|
||||||
// If the symbol is from a bundled index, use the declaration location of the
|
|
||||||
// symbol so relative references (such as './my.html') will be calculated
|
|
||||||
// correctly.
|
|
||||||
const originFilePath = this.resolveModule(origin, filePath);
|
|
||||||
if (!originFilePath) {
|
|
||||||
this.reportError(
|
|
||||||
new Error(`Couldn't resolve original symbol for ${origin} from ${filePath}`));
|
|
||||||
} else {
|
|
||||||
this.symbolResourcePaths.set(symbol, originFilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolvedSymbols.push(
|
|
||||||
this.createResolvedSymbol(symbol, filePath, topLevelSymbolNames, symbolMeta));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle the symbols in one of the re-export location
|
// handle the symbols in one of the re-export location
|
||||||
if (metadata['exports']) {
|
if (metadata['exports']) {
|
||||||
|
@ -358,6 +330,38 @@ export class StaticSymbolResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle the actual metadata. Has to be after the exports
|
||||||
|
// as there migth be collisions in the names, and we want the symbols
|
||||||
|
// of the current module to win ofter reexports.
|
||||||
|
if (metadata['metadata']) {
|
||||||
|
// handle direct declarations of the symbol
|
||||||
|
const topLevelSymbolNames =
|
||||||
|
new Set<string>(Object.keys(metadata['metadata']).map(unescapeIdentifier));
|
||||||
|
const origins: {[index: string]: string} = metadata['origins'] || {};
|
||||||
|
Object.keys(metadata['metadata']).forEach((metadataKey) => {
|
||||||
|
const symbolMeta = metadata['metadata'][metadataKey];
|
||||||
|
const name = unescapeIdentifier(metadataKey);
|
||||||
|
|
||||||
|
const symbol = this.getStaticSymbol(filePath, name);
|
||||||
|
|
||||||
|
const origin = origins.hasOwnProperty(metadataKey) && origins[metadataKey];
|
||||||
|
if (origin) {
|
||||||
|
// If the symbol is from a bundled index, use the declaration location of the
|
||||||
|
// symbol so relative references (such as './my.html') will be calculated
|
||||||
|
// correctly.
|
||||||
|
const originFilePath = this.resolveModule(origin, filePath);
|
||||||
|
if (!originFilePath) {
|
||||||
|
this.reportError(
|
||||||
|
new Error(`Couldn't resolve original symbol for ${origin} from ${filePath}`));
|
||||||
|
} else {
|
||||||
|
this.symbolResourcePaths.set(symbol, originFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolvedSymbols.push(
|
||||||
|
this.createResolvedSymbol(symbol, filePath, topLevelSymbolNames, symbolMeta));
|
||||||
|
});
|
||||||
|
}
|
||||||
resolvedSymbols.forEach(
|
resolvedSymbols.forEach(
|
||||||
(resolvedSymbol) => this.resolvedSymbols.set(resolvedSymbol.symbol, resolvedSymbol));
|
(resolvedSymbol) => this.resolvedSymbols.set(resolvedSymbol.symbol, resolvedSymbol));
|
||||||
this.symbolFromFile.set(filePath, resolvedSymbols.map(resolvedSymbol => resolvedSymbol.symbol));
|
this.symbolFromFile.set(filePath, resolvedSymbols.map(resolvedSymbol => resolvedSymbol.symbol));
|
||||||
|
|
|
@ -124,6 +124,7 @@ describe('StaticSymbolResolver', () => {
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'One'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'One'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Two'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Two'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Three'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Three'),
|
||||||
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Six'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,8 +133,9 @@ describe('StaticSymbolResolver', () => {
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'One'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'One'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Two'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Two'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Four'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Four'),
|
||||||
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Six'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Five'),
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Five'),
|
||||||
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Thirty')
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Thirty'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -287,8 +289,9 @@ describe('StaticSymbolResolver', () => {
|
||||||
.toBe(symbolCache.get('/test2.d.ts', '__a__'));
|
.toBe(symbolCache.get('/test2.d.ts', '__a__'));
|
||||||
|
|
||||||
expect(symbolResolver.getSymbolsOf('/test.ts')).toEqual([
|
expect(symbolResolver.getSymbolsOf('/test.ts')).toEqual([
|
||||||
symbolCache.get('/test.ts', '__x__'), symbolCache.get('/test.ts', '__y__'),
|
symbolCache.get('/test.ts', '__b__'),
|
||||||
symbolCache.get('/test.ts', '__b__')
|
symbolCache.get('/test.ts', '__x__'),
|
||||||
|
symbolCache.get('/test.ts', '__y__'),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -356,6 +359,14 @@ describe('StaticSymbolResolver', () => {
|
||||||
expect(symbol2.filePath).toEqual('/tmp/src/reexport/src/origin30.d.ts');
|
expect(symbol2.filePath).toEqual('/tmp/src/reexport/src/origin30.d.ts');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should prefer names in the file over reexports', () => {
|
||||||
|
const metadata = symbolResolver
|
||||||
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
||||||
|
'./reexport/reexport', 'Six', '/tmp/src/main.ts'))
|
||||||
|
.metadata;
|
||||||
|
expect(metadata.__symbolic).toBe('class');
|
||||||
|
});
|
||||||
|
|
||||||
it('should cache tracing a named export', () => {
|
it('should cache tracing a named export', () => {
|
||||||
const moduleNameToFileNameSpy = spyOn(host, 'moduleNameToFileName').and.callThrough();
|
const moduleNameToFileNameSpy = spyOn(host, 'moduleNameToFileName').and.callThrough();
|
||||||
const getMetadataForSpy = spyOn(host, 'getMetadataFor').and.callThrough();
|
const getMetadataForSpy = spyOn(host, 'getMetadataFor').and.callThrough();
|
||||||
|
@ -494,9 +505,11 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||||
'/tmp/src/reexport/reexport.d.ts': {
|
'/tmp/src/reexport/reexport.d.ts': {
|
||||||
__symbolic: 'module',
|
__symbolic: 'module',
|
||||||
version: 3,
|
version: 3,
|
||||||
metadata: {},
|
metadata: {
|
||||||
|
Six: {__symbolic: 'class'},
|
||||||
|
},
|
||||||
exports: [
|
exports: [
|
||||||
{from: './src/origin1', export: ['One', 'Two', {name: 'Three', as: 'Four'}]},
|
{from: './src/origin1', export: ['One', 'Two', {name: 'Three', as: 'Four'}, 'Six']},
|
||||||
{from: './src/origin5'}, {from: './src/reexport2'}
|
{from: './src/origin5'}, {from: './src/reexport2'}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -507,6 +520,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||||
One: {__symbolic: 'class'},
|
One: {__symbolic: 'class'},
|
||||||
Two: {__symbolic: 'class'},
|
Two: {__symbolic: 'class'},
|
||||||
Three: {__symbolic: 'class'},
|
Three: {__symbolic: 'class'},
|
||||||
|
Six: {__symbolic: 'class'},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'/tmp/src/reexport/src/origin5.d.ts': {
|
'/tmp/src/reexport/src/origin5.d.ts': {
|
||||||
|
|
Loading…
Reference in New Issue