From 7e32392557546c20542b79a935db2821acd3d8be Mon Sep 17 00:00:00 2001 From: Roee-BY <63245129+Roee-BY@users.noreply.github.com> Date: Sun, 10 Apr 2022 14:47:17 +0300 Subject: [PATCH 1/5] fixed a problem with the invocation of overloaded functions the function invocation mechanism was choosing the first compatible func according the the args and available overloads but there was a bug since some types that are available in java are unified into one type in JS for example JS number can be int double float or long hence choosing the first might cause a problem (in my case an android app crashes due to the incorrect overload). instead of the current mechanism i have implemented a mechanism that goes over all of the overloads and if there is more then one matching overload it invokes the method throwIfDispatcherAmbiguous(dispatcher) which will alert the user about the multiple a available overloads and ask his to choose which one to use. --- lib/class-factory.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/class-factory.js b/lib/class-factory.js index c066ad4c..2f213c3f 100644 --- a/lib/class-factory.js +++ b/lib/class-factory.js @@ -1388,15 +1388,28 @@ dispatcherPrototype = Object.create(Function.prototype, { const overloads = this._o; const isInstance = receiver.$h !== null; + + const MethodsThatCanBeInvoked=[]; for (let i = 0; i !== overloads.length; i++) { const method = overloads[i]; - if (!method.canInvokeWith(args)) { - continue; - } - - if (method.type === INSTANCE_METHOD && !isInstance) { + if (method.canInvokeWith(args)) { + if (MethodsThatCanBeInvoked.length > 0) { + throwIfDispatcherAmbiguous(this); + } + + MethodsThatCanBeInvoked.push(method); + } + } + + if (MethodsThatCanBeInvoked.length === 0){ + throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); + } + + const method = MethodsThatCanBeInvoked[0]; + + if (method.type === INSTANCE_METHOD && !isInstance) { const name = this.methodName; if (name === 'toString') { @@ -1404,12 +1417,9 @@ dispatcherPrototype = Object.create(Function.prototype, { } throw new Error(name + ': cannot call instance method without an instance'); - } - - return method.apply(receiver, args); - } + } - throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); + return method.apply(receiver, args); } } }); From e96b8e34f9caa3d6819767b72e0d8bb622304990 Mon Sep 17 00:00:00 2001 From: Roee-BY <63245129+Roee-BY@users.noreply.github.com> Date: Mon, 11 Apr 2022 12:23:38 +0300 Subject: [PATCH 2/5] fixed code format --- lib/class-factory.js | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/class-factory.js b/lib/class-factory.js index 2f213c3f..a050bb9c 100644 --- a/lib/class-factory.js +++ b/lib/class-factory.js @@ -1386,40 +1386,38 @@ dispatcherPrototype = Object.create(Function.prototype, { invoke: { value (receiver, args) { const overloads = this._o; - - const isInstance = receiver.$h !== null; - - const MethodsThatCanBeInvoked=[]; + const isInstance = receiver.$h !== null; + const methodsThatCanBeInvoked=[]; for (let i = 0; i !== overloads.length; i++) { const method = overloads[i]; if (method.canInvokeWith(args)) { - if (MethodsThatCanBeInvoked.length > 0) { + if (methodsThatCanBeInvoked.length > 0) { throwIfDispatcherAmbiguous(this); } - MethodsThatCanBeInvoked.push(method); + methodsThatCanBeInvoked.push(method); } } - if (MethodsThatCanBeInvoked.length === 0){ + if (methodsThatCanBeInvoked.length === 0) { throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); } - const method = MethodsThatCanBeInvoked[0]; + const method = methodsThatCanBeInvoked[0]; if (method.type === INSTANCE_METHOD && !isInstance) { - const name = this.methodName; + const name = this.methodName; - if (name === 'toString') { - return ``; - } + if (name === 'toString') { + return ``; + } - throw new Error(name + ': cannot call instance method without an instance'); - } + throw new Error(name + ': cannot call instance method without an instance'); + } - return method.apply(receiver, args); + return method.apply(receiver, args); } } }); From 0d626ce2ef8a7159bf77bde6c423f2edb003e6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Andr=C3=A9=20Vadla=20Ravn=C3=A5s?= Date: Thu, 22 Sep 2022 12:10:39 +0200 Subject: [PATCH 3/5] Refactor a bit --- lib/class-factory.js | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/lib/class-factory.js b/lib/class-factory.js index a050bb9c..4e45b107 100644 --- a/lib/class-factory.js +++ b/lib/class-factory.js @@ -1386,27 +1386,15 @@ dispatcherPrototype = Object.create(Function.prototype, { invoke: { value (receiver, args) { const overloads = this._o; - const isInstance = receiver.$h !== null; - const methodsThatCanBeInvoked=[]; - - for (let i = 0; i !== overloads.length; i++) { - const method = overloads[i]; - - if (method.canInvokeWith(args)) { - if (methodsThatCanBeInvoked.length > 0) { - throwIfDispatcherAmbiguous(this); - } - - methodsThatCanBeInvoked.push(method); - } - } - + const methodsThatCanBeInvoked = overloads.filter(method => method.canInvokeWith(args)); if (methodsThatCanBeInvoked.length === 0) { throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); + } else if (methodsThatCanBeInvoked.length > 1) { + throwIfDispatcherAmbiguous(this); } - const method = methodsThatCanBeInvoked[0]; - + + const isInstance = receiver.$h !== null; if (method.type === INSTANCE_METHOD && !isInstance) { const name = this.methodName; From 3a2b99f247454e34f5753aec902bde20384ad616 Mon Sep 17 00:00:00 2001 From: Roee-BY <63245129+Roee-BY@users.noreply.github.com> Date: Mon, 6 Feb 2023 01:26:16 +0200 Subject: [PATCH 4/5] Warning istead of throwing an Error --- lib/class-factory.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/class-factory.js b/lib/class-factory.js index 4e45b107..1d6a23f3 100644 --- a/lib/class-factory.js +++ b/lib/class-factory.js @@ -1390,7 +1390,9 @@ dispatcherPrototype = Object.create(Function.prototype, { if (methodsThatCanBeInvoked.length === 0) { throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); } else if (methodsThatCanBeInvoked.length > 1) { - throwIfDispatcherAmbiguous(this); + console.warn("Multiple overloads fit the invocation of " + receiver + + ",\n The overload that will be used is: " + methodsThatCanBeInvoked[0] + + ",\n To avoid this warining please choose one of the follwoing overloads and invoke it specifically: " + methodsThatCanBeInvoked); } const method = methodsThatCanBeInvoked[0]; From 5e7eecda585509cf6fb03137e1f6750ec24b273e Mon Sep 17 00:00:00 2001 From: Roee-BY Date: Wed, 15 May 2024 00:59:13 +0300 Subject: [PATCH 5/5] Update class-factory.js CR --- lib/class-factory.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/class-factory.js b/lib/class-factory.js index 1d6a23f3..a730d3b5 100644 --- a/lib/class-factory.js +++ b/lib/class-factory.js @@ -1388,11 +1388,11 @@ dispatcherPrototype = Object.create(Function.prototype, { const overloads = this._o; const methodsThatCanBeInvoked = overloads.filter(method => method.canInvokeWith(args)); if (methodsThatCanBeInvoked.length === 0) { - throwOverloadError(this.methodName, this.overloads, 'argument types do not match any of:'); + throwOverloadError(this.methodName, overloads, 'argument types do not match any of:'); } else if (methodsThatCanBeInvoked.length > 1) { - console.warn("Multiple overloads fit the invocation of " + receiver + - ",\n The overload that will be used is: " + methodsThatCanBeInvoked[0] + - ",\n To avoid this warining please choose one of the follwoing overloads and invoke it specifically: " + methodsThatCanBeInvoked); + console.warn(`Multiple overloads fit the invocation of ${receiver}`, + `\nThe overload that will be used is: ${methodsThatCanBeInvoked[0]}`, + `\nTo avoid this warning please choose one of the following overloads and invoke it specifically: \n\t${methodsThatCanBeInvoked.join('\n\t')}`); } const method = methodsThatCanBeInvoked[0]; @@ -1404,7 +1404,7 @@ dispatcherPrototype = Object.create(Function.prototype, { return ``; } - throw new Error(name + ': cannot call instance method without an instance'); + throw new Error(`${name}: cannot call instance method without an instance`); } return method.apply(receiver, args);