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 5d3136763de8..d41a5e17ad72 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 @@ -50,10 +50,8 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.StringJoiner; @@ -83,8 +81,8 @@ */ class JMethodResolver { - private ClassLoader classLoader; - private SymbolTable symbolTable; + private final ClassLoader classLoader; + private final SymbolTable symbolTable; private final BType[] definedReadOnlyMemberTypes; JMethodResolver(ClassLoader classLoader, SymbolTable symbolTable) { @@ -224,24 +222,10 @@ private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { if (jMethods.size() == 1 && noConstraints) { return jMethods.get(0); } else if (noConstraints) { - Optional covariantRetTypeMethod = findCovariantReturnTypeMethod(jMethods); - if (covariantRetTypeMethod.isPresent()) { - return covariantRetTypeMethod.get(); - } - - int paramCount = jMethods.get(0).getParamTypes().length; - 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 " + - "in 'paramTypes' field in the annotation"); - } else { - throw new JInteropException(OVERLOADED_METHODS, - "Overloaded methods '" + jMethodRequest.methodName + "' with '" + paramCount + - "' parameter(s) in class '" + jMethodRequest.declaringClass + - "', please specify class names for each parameter " + - "with 'paramTypes' field in the annotation"); + if (areAllMethodsOverridden(jMethods, jMethodRequest.declaringClass)) { + return jMethods.get(0); } + throwOverloadedMethodError(jMethodRequest, jMethods.get(0).getParamTypes().length); } JMethod jMethod = resolveExactMethod(jMethodRequest.declaringClass, jMethodRequest.methodName, @@ -252,28 +236,51 @@ private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { return jMethod; } - private Optional findCovariantReturnTypeMethod(List jMethods) { + private boolean areAllMethodsOverridden(List jMethods, Class clazz) { + if (jMethods.get(0).getKind() == JMethodKind.CONSTRUCTOR) { + return false; + } for (int i = 0; i < jMethods.size(); i++) { + Method method1 = (Method) jMethods.get(i).getMethod(); for (int k = i + 1; k < jMethods.size(); k++) { - JMethod ithMethod = jMethods.get(i); - JMethod kthMethod = jMethods.get(k); - - if (ithMethod.getReturnType().isAssignableFrom(kthMethod.getReturnType()) || - kthMethod.getReturnType().isAssignableFrom(ithMethod.getReturnType())) { - if (ithMethod.getParamTypes().length != kthMethod.getParamTypes().length) { - // This occurs when there are static methods and instance methods and the static method - // has one more parameter than the instance method. Also this occurs when an interop - // method in an object maps to instance methods of which one accepting self and another - // that doesn't. - throw new JInteropException( - OVERLOADED_METHODS, "Overloaded methods cannot be differentiated. Please specify the " + - "parameterTypes for each parameter in 'paramTypes' field in the annotation"); - } - return Optional.of(ithMethod); + Method method2 = (Method) jMethods.get(k).getMethod(); + if (!isOverridden(method1, method2, clazz)) { + return false; } } } - return Optional.empty(); + return true; + } + + private boolean isOverridden(Method method1, Method method2, Class clazz) { + if (method1.getParameterCount() != method2.getParameterCount()) { + // This occurs when there are static methods and instance methods, and the static method has one more + // parameter than the instance method. Additionally, this occurs when an interop method in an object + // maps to instance methods, one accepting `self` and another that doesn't. + throw new JInteropException(OVERLOADED_METHODS, "Overloaded methods cannot be differentiated. " + + "Please specify the parameter types for each parameter in 'paramTypes' field in the annotation"); + } + // Returns false if return types are not covariant + Method currentMethod; + Method otherMethod; + if (method2.getReturnType().isAssignableFrom(method1.getReturnType())) { + currentMethod = method1; + otherMethod = method2; + } else if (method1.getReturnType().isAssignableFrom(method2.getReturnType())) { + currentMethod = method2; + otherMethod = method1; + } else { + return false; + } + + try { + Method superMethod = clazz.getSuperclass() + .getDeclaredMethod(currentMethod.getName(), currentMethod.getParameterTypes()); + return Arrays.equals(superMethod.getParameterTypes(), otherMethod.getParameterTypes()) && + superMethod.getReturnType().equals(otherMethod.getReturnType()); + } catch (NoSuchMethodException e) { + return false; + } } private void validateMethodSignature(JMethodRequest jMethodRequest, JMethod jMethod) { @@ -317,8 +324,7 @@ private void validateExceptionTypes(JMethodRequest jMethodRequest, JMethod jMeth "': expected '" + expectedRetTypeName + "', found '" + returnType + "'"); } else if (jMethodRequest.returnsBErrorType && !throwsCheckedException && !returnsErrorValue) { String errorMsgPart; - if (returnType instanceof BUnionType) { - BUnionType bUnionReturnType = (BUnionType) returnType; + if (returnType instanceof BUnionType bUnionReturnType) { BType modifiedRetType = BUnionType.create(null, getNonErrorMembers(bUnionReturnType)); errorMsgPart = "expected '" + modifiedRetType + "', found '" + returnType + "'"; } else { @@ -335,8 +341,7 @@ private String getExpectedReturnType(BType retType) { if (retType.tag == TypeTags.NIL || (retType instanceof BTypeReferenceType && ((BTypeReferenceType) retType).referredType.tag == TypeTags.ERROR)) { return "error"; - } else if (retType instanceof BUnionType) { - BUnionType bUnionReturnType = (BUnionType) retType; + } else if (retType instanceof BUnionType bUnionReturnType) { BType modifiedRetType = BUnionType.create(null, getNonErrorMembers(bUnionReturnType)); return modifiedRetType + "|error"; } else { @@ -520,6 +525,7 @@ private boolean isValidParamBType(Class jType, BType bType, boolean isLastPar case TypeTags.RECORD: return this.classLoader.loadClass(BMap.class.getCanonicalName()).isAssignableFrom(jType); case TypeTags.JSON: + case TypeTags.READONLY: return jTypeName.equals(J_OBJECT_TNAME); case TypeTags.OBJECT: return this.classLoader.loadClass(BObject.class.getCanonicalName()).isAssignableFrom(jType); @@ -547,16 +553,13 @@ private boolean isValidParamBType(Class jType, BType bType, boolean isLastPar } } return true; - case TypeTags.READONLY: - return jTypeName.equals(J_OBJECT_TNAME); case TypeTags.FINITE: if (jTypeName.equals(J_OBJECT_TNAME)) { return true; } Set valueSpace = ((BFiniteType) bType).getValueSpace(); - for (Iterator iterator = valueSpace.iterator(); iterator.hasNext(); ) { - BLangExpression value = iterator.next(); + for (BLangExpression value : valueSpace) { if (!isValidParamBType(jType, value.getBType(), isLastParam, restParamExist)) { return false; } @@ -669,11 +672,7 @@ private boolean isValidReturnBType(Class jType, BType bType, JMethodRequest j return true; } - if (isValidReturnBType(jType, symbolTable.jsonType, jMethodRequest, visitedSet)) { - return true; - } - - return false; + return isValidReturnBType(jType, symbolTable.jsonType, jMethodRequest, visitedSet); case TypeTags.OBJECT: return this.classLoader.loadClass(BObject.class.getCanonicalName()).isAssignableFrom(jType); case TypeTags.ERROR: @@ -1007,4 +1006,16 @@ private void throwParamCountMismatchError(JMethodRequest jMethodRequest) throws "Parameter count does not match with Java method '" + jMethodRequest.methodName + "' found in class '" + jMethodRequest.declaringClass.getName() + "'"); } + + private void throwOverloadedMethodError(JMethodRequest jMethodRequest, int paramCount) throws JInteropException { + if (jMethodRequest.kind == JMethodKind.CONSTRUCTOR) { + throw new JInteropException(OVERLOADED_METHODS, "Overloaded constructors with '" + paramCount + + "' parameter(s) in class '" + jMethodRequest.declaringClass.getName() + + "', please specify the parameter types 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() + + "', please specify the parameter types for each parameter in 'paramTypes' field in the annotation"); + } + } } 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 6623c907dc8c..32da1137cfa1 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 @@ -401,34 +401,62 @@ public void testResolveWithInstanceAndStatic() { String path = "test-src/javainterop/negative/method_resolve_error.bal"; CompileResult compileResult = BCompileUtil.compile(path); compileResult.getDiagnostics(); - Assert.assertEquals(compileResult.getDiagnostics().length, 2); + Assert.assertEquals(compileResult.getDiagnostics().length, 8); BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods " + - "cannot be differentiated. Please specify the parameterTypes for each " + + "cannot be differentiated. Please specify the parameter types for each " + "parameter in 'paramTypes' field in the annotation'", - "method_resolve_error.bal", 19, 1); + "method_resolve_error.bal", 19, 1); BAssertUtil.validateError(compileResult, 1, "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods " + - "cannot be differentiated. Please specify the parameterTypes for each " + + "cannot be differentiated. Please specify the parameter types for each " + "parameter in 'paramTypes' field in the annotation'", - "method_resolve_error.bal", 24, 1); - + "method_resolve_error.bal", 24, 1); + BAssertUtil.validateError(compileResult, 2, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods cannot be " + + "differentiated. Please specify the parameter types for each parameter in 'paramTypes' " + + "field in the annotation'", "method_resolve_error.bal", 29, 1); + BAssertUtil.validateError(compileResult, 3, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods cannot be " + + "differentiated. Please specify the parameter types for each parameter in 'paramTypes' " + + "field in the annotation'", "method_resolve_error.bal", 33, 1); + BAssertUtil.validateError(compileResult, 4, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods 'getDescription' " + + "with '1' parameter(s) in class " + + "'org.ballerinalang.test.javainterop.overloading.pkg.SportsCar', please specify the " + + "parameter types for each parameter in 'paramTypes' field in the annotation'", + "method_resolve_error.bal", 38, 1); + BAssertUtil.validateError(compileResult, 5, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded constructors with '1' " + + "parameter(s) in class 'java.lang.Byte', please specify the parameter types for each " + + "parameter in 'paramTypes' field in the annotation'", + "method_resolve_error.bal", 42, 1); + BAssertUtil.validateError(compileResult, 6, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods " + + "'getCategorization' with '2' parameter(s) in class " + + "'org.ballerinalang.test.javainterop.overloading.pkg.SportsCar', please specify the " + + "parameter types for each parameter in 'paramTypes' field in the annotation'", + "method_resolve_error.bal", 46, 1); } @Test public void testOverloadedMethods() { String path = "test-src/javainterop/negative/overloaded_methods.bal"; CompileResult compileResult = BCompileUtil.compile(path); - Assert.assertEquals(compileResult.getDiagnostics().length, 2); + Assert.assertEquals(compileResult.getDiagnostics().length, 3); BAssertUtil.validateError(compileResult, 0, - "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods " + - "cannot be differentiated. Please specify the parameterTypes for each " + - "parameter in 'paramTypes' field in the annotation'", - "overloaded_methods.bal", 24, 5); + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods cannot be " + + "differentiated. Please specify the parameter types for each parameter in 'paramTypes' field " + + "in the annotation'", "overloaded_methods.bal", 24, 5); BAssertUtil.validateError(compileResult, 1, - "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods " + - "cannot be differentiated. Please specify the parameterTypes for each parameter in " + - "'paramTypes' field in the annotation'", "overloaded_methods.bal", 30, 1); + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods cannot be " + + "differentiated. Please specify the parameter types for each parameter in 'paramTypes' field " + + "in the annotation'", "overloaded_methods.bal", 30, 1); + BAssertUtil.validateError(compileResult, 2, + "{ballerina/jballerina.java}OVERLOADED_METHODS 'Overloaded methods 'getPrice' with '1' " + + "parameter(s) in class 'org.ballerinalang.test.javainterop.overloading.pkg.SportsCar', " + + "please specify the parameter types for each parameter in 'paramTypes' " + + "field in the annotation'", "overloaded_methods.bal", 35, 1); } @Test diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/OverriddenMethodTests.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/OverriddenMethodTests.java index 0d235d3b3250..fc4d3d6729cb 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/OverriddenMethodTests.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/OverriddenMethodTests.java @@ -17,11 +17,9 @@ */ package org.ballerinalang.test.javainterop.overloading; -import io.ballerina.runtime.api.values.BArray; import org.ballerinalang.test.BCompileUtil; import org.ballerinalang.test.BRunUtil; import org.ballerinalang.test.CompileResult; -import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -41,11 +39,7 @@ public void setup() { @Test(description = "Test invoking an overridden and overloaded java method") public void testOverriddenMethods() { - Object val = BRunUtil.invoke(result, "testOverriddenMethods"); - BArray returns = (BArray) val; - Assert.assertEquals(returns.size(), 2); - Assert.assertEquals(returns.get(0).toString(), "Motor Car : Honda"); - Assert.assertEquals(returns.get(1).toString(), "GrazeHonda"); + BRunUtil.invoke(result, "testOverriddenMethods"); } @AfterClass diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Car.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Car.java index 8f2424736749..8d22a10125e0 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Car.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Car.java @@ -22,7 +22,7 @@ */ public class Car extends Vehicle { - private String model; + private final String model; public Car(String name, String model) { @@ -41,4 +41,27 @@ public String getDescription(String prefix) { return prefix + this.model; } + + public long getSeatCount() { + return 4; + } + + public static String getMaxSpeed(String model) { + if (model.equals("BMW")) { + return "200MPH"; + } + return "160MPH"; + } + + public Object[] getCategorization(int num, String category) { + return new Object[] {num, category}; + } + + public Object getBatteryType(long prefix) { + return prefix + " EVL-HP-LiPo powered"; + } + + public static String getMillage(long val) { + return val + "MPG"; + } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/SportsCar.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/SportsCar.java new file mode 100644 index 000000000000..cf9447316bba --- /dev/null +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/SportsCar.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * 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.test.javainterop.overloading.pkg; + +public class SportsCar extends Car { + + private final long seatCount; + + public SportsCar(String name, String model, long seatCount) { + + super(name, model); + this.seatCount = seatCount; + } + + @Override + public String getDescription(String prefix) { + return prefix + " seat count: " + seatCount; + } + + public long getSeatCount() { + return seatCount; + } + + public String getDescription(long[] numProps) { + return getName() + "| no of seats: " + seatCount + "| max speed: " + numProps[0] + "| mileage: " + numProps[1]; + } + + public static long getSeatCount(String model) { + if (model.equals("Nissan-GTR")) { + return 4; + } + return 2; + } + + public static String getMaxSpeed(String model) { + if (model.equals("Nissan-GTR")) { + return "300MPH"; + } + return "250MPH"; + } + + public char[] getCategorization(char category, char type) { + return new char[] {category, type}; + } + + public String[] getCategorization(String category, String type) { + return new String[] {category, type}; + } + + public String getBatteryType(String prefix) { + return prefix + " EV-HY3-Lithium-ion power"; + } + + public static String getPrice(String model) { + if (model.equals("Nissan-GTR")) { + return "USD 100,000"; + } + return "USD 50,000"; + } + + public static Object getPrice(Object type) { + if (type.equals("BMW-S6")) { + return " 120,000"; + } + return " 60,000"; + } +} diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Vehicle.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Vehicle.java index 76118c18f6d4..fce097d4ff9d 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Vehicle.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/overloading/pkg/Vehicle.java @@ -24,7 +24,7 @@ */ public class Vehicle { - private String name; + private final String name; public Vehicle(String name) { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal index 86c9789a7892..9569e22f8a6f 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal @@ -235,7 +235,8 @@ function hashCode(handle receiver) returns int = @java:Method { } external; function newByte(int val) returns handle = @java:Constructor { - 'class: "java.lang.Byte" + 'class: "java.lang.Byte", + paramTypes: ["byte"] } external; function getStringFromFutureResult(handle receiver) returns string = @java:Method { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_resolve_error.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_resolve_error.bal index 8f2a601633d9..46330e31f014 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_resolve_error.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/method_resolve_error.bal @@ -26,3 +26,29 @@ function hashCodeStatic(int receiver) returns int = @java:Method { 'class: "java.lang.Byte" } external; +function getSeatCount(handle receiver) returns int = @java:Method { + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + +function getSeatCountWithModel(handle receiver) returns int = @java:Method { + name: "getSeatCount", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + +function getDescription(handle receiver, handle val) returns handle = @java:Method { + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + +function newByte(int val) returns handle = @java:Constructor { + 'class: "java.lang.Byte" +} external; + +function getCarCategorization(handle receiver, handle val1, handle val2) returns handle = @java:Method { + name: "getCategorization", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + +function getBatteryType(handle receiver, handle val) returns handle = @java:Method { + name: "getBatteryType", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/overloaded_methods.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/overloaded_methods.bal index 3da564d53ca4..a35ab4e46f44 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/overloaded_methods.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/overloaded_methods.bal @@ -31,3 +31,7 @@ function testOverloadedMethods(int[] arr, string str) returns string = @java:Met 'class: "org/ballerinalang/nativeimpl/jvm/tests/StaticMethods", name: "testOverloadedMethods" } external; + +function getPrice(handle val) returns handle = @java:Method { + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/overloading/overridden_method_test.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/overloading/overridden_method_test.bal index c6833bc3592f..d39e87233cba 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/overloading/overridden_method_test.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/overloading/overridden_method_test.bal @@ -1,4 +1,5 @@ import ballerina/jballerina.java; +import ballerina/test; function newVehicle(handle strName) returns handle = @java:Constructor { 'class:"org.ballerinalang.test.javainterop.overloading.pkg.Vehicle", @@ -9,6 +10,10 @@ function newCar(handle strName, handle strModel) returns handle = @java:Construc 'class:"org.ballerinalang.test.javainterop.overloading.pkg.Car" } external; +function newSportsCar(handle strName, handle strModel, int seatCount) returns handle = @java:Constructor { + 'class:"org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + function getName(handle receiver) returns handle = @java:Method { 'class:"org.ballerinalang.test.javainterop.overloading.pkg.Car" @@ -18,8 +23,32 @@ function getDescription(handle receiver, handle inputStr) returns handle = @java 'class:"org.ballerinalang.test.javainterop.overloading.pkg.Car" } external; +function getSeatCount(handle receiver) returns int = @java:Method { + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar", + paramTypes: [] +} external; + +function getSeatCountWithModel(handle receiver) returns int = @java:Method { + name: "getSeatCount", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar", + paramTypes: ["java.lang.String"] +} external; + +function getSportsCarMaxSpeed(handle model) returns handle = @java:Method { + name: "getMaxSpeed", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; + +function getCarMaxSpeed(handle model) returns handle = @java:Method { + name: "getMaxSpeed", + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.Car" +} external; + +function getMillage(int val) returns handle = @java:Method { + 'class: "org.ballerinalang.test.javainterop.overloading.pkg.SportsCar" +} external; -public function testOverriddenMethods() returns [string?, string?] { +public function testOverriddenMethods() { handle strName1 = java:fromString("Generic vehicle"); handle vehicle = newVehicle(strName1); @@ -27,7 +56,21 @@ public function testOverriddenMethods() returns [string?, string?] { handle strModel = java:fromString("Honda"); handle car = newCar(strName2, strModel); + handle strName3 = java:fromString("Sports Car"); + handle strModel2 = java:fromString("Nissan-GTR"); + handle sportsCar = newSportsCar(strName3, strModel2, 4); + handle carName = getName(car); handle carDesc = getDescription(car, java:fromString("Graze")); - return [java:toString(carName), java:toString(carDesc)]; + + handle sportsCarMaxSpeed = getSportsCarMaxSpeed(java:fromString("BMW-S6")); + handle carMaxSpeed = getCarMaxSpeed(java:fromString("BMW")); + + test:assertEquals(java:toString(carName), "Motor Car : Honda"); + test:assertEquals(java:toString(carDesc), "GrazeHonda"); + test:assertEquals(getSeatCount(sportsCar), 4); + test:assertEquals(getSeatCountWithModel(java:fromString("Mazda MX-5")), 2); + test:assertEquals(java:toString(sportsCarMaxSpeed), "250MPH"); + test:assertEquals(java:toString(carMaxSpeed), "200MPH"); + test:assertEquals(java:toString(getMillage(40)), "40MPG"); }