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 record Point(Number x, Number y) {}
|
||||||
|
|
||||||
public class OverloadPattern {
|
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;
|
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;
|
return x * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import de.dhbwstuttgart.bytecode.FunNGenerator;
|
|||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
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) {
|
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
||||||
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
||||||
// Check if we have a pattern as a parameter
|
// 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()));
|
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate dispatch method
|
var signatureParams = firstMethod.signature().parameters().stream().map(p -> {
|
||||||
var firstParam = firstMethod.signature().parameters().get(0);
|
if (p.pattern() instanceof TargetComplexPattern pat) {
|
||||||
var cases = new ArrayList<TargetSwitch.Case>();
|
return new MethodParameter(pat.type(), pat.name());
|
||||||
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 body = new TargetBlock(List.of(caseBody));
|
return p;
|
||||||
var case_ = new TargetSwitch.Case(List.of(method.signature().parameters().getFirst().pattern()), body);
|
}).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_);
|
// 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 stmt = new TargetSwitch(expr, cases, null);
|
|
||||||
var block = new TargetBlock(List.of(stmt));
|
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(), signatureParams, firstMethod.signature().returnType());
|
||||||
var signature = new TargetMethod.Signature(firstMethod.signature().generics(), parameters, firstMethod.signature().returnType());
|
|
||||||
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, signature, firstMethod.txSignature());
|
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, signature, firstMethod.txSignature());
|
||||||
|
|
||||||
res.add(bridgeMethod);
|
res.add(bridgeMethod);
|
||||||
|
Loading…
Reference in New Issue
Block a user