mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-22 16:27:41 +00:00
Merge pull request #14097 from keymanapp/feat/developer/13937-ln-tran-bksp
feat(developer): remaining line numbers for tran/bksp compilers
This commit is contained in:
commit
72f4abc323
3 changed files with 37 additions and 35 deletions
|
|
@ -85,6 +85,7 @@ export class LdmlCompilerMessages {
|
|||
`After minimization, one or more locales is repeated and has been removed`,
|
||||
);
|
||||
|
||||
// This is the only allowed use of m() vs mx() in this file, all the others take context.
|
||||
static ERROR_InvalidFile = SevError | 0x0007;
|
||||
static Error_InvalidFile = (o:{errorText: string}) =>
|
||||
m(this.ERROR_InvalidFile, `The source file has an invalid structure: ${def(o.errorText)}`);
|
||||
|
|
@ -306,8 +307,10 @@ export class LdmlCompilerMessages {
|
|||
);
|
||||
|
||||
static ERROR_UnparseableReorderSet = SevError | 0x0028;
|
||||
static Error_UnparseableReorderSet = (o: { from: string, set: string }) =>
|
||||
m(this.ERROR_UnparseableReorderSet, `Illegal UnicodeSet "${def(o.set)}" in reorder "${def(o.from)}`);
|
||||
static Error_UnparseableReorderSet = (o: { from: string, set: string }, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_UnparseableReorderSet, x,
|
||||
`Illegal UnicodeSet "${def(o.set)}" in reorder "${def(o.from)}`,
|
||||
);
|
||||
|
||||
static ERROR_InvalidVariableIdentifier = SevError | 0x0029;
|
||||
static Error_InvalidVariableIdentifier = (o: { id: string }, x?: ObjectWithMetadata) => mx(
|
||||
|
|
@ -354,16 +357,18 @@ export class LdmlCompilerMessages {
|
|||
|
||||
// This is a bit of a catch-all and represents messages bubbling up from the underlying regex engine
|
||||
static ERROR_UnparseableTransformFrom = SevErrorTransform | 0x00;
|
||||
static Error_UnparseableTransformFrom = (o: { from: string, message: string }) =>
|
||||
m(this.ERROR_UnparseableTransformFrom, `Invalid transform from="${def(o.from)}": "${def(o.message)}"`);
|
||||
static Error_UnparseableTransformFrom = (o: { from: string, message: string }, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_UnparseableTransformFrom, x,
|
||||
`Invalid transform from="${def(o.from)}": "${def(o.message)}"`,
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------|
|
||||
// max length of detail message lines (checked by verifyCompilerMessagesObject) |
|
||||
//------------------------------------------------------------------------------|
|
||||
|
||||
static ERROR_IllegalTransformDollarsign = SevErrorTransform | 0x01;
|
||||
static Error_IllegalTransformDollarsign = (o: { from: string }) => m(
|
||||
this.ERROR_IllegalTransformDollarsign,
|
||||
static Error_IllegalTransformDollarsign = (o: { from: string }, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_IllegalTransformDollarsign, x,
|
||||
`Invalid transform from="${def(o.from)}": Unescaped dollar-sign ($) is not valid transform syntax.`, `
|
||||
**Hint**: Use \`\\$\` to match a literal dollar-sign. If this precedes a
|
||||
variable name, the variable name may not be valid (A-Z, a-z, 0-9, _, 32
|
||||
|
|
@ -377,30 +382,30 @@ export class LdmlCompilerMessages {
|
|||
);
|
||||
|
||||
static ERROR_IllegalTransformPlus = SevErrorTransform | 0x03;
|
||||
static Error_IllegalTransformPlus = (o: { from: string }) => m(
|
||||
this.ERROR_IllegalTransformPlus,
|
||||
static Error_IllegalTransformPlus = (o: { from: string }, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_IllegalTransformPlus, x,
|
||||
`Invalid transform from="${def(o.from)}": Unescaped plus (+) is not valid transform syntax.`, `
|
||||
**Hint**: Use \`\\+\` to match a literal plus.
|
||||
`);
|
||||
|
||||
static ERROR_IllegalTransformAsterisk = SevErrorTransform | 0x04;
|
||||
static Error_IllegalTransformAsterisk = (o: { from: string }) =>m(
|
||||
this.ERROR_IllegalTransformAsterisk,
|
||||
static Error_IllegalTransformAsterisk = (o: { from: string }, x?: ObjectWithMetadata) =>mx(
|
||||
this.ERROR_IllegalTransformAsterisk, x,
|
||||
`Invalid transform from="${def(o.from)}": Unescaped asterisk (*) is not valid transform syntax.`, `
|
||||
**Hint**: Use \`\\*\` to match a literal asterisk.
|
||||
`);
|
||||
|
||||
static ERROR_IllegalTransformToUset = SevErrorTransform | 0x05;
|
||||
static Error_IllegalTransformToUset = (o: { to: string }) => m(
|
||||
this.ERROR_IllegalTransformToUset,
|
||||
static Error_IllegalTransformToUset = (o: { to: string }, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_IllegalTransformToUset, x,
|
||||
`Invalid transform to="${def(o.to)}": Set variable (\\$[…]) cannot be used in 'to=' unless part of a map.`, `
|
||||
**Hint**: If a map was meant, must use the form
|
||||
\`<transform from="($[fromSet])" to="$[1:toSet]"/>\`.
|
||||
`);
|
||||
|
||||
static ERROR_UnparseableTransformTo = SevErrorTransform | 0x06;
|
||||
static Error_UnparseableTransformTo = (o: {to: string, message: string}) => m(
|
||||
this.ERROR_UnparseableTransformTo,
|
||||
static Error_UnparseableTransformTo = (o: {to: string, message: string}, x?: ObjectWithMetadata) => mx(
|
||||
this.ERROR_UnparseableTransformTo, x,
|
||||
`Invalid transform to="${def(o.to)}": "${def(o.message)}"`,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { constants, SectionIdent } from "@keymanapp/ldml-keyboard-constants";
|
||||
import { KMXPlus, LdmlKeyboardTypes, util } from '@keymanapp/common-types';
|
||||
import { CompilerCallbacks, LDMLKeyboard } from "@keymanapp/developer-utils";
|
||||
import { CompilerCallbacks, LDMLKeyboard, ObjectWithMetadata } from "@keymanapp/developer-utils";
|
||||
import { SectionCompiler } from "./section-compiler.js";
|
||||
|
||||
import Bksp = KMXPlus.Bksp;
|
||||
|
|
@ -204,7 +204,7 @@ export abstract class TransformCompiler<T extends TransformCompilerType, TranBas
|
|||
transform_from_parse(transform.from);
|
||||
}
|
||||
} catch (e) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformFrom({ from: cookedFrom, message: e.toString() }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformFrom({ from: cookedFrom, message: e.toString() }, transform));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ export abstract class TransformCompiler<T extends TransformCompilerType, TranBas
|
|||
try {
|
||||
transform_to_parse(transform.to || '');
|
||||
} catch (e) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformTo({ to: transform.to || '', message: e.toString() }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformTo({ to: transform.to || '', message: e.toString() }, transform));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +237,9 @@ export abstract class TransformCompiler<T extends TransformCompilerType, TranBas
|
|||
* We have already checked that it's not a mapTo,
|
||||
* so there should not be any illegal substitutions.
|
||||
*/
|
||||
private isValidTo(to: string) : boolean {
|
||||
private isValidTo(to: string, x?: ObjectWithMetadata) : boolean {
|
||||
if (/(?<!\\)(?:\\\\)*\$\[/.test(to)) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformToUset({ to }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformToUset({ to }, x));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -251,18 +251,18 @@ export abstract class TransformCompiler<T extends TransformCompilerType, TranBas
|
|||
* @param from the original from - for error reporting
|
||||
* @returns true if OK
|
||||
*/
|
||||
private isValidRegex(cookedFrom: string, from: string) : boolean {
|
||||
private isValidRegex(cookedFrom: string, from: string, x?: ObjectWithMetadata) : boolean {
|
||||
// check for any unescaped dollar sign here
|
||||
if (/(?<!\\)(?:\\\\)*\$/.test(cookedFrom)) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformDollarsign({ from }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformDollarsign({ from }, x));
|
||||
return false;
|
||||
}
|
||||
if (/(?<!\\)(?:\\\\)*\*/.test(cookedFrom)) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformAsterisk({ from }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformAsterisk({ from }, x));
|
||||
return false;
|
||||
}
|
||||
if (/(?<!\\)(?:\\\\)*\+/.test(cookedFrom)) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformPlus({ from }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_IllegalTransformPlus({ from }, x));
|
||||
return false;
|
||||
}
|
||||
// Verify that the regex is syntactically valid
|
||||
|
|
@ -272,14 +272,14 @@ export abstract class TransformCompiler<T extends TransformCompilerType, TranBas
|
|||
|
||||
// does it match an empty string?
|
||||
if (rg.test('')) {
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_TransformFromMatchesNothing({ from }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_TransformFromMatchesNothing({ from }, x));
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
// We're exposing the internal regex error message here.
|
||||
// In the future, CLDR plans to expose the EBNF for the transform,
|
||||
// at which point we would have more precise validation prior to getting to this point.
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformFrom({ from, message: e.message }));
|
||||
this.callbacks.reportMessage(LdmlCompilerMessages.Error_UnparseableTransformFrom({ from, message: e.message }, x));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -15,18 +15,20 @@ describe('LdmlCompilerMessages', function () {
|
|||
/** all fns */
|
||||
let total = 0;
|
||||
/** does not take line numbers */
|
||||
let noLines = 0;
|
||||
const noLines = new Set<string>();
|
||||
/** takes line numbers */
|
||||
let lines = 0;
|
||||
const fakeOffsetNumber = 1234;
|
||||
const fakeOffsetObject = withOffset(fakeOffsetNumber);
|
||||
for(const key of keys) {
|
||||
if(typeof m[key] == 'function') {
|
||||
// exclude this one, does not need line numbers
|
||||
if (key == 'Error_InvalidFile') continue;
|
||||
if (typeof m[key] == 'function') {
|
||||
total++;
|
||||
const f = m[key] as Function;
|
||||
// console.log(`${f.name}: ${f.length}`);
|
||||
if (f.length === 0) { // Error_foo()
|
||||
noLines++;
|
||||
noLines.add(key);
|
||||
continue;
|
||||
}
|
||||
// now try to call it
|
||||
|
|
@ -42,16 +44,11 @@ describe('LdmlCompilerMessages', function () {
|
|||
expect(resp.offset).to.equal(fakeOffsetNumber, `Offset number round trip for error ${f.name} did not work, check the message function`);
|
||||
} else {
|
||||
// did not get a column number back
|
||||
noLines++;
|
||||
noLines.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(lines).to.not.be.equal(0, `None of ${total} messages had offset reporting.`);
|
||||
if (noLines > 0) {
|
||||
// Once this goes to zero, make it an error if it goes up!
|
||||
// Oh, and while you're here, once this is zero, uncomment the code in testCompilationCases
|
||||
// that asserts that all messages are actually generated with an offset.
|
||||
console.warn(`TODO-LDML (#10622) ${noLines}/${total} ${Number((noLines/total)*1000).toFixed(0)}‰ of message(s) did not have detectable offset (line number) reporting.`);
|
||||
}
|
||||
expect(Array.from(noLines.values())).to.deep.equal([], `${noLines.size}/${total} ${Number((noLines.size/total)*100).toFixed(0)}% of message(s) did not have detectable offset (line number) reporting`);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue