Merge pull request #10867 from keymanapp/refactor/developer/10207-kmn-compiler-message-namespaces

refactor(developer): cleanup kmn compiler message namespaces
This commit is contained in:
Marc Durdin 2024-03-01 07:52:31 +07:00 committed by GitHub
commit 8e05592d41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 359 additions and 115 deletions

View file

@ -1,4 +1,5 @@
import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerEvent, CompilerMessageSpec as m } from "@keymanapp/common-types";
import { kmnfile } from "../kmw-compiler/compiler-globals.js";
const Namespace = CompilerErrorNamespace.KmnCompiler;
const SevInfo = CompilerErrorSeverity.Info | Namespace;
@ -7,6 +8,15 @@ const SevWarn = CompilerErrorSeverity.Warn | Namespace;
const SevError = CompilerErrorSeverity.Error | Namespace;
const SevFatal = CompilerErrorSeverity.Fatal | Namespace;
// For messages from the KeymanWeb compiler, we need to construct our messages
// slightly differently. This could be refactored in the future, as it is not
// obvious which messages should use which function.
const mw = (code: number, message: string, o?: {e?: any, filename?: string, line?: number}) : CompilerEvent => ({
...m(code, message, o?.e),
filename: o?.filename ?? kmnfile,
line: o?.line,
});
/**
* LogLevel comes from kmn_compiler_errors.h, for legacy compiler error messages
*/
@ -42,12 +52,33 @@ export const enum KmnCompilerMessageRanges {
/**
* @public
*
* Error messages reported by the .kmn compiler. The error codes in this class
* share an address space with messages from kmn_compiler_errors.h, which are
* generated by kmcmplib, so codes below 0x900 are reserved for kmcmplib
* messages.
*
* The second half of this class defines the messages from kmcmplib. These
* messages should correspond to codes in kmn_compiler_errors.h, exclusive
* severity bits. Message text is defined by kmcmplib and passed through a
* callback at this time. The message text presented here is currently unused
* during the compilation process, but is used in the `kmc messages` tool and
* for documentation.
*
* `CERR_` messages that are actually fatals have been renamed to `FATAL_`.
*
* @example
*
* ```
* kmcmplib.CERR_BadCallParams = CERR_FATAL | 0x002 = 0x8002
* ERROR_BadCallParams = SevError | 0x0002 = 0x300000 | 0x2000 | 0x002 = 0x302002
* ```
*/
export class CompilerMessages {
export class KmnCompilerMessages {
// TODO: v18.0 we should consider moving error message generation in kmcmplib to
// kmc-kmn, which would avoid a number of legacy issues. Questions about
// parameterisation.
/** @internal */
static Fatal_UnexpectedException = (o:{e: any}) => m(this.FATAL_UnexpectedException, null, o.e ?? 'unknown error');
/**
@ -182,226 +213,525 @@ export class CompilerMessages {
* to the file.
*/
static ERROR_FileNotFound = SevError | 0x90C;
};
/**
* @public
* This class defines messages from kmcmplib. They should correspond to codes in
* kmn_compiler_errors.h, exclusive severity bits. Message text is defined by
* kmcmplib and passed through a callback.
*
* @example
*
* ```
* kmcmplib.CERR_BadCallParams = CERR_FATAL | 0x002 = 0x8002
* ERROR_BadCallParams = SevError | 0x0002 = 0x300000 | 0x2000 | 0x002 = 0x302002
* ```
*
* `CERR_` messages that are actually fatals have been renamed to `FATAL_`.
*
*/
export class KmnCompilerMessages {
static INFO_None = SevInfo | 0x000;
// static INFO_None = SevInfo | 0x000;
static Info_EndOfFile = () => m(this.INFO_EndOfFile, `(no error - reserved code)`);
static INFO_EndOfFile = SevInfo | 0x001;
static Fatal_BadCallParams = () => m(this.FATAL_BadCallParams, `CompileKeyboardFile was called with bad parameters`);
static FATAL_BadCallParams = SevFatal | 0x002;
static Fatal_CannotAllocateMemory = () => m(this.FATAL_CannotAllocateMemory, `Out of memory`);
static FATAL_CannotAllocateMemory = SevFatal | 0x004;
static Error_InfileNotExist = () => m(this.ERROR_InfileNotExist, `Cannot find the input file`);
static ERROR_InfileNotExist = SevError | 0x005; // #10678: reduced from fatal to error in 17.0
// static Error_CannotCreateOutfile = () => m(this.ERROR_CannotCreateOutfile, `Cannot open output file for writing`); unused
// static ERROR_CannotCreateOutfile = SevError | 0x006; // #10678: reduced from fatal to error in 17.0, but unused
static Fatal_UnableToWriteFully = () => m(this.FATAL_UnableToWriteFully, `Unable to write the file completely`);
static FATAL_UnableToWriteFully = SevFatal | 0x007;
static Error_CannotReadInfile = () => m(this.ERROR_CannotReadInfile, `Cannot read the input file`);
static ERROR_CannotReadInfile = SevError | 0x008; // #10678: reduced from fatal to error in 17.0
static Fatal_SomewhereIGotItWrong = () => m(this.FATAL_SomewhereIGotItWrong, `Internal error: contact Keyman`);
static FATAL_SomewhereIGotItWrong = SevFatal | 0x009;
static Error_InvalidToken = () => m(this.ERROR_InvalidToken, `Invalid token found`);
static ERROR_InvalidToken = SevError | 0x00A;
// kmcmplib: static Error_InvalidBegin = () => m(this.ERROR_InvalidBegin, `Invalid 'begin' command`);
static Error_InvalidBegin = () => mw(this.ERROR_InvalidBegin,
`A "begin unicode" statement is required to compile a KeymanWeb keyboard`);
static ERROR_InvalidBegin = SevError | 0x00B;
static Error_InvalidName = () => m(this.ERROR_InvalidName, `Invalid 'name' command`);
static ERROR_InvalidName = SevError | 0x00C;
static Error_InvalidVersion = () => m(this.ERROR_InvalidVersion, `Invalid 'version' command`);
static ERROR_InvalidVersion = SevError | 0x00D;
static Error_InvalidLanguageLine = () => m(this.ERROR_InvalidLanguageLine, `Invalid 'language' command`);
static ERROR_InvalidLanguageLine = SevError | 0x00E;
static Error_LayoutButNoLanguage = () => m(this.ERROR_LayoutButNoLanguage, `Layout command found but no language command`);
static ERROR_LayoutButNoLanguage = SevError | 0x00F;
static Error_InvalidLayoutLine = () => m(this.ERROR_InvalidLayoutLine, `Invalid 'layout' command`);
static ERROR_InvalidLayoutLine = SevError | 0x010;
static Error_NoVersionLine = () => m(this.ERROR_NoVersionLine, `No version line found for file`);
static ERROR_NoVersionLine = SevError | 0x011;
static Error_InvalidGroupLine = () => m(this.ERROR_InvalidGroupLine, `Invalid 'group' command`);
static ERROR_InvalidGroupLine = SevError | 0x012;
static Error_InvalidStoreLine = () => m(this.ERROR_InvalidStoreLine, `Invalid 'store' command`);
static ERROR_InvalidStoreLine = SevError | 0x013;
static Error_InvalidCodeInKeyPartOfRule = () => m(this.ERROR_InvalidCodeInKeyPartOfRule, `Invalid command or code found in key part of rule`);
static ERROR_InvalidCodeInKeyPartOfRule = SevError | 0x014;
static Error_InvalidDeadkey = () => m(this.ERROR_InvalidDeadkey, `Invalid 'deadkey' or 'dk' command`);
static ERROR_InvalidDeadkey = SevError | 0x015;
static Error_InvalidValue = () => m(this.ERROR_InvalidValue, `Invalid value in extended string`);
static ERROR_InvalidValue = SevError | 0x016;
static Error_ZeroLengthString = () => m(this.ERROR_ZeroLengthString, `A string of zero characters was found`);
static ERROR_ZeroLengthString = SevError | 0x017;
static Error_TooManyIndexToKeyRefs = () => m(this.ERROR_TooManyIndexToKeyRefs, `Too many index commands refering to key string`);
static ERROR_TooManyIndexToKeyRefs = SevError | 0x018;
static Error_UnterminatedString = () => m(this.ERROR_UnterminatedString, `Unterminated string in line`);
static ERROR_UnterminatedString = SevError | 0x019;
static Error_StringInVirtualKeySection = () => m(this.ERROR_StringInVirtualKeySection, `extend string illegal in virtual key section`);
static ERROR_StringInVirtualKeySection = SevError | 0x01A;
static Error_AnyInVirtualKeySection = () => m(this.ERROR_AnyInVirtualKeySection, `'any' command is illegal in virtual key section`);
static ERROR_AnyInVirtualKeySection = SevError | 0x01B;
static Error_InvalidAny = () => m(this.ERROR_InvalidAny, `Invalid 'any' command`);
static ERROR_InvalidAny = SevError | 0x01C;
static Error_StoreDoesNotExist = () => m(this.ERROR_StoreDoesNotExist, `Store referenced does not exist`);
static ERROR_StoreDoesNotExist = SevError | 0x01D;
static Error_BeepInVirtualKeySection = () => m(this.ERROR_BeepInVirtualKeySection, `'beep' command is illegal in virtual key section`);
static ERROR_BeepInVirtualKeySection = SevError | 0x01E;
static Error_IndexInVirtualKeySection = () => m(this.ERROR_IndexInVirtualKeySection, `'index' command is illegal in virtual key section`);
static ERROR_IndexInVirtualKeySection = SevError | 0x01F;
static Error_InvalidIndex = () => m(this.ERROR_InvalidIndex, `Invalid 'index' command`);
static ERROR_InvalidIndex = SevError | 0x020;
static Error_OutsInVirtualKeySection = () => m(this.ERROR_OutsInVirtualKeySection, `'outs' command is illegal in virtual key section`);
static ERROR_OutsInVirtualKeySection = SevError | 0x021;
static Error_InvalidOuts = () => m(this.ERROR_InvalidOuts, `Invalid 'outs' command`);
static ERROR_InvalidOuts = SevError | 0x022;
static Error_ContextInVirtualKeySection = () => m(this.ERROR_ContextInVirtualKeySection, `'context' command is illegal in virtual key section`);
static ERROR_ContextInVirtualKeySection = SevError | 0x024;
static Error_InvalidUse = () => m(this.ERROR_InvalidUse, `Invalid 'use' command`);
static ERROR_InvalidUse = SevError | 0x025;
static Error_GroupDoesNotExist = () => m(this.ERROR_GroupDoesNotExist, `Group does not exist`);
static ERROR_GroupDoesNotExist = SevError | 0x026;
static Error_VirtualKeyNotAllowedHere = () => m(this.ERROR_VirtualKeyNotAllowedHere, `Virtual key is not allowed here`);
static ERROR_VirtualKeyNotAllowedHere = SevError | 0x027;
static Error_InvalidSwitch = () => m(this.ERROR_InvalidSwitch, `Invalid 'switch' command`);
static ERROR_InvalidSwitch = SevError | 0x028;
static Error_NoTokensFound = () => m(this.ERROR_NoTokensFound, `No tokens found in line`);
static ERROR_NoTokensFound = SevError | 0x029;
static Error_InvalidLineContinuation = () => m(this.ERROR_InvalidLineContinuation, `Invalid line continuation`);
static ERROR_InvalidLineContinuation = SevError | 0x02A;
static Error_LineTooLong = () => m(this.ERROR_LineTooLong, `Line too long`);
static ERROR_LineTooLong = SevError | 0x02B;
static Error_InvalidCopyright = () => m(this.ERROR_InvalidCopyright, `Invalid 'copyright' command`);
static ERROR_InvalidCopyright = SevError | 0x02C;
static Error_CodeInvalidInThisSection = () => m(this.ERROR_CodeInvalidInThisSection, `This line is invalid in this section of the file`);
static ERROR_CodeInvalidInThisSection = SevError | 0x02D;
static Error_InvalidMessage = () => m(this.ERROR_InvalidMessage, `Invalid 'message' command`);
static ERROR_InvalidMessage = SevError | 0x02E;
static Error_InvalidLanguageName = () => m(this.ERROR_InvalidLanguageName, `Invalid 'languagename' command`);
static ERROR_InvalidLanguageName = SevError | 0x02F;
static Error_InvalidBitmapLine = () => m(this.ERROR_InvalidBitmapLine, `Invalid 'bitmaps' command`);
static ERROR_InvalidBitmapLine = SevError | 0x030;
static Error_CannotReadBitmapFile = () => m(this.ERROR_CannotReadBitmapFile, `Cannot open the bitmap or icon file for reading`);
static ERROR_CannotReadBitmapFile = SevError | 0x031;
static Error_IndexDoesNotPointToAny = () => m(this.ERROR_IndexDoesNotPointToAny, `An index() in the output does not have a corresponding any() statement`);
static ERROR_IndexDoesNotPointToAny = SevError | 0x032;
static Error_ReservedCharacter = () => m(this.ERROR_ReservedCharacter, `A reserved character was found`);
static ERROR_ReservedCharacter = SevError | 0x033;
static Error_InvalidCharacter = () => m(this.ERROR_InvalidCharacter, `A character was found that is outside the valid Unicode range (U+0000 - U+10FFFF)`);
static ERROR_InvalidCharacter = SevError | 0x034;
static Error_InvalidCall = () => m(this.ERROR_InvalidCall, `The 'call' command is invalid`);
static ERROR_InvalidCall = SevError | 0x035;
static Error_CallInVirtualKeySection = () => m(this.ERROR_CallInVirtualKeySection, `'call' command is illegal in virtual key section`);
static ERROR_CallInVirtualKeySection = SevError | 0x036;
static Error_CodeInvalidInKeyStore = () => m(this.ERROR_CodeInvalidInKeyStore, `The command is invalid inside a store that is used in a key part of the rule`);
static ERROR_CodeInvalidInKeyStore = SevError | 0x037;
static Error_CannotLoadIncludeFile = () => m(this.ERROR_CannotLoadIncludeFile, `Cannot load the included file: it is either invalid or does not exist`);
static ERROR_CannotLoadIncludeFile = SevError | 0x038;
static Error_60FeatureOnly_EthnologueCode = () => m(this.ERROR_60FeatureOnly_EthnologueCode, `EthnologueCode system store requires VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_EthnologueCode = SevError | 0x039;
static Error_60FeatureOnly_MnemonicLayout = () => m(this.ERROR_60FeatureOnly_MnemonicLayout, `MnemonicLayout functionality requires VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_MnemonicLayout = SevError | 0x03A;
static Error_60FeatureOnly_OldCharPosMatching = () => m(this.ERROR_60FeatureOnly_OldCharPosMatching, `OldCharPosMatching system store requires VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_OldCharPosMatching = SevError | 0x03B;
static Error_60FeatureOnly_NamedCodes = () => m(this.ERROR_60FeatureOnly_NamedCodes, `Named character constants requires VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_NamedCodes = SevError | 0x03C;
static Error_60FeatureOnly_Contextn = () => m(this.ERROR_60FeatureOnly_Contextn, `Context(n) requires VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_Contextn = SevError | 0x03D;
static Error_501FeatureOnly_Call = () => m(this.ERROR_501FeatureOnly_Call, `Call() requires VERSION 5.01 or higher`);
static ERROR_501FeatureOnly_Call = SevError | 0x03E;
static Error_InvalidNamedCode = () => m(this.ERROR_InvalidNamedCode, `Invalid named code constant`);
static ERROR_InvalidNamedCode = SevError | 0x03F;
static Error_InvalidSystemStore = () => m(this.ERROR_InvalidSystemStore, `Invalid system store name found`);
static ERROR_InvalidSystemStore = SevError | 0x040;
static Error_60FeatureOnly_VirtualCharKey = () => m(this.ERROR_60FeatureOnly_VirtualCharKey, `Virtual character keys require VERSION 6.0 or higher`);
static ERROR_60FeatureOnly_VirtualCharKey = SevError | 0x044;
static Error_VersionAlreadyIncluded = () => m(this.ERROR_VersionAlreadyIncluded, `Only one VERSION or store(version) line allowed in a source file.`);
static ERROR_VersionAlreadyIncluded = SevError | 0x045;
static Error_70FeatureOnly = () => m(this.ERROR_70FeatureOnly, `This feature requires store(version) '7.0' or higher`);
static ERROR_70FeatureOnly = SevError | 0x046;
static Error_80FeatureOnly = () => m(this.ERROR_80FeatureOnly, `This feature requires store(version) '8.0' or higher`);
static ERROR_80FeatureOnly = SevError | 0x047;
static Error_InvalidInVirtualKeySection = () => m(this.ERROR_InvalidInVirtualKeySection, `This statement is not valid in a virtual key section`);
static ERROR_InvalidInVirtualKeySection = SevError | 0x048;
static Error_InvalidIf = () => m(this.ERROR_InvalidIf, `The if() statement is not valid`);
static ERROR_InvalidIf = SevError | 0x049;
static Error_InvalidReset = () => m(this.ERROR_InvalidReset, `The reset() statement is not valid`);
static ERROR_InvalidReset = SevError | 0x04A;
static Error_InvalidSet = () => m(this.ERROR_InvalidSet, `The set() statement is not valid`);
static ERROR_InvalidSet = SevError | 0x04B;
static Error_InvalidSave = () => m(this.ERROR_InvalidSave, `The save() statement is not valid`);
static ERROR_InvalidSave = SevError | 0x04C;
static Error_InvalidEthnologueCode = () => m(this.ERROR_InvalidEthnologueCode, `Invalid ethnologuecode format`);
static ERROR_InvalidEthnologueCode = SevError | 0x04D;
static Fatal_CannotCreateTempfile = () => m(this.FATAL_CannotCreateTempfile, `Cannot create temp file`);
static FATAL_CannotCreateTempfile = SevFatal | 0x04E;
static Error_90FeatureOnly_IfSystemStores = () => m(this.ERROR_90FeatureOnly_IfSystemStores, `if(store) requires store(version) '9.0' or higher`);
static ERROR_90FeatureOnly_IfSystemStores = SevError | 0x04F;
static Error_IfSystemStore_NotFound = () => m(this.ERROR_IfSystemStore_NotFound, `System store in if() not found`);
static ERROR_IfSystemStore_NotFound = SevError | 0x050;
static Error_90FeatureOnly_SetSystemStores = () => m(this.ERROR_90FeatureOnly_SetSystemStores, `set(store) requires store(version) '9.0' or higher`);
static ERROR_90FeatureOnly_SetSystemStores = SevError | 0x051;
static Error_SetSystemStore_NotFound = () => m(this.ERROR_SetSystemStore_NotFound, `System store in set() not found`);
static ERROR_SetSystemStore_NotFound = SevError | 0x052;
static Error_90FeatureOnlyVirtualKeyDictionary = () => m(this.ERROR_90FeatureOnlyVirtualKeyDictionary, `Custom virtual key names require store(version) '9.0'`);
static ERROR_90FeatureOnlyVirtualKeyDictionary = SevError | 0x053;
static Error_NotSupportedInKeymanWebContext = (o:{line:number, code:String}) => mw(this.ERROR_NotSupportedInKeymanWebContext,
`Statement '${o.code}' is not currently supported in context for web and touch targets`, o);
static ERROR_NotSupportedInKeymanWebContext = SevError | 0x054;
static Error_NotSupportedInKeymanWebOutput = (o:{line:number, code:string}) => mw(this.ERROR_NotSupportedInKeymanWebOutput,
`Statement '${o.code}' is not currently supported in output for web and touch targets`, o);
static ERROR_NotSupportedInKeymanWebOutput = SevError | 0x055;
static Error_NotSupportedInKeymanWebStore = (o:{code:string,store:string}) => mw(this.ERROR_NotSupportedInKeymanWebStore,
`'${o.code}' is not currently supported in store '${o.store}' when used by any or index for web and touch targets`);
static ERROR_NotSupportedInKeymanWebStore = SevError | 0x056;
static Error_VirtualCharacterKeysNotSupportedInKeymanWeb = (o:{line:number}) => mw(this.ERROR_VirtualCharacterKeysNotSupportedInKeymanWeb,
`Virtual character keys not currently supported in KeymanWeb`, o);
static ERROR_VirtualCharacterKeysNotSupportedInKeymanWeb = SevError | 0x057;
static Error_VirtualKeysNotValidForMnemonicLayouts = (o:{line:number}) => mw(this.ERROR_VirtualKeysNotValidForMnemonicLayouts,
`Virtual keys are not valid for mnemonic layouts`, o);
static ERROR_VirtualKeysNotValidForMnemonicLayouts = SevError | 0x058;
static Error_InvalidTouchLayoutFile = (o:{filename:string}) => mw(this.ERROR_InvalidTouchLayoutFile,
`Touch layout file ${o.filename} is not valid`);
static ERROR_InvalidTouchLayoutFile = SevError | 0x059;
static Error_TouchLayoutInvalidIdentifier = (o:{keyId:string, platformName: string, layerId:string}) => mw(this.ERROR_TouchLayoutInvalidIdentifier,
`Key "${o.keyId}" on "${o.platformName}", layer "${o.layerId}" has an invalid identifier.`);
static ERROR_TouchLayoutInvalidIdentifier = SevError | 0x05A;
static Error_InvalidKeyCode = (o:{keyId: string}) => mw(this.ERROR_InvalidKeyCode,
`Invalid key identifier "${o.keyId}"`);
static ERROR_InvalidKeyCode = SevError | 0x05B;
static Error_90FeatureOnlyLayoutFile = () => m(this.ERROR_90FeatureOnlyLayoutFile, `Touch layout file reference requires store(version) '9.0'or higher`);
static ERROR_90FeatureOnlyLayoutFile = SevError | 0x05C;
static Error_90FeatureOnlyKeyboardVersion = () => m(this.ERROR_90FeatureOnlyKeyboardVersion, `KeyboardVersion system store requires store(version) '9.0'or higher`);
static ERROR_90FeatureOnlyKeyboardVersion = SevError | 0x05D;
static Error_KeyboardVersionFormatInvalid = () => m(this.ERROR_KeyboardVersionFormatInvalid, `KeyboardVersion format is invalid, expecting dot-separated integers`);
static ERROR_KeyboardVersionFormatInvalid = SevError | 0x05E;
static Error_ContextExHasInvalidOffset = () => m(this.ERROR_ContextExHasInvalidOffset, `context() statement has offset out of range`);
static ERROR_ContextExHasInvalidOffset = SevError | 0x05F;
static Error_90FeatureOnlyEmbedCSS = () => m(this.ERROR_90FeatureOnlyEmbedCSS, `Embedding CSS requires store(version) '9.0'or higher`);
static ERROR_90FeatureOnlyEmbedCSS = SevError | 0x060;
static Error_90FeatureOnlyTargets = () => m(this.ERROR_90FeatureOnlyTargets, `TARGETS system store requires store(version) '9.0'or higher`);
static ERROR_90FeatureOnlyTargets = SevError | 0x061;
static Error_ContextAndIndexInvalidInMatchNomatch = () => m(this.ERROR_ContextAndIndexInvalidInMatchNomatch, `context and index statements cannot be used in a match or nomatch statement`);
static ERROR_ContextAndIndexInvalidInMatchNomatch = SevError | 0x062;
static Error_140FeatureOnlyContextAndNotAnyWeb = () => m(this.ERROR_140FeatureOnlyContextAndNotAnyWeb, `For web and touch platforms, context() statement referring to notany() requires store(version) '14.0'or higher`);
static ERROR_140FeatureOnlyContextAndNotAnyWeb = SevError | 0x063;
static Error_ExpansionMustFollowCharacterOrVKey = () => m(this.ERROR_ExpansionMustFollowCharacterOrVKey, `An expansion must follow a character or a virtual key`);
static ERROR_ExpansionMustFollowCharacterOrVKey = SevError | 0x064;
static Error_VKeyExpansionMustBeFollowedByVKey = () => m(this.ERROR_VKeyExpansionMustBeFollowedByVKey, `A virtual key expansion must be terminated by a virtual key`);
static ERROR_VKeyExpansionMustBeFollowedByVKey = SevError | 0x065;
static Error_CharacterExpansionMustBeFollowedByCharacter = () => m(this.ERROR_CharacterExpansionMustBeFollowedByCharacter, `A character expansion must be terminated by a character key`);
static ERROR_CharacterExpansionMustBeFollowedByCharacter = SevError | 0x066;
static Error_VKeyExpansionMustUseConsistentShift = () => m(this.ERROR_VKeyExpansionMustUseConsistentShift, `A virtual key expansion must use the same shift state for both terminators`);
static ERROR_VKeyExpansionMustUseConsistentShift = SevError | 0x067;
static Error_ExpansionMustBePositive = () => m(this.ERROR_ExpansionMustBePositive, `An expansion must have positive difference (i.e. A-Z, not Z-A)`);
static ERROR_ExpansionMustBePositive = SevError | 0x068;
static Error_CasedKeysMustContainOnlyVirtualKeys = () => m(this.ERROR_CasedKeysMustContainOnlyVirtualKeys, `The &CasedKeys system store must contain only virtual keys or characters found on a US English keyboard`);
static ERROR_CasedKeysMustContainOnlyVirtualKeys = SevError | 0x069;
static Error_CasedKeysMustNotIncludeShiftStates = () => m(this.ERROR_CasedKeysMustNotIncludeShiftStates, `The &CasedKeys system store must not include shift states`);
static ERROR_CasedKeysMustNotIncludeShiftStates = SevError | 0x06A;
static Error_CasedKeysNotSupportedWithMnemonicLayout = () => m(this.ERROR_CasedKeysNotSupportedWithMnemonicLayout, `The &CasedKeys system store is not supported with mnemonic layouts`);
static ERROR_CasedKeysNotSupportedWithMnemonicLayout = SevError | 0x06B;
static Error_CannotUseReadWriteGroupFromReadonlyGroup = () => m(this.ERROR_CannotUseReadWriteGroupFromReadonlyGroup, `Group used from a readonly group must also be readonly`);
static ERROR_CannotUseReadWriteGroupFromReadonlyGroup = SevError | 0x06C;
static Error_StatementNotPermittedInReadonlyGroup = () => m(this.ERROR_StatementNotPermittedInReadonlyGroup, `Statement is not permitted in output of readonly group`);
static ERROR_StatementNotPermittedInReadonlyGroup = SevError | 0x06D;
static Error_OutputInReadonlyGroup = () => m(this.ERROR_OutputInReadonlyGroup, `Output is not permitted in a readonly group`);
static ERROR_OutputInReadonlyGroup = SevError | 0x06E;
static Error_NewContextGroupMustBeReadonly = () => m(this.ERROR_NewContextGroupMustBeReadonly, `Group used in begin newContext must be readonly`);
static ERROR_NewContextGroupMustBeReadonly = SevError | 0x06F;
static Error_PostKeystrokeGroupMustBeReadonly = () => m(this.ERROR_PostKeystrokeGroupMustBeReadonly, `Group used in begin postKeystroke must be readonly`);
static ERROR_PostKeystrokeGroupMustBeReadonly = SevError | 0x070;
static Error_DuplicateGroup = () => m(this.ERROR_DuplicateGroup, `A group with this name has already been defined.`);
static ERROR_DuplicateGroup = SevError | 0x071;
static Error_DuplicateStore = () => m(this.ERROR_DuplicateStore, `A store with this name has already been defined.`);
static ERROR_DuplicateStore = SevError | 0x072;
static Error_RepeatedBegin = () => m(this.ERROR_RepeatedBegin, `Begin has already been set`);
static ERROR_RepeatedBegin = SevError | 0x073;
static Error_VirtualKeyInContext = () => m(this.ERROR_VirtualKeyInContext, `Virtual keys are not permitted in context`);
static ERROR_VirtualKeyInContext = SevError | 0x074;
static Warn_TooManyWarnings = () => m(this.WARN_TooManyWarnings, `Too many warnings or errors`);
static WARN_TooManyWarnings = SevWarn | 0x080;
static Warn_OldVersion = () => m(this.WARN_OldVersion, `The keyboard file is an old version`);
static WARN_OldVersion = SevWarn | 0x081;
static Warn_BitmapNotUsed = () => m(this.WARN_BitmapNotUsed, `The 'bitmaps' statement is obsolete and only the first bitmap referred to will be used, you should use 'bitmap'.`);
static WARN_BitmapNotUsed = SevWarn | 0x082;
static Warn_CustomLanguagesNotSupported = () => m(this.WARN_CustomLanguagesNotSupported, `Languages over 0x1FF, 0x1F are not supported correctly by Windows. You should use no LANGUAGE line instead.`);
static WARN_CustomLanguagesNotSupported = SevWarn | 0x083;
static Warn_KeyBadLength = () => m(this.WARN_KeyBadLength, `There are too many characters in the keystroke part of the rule.`);
static WARN_KeyBadLength = SevWarn | 0x084;
static Warn_IndexStoreShort = () => m(this.WARN_IndexStoreShort, `The store referenced in index() is shorter than the store referenced in any()`);
static WARN_IndexStoreShort = SevWarn | 0x085;
static Warn_UnicodeInANSIGroup = () => m(this.WARN_UnicodeInANSIGroup, `A Unicode character was found in an ANSI group`);
static WARN_UnicodeInANSIGroup = SevWarn | 0x086;
static Warn_ANSIInUnicodeGroup = () => m(this.WARN_ANSIInUnicodeGroup, `An ANSI character was found in a Unicode group`);
static WARN_ANSIInUnicodeGroup = SevWarn | 0x087;
static Warn_UnicodeSurrogateUsed = () => m(this.WARN_UnicodeSurrogateUsed, `A Unicode surrogate character was found. You should use Unicode scalar values to represent values > U+FFFF`);
static WARN_UnicodeSurrogateUsed = SevWarn | 0x088;
static Warn_ReservedCharacter = () => m(this.WARN_ReservedCharacter, `A Unicode character was found that should not be used`);
static WARN_ReservedCharacter = SevWarn | 0x089;
// Note: INFO_Info is called CWARN_Info in kmn_compiler_errors.h, but should have an "info" severity
static Info_Info = () => m(this.INFO_Info, `Information`);
static INFO_Info = SevInfo | 0x08A;
static Warn_VirtualKeyWithMnemonicLayout = () => m(this.WARN_VirtualKeyWithMnemonicLayout, `Virtual key used instead of virtual character key with a mnemonic layout`);
static WARN_VirtualKeyWithMnemonicLayout = SevWarn | 0x08B;
static Warn_VirtualCharKeyWithPositionalLayout = () => m(this.WARN_VirtualCharKeyWithPositionalLayout, `Virtual character key used with a positional layout instead of mnemonic layout`);
static WARN_VirtualCharKeyWithPositionalLayout = SevWarn | 0x08C;
static Warn_StoreAlreadyUsedAsOptionOrCall = () => m(this.WARN_StoreAlreadyUsedAsOptionOrCall, `Store already used as an option or in a call statement and should not be used as a normal store`);
static WARN_StoreAlreadyUsedAsOptionOrCall = SevWarn | 0x08D;
static Warn_StoreAlreadyUsedAsStoreOrCall = () => m(this.WARN_StoreAlreadyUsedAsStoreOrCall, `Store already used as a normal store or in a call statement and should not be used as an option`);
static WARN_StoreAlreadyUsedAsStoreOrCall = SevWarn | 0x08E;
static Warn_StoreAlreadyUsedAsStoreOrOption = () => m(this.WARN_StoreAlreadyUsedAsStoreOrOption, `Store already used as a normal store or as an option and should not be used in a call statement`);
static WARN_StoreAlreadyUsedAsStoreOrOption = SevWarn | 0x08F;
static Warn_PunctuationInEthnologueCode = () => m(this.WARN_PunctuationInEthnologueCode, `Punctuation should not be used to separate Ethnologue codes; instead use spaces`);
static WARN_PunctuationInEthnologueCode = SevWarn | 0x090;
static Warn_TouchLayoutMissingLayer = (o:{keyId:string, platformName:string, layerId:string, nextLayer:string}) => mw(this.WARN_TouchLayoutMissingLayer,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", references a missing layer "${o.nextLayer}"`);
static WARN_TouchLayoutMissingLayer = SevWarn | 0x091;
static Warn_TouchLayoutCustomKeyNotDefined = (o:{keyId:string, platformName:string, layerId:string}) => mw(this.WARN_TouchLayoutCustomKeyNotDefined,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", is a custom key but has no corresponding rule in the source.`);
static WARN_TouchLayoutCustomKeyNotDefined = SevWarn | 0x092;
static Warn_TouchLayoutMissingRequiredKeys = (o:{layerId:string, platformName:string, missingKeys:string}) => mw(this.WARN_TouchLayoutMissingRequiredKeys,
`Layer "${o.layerId}" on platform "${o.platformName}" is missing the required key(s) '${o.missingKeys}'.`);
static WARN_TouchLayoutMissingRequiredKeys = SevWarn | 0x093;
static Warn_HelpFileMissing = (o:{line:number, helpFilename:string, e:any}) => mw(this.WARN_HelpFileMissing,
`File ${o.helpFilename} could not be loaded: ${(o.e??'').toString()}`,o);
static WARN_HelpFileMissing = SevWarn | 0x094;
static Warn_EmbedJsFileMissing = (o:{line:number, jsFilename: string, e:any}) => mw(this.WARN_EmbedJsFileMissing,
`File ${o.jsFilename} could not be loaded: ${(o.e??'').toString()}`, o);
static WARN_EmbedJsFileMissing = SevWarn | 0x095;
static WARN_TouchLayoutFileMissing = SevWarn | 0x096;
static WARN_VisualKeyboardFileMissing = SevWarn | 0x097;
// static WARN_TouchLayoutFileMissing = SevWarn | 0x096;
// static WARN_VisualKeyboardFileMissing = SevWarn | 0x097;
static Warn_ExtendedShiftFlagsNotSupportedInKeymanWeb = (o:{line:number,flags:string}) => mw(this.WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb,
`Extended shift flags ${o.flags} are not supported in KeymanWeb`, o);
static WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb = SevWarn | 0x098;
static Warn_TouchLayoutUnidentifiedKey = (o:{layerId:string}) => mw(this.WARN_TouchLayoutUnidentifiedKey,
`A key on layer "${o.layerId}" has no identifier.`);
static WARN_TouchLayoutUnidentifiedKey = SevWarn | 0x099;
static Hint_UnreachableKeyCode = (o:{line:number,key:string}) => mw(this.HINT_UnreachableKeyCode,
`The rule will never be matched for key ${o.key} because its key code is never fired.`, o);
static HINT_UnreachableKeyCode = SevHint | 0x09A;
static WARN_CouldNotCopyJsonFile = SevWarn | 0x09B;
// static WARN_CouldNotCopyJsonFile = SevWarn | 0x09B;
static Warn_PlatformNotInTargets = () => m(this.WARN_PlatformNotInTargets, `The specified platform is not a target platform`);
static WARN_PlatformNotInTargets = SevWarn | 0x09C;
static Warn_HeaderStatementIsDeprecated = () => m(this.WARN_HeaderStatementIsDeprecated, `Header statements are deprecated; use instead the equivalent system store`);
static WARN_HeaderStatementIsDeprecated = SevWarn | 0x09D;
static Warn_UseNotLastStatementInRule = () => m(this.WARN_UseNotLastStatementInRule, `A rule with use() statements in the output should not have other content following the use() statements`);
static WARN_UseNotLastStatementInRule = SevWarn | 0x09E;
static Warn_TouchLayoutFontShouldBeSameForAllPlatforms = () => mw(this.WARN_TouchLayoutFontShouldBeSameForAllPlatforms,
`The touch layout font should be the same for all platforms.`);
static WARN_TouchLayoutFontShouldBeSameForAllPlatforms = SevWarn | 0x09F;
static WARN_InvalidJSONMetadataFile = SevWarn | 0x0A0;
static WARN_JSONMetadataOSKFontShouldMatchTouchFont = SevWarn | 0x0A1;
// static WARN_InvalidJSONMetadataFile = SevWarn | 0x0A0;
// static WARN_JSONMetadataOSKFontShouldMatchTouchFont = SevWarn | 0x0A1;
static Warn_KVKFileIsInSourceFormat = () => m(this.WARN_KVKFileIsInSourceFormat, `.kvk file should be binary but is an XML file`);
static WARN_KVKFileIsInSourceFormat = SevWarn | 0x0A2;
// kmcmplib: static Warn_DontMixChiralAndNonChiralModifiers = () => m(this.WARN_DontMixChiralAndNonChiralModifiers, `Don't mix the use of left/right modifiers with non-left/right modifiers in the same platform`);
static Warn_DontMixChiralAndNonChiralModifiers = () => mw(this.WARN_DontMixChiralAndNonChiralModifiers,
`This keyboard contains Ctrl,Alt and LCtrl,LAlt,RCtrl,RAlt sets of modifiers. Use only one or the other set for web target.`);
static WARN_DontMixChiralAndNonChiralModifiers = SevWarn | 0x0A3;
static Warn_MixingLeftAndRightModifiers = () => m(this.WARN_MixingLeftAndRightModifiers, `Left and right modifiers should not both be used in the same rule`);
static WARN_MixingLeftAndRightModifiers = SevWarn | 0x0A4;
static Warn_LanguageHeadersDeprecatedInKeyman10 = () => m(this.WARN_LanguageHeadersDeprecatedInKeyman10, `This language header has been deprecated in Keyman 10. Instead, add language metadata in the package file`);
static WARN_LanguageHeadersDeprecatedInKeyman10 = SevWarn | 0x0A5;
static Hint_NonUnicodeFile = () => m(this.HINT_NonUnicodeFile, `Keyman Developer has detected that the file has ANSI encoding. Consider converting this file to UTF-8`);
static HINT_NonUnicodeFile = SevHint | 0x0A6;
static WARN_TooManyErrorsOrWarnings = SevWarn | 0x0A7;
// static WARN_TooManyErrorsOrWarnings = SevWarn | 0x0A7;
static Warn_HotkeyHasInvalidModifier = () => m(this.WARN_HotkeyHasInvalidModifier, `Hotkey has modifiers that are not supported. Use only SHIFT, CTRL and ALT`);
static WARN_HotkeyHasInvalidModifier = SevWarn | 0x0A8;
static Warn_TouchLayoutSpecialLabelOnNormalKey = (o:{keyId:string, platformName:string, layerId:string, label:string}) =>
mw(this.WARN_TouchLayoutSpecialLabelOnNormalKey,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}" does not have `+
`the key type "Special" or "Special (active)" but has the label "${o.label}". This feature is only supported in Keyman 14 or later`);
static WARN_TouchLayoutSpecialLabelOnNormalKey = SevWarn | 0x0A9;
static Warn_OptionStoreNameInvalid = (o:{name:string}) => mw(this.WARN_OptionStoreNameInvalid,
`The option store ${o.name} should be named with characters in the range A-Z, a-z, 0-9 and _ only.`);
static WARN_OptionStoreNameInvalid = SevWarn | 0x0AA;
static Warn_NulNotFirstStatementInContext = () => m(this.WARN_NulNotFirstStatementInContext, `nul must be the first statement in the context`);
static WARN_NulNotFirstStatementInContext = SevWarn | 0x0AB;
static Warn_IfShouldBeAtStartOfContext = () => m(this.WARN_IfShouldBeAtStartOfContext, `if, platform and baselayout should be at start of context (after nul, if present)`);
static WARN_IfShouldBeAtStartOfContext = SevWarn | 0x0AC;
static Warn_KeyShouldIncludeNCaps = () => m(this.WARN_KeyShouldIncludeNCaps, `Other rules which reference this key include CAPS or NCAPS modifiers, so this rule must include NCAPS modifier to avoid inconsistent matches`);
static WARN_KeyShouldIncludeNCaps = SevWarn | 0x0AD;
static Hint_UnreachableRule = () => m(this.HINT_UnreachableRule, `This rule will never be matched as another rule takes precedence`);
static HINT_UnreachableRule = SevHint | 0x0AE;
static Warn_VirtualKeyInOutput = () => m(this.WARN_VirtualKeyInOutput, `Virtual keys are not supported in output`);
static WARN_VirtualKeyInOutput = SevWarn | 0x0AF;
static Fatal_BufferOverflow = () => m(this.FATAL_BufferOverflow, `The compiler memory buffer overflowed`);
static FATAL_BufferOverflow = SevFatal | 0x0C0;
static Fatal_Break = () => m(this.FATAL_Break, `Compiler interrupted by user`);
static FATAL_Break = SevFatal | 0x0C1;
};
/**
* @internal
* TODO: This class is here as a stopgap as we merged it with
* KmnCompilerMessages. It should be removed in v18.0.
*/
export class CompilerMessages extends KmnCompilerMessages {
}
export function mapErrorFromKmcmplib(line: number, code: number, msg: string): CompilerEvent {
const severity = LogLevelToSeverity[code & LogLevel.LEVEL_MASK];
const baseCode = code & LogLevel.CODE_MASK;

View file

@ -28,92 +28,6 @@ export class KmwCompilerMessages extends KmnCompilerMessages {
// the splitting of all KMW-specific error messages out of the
// KmnCompilerMessages space.
/** @internal */
static Error_InvalidBegin = () => m(this.ERROR_InvalidBegin,
`A "begin unicode" statement is required to compile a KeymanWeb keyboard`);
/** @internal */
static Error_InvalidTouchLayoutFile = (o:{filename:string}) => m(this.ERROR_InvalidTouchLayoutFile,
`Touch layout file ${o.filename} is not valid`);
/** @internal */
static Warn_DontMixChiralAndNonChiralModifiers = () => m(this.WARN_DontMixChiralAndNonChiralModifiers,
`This keyboard contains Ctrl,Alt and LCtrl,LAlt,RCtrl,RAlt sets of modifiers. Use only one or the other set for web target.`);
/** @internal */
static Warn_OptionStoreNameInvalid = (o:{name:string}) => m(this.WARN_OptionStoreNameInvalid,
`The option store ${o.name} should be named with characters in the range A-Z, a-z, 0-9 and _ only.`);
/** @internal */
static Error_VirtualCharacterKeysNotSupportedInKeymanWeb = (o:{line:number}) => m(this.ERROR_VirtualCharacterKeysNotSupportedInKeymanWeb,
`Virtual character keys not currently supported in KeymanWeb`, o);
/** @internal */
static Error_VirtualKeysNotValidForMnemonicLayouts = (o:{line:number}) => m(this.ERROR_VirtualKeysNotValidForMnemonicLayouts,
`Virtual keys are not valid for mnemonic layouts`, o);
/** @internal */
static Warn_ExtendedShiftFlagsNotSupportedInKeymanWeb = (o:{line:number,flags:string}) => m(this.WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb,
`Extended shift flags ${o.flags} are not supported in KeymanWeb`, o);
/** @internal */
static Hint_UnreachableKeyCode = (o:{line:number,key:string}) => m(this.HINT_UnreachableKeyCode,
`The rule will never be matched for key ${o.key} because its key code is never fired.`, o);
/** @internal */
static Error_NotSupportedInKeymanWebStore = (o:{code:string,store:string}) => m(this.ERROR_NotSupportedInKeymanWebStore,
`'${o.code}' is not currently supported in store '${o.store}' when used by any or index for web and touch targets`);
/** @internal */
static Error_NotSupportedInKeymanWebContext = (o:{line:number, code:String}) => m(this.ERROR_NotSupportedInKeymanWebContext,
`Statement '${o.code}' is not currently supported in context for web and touch targets`, o);
/** @internal */
static Error_NotSupportedInKeymanWebOutput = (o:{line:number, code:string}) => m(this.ERROR_NotSupportedInKeymanWebOutput,
`Statement '${o.code}' is not currently supported in output for web and touch targets`, o);
/** @internal */
static Warn_HelpFileMissing = (o:{line:number, helpFilename:string, e:any}) => m(this.WARN_HelpFileMissing,
`File ${o.helpFilename} could not be loaded: ${(o.e??'').toString()}`,o);
/** @internal */
static Warn_EmbedJsFileMissing = (o:{line:number, jsFilename: string, e:any}) => m(this.WARN_EmbedJsFileMissing,
`File ${o.jsFilename} could not be loaded: ${(o.e??'').toString()}`, o);
/** @internal */
static Warn_TouchLayoutMissingLayer = (o:{keyId:string, platformName:string, layerId:string, nextLayer:string}) => m(this.WARN_TouchLayoutMissingLayer,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", references a missing layer "${o.nextLayer}"`);
/** @internal */
static Warn_TouchLayoutUnidentifiedKey = (o:{layerId:string}) => m(this.WARN_TouchLayoutUnidentifiedKey,
`A key on layer "${o.layerId}" has no identifier.`);
/** @internal */
static Error_TouchLayoutInvalidIdentifier = (o:{keyId:string, platformName: string, layerId:string}) => m(this.ERROR_TouchLayoutInvalidIdentifier,
`Key "${o.keyId}" on "${o.platformName}", layer "${o.layerId}" has an invalid identifier.`);
/** @internal */
static Warn_TouchLayoutCustomKeyNotDefined = (o:{keyId:string, platformName:string, layerId:string}) => m(this.WARN_TouchLayoutCustomKeyNotDefined,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", is a custom key but has no corresponding rule in the source.`);
/** @internal */
static Warn_TouchLayoutSpecialLabelOnNormalKey = (o:{keyId:string, platformName:string, layerId:string, label:string}) =>
m(this.WARN_TouchLayoutSpecialLabelOnNormalKey,
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}" does not have `+
`the key type "Special" or "Special (active)" but has the label "${o.label}". This feature is only supported in Keyman 14 or later`);
/** @internal */
static Error_InvalidKeyCode = (o:{keyId: string}) => m(this.ERROR_InvalidKeyCode,
`Invalid key identifier "${o.keyId}"`);
/** @internal */
static Warn_TouchLayoutFontShouldBeSameForAllPlatforms = () => m(this.WARN_TouchLayoutFontShouldBeSameForAllPlatforms,
`The touch layout font should be the same for all platforms.`);
/** @internal */
static Warn_TouchLayoutMissingRequiredKeys = (o:{layerId:string, platformName:string, missingKeys:string}) => m(this.WARN_TouchLayoutMissingRequiredKeys,
`Layer "${o.layerId}" on platform "${o.platformName}" is missing the required key(s) '${o.missingKeys}'.`);
// Following messages are kmw-compiler only, so use KmwCompiler error namespace
/** @internal */

View file

@ -6,11 +6,11 @@ import { makePathToFixture } from './helpers/index.js';
import { KmnCompiler } from '../src/main.js';
import { CompilerErrorNamespace } from '@keymanapp/common-types';
describe('CompilerMessages', function () {
describe('KmnCompilerMessages', function () {
const callbacks = new TestCompilerCallbacks();
it('should have a valid CompilerMessages object', function() {
return verifyCompilerMessagesObject(CompilerMessages, CompilerErrorNamespace.KmnCompiler);
it('should have a valid KmnCompilerMessages object', function() {
return verifyCompilerMessagesObject(KmnCompilerMessages, CompilerErrorNamespace.KmnCompiler);
});
//