mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-26 18:27:41 +00:00
feat(developer): provide line number for some kmw compiler messages
Fixes #9931. Provide additional line and file context for some KeymanWeb compiler messages. This change requires debug data in the intermediate kmx data provided to the kmw compiler, which should have no impact on the final .js if debug=false. This commit only addresses line number data in Error_NotSupportedInKeymanWebContext and Error_NotSupportedInKeymanWebOutput. There are other compiler messages which could benefit from this data: * Warn_OptionStoreNameInvalid * Error_VirtualCharacterKeysNotSupportedInKeymanWeb * Error_VirtualKeysNotValidForMnemonicLayouts * Warn_ExtendedShiftFlagsNotSupportedInKeymanWeb * Hint_UnreachableKeyCode * Error_NotSupportedInKeymanWebStore * Warn_HelpFileMissing * Warn_EmbedJsFileMissing * Error_NotAnyRequiresVersion14
This commit is contained in:
parent
8782d32a59
commit
02e1ea59a2
5 changed files with 65 additions and 12 deletions
|
|
@ -298,6 +298,12 @@ export class KmnCompiler implements UnicodeSetParser {
|
|||
|
||||
if(wasm_result.extra.targets & COMPILETARGETS_JS) {
|
||||
wasm_options.target = 1; // CKF_KEYMANWEB TODO use COMPILETARGETS_JS
|
||||
|
||||
// We always want debug data in the intermediate .kmx, so that error
|
||||
// messages from KMW compiler can give line numbers in .kmn. This
|
||||
// should have no impact on the final .js if options.debug is false
|
||||
wasm_options.saveDebug = true;
|
||||
|
||||
wasm_result = Module.kmcmp_compile(infile, wasm_options, wasm_interface);
|
||||
if(!wasm_result.result) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ function JavaScript_CompositeContextValue(fk: KMX.KEYBOARD, fkp: KMX.KEY, pwsz:
|
|||
`this.s${JavaScript_Name(rec.Any.StoreIndex, rec.Any.Store.dpName)})`;
|
||||
break;
|
||||
default:
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({code: GetCodeName(rec.Code)}));
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({line: fkp.Line, code: GetCodeName(rec.Code)}));
|
||||
Result += '/*.*/ 0 ';
|
||||
}
|
||||
}
|
||||
|
|
@ -579,7 +579,7 @@ function JavaScript_FullContextValue(fk: KMX.KEYBOARD, fkp: KMX.KEY, pwsz: strin
|
|||
`o:${rec.Index.Index}}`; // I4611
|
||||
break;
|
||||
default:
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({code: GetCodeName(rec.Code)}));
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({line: fkp.Line, code: GetCodeName(rec.Code)}));
|
||||
Result += '/*.*/ 0 ';
|
||||
}
|
||||
}
|
||||
|
|
@ -677,7 +677,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp
|
|||
// These have no output for a context emit
|
||||
break;
|
||||
default:
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({code: GetCodeName(recContext.Code)}));
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebContext({line: fkp.Line, code: GetCodeName(recContext.Code)}));
|
||||
Result += nlt + '/*.*/ '; // I4611
|
||||
}
|
||||
}
|
||||
|
|
@ -885,7 +885,7 @@ export function JavaScript_OutputString(fk: KMX.KEYBOARD, FTabStops: string, fkp
|
|||
len = -1;
|
||||
break;
|
||||
default:
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebOutput({code: GetCodeName(rec.Code)}));
|
||||
callbacks.reportMessage(KmwCompilerMessages.Error_NotSupportedInKeymanWebOutput({line: fkp.Line, code: GetCodeName(rec.Code)}));
|
||||
Result += '';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { KmnCompilerMessages } from "../compiler/kmn-compiler-messages.js";
|
||||
import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerMessageSpec as m } from "@keymanapp/common-types";
|
||||
import { CompilerErrorNamespace, CompilerErrorSeverity, CompilerEvent, CompilerMessageSpec } from "@keymanapp/common-types";
|
||||
import { kmnfile } from "./compiler-globals.js";
|
||||
|
||||
const Namespace = CompilerErrorNamespace.KmwCompiler;
|
||||
// const SevInfo = CompilerErrorSeverity.Info | Namespace;
|
||||
|
|
@ -8,6 +9,12 @@ const Namespace = CompilerErrorNamespace.KmwCompiler;
|
|||
const SevError = CompilerErrorSeverity.Error | Namespace;
|
||||
// const SevFatal = CompilerErrorSeverity.Fatal | Namespace;
|
||||
|
||||
const m = (code: number, message: string, o?: {e?: any, filename?: string, line?: number}) : CompilerEvent => ({
|
||||
...CompilerMessageSpec(code, message, o?.e),
|
||||
filename: o?.filename ?? kmnfile,
|
||||
line: o?.line,
|
||||
});
|
||||
|
||||
export class KmwCompilerMessages extends KmnCompilerMessages {
|
||||
// Note: for legacy reasons, KMWCompilerMessages extends from
|
||||
// KMNCompilerMessages as they share the same error codes. This can be a
|
||||
|
|
@ -19,44 +26,66 @@ export class KmwCompilerMessages extends KmnCompilerMessages {
|
|||
|
||||
static Error_InvalidBegin = () => m(this.ERROR_InvalidBegin,
|
||||
`A "begin unicode" statement is required to compile a KeymanWeb keyboard`);
|
||||
|
||||
static Error_InvalidTouchLayoutFile = (o:{filename:string}) => m(this.ERROR_InvalidTouchLayoutFile,
|
||||
`Touch layout file ${o.filename} is not valid`);
|
||||
|
||||
static Warn_DontMixChiralAndNonChiralModifiers = () => m(this.WARN_DontMixChiralAndNonChiralModifiers,
|
||||
`This keyboard contains Ctrl,Alt and LCtrl,LAlt,RCtrl,RAlt sets of modifiers. Use only one or the other set for web target.`);
|
||||
|
||||
static Warn_OptionStoreNameInvalid = (o:{name:string}) => m(this.WARN_OptionStoreNameInvalid,
|
||||
`The option store ${o.name} should be named with characters in the range A-Z, a-z, 0-9 and _ only.`);
|
||||
|
||||
static Error_VirtualCharacterKeysNotSupportedInKeymanWeb = () => m(this.ERROR_VirtualCharacterKeysNotSupportedInKeymanWeb,
|
||||
`Virtual character keys not currently supported in KeymanWeb`);
|
||||
|
||||
static Error_VirtualKeysNotValidForMnemonicLayouts = () => m(this.ERROR_VirtualKeysNotValidForMnemonicLayouts,
|
||||
`Virtual keys are not valid for mnemonic layouts`);
|
||||
|
||||
static Warn_ExtendedShiftFlagsNotSupportedInKeymanWeb = (o:{flags:string}) => m(this.WARN_ExtendedShiftFlagsNotSupportedInKeymanWeb,
|
||||
`Extended shift flags ${o.flags} are not supported in KeymanWeb`);
|
||||
|
||||
static Hint_UnreachableKeyCode = (o:{key:string}) => m(this.HINT_UnreachableKeyCode,
|
||||
`The rule will never be matched for key ${o.key} because its key code is never fired.`);
|
||||
|
||||
static Error_NotSupportedInKeymanWebStore = (o:{code:string,store:string}) => m(this.ERROR_NotSupportedInKeymanWebStore,
|
||||
`${o.code} is not currently supported in store '${o.store}' when used by any or index`);
|
||||
static Error_NotSupportedInKeymanWebContext = (o:{code:String}) => m(this.ERROR_NotSupportedInKeymanWebContext,
|
||||
`Statement ${o.code} is not currently supported in context`);
|
||||
static Error_NotSupportedInKeymanWebOutput = (o:{code:string}) => m(this.ERROR_NotSupportedInKeymanWebOutput,
|
||||
`Statement ${o.code} is not currently supported in output`);
|
||||
`'${o.code}' is not currently supported in store '${o.store}' when used by any or index for web and touch targets`);
|
||||
|
||||
static Error_NotSupportedInKeymanWebContext = (o:{line:number, code:String}) => m(this.ERROR_NotSupportedInKeymanWebContext,
|
||||
`Statement '${o.code}' is not currently supported in context for web and touch targets`, o);
|
||||
|
||||
static Error_NotSupportedInKeymanWebOutput = (o:{line:number, code:string}) => m(this.ERROR_NotSupportedInKeymanWebOutput,
|
||||
`Statement '${o.code}' is not currently supported in output for web and touch targets`, o);
|
||||
|
||||
static Warn_HelpFileMissing = (o:{filename: string, e:any}) => m(this.WARN_HelpFileMissing,
|
||||
`File ${o.filename} could not be loaded: ${(o.e??'').toString()}`);
|
||||
|
||||
static Warn_EmbedJsFileMissing = (o:{filename: string, e:any}) => m(this.WARN_EmbedJsFileMissing,
|
||||
`File ${o.filename} could not be loaded: ${(o.e??'').toString()}`);
|
||||
|
||||
static Warn_TouchLayoutMissingLayer = (o:{keyId:string, platformName:string, layerId:string, nextLayer:string}) => m(this.WARN_TouchLayoutMissingLayer,
|
||||
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", references a missing layer "${o.nextLayer}"`);
|
||||
|
||||
static Warn_TouchLayoutUnidentifiedKey = (o:{layerId:string}) => m(this.WARN_TouchLayoutUnidentifiedKey,
|
||||
`A key on layer "${o.layerId}" has no identifier.`);
|
||||
|
||||
static Error_TouchLayoutInvalidIdentifier = (o:{keyId:string, platformName: string, layerId:string}) => m(this.ERROR_TouchLayoutInvalidIdentifier,
|
||||
`Key "${o.keyId}" on "${o.platformName}", layer "${o.layerId}" has an invalid identifier.`);
|
||||
|
||||
static Warn_TouchLayoutCustomKeyNotDefined = (o:{keyId:string, platformName:string, layerId:string}) => m(this.WARN_TouchLayoutCustomKeyNotDefined,
|
||||
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}", is a custom key but has no corresponding rule in the source.`);
|
||||
static Warn_TouchLayoutSpecialLabelOnNormalKey = (o:{keyId:string, platformName:string, layerId:string, label:string}) => m(this.WARN_TouchLayoutSpecialLabelOnNormalKey,
|
||||
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}" does not have the key type "Special" or "Special (active)" but has the label "${o.label}". This feature is only supported in Keyman 14 or later`);
|
||||
|
||||
static Warn_TouchLayoutSpecialLabelOnNormalKey = (o:{keyId:string, platformName:string, layerId:string, label:string}) =>
|
||||
m(this.WARN_TouchLayoutSpecialLabelOnNormalKey,
|
||||
`Key "${o.keyId}" on platform "${o.platformName}", layer "${o.layerId}" does not have `+
|
||||
`the key type "Special" or "Special (active)" but has the label "${o.label}". This feature is only supported in Keyman 14 or later`);
|
||||
|
||||
static Error_InvalidKeyCode = (o:{keyId: string}) => m(this.ERROR_InvalidKeyCode,
|
||||
`Invalid key identifier "${o.keyId}"`);
|
||||
|
||||
static Warn_TouchLayoutFontShouldBeSameForAllPlatforms = () => m(this.WARN_TouchLayoutFontShouldBeSameForAllPlatforms,
|
||||
`The touch layout font should be the same for all platforms.`);
|
||||
|
||||
static Warn_TouchLayoutMissingRequiredKeys = (o:{layerId:string, platformName:string, missingKeys:string}) => m(this.WARN_TouchLayoutMissingRequiredKeys,
|
||||
`Layer "${o.layerId}" on platform "${o.platformName}" is missing the required key(s) '${o.missingKeys}'.`);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
c Tests ERROR_NotSupportedInKeymanWebOutput for `return`
|
||||
|
||||
store(&NAME) 'ERROR_NotSupportedInKeymanWebOutput'
|
||||
store(&VERSION) '9.0'
|
||||
store(&TARGETS) 'web'
|
||||
|
||||
begin unicode > use(main)
|
||||
|
||||
group(main) using keys
|
||||
|
||||
+ 'a' > return
|
||||
|
|
@ -80,4 +80,11 @@ describe('CompilerMessages', function () {
|
|||
assert.equal(callbacks.messages[0].message, "A key on layer \"default\" has no identifier.");
|
||||
});
|
||||
|
||||
// ERROR_NotSupportedInKeymanWebOutput
|
||||
|
||||
it('should generate ERROR_NotSupportedInKeymanWebOutput if a rule has `return` in the output', async function() {
|
||||
await testForMessage(this, ['invalid-keyboards', 'error_not_supported_in_keyman_web_output.kmn'], KmnCompilerMessages.ERROR_NotSupportedInKeymanWebOutput);
|
||||
assert.equal(callbacks.messages[0].message, "Statement \"return\" is not currently supported in output");
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue