diff --git a/resources/bytecode/javFiles/OverloadPattern.jav b/resources/bytecode/javFiles/OverloadPattern.jav index 16973a0a..117600f5 100644 --- a/resources/bytecode/javFiles/OverloadPattern.jav +++ b/resources/bytecode/javFiles/OverloadPattern.jav @@ -5,13 +5,13 @@ import java.lang.Float; public record Point(Number x, Number y) {} public class OverloadPattern { - public m(Point(x, y), Point(z, a)) { - return x + y + z + a; + public Number m(Point(Integer x, Integer y)) { + return x + y; } - /*public m(Point(Float x, Float y)) { + public Number m(Point(Float x, Float y)) { return x * y; - }*/ + } public m(Integer x) { return x; diff --git a/resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav b/resources/bytecode/javFiles/PatternMatchingHaskellStyle.jav similarity index 92% rename from resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav rename to resources/bytecode/javFiles/PatternMatchingHaskellStyle.jav index 88a0cc92..3e4e2283 100644 --- a/resources/bytecode/javFiles/PaternMatchingHaskellStyle.jav +++ b/resources/bytecode/javFiles/PatternMatchingHaskellStyle.jav @@ -5,7 +5,7 @@ sealed interface List permits LinkedElem, Elem {} public record LinkedElem(T a, List l) implements List {} public record Elem(T a) implements List {} -public class PaternMatchingHaskellStyle { +public class PatternMatchingHaskellStyle { public append(LinkedElem(a, b), list2) { return handleAppend(a, b, list2); diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 06e11131..6bbe7969 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -145,37 +145,60 @@ public class ASTToTargetAST { return ret; } + // This is used to serve as a custom equality to signature that performs a weak check without going into record patterns. + // The two signatures are considered equal if all the argument types match. + record WeakSignature(TargetMethod.Signature signature) { + @Override + public boolean equals(Object o) { + if (!(o instanceof WeakSignature other)) return false; + if (other.signature.parameters().size() != signature.parameters().size()) return false; + for (var i = 0; i < signature.parameters().size(); i++) { + var p1 = signature.parameters().get(i).pattern().type(); + var p2 = other.signature.parameters().get(i).pattern().type(); + if (!p1.equals(p2)) return false; + } + return true; + } + + @Override + public int hashCode() { + return Objects.hash(signature.parameters().stream().map(p -> p.pattern().type()).toArray()); + } + } + public List> groupOverloads(ClassOrInterface input, List methods) { var res = new ArrayList>(); + var mapOfSignatures = new HashMap>(); for (var method : methods) { // Convert all methods var methodsWithTphs = convert(input, method); // Then check for methods with the same signature - var mapOfSignatures = new HashMap>(); for (var m : methodsWithTphs) { - var methodsWithSameSignature = mapOfSignatures.getOrDefault(m.method.signature(), new ArrayList<>()); + var signature = new WeakSignature(m.method.signature()); + var methodsWithSameSignature = mapOfSignatures.getOrDefault(signature, new ArrayList<>()); methodsWithSameSignature.add(m); - mapOfSignatures.put(m.method.signature(), methodsWithSameSignature); + mapOfSignatures.put(signature, methodsWithSameSignature); } + } + for (var methodsWithSignature : mapOfSignatures.values()) { var resMethods = new HashSet(); - for (var methodsWithSignature : mapOfSignatures.values()) { - outer: for (var m1 : methodsWithSignature) { - for (var m2 : methodsWithSignature) { - for (var i = 0; i < m1.args.size(); i++) { - var arg1 = m1.args.get(i); - var arg2 = m2.args.get(i); - if (arg1.parameter.equals(arg2.parameter)) { - if (isSupertype(arg1.signature, arg2.signature) && + outer: for (var m1 : methodsWithSignature) { + for (var m2 : methodsWithSignature) { + for (var i = 0; i < m1.args.size(); i++) { + var arg1 = m1.args.get(i); + var arg2 = m2.args.get(i); + if (arg1.parameter.equals(arg2.parameter)) { + if (isSupertype(arg1.signature, arg2.signature) && !arg1.signature.equals(arg2.signature)) continue outer; - } } } - resMethods.add(m1.method); } + resMethods.add(m1.method); } res.add(resMethods.stream().toList()); } + return res; } @@ -309,7 +332,6 @@ public class ASTToTargetAST { } // Generate dispatch method - return res; } diff --git a/src/test/java/TestComplete.java b/src/test/java/TestComplete.java index ce50ae6b..dab2dc37 100644 --- a/src/test/java/TestComplete.java +++ b/src/test/java/TestComplete.java @@ -857,8 +857,8 @@ public class TestComplete { //@Ignore("Not implemented") @Test public void testOverloadPatternMatching() throws Exception { - var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PaternMatchingHaskellStyle.jav"); - var clazz = classFiles.get("PaternMatchingHaskellStyle"); + var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav"); + var clazz = classFiles.get("PatternMatchingHaskellStyle"); var R2 = classFiles.get("Elem"); var R = classFiles.get("LinkedElem"); var I = classFiles.get("List");