Compare commits
8 Commits
master
...
patternMat
Author | SHA1 | Date | |
---|---|---|---|
a4f18e91fb | |||
3516cd93f4 | |||
4c42983bb5 | |||
6569fb4dc1 | |||
f04c3bc01e | |||
a3f6365b07 | |||
b808c85722 | |||
8d41ed2328 |
@@ -1,8 +1,5 @@
|
|||||||
name: Build and Test with Maven
|
name: Build and Test with Maven
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-and-test-with-Maven:
|
Build-and-test-with-Maven:
|
||||||
|
@@ -1,45 +0,0 @@
|
|||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
|
|
||||||
name: SonarQube Scan
|
|
||||||
jobs:
|
|
||||||
sonarqube:
|
|
||||||
name: SonarQube Trigger
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checking out
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
# Disabling shallow clone is recommended for improving relevancy of reporting
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Install maven
|
|
||||||
run: |
|
|
||||||
apt update
|
|
||||||
apt install -y maven
|
|
||||||
- name: Install java
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: '24'
|
|
||||||
cache: 'maven'
|
|
||||||
- name: Compile project
|
|
||||||
run: |
|
|
||||||
mvn clean dependency:copy-dependencies verify
|
|
||||||
- name: SonarQube Scan
|
|
||||||
uses: SonarSource/sonarqube-scan-action@v5.3.0
|
|
||||||
env:
|
|
||||||
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }}
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
|
|
||||||
with:
|
|
||||||
args: >
|
|
||||||
-Dsonar.projectKey=Java-TX
|
|
||||||
-Dsonar.sources=src/main/java
|
|
||||||
-Dsonar.tests=src/test/java
|
|
||||||
-Dsonar.junit.reportPaths=target/test-reports
|
|
||||||
-Dsonar.java.binaries=target/classes
|
|
||||||
-Dsonar.java.libraries=target/dependency/*.jar
|
|
||||||
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml
|
|
@@ -1,7 +0,0 @@
|
|||||||
## Java-TX Compiler
|
|
||||||
|
|
||||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
|
||||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
|
||||||
[](https://gitea.hb.dhbw-stuttgart.de/sonarqube/dashboard?id=Java-TX)
|
|
||||||
|
|
||||||
Work in Progress Java-TX Compiler repository!
|
|
21
pom.xml
21
pom.xml
@@ -48,25 +48,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>0.8.13</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>report</id>
|
|
||||||
<phase>prepare-package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
@@ -84,7 +65,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<configuration>
|
<configuration>
|
||||||
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
<redirectTestOutputToFile>true</redirectTestOutputToFile>
|
||||||
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
<reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
|
||||||
<argLine>${argLine} --enable-preview</argLine>
|
<argLine>--enable-preview</argLine>
|
||||||
<trimStackTrace>false</trimStackTrace>
|
<trimStackTrace>false</trimStackTrace>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/JavaTXCompilerTest.java</exclude>
|
<exclude>**/JavaTXCompilerTest.java</exclude>
|
||||||
|
@@ -1739,7 +1739,7 @@ public class Codegen {
|
|||||||
methodName = fromMethod.name;
|
methodName = fromMethod.name;
|
||||||
|
|
||||||
fromReturn = converter.convert(fromMethod.getReturnType());
|
fromReturn = converter.convert(fromMethod.getReturnType());
|
||||||
var fromParams = converter.convert(fromMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
var fromParams = converter.convert(fromMethod.getParameterList()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
||||||
fromDescriptor = TargetMethod.getDescriptor(fromReturn, fromParams);
|
fromDescriptor = TargetMethod.getDescriptor(fromReturn, fromParams);
|
||||||
} else {
|
} else {
|
||||||
fromReturn = funNType.returnArguments() > 0 ? TargetType.Object : null;
|
fromReturn = funNType.returnArguments() > 0 ? TargetType.Object : null;
|
||||||
@@ -1749,7 +1749,7 @@ public class Codegen {
|
|||||||
var toClass = compiler.getClass(new JavaClassName(pair.to.name()));
|
var toClass = compiler.getClass(new JavaClassName(pair.to.name()));
|
||||||
var toMethod = toClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
|
var toMethod = toClass.getMethods().stream().filter(m -> (m.modifier & ACC_ABSTRACT) != 0).findFirst().orElseThrow();
|
||||||
var toReturn = converter.convert(toMethod.getReturnType());
|
var toReturn = converter.convert(toMethod.getReturnType());
|
||||||
var toParams = converter.convert(toMethod.getParameterList(), converter.generics.javaGenerics()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
var toParams = converter.convert(toMethod.getParameterList()).stream().map(m -> m.pattern().type()).toArray(TargetType[]::new);
|
||||||
var toDescriptor = TargetMethod.getDescriptor(toReturn, toParams);
|
var toDescriptor = TargetMethod.getDescriptor(toReturn, toParams);
|
||||||
|
|
||||||
// Generate wrapper method
|
// Generate wrapper method
|
||||||
|
@@ -30,7 +30,7 @@ public class CompilationEnvironment {
|
|||||||
public final PackageCrawler packageCrawler;
|
public final PackageCrawler packageCrawler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enthält automatisch die Java Standard Library
|
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
|
||||||
*
|
*
|
||||||
* @param sourceFiles die zu kompilierenden Dateien
|
* @param sourceFiles die zu kompilierenden Dateien
|
||||||
*/
|
*/
|
||||||
|
@@ -41,7 +41,7 @@ public class JavaClassName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt von einem Klassennamen nur den Namen der Klasse zurück
|
* Gibt von einem Klassennamen nur den Namen der Klasse zur<EFBFBD>ck
|
||||||
* Beispiel:
|
* Beispiel:
|
||||||
* java.lang.Object wird zu: Object
|
* java.lang.Object wird zu: Object
|
||||||
*/
|
*/
|
||||||
|
@@ -5,7 +5,7 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Speichert die Klassen für einen bestimmten Projektscope
|
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
|
||||||
*/
|
*/
|
||||||
public class JavaClassRegistry{
|
public class JavaClassRegistry{
|
||||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||||
|
@@ -18,6 +18,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
|||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
|
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -32,9 +33,9 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
public static RefType OBJECT = ASTFactory.createObjectType(); // TODO It would be better if I could call this directly but the hashcode seems to change
|
||||||
|
|
||||||
protected List<Generics> all;
|
public List<Generics> all;
|
||||||
public Generics generics;
|
//public Generics generics;
|
||||||
public List<Generics> currentMethodOverloads;
|
//public List<Generics> currentMethodOverloads;
|
||||||
|
|
||||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
||||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||||
@@ -54,13 +55,13 @@ public class ASTToTargetAST {
|
|||||||
return all.stream().map(generics -> new GenericsResult(generics.javaGenerics)).toList();
|
return all.stream().map(generics -> new GenericsResult(generics.javaGenerics)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetExpression convert(Pattern pattern) {
|
public TargetExpression convert(Pattern pattern, IGenerics generics) {
|
||||||
var converter = new StatementToTargetExpression(this);
|
var converter = new StatementToTargetExpression(this, generics);
|
||||||
pattern.accept(converter);
|
pattern.accept(converter);
|
||||||
return converter.result;
|
return converter.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
public record Generics(IGenerics javaGenerics, IGenerics txGenerics) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,7 +84,6 @@ public class ASTToTargetAST {
|
|||||||
for (var set : resultSets) {
|
for (var set : resultSets) {
|
||||||
all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
|
all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
|
||||||
}
|
}
|
||||||
this.generics = all.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
||||||
@@ -112,20 +112,23 @@ public class ASTToTargetAST {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (var i = 0; i < pars.size(); i++) {
|
for (var i = 0; i < pars.size(); i++) {
|
||||||
var type1 = convert(pars.get(i).getType(), generics.javaGenerics);
|
var type1 = pars.get(i).getType();
|
||||||
var type2 = arguments.get(i);
|
var type2 = arguments.get(i);
|
||||||
if (type1 instanceof TargetGenericType)
|
//if (type1 instanceof GenericRefType)
|
||||||
return true;
|
// return true;
|
||||||
if (TargetType.toPrimitive(type2).equals(type1))
|
//if (TargetType.toPrimitive(type2).equals(type1))
|
||||||
return true;
|
// return true;
|
||||||
if (!type1.equals(type2))
|
if (type1 instanceof RefType rt) {
|
||||||
|
if (type2 instanceof TargetRefType rt2 && !rt2.name().equals(rt.getName().toString())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<TargetGeneric> convert(Set<GenerateGenerics.Pair> result, GenerateGenerics generics) {
|
Set<TargetGeneric> convert(Set<GenerateGenerics.Pair> result, IGenerics generics) {
|
||||||
return result.stream().map(p -> {
|
return result.stream().map(p -> {
|
||||||
if (p instanceof GenerateGenerics.PairLT pair) {
|
if (p instanceof GenerateGenerics.PairLT pair) {
|
||||||
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right.resolve(), generics));
|
return new TargetGeneric(pair.left.resolve().getName(), convert(pair.right.resolve(), generics));
|
||||||
@@ -137,7 +140,7 @@ public class ASTToTargetAST {
|
|||||||
}).collect(Collectors.toSet());
|
}).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TargetGeneric> convert(GenericTypeVar typeVar, GenerateGenerics generics) {
|
public List<TargetGeneric> convert(GenericTypeVar typeVar, IGenerics generics) {
|
||||||
var ret = new ArrayList<TargetGeneric>();
|
var ret = new ArrayList<TargetGeneric>();
|
||||||
for (var bound : typeVar.getBounds()) {
|
for (var bound : typeVar.getBounds()) {
|
||||||
ret.add(new TargetGeneric(typeVar.getName(), generics.getTargetType(bound)));
|
ret.add(new TargetGeneric(typeVar.getName(), generics.getTargetType(bound)));
|
||||||
@@ -146,6 +149,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This finds a common sealed interface type to group together methods that use different records
|
// This finds a common sealed interface type to group together methods that use different records
|
||||||
|
// This function should do matching or unification
|
||||||
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
||||||
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
|
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
|
||||||
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
|
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
|
||||||
@@ -183,44 +187,28 @@ public class ASTToTargetAST {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO This is ugly and probably doesn't work right
|
private boolean canCombine(Signature m1, Signature m2) {
|
||||||
private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
|
var pl1 = m1.java.parameters();
|
||||||
if (!a.name().equals(b.name())) return false;
|
var pl2 = m2.java.parameters();
|
||||||
if (a.subPatterns().size() != b.subPatterns().size()) return false;
|
if (pl1.size() != pl2.size()) return false;
|
||||||
for (var i = 0; i < a.subPatterns().size(); i++) {
|
if (pl1.isEmpty()) return false;
|
||||||
var p1 = a.subPatterns().get(i);
|
for (var i = 0; i < pl1.size(); i++) {
|
||||||
var p2 = b.subPatterns().get(i);
|
var p1 = pl1.get(i).pattern();
|
||||||
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
var p2 = pl2.get(i).pattern();
|
||||||
patternStrictlyEquals(pc1, pc2)) return false;
|
// TPH <> RefType sind nicht unterscheidbar
|
||||||
if (p1 instanceof TargetTypePattern pt1 && p2 instanceof TargetTypePattern pt2) {
|
|
||||||
if (pt1.type() instanceof TargetGenericType && pt2.type() instanceof TargetGenericType) continue;
|
|
||||||
}
|
|
||||||
if (!p1.type().equals(p2.type()) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canCombine(TargetMethod m1, TargetMethod m2) {
|
|
||||||
if (!m1.name().equals(m2.name())) return false;
|
|
||||||
var s1 = m1.signature();
|
|
||||||
var s2 = m2.signature();
|
|
||||||
if (s1.parameters().size() != s2.parameters().size()) return false;
|
|
||||||
if (s1.parameters().isEmpty()) return false;
|
|
||||||
for (var i = 0; i < s1.parameters().size(); i++) {
|
|
||||||
var p1 = s1.parameters().get(i).pattern();
|
|
||||||
var p2 = s2.parameters().get(i).pattern();
|
|
||||||
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
|
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
|
||||||
|
// Pattern(X) <> Pattern(Y) ist nicht unterscheidbar
|
||||||
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
||||||
patternStrictlyEquals(pc1, pc2)) return false;
|
pc1.type().equals(pc2.type())) continue;
|
||||||
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
if (!p1.equals(p2)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record Combination(TargetMethod a, TargetMethod b) {
|
private record Combination(MethodWithTphs a, MethodWithTphs b) {
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (!(o instanceof Combination(TargetMethod a1, TargetMethod b1))) return false;
|
if (!(o instanceof Combination(MethodWithTphs a1, MethodWithTphs b1))) return false;
|
||||||
return this.a.equals(a1) && this.b.equals(b1) ||
|
return this.a.equals(a1) && this.b.equals(b1) ||
|
||||||
this.a.equals(b1) && this.b.equals(a1);
|
this.a.equals(b1) && this.b.equals(a1);
|
||||||
}
|
}
|
||||||
@@ -231,10 +219,10 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
private List<List<MethodWithTphs>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
||||||
var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
|
var mapOfTargetMethods = new HashMap<Generics, MethodWithTphs[]>();
|
||||||
for (var generics : all) {
|
for (var gen : all) {
|
||||||
mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
|
mapOfTargetMethods.put(gen, new MethodWithTphs[methods.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < methods.size(); i++) {
|
for (var i = 0; i < methods.size(); i++) {
|
||||||
@@ -243,14 +231,14 @@ public class ASTToTargetAST {
|
|||||||
var methodsWithTphs = convert(input, method);
|
var methodsWithTphs = convert(input, method);
|
||||||
for (var m : methodsWithTphs) {
|
for (var m : methodsWithTphs) {
|
||||||
var resultMethods = mapOfTargetMethods.get(m.generics);
|
var resultMethods = mapOfTargetMethods.get(m.generics);
|
||||||
resultMethods[i] = m.method;
|
resultMethods[i] = new MethodWithTphs(m.method, m.generics, m.signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*System.out.println("============== INPUT ==============");
|
System.out.println("============== INPUT ==============");
|
||||||
for (var m : mapOfTargetMethods.values()) {
|
for (var m : mapOfTargetMethods.values()) {
|
||||||
for (var v : m) System.out.println(v.name() + " " + v.getSignature());
|
for (var v : m) if (v != null) System.out.println(v.method.name + " " + v.signature.java.getSignature());
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
var allCombinations = new HashSet<Set<Combination>>();
|
var allCombinations = new HashSet<Set<Combination>>();
|
||||||
// Combine methods based on their signature and position in the result set
|
// Combine methods based on their signature and position in the result set
|
||||||
@@ -268,8 +256,8 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
var combinations = new HashSet<Combination>();
|
var combinations = new HashSet<Combination>();
|
||||||
|
|
||||||
if (canCombine(m1, m2)) {
|
if (canCombine(m1.signature, m2.signature)) {
|
||||||
//System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
|
System.out.println(" Combining " + m1.signature.java.getSignature() + " and " + m2.signature.java.getSignature());
|
||||||
combinations.add(new Combination(m1, m2));
|
combinations.add(new Combination(m1, m2));
|
||||||
for (var j = 0; j < methods.size(); j++) {
|
for (var j = 0; j < methods.size(); j++) {
|
||||||
if (j == i) continue;
|
if (j == i) continue;
|
||||||
@@ -278,10 +266,10 @@ public class ASTToTargetAST {
|
|||||||
var m4 = resMeth1[j];
|
var m4 = resMeth1[j];
|
||||||
if (m4 == null) continue;
|
if (m4 == null) continue;
|
||||||
combinations.add(new Combination(m4, m3));
|
combinations.add(new Combination(m4, m3));
|
||||||
//System.out.println("Also Combining " + m4.getSignature() + " and " + m3.getSignature());
|
System.out.println("Also Combining " + m4.signature.java.getSignature() + " and " + m3.signature.java.getSignature());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//System.out.println(" Not Combining " + m1.getSignature() + " and " + m2.getSignature());
|
System.out.println(" Not Combining " + m1.signature.java.getSignature() + " and " + m2.signature.java.getSignature());
|
||||||
}
|
}
|
||||||
if (!combinations.isEmpty()) allCombinations.add(combinations);
|
if (!combinations.isEmpty()) allCombinations.add(combinations);
|
||||||
}
|
}
|
||||||
@@ -291,14 +279,14 @@ public class ASTToTargetAST {
|
|||||||
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
|
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
|
||||||
|
|
||||||
// Combine back into output format
|
// Combine back into output format
|
||||||
var r0 = new HashSet<Set<TargetMethod>>();
|
var r0 = new HashSet<Set<MethodWithTphs>>();
|
||||||
for (var combinations : allCombinations) {
|
for (var combinations : allCombinations) {
|
||||||
var r1 = new HashSet<Set<TargetMethod>>();
|
var r1 = new HashSet<Set<MethodWithTphs>>();
|
||||||
// This is used to weed out duplicates
|
// This is used to weed out duplicates
|
||||||
var uniqued = new HashSet<TargetMethod>();
|
var uniqued = new HashSet<MethodWithTphs>();
|
||||||
// We go over all methods in the result
|
// We go over all methods in the result
|
||||||
for (var g : all) for (var i = 0; i < methods.size(); i++) {
|
for (var g : all) for (var i = 0; i < methods.size(); i++) {
|
||||||
var r2 = new HashSet<TargetMethod>();
|
var r2 = new HashSet<MethodWithTphs>();
|
||||||
var m = mapOfTargetMethods.get(g)[i];
|
var m = mapOfTargetMethods.get(g)[i];
|
||||||
if (m == null) continue;
|
if (m == null) continue;
|
||||||
if (!uniqued.contains(m)) {
|
if (!uniqued.contains(m)) {
|
||||||
@@ -340,13 +328,14 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
System.out.println("============== OUTPUT ==============");
|
System.out.println("============== OUTPUT ==============");
|
||||||
for (var l : result) {
|
for (var l : result) {
|
||||||
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
|
for (var m : l) System.out.println(m.method.name + " " + m.signature.java.getSignature());
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetStructure convert(ClassOrInterface input) {
|
public TargetStructure convert(ClassOrInterface input) {
|
||||||
|
var generics = all.getFirst();
|
||||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||||
|
|
||||||
@@ -359,7 +348,7 @@ public class ASTToTargetAST {
|
|||||||
var next = genericsIter.next();
|
var next = genericsIter.next();
|
||||||
userDefinedGenerics.add(next);
|
userDefinedGenerics.add(next);
|
||||||
// TODO Support multiple bounds
|
// TODO Support multiple bounds
|
||||||
javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().get(0))));
|
javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().getFirst(), generics.javaGenerics)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.userDefinedGenerics.put(input, new HashSet<>());
|
this.userDefinedGenerics.put(input, new HashSet<>());
|
||||||
@@ -370,18 +359,20 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
TargetBlock fieldInitializer = null;
|
TargetBlock fieldInitializer = null;
|
||||||
if (input.getfieldInitializations().isPresent())
|
if (input.getfieldInitializations().isPresent())
|
||||||
fieldInitializer = convert(input.getfieldInitializations().get().block);
|
fieldInitializer = convert(input.getfieldInitializations().get().block, generics.javaGenerics);
|
||||||
TargetBlock finalFieldInitializer = fieldInitializer;
|
TargetBlock finalFieldInitializer = fieldInitializer;
|
||||||
|
|
||||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
||||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer, generics)).flatMap(List::stream).toList();
|
||||||
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
var fields = input.getFieldDecl().stream().map(f -> convert(f, generics.javaGenerics)).toList();
|
||||||
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
|
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
|
||||||
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
|
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
|
||||||
|
|
||||||
TargetMethod staticConstructor = null;
|
TargetMethod staticConstructor = null;
|
||||||
if (input.getStaticInitializer().isPresent())
|
if (input.getStaticInitializer().isPresent()) {
|
||||||
staticConstructor = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow().method;
|
var init = this.convert(input, input.getStaticInitializer().get()).stream().findFirst().orElseThrow();
|
||||||
|
staticConstructor = this.convert(init, init.generics.javaGenerics);
|
||||||
|
}
|
||||||
|
|
||||||
if (input instanceof Record)
|
if (input instanceof Record)
|
||||||
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
@@ -390,11 +381,16 @@ public class ASTToTargetAST {
|
|||||||
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
@Deprecated
|
||||||
|
public List<MethodParameter> convert(ParameterList input) {
|
||||||
|
return convert(input, all.getFirst().javaGenerics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<MethodParameter> convert(ParameterList input, IGenerics generics) {
|
||||||
var res = new ArrayList<MethodParameter>();
|
var res = new ArrayList<MethodParameter>();
|
||||||
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
for (var i = 0; i < input.getFormalparalist().size(); i++) {
|
||||||
var param = input.getFormalparalist().get(i);
|
var param = input.getFormalparalist().get(i);
|
||||||
var pattern = (TargetPattern) convert(param);
|
var pattern = (TargetPattern) convert(param, generics);
|
||||||
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
||||||
res.add(new MethodParameter(pattern));
|
res.add(new MethodParameter(pattern));
|
||||||
}
|
}
|
||||||
@@ -405,7 +401,7 @@ public class ASTToTargetAST {
|
|||||||
return generics.stream().anyMatch(g -> g.name().equals(type.getParsedName()));
|
return generics.stream().anyMatch(g -> g.name().equals(type.getParsedName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<TargetGeneric> collectMethodGenerics(ClassOrInterface clazz, GenerateGenerics generateGenerics, Set<GenerateGenerics.Pair> generics, Method input) {
|
private Set<TargetGeneric> collectMethodGenerics(ClassOrInterface clazz, IGenerics generateGenerics, Set<GenerateGenerics.Pair> generics, Method input) {
|
||||||
var convertedGenerics = new HashSet<>(convert(generics, generateGenerics));
|
var convertedGenerics = new HashSet<>(convert(generics, generateGenerics));
|
||||||
outer: for (GenericTypeVar typeVar : input.getGenerics()) {
|
outer: for (GenericTypeVar typeVar : input.getGenerics()) {
|
||||||
for (var classGeneric : clazz.getGenerics()) {
|
for (var classGeneric : clazz.getGenerics()) {
|
||||||
@@ -423,7 +419,7 @@ public class ASTToTargetAST {
|
|||||||
return convertedGenerics;
|
return convertedGenerics;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer, Generics generics) {
|
||||||
generics = all.get(0);
|
generics = all.get(0);
|
||||||
List<TargetConstructor> result = new ArrayList<>();
|
List<TargetConstructor> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
@@ -431,15 +427,15 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
for (var s : all) {
|
for (var s : all) {
|
||||||
generics = s;
|
generics = s;
|
||||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, input);
|
var javaGenerics = generics.javaGenerics.generics(currentClass, input);
|
||||||
var txGenerics = this.generics.txGenerics.generics(currentClass, input);
|
var txGenerics = generics.txGenerics.generics(currentClass, input);
|
||||||
List<MethodParameter> params = convert(input.getParameterList(), this.generics.javaGenerics);
|
List<MethodParameter> params = convert(input.getParameterList(), generics.javaGenerics);
|
||||||
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
|
if (parameterSet.stream().noneMatch(p -> p.equals(params))) {
|
||||||
List<MethodParameter> txParams = convert(input.getParameterList(), this.generics.txGenerics);
|
List<MethodParameter> txParams = convert(input.getParameterList(), generics.txGenerics);
|
||||||
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, input);
|
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, input);
|
||||||
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, input);
|
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, input);
|
||||||
|
|
||||||
result.add(new TargetConstructor(input.modifier, javaMethodGenerics, txMethodGenerics, params, txParams, convert(input.block), fieldInitializer));
|
result.add(new TargetConstructor(input.modifier, javaMethodGenerics, txMethodGenerics, params, txParams, convert(input.block, generics.javaGenerics), fieldInitializer));
|
||||||
parameterSet.add(params);
|
parameterSet.add(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,10 +443,13 @@ public class ASTToTargetAST {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int counter = 0;
|
||||||
private String encodeName(String name, TargetMethod.Signature params) {
|
private String encodeName(String name, TargetMethod.Signature params) {
|
||||||
var res = new StringBuilder();
|
var res = new StringBuilder();
|
||||||
res.append(name);
|
res.append(name);
|
||||||
res.append('$');
|
res.append('$');
|
||||||
|
res.append(counter++);
|
||||||
|
res.append('$');
|
||||||
for (var param : params.parameters()) {
|
for (var param : params.parameters()) {
|
||||||
encodeName(param.pattern(), res);
|
encodeName(param.pattern(), res);
|
||||||
}
|
}
|
||||||
@@ -526,12 +525,14 @@ public class ASTToTargetAST {
|
|||||||
var j = 0;
|
var j = 0;
|
||||||
for (var param : m.signature().parameters()) {
|
for (var param : m.signature().parameters()) {
|
||||||
if (j >= patternsRec.size()) return true;
|
if (j >= patternsRec.size()) return true;
|
||||||
if (!patternsRec.get(j).type().equals(param.pattern().type())) return false;
|
if (!patternsRec.get(j).equals(param.pattern())) return false;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
//System.out.println(offset + " -> " + lastPattern);
|
||||||
|
//candidates.forEach(m -> System.out.println(m.getSignature()));
|
||||||
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(lastPattern), body);
|
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
||||||
@@ -542,19 +543,14 @@ public class ASTToTargetAST {
|
|||||||
return new TargetSwitch(switchExpr, cases, null, true);
|
return new TargetSwitch(switchExpr, cases, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<TargetMethod> overloadedMethods) {
|
private List<TargetMethod> generatePatternOverloads(ClassOrInterface clazz, List<MethodWithTphs> overloadedMethods) {
|
||||||
if (overloadedMethods.size() <= 1) return overloadedMethods;
|
if (overloadedMethods.isEmpty()) return List.of();
|
||||||
// Check if we have a pattern as a parameter
|
// Check if we have a pattern as a parameter
|
||||||
var firstMethod = overloadedMethods.getFirst();
|
var firstMethod = convert(overloadedMethods.getFirst(), overloadedMethods.getFirst().generics.javaGenerics);
|
||||||
var secondMethod = overloadedMethods.get(1);
|
if (overloadedMethods.size() == 1) return List.of(firstMethod);
|
||||||
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern)) return overloadedMethods;
|
var secondMethod = convert(overloadedMethods.get(1), overloadedMethods.get(1).generics.javaGenerics);
|
||||||
// Rename existing methods
|
if (firstMethod.signature().parameters().stream().noneMatch(mp -> mp.pattern() instanceof TargetComplexPattern))
|
||||||
|
return overloadedMethods.stream().map(m -> convert(m, m.generics.javaGenerics)).toList();
|
||||||
var res = new ArrayList<TargetMethod>();
|
|
||||||
for (var method : overloadedMethods) {
|
|
||||||
var name = encodeName(method.name(), method.signature());
|
|
||||||
res.add(new TargetMethod(method.access(), name, method.block(), method.signature(), method.txSignature()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var signatureParams = new ArrayList<MethodParameter>();
|
var signatureParams = new ArrayList<MethodParameter>();
|
||||||
for (var i = 0; i < firstMethod.signature().parameters().size(); i++) {
|
for (var i = 0; i < firstMethod.signature().parameters().size(); i++) {
|
||||||
@@ -563,7 +559,7 @@ public class ASTToTargetAST {
|
|||||||
var t2 = secondMethod.signature().parameters().get(i).pattern().type();
|
var t2 = secondMethod.signature().parameters().get(i).pattern().type();
|
||||||
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2));
|
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(t1, t2));
|
||||||
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
||||||
var t3 = m.signature().parameters().get(i).pattern().type();
|
var t3 = m.signature().java.parameters().get(i).pattern().type();
|
||||||
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
|
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
|
||||||
}
|
}
|
||||||
if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload");
|
if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload");
|
||||||
@@ -578,9 +574,28 @@ public class ASTToTargetAST {
|
|||||||
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
|
signatureParams.add(new MethodParameter(new TargetRefType(superType.getClassName().toString()), name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rename existing methods
|
||||||
|
|
||||||
|
var res = new ArrayList<TargetMethod>();
|
||||||
|
for (var method : overloadedMethods) {
|
||||||
|
var name = encodeName(method.method.name, method.signature.java);
|
||||||
|
|
||||||
|
var generics = new OverlayGenerics(method.generics.javaGenerics, this);
|
||||||
|
var m = overloadedMethods.getFirst();
|
||||||
|
var params = m.method.getParameterList().getFormalparalist();
|
||||||
|
for (var i = 0; i < params.size(); i++) {
|
||||||
|
var param = params.get(i);
|
||||||
|
if (param.getType() instanceof TypePlaceholder tph) {
|
||||||
|
generics.addOverlay(tph, signatureParams.get(i).pattern().type());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tMethod = convert(method, generics);
|
||||||
|
res.add(new TargetMethod(tMethod.access(), name, tMethod.block(), tMethod.signature(), tMethod.txSignature()));
|
||||||
|
}
|
||||||
|
|
||||||
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType()));
|
var commonSubTypes = new HashSet<>(commonSuperInterfaceTypes(firstMethod.signature().returnType(), secondMethod.signature().returnType()));
|
||||||
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
for (var m : overloadedMethods.subList(2, overloadedMethods.size())) {
|
||||||
commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().returnType()));
|
commonSubTypes.retainAll(commonSuperInterfaceTypes(firstMethod.signature().returnType(), m.signature().java.returnType()));
|
||||||
}
|
}
|
||||||
var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString());
|
var returnType = commonSubTypes.isEmpty() ? TargetType.Object : new TargetRefType(commonSubTypes.iterator().next().getClassName().toString());
|
||||||
|
|
||||||
@@ -601,7 +616,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
|
private Expression makeRecordSwitch(RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList params, List<Method> overloadedMethods) {
|
||||||
var param = params.getFormalparalist().get(0);
|
var param = params.getFormalparalist().getFirst();
|
||||||
assert param instanceof RecordPattern; // TODO
|
assert param instanceof RecordPattern; // TODO
|
||||||
|
|
||||||
var cases = new ArrayList<SwitchBlock>();
|
var cases = new ArrayList<SwitchBlock>();
|
||||||
@@ -621,7 +636,7 @@ public class ASTToTargetAST {
|
|||||||
return swtch;
|
return swtch;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Method> findSuperMethodToOverride(ClassOrInterface currentClass, String name, List<MethodParameter> params) {
|
private Optional<Method> findSuperMethodToOverride(ClassOrInterface currentClass, String name, List<MethodParameter> params, IGenerics generics) {
|
||||||
var superClass = compiler.getClass(currentClass.getSuperClass().getName());
|
var superClass = compiler.getClass(currentClass.getSuperClass().getName());
|
||||||
var methodStream = superClass.getMethods().stream();
|
var methodStream = superClass.getMethods().stream();
|
||||||
for (var superInterface : currentClass.getSuperInterfaces()) {
|
for (var superInterface : currentClass.getSuperInterfaces()) {
|
||||||
@@ -634,115 +649,106 @@ public class ASTToTargetAST {
|
|||||||
if (sParams.getFormalparalist().size() != params.size()) return false;
|
if (sParams.getFormalparalist().size() != params.size()) return false;
|
||||||
for (var i = 0; i < params.size(); i++) {
|
for (var i = 0; i < params.size(); i++) {
|
||||||
var a = TargetType.toPrimitive(params.get(i).pattern().type());
|
var a = TargetType.toPrimitive(params.get(i).pattern().type());
|
||||||
var b = convert(sParams.getFormalparalist().get(i).getType());
|
var b = convert(sParams.getFormalparalist().get(i).getType(), generics);
|
||||||
if (!Objects.equals(a, b)) return false;
|
if (!Objects.equals(a, b)) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).findFirst();
|
}).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
|
record MethodWithTphs(Method method, Generics generics, Signature signature) {
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (!(o instanceof MethodWithTphs that)) return false;
|
if (!(o instanceof MethodWithTphs that)) return false;
|
||||||
return Objects.equals(method, that.method) && Objects.equals(args, that.args);
|
return Objects.equals(method, that.method) && Objects.equals(signature, that.signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(method, args);
|
return Objects.hash(method, signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TargetMethod convert(MethodWithTphs mtph, IGenerics generics) {
|
||||||
|
return new TargetMethod(mtph.method.modifier, mtph.method.name, convert(mtph.method.block, generics), mtph.signature.java(), mtph.signature.tx());
|
||||||
|
}
|
||||||
|
|
||||||
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
|
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
|
||||||
|
|
||||||
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
private List<MethodWithTphs> convert(ClassOrInterface currentClass, Method method) {
|
||||||
generics = all.getFirst();
|
|
||||||
List<MethodWithTphs> result = new ArrayList<>();
|
List<MethodWithTphs> result = new ArrayList<>();
|
||||||
this.currentMethod = method;
|
this.currentMethod = method;
|
||||||
|
|
||||||
List<Signature> signatures = new ArrayList<>();
|
List<Signature> signatures = new ArrayList<>();
|
||||||
HashMap<TargetMethod.Signature, List<Generics>> collectedGenerics = new HashMap<>();
|
for (var generics : all) {
|
||||||
|
var javaGenerics = generics.javaGenerics.generics(currentClass, method);
|
||||||
for (var s : all) {
|
var txGenerics = generics.txGenerics.generics(currentClass, method);
|
||||||
generics = s;
|
List<MethodParameter> params = convert(method.getParameterList(), generics.javaGenerics);
|
||||||
var javaGenerics = this.generics.javaGenerics.generics(currentClass, method);
|
var returnType = convert(method.getReturnType(), generics.javaGenerics);
|
||||||
var txGenerics = this.generics.txGenerics.generics(currentClass, method);
|
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params, generics.javaGenerics);
|
||||||
List<MethodParameter> params = convert(method.getParameterList(), this.generics.javaGenerics);
|
|
||||||
var returnType = convert(method.getReturnType(), this.generics.javaGenerics);
|
|
||||||
var superMethod = findSuperMethodToOverride(currentClass, method.getName(), params);
|
|
||||||
if (superMethod.isPresent()) {
|
if (superMethod.isPresent()) {
|
||||||
// If we find a super method to override, use its parameters and return types
|
// If we find a super method to override, use its parameters and return types
|
||||||
var newReturnType = convert(superMethod.get().getReturnType(), this.generics.javaGenerics);
|
var newReturnType = convert(superMethod.get().getReturnType(), generics.javaGenerics);
|
||||||
if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) {
|
if (newReturnType instanceof TargetPrimitiveType && TargetType.toPrimitive(returnType).equals(newReturnType)) {
|
||||||
returnType = newReturnType;
|
returnType = newReturnType;
|
||||||
params = convert(superMethod.get().getParameterList(), method.getParameterList(), this.generics.javaGenerics);
|
params = convert(superMethod.get().getParameterList(), method.getParameterList(), generics.javaGenerics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodParameter> txParams = convert(method.getParameterList(), this.generics.txGenerics);
|
List<MethodParameter> txParams = convert(method.getParameterList(), generics.txGenerics);
|
||||||
|
|
||||||
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
|
var javaMethodGenerics = collectMethodGenerics(currentClass, generics.javaGenerics(), javaGenerics, method);
|
||||||
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
var txMethodGenerics = collectMethodGenerics(currentClass, generics.txGenerics(), txGenerics, method);
|
||||||
|
|
||||||
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
var javaSignature = new TargetMethod.Signature(javaMethodGenerics, params, returnType);
|
||||||
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), this.generics.txGenerics));
|
var txSignature = new TargetMethod.Signature(txMethodGenerics, txParams, convert(method.getReturnType(), generics.txGenerics));
|
||||||
|
|
||||||
signatures.add(new Signature(javaSignature, txSignature, generics));
|
signatures.add(new Signature(javaSignature, txSignature, generics));
|
||||||
var listOfGenerics = collectedGenerics.getOrDefault(javaSignature, new ArrayList<>());
|
|
||||||
listOfGenerics.add(generics);
|
|
||||||
collectedGenerics.put(javaSignature, listOfGenerics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var signature : signatures) {
|
for (var signature : signatures) {
|
||||||
generics = signature.generics;
|
result.add(new MethodWithTphs(method, signature.generics, signature));
|
||||||
currentMethodOverloads = collectedGenerics.get(signature.java);
|
|
||||||
|
|
||||||
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
|
|
||||||
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
|
|
||||||
|
|
||||||
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodParameter> convert(ParameterList superList, ParameterList paraList, JavaGenerics generics) {
|
private List<MethodParameter> convert(ParameterList superList, ParameterList paraList, IGenerics generics) {
|
||||||
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);
|
||||||
var pattern = (TargetPattern) convert(param);
|
var pattern = (TargetPattern) convert(param, generics);
|
||||||
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
if (pattern instanceof TargetComplexPattern) pattern = pattern.withName("__var" + i);
|
||||||
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
|
list.add(new MethodParameter(pattern).withType(convert(superList.getParameterAt(i).getType(), generics)));
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetSwitch.Case convert(SwitchBlock block) {
|
protected TargetSwitch.Case convert(SwitchBlock block, IGenerics generics) {
|
||||||
return new TargetSwitch.Case(block.getLabels().stream().map(this::convert).toList(), convert((Block) block), block.isExpression);
|
return new TargetSwitch.Case(block.getLabels().stream().map(s -> convert(s, generics)).toList(), convert((Block) block, generics), block.isExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetBlock convert(Block block) {
|
protected TargetBlock convert(Block block, IGenerics generics) {
|
||||||
if (block == null) return null;
|
if (block == null) return null;
|
||||||
return new TargetBlock(block.statements.stream().map(this::convert).toList());
|
return new TargetBlock(block.statements.stream().map(s -> convert(s, generics)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetBlock convertWrapInBlock(Expression expression) {
|
protected TargetBlock convertWrapInBlock(Expression expression, IGenerics generics) {
|
||||||
var res = convert(expression);
|
var res = convert(expression, generics);
|
||||||
if (!(res instanceof TargetBlock))
|
if (!(res instanceof TargetBlock))
|
||||||
return new TargetBlock(List.of(res));
|
return new TargetBlock(List.of(res));
|
||||||
return (TargetBlock) res;
|
return (TargetBlock) res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetExpression convert(Expression expr) {
|
protected TargetExpression convert(Expression expr, IGenerics generics) {
|
||||||
var converter = new StatementToTargetExpression(this);
|
var converter = new StatementToTargetExpression(this, generics);
|
||||||
expr.accept(converter);
|
expr.accept(converter);
|
||||||
return converter.result;
|
return converter.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TargetField convert(Field input) {
|
private TargetField convert(Field input, IGenerics generics) {
|
||||||
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
return new TargetField(input.modifier, convert(input.getType(), generics), input.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||||
@@ -750,9 +756,6 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||||
|
|
||||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
|
||||||
return convert(input, generics.javaGenerics);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void collectArguments(TargetSpecializedType tspec, List<TargetType> newParams) {
|
private static void collectArguments(TargetSpecializedType tspec, List<TargetType> newParams) {
|
||||||
for (var i = 0; i < tspec.params().size(); i++) {
|
for (var i = 0; i < tspec.params().size(); i++) {
|
||||||
@@ -831,7 +834,13 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
// FIXME This method shouldn't be used
|
||||||
|
@Deprecated
|
||||||
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
||||||
|
return convert(input, all.getFirst().javaGenerics);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, IGenerics generics) {
|
||||||
return input.acceptTV(new TypeVisitor<>() {
|
return input.acceptTV(new TypeVisitor<>() {
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(RefType refType) {
|
public TargetType visit(RefType refType) {
|
||||||
|
@@ -16,7 +16,7 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class GenerateGenerics {
|
public abstract class GenerateGenerics implements IGenerics {
|
||||||
|
|
||||||
private final ASTToTargetAST astToTargetAST;
|
private final ASTToTargetAST astToTargetAST;
|
||||||
|
|
||||||
@@ -151,22 +151,6 @@ public abstract class GenerateGenerics {
|
|||||||
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
System.out.println("Simplified constraints: " + simplifiedConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public record GenericsState(Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes, Map<TypePlaceholder, TypePlaceholder> equality) {}
|
|
||||||
|
|
||||||
public GenericsState store() {
|
|
||||||
return new GenericsState(new HashMap<>(concreteTypes), new HashMap<>(equality));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void restore(GenericsState state) {
|
|
||||||
this.concreteTypes = state.concreteTypes;
|
|
||||||
this.equality = state.equality;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addOverlay(TypePlaceholder from, RefTypeOrTPHOrWildcardOrGeneric to) {
|
|
||||||
if (to instanceof TypePlaceholder t) equality.put(from, t);
|
|
||||||
else if (to instanceof RefType t) concreteTypes.put(new TPH(from), t);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Set<TPH> findTypeVariables(ParameterList params) {
|
Set<TPH> findTypeVariables(ParameterList params) {
|
||||||
var res = new HashSet<TPH>();
|
var res = new HashSet<TPH>();
|
||||||
for (var param : params.getFormalparalist()) {
|
for (var param : params.getFormalparalist()) {
|
||||||
@@ -282,6 +266,7 @@ public abstract class GenerateGenerics {
|
|||||||
Set<Pair> result
|
Set<Pair> result
|
||||||
) {
|
) {
|
||||||
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
|
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
|
||||||
|
var generics = this;
|
||||||
|
|
||||||
// Type variables with bounds that are also type variables of the method
|
// Type variables with bounds that are also type variables of the method
|
||||||
for (var typeVariable : new HashSet<>(typeVariables)) {
|
for (var typeVariable : new HashSet<>(typeVariables)) {
|
||||||
@@ -329,7 +314,7 @@ public abstract class GenerateGenerics {
|
|||||||
|
|
||||||
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
|
||||||
if (expressionReceiver.expr instanceof This) {
|
if (expressionReceiver.expr instanceof This) {
|
||||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(astToTargetAST::convert).toList());
|
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.signatureArguments().stream().map(sa -> astToTargetAST.convert(sa, generics)).toList());
|
||||||
if (optMethod.isEmpty()) return;
|
if (optMethod.isEmpty()) return;
|
||||||
var method2 = optMethod.get();
|
var method2 = optMethod.get();
|
||||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
||||||
@@ -539,8 +524,6 @@ public abstract class GenerateGenerics {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> javaTypeVariablesOfClass);
|
|
||||||
|
|
||||||
Set<Pair> family(ClassOrInterface owner, Method method) {
|
Set<Pair> family(ClassOrInterface owner, Method method) {
|
||||||
Set<Pair> result = new HashSet<>();
|
Set<Pair> result = new HashSet<>();
|
||||||
if (familyOfMethods.containsKey(method))
|
if (familyOfMethods.containsKey(method))
|
||||||
@@ -564,7 +547,8 @@ public abstract class GenerateGenerics {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
@Override
|
||||||
|
public Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||||
if (computedGenericsOfMethods.containsKey(method)) {
|
if (computedGenericsOfMethods.containsKey(method)) {
|
||||||
var cached = computedGenericsOfMethods.get(method);
|
var cached = computedGenericsOfMethods.get(method);
|
||||||
System.out.println("Cached " + method.getName() + ": " + cached);
|
System.out.println("Cached " + method.getName() + ": " + cached);
|
||||||
@@ -652,8 +636,10 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract void generics(ClassOrInterface classOrInterface, Set<Pair> result, Set<TPH> referenced);
|
abstract void generics(ClassOrInterface classOrInterface, Set<Pair> result, Set<TPH> referenced);
|
||||||
|
abstract void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced);
|
||||||
|
|
||||||
Set<Pair> generics(ClassOrInterface classOrInterface) {
|
@Override
|
||||||
|
public Set<Pair> generics(ClassOrInterface classOrInterface) {
|
||||||
if (computedGenericsOfClasses.containsKey(classOrInterface))
|
if (computedGenericsOfClasses.containsKey(classOrInterface))
|
||||||
return computedGenericsOfClasses.get(classOrInterface);
|
return computedGenericsOfClasses.get(classOrInterface);
|
||||||
|
|
||||||
@@ -988,7 +974,13 @@ public abstract class GenerateGenerics {
|
|||||||
} while (foundInfima);
|
} while (foundInfima);
|
||||||
}
|
}
|
||||||
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
@Override
|
||||||
|
public TypePlaceholder getEqualType(TypePlaceholder tph) {
|
||||||
|
return this.equality.getOrDefault(tph, tph);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
if (type instanceof TypePlaceholder tph) {
|
if (type instanceof TypePlaceholder tph) {
|
||||||
if (equality.containsKey(tph)) {
|
if (equality.containsKey(tph)) {
|
||||||
return getType(equality.get(tph));
|
return getType(equality.get(tph));
|
||||||
@@ -998,7 +990,8 @@ public abstract class GenerateGenerics {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
@Override
|
||||||
|
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
||||||
if (in instanceof TypePlaceholder tph) {
|
if (in instanceof TypePlaceholder tph) {
|
||||||
if (equality.containsKey(tph)) {
|
if (equality.containsKey(tph)) {
|
||||||
return getTargetType(equality.get(tph));
|
return getTargetType(equality.get(tph));
|
||||||
|
@@ -9,21 +9,20 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class GenericsResult {
|
public class GenericsResult {
|
||||||
private final GenerateGenerics generics;
|
private final IGenerics generics;
|
||||||
|
|
||||||
GenericsResult(GenerateGenerics generics) {
|
GenericsResult(IGenerics generics) {
|
||||||
this.generics = generics;
|
this.generics = generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GenericsResultSet get(ClassOrInterface clazz) {
|
public GenericsResultSet get(ClassOrInterface clazz) {
|
||||||
var generics = this.generics.computedGenericsOfClasses.get(clazz);
|
var generics = this.generics.generics(clazz);
|
||||||
return new GenericsResultSet(generics, this.generics.equality);
|
return new GenericsResultSet(generics, this.generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Compute generics if not present?
|
public GenericsResultSet get(ClassOrInterface clazz, Method method) {
|
||||||
public GenericsResultSet get(Method method) {
|
var generics = this.generics.generics(clazz, method);
|
||||||
var generics = this.generics.computedGenericsOfMethods.get(method);
|
return new GenericsResultSet(generics, this.generics);
|
||||||
return new GenericsResultSet(generics, this.generics.equality);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
|
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz) {
|
||||||
@@ -34,7 +33,7 @@ public class GenericsResult {
|
|||||||
var resolvedType = resolve(type);
|
var resolvedType = resolve(type);
|
||||||
type = resolvedType;
|
type = resolvedType;
|
||||||
if (type instanceof TypePlaceholder) {
|
if (type instanceof TypePlaceholder) {
|
||||||
var methodGenerics = get(method);
|
var methodGenerics = get(clazz, method);
|
||||||
var classGenerics = get(clazz);
|
var classGenerics = get(clazz);
|
||||||
List<Bound> result = new ArrayList<>();
|
List<Bound> result = new ArrayList<>();
|
||||||
|
|
||||||
|
@@ -4,17 +4,18 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType;
|
||||||
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||||
|
import org.antlr.v4.codegen.model.decl.ContextRuleListIndexedGetterDecl;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
||||||
|
|
||||||
final Set<GenerateGenerics.Pair> backing;
|
final Set<GenerateGenerics.Pair> backing;
|
||||||
final Map<TypePlaceholder, TypePlaceholder> equality;
|
final IGenerics generics;
|
||||||
|
|
||||||
public GenericsResultSet(Set<GenerateGenerics.Pair> backing, Map<TypePlaceholder, TypePlaceholder> equality) {
|
public GenericsResultSet(Set<GenerateGenerics.Pair> backing, IGenerics generics) {
|
||||||
this.backing = backing == null ? new HashSet<>() : new HashSet<>(backing);
|
this.backing = backing == null ? new HashSet<>() : new HashSet<>(backing);
|
||||||
this.equality = equality;
|
this.generics = generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -28,7 +29,7 @@ public class GenericsResultSet extends AbstractSet<GenerateGenerics.Pair> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) {
|
public Optional<ResultPair<?, ?>> getResultPairFor(TypePlaceholder tph) {
|
||||||
var tph2 = equality.getOrDefault(tph, tph);
|
var tph2 = generics.getEqualType(tph);
|
||||||
return this.stream().filter(pair -> {
|
return this.stream().filter(pair -> {
|
||||||
return pair.left.resolve().equals(tph2);
|
return pair.left.resolve().equals(tph2);
|
||||||
}).findFirst().map(pair -> {
|
}).findFirst().map(pair -> {
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface IGenerics {
|
||||||
|
|
||||||
|
Set<GenerateGenerics.Pair> generics(ClassOrInterface classOrInterface);
|
||||||
|
|
||||||
|
Set<GenerateGenerics.Pair> generics(ClassOrInterface owner, Method method);
|
||||||
|
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type);
|
||||||
|
|
||||||
|
TypePlaceholder getEqualType(TypePlaceholder tph);
|
||||||
|
|
||||||
|
TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in);
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetGenericType;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class OverlayGenerics implements IGenerics {
|
||||||
|
private final IGenerics wrapped;
|
||||||
|
private final ASTToTargetAST converter;
|
||||||
|
private final Map<TypePlaceholder, TargetType> overlay;
|
||||||
|
|
||||||
|
public OverlayGenerics(IGenerics wrapped, ASTToTargetAST converter) {
|
||||||
|
this.wrapped = wrapped;
|
||||||
|
this.converter = converter;
|
||||||
|
this.overlay = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOverlay(TypePlaceholder tph, TargetType type) {
|
||||||
|
this.overlay.put(tph, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<GenerateGenerics.Pair> generics(ClassOrInterface classOrInterface) {
|
||||||
|
return wrapped.generics(classOrInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<GenerateGenerics.Pair> generics(ClassOrInterface owner, Method method) {
|
||||||
|
return wrapped.generics(owner, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RefTypeOrTPHOrWildcardOrGeneric getType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
return wrapped.getType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypePlaceholder getEqualType(TypePlaceholder tph) {
|
||||||
|
return wrapped.getEqualType(tph);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TargetType getTargetType(RefTypeOrTPHOrWildcardOrGeneric in) {
|
||||||
|
if (in instanceof TypePlaceholder tph) {
|
||||||
|
var overlay = this.overlay.get(tph);
|
||||||
|
if (overlay != null) return overlay;
|
||||||
|
var type = getType(tph);
|
||||||
|
if (type == null) return new TargetGenericType(tph.getName());
|
||||||
|
return wrapped.getTargetType(type);
|
||||||
|
}
|
||||||
|
return converter.convert(in, this);
|
||||||
|
}
|
||||||
|
}
|
@@ -21,11 +21,13 @@ import java.util.stream.StreamSupport;
|
|||||||
|
|
||||||
public class StatementToTargetExpression implements ASTVisitor {
|
public class StatementToTargetExpression implements ASTVisitor {
|
||||||
|
|
||||||
public StatementToTargetExpression(ASTToTargetAST converter) {
|
public StatementToTargetExpression(ASTToTargetAST converter, IGenerics generics) {
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
|
this.generics = generics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetExpression result;
|
public TargetExpression result;
|
||||||
|
private final IGenerics generics;
|
||||||
private final ASTToTargetAST converter;
|
private final ASTToTargetAST converter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,7 +66,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
super.visit(localVar);
|
super.visit(localVar);
|
||||||
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType()), localVar.name));
|
var capture = new MethodParameter(new TargetTypePattern(converter.convert(localVar.getType(), generics), localVar.name));
|
||||||
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
if (!hasLocalVar(localVar.name) && !parameters.contains(capture) && !captures.contains(capture))
|
||||||
captures.add(capture);
|
captures.add(capture);
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
private List<MethodParameter> createParameters(LambdaExpression lambda) {
|
private List<MethodParameter> createParameters(LambdaExpression lambda) {
|
||||||
return StreamSupport.stream(lambda.params.spliterator(), false)
|
return StreamSupport.stream(lambda.params.spliterator(), false)
|
||||||
.map(p -> (FormalParameter) p)
|
.map(p -> (FormalParameter) p)
|
||||||
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType()), p.getName())))
|
.map(p -> new MethodParameter(new TargetTypePattern(converter.convert(p.getType(), generics), p.getName())))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,59 +101,59 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
var visitor = new LambdaCaptureFinder(parameters, captures);
|
var visitor = new LambdaCaptureFinder(parameters, captures);
|
||||||
lambdaExpression.methodBody.accept(visitor);
|
lambdaExpression.methodBody.accept(visitor);
|
||||||
|
|
||||||
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType()));;
|
TargetMethod.Signature signature = new TargetMethod.Signature(Set.of(), parameters, converter.convert(lambdaExpression.getReturnType(), generics));;
|
||||||
var tpe = converter.convert(lambdaExpression.getType());
|
var tpe = converter.convert(lambdaExpression.getType(), generics);
|
||||||
result = new TargetLambdaExpression(tpe, captures, signature, converter.convert(lambdaExpression.methodBody));
|
result = new TargetLambdaExpression(tpe, captures, signature, converter.convert(lambdaExpression.methodBody, this.generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
TargetExpression left;
|
TargetExpression left;
|
||||||
if (assign.lefSide instanceof AssignToLocal) {
|
if (assign.lefSide instanceof AssignToLocal) {
|
||||||
left = converter.convert(((AssignToLocal) assign.lefSide).localVar);
|
left = converter.convert(((AssignToLocal) assign.lefSide).localVar, this.generics);
|
||||||
} else {
|
} else {
|
||||||
left = converter.convert(((AssignToField) assign.lefSide).field);
|
left = converter.convert(((AssignToField) assign.lefSide).field, this.generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = new TargetAssign(converter.convert(assign.getType()), left, converter.convert(assign.rightSide));
|
result = new TargetAssign(converter.convert(assign.getType(), generics), left, converter.convert(assign.rightSide, this.generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
result = switch (binary.operation) {
|
result = switch (binary.operation) {
|
||||||
case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case AND -> new TargetBinaryOp.BAnd(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case AND -> new TargetBinaryOp.BAnd(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case OR -> new TargetBinaryOp.BOr(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case OR -> new TargetBinaryOp.BOr(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case XOR -> new TargetBinaryOp.XOr(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case XOR -> new TargetBinaryOp.XOr(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
|
case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType(), generics), converter.convert(binary.lexpr, this.generics), converter.convert(binary.rexpr, this.generics));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BoolExpression bool) {
|
public void visit(BoolExpression bool) {
|
||||||
result = switch(bool.operation) {
|
result = switch(bool.operation) {
|
||||||
case OR -> new TargetBinaryOp.Or(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
case OR -> new TargetBinaryOp.Or(converter.convert(bool.getType(), generics), converter.convert(bool.lexpr, generics), converter.convert(bool.rexpr, generics));
|
||||||
case AND -> new TargetBinaryOp.And(converter.convert(bool.getType()), converter.convert(bool.lexpr), converter.convert(bool.rexpr));
|
case AND -> new TargetBinaryOp.And(converter.convert(bool.getType(), generics), converter.convert(bool.lexpr, generics), converter.convert(bool.rexpr, generics));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Block block) {
|
public void visit(Block block) {
|
||||||
result = converter.convert(block);
|
result = converter.convert(block, generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr castExpr) {
|
public void visit(CastExpr castExpr) {
|
||||||
result = new TargetCast(converter.convert(castExpr.getType()), converter.convert(castExpr.expr));
|
result = new TargetCast(converter.convert(castExpr.getType(), generics), converter.convert(castExpr.expr, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -162,46 +164,46 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
var isStatic = false;
|
var isStatic = false;
|
||||||
var type = converter.convert(fieldVar.receiver.getType());
|
var type = converter.convert(fieldVar.receiver.getType(), generics);
|
||||||
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
|
var clazz = converter.compiler.getClass(new JavaClassName(type.name()));
|
||||||
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
|
var field = clazz.getField(fieldVar.fieldVarName).orElseThrow();
|
||||||
result = new TargetFieldVar(converter.convert(fieldVar.getType()), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
|
result = new TargetFieldVar(converter.convert(fieldVar.getType(), generics), type, Modifier.isStatic(field.modifier), converter.convert(fieldVar.receiver, this.generics), fieldVar.fieldVarName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
result = new TargetFor(
|
result = new TargetFor(
|
||||||
forStmt.initializer.stream().map(converter::convert).toList(),
|
forStmt.initializer.stream().map(c -> converter.convert(c, generics)).toList(),
|
||||||
forStmt.condition != null ? converter.convert(forStmt.condition) : null,
|
forStmt.condition != null ? converter.convert(forStmt.condition, generics) : null,
|
||||||
forStmt.loopExpr.stream().map(converter::convert).toList(),
|
forStmt.loopExpr.stream().map(e -> converter.convert(e, generics)).toList(),
|
||||||
converter.convertWrapInBlock(forStmt.block)
|
converter.convertWrapInBlock(forStmt.block, generics)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForEachStmt forEachStmt) {
|
public void visit(ForEachStmt forEachStmt) {
|
||||||
result = new TargetForEach(converter.convert(forEachStmt.statement), converter.convert(forEachStmt.expression), converter.convertWrapInBlock(forEachStmt.block));
|
result = new TargetForEach(converter.convert(forEachStmt.statement, generics), converter.convert(forEachStmt.expression, generics), converter.convertWrapInBlock(forEachStmt.block, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
result = new TargetIf(converter.convert(ifStmt.expr), converter.convertWrapInBlock(ifStmt.then_block), ifStmt.else_block != null ? converter.convertWrapInBlock(ifStmt.else_block) : null);
|
result = new TargetIf(converter.convert(ifStmt.expr, generics), converter.convertWrapInBlock(ifStmt.then_block, generics), ifStmt.else_block != null ? converter.convertWrapInBlock(ifStmt.else_block, generics) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InstanceOf instanceOf) {
|
public void visit(InstanceOf instanceOf) {
|
||||||
result = new TargetInstanceOf(converter.convert(instanceOf.getExpression()), converter.convert(instanceOf.getPattern()));
|
result = new TargetInstanceOf(converter.convert(instanceOf.getExpression(), generics), converter.convert(instanceOf.getPattern(), this.generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
result = new TargetLocalVar(converter.convert(localVar.getType()), localVar.name);
|
result = new TargetLocalVar(converter.convert(localVar.getType(), generics), localVar.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
// TODO No value, is this correct?
|
// TODO No value, is this correct?
|
||||||
result = new TargetVarDecl(converter.convert(localVarDecl.getType()), localVarDecl.getName(), null);
|
result = new TargetVarDecl(converter.convert(localVarDecl.getType(), generics), localVarDecl.getName(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean convertsTo(TargetType from, TargetType to) {
|
static boolean convertsTo(TargetType from, TargetType to) {
|
||||||
@@ -216,19 +218,19 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
var receiverType = converter.convert(methodCall.receiver.getType());
|
var receiverType = converter.convert(methodCall.receiver.getType(), generics);
|
||||||
var isFunNType = receiverType instanceof TargetFunNType;
|
var isFunNType = receiverType instanceof TargetFunNType;
|
||||||
|
|
||||||
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.get(methodCall.signature.size() - 1));
|
var returnType = isFunNType ? TargetType.Object : converter.convert(methodCall.signature.getLast(), generics);
|
||||||
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType()).name());
|
var receiverName = new JavaClassName(converter.convert(methodCall.receiver.getType(), generics).name());
|
||||||
var argList = methodCall.signature.stream().map(converter::convert).toList();
|
var argList = methodCall.signature.stream().map(sig -> converter.convert(sig, generics)).toList();
|
||||||
argList = argList.subList(0, argList.size() - 1);
|
argList = argList.subList(0, argList.size() - 1);
|
||||||
|
|
||||||
Method foundMethod = null;
|
Method foundMethod = null;
|
||||||
var isStatic = false;
|
var isStatic = false;
|
||||||
var isInterface = true;
|
var isInterface = true;
|
||||||
var isPrivate = false;
|
var isPrivate = false;
|
||||||
var signature = methodCall.signatureArguments().stream().map(converter::convert).toList();
|
var signature = methodCall.signatureArguments().stream().map(sig -> converter.convert(sig, generics)).toList();
|
||||||
|
|
||||||
// Add used TPHs to containing method
|
// Add used TPHs to containing method
|
||||||
for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
|
for (var i = 0; i < methodCall.signatureArguments().size(); i++) {
|
||||||
@@ -248,23 +250,28 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isFunNType) {
|
if (!isFunNType) {
|
||||||
returnType = converter.convert(foundMethod.getReturnType());
|
returnType = converter.convert(foundMethod.getReturnType(), generics);
|
||||||
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
|
argList = foundMethod.getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||||
isStatic = Modifier.isStatic(foundMethod.modifier);
|
isStatic = Modifier.isStatic(foundMethod.modifier);
|
||||||
isPrivate = Modifier.isPrivate(foundMethod.modifier);
|
isPrivate = Modifier.isPrivate(foundMethod.modifier);
|
||||||
isInterface = receiverClass.isInterface();
|
isInterface = receiverClass.isInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(argList);
|
System.out.println(argList);
|
||||||
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, isStatic, isInterface, isPrivate);
|
result = new TargetMethodCall(
|
||||||
|
converter.convert(methodCall.getType(), generics), returnType, argList,
|
||||||
|
converter.convert(methodCall.receiver, generics),
|
||||||
|
methodCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList(),
|
||||||
|
receiverType, methodCall.name, isStatic, isInterface, isPrivate
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass newClass) {
|
public void visit(NewClass newClass) {
|
||||||
var receiverName = new JavaClassName(newClass.name);
|
var receiverName = new JavaClassName(newClass.name);
|
||||||
var ctor = converter.findConstructor(converter.compiler.getClass(receiverName), newClass.signatureArguments().stream().map(converter::convert).toList());
|
var ctor = converter.findConstructor(converter.compiler.getClass(receiverName), newClass.signatureArguments().stream().map(arg -> converter.convert(arg, generics)).toList());
|
||||||
var signature = ctor.orElseThrow().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
|
var signature = ctor.orElseThrow().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||||
result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(converter::convert).toList());
|
result = new TargetNew(new TargetRefType(newClass.name), signature, newClass.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -275,7 +282,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Return aReturn) {
|
public void visit(Return aReturn) {
|
||||||
result = new TargetReturn(converter.convert(aReturn.retexpr));
|
result = new TargetReturn(converter.convert(aReturn.retexpr, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -295,53 +302,53 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
result = new TargetClassName(converter.convert(staticClassName.getType(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Super aSuper) {
|
public void visit(Super aSuper) {
|
||||||
result = new TargetSuper(converter.convert(aSuper.getType()));
|
result = new TargetSuper(converter.convert(aSuper.getType(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
result = new TargetThis(converter.convert(aThis.getType()));
|
result = new TargetThis(converter.convert(aThis.getType(), generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStmt whileStmt) {
|
public void visit(WhileStmt whileStmt) {
|
||||||
result = new TargetWhile(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
|
result = new TargetWhile(converter.convert(whileStmt.expr, generics), converter.convert(whileStmt.loopBlock, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
result = new TargetDo(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
|
result = new TargetDo(converter.convert(whileStmt.expr, generics), converter.convert(whileStmt.loopBlock, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO These two might not be necessary
|
// TODO These two might not be necessary
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
result = converter.convert(assignLeftSide.field);
|
result = converter.convert(assignLeftSide.field, generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
result = converter.convert(assignLeftSide.localVar);
|
result = converter.convert(assignLeftSide.localVar, generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
var aSuper = converter.convert(superCall.receiver.getType());
|
var aSuper = converter.convert(superCall.receiver.getType(), generics);
|
||||||
var type = converter.convert(superCall.getType());
|
var type = converter.convert(superCall.getType(), generics);
|
||||||
var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType()).name());
|
var receiverName = new JavaClassName(converter.convert(superCall.receiver.getType(), generics).name());
|
||||||
var clazz = converter.compiler.getClass(receiverName);
|
var clazz = converter.compiler.getClass(receiverName);
|
||||||
var signature = superCall.signatureArguments().stream().map(converter::convert).toList();
|
var signature = superCall.signatureArguments().stream().map(arg -> converter.convert(arg, generics)).toList();
|
||||||
var method = converter.findConstructor(clazz, signature);
|
var method = converter.findConstructor(clazz, signature);
|
||||||
var params = superCall.getArgumentList().getArguments().stream().map(converter::convert).toList();
|
var params = superCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList();
|
||||||
|
|
||||||
List<TargetType> argList;
|
List<TargetType> argList;
|
||||||
if (method.isPresent()) {
|
if (method.isPresent()) {
|
||||||
argList = method.get().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType())).toList();
|
argList = method.get().getParameterList().getFormalparalist().stream().map(e -> converter.convert(e.getType(), generics)).toList();
|
||||||
} else {
|
} else {
|
||||||
argList = params.stream().map(TargetExpression::type).toList();
|
argList = params.stream().map(TargetExpression::type).toList();
|
||||||
}
|
}
|
||||||
@@ -351,28 +358,28 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ThisCall thisCall) {
|
public void visit(ThisCall thisCall) {
|
||||||
var aThis = converter.convert(thisCall.receiver.getType());
|
var aThis = converter.convert(thisCall.receiver.getType(), generics);
|
||||||
var type = converter.convert(thisCall.getType());
|
var type = converter.convert(thisCall.getType(), generics);
|
||||||
var parameters = thisCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList();
|
var parameters = thisCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType(), generics)).toList();
|
||||||
|
|
||||||
result = new TargetMethodCall(type, type, parameters, new TargetThis(aThis), thisCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), aThis, thisCall.name, false, false, false);
|
result = new TargetMethodCall(type, type, parameters, new TargetThis(aThis), thisCall.getArgumentList().getArguments().stream().map(arg -> converter.convert(arg, generics)).toList(), aThis, thisCall.name, false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ExpressionReceiver expressionReceiver) {
|
public void visit(ExpressionReceiver expressionReceiver) {
|
||||||
result = converter.convert(expressionReceiver.expr);
|
result = converter.convert(expressionReceiver.expr, generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(UnaryExpr unaryExpr) {
|
public void visit(UnaryExpr unaryExpr) {
|
||||||
result = switch (unaryExpr.operation) {
|
result = switch (unaryExpr.operation) {
|
||||||
case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
|
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType(), generics), converter.convert(unaryExpr.expr, generics));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,12 +407,12 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Throw aThrow) {
|
public void visit(Throw aThrow) {
|
||||||
result = new TargetThrow(converter.convert(aThrow.expr));
|
result = new TargetThrow(converter.convert(aThrow.expr, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Ternary ternary) {
|
public void visit(Ternary ternary) {
|
||||||
result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
|
result = new TargetTernary(converter.convert(ternary.getType(), generics), converter.convert(ternary.cond, generics), converter.convert(ternary.iftrue, generics), converter.convert(ternary.iffalse, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {}
|
record TypeVariants(RefTypeOrTPHOrWildcardOrGeneric in, List<RefTypeOrTPHOrWildcardOrGeneric> types) {}
|
||||||
@@ -469,10 +476,8 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
var product = cartesianProduct(extractAllPatterns(label.getPattern()));
|
var product = cartesianProduct(extractAllPatterns(label.getPattern()));
|
||||||
|
|
||||||
for (var l : product) {
|
for (var l : product) {
|
||||||
var oldGenerics = converter.generics;
|
|
||||||
|
|
||||||
// Set the generics to matching result set
|
// Set the generics to matching result set
|
||||||
for (var generics : converter.currentMethodOverloads) {
|
/*for (var generics : converter.currentMethodOverloads) {
|
||||||
var java = generics.javaGenerics();
|
var java = generics.javaGenerics();
|
||||||
var equals = true;
|
var equals = true;
|
||||||
for (var pair : l) {
|
for (var pair : l) {
|
||||||
@@ -481,17 +486,15 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (equals) {
|
if (equals) {
|
||||||
converter.generics = generics;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
overloads.add(converter.convert(case_));
|
overloads.add(converter.convert(case_, generics));
|
||||||
converter.generics = oldGenerics;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
overloads.add(converter.convert(case_));
|
overloads.add(converter.convert(case_, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
return overloads;
|
return overloads;
|
||||||
@@ -500,10 +503,10 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
TargetSwitch.Case default_ = null;
|
TargetSwitch.Case default_ = null;
|
||||||
for (var block : switchStmt.getBlocks()) {
|
for (var block : switchStmt.getBlocks()) {
|
||||||
if (block.isDefault()) {
|
if (block.isDefault()) {
|
||||||
default_ = new TargetSwitch.Case(converter.convert((Block) block), block.isExpression);
|
default_ = new TargetSwitch.Case(converter.convert((Block) block, generics), block.isExpression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = new TargetSwitch(converter.convert(switchStmt.getSwitch()), cases, default_ , converter.convert(switchStmt.getType()), !switchStmt.getStatement());
|
result = new TargetSwitch(converter.convert(switchStmt.getSwitch(), generics), cases, default_ , converter.convert(switchStmt.getType(), generics), !switchStmt.getStatement());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -511,12 +514,12 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SwitchLabel switchLabel) {
|
public void visit(SwitchLabel switchLabel) {
|
||||||
result = converter.convert(switchLabel.getPattern());
|
result = converter.convert(switchLabel.getPattern(), this.generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Yield aYield) {
|
public void visit(Yield aYield) {
|
||||||
result = new TargetYield(converter.convert(aYield.retexpr));
|
result = new TargetYield(converter.convert(aYield.retexpr, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -586,30 +589,30 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FormalParameter aPattern) {
|
public void visit(FormalParameter aPattern) {
|
||||||
result = new TargetTypePattern(converter.convert(aPattern.getType()), aPattern.getName());
|
result = new TargetTypePattern(converter.convert(aPattern.getType(), generics), aPattern.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LiteralPattern literalPattern) {
|
public void visit(LiteralPattern literalPattern) {
|
||||||
result = new TargetExpressionPattern(converter.convert(literalPattern.value));
|
result = new TargetExpressionPattern(converter.convert(literalPattern.value, generics));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ExpressionPattern aPattern) {
|
public void visit(ExpressionPattern aPattern) {
|
||||||
result = converter.convert(aPattern.getExpression());
|
result = converter.convert(aPattern.getExpression(), generics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RecordPattern aRecordPattern) {
|
public void visit(RecordPattern aRecordPattern) {
|
||||||
result = new TargetComplexPattern(
|
result = new TargetComplexPattern(
|
||||||
converter.convert(aRecordPattern.getType()),
|
converter.convert(aRecordPattern.getType(), generics),
|
||||||
aRecordPattern.getName(),
|
aRecordPattern.getName(),
|
||||||
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x)).toList()
|
aRecordPattern.getSubPattern().stream().map(x -> (TargetPattern) converter.convert(x, generics)).toList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GuardedPattern aGuardedPattern) {
|
public void visit(GuardedPattern aGuardedPattern) {
|
||||||
result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern()), converter.convert(aGuardedPattern.getCondition()));
|
result = new TargetGuard((TargetPattern) converter.convert(aGuardedPattern.getNestedPattern(), generics), converter.convert(aGuardedPattern.getCondition(), generics));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -55,7 +55,7 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
constraints = generatedGenerics.get(method);
|
constraints = generatedGenerics.get(cl, method);
|
||||||
classConstraints = generatedGenerics.get(cl);
|
classConstraints = generatedGenerics.get(cl);
|
||||||
if(method.getReturnType() instanceof TypePlaceholder)
|
if(method.getReturnType() instanceof TypePlaceholder)
|
||||||
inserts.add(TypeInsertFactory.createInsertPoints(
|
inserts.add(TypeInsertFactory.createInsertPoints(
|
||||||
|
@@ -931,7 +931,7 @@ public class TestComplete {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Disabled("Not implemented")
|
//@Disabled("Not implemented")
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingListAppend() throws Exception {
|
public void testPatternMatchingListAppend() throws Exception {
|
||||||
var classFiles = generateClassFiles(createClassLoader(), "PatternMatchingListAppend.jav");
|
var classFiles = generateClassFiles(createClassLoader(), "PatternMatchingListAppend.jav");
|
||||||
|
@@ -65,7 +65,7 @@ public class TestGenerics {
|
|||||||
var b = result.findField("b");
|
var b = result.findField("b");
|
||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(1, generics.get(anyMethod).size());
|
assertEquals(1, generics.get(result.clazz, anyMethod).size());
|
||||||
assertEquals(2, generics.get(result.clazz).size());
|
assertEquals(2, generics.get(result.clazz).size());
|
||||||
|
|
||||||
var ECK1 = generics.getBounds(otherMethod.getParameterList().getParameterAt(0).getType(), result.clazz, anyMethod);
|
var ECK1 = generics.getBounds(otherMethod.getParameterList().getParameterAt(0).getType(), result.clazz, anyMethod);
|
||||||
@@ -86,7 +86,7 @@ public class TestGenerics {
|
|||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(1, generics.get(result.clazz).size());
|
assertEquals(1, generics.get(result.clazz).size());
|
||||||
assertEquals(0, generics.get(fReturn).size());
|
assertEquals(0, generics.get(result.clazz, fReturn).size());
|
||||||
|
|
||||||
var N = generics.getBounds(fReturn.getReturnType(), result.clazz);
|
var N = generics.getBounds(fReturn.getReturnType(), result.clazz);
|
||||||
var NChain = new BoundsList(onClass(OBJECT));
|
var NChain = new BoundsList(onClass(OBJECT));
|
||||||
@@ -101,8 +101,8 @@ public class TestGenerics {
|
|||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(0, generics.get(result.clazz).size());
|
assertEquals(0, generics.get(result.clazz).size());
|
||||||
assertEquals(3, generics.get(m).size());
|
assertEquals(3, generics.get(result.clazz, m).size());
|
||||||
assertEquals(3, generics.get(main).size());
|
assertEquals(3, generics.get(result.clazz, main).size());
|
||||||
|
|
||||||
{
|
{
|
||||||
var AJ = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
var AJ = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
||||||
@@ -143,9 +143,9 @@ public class TestGenerics {
|
|||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(1, generics.get(result.clazz).size());
|
assertEquals(1, generics.get(result.clazz).size());
|
||||||
assertEquals(2, generics.get(id).size());
|
assertEquals(2, generics.get(result.clazz, id).size());
|
||||||
assertEquals(1, generics.get(setA).size());
|
assertEquals(1, generics.get(result.clazz, setA).size());
|
||||||
assertEquals(2, generics.get(m).size());
|
assertEquals(2, generics.get(result.clazz, m).size());
|
||||||
|
|
||||||
var R = generics.getBounds(a.getType(), result.clazz);
|
var R = generics.getBounds(a.getType(), result.clazz);
|
||||||
var RChain = new BoundsList(onClass(OBJECT));
|
var RChain = new BoundsList(onClass(OBJECT));
|
||||||
@@ -183,9 +183,9 @@ public class TestGenerics {
|
|||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(1, generics.get(result.clazz).size());
|
assertEquals(1, generics.get(result.clazz).size());
|
||||||
assertEquals(2, generics.get(id).size());
|
assertEquals(2, generics.get(result.clazz, id).size());
|
||||||
assertEquals(2, generics.get(m).size());
|
assertEquals(2, generics.get(result.clazz, m).size());
|
||||||
assertEquals(3, generics.get(main).size());
|
assertEquals(3, generics.get(result.clazz, main).size());
|
||||||
|
|
||||||
var N = generics.getBounds(a.getType(), result.clazz);
|
var N = generics.getBounds(a.getType(), result.clazz);
|
||||||
assertEquals(N, new BoundsList(onClass(OBJECT)));
|
assertEquals(N, new BoundsList(onClass(OBJECT)));
|
||||||
@@ -215,7 +215,7 @@ public class TestGenerics {
|
|||||||
var anyMethod = result.findMethod("anyMethod");
|
var anyMethod = result.findMethod("anyMethod");
|
||||||
|
|
||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
assertEquals(1, generics.get(anyMethod).size());
|
assertEquals(1, generics.get(result.clazz, anyMethod).size());
|
||||||
|
|
||||||
var M = generics.getBounds(anyMethod.getReturnType(), result.clazz, anyMethod);
|
var M = generics.getBounds(anyMethod.getReturnType(), result.clazz, anyMethod);
|
||||||
assertEquals(M, new BoundsList(onMethod(OBJECT)));
|
assertEquals(M, new BoundsList(onMethod(OBJECT)));
|
||||||
|
Reference in New Issue
Block a user