2014-07-13 01:04:16 +02:00
|
|
|
interface DiagnosticDetails {
|
|
|
|
category: string;
|
|
|
|
code: number;
|
2018-04-10 19:15:15 +02:00
|
|
|
reportsUnnecessary?: {};
|
2014-10-21 02:38:50 +02:00
|
|
|
isEarly?: boolean;
|
2014-07-13 01:04:16 +02:00
|
|
|
}
|
|
|
|
|
2017-07-28 19:11:57 +02:00
|
|
|
type InputDiagnosticMessageTable = ts.Map<DiagnosticDetails>;
|
2014-07-13 01:04:16 +02:00
|
|
|
|
|
|
|
function main(): void {
|
2017-11-08 21:56:39 +01:00
|
|
|
const sys = ts.sys;
|
2014-07-13 01:04:16 +02:00
|
|
|
if (sys.args.length < 1) {
|
2017-11-08 21:56:39 +01:00
|
|
|
sys.write("Usage:" + sys.newLine);
|
2014-07-13 01:04:16 +02:00
|
|
|
sys.write("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>" + sys.newLine);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-15 20:22:22 +02:00
|
|
|
function writeFile(fileName: string, contents: string) {
|
2017-11-08 21:56:39 +01:00
|
|
|
const inputDirectory = ts.getDirectoryPath(inputFilePath);
|
|
|
|
const fileOutputPath = ts.combinePaths(inputDirectory, fileName);
|
2015-10-15 20:22:22 +02:00
|
|
|
sys.writeFile(fileOutputPath, contents);
|
|
|
|
}
|
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
const inputFilePath = sys.args[0].replace(/\\/g, "/");
|
|
|
|
const inputStr = sys.readFile(inputFilePath);
|
2016-12-05 23:13:32 +01:00
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
|
2014-07-13 01:04:16 +02:00
|
|
|
|
2017-07-28 19:11:57 +02:00
|
|
|
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
|
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
const outputFilesDir = ts.getDirectoryPath(inputFilePath);
|
|
|
|
const thisFilePathRel = ts.getRelativePathToDirectoryOrUrl(outputFilesDir, sys.getExecutingFilePath(),
|
|
|
|
sys.getCurrentDirectory(), ts.createGetCanonicalFileName(sys.useCaseSensitiveFileNames), /* isAbsolutePathAnUrl */ false);
|
|
|
|
|
|
|
|
const infoFileOutput = buildInfoFileOutput(diagnosticMessages, "./diagnosticInformationMap.generated.ts", thisFilePathRel);
|
2017-07-28 19:11:57 +02:00
|
|
|
checkForUniqueCodes(diagnosticMessages);
|
2015-10-15 20:22:22 +02:00
|
|
|
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
|
2015-09-20 21:14:56 +02:00
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
const messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
|
2015-10-15 20:22:22 +02:00
|
|
|
writeFile("diagnosticMessages.generated.json", messageOutput);
|
2014-07-13 01:04:16 +02:00
|
|
|
}
|
|
|
|
|
2017-07-28 19:11:57 +02:00
|
|
|
function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
|
|
|
|
const allCodes: { [key: number]: true | undefined } = [];
|
|
|
|
diagnosticTable.forEach(({ code }) => {
|
2017-11-08 21:56:39 +01:00
|
|
|
if (allCodes[code]) {
|
2017-07-28 19:11:57 +02:00
|
|
|
throw new Error(`Diagnostic code ${code} appears more than once.`);
|
2017-11-08 21:56:39 +01:00
|
|
|
}
|
2017-07-28 19:11:57 +02:00
|
|
|
allCodes[code] = true;
|
|
|
|
});
|
2015-09-20 21:14:56 +02:00
|
|
|
}
|
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, inputFilePathRel: string, thisFilePathRel: string): string {
|
|
|
|
let result =
|
|
|
|
"// <auto-generated />\r\n" +
|
|
|
|
"// generated from '" + inputFilePathRel + "' by '" + thisFilePathRel + "'\r\n" +
|
|
|
|
"/* @internal */\r\n" +
|
|
|
|
"namespace ts {\r\n" +
|
2018-04-10 19:15:15 +02:00
|
|
|
" function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}): DiagnosticMessage {\r\n" +
|
|
|
|
" return { code, category, key, message, reportsUnnecessary };\r\n" +
|
2017-07-28 19:11:57 +02:00
|
|
|
" }\r\n" +
|
2017-11-06 18:23:47 +01:00
|
|
|
" // tslint:disable-next-line variable-name\r\n" +
|
|
|
|
" export const Diagnostics = {\r\n";
|
2018-04-10 19:15:15 +02:00
|
|
|
messageTable.forEach(({ code, category, reportsUnnecessary }, name) => {
|
2017-07-28 19:11:57 +02:00
|
|
|
const propName = convertPropertyName(name);
|
2018-04-10 19:15:15 +02:00
|
|
|
const argReportsUnnecessary = reportsUnnecessary ? `, /*reportsUnnecessary*/ ${reportsUnnecessary}` : "";
|
|
|
|
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}),\r\n`;
|
2017-07-28 19:11:57 +02:00
|
|
|
});
|
2014-07-13 01:04:16 +02:00
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
result += " };\r\n}";
|
2014-07-13 01:04:16 +02:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-27 21:30:37 +02:00
|
|
|
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
|
2017-11-08 21:56:39 +01:00
|
|
|
let result = "{";
|
2017-07-28 19:11:57 +02:00
|
|
|
messageTable.forEach(({ code }, name) => {
|
|
|
|
const propName = convertPropertyName(name);
|
2017-07-31 21:51:25 +02:00
|
|
|
result += `\r\n "${createKey(propName, code)}" : "${name.replace(/[\"]/g, '\\"')}",`;
|
2017-07-28 19:11:57 +02:00
|
|
|
});
|
2015-10-15 20:22:22 +02:00
|
|
|
|
2017-07-31 21:51:25 +02:00
|
|
|
// Shave trailing comma, then add newline and ending brace
|
2017-11-08 21:56:39 +01:00
|
|
|
result = result.slice(0, result.length - 1) + "\r\n}";
|
2017-07-31 21:51:25 +02:00
|
|
|
|
|
|
|
// Assert that we generated valid JSON
|
|
|
|
JSON.parse(result);
|
2015-10-15 20:22:22 +02:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-11-08 21:56:39 +01:00
|
|
|
function createKey(name: string, code: number): string {
|
|
|
|
return name.slice(0, 100) + "_" + code;
|
2015-10-15 20:22:22 +02:00
|
|
|
}
|
|
|
|
|
2014-07-13 01:04:16 +02:00
|
|
|
function convertPropertyName(origName: string): string {
|
2017-11-08 21:56:39 +01:00
|
|
|
let result = origName.split("").map(char => {
|
|
|
|
if (char === "*") { return "_Asterisk"; }
|
|
|
|
if (char === "/") { return "_Slash"; }
|
|
|
|
if (char === ":") { return "_Colon"; }
|
2014-07-13 01:04:16 +02:00
|
|
|
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.
|
2017-11-08 21:56:39 +01:00
|
|
|
result = result.replace(/^_([^\d])/, "$1");
|
2014-07-13 01:04:16 +02:00
|
|
|
|
|
|
|
// get rid of all trailing underscores.
|
|
|
|
result = result.replace(/_$/, "");
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|