Work on overloading
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 47s
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 47s
This commit is contained in:
parent
bb11d24101
commit
88d81f4af7
@ -5,11 +5,19 @@ import java.lang.Float;
|
||||
public record Point(Number x, Number y) {}
|
||||
|
||||
public class OverloadPattern {
|
||||
public Number m(Point(Integer x, Integer y)) {
|
||||
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
public Number m(Point(Float x, Float y)) {
|
||||
public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
public Number m(Point(Float x, Float y), Point(Integer a, Integer b)) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
public Number m(Point(Float x, Float y), Point(Float a, Float b)) {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
@ -318,6 +319,63 @@ public class ASTToTargetAST {
|
||||
}
|
||||
}
|
||||
|
||||
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetExpression> params, List<TargetComplexPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||
if (methods.size() == 1) {
|
||||
var method = methods.getFirst();
|
||||
TargetExpression caseBody = new TargetMethodCall(
|
||||
method.signature().returnType(),
|
||||
new TargetThis(classType),
|
||||
params,
|
||||
classType,
|
||||
method.name(),
|
||||
false, false, method.isPrivate()
|
||||
);
|
||||
if (method.signature().returnType() != null) {
|
||||
caseBody = new TargetReturn(caseBody);
|
||||
}
|
||||
return caseBody;
|
||||
}
|
||||
|
||||
var cases = new ArrayList<TargetSwitch.Case>();
|
||||
for (var method : methods) {
|
||||
var patternsRec = new ArrayList<>(patterns);
|
||||
|
||||
var i = 0;
|
||||
for (var param : method.signature().parameters()) {
|
||||
if (param.pattern() instanceof TargetComplexPattern pat) {
|
||||
if (i == offset) {
|
||||
patternsRec.add(pat);
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
var candidates = methods.stream().filter(m -> {
|
||||
var j = 0;
|
||||
for (var param : m.signature().parameters()) {
|
||||
if (j >= patternsRec.size()) return true;
|
||||
if (param.pattern() instanceof TargetComplexPattern) {
|
||||
if (!patternsRec.get(j).equals(param.pattern())) return false;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}).toList();
|
||||
|
||||
var last = patternsRec.getLast();
|
||||
var expr = new TargetLocalVar(last.type(), last.name());
|
||||
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
|
||||
var body = new TargetBlock(List.of(caseBody));
|
||||
var case_ = new TargetSwitch.Case(List.of(method.signature().parameters().getFirst().pattern()), body);
|
||||
|
||||
cases.add(case_);
|
||||
}
|
||||
|
||||
return new TargetSwitch(switchExpr, cases, null);
|
||||
}
|
||||
|
||||
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
||||
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
||||
// Check if we have a pattern as a parameter
|
||||
@ -331,37 +389,23 @@ public class ASTToTargetAST {
|
||||
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature()));
|
||||
}
|
||||
|
||||
// Generate dispatch method
|
||||
var firstParam = firstMethod.signature().parameters().get(0);
|
||||
var cases = new ArrayList<TargetSwitch.Case>();
|
||||
TargetExpression expr = new TargetLocalVar(firstParam.pattern().type(), firstParam.pattern().name());
|
||||
|
||||
var classType = new TargetRefType(clazz.getClassName().getClassName());
|
||||
|
||||
for (var method : res) {
|
||||
TargetExpression caseBody = new TargetMethodCall(
|
||||
method.signature().returnType(),
|
||||
new TargetThis(classType),
|
||||
List.of(expr),
|
||||
classType,
|
||||
method.name(),
|
||||
false, false, method.isPrivate()
|
||||
);
|
||||
|
||||
if (method.signature().returnType() != null) {
|
||||
caseBody = new TargetReturn(caseBody);
|
||||
var signatureParams = firstMethod.signature().parameters().stream().map(p -> {
|
||||
if (p.pattern() instanceof TargetComplexPattern pat) {
|
||||
return new MethodParameter(pat.type(), pat.name());
|
||||
}
|
||||
var body = new TargetBlock(List.of(caseBody));
|
||||
var case_ = new TargetSwitch.Case(List.of(method.signature().parameters().getFirst().pattern()), body);
|
||||
return p;
|
||||
}).toList();
|
||||
var parameters = firstMethod.signature().parameters().stream().map( p -> (TargetExpression) new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
||||
//var patterns = List.of((TargetComplexPattern) firstMethod.signature().parameters().stream()
|
||||
// .filter(p -> p.pattern() instanceof TargetComplexPattern).findFirst().orElseThrow().pattern());
|
||||
var firstPattern = firstMethod.signature().parameters().stream().filter(p -> p.pattern() instanceof TargetComplexPattern).findFirst().orElseThrow().pattern();
|
||||
|
||||
cases.add(case_);
|
||||
}
|
||||
|
||||
var stmt = new TargetSwitch(expr, cases, null);
|
||||
// Generate dispatch method
|
||||
var classType = new TargetRefType(clazz.getClassName().getClassName());
|
||||
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(firstPattern.type(), firstPattern.name()), parameters, List.of(), res, classType);
|
||||
var block = new TargetBlock(List.of(stmt));
|
||||
|
||||
var parameters = List.of(new MethodParameter(firstParam.pattern().type(), firstParam.pattern().name()));
|
||||
var signature = new TargetMethod.Signature(firstMethod.signature().generics(), parameters, firstMethod.signature().returnType());
|
||||
var signature = new TargetMethod.Signature(firstMethod.signature().generics(), signatureParams, firstMethod.signature().returnType());
|
||||
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, signature, firstMethod.txSignature());
|
||||
|
||||
res.add(bridgeMethod);
|
||||
|
Loading…
Reference in New Issue
Block a user