feat(bazel): prefix private-export (barred-latin-o) symbols (#23007)

This allows a bundle index to be re-exported by a higher-level module without fear of collisions.
Under bazel, we always set the prefix to be underscore-joined workspace, package, label

PR Close #23007
This commit is contained in:
Alex Eagle
2018-03-26 14:34:44 -07:00
committed by Matias Niemelä
parent 7a406a32fa
commit 27e14b2fb3
6 changed files with 24 additions and 14 deletions

View File

@ -77,8 +77,9 @@ export function createBundleIndexHost<H extends ts.CompilerHost>(
}
const file = files[0];
const indexModule = file.replace(/\.ts$/, '');
const bundler =
new MetadataBundler(indexModule, ngOptions.flatModuleId, new CompilerHostAdapter(host));
const bundler = new MetadataBundler(
indexModule, ngOptions.flatModuleId, new CompilerHostAdapter(host),
ngOptions.flatModulePrivateSymbolPrefix);
const metadataBundle = bundler.getMetadataBundle();
const metadata = JSON.stringify(metadataBundle.metadata);
const name =

View File

@ -83,11 +83,14 @@ export class MetadataBundler {
private metadataCache = new Map<string, ModuleMetadata|undefined>();
private exports = new Map<string, Symbol[]>();
private rootModule: string;
private privateSymbolPrefix: string;
private exported: Set<Symbol>;
constructor(
private root: string, private importAs: string|undefined, private host: MetadataBundlerHost) {
private root: string, private importAs: string|undefined, private host: MetadataBundlerHost,
privateSymbolPrefix?: string) {
this.rootModule = `./${path.basename(root)}`;
this.privateSymbolPrefix = (privateSymbolPrefix || '').replace(/\W/g, '_');
}
getMetadataBundle(): BundledModule {
@ -244,7 +247,7 @@ export class MetadataBundler {
const exportedNames = new Set(exportedSymbols.map(s => s.name));
let privateName = 0;
function newPrivateName(): string {
function newPrivateName(prefix: string): string {
while (true) {
let digits: string[] = [];
let index = privateName++;
@ -253,8 +256,7 @@ export class MetadataBundler {
digits.unshift(base[index % base.length]);
index = Math.floor(index / base.length);
}
digits.unshift('\u0275');
const result = digits.join('');
const result = `\u0275${prefix}${digits.join('')}`;
if (!exportedNames.has(result)) return result;
}
}
@ -267,7 +269,7 @@ export class MetadataBundler {
let name = symbol.name;
const identifier = `${symbol.declaration!.module}:${symbol.declaration !.name}`;
if (symbol.isPrivate && !symbol.privateName) {
name = newPrivateName();
name = newPrivateName(this.privateSymbolPrefix);
symbol.privateName = name;
}
if (symbolsMap.has(identifier)) {

View File

@ -99,6 +99,10 @@ export interface CompilerOptions extends ts.CompilerOptions {
// meaningful when `flatModuleOutFile` is also supplied. It is otherwise ignored.
flatModuleId?: string;
// A prefix to insert in generated private symbols, e.g. for "my_prefix_" we
// would generate private symbols named like `ɵmy_prefix_a`.
flatModulePrivateSymbolPrefix?: string;
// Whether to generate code for library code.
// If true, produce .ngfactory.ts and .ngstyle.ts files for .d.ts inputs.
// Default is true.