@predictive-text-studio/lexical-model-compiler
Version:
Keyman Developer lexical model compiler
153 lines • 5.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Log levels.
*
* Note: Currently, this acts like a bit set, where the upper 4 bits of an
* unsigned 16 bit value are the log level flags.
*/
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["CERR_FATAL"] = 32768] = "CERR_FATAL";
LogLevel[LogLevel["CERR_ERROR"] = 16384] = "CERR_ERROR";
LogLevel[LogLevel["CERR_WARNING"] = 8192] = "CERR_WARNING";
// Note: 0x01000 is a memory error, but that is never raised in TypeScript
LogLevel[LogLevel["CERR_INFO"] = 0] = "CERR_INFO";
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
;
/**
* Error codes. Use these when logging messages.
*
* Extends https://github.com/keymanapp/keyman/blob/99db3c0d2448f448242e6397f9d72e9a7ccee4b9/windows/src/global/inc/Comperr.h
*/
var KeymanCompilerError;
(function (KeymanCompilerError) {
KeymanCompilerError[KeymanCompilerError["CERR_LEXICAL_MODEL_MIN"] = 2048] = "CERR_LEXICAL_MODEL_MIN";
KeymanCompilerError[KeymanCompilerError["CERR_LEXICAL_MODEL_MAX"] = 2303] = "CERR_LEXICAL_MODEL_MAX";
KeymanCompilerError[KeymanCompilerError["CERR_FATAL_LM"] = 34816] = "CERR_FATAL_LM";
/* Place all fatal LM compiler errors here! */
KeymanCompilerError[KeymanCompilerError["CERR_ERROR_LM"] = 18432] = "CERR_ERROR_LM";
/* Place all recoverable LM compiler errors here! */
KeymanCompilerError[KeymanCompilerError["CERR_WARN_LM"] = 10240] = "CERR_WARN_LM";
/* Place all LM compiler warnings here! */
KeymanCompilerError[KeymanCompilerError["CWARN_MixedNormalizationForms"] = 10241] = "CWARN_MixedNormalizationForms";
KeymanCompilerError[KeymanCompilerError["CWARN_DuplicateWordInSameFile"] = 10242] = "CWARN_DuplicateWordInSameFile";
/* Errors that are not specific to the lexical model compiler: */
KeymanCompilerError[KeymanCompilerError["CWARN_TooManyErrorsOrWarnings"] = 8359] = "CWARN_TooManyErrorsOrWarnings";
})(KeymanCompilerError = exports.KeymanCompilerError || (exports.KeymanCompilerError = {}));
/**
* Human-readable titles for the various log levels.
*
* Taken from https://github.com/keymanapp/keyman/blob/d83cfffe511ce65b781f919e89e3693146844849/windows/src/developer/TIKE/project/Keyman.Developer.System.Project.ProjectLog.pas#L39-L46
*/
const LOG_LEVEL_TITLE = {
[LogLevel.CERR_INFO]: '',
[LogLevel.CERR_WARNING]: 'Warning',
[LogLevel.CERR_ERROR]: 'Error',
[LogLevel.CERR_FATAL]: 'Fatal Error',
};
/**
* How many errors or warnings are too many!
*/
exports.MAX_MESSAGES = 100;
/**
* Direct where log messages go.
*/
let _logHandler = printLogs;
/**
* How many logs or warnings have been witnessed so far.
*/
let _messagesSeen = 0;
/**
* Logs compiler messages (warnings, errors, logs).
*
* @param code Error code
* @param message A helpful message!
* @param source [optional] the filename/line number in the source that induced this error
*
* @see https://github.com/keymanapp/keyman/blob/99db3c0d2448f448242e6397f9d72e9a7ccee4b9/windows/src/developer/TIKE/project/Keyman.Developer.System.Project.ProjectLog.pas#L60-L77
*/
function log(code, message, source) {
// Ignore the request if there are too many messages
if (_messagesSeen > exports.MAX_MESSAGES)
return;
let logMessage = source
? new LogMessageFromSource(code, message, source)
: new OrdinaryLogMessage(code, message);
_logHandler(logMessage);
_messagesSeen++;
if (_messagesSeen > exports.MAX_MESSAGES) {
_logHandler(new OrdinaryLogMessage(KeymanCompilerError.CWARN_TooManyErrorsOrWarnings, `More than ${exports.MAX_MESSAGES} warnings or errors received; suppressing further messages`));
}
}
exports.log = log;
/**
* Override where log messages go.
*
* @param fn The desired log message handler.
*/
function redirectLogMessagesTo(fn) {
_logHandler = fn;
}
exports.redirectLogMessagesTo = redirectLogMessagesTo;
/**
* Reset the log message handler to the default.
*/
function resetLogMessageHandler() {
_logHandler = printLogs;
_messagesSeen = 0;
}
exports.resetLogMessageHandler = resetLogMessageHandler;
/**
* Prints log messages to stdout. The default log action.
*/
function printLogs(log) {
console.log(log.format());
}
exports.printLogs = printLogs;
/**
* Concrete implementation of the log message.
*/
class OrdinaryLogMessage {
constructor(code, message) {
this.code = code;
this.message = message;
}
get level() {
return this.code & 0xF000;
}
determineLogLevelTitle() {
return LOG_LEVEL_TITLE[this.level] || '';
}
format() {
let prefix = this.determineLogLevelTitle();
if (prefix)
prefix = `${prefix}: `;
return `${prefix}${h(this.code)} ${this.message}`;
}
}
/**
* A log message with a filename and line number.
*/
class LogMessageFromSource extends OrdinaryLogMessage {
constructor(code, message, source) {
super(code, message);
this.filename = source.filename;
this.lineno = source.lineno;
}
format() {
let originalMessage = super.format();
return `${this.filename} (${this.lineno}): ${originalMessage}`;
}
}
/**
* Format a number as a zero-padded 4 digit hexadecimal.
*/
function h(n) {
let formatted = n.toString(16).toUpperCase();
if (formatted.length < 4) {
formatted = '0'.repeat(4 - formatted.length);
}
return formatted;
}
//# sourceMappingURL=errors.js.map