TypeScript/scripts/processDiagnosticMessages.ts

121 lines
4.1 KiB
TypeScript
Raw Normal View History

2014-07-13 01:04:16 +02:00
/// <reference path="../src/compiler/sys.ts" />
interface DiagnosticDetails {
category: string;
code: number;
isEarly?: boolean;
2014-07-13 01:04:16 +02:00
}
type InputDiagnosticMessageTable = ts.Map<DiagnosticDetails>;
2014-07-13 01:04:16 +02:00
function main(): void {
var sys = ts.sys;
2014-07-13 01:04:16 +02:00
if (sys.args.length < 1) {
sys.write("Usage:" + sys.newLine)
sys.write("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>" + sys.newLine);
return;
}
function writeFile(fileName: string, contents: string) {
// TODO: Fix path joining
var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/"));
var fileOutputPath = inputDirectory + "/" + fileName;
sys.writeFile(fileOutputPath, contents);
}
2014-07-13 01:04:16 +02:00
var inputFilePath = sys.args[0].replace(/\\/g, "/");
var inputStr = sys.readFile(inputFilePath);
2016-12-05 23:13:32 +01:00
var diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
// Check that there are no duplicates.
const seenNames = ts.createMap<true>();
for (const name of Object.keys(diagnosticMessagesJson)) {
if (seenNames.has(name))
throw new Error(`Name ${name} appears twice`);
seenNames.set(name, true);
}
2014-07-13 01:04:16 +02:00
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
checkForUniqueCodes(diagnosticMessages);
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
writeFile("diagnosticMessages.generated.json", messageOutput);
2014-07-13 01:04:16 +02:00
}
function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
const allCodes: { [key: number]: true | undefined } = [];
diagnosticTable.forEach(({ code }) => {
if (allCodes[code])
throw new Error(`Diagnostic code ${code} appears more than once.`);
allCodes[code] = true;
});
}
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
2014-07-13 01:04:16 +02:00
var result =
'// <auto-generated />\r\n' +
'/// <reference path="types.ts" />\r\n' +
'/* @internal */\r\n' +
'namespace ts {\r\n' +
" function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" +
" return { code, category, key, message };\r\n" +
" }\r\n" +
2016-10-04 23:00:45 +02:00
' export const Diagnostics = {\r\n';
messageTable.forEach(({ code, category }, name) => {
const propName = convertPropertyName(name);
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`;
});
2014-07-13 01:04:16 +02:00
result += ' };\r\n}';
return result;
}
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
let result = '{';
let first = true;
messageTable.forEach(({ code }, name) => {
if (!first) {
first = false;
}
else {
result += ',';
}
const propName = convertPropertyName(name);
result += `\r\n "${createKey(propName, code)}": "${name.replace(/[\"]/g, '\\"')}"`;
});
2015-10-15 20:46:50 +02:00
result += '\r\n}';
return result;
}
function createKey(name: string, code: number) : string {
return name.slice(0, 100) + '_' + code;
}
2014-07-13 01:04:16 +02:00
function convertPropertyName(origName: string): string {
var result = origName.split("").map(char => {
if (char === '*') { return "_Asterisk"; }
if (char === '/') { return "_Slash"; }
if (char === ':') { return "_Colon"; }
return /\w/.test(char) ? char : "_";
}).join("");
// get rid of all multi-underscores
result = result.replace(/_+/g, "_");
// remove any leading underscore, unless it is followed by a number.
result = result.replace(/^_([^\d])/, "$1")
// get rid of all trailing underscores.
result = result.replace(/_$/, "");
return result;
}
main();