Change grouping, doesnt work yet
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 5m18s

This commit is contained in:
Daniel Holle 2024-12-09 16:53:32 +01:00
parent 77411973be
commit 09c483542d
2 changed files with 64 additions and 22 deletions

View File

@ -16,4 +16,11 @@ public class PatternMatchingListAppend {
return list2;
}
/*public append(a, list2) {
switch(a) {
case Cons(x, y) -> ...
case Empty() ->
}
}*/
}

View File

@ -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<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
var res = new HashSet<ClassOrInterface>();
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<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
var res = new ArrayList<List<TargetMethod>>();
var mapOfSignatures = new HashMap<WeakSignature, List<MethodWithTphs>>();
var mapOfSignatures = new HashMap<PatternSignature, List<TargetMethod>>();
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<MethodWithTphs>();
for (var methodsWithSignature : mapOfSignatures.values()) {
var resMethods = new HashSet<TargetMethod>();
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) {