feat(developer): add line number for keys

- all remaining tests for KeysCompiler
- who's next?

Fixes: #10622
This commit is contained in:
Steven R. Loomis 2025-05-14 16:25:59 -05:00
parent d4bc0ecda5
commit 155b5558bf
5 changed files with 22 additions and 11 deletions

View file

@ -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;

View file

@ -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

View file

@ -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 = () =>

View file

@ -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 {

View file

@ -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;