From 186132dcb96090774662097108171a3e42e0b5ca Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 3 Nov 2023 12:29:56 +0700 Subject: [PATCH] fix(developer): kmc code generation for context(n) in context Fixes #9930. * Fixes the index offset calculation, with +1 for >=v10.0 keyboards and -1 for use(main) + +group(main) using keys + +store(liveQwerty) 'qwerty' +store(deadQwerty) dk(q) dk(w) dk(e) dk(r) dk(t) dk(y) + +c any/index with deadkeys in stores. +any(liveQwerty) + '!' > '?' index(deadQwerty, 1) index(deadQwerty, 1) + +c The rule below is misgenerated by kmc-17.0.205-alpha on `context(2)` statement; +c see https://github.com/keymanapp/keyman/issues/9930 +'?' any(deadQwerty) context(2) + '.' > '(' index(liveQwerty, 2) index(liveQwerty, 2) ')' diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.js b/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.js new file mode 100644 index 00000000000..d4a6983ffe1 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.js @@ -0,0 +1,47 @@ + +KeymanWeb.KR(new Keyboard_test_context_in_context_9()); + +function Keyboard_test_context_in_context_9() +{ + + this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9; + this.KI="Keyboard_test_context_in_context_9"; + this.KN="test context(n) in context, #9930, v9.0"; + this.KMINVER="9.0"; + this.KV=null; + this.KDU=0; + this.KH=''; + this.KM=0; + this.KBVER="1.0"; + this.KMBM=0x0010; + this.s_liveQwerty_6="qwerty"; + this.s_deadQwerty_7="123456"; + this.KVS=[]; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.g_main_0=function(t,e) { + var k=KeymanWeb,r=0,m=0; + if(k.KKM(e, 0x4010, 0x31)) { + if(k.KA(0,k.KC(1,1,t),this.s_liveQwerty_6)){ + r=m=1; // Line 13 + k.KO(1,t,"?"); + k.KIO(-1,this.s_deadQwerty_7,1,t); + k.KIO(-1,this.s_deadQwerty_7,1,t); + } + } + else if(k.KKM(e, 0x4000, 0xBE)) { + if(k.KCM(3,t,"?",1)&&k.KA(1,k.KC(2,1,t),this.s_deadQwerty_7)&&k.KCCM(1,2,t)){ + r=m=1; // Line 17 + k.KO(3,t,"("); + k.KIO(-1,this.s_liveQwerty_6,2,t); + k.KIO(-1,this.s_liveQwerty_6,2,t); + k.KO(-1,t,")"); + } + } + return r; + }; +} diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.kmn new file mode 100644 index 00000000000..6b06eb6cec0 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_context_in_context_9.kmn @@ -0,0 +1,17 @@ +store(&VERSION) "9.0" +store(&TARGETS) 'web' +store(&NAME) 'test context(n) in context, #9930, v9.0' + +begin Unicode > use(main) + +group(main) using keys + +store(liveQwerty) 'qwerty' +store(deadQwerty) '123456' + +c any/index with deadkeys in stores. +any(liveQwerty) + '!' > '?' index(deadQwerty, 1) index(deadQwerty, 1) + +c The rule below is misgenerated by kmc-17.0.205-alpha on `context(2)` statement; +c see https://github.com/keymanapp/keyman/issues/9930 +'?' any(deadQwerty) context(2) + '.' > '(' index(liveQwerty, 2) index(liveQwerty, 2) ')' diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.js b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.js new file mode 100644 index 00000000000..da0c1b9477f --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.js @@ -0,0 +1,44 @@ +if(typeof keyman === 'undefined') { + console.log('Keyboard requires KeymanWeb 10.0 or later'); + if(typeof tavultesoft !== 'undefined') tavultesoft.keymanweb.util.alert("This keyboard requires KeymanWeb 10.0 or later"); +} else { +KeymanWeb.KR(new Keyboard_test_contextn_in_output()); +} +function Keyboard_test_contextn_in_output() +{ + var modCodes = keyman.osk.modifierCodes; + var keyCodes = keyman.osk.keyCodes; + + this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9; + this.KI="Keyboard_test_contextn_in_output"; + this.KN="test context(n) in output, #9930, v10.0"; + this.KMINVER="10.0"; + this.KV=null; + this.KDU=0; + this.KH=''; + this.KM=0; + this.KBVER="1.0"; + this.KMBM=modCodes.SHIFT /* 0x0010 */; + this.s_liveQwerty_6="qwerty"; + this.s_deadQwerty_7=[{t:'d',d:0},{t:'d',d:1},{t:'d',d:2},{t:'d',d:3},{t:'d',d:4},{t:'d',d:5}]; + this.KVS=[]; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.g_main_0=function(t,e) { + var k=KeymanWeb,r=0,m=0; + if(k.KKM(e, modCodes.SHIFT | modCodes.VIRTUAL_KEY /* 0x4010 */, keyCodes.K_1 /* 0x31 */)) { + if(k.KFCM(2,t,[{t:'a',a:this.s_liveQwerty_6},'1'])){ + r=m=1; // Line 13 + k.KDC(2,t); + k.KO(-1,t,"?"); + k.KIO(-1,this.s_deadQwerty_7,1,t); + k.KO(-1,t,"1"); + } + } + return r; + }; +} diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.kmn new file mode 100644 index 00000000000..4a34730922b --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output.kmn @@ -0,0 +1,13 @@ +store(&VERSION) "10.0" +store(&TARGETS) 'web' +store(&NAME) 'test context(n) in output, #9930, v10.0' + +begin Unicode > use(main) + +group(main) using keys + +store(liveQwerty) 'qwerty' +store(deadQwerty) dk(q) dk(w) dk(e) dk(r) dk(t) dk(y) + +c any/index with deadkeys in stores. +any(liveQwerty) '1' + '!' > '?' index(deadQwerty, 1) context(2) diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.js b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.js new file mode 100644 index 00000000000..07755dc1752 --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.js @@ -0,0 +1,38 @@ + +KeymanWeb.KR(new Keyboard_test_contextn_in_output_9()); + +function Keyboard_test_contextn_in_output_9() +{ + + this._v=(typeof keyman!="undefined"&&typeof keyman.version=="string")?parseInt(keyman.version,10):9; + this.KI="Keyboard_test_contextn_in_output_9"; + this.KN="test context(n) in output, #9930, v9.0"; + this.KMINVER="9.0"; + this.KV=null; + this.KDU=0; + this.KH=''; + this.KM=0; + this.KBVER="1.0"; + this.KMBM=0x0010; + this.s_liveQwerty_6="qwerty"; + this.s_deadQwerty_7="123456"; + this.KVS=[]; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.gs=function(t,e) { + return this.g_main_0(t,e); + }; + this.g_main_0=function(t,e) { + var k=KeymanWeb,r=0,m=0; + if(k.KKM(e, 0x4010, 0x31)) { + if(k.KA(0,k.KC(2,1,t),this.s_liveQwerty_6)&&k.KCM(1,t,"1",1)){ + r=m=1; // Line 13 + k.KO(2,t,"?"); + k.KIO(-1,this.s_deadQwerty_7,1,t); + k.KO(-1,t,"1"); + } + } + return r; + }; +} diff --git a/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.kmn b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.kmn new file mode 100644 index 00000000000..971d11694aa --- /dev/null +++ b/developer/src/kmc-kmn/test/fixtures/kmw/test_contextn_in_output_9.kmn @@ -0,0 +1,13 @@ +store(&VERSION) "9.0" +store(&TARGETS) 'web' +store(&NAME) 'test context(n) in output, #9930, v9.0' + +begin Unicode > use(main) + +group(main) using keys + +store(liveQwerty) 'qwerty' +store(deadQwerty) '123456' + +c any/index with deadkeys in stores. +any(liveQwerty) '1' + '!' > '?' index(deadQwerty, 1) context(2) diff --git a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts index 42aa489a911..a7eecda019e 100644 --- a/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts +++ b/developer/src/kmc-kmn/test/kmw/test-kmw-compiler.ts @@ -35,11 +35,11 @@ describe('KeymanWeb Compiler', function() { callbacks.clear(); }); - it('should compile a complex keyboard', async function() { + it('should compile a complex keyboard', function() { run_test_keyboard(kmnCompiler, 'khmer_angkor'); }); - it('should handle option stores', async function() { + it('should handle option stores', function() { // // This is enough to verify that the option store is set appropriately with // KLOAD because the fixture has that code present: @@ -49,7 +49,7 @@ describe('KeymanWeb Compiler', function() { run_test_keyboard(kmnCompiler, 'test_options'); }); - it('should translate every "character style" key correctly', async function() { + it('should translate every "character style" key correctly', function() { // // This is enough to verify that every character style key is encoded in the // same way as the fixture. @@ -57,9 +57,25 @@ describe('KeymanWeb Compiler', function() { run_test_keyboard(kmnCompiler, 'test_keychars'); }); - it('should handle readonly groups', async function() { + it('should handle readonly groups', function() { run_test_keyboard(kmnCompiler, 'test_readonly_groups'); }); + + it('should handle context(n) in output of rule, v10.0 generation', function() { + run_test_keyboard(kmnCompiler, 'test_contextn_in_output'); + }); + + it('should handle context(n) in output of rule, v9.0 generation', function() { + run_test_keyboard(kmnCompiler, 'test_contextn_in_output_9'); + }); + + it('should handle context(n) in context part of rule, v9.0 generation', function() { + run_test_keyboard(kmnCompiler, 'test_context_in_context_9'); + }); + + it('should handle context(n) in context part of rule, v10.0 generation', function() { + run_test_keyboard(kmnCompiler, 'test_context_in_context'); + }); });