processDiagnosticMessages: Simplify check for uniqueness of names (#17331)

* processDiagnosticMessages: Simplify check for uniqueness of names

* Be case-sensitive
This commit is contained in:
Andy 2017-07-27 12:30:37 -07:00 committed by GitHub
parent 70e5c6b1e5
commit 12acc141c0

View File

@ -30,14 +30,20 @@ function main(): void {
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
var names = Utilities.getObjectKeys(diagnosticMessages);
var nameMap = buildUniqueNameMap(names);
var names = Object.keys(diagnosticMessages);
// Check that there are no duplicates.
const seenNames = ts.createMap<true>();
for (const name of names) {
if (seenNames.has(name))
throw new Error(`Name ${name} appears twice`);
seenNames.set(name, true);
}
var infoFileOutput = buildInfoFileOutput(diagnosticMessages, nameMap);
var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
checkForUniqueCodes(names, diagnosticMessages);
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages, nameMap);
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
writeFile("diagnosticMessages.generated.json", messageOutput);
}
@ -68,30 +74,16 @@ function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosti
}
}
function buildUniqueNameMap(names: string[]): ts.Map<string> {
var nameMap = ts.createMap<string>();
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
for (var i = 0; i < names.length; i++) {
nameMap.set(names[i], uniqueNames[i]);
}
return nameMap;
}
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
var result =
'// <auto-generated />\r\n' +
'/// <reference path="types.ts" />\r\n' +
'/* @internal */\r\n' +
'namespace ts {\r\n' +
' export const Diagnostics = {\r\n';
var names = Utilities.getObjectKeys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
for (const name of Object.keys(messageTable)) {
var diagnosticDetails = messageTable[name];
var propName = convertPropertyName(nameMap.get(name));
var propName = convertPropertyName(name);
result +=
' ' + propName +
@ -107,14 +99,14 @@ function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap:
return result;
}
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
var result =
'{';
var names = Utilities.getObjectKeys(messageTable);
var names = Object.keys(messageTable);
for (var i = 0; i < names.length; i++) {
var name = names[i];
var diagnosticDetails = messageTable[name];
var propName = convertPropertyName(nameMap.get(name));
var propName = convertPropertyName(name);
result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"';
if (i !== names.length - 1) {
@ -152,93 +144,4 @@ function convertPropertyName(origName: string): string {
return result;
}
module NameGenerator {
export function ensureUniqueness(names: string[], isCaseSensitive: boolean, isFixed?: boolean[]): string[]{
if (!isFixed) {
isFixed = names.map(() => false)
}
var names = names.slice();
ensureUniquenessInPlace(names, isCaseSensitive, isFixed);
return names;
}
function ensureUniquenessInPlace(names: string[], isCaseSensitive: boolean, isFixed: boolean[]): void {
for (var i = 0; i < names.length; i++) {
var name = names[i];
var collisionIndices = Utilities.collectMatchingIndices(name, names, isCaseSensitive);
// We will always have one "collision" because getCollisionIndices returns the index of name itself as well;
// so if we only have one collision, then there are no issues.
if (collisionIndices.length < 2) {
continue;
}
handleCollisions(name, names, isFixed, collisionIndices, isCaseSensitive);
}
}
function handleCollisions(name: string, proposedNames: string[], isFixed: boolean[], collisionIndices: number[], isCaseSensitive: boolean): void {
var suffix = 1;
for (var i = 0; i < collisionIndices.length; i++) {
var collisionIndex = collisionIndices[i];
if (isFixed[collisionIndex]) {
// can't do anything about this name.
continue;
}
while (true) {
var newName = name + suffix;
suffix++;
// Check if we've synthesized a unique name, and if so
// replace the conflicting name with the new one.
if (!proposedNames.some(name => Utilities.stringEquals(name, newName, isCaseSensitive))) {
proposedNames[collisionIndex] = newName;
break;
}
}
}
}
}
module Utilities {
/// Return a list of all indices where a string occurs.
export function collectMatchingIndices(name: string, proposedNames: string[], isCaseSensitive: boolean): number[] {
var matchingIndices: number[] = [];
for (var i = 0; i < proposedNames.length; i++) {
if (stringEquals(name, proposedNames[i], isCaseSensitive)) {
matchingIndices.push(i);
}
}
return matchingIndices;
}
export function stringEquals(s1: string, s2: string, caseSensitive: boolean): boolean {
if (caseSensitive) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
}
return s1 == s2;
}
// Like Object.keys
export function getObjectKeys(obj: any): string[] {
var result: string[] = [];
for (var name in obj) {
if (obj.hasOwnProperty(name)) {
result.push(name);
}
}
return result;
}
}
main();