2014-07-13 03:04:16 +04:00
|
|
|
/// <reference path="../src/compiler/sys.ts" />
|
|
|
|
|
|
|
|
interface DiagnosticDetails {
|
|
|
|
category: string;
|
|
|
|
code: number;
|
2014-10-21 04:38:50 +04:00
|
|
|
isEarly?: boolean;
|
2014-07-13 03:04:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
interface InputDiagnosticMessageTable {
|
|
|
|
[msg: string]: DiagnosticDetails;
|
|
|
|
}
|
|
|
|
|
|
|
|
function main(): void {
|
2014-12-12 01:46:54 +03:00
|
|
|
var sys = ts.sys;
|
2014-07-13 03:04:16 +04:00
|
|
|
if (sys.args.length < 1) {
|
|
|
|
sys.write("Usage:" + sys.newLine)
|
|
|
|
sys.write("\tnode processDiagnosticMessages.js <diagnostic-json-input-file>" + sys.newLine);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-15 21:22:22 +03:00
|
|
|
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 03:04:16 +04:00
|
|
|
var inputFilePath = sys.args[0].replace(/\\/g, "/");
|
|
|
|
var inputStr = sys.readFile(inputFilePath);
|
2016-12-06 01:13:32 +03:00
|
|
|
|
2015-09-20 22:14:56 +03:00
|
|
|
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
|
2014-07-13 03:04:16 +04:00
|
|
|
|
2017-07-27 22:30:37 +03:00
|
|
|
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);
|
|
|
|
}
|
2014-07-13 03:04:16 +04:00
|
|
|
|
2017-07-27 22:30:37 +03:00
|
|
|
var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
|
2015-09-20 22:14:56 +03:00
|
|
|
checkForUniqueCodes(names, diagnosticMessages);
|
2015-10-15 21:22:22 +03:00
|
|
|
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
|
2015-09-20 22:14:56 +03:00
|
|
|
|
2017-07-27 22:30:37 +03:00
|
|
|
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
|
2015-10-15 21:22:22 +03:00
|
|
|
writeFile("diagnosticMessages.generated.json", messageOutput);
|
2014-07-13 03:04:16 +04:00
|
|
|
}
|
|
|
|
|
2015-09-20 22:14:56 +03:00
|
|
|
function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) {
|
|
|
|
const originalMessageForCode: string[] = [];
|
2015-09-20 22:41:28 +03:00
|
|
|
let numConflicts = 0;
|
2016-12-06 01:13:32 +03:00
|
|
|
|
2015-09-20 22:14:56 +03:00
|
|
|
for (const currentMessage of messages) {
|
|
|
|
const code = diagnosticTable[currentMessage].code;
|
|
|
|
|
|
|
|
if (code in originalMessageForCode) {
|
|
|
|
const originalMessage = originalMessageForCode[code];
|
2015-09-20 22:41:28 +03:00
|
|
|
ts.sys.write("\x1b[91m"); // High intensity red.
|
|
|
|
ts.sys.write("Error");
|
2015-09-20 22:14:56 +03:00
|
|
|
ts.sys.write("\x1b[0m"); // Reset formatting.
|
|
|
|
ts.sys.write(`: Diagnostic code '${code}' conflicts between "${originalMessage}" and "${currentMessage}".`);
|
|
|
|
ts.sys.write(ts.sys.newLine + ts.sys.newLine);
|
2015-09-20 22:41:28 +03:00
|
|
|
|
|
|
|
numConflicts++;
|
2015-09-20 22:14:56 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
originalMessageForCode[code] = currentMessage;
|
|
|
|
}
|
|
|
|
}
|
2015-09-20 22:41:28 +03:00
|
|
|
|
|
|
|
if (numConflicts > 0) {
|
|
|
|
throw new Error(`Found ${numConflicts} conflict(s) in diagnostic codes.`);
|
|
|
|
}
|
2015-09-20 22:14:56 +03:00
|
|
|
}
|
|
|
|
|
2017-07-27 22:30:37 +03:00
|
|
|
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
|
2014-07-13 03:04:16 +04:00
|
|
|
var result =
|
|
|
|
'// <auto-generated />\r\n' +
|
|
|
|
'/// <reference path="types.ts" />\r\n' +
|
2015-04-14 01:55:56 +03:00
|
|
|
'/* @internal */\r\n' +
|
2015-06-12 19:01:48 +03:00
|
|
|
'namespace ts {\r\n' +
|
2016-10-05 00:00:45 +03:00
|
|
|
' export const Diagnostics = {\r\n';
|
2017-07-27 22:30:37 +03:00
|
|
|
for (const name of Object.keys(messageTable)) {
|
2014-07-13 03:04:16 +04:00
|
|
|
var diagnosticDetails = messageTable[name];
|
2017-07-27 22:30:37 +03:00
|
|
|
var propName = convertPropertyName(name);
|
2014-07-13 03:04:16 +04:00
|
|
|
|
|
|
|
result +=
|
2015-10-15 21:22:22 +03:00
|
|
|
' ' + propName +
|
2014-07-13 03:04:16 +04:00
|
|
|
': { code: ' + diagnosticDetails.code +
|
|
|
|
', category: DiagnosticCategory.' + diagnosticDetails.category +
|
2015-10-15 21:22:22 +03:00
|
|
|
', key: "' + createKey(propName, diagnosticDetails.code) + '"' +
|
|
|
|
', message: "' + name.replace(/[\"]/g, '\\"') + '"' +
|
2014-10-21 04:38:50 +04:00
|
|
|
' },\r\n';
|
2014-07-13 03:04:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
result += ' };\r\n}';
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-07-27 22:30:37 +03:00
|
|
|
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
|
2015-10-15 21:22:22 +03:00
|
|
|
var result =
|
|
|
|
'{';
|
2017-07-27 22:30:37 +03:00
|
|
|
var names = Object.keys(messageTable);
|
2015-10-15 21:22:22 +03:00
|
|
|
for (var i = 0; i < names.length; i++) {
|
|
|
|
var name = names[i];
|
|
|
|
var diagnosticDetails = messageTable[name];
|
2017-07-27 22:30:37 +03:00
|
|
|
var propName = convertPropertyName(name);
|
2015-10-15 21:22:22 +03:00
|
|
|
|
2015-10-15 21:46:50 +03:00
|
|
|
result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"';
|
2015-10-15 21:22:22 +03:00
|
|
|
if (i !== names.length - 1) {
|
|
|
|
result += ',';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-15 21:46:50 +03:00
|
|
|
result += '\r\n}';
|
2015-10-15 21:22:22 +03:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createKey(name: string, code: number) : string {
|
|
|
|
return name.slice(0, 100) + '_' + code;
|
|
|
|
}
|
|
|
|
|
2014-07-13 03:04:16 +04: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();
|