Alex Rickabaugh 83a9159063 style(compiler): reformat of codebase with new clang-format version (#36520)
This commit reformats the packages/compiler tree using the new version of
clang-format.

PR Close #36520
2020-04-08 14:51:08 -07:00

105 lines
3.4 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as i18n from '../i18n_ast';
export abstract class Serializer {
// - The `placeholders` and `placeholderToMessage` properties are irrelevant in the input messages
// - The `id` contains the message id that the serializer is expected to use
// - Placeholder names are already map to public names using the provided mapper
abstract write(messages: i18n.Message[], locale: string|null): string;
abstract load(content: string, url: string):
{locale: string|null, i18nNodesByMsgId: {[msgId: string]: i18n.Node[]}};
abstract digest(message: i18n.Message): string;
// Creates a name mapper, see `PlaceholderMapper`
// Returning `null` means that no name mapping is used.
createNameMapper(message: i18n.Message): PlaceholderMapper|null {
return null;
}
}
/**
* A `PlaceholderMapper` converts placeholder names from internal to serialized representation and
* back.
*
* It should be used for serialization format that put constraints on the placeholder names.
*/
export interface PlaceholderMapper {
toPublicName(internalName: string): string|null;
toInternalName(publicName: string): string|null;
}
/**
* A simple mapper that take a function to transform an internal name to a public name
*/
export class SimplePlaceholderMapper extends i18n.RecurseVisitor implements PlaceholderMapper {
private internalToPublic: {[k: string]: string} = {};
private publicToNextId: {[k: string]: number} = {};
private publicToInternal: {[k: string]: string} = {};
// create a mapping from the message
constructor(message: i18n.Message, private mapName: (name: string) => string) {
super();
message.nodes.forEach(node => node.visit(this));
}
toPublicName(internalName: string): string|null {
return this.internalToPublic.hasOwnProperty(internalName) ?
this.internalToPublic[internalName] :
null;
}
toInternalName(publicName: string): string|null {
return this.publicToInternal.hasOwnProperty(publicName) ? this.publicToInternal[publicName] :
null;
}
visitText(text: i18n.Text, context?: any): any {
return null;
}
visitTagPlaceholder(ph: i18n.TagPlaceholder, context?: any): any {
this.visitPlaceholderName(ph.startName);
super.visitTagPlaceholder(ph, context);
this.visitPlaceholderName(ph.closeName);
}
visitPlaceholder(ph: i18n.Placeholder, context?: any): any {
this.visitPlaceholderName(ph.name);
}
visitIcuPlaceholder(ph: i18n.IcuPlaceholder, context?: any): any {
this.visitPlaceholderName(ph.name);
}
// XMB placeholders could only contains A-Z, 0-9 and _
private visitPlaceholderName(internalName: string): void {
if (!internalName || this.internalToPublic.hasOwnProperty(internalName)) {
return;
}
let publicName = this.mapName(internalName);
if (this.publicToInternal.hasOwnProperty(publicName)) {
// Create a new XMB when it has already been used
const nextId = this.publicToNextId[publicName];
this.publicToNextId[publicName] = nextId + 1;
publicName = `${publicName}_${nextId}`;
} else {
this.publicToNextId[publicName] = 1;
}
this.internalToPublic[internalName] = publicName;
this.publicToInternal[publicName] = internalName;
}
}