diff --git a/developer/src/kmc-ldml/src/compiler/keys.ts b/developer/src/kmc-ldml/src/compiler/keys.ts index ccfc89fc76..f1416cb6d0 100644 --- a/developer/src/kmc-ldml/src/compiler/keys.ts +++ b/developer/src/kmc-ldml/src/compiler/keys.ts @@ -474,7 +474,8 @@ export class KeysCompiler extends SectionCompiler { } for (let y = 0; y < layer.row.length && y < keymap.length; y++) { - const keys = layer.row[y].keys.split(" "); + const row = layer.row[y]; + const keys = row.keys.split(" "); if (keys.length > keymap[y].length) { this.callbacks.reportMessage( @@ -482,7 +483,7 @@ export class KeysCompiler extends SectionCompiler { row: y + 1, hardware: layers.formId, modifiers, - }) + }, row) ); valid = false; } @@ -500,7 +501,7 @@ export class KeysCompiler extends SectionCompiler { row: y + 1, layer: layer.id, form: "hardware", - }) + }, row) ); valid = false; continue; diff --git a/developer/src/kmc-ldml/src/compiler/layr.ts b/developer/src/kmc-ldml/src/compiler/layr.ts index 3e0e051ac2..9b1bd824ad 100644 --- a/developer/src/kmc-ldml/src/compiler/layr.ts +++ b/developer/src/kmc-ldml/src/compiler/layr.ts @@ -65,7 +65,8 @@ export class LayrCompiler extends SectionCompiler { const erow: LayrRow = { keys: row.keys.trim().split(/[ \t]+/).map((id) => sections.strs.allocString(id)), }; - return erow; + // include linenumber info for row + return SectionCompiler.copySymbols(erow, row); }); const mods = translateLayerAttrToModifier(layer); // push a layer entry for each modifier set diff --git a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts index 3cec749cb3..93a30bd046 100644 --- a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts +++ b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts @@ -1,4 +1,4 @@ -import { util } from "@keymanapp/common-types"; +import { KMXPlus, util } from "@keymanapp/common-types"; import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m, CompilerMessageDef as def, XML_FILENAME_SYMBOL, CompilerEvent, KeymanXMLReader } from '@keymanapp/developer-utils'; import { LDMLKeyboard } from '@keymanapp/developer-utils'; // const SevInfo = CompilerErrorSeverity.Info | CompilerErrorNamespace.LdmlKeyboardCompiler; @@ -54,11 +54,18 @@ export class LdmlCompilerMessages { ); static ERROR_RowOnHardwareLayerHasTooManyKeys = SevError | 0x0004; - static Error_RowOnHardwareLayerHasTooManyKeys = (o:{row: number, hardware: string, modifiers: string}) => m(this.ERROR_RowOnHardwareLayerHasTooManyKeys, `Row #${def(o.row)} on 'hardware' ${def(o.hardware)} layer for modifier ${o.modifiers || 'none'} has too many keys`); + static Error_RowOnHardwareLayerHasTooManyKeys = (o: { row: number, hardware: string, modifiers: string }, x: LDMLKeyboard.LKRow) => mx( + this.ERROR_RowOnHardwareLayerHasTooManyKeys, + `Row #${def(o.row)} on 'hardware' ${def(o.hardware)} layer for modifier ${o.modifiers || 'none'} has too many keys`, + x, + ); static ERROR_KeyNotFoundInKeyBag = SevError | 0x0005; - static Error_KeyNotFoundInKeyBag = (o:{keyId: string, col: number, row: number, layer: string, form: string}) => - m(this.ERROR_KeyNotFoundInKeyBag, `Key '${def(o.keyId)}' in position #${def(o.col)} on row #${def(o.row)} of layer ${def(o.layer)}, form '${def(o.form)}' not found in key bag`); + static Error_KeyNotFoundInKeyBag = (o: { keyId: string, col: number, row: number, layer: string, form: string }, x: LDMLKeyboard.LKRow | KMXPlus.LayrRow) => mx( + this.ERROR_KeyNotFoundInKeyBag, + `Key '${def(o.keyId)}' in position #${def(o.col)} on row #${def(o.row)} of layer ${def(o.layer)}, form '${def(o.form)}' not found in key bag`, + x, + ); static HINT_OneOrMoreRepeatedLocales = SevHint | 0x0006; static Hint_OneOrMoreRepeatedLocales = () => diff --git a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts index 56431b63c3..480ac5add5 100644 --- a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts @@ -117,7 +117,9 @@ export class LdmlKeyboardVisualKeyboardCompiler { if (!keydef || !kmap || text === null) { this.callbacks.reportMessage( - LdmlCompilerMessages.Error_KeyNotFoundInKeyBag({ keyId: key.value, layer: layerId, row: y, col: x, form: hardware }) + LdmlCompilerMessages.Error_KeyNotFoundInKeyBag({ + keyId: key.value, layer: layerId, row: y, col: x, form: hardware + }, row) ); result = false; } else { diff --git a/developer/src/kmc-ldml/test/keys.tests.ts b/developer/src/kmc-ldml/test/keys.tests.ts index f45076050b..bc8e41fef7 100644 --- a/developer/src/kmc-ldml/test/keys.tests.ts +++ b/developer/src/kmc-ldml/test/keys.tests.ts @@ -458,7 +458,7 @@ describe('keys.kmap', function () { assert.isNull(keys); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_RowOnHardwareLayerHasTooManyKeys({row: 1, hardware: 'us', modifiers: 'none'})); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_RowOnHardwareLayerHasTooManyKeys({ row: 1, hardware: 'us', modifiers: 'none' }, withOffset(785) as LDMLKeyboard.LKRow)); }); it('should reject layouts with undefined keys', async function() { @@ -466,7 +466,7 @@ describe('keys.kmap', function () { assert.isNull(keys); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_KeyNotFoundInKeyBag({col: 1, form: 'hardware', keyId: 'foo', layer: 'base', row: 1})); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_KeyNotFoundInKeyBag({col: 1, form: 'hardware', keyId: 'foo', layer: 'base', row: 1}, withOffset(271) as LDMLKeyboard.LKRow)); }); it('should reject layouts with invalid keys', async function() { const keys = await loadSectionFixture(KeysCompiler, 'sections/keys/invalid-key-missing-attrs.xml', compilerTestCallbacks, keysDependencies) as Keys;