fix(compiler): look for flat module resources using declaration module path (#15367)

`ngc` would look for flat module resources relative to the flat module index.
`ngc` now looks for flat module resources relative to the `.d.ts` file that declarates
the component.

Fixes #15221

PR Close #15367
This commit is contained in:
Chuck Jazdzewski
2017-03-20 16:31:11 -07:00
committed by Miško Hevery
parent 7354949763
commit 90d2518d9a
19 changed files with 311 additions and 17 deletions

View File

@ -58,6 +58,7 @@ export class StaticSymbolResolver {
private resolvedFilePaths = new Set<string>();
// Note: this will only contain StaticSymbols without members!
private importAs = new Map<StaticSymbol, StaticSymbol>();
private symbolResourcePaths = new Map<StaticSymbol, string>();
constructor(
private host: StaticSymbolResolverHost, private staticSymbolCache: StaticSymbolCache,
@ -108,6 +109,15 @@ export class StaticSymbolResolver {
return result;
}
/**
* getResourcePath produces the path to the original location of the symbol and should
* be used to determine the relative location of resource references recorded in
* symbol metadata.
*/
getResourcePath(staticSymbol: StaticSymbol): string {
return this.symbolResourcePaths.get(staticSymbol) || staticSymbol.filePath;
}
/**
* getTypeArity returns the number of generic type parameters the given symbol
* has. If the symbol is not a type the result is null.
@ -200,18 +210,35 @@ export class StaticSymbolResolver {
// 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 canonicalSymbol = this.getStaticSymbol(filePath, name);
const symbol = this.getStaticSymbol(filePath, name);
let importSymbol: StaticSymbol|undefined = undefined;
if (metadata['importAs']) {
// Index bundle indexes should use the importAs module name instead of a reference
// to the .d.ts file directly.
const importSymbol = this.getStaticSymbol(metadata['importAs'], name);
this.recordImportAs(canonicalSymbol, importSymbol);
importSymbol = this.getStaticSymbol(metadata['importAs'], name);
this.recordImportAs(symbol, importSymbol);
}
const origin = 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}`), null);
} else {
this.symbolResourcePaths.set(symbol, originFilePath);
}
}
resolvedSymbols.push(
this.createResolvedSymbol(canonicalSymbol, topLevelSymbolNames, symbolMeta));
this.createResolvedSymbol(symbol, filePath, topLevelSymbolNames, symbolMeta));
});
}
@ -257,7 +284,7 @@ export class StaticSymbolResolver {
}
private createResolvedSymbol(
sourceSymbol: StaticSymbol, topLevelSymbolNames: Set<string>,
sourceSymbol: StaticSymbol, topLevelPath: string, topLevelSymbolNames: Set<string>,
metadata: any): ResolvedStaticSymbol {
const self = this;
@ -291,7 +318,7 @@ export class StaticSymbolResolver {
return {__symbolic: 'reference', name: name};
} else {
if (topLevelSymbolNames.has(name)) {
return self.getStaticSymbol(sourceSymbol.filePath, name);
return self.getStaticSymbol(topLevelPath, name);
}
// ambient value
null;