From 4befb7064cc9beed39ea762b5f6c77ca607d270a Mon Sep 17 00:00:00 2001 From: gabilang Date: Wed, 27 Sep 2023 17:12:34 +0530 Subject: [PATCH 1/6] Provide proper compilation errors for invalid interop usages --- .../bir/codegen/interop/JMethodResolver.java | 34 ++++++++----------- .../basic/NegativeValidationTest.java | 30 ++++++++++++---- .../negative/method_not_found7.bal | 25 ++++++++++++++ 3 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java index 3fb27f038d47..ddc02a299598 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java @@ -116,11 +116,11 @@ JMethod resolve(JMethodRequest jMethodRequest) { if (jMethods.isEmpty()) { if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { throw new JInteropException(DiagnosticErrorCode.CONSTRUCTOR_NOT_FOUND, - "No such public constructor found in class '" + jMethodRequest.declaringClass + "'"); + "No such public constructor found in class '" + jMethodRequest.declaringClass.getName() + "'"); } else { throw new JInteropException(DiagnosticErrorCode.METHOD_NOT_FOUND, "No such public method '" + jMethodRequest.methodName + "' found in class '" + - jMethodRequest.declaringClass + "'"); + jMethodRequest.declaringClass.getName() + "'"); } } @@ -232,12 +232,13 @@ private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { throw new JInteropException(OVERLOADED_METHODS, "Overloaded constructors with '" + paramCount + "' parameter(s) in class '" + - jMethodRequest.declaringClass + "', please specify class names for each parameter " + + jMethodRequest.declaringClass.getName() + + "', please specify class names for each parameter " + "in 'paramTypes' field in the annotation"); } else { throw new JInteropException(OVERLOADED_METHODS, "Overloaded methods '" + jMethodRequest.methodName + "' with '" + paramCount + - "' parameter(s) in class '" + jMethodRequest.declaringClass + + "' parameter(s) in class '" + jMethodRequest.declaringClass.getName() + "', please specify class names for each parameter " + "with 'paramTypes' field in the annotation"); } @@ -398,15 +399,8 @@ private void validateArgumentTypes(JMethodRequest jMethodRequest, JMethod jMetho receiverIndex = jMethodRequest.pathParamCount; } BType receiverType = bParamTypes[receiverIndex]; - boolean isLastParam = (bParamTypes.length - jMethodRequest.pathParamCount) == 1; - if (!isValidParamBType(jMethodRequest.declaringClass, receiverType, isLastParam, - jMethodRequest.restParamExist)) { - if (jParamTypes.length == 0 || bParamTypes[0].tag != TypeTags.HANDLE) { - throwMethodNotFoundError(jMethodRequest); - } else { - throwNoSuchMethodError(jMethodRequest.methodName, jParamTypes[0], receiverType, - jMethodRequest.declaringClass); - } + if (receiverType.tag != TypeTags.HANDLE) { + throwMethodNotFoundError(jMethodRequest); } for (int k = receiverIndex; k < bParamTypes.length - 1; k++) { bParamTypes[k] = bParamTypes[k + 1]; @@ -853,23 +847,23 @@ private JMethod resolveMatchingMethod(JMethodRequest jMethodRequest, List 1) { if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { throw new JInteropException(OVERLOADED_METHODS, "More than one public constructors that match with the parameter types '" + - paramTypesSig + "' found in class '" + jMethodRequest.declaringClass + "'"); + paramTypesSig + "' found in class '" + jMethodRequest.declaringClass.getName() + "'"); } else { throw new JInteropException(OVERLOADED_METHODS, "More than one public methods '" + jMethodRequest.methodName + "' that match with the parameter types '" + paramTypesSig + - "' found in class '" + jMethodRequest.declaringClass + "'"); + "' found in class '" + jMethodRequest.declaringClass.getName() + "'"); } } else { return resolvedJMethods.get(0); @@ -978,18 +972,18 @@ private void throwMethodNotFoundError(JMethodRequest jMethodRequest) throws JInt if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { throw new JInteropException(DiagnosticErrorCode.CONSTRUCTOR_NOT_FOUND, "No such public constructor with '" + jMethodRequest.bFuncParamCount + - "' parameter(s) found in class '" + jMethodRequest.declaringClass + "'"); + "' parameter(s) found in class '" + jMethodRequest.declaringClass.getName() + "'"); } else { if (jMethodRequest.bFuncParamCount == 0 || jMethodRequest.bParamTypes[0].tag != TypeTags.HANDLE) { throw new JInteropException(DiagnosticErrorCode.METHOD_NOT_FOUND, "No such public static method '" + jMethodRequest.methodName + "' with '" + jMethodRequest.bFuncParamCount + - "' parameter(s) found in class '" + jMethodRequest.declaringClass + "'"); + "' parameter(s) found in class '" + jMethodRequest.declaringClass.getName() + "'"); } else { throw new JInteropException(DiagnosticErrorCode.METHOD_NOT_FOUND, "No such public method '" + jMethodRequest.methodName + "' with '" + jMethodRequest.bFuncParamCount + - "' parameter(s) found in class '" + jMethodRequest.declaringClass + "'"); + "' parameter(s) found in class '" + jMethodRequest.declaringClass.getName() + "'"); } } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java index c73e6c70a6bf..39178084b836 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java @@ -60,7 +60,7 @@ public void testMethodNotFound1() { Assert.assertEquals(compileResult.getDiagnostics().length, 1); BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method " + - "'acceptStringOrErrorReturn' found in class 'class org.ballerinalang.nativeimpl." + + "'acceptStringOrErrorReturn' found in class 'org.ballerinalang.nativeimpl." + "jvm.tests.StaticMethods''", "method_not_found1.bal", 8, 1); } @@ -74,7 +74,7 @@ public void testMethodNotFound2() { Assert.assertEquals(compileResult.getDiagnostics().length, 1); BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public static method " + - "'acceptObjectAndObjectReturn' with '3' " + "parameter(s) found in class 'class " + + "'acceptObjectAndObjectReturn' with '3' " + "parameter(s) found in class '" + "org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''", "method_not_found2.bal", 22, 1); } @@ -90,7 +90,7 @@ public void testMethodNotFound3() { BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public static method " + "'acceptRecordAndRecordReturn' with '3' " + "parameter(s) found in class " + - "'class org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''", + "'org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''", "method_not_found3.bal", 21, 1); } @@ -104,7 +104,7 @@ public void testMethodNotFound4() { Assert.assertEquals(compileResult.getDiagnostics().length, 1); BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method " + - "'acceptIntAndUnionReturn' found in class 'class org.ballerinalang.nativeimpl.jvm." + + "'acceptIntAndUnionReturn' found in class 'org.ballerinalang.nativeimpl.jvm." + "tests.StaticMethods''", "method_not_found4.bal", 23, 1); } @@ -118,7 +118,7 @@ public void testMethodNotFound5() { Assert.assertEquals(compileResult.getDiagnostics().length, 1); BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method " + - "'acceptIntStringAndUnionReturn' found in class 'class org.ballerinalang.nativeimpl." + + "'acceptIntStringAndUnionReturn' found in class 'org.ballerinalang.nativeimpl." + "jvm.tests.StaticMethods''", "method_not_found5.bal", 23, 1); } @@ -132,7 +132,7 @@ public void testMethodNotFound6() { Assert.assertEquals(compileResult.getDiagnostics().length, 4); String message = "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method '%s' that matches with " + - "parameter types '(%s)' found in class 'class org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''"; + "parameter types '(%s)' found in class 'org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''"; String bTypeDescClassName = BTypedesc.class.getName(); String bFutureClassName = BFuture.class.getName(); @@ -152,6 +152,24 @@ public void testMethodNotFound6() { testFileName, 21, 1); } + @Test + public void testMethodNotFound7() { + + String path = "test-src/javainterop/negative/method_not_found7.bal"; + + CompileResult compileResult = BCompileUtil.compile(path); + Assert.assertEquals(compileResult.getDiagnostics().length, 2); + + String message = "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public static method '%s' with " + + "'%s' parameter(s) found in class '%s''"; + + BAssertUtil.validateError(compileResult, 0, String.format(message, "getPrintableStackTrace", "1", + "io.ballerina.runtime.api.values.BError"), "method_not_found7.bal", 19, 1); + + BAssertUtil.validateError(compileResult, 1, String.format(message, "concat", "2", + "io.ballerina.runtime.api.values.BString"), "method_not_found7.bal", 23, 1); + } + @Test public void testMethodSignatureNotMatch1() { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal new file mode 100644 index 000000000000..5b3c5c170e4d --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal @@ -0,0 +1,25 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/jballerina.java; + +function getPrintableStackTrace(error s) returns handle = @java:Method { + 'class: "io.ballerina.runtime.api.values.BError" +} external; + +function concat(string s1, string s2) returns handle = @java:Method { + 'class: "io.ballerina.runtime.api.values.BString" +} external; From bb1911acfbdc0f05d037e734a29b531c33511eec Mon Sep 17 00:00:00 2001 From: gabilang Date: Tue, 3 Oct 2023 10:08:31 +0530 Subject: [PATCH 2/6] Add and remove white spaces as per the style guide --- .../basic/NegativeValidationTest.java | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java index 39178084b836..4288bae5eb83 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java @@ -68,7 +68,6 @@ public void testMethodNotFound1() { public void testMethodNotFound2() { String path = "test-src/javainterop/negative/method_not_found2.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -83,7 +82,6 @@ public void testMethodNotFound2() { public void testMethodNotFound3() { String path = "test-src/javainterop/negative/method_not_found3.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -98,7 +96,6 @@ public void testMethodNotFound3() { public void testMethodNotFound4() { String path = "test-src/javainterop/negative/method_not_found4.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -112,7 +109,6 @@ public void testMethodNotFound4() { public void testMethodNotFound5() { String path = "test-src/javainterop/negative/method_not_found5.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -127,26 +123,20 @@ public void testMethodNotFound6() { String testFileName = "method_not_found6.bal"; String path = "test-src/javainterop/negative/" + testFileName; - CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 4); - String message = "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method '%s' that matches with " + "parameter types '(%s)' found in class 'org.ballerinalang.nativeimpl.jvm.tests.StaticMethods''"; String bTypeDescClassName = BTypedesc.class.getName(); String bFutureClassName = BFuture.class.getName(); - BAssertUtil.validateError(compileResult, 0, String.format(message, "getFuture", bTypeDescClassName), testFileName, 3, 1); - BAssertUtil.validateError(compileResult, 1, String.format(message, "getTypeDesc", bFutureClassName), testFileName, 9, 1); - BAssertUtil.validateError(compileResult, 2, String.format(message, "getFutureOnly", bFutureClassName + "," + bTypeDescClassName), testFileName, 15, 1); - BAssertUtil.validateError(compileResult, 3, String.format(message, "getTypeDescOnly", bTypeDescClassName + "," + bFutureClassName), testFileName, 21, 1); @@ -156,16 +146,12 @@ public void testMethodNotFound6() { public void testMethodNotFound7() { String path = "test-src/javainterop/negative/method_not_found7.bal"; - CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); - String message = "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public static method '%s' with " + "'%s' parameter(s) found in class '%s''"; - BAssertUtil.validateError(compileResult, 0, String.format(message, "getPrintableStackTrace", "1", "io.ballerina.runtime.api.values.BError"), "method_not_found7.bal", 19, 1); - BAssertUtil.validateError(compileResult, 1, String.format(message, "concat", "2", "io.ballerina.runtime.api.values.BString"), "method_not_found7.bal", 23, 1); } @@ -174,7 +160,6 @@ public void testMethodNotFound7() { public void testMethodSignatureNotMatch1() { String path = "test-src/javainterop/negative/method_sig_not_match1.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -190,7 +175,6 @@ public void testMethodSignatureNotMatch1() { public void testMethodSignatureNotMatch2() { String path = "test-src/javainterop/negative/method_sig_not_match2.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -207,7 +191,6 @@ public void testMethodSignatureNotMatch2() { public void testMethodSignatureNotMatch3() { String path = "test-src/javainterop/negative/method_sig_not_match3.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -224,7 +207,6 @@ public void testMethodSignatureNotMatch3() { public void testMethodSignatureNotMatch4() { String path = "test-src/javainterop/negative/method_sig_not_match4.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -241,7 +223,6 @@ public void testMethodSignatureNotMatch4() { public void testMethodSignatureNotMatch5() { String path = "test-src/javainterop/negative/method_sig_not_match5.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -258,7 +239,6 @@ public void testMethodSignatureNotMatch5() { public void testMethodSignatureNotMatch6() { String path = "test-src/javainterop/negative/method_sig_not_match6.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -275,7 +255,6 @@ public void testMethodSignatureNotMatch6() { public void testMethodSignatureNotMatch7() { String path = "test-src/javainterop/negative/method_sig_not_match15.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -290,6 +269,7 @@ public void testMethodSignatureNotMatch7() { @Test public void testMethodSignatureNotMatch8() { + CompileResult compileResult = BCompileUtil.compile("test-src/javainterop/negative/distinct_error"); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -306,7 +286,6 @@ public void testMethodSignatureNotMatch8() { public void testMethodSignatureNotMatch9() { String path = "test-src/javainterop/negative/method_sig_not_match7.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -320,7 +299,6 @@ public void testMethodSignatureNotMatch9() { public void testMethodSignatureNotMatch10() { String path = "test-src/javainterop/negative/method_sig_not_match8.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -334,7 +312,6 @@ public void testMethodSignatureNotMatch10() { public void testMethodSignatureNotMatch11() { String path = "test-src/javainterop/negative/method_sig_not_match9.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -350,7 +327,6 @@ public void testMethodSignatureNotMatch11() { public void testMethodSignatureNotMatch12() { String path = "test-src/javainterop/negative/method_sig_not_match10.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -422,6 +398,7 @@ public void testMethodSignatureNotMatch14() { @Test(description = "When there are instance and static methods with same name and parameters that differ by one") public void testResolveWithInstanceAndStatic() { + String path = "test-src/javainterop/negative/method_resolve_error.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -441,6 +418,7 @@ public void testResolveWithInstanceAndStatic() { @Test public void testNoClassDefFoundError() { + String path = "test-src/javainterop/negative/project_no_class_def_found"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -451,6 +429,7 @@ public void testNoClassDefFoundError() { @Test public void testNoClassDefFoundErrorForConstructorCalls() { + String path = "test-src/javainterop/negative/project_no_class_def_found_constructor"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -461,6 +440,7 @@ public void testNoClassDefFoundErrorForConstructorCalls() { @Test(description = "Test error in instance field set without exactly two parameters") public void testInstanceFieldSetWithoutTwoParameters() { + String path = "test-src/javainterop/negative/fieldset_error1.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -471,6 +451,7 @@ public void testInstanceFieldSetWithoutTwoParameters() { @Test(description = "Test error in instance field set with no handle type first parameter") public void testNotHandleTypeFirstParameterForInstanceFieldSet() { + String path = "test-src/javainterop/negative/fieldset_error2.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -481,6 +462,7 @@ public void testNotHandleTypeFirstParameterForInstanceFieldSet() { @Test(description = "Test error in instance field get without exactly one parameter") public void testInstanceFieldGetWithoutOneParameter() { + String path = "test-src/javainterop/negative/fieldget_error1.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -492,6 +474,7 @@ public void testInstanceFieldGetWithoutOneParameter() { @Test(description = "Test error in instance field get with no handle type parameter") public void testNoHandleTypeParameterForInstanceFieldGet() { + String path = "test-src/javainterop/negative/fieldget_error2.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -503,6 +486,7 @@ public void testNoHandleTypeParameterForInstanceFieldGet() { @Test(description = "Test error in static field set without exactly one parameter") public void testStaticFieldSetWithoutOneParameter() { + String path = "test-src/javainterop/negative/fieldset_error3.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -513,6 +497,7 @@ public void testStaticFieldSetWithoutOneParameter() { @Test(description = "Test error in static field get with any parameter") public void testStaticFieldGetWithAnyParameter() { + String path = "test-src/javainterop/negative/fieldget_error3.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -526,7 +511,6 @@ public void testStaticFieldGetWithAnyParameter() { public void testMethodSignatureNotMatch16() { String path = "test-src/javainterop/negative/method_sig_not_match16.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -544,7 +528,6 @@ public void testMethodSignatureNotMatch16() { public void testMethodSignatureNotMatch17() { String path = "test-src/javainterop/negative/method_sig_not_match17.bal"; - CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 1); From d2457f5b8040ef2d6c560706c024a791a7263682 Mon Sep 17 00:00:00 2001 From: gabilang Date: Wed, 4 Oct 2023 18:22:18 +0530 Subject: [PATCH 3/6] Add tests for constructor not found cases --- .../bir/codegen/interop/JMethodResolver.java | 4 +-- .../tests/ClassWithPrivateConstructor.java | 29 ++++++++++++++++++ .../basic/NegativeValidationTest.java | 21 +++++++++++++ .../negative/constructor_not_found.bal | 30 +++++++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithPrivateConstructor.java create mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/constructor_not_found.bal diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java index ddc02a299598..86994b95e07f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java @@ -851,8 +851,8 @@ private JMethod resolveMatchingMethod(JMethodRequest jMethodRequest, List 1) { if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithPrivateConstructor.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithPrivateConstructor.java new file mode 100644 index 000000000000..1672797c584a --- /dev/null +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithPrivateConstructor.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.nativeimpl.jvm.tests; + +/** + * This class is used for Java interoperability tests. + * + * @since 2201.9.0 + */ +public class ClassWithPrivateConstructor { + + private ClassWithPrivateConstructor() { + } +} diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java index 4288bae5eb83..89f838f2eb69 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java @@ -156,6 +156,27 @@ public void testMethodNotFound7() { "io.ballerina.runtime.api.values.BString"), "method_not_found7.bal", 23, 1); } + @Test + public void testConstructorNotFound() { + String path = "test-src/javainterop/negative/constructor_not_found.bal"; + CompileResult compileResult = BCompileUtil.compile(path); + Assert.assertEquals(compileResult.getDiagnostics().length, 3); + BAssertUtil.validateError(compileResult, 0, + "{ballerina/jballerina.java}CONSTRUCTOR_NOT_FOUND 'No such public constructor found " + + "in class 'org.ballerinalang.nativeimpl.jvm.tests.ClassWithPrivateConstructor''", + "constructor_not_found.bal", 19, 1); + BAssertUtil.validateError(compileResult, 1, + "{ballerina/jballerina.java}CONSTRUCTOR_NOT_FOUND " + + "'No such public constructor with '2' parameter(s) found in class " + + "'org.ballerinalang.nativeimpl.jvm.tests.ClassWithOneParamConstructor''", + "constructor_not_found.bal", 23, 1); + BAssertUtil.validateError(compileResult, 2, + "{ballerina/jballerina.java}CONSTRUCTOR_NOT_FOUND " + + "'No such public constructor that matches with parameter types '(int)' found in class " + + "'org.ballerinalang.nativeimpl.jvm.tests.ClassWithDefaultConstructor''", + "constructor_not_found.bal", 27, 1); + } + @Test public void testMethodSignatureNotMatch1() { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/constructor_not_found.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/constructor_not_found.bal new file mode 100644 index 000000000000..900bd88024a0 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/constructor_not_found.bal @@ -0,0 +1,30 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/jballerina.java; + +function getConstructor() returns handle = @java:Constructor { + 'class: "org.ballerinalang.nativeimpl.jvm.tests.ClassWithPrivateConstructor" +} external; + +function getConstructorWithDifferentArgsCount(string name, int age) returns handle = @java:Constructor { + 'class: "org.ballerinalang.nativeimpl.jvm.tests.ClassWithOneParamConstructor" +} external; + +function getConstructorWithArgs() returns handle = @java:Constructor { + 'class: "org.ballerinalang.nativeimpl.jvm.tests.ClassWithDefaultConstructor", + paramTypes: ["int"] +} external; From 7ca42bce645641bb90c2e4cb38ad72d341f31d8c Mon Sep 17 00:00:00 2001 From: gabilang Date: Mon, 9 Oct 2023 15:49:57 +0530 Subject: [PATCH 4/6] Remove white spaces per discussion --- .../basic/NegativeValidationTest.java | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java index 89f838f2eb69..7250aef9db2d 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java @@ -34,7 +34,6 @@ public class NegativeValidationTest { @Test public void testAcceptNothing() { - String path = "test-src/javainterop/ballerina_types_as_interop_types_negative.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 12); @@ -42,7 +41,6 @@ public void testAcceptNothing() { @Test public void testClassNotFound() { - String path = "test-src/javainterop/negative/class_not_found.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -53,7 +51,6 @@ public void testClassNotFound() { @Test public void testMethodNotFound1() { - String path = "test-src/javainterop/negative/method_not_found1.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -66,7 +63,6 @@ public void testMethodNotFound1() { @Test public void testMethodNotFound2() { - String path = "test-src/javainterop/negative/method_not_found2.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -80,7 +76,6 @@ public void testMethodNotFound2() { @Test public void testMethodNotFound3() { - String path = "test-src/javainterop/negative/method_not_found3.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -94,7 +89,6 @@ public void testMethodNotFound3() { @Test public void testMethodNotFound4() { - String path = "test-src/javainterop/negative/method_not_found4.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -107,7 +101,6 @@ public void testMethodNotFound4() { @Test public void testMethodNotFound5() { - String path = "test-src/javainterop/negative/method_not_found5.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -120,7 +113,6 @@ public void testMethodNotFound5() { @Test public void testMethodNotFound6() { - String testFileName = "method_not_found6.bal"; String path = "test-src/javainterop/negative/" + testFileName; CompileResult compileResult = BCompileUtil.compile(path); @@ -144,7 +136,6 @@ public void testMethodNotFound6() { @Test public void testMethodNotFound7() { - String path = "test-src/javainterop/negative/method_not_found7.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -179,7 +170,6 @@ public void testConstructorNotFound() { @Test public void testMethodSignatureNotMatch1() { - String path = "test-src/javainterop/negative/method_sig_not_match1.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -194,7 +184,6 @@ public void testMethodSignatureNotMatch1() { @Test public void testMethodSignatureNotMatch2() { - String path = "test-src/javainterop/negative/method_sig_not_match2.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -210,7 +199,6 @@ public void testMethodSignatureNotMatch2() { @Test public void testMethodSignatureNotMatch3() { - String path = "test-src/javainterop/negative/method_sig_not_match3.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -226,7 +214,6 @@ public void testMethodSignatureNotMatch3() { @Test public void testMethodSignatureNotMatch4() { - String path = "test-src/javainterop/negative/method_sig_not_match4.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -242,7 +229,6 @@ public void testMethodSignatureNotMatch4() { @Test public void testMethodSignatureNotMatch5() { - String path = "test-src/javainterop/negative/method_sig_not_match5.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -258,7 +244,6 @@ public void testMethodSignatureNotMatch5() { @Test public void testMethodSignatureNotMatch6() { - String path = "test-src/javainterop/negative/method_sig_not_match6.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -274,7 +259,6 @@ public void testMethodSignatureNotMatch6() { @Test public void testMethodSignatureNotMatch7() { - String path = "test-src/javainterop/negative/method_sig_not_match15.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -290,7 +274,6 @@ public void testMethodSignatureNotMatch7() { @Test public void testMethodSignatureNotMatch8() { - CompileResult compileResult = BCompileUtil.compile("test-src/javainterop/negative/distinct_error"); compileResult.getDiagnostics(); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -305,7 +288,6 @@ public void testMethodSignatureNotMatch8() { @Test public void testMethodSignatureNotMatch9() { - String path = "test-src/javainterop/negative/method_sig_not_match7.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -318,7 +300,6 @@ public void testMethodSignatureNotMatch9() { @Test public void testMethodSignatureNotMatch10() { - String path = "test-src/javainterop/negative/method_sig_not_match8.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -331,7 +312,6 @@ public void testMethodSignatureNotMatch10() { @Test public void testMethodSignatureNotMatch11() { - String path = "test-src/javainterop/negative/method_sig_not_match9.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -346,7 +326,6 @@ public void testMethodSignatureNotMatch11() { @Test public void testMethodSignatureNotMatch12() { - String path = "test-src/javainterop/negative/method_sig_not_match10.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -361,7 +340,6 @@ public void testMethodSignatureNotMatch12() { @Test public void testReturnStringForBUnionFromJava() { - String path = "test-src/javainterop/negative/method_sig_not_match11.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -376,7 +354,6 @@ public void testReturnStringForBUnionFromJava() { @Test public void testJavaPrimitiveForBJsonParam() { - String path = "test-src/javainterop/negative/method_sig_not_match12.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -390,7 +367,6 @@ public void testJavaPrimitiveForBJsonParam() { @Test public void testJavaPrimitiveForBUnionParam() { - String path = "test-src/javainterop/negative/method_sig_not_match13.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -404,7 +380,6 @@ public void testJavaPrimitiveForBUnionParam() { @Test public void testMethodSignatureNotMatch14() { - String path = "test-src/javainterop/negative/method_sig_not_match14.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -419,7 +394,6 @@ public void testMethodSignatureNotMatch14() { @Test(description = "When there are instance and static methods with same name and parameters that differ by one") public void testResolveWithInstanceAndStatic() { - String path = "test-src/javainterop/negative/method_resolve_error.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -439,7 +413,6 @@ public void testResolveWithInstanceAndStatic() { @Test public void testNoClassDefFoundError() { - String path = "test-src/javainterop/negative/project_no_class_def_found"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -450,7 +423,6 @@ public void testNoClassDefFoundError() { @Test public void testNoClassDefFoundErrorForConstructorCalls() { - String path = "test-src/javainterop/negative/project_no_class_def_found_constructor"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -461,7 +433,6 @@ public void testNoClassDefFoundErrorForConstructorCalls() { @Test(description = "Test error in instance field set without exactly two parameters") public void testInstanceFieldSetWithoutTwoParameters() { - String path = "test-src/javainterop/negative/fieldset_error1.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -472,7 +443,6 @@ public void testInstanceFieldSetWithoutTwoParameters() { @Test(description = "Test error in instance field set with no handle type first parameter") public void testNotHandleTypeFirstParameterForInstanceFieldSet() { - String path = "test-src/javainterop/negative/fieldset_error2.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -483,7 +453,6 @@ public void testNotHandleTypeFirstParameterForInstanceFieldSet() { @Test(description = "Test error in instance field get without exactly one parameter") public void testInstanceFieldGetWithoutOneParameter() { - String path = "test-src/javainterop/negative/fieldget_error1.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -495,7 +464,6 @@ public void testInstanceFieldGetWithoutOneParameter() { @Test(description = "Test error in instance field get with no handle type parameter") public void testNoHandleTypeParameterForInstanceFieldGet() { - String path = "test-src/javainterop/negative/fieldget_error2.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -507,7 +475,6 @@ public void testNoHandleTypeParameterForInstanceFieldGet() { @Test(description = "Test error in static field set without exactly one parameter") public void testStaticFieldSetWithoutOneParameter() { - String path = "test-src/javainterop/negative/fieldset_error3.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 1); @@ -518,7 +485,6 @@ public void testStaticFieldSetWithoutOneParameter() { @Test(description = "Test error in static field get with any parameter") public void testStaticFieldGetWithAnyParameter() { - String path = "test-src/javainterop/negative/fieldget_error3.bal"; CompileResult compileResult = BCompileUtil.compile(path); Assert.assertEquals(compileResult.getDiagnostics().length, 2); @@ -530,7 +496,6 @@ public void testStaticFieldGetWithAnyParameter() { @Test public void testMethodSignatureNotMatch16() { - String path = "test-src/javainterop/negative/method_sig_not_match16.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); @@ -547,7 +512,6 @@ public void testMethodSignatureNotMatch16() { @Test public void testMethodSignatureNotMatch17() { - String path = "test-src/javainterop/negative/method_sig_not_match17.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); From e6cc3adc2027382e50dc6f463b0e120de307f66f Mon Sep 17 00:00:00 2001 From: gabilang Date: Tue, 10 Oct 2023 09:41:20 +0530 Subject: [PATCH 5/6] Add more interop test cases --- .../bir/codegen/interop/JMethodResolver.java | 9 +++-- .../nativeimpl/jvm/tests/StaticMethods.java | 8 +++++ .../basic/NegativeValidationTest.java | 16 +++++++++ .../negative/overloaded_methods.bal | 33 +++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/overloaded_methods.bal diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java index 86994b95e07f..2b81822f1562 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java @@ -232,13 +232,12 @@ private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { throw new JInteropException(OVERLOADED_METHODS, "Overloaded constructors with '" + paramCount + "' parameter(s) in class '" + - jMethodRequest.declaringClass.getName() + - "', please specify class names for each parameter " + + jMethodRequest.declaringClass + "', please specify class names for each parameter " + "in 'paramTypes' field in the annotation"); } else { throw new JInteropException(OVERLOADED_METHODS, "Overloaded methods '" + jMethodRequest.methodName + "' with '" + paramCount + - "' parameter(s) in class '" + jMethodRequest.declaringClass.getName() + + "' parameter(s) in class '" + jMethodRequest.declaringClass + "', please specify class names for each parameter " + "with 'paramTypes' field in the annotation"); } @@ -858,12 +857,12 @@ private JMethod resolveMatchingMethod(JMethodRequest jMethodRequest, List Date: Thu, 12 Oct 2023 18:03:43 +0530 Subject: [PATCH 6/6] Add tests to cover missing lines --- .../test/javainterop/basic/NegativeValidationTest.java | 6 +++++- .../test-src/javainterop/negative/method_not_found7.bal | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java index 9745e33a9da1..4dbc55f32ea5 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java @@ -138,13 +138,17 @@ public void testMethodNotFound6() { public void testMethodNotFound7() { String path = "test-src/javainterop/negative/method_not_found7.bal"; CompileResult compileResult = BCompileUtil.compile(path); - Assert.assertEquals(compileResult.getDiagnostics().length, 2); + Assert.assertEquals(compileResult.getDiagnostics().length, 3); String message = "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public static method '%s' with " + "'%s' parameter(s) found in class '%s''"; BAssertUtil.validateError(compileResult, 0, String.format(message, "getPrintableStackTrace", "1", "io.ballerina.runtime.api.values.BError"), "method_not_found7.bal", 19, 1); BAssertUtil.validateError(compileResult, 1, String.format(message, "concat", "2", "io.ballerina.runtime.api.values.BString"), "method_not_found7.bal", 23, 1); + BAssertUtil.validateError(compileResult, 2, + "{ballerina/jballerina.java}METHOD_NOT_FOUND 'No such public method 'concat' " + + "with '3' parameter(s) found in class 'io.ballerina.runtime.api.values.BString''", + "method_not_found7.bal", 27, 1); } @Test diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal index 5b3c5c170e4d..c6cc062a3d30 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_not_found7.bal @@ -23,3 +23,8 @@ function getPrintableStackTrace(error s) returns handle = @java:Method { function concat(string s1, string s2) returns handle = @java:Method { 'class: "io.ballerina.runtime.api.values.BString" } external; + +function concatString(handle h, string s1, string s2) returns handle = @java:Method { + 'class: "io.ballerina.runtime.api.values.BString", + name: "concat" +} external;