More complex overloading for switch
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 43s

This commit is contained in:
Daniel Holle 2024-11-19 15:19:40 +01:00
parent 88d81f4af7
commit 170955b333
9 changed files with 71 additions and 20 deletions

View File

@ -6,19 +6,27 @@ public record Point(Number x, Number y) {}
public class OverloadPattern {
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) {
return x + y;
return 1;
}
public Number m(Point(Integer x, Integer y), Point(Integer a, Integer b)) {
return x + y;
return 2;
}
public Number m(Point(Float x, Float y), Point(Integer a, Integer b)) {
return x * y;
return 3;
}
public Number m(Point(Float x, Float y), Point(Float a, Float b)) {
return x * y;
return 4;
}
public Number m(Point(Integer x, Integer y)) {
return 5;
}
public Number m(Point(Float x, Float y)) {
return 6;
}
public m(Integer x) {

View File

@ -1393,8 +1393,10 @@ public class Codegen {
state.breakStack.pop();
if (aSwitch.isExpression()) {
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
unboxPrimitive(state, aSwitch.type());
if (aSwitch.type() != null) {
mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
unboxPrimitive(state, aSwitch.type());
}
state.popSwitch();
}

View File

@ -247,9 +247,14 @@ public class ASTToTargetAST {
}
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
return input.getFormalparalist().stream().map(param ->
new MethodParameter((TargetPattern) convert(param))
).toList();
var res = new ArrayList<MethodParameter>();
for (var i = 0; i < input.getFormalparalist().size(); i++) {
var param = input.getFormalparalist().get(i);
var pattern = (TargetPattern) convert(param);
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
res.add(new MethodParameter(pattern));
}
return res;
}
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
@ -341,11 +346,17 @@ public class ASTToTargetAST {
for (var method : methods) {
var patternsRec = new ArrayList<>(patterns);
TargetExpression expr = null;
var i = 0;
for (var param : method.signature().parameters()) {
if (param.pattern() instanceof TargetComplexPattern pat) {
if (i == offset) {
patternsRec.add(pat);
}
if (i > offset) {
// Find next pattern
var pattern = param.pattern();
expr = new TargetLocalVar(pattern.type(), pattern.name());
break;
}
i++;
@ -364,16 +375,14 @@ public class ASTToTargetAST {
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);
var case_ = new TargetSwitch.Case(List.of(patternsRec.getLast()), body);
cases.add(case_);
}
return new TargetSwitch(switchExpr, cases, null);
return new TargetSwitch(switchExpr, cases, null, true);
}
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
@ -490,7 +499,6 @@ public class ASTToTargetAST {
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
signatures.add(new Signature(javaSignature, txSignature, generics));
System.out.println(javaSignature);
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
listOfGenerics.add(generics);
collectedGenerics.put(javaSignature, listOfGenerics);
@ -513,7 +521,9 @@ public class ASTToTargetAST {
var list = new ArrayList<MethodParameter>();
for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
var param = paraList.getParameterAt(i);
list.add(new MethodParameter((TargetPattern) convert(param)).withType(convert(superList.getParameterAt(i).getType(), generics)));
var pattern = (TargetPattern) convert(param);
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
}
return list;
}

View File

@ -11,4 +11,8 @@ public record MethodParameter(TargetPattern pattern) {
public MethodParameter withType(TargetType type) {
return new MethodParameter(pattern.withType(type));
}
public MethodParameter withName(String name) {
return new MethodParameter(pattern.withName(name));
}
}

View File

@ -9,4 +9,9 @@ public record TargetComplexPattern(TargetType type, String name, List<TargetPatt
public TargetComplexPattern withType(TargetType type) {
return new TargetComplexPattern(type, name, subPatterns);
}
@Override
public TargetComplexPattern withName(String name) {
return new TargetComplexPattern(type, name, subPatterns);
}
}

View File

@ -12,4 +12,9 @@ public record TargetGuard(TargetPattern inner, TargetExpression expression) impl
public TargetType type() {
return inner.type();
}
@Override
public TargetGuard withName(String name) {
return new TargetGuard(inner.withName(name), expression);
}
}

View File

@ -10,4 +10,6 @@ public sealed interface TargetPattern extends TargetExpression permits TargetCom
TargetPattern withType(TargetType type);
TargetType type();
TargetPattern withName(String name);
}

View File

@ -7,4 +7,9 @@ public record TargetTypePattern(TargetType type, String name) implements TargetP
public TargetTypePattern withType(TargetType type) {
return new TargetTypePattern(type, name);
}
@Override
public TargetTypePattern withName(String name) {
return new TargetTypePattern(type, name);
}
}

View File

@ -846,12 +846,22 @@ public class TestComplete {
var rec = classFiles.get("Point");
var instance = clazz.getDeclaredConstructor().newInstance();
var m1 = clazz.getDeclaredMethod("m", rec);
var m2 = clazz.getDeclaredMethod("m", Integer.class);
var m1 = clazz.getDeclaredMethod("m", rec, rec);
var m2 = clazz.getDeclaredMethod("m", rec);
var m3 = clazz.getDeclaredMethod("m", Integer.class);
var pt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(10, 20);
assertEquals(m1.invoke(instance, pt), 30);
assertEquals(m2.invoke(instance, 10), 10);
var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2);
var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f);
assertEquals(m1.invoke(instance, ptInt, ptFlt), 1);
assertEquals(m1.invoke(instance, ptInt, ptInt), 2);
assertEquals(m1.invoke(instance, ptFlt, ptInt), 3);
assertEquals(m1.invoke(instance, ptFlt, ptFlt), 4);
assertEquals(m2.invoke(instance, ptInt), 5);
assertEquals(m2.invoke(instance, ptFlt), 6);
assertEquals(m3.invoke(instance, 10), 10);
}
//@Ignore("Not implemented")