diff --git a/common/web/types/src/kmx/kmx-plus.ts b/common/web/types/src/kmx/kmx-plus.ts
index 020d5fb330..d7e21a5097 100644
--- a/common/web/types/src/kmx/kmx-plus.ts
+++ b/common/web/types/src/kmx/kmx-plus.ts
@@ -150,6 +150,21 @@ export class Vars extends Section {
strings: StringVarItem[] = []; // ≠ StrsItem
sets: SetVarItem[] = [];
unicodeSets: UnicodeSetItem[] = [];
+
+ /**
+ *
+ * @returns false if any invalid variables
+ */
+ valid() : boolean {
+ for (const t of [this.sets, this.strings, this.unicodeSets]) {
+ for (const i of t) {
+ if (!i.valid()) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
};
/**
@@ -165,6 +180,10 @@ class VarsItem extends Section {
this.id = sections.strs.allocString(id);
this.value = sections.strs.allocAndUnescapeString(value);
}
+
+ valid() : boolean {
+ return true;
+ }
};
export class UnicodeSetItem extends VarsItem {
@@ -177,14 +196,20 @@ export class UnicodeSetItem extends VarsItem {
// A message will have been set in that case.
}
_unicodeSet?: UnicodeSet;
+ valid() : boolean {
+ return !!this._unicodeSet;
+ }
};
export class SetVarItem extends VarsItem {
constructor(id: string, value: string, sections: GlobalSections) {
super(id, value, sections);
- this._items = null; // TODO-LDML
+ this._items = value.split(' '); // TODO-LDML
+ }
+ _items: string[];
+ valid() : boolean {
+ return !!this._items;
}
- _items: string;
};
export class StringVarItem extends VarsItem {
diff --git a/developer/src/kmc-kmn/src/main.ts b/developer/src/kmc-kmn/src/main.ts
index c3c3d6f173..53e629929d 100644
--- a/developer/src/kmc-kmn/src/main.ts
+++ b/developer/src/kmc-kmn/src/main.ts
@@ -1,2 +1,3 @@
export { Compiler } from './compiler/compiler.js';
+export { CompilerMessages } from './compiler/messages.js';
diff --git a/developer/src/kmc-ldml/src/compiler/messages.ts b/developer/src/kmc-ldml/src/compiler/messages.ts
index abd2325aa1..c937dbfa04 100644
--- a/developer/src/kmc-ldml/src/compiler/messages.ts
+++ b/developer/src/kmc-ldml/src/compiler/messages.ts
@@ -91,7 +91,7 @@ export class CompilerMessages {
static ERROR_MissingFlicks = SevError | 0x0015;
static Error_DuplicateVariable = (o:{ids: string}) => m(this.ERROR_DuplicateVariable,
- `duplicate variable id=${o.ids}`);
+ `duplicate variables: id=${o.ids}`);
static ERROR_DuplicateVariable = SevError | 0x0016;
static Fatal_SectionInitFailed = (o:{sect: string}) =>
diff --git a/developer/src/kmc-ldml/src/compiler/vars.ts b/developer/src/kmc-ldml/src/compiler/vars.ts
index 52466a14e7..09a7f5ff01 100644
--- a/developer/src/kmc-ldml/src/compiler/vars.ts
+++ b/developer/src/kmc-ldml/src/compiler/vars.ts
@@ -54,7 +54,7 @@ export class VarsCompiler extends SectionCompiler {
// one report if any dups
if (dups.size > 0) {
this.callbacks.reportMessage(CompilerMessages.Error_DuplicateVariable({
- ids: Array.of(dups.values()).join(', ')
+ ids: Array.from(dups.values()).sort().join(', ')
}));
valid = false;
}
@@ -80,6 +80,10 @@ export class VarsCompiler extends SectionCompiler {
variables?.unicodeSet?.map(({ id, value }) =>
new UnicodeSetItem(id, value, sections, this.usetparser));
- return result;
+ if (!result.valid()) {
+ return null;
+ } else {
+ return result;
+ }
}
}
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props1.xml b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props1.xml
new file mode 100644
index 0000000000..c7930181d3
--- /dev/null
+++ b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props1.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props2.xml b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props2.xml
new file mode 100644
index 0000000000..761c2251c3
--- /dev/null
+++ b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-props2.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-strings.xml b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-strings.xml
new file mode 100644
index 0000000000..a207df13f1
--- /dev/null
+++ b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-strings.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-syntax.xml b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-syntax.xml
new file mode 100644
index 0000000000..0fd29f5bab
--- /dev/null
+++ b/developer/src/kmc-ldml/test/fixtures/sections/vars/fail-uset-syntax.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/developer/src/kmc-ldml/test/helpers/index.ts b/developer/src/kmc-ldml/test/helpers/index.ts
index fc85323261..2b03b3c092 100644
--- a/developer/src/kmc-ldml/test/helpers/index.ts
+++ b/developer/src/kmc-ldml/test/helpers/index.ts
@@ -19,6 +19,7 @@ import GlobalSections = KMXPlus.GlobalSections;
import Section = KMXPlus.Section;
import Strs = KMXPlus.Strs;
import List = KMXPlus.List;
+// import Vars = KMXPlus.Vars;
/**
* Builds a path to the fixture with the given path components.
@@ -70,11 +71,10 @@ export async function loadSectionFixture(compilerClass: typeof SectionCompiler,
strs: new Strs(),
elem: null,
list: null,
- vars: null,
+ vars: null, // ?
};
globalSections.elem = new Elem(globalSections.strs);
globalSections.list = new List(globalSections.strs);
- globalSections.vars = null; // new Vars(globalSections.strs);
return compiler.compile(globalSections);
}
@@ -175,7 +175,7 @@ export function testCompilationCases(compiler: typeof SectionCompiler, cases : C
}
let section = await loadSectionFixture(compiler, testcase.subpath, callbacks);
if (expectFailure) {
- assert.isNull(section, 'expected compilation result to be null, but got something');
+ assert.isNull(section, 'expected compilation result failure (null)');
} else {
assert.isNotNull(section, `expected successful compilation, but got null and ${JSON.stringify(callbacks.messages)}`);
}
diff --git a/developer/src/kmc-ldml/test/test-vars.ts b/developer/src/kmc-ldml/test/test-vars.ts
index c81060abb5..9c2e5c3e1b 100644
--- a/developer/src/kmc-ldml/test/test-vars.ts
+++ b/developer/src/kmc-ldml/test/test-vars.ts
@@ -1,7 +1,8 @@
import 'mocha';
import { assert } from 'chai';
import { VarsCompiler } from '../src/compiler/vars.js';
-// import { CompilerMessages } from '../src/compiler/messages.js';
+import { CompilerMessages } from '../src/compiler/messages.js';
+import { CompilerMessages as KmnCompilerMessages } from '@keymanapp/kmc-kmn';
import { /*compilerTestCallbacks, loadSectionFixture,*/testCompilationCases } from './helpers/index.js';
import { KMXPlus /*, CommonTypesMessages*/ } from '@keymanapp/common-types';
// import { constants } from '@keymanapp/ldml-keyboard-constants';
@@ -32,11 +33,39 @@ describe('vars', function () {
},
{
subpath: 'sections/vars/dup0.xml',
- errors: [],
+ errors: [
+ CompilerMessages.Error_DuplicateVariable({ids: 'y'})
+ ],
},
{
subpath: 'sections/vars/dup1.xml',
- errors: [],
+ errors: [
+ CompilerMessages.Error_DuplicateVariable({ids: 'upper, y'})
+ ],
+ },
+ {
+ subpath: 'sections/vars/fail-uset-props1.xml',
+ errors: [
+ KmnCompilerMessages.Error_UnicodeSetHasProperties()
+ ],
+ },
+ {
+ subpath: 'sections/vars/fail-uset-props2.xml',
+ errors: [
+ KmnCompilerMessages.Error_UnicodeSetHasProperties()
+ ],
+ },
+ {
+ subpath: 'sections/vars/fail-uset-strings.xml',
+ errors: [
+ KmnCompilerMessages.Error_UnicodeSetHasStrings()
+ ],
+ },
+ {
+ subpath: 'sections/vars/fail-uset-syntax.xml',
+ errors: [
+ KmnCompilerMessages.Error_UnicodeSetSyntaxError()
+ ],
},
]);
});