refactor(localize): allow ParsedMessage to hold additional location data (#38536)

In preparation for supporting `equiv-text` placeholder information in
extracted translation files, this commit adds these optional properties
to the `ParsedMessage` interface and updates `parseMessage()` to
be able to store them.

PR Close #38536
This commit is contained in:
Pete Bacon Darwin 2020-08-19 12:21:10 +01:00 committed by Misko Hevery
parent 94a3e0e81d
commit 23f855b300

View File

@ -48,6 +48,7 @@ export interface SourceLocation {
start: {line: number, column: number}; start: {line: number, column: number};
end: {line: number, column: number}; end: {line: number, column: number};
file: AbsoluteFsPath; file: AbsoluteFsPath;
text?: string;
} }
/** /**
@ -118,10 +119,18 @@ export interface ParsedMessage extends MessageMetadata {
* A mapping of placeholder names to substitution values. * A mapping of placeholder names to substitution values.
*/ */
substitutions: Record<string, any>; substitutions: Record<string, any>;
/**
* An optional mapping of placeholder names to source locations
*/
substitutionLocations?: Record<string, SourceLocation|undefined>;
/** /**
* The static parts of the message. * The static parts of the message.
*/ */
messageParts: string[]; messageParts: string[];
/**
* An optional mapping of message parts to source locations
*/
messagePartLocations?: (SourceLocation|undefined)[];
/** /**
* The names of the placeholders that will be replaced with substitutions. * The names of the placeholders that will be replaced with substitutions.
*/ */
@ -135,9 +144,11 @@ export interface ParsedMessage extends MessageMetadata {
* See `ParsedMessage` for an example. * See `ParsedMessage` for an example.
*/ */
export function parseMessage( export function parseMessage(
messageParts: TemplateStringsArray, expressions?: readonly any[], messageParts: TemplateStringsArray, expressions?: readonly any[], location?: SourceLocation,
location?: SourceLocation): ParsedMessage { messagePartLocations?: (SourceLocation|undefined)[],
expressionLocations: (SourceLocation|undefined)[] = []): ParsedMessage {
const substitutions: {[placeholderName: string]: any} = {}; const substitutions: {[placeholderName: string]: any} = {};
const substitutionLocations: {[placeholderName: string]: SourceLocation|undefined} = {};
const metadata = parseMetadata(messageParts[0], messageParts.raw[0]); const metadata = parseMetadata(messageParts[0], messageParts.raw[0]);
const cleanedMessageParts: string[] = [metadata.text]; const cleanedMessageParts: string[] = [metadata.text];
const placeholderNames: string[] = []; const placeholderNames: string[] = [];
@ -148,6 +159,7 @@ export function parseMessage(
messageString += `{$${placeholderName}}${messagePart}`; messageString += `{$${placeholderName}}${messagePart}`;
if (expressions !== undefined) { if (expressions !== undefined) {
substitutions[placeholderName] = expressions[i - 1]; substitutions[placeholderName] = expressions[i - 1];
substitutionLocations[placeholderName] = expressionLocations[i - 1];
} }
placeholderNames.push(placeholderName); placeholderNames.push(placeholderName);
cleanedMessageParts.push(messagePart); cleanedMessageParts.push(messagePart);
@ -158,11 +170,13 @@ export function parseMessage(
id: messageId, id: messageId,
legacyIds, legacyIds,
substitutions, substitutions,
substitutionLocations,
text: messageString, text: messageString,
customId: metadata.customId, customId: metadata.customId,
meaning: metadata.meaning || '', meaning: metadata.meaning || '',
description: metadata.description || '', description: metadata.description || '',
messageParts: cleanedMessageParts, messageParts: cleanedMessageParts,
messagePartLocations,
placeholderNames, placeholderNames,
location, location,
}; };