From 534d5ec64ffd7bcf0d90cb5522597459582db60b Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Wed, 28 Feb 2024 06:58:19 +0700 Subject: [PATCH] refactor(developer): cleanup kmn compiler message namespaces This is in preparation for message documentation. Moves all messages with the KmnCompiler namespace into KmnCompilerMessages. For now, keeps CompilerMessages class as a subclass of KmnCompilerMessages, for removal in 18.0. Moves messages with KmnCompiler namespace from kmw-compiler-messages.ts to kmn-compiler-messages.ts. This avoids confusion as to source of message, and should allow us in the future to split the classes entirely. --- .../src/compiler/kmn-compiler-messages.ts | 382 ++++++++++++++++-- .../src/kmw-compiler/kmw-compiler-messages.ts | 86 ---- developer/src/kmc-kmn/test/test-messages.ts | 6 +- 3 files changed, 359 insertions(+), 115 deletions(-) diff --git a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts index dd8d10ad16..eb04f85877 100644 --- a/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts +++ b/developer/src/kmc-kmn/src/compiler/kmn-compiler-messages.ts @@ -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 messages in this class * share the namespace with messages from kmn_compiler_errors.h, which are * generated by kmcmplib, so values 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; diff --git a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts index e81b7dfdcc..5f9b0b869f 100644 --- a/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts +++ b/developer/src/kmc-kmn/src/kmw-compiler/kmw-compiler-messages.ts @@ -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 */ diff --git a/developer/src/kmc-kmn/test/test-messages.ts b/developer/src/kmc-kmn/test/test-messages.ts index 92f8936f32..674dd17e34 100644 --- a/developer/src/kmc-kmn/test/test-messages.ts +++ b/developer/src/kmc-kmn/test/test-messages.ts @@ -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); }); //