From 09c483542d40438a3800296bedcf20e545f8f745 Mon Sep 17 00:00:00 2001 From: Daniel Holle Date: Mon, 9 Dec 2024 16:53:32 +0100 Subject: [PATCH] Change grouping, doesnt work yet --- .../javFiles/PatternMatchingListAppend.jav | 7 ++ .../target/generate/ASTToTargetAST.java | 79 +++++++++++++------ 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/resources/bytecode/javFiles/PatternMatchingListAppend.jav b/resources/bytecode/javFiles/PatternMatchingListAppend.jav index 3fa186db..764099d2 100644 --- a/resources/bytecode/javFiles/PatternMatchingListAppend.jav +++ b/resources/bytecode/javFiles/PatternMatchingListAppend.jav @@ -16,4 +16,11 @@ public class PatternMatchingListAppend { return list2; } + /*public append(a, list2) { + switch(a) { + case Cons(x, y) -> ... + case Empty() -> + } + }*/ + } \ No newline at end of file diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 0a446fb8..d5bd882e 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -1,6 +1,5 @@ package de.dhbwstuttgart.target.generate; -import de.dhbwstuttgart.bytecode.CodeGenException; import de.dhbwstuttgart.bytecode.FunNGenerator; import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.environment.ByteArrayClassLoader; @@ -18,7 +17,6 @@ import de.dhbwstuttgart.target.tree.expression.*; import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.typeinference.result.*; -import java.sql.Array; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -148,44 +146,75 @@ public class ASTToTargetAST { // 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) { + // This also turns equal if both types implement a sealed super interface + class PatternSignature { + final TargetMethod.Signature signature; + final String name; + PatternSignature(String name, TargetMethod.Signature signature) { + this.signature = signature; + this.name = name; + } + @Override public boolean equals(Object o) { - if (!(o instanceof WeakSignature other)) return false; + if (!(o instanceof PatternSignature other)) return false; + if (!this.name.equals(other.name)) 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; + if (!p1.equals(p2) && commonSuperInterfaceTypes(p1, p2).isEmpty()) return false; } return true; } @Override public int hashCode() { - return Objects.hash(signature.parameters().stream().map(p -> p.pattern().type()).toArray()); + return signature.parameters().size(); } } + // This finds a common sealed interface type to group together methods that use different records + private List commonSuperInterfaceTypes(TargetType a, TargetType b) { + if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) { + var res = new HashSet(); + + var cla = compiler.getClass(new JavaClassName(ta.name())); + var clb = compiler.getClass(new JavaClassName(tb.name())); + + while (!cla.equals(ASTFactory.createClass(Object.class))) { + var clb2 = clb; + while (!clb2.equals(ASTFactory.createClass(Object.class))) { + for (var intfa : cla.getSuperInterfaces()) { + for (var intfb : clb.getSuperInterfaces()) { + if (intfa.equals(intfb)) { + var clintf = compiler.getClass(intfa.getName()); + if (clintf.isSealed()) { + res.add(clintf); + } + } + } + } + clb2 = compiler.getClass(clb2.getSuperClass().getName()); + } + cla = compiler.getClass(cla.getSuperClass().getName()); + } + return res.stream().toList(); + } + return List.of(); + } + public List> groupOverloads(ClassOrInterface input, List methods) { - var res = new ArrayList>(); - var mapOfSignatures = new HashMap>(); + var mapOfSignatures = new HashMap>(); for (var method : methods) { // Convert all methods var methodsWithTphs = convert(input, method); // Then check for methods with the same signature - for (var m : methodsWithTphs) { - var signature = new WeakSignature(m.method.signature()); - var methodsWithSameSignature = mapOfSignatures.getOrDefault(signature, new ArrayList<>()); - methodsWithSameSignature.add(m); - mapOfSignatures.put(signature, methodsWithSameSignature); - } - } + var resMethods = new HashSet(); - for (var methodsWithSignature : mapOfSignatures.values()) { - var resMethods = new HashSet(); - outer: for (var m1 : methodsWithSignature) { - for (var m2 : methodsWithSignature) { + outer: + for (var m1 : methodsWithTphs) { + for (var m2 : methodsWithTphs) { for (var i = 0; i < m1.args.size(); i++) { var arg1 = m1.args.get(i); var arg2 = m2.args.get(i); @@ -195,12 +224,18 @@ public class ASTToTargetAST { } } } - resMethods.add(m1.method); + resMethods.add(m1); + } + + for (var m : resMethods) { + var signature = new PatternSignature(m.method.name(), m.method.signature()); + var methodsWithSameSignature = mapOfSignatures.getOrDefault(signature, new ArrayList<>()); + methodsWithSameSignature.add(m.method); + mapOfSignatures.put(signature, methodsWithSameSignature); } - res.add(resMethods.stream().toList()); } - return res; + return mapOfSignatures.values().stream().toList(); } public TargetStructure convert(ClassOrInterface input) {