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 class OverloadPattern {
public Number m(Point(Integer x, Integer y), Point(Float a, Float b)) { 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)) { 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)) { 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)) { 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) { public m(Integer x) {

View File

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

View File

@ -247,9 +247,14 @@ public class ASTToTargetAST {
} }
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) { public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
return input.getFormalparalist().stream().map(param -> var res = new ArrayList<MethodParameter>();
new MethodParameter((TargetPattern) convert(param)) for (var i = 0; i < input.getFormalparalist().size(); i++) {
).toList(); 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) { private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
@ -341,11 +346,17 @@ public class ASTToTargetAST {
for (var method : methods) { for (var method : methods) {
var patternsRec = new ArrayList<>(patterns); var patternsRec = new ArrayList<>(patterns);
TargetExpression expr = null;
var i = 0; var i = 0;
for (var param : method.signature().parameters()) { for (var param : method.signature().parameters()) {
if (param.pattern() instanceof TargetComplexPattern pat) { if (param.pattern() instanceof TargetComplexPattern pat) {
if (i == offset) { if (i == offset) {
patternsRec.add(pat); patternsRec.add(pat);
}
if (i > offset) {
// Find next pattern
var pattern = param.pattern();
expr = new TargetLocalVar(pattern.type(), pattern.name());
break; break;
} }
i++; i++;
@ -364,16 +375,14 @@ public class ASTToTargetAST {
return true; return true;
}).toList(); }).toList();
var last = patternsRec.getLast();
var expr = new TargetLocalVar(last.type(), last.name());
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType); var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
var body = new TargetBlock(List.of(caseBody)); 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_); 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) { 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)); var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
signatures.add(new Signature(javaSignature, txSignature, generics)); signatures.add(new Signature(javaSignature, txSignature, generics));
System.out.println(javaSignature);
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>()); var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
listOfGenerics.add(generics); listOfGenerics.add(generics);
collectedGenerics.put(javaSignature, listOfGenerics); collectedGenerics.put(javaSignature, listOfGenerics);
@ -513,7 +521,9 @@ public class ASTToTargetAST {
var list = new ArrayList<MethodParameter>(); var list = new ArrayList<MethodParameter>();
for (var i = 0; i < paraList.getFormalparalist().size(); i++) { for (var i = 0; i < paraList.getFormalparalist().size(); i++) {
var param = paraList.getParameterAt(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; return list;
} }

View File

@ -11,4 +11,8 @@ public record MethodParameter(TargetPattern pattern) {
public MethodParameter withType(TargetType type) { public MethodParameter withType(TargetType type) {
return new MethodParameter(pattern.withType(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) { public TargetComplexPattern withType(TargetType type) {
return new TargetComplexPattern(type, name, subPatterns); 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() { public TargetType type() {
return inner.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); TargetPattern withType(TargetType type);
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) { public TargetTypePattern withType(TargetType type) {
return new TargetTypePattern(type, name); 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 rec = classFiles.get("Point");
var instance = clazz.getDeclaredConstructor().newInstance(); var instance = clazz.getDeclaredConstructor().newInstance();
var m1 = clazz.getDeclaredMethod("m", rec); var m1 = clazz.getDeclaredMethod("m", rec, rec);
var m2 = clazz.getDeclaredMethod("m", Integer.class); var m2 = clazz.getDeclaredMethod("m", rec);
var m3 = clazz.getDeclaredMethod("m", Integer.class);
var pt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(10, 20); var ptInt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1, 2);
assertEquals(m1.invoke(instance, pt), 30); var ptFlt = rec.getDeclaredConstructor(Number.class, Number.class).newInstance(1f, 2f);
assertEquals(m2.invoke(instance, 10), 10);
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") //@Ignore("Not implemented")