diff --git a/developer/src/kmc-ldml/src/compiler/disp.ts b/developer/src/kmc-ldml/src/compiler/disp.ts index 65119118d5..5b63a99a8f 100644 --- a/developer/src/kmc-ldml/src/compiler/disp.ts +++ b/developer/src/kmc-ldml/src/compiler/disp.ts @@ -31,20 +31,21 @@ export class DispCompiler extends SectionCompiler { const ids = new Set(); if (this.keyboard3.displays?.display) { - for (const { output, keyId } of this.keyboard3.displays?.display) { + for (const display of this.keyboard3.displays?.display) { + const { output, keyId } = display; if ((output && keyId) || (!output && !keyId)) { - this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayNeedsToOrId({ output, keyId })); + this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayNeedsToOrId({ output, keyId }, display)); return false; } else if (output) { if (tos.has(output)) { - this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayIsRepeated({ output })); + this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayIsRepeated({ output }, display)); return false; } else { tos.add(output); } } else if (keyId) { if (ids.has(keyId)) { - this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayIsRepeated({ keyId })); + this.callbacks.reportMessage(LdmlCompilerMessages.Error_DisplayIsRepeated({ keyId }, display)); return false; } else { ids.add(keyId); 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 a5636104f2..98dad153d9 100644 --- a/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts +++ b/developer/src/kmc-ldml/src/compiler/ldml-compiler-messages.ts @@ -147,8 +147,10 @@ export class LdmlCompilerMessages { } static ERROR_DisplayIsRepeated = SevError | 0x0010; - static Error_DisplayIsRepeated = (o:{output?: string, keyId?: string}) => - m(this.ERROR_DisplayIsRepeated, `display ${LdmlCompilerMessages.outputOrKeyId(o)} has more than one display entry.`); + static Error_DisplayIsRepeated = (o:{output?: string, keyId?: string}, x?: ObjectWithMetadata) => mx( + this.ERROR_DisplayIsRepeated, x, + `display ${LdmlCompilerMessages.outputOrKeyId(o)} has more than one display entry.`, + ); static ERROR_KeyMissingToGapOrSwitch = SevError | 0x0011; static Error_KeyMissingToGapOrSwitch = (o:{keyId: string}, x?: ObjectWithMetadata) => mx( @@ -244,8 +246,10 @@ export class LdmlCompilerMessages { m(this.ERROR_MissingMarkers, `Markers used for matching but not defined: ${def(o.ids?.join(','))}`); static ERROR_DisplayNeedsToOrId = SevError | 0x0022; - static Error_DisplayNeedsToOrId = (o:{output?: string, keyId?: string}) => - m(this.ERROR_DisplayNeedsToOrId, `display ${LdmlCompilerMessages.outputOrKeyId(o)} needs output= or keyId=, but not both`); + static Error_DisplayNeedsToOrId = (o:{output?: string, keyId?: string}, x?: ObjectWithMetadata) => mx( + this.ERROR_DisplayNeedsToOrId, x, + `display ${LdmlCompilerMessages.outputOrKeyId(o)} needs output= or keyId=, but not both`, + ); static HINT_PUACharacters = SevHint | 0x0023; static Hint_PUACharacters = (o: { count: number, lowestCh: number }) => diff --git a/developer/src/kmc-ldml/test/disp.tests.ts b/developer/src/kmc-ldml/test/disp.tests.ts index 80b416bf94..032e4829bf 100644 --- a/developer/src/kmc-ldml/test/disp.tests.ts +++ b/developer/src/kmc-ldml/test/disp.tests.ts @@ -1,7 +1,7 @@ import 'mocha'; import {assert} from 'chai'; import { DispCompiler } from '../src/compiler/disp.js'; -import { compilerTestCallbacks, loadSectionFixture, testCompilationCases } from './helpers/index.js'; +import { compilerTestCallbacks, loadSectionFixture, testCompilationCases, withOffset } from './helpers/index.js'; import { KMXPlus } from '@keymanapp/common-types'; import { LdmlCompilerMessages } from '../src/compiler/ldml-compiler-messages.js'; @@ -67,25 +67,25 @@ describe('disp', function () { const disp = await loadSectionFixture(DispCompiler, 'sections/disp/invalid-dupto.xml', compilerTestCallbacks) as Disp; assert.isNull(disp); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayIsRepeated({ output: 'e' })); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayIsRepeated({ output: 'e' }, withOffset(330))); }); it('should reject duplicate ids', async function() { const disp = await loadSectionFixture(DispCompiler, 'sections/disp/invalid-dupid.xml', compilerTestCallbacks) as Disp;1 assert.isNull(disp); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayIsRepeated({ keyId: 'e' })); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayIsRepeated({ keyId: 'e' }, withOffset(329))); }); it('should reject if neither to nor id', async function() { const disp = await loadSectionFixture(DispCompiler, 'sections/disp/invalid-none.xml', compilerTestCallbacks) as Disp; assert.isNull(disp); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayNeedsToOrId({})); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayNeedsToOrId({}, withOffset(182))); }); it('should reject if both to and id', async function() { const disp = await loadSectionFixture(DispCompiler, 'sections/disp/invalid-both.xml', compilerTestCallbacks) as Disp; assert.isNull(disp); assert.equal(compilerTestCallbacks.messages.length, 1); - assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayNeedsToOrId({ output: 'e', keyId: 'e' })); + assert.deepEqual(compilerTestCallbacks.messages[0], LdmlCompilerMessages.Error_DisplayNeedsToOrId({ output: 'e', keyId: 'e' }, withOffset(182))); }); testCompilationCases(DispCompiler, [ {