forked from JavaTX/JavaCompilerCore
Allow packages
This commit is contained in:
parent
0b815950e1
commit
628f1631e8
21
Switch.java
21
Switch.java
@ -1,21 +0,0 @@
|
|||||||
|
|
||||||
public class Switch {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
CharSequence s = "some string";
|
|
||||||
/*var res = switch (s) {
|
|
||||||
case "AaAaAa" -> 20;
|
|
||||||
case "AaAaBB" -> 30;
|
|
||||||
case String y -> 40;
|
|
||||||
case CharSequence cs -> 30;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
var i = s instanceof String s2;
|
|
||||||
//System.out.println(s2);
|
|
||||||
|
|
||||||
if (!(s instanceof String s2)) {
|
|
||||||
System.out.println(s2);
|
|
||||||
} else {
|
|
||||||
System.out.println(s2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
4
pom.xml
4
pom.xml
@ -54,8 +54,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<version>3.11.0</version>
|
<version>3.11.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>20</source>
|
<source>21</source>
|
||||||
<target>20</target>
|
<target>21</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
11
resources/packageTest/pkg/sub/Cycle1.jav
Normal file
11
resources/packageTest/pkg/sub/Cycle1.jav
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package pkg.sub;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import pkg.sub2.Cycle2;
|
||||||
|
|
||||||
|
public class Cycle1 {
|
||||||
|
test() {
|
||||||
|
var cycle2 = new Cycle2();
|
||||||
|
cycle2.test();
|
||||||
|
}
|
||||||
|
}
|
11
resources/packageTest/pkg/sub/Test1.jav
Normal file
11
resources/packageTest/pkg/sub/Test1.jav
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package pkg.sub;
|
||||||
|
|
||||||
|
import pkg.sub2.Test2;
|
||||||
|
|
||||||
|
public class Test1 {
|
||||||
|
|
||||||
|
main() {
|
||||||
|
var t2 = new Test2();
|
||||||
|
t2.test();
|
||||||
|
}
|
||||||
|
}
|
11
resources/packageTest/pkg/sub2/Cycle2.jav
Normal file
11
resources/packageTest/pkg/sub2/Cycle2.jav
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package pkg.sub2;
|
||||||
|
|
||||||
|
import java.lang.Integer;
|
||||||
|
import pkg.sub.Cycle1;
|
||||||
|
|
||||||
|
public class Cycle2 {
|
||||||
|
test() {
|
||||||
|
var cycle1 = new Cycle1();
|
||||||
|
cycle1.test();
|
||||||
|
}
|
||||||
|
}
|
6
resources/packageTest/pkg/sub2/Test2.jav
Normal file
6
resources/packageTest/pkg/sub2/Test2.jav
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package pkg.sub2;
|
||||||
|
|
||||||
|
public class Test2 {
|
||||||
|
|
||||||
|
test() {}
|
||||||
|
}
|
@ -27,7 +27,7 @@ public class Codegen {
|
|||||||
|
|
||||||
public Codegen(TargetStructure clazz, JavaTXCompiler compiler) {
|
public Codegen(TargetStructure clazz, JavaTXCompiler compiler) {
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.className = clazz.qualifiedName();
|
this.className = clazz.qualifiedName().getClassName();
|
||||||
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
|
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
|
||||||
@Override
|
@Override
|
||||||
protected ClassLoader getClassLoader() {
|
protected ClassLoader getClassLoader() {
|
||||||
@ -743,7 +743,7 @@ public class Codegen {
|
|||||||
desugared += "V";
|
desugared += "V";
|
||||||
|
|
||||||
var params = new ArrayList<TargetType>();
|
var params = new ArrayList<TargetType>();
|
||||||
params.add(new TargetRefType(clazz.qualifiedName()));
|
params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
||||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||||
|
|
||||||
var descriptor = TargetMethod.getDescriptor(lambda.type(), params.toArray(TargetType[]::new));
|
var descriptor = TargetMethod.getDescriptor(lambda.type(), params.toArray(TargetType[]::new));
|
||||||
@ -1382,7 +1382,7 @@ public class Codegen {
|
|||||||
if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
if ((access & ACC_PRIVATE) == 0 && (access & ACC_PROTECTED) == 0) // TODO Implement access modifiers properly
|
||||||
access |= ACC_PUBLIC;
|
access |= ACC_PUBLIC;
|
||||||
|
|
||||||
cw.visit(V1_8, access | ACC_SUPER, clazz.qualifiedName(), generateSignature(clazz, clazz.generics()), clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object", clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new));
|
cw.visit(V1_8, access | ACC_SUPER, clazz.qualifiedName().toString().replaceAll("\\.", "/"), generateSignature(clazz, clazz.generics()), clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object", clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new));
|
||||||
if (clazz.txGenerics() != null)
|
if (clazz.txGenerics() != null)
|
||||||
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
|||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
@ -30,6 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
|||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
|
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
||||||
|
import de.dhbwstuttgart.target.tree.expression.TargetBinaryOp;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
@ -72,6 +74,8 @@ public class JavaTXCompiler {
|
|||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
private final DirectoryClassLoader classLoader;
|
private final DirectoryClassLoader classLoader;
|
||||||
|
|
||||||
|
private final List<File> classPath;
|
||||||
|
|
||||||
public DirectoryClassLoader getClassLoader() {
|
public DirectoryClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
@ -96,6 +100,8 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
|
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
|
||||||
environment = new CompilationEnvironment(sources);
|
environment = new CompilationEnvironment(sources);
|
||||||
|
classPath = contextPath;
|
||||||
|
|
||||||
for (File s : sources) {
|
for (File s : sources) {
|
||||||
sourceFiles.put(s, parse(s));
|
sourceFiles.put(s, parse(s));
|
||||||
}
|
}
|
||||||
@ -109,11 +115,9 @@ public class JavaTXCompiler {
|
|||||||
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
||||||
for (Entry<File, SourceFile> source : sourceFiles.entrySet()) {
|
for (Entry<File, SourceFile> source : sourceFiles.entrySet()) {
|
||||||
for (JavaClassName name : source.getValue().getImports()) {
|
for (JavaClassName name : source.getValue().getImports()) {
|
||||||
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
importedClasses.addAll(getAvailableClasses(name));
|
||||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
|
||||||
importedClasses.add(importedClass);
|
|
||||||
}
|
}
|
||||||
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), classLoader)) {
|
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(source.getValue().getPkgName(), source.getKey(), this)) {
|
||||||
ClassOrInterface importedClass = ASTFactory.createClass(c);
|
ClassOrInterface importedClass = ASTFactory.createClass(c);
|
||||||
importedClasses.add(importedClass);
|
importedClasses.add(importedClass);
|
||||||
}
|
}
|
||||||
@ -176,6 +180,19 @@ public class JavaTXCompiler {
|
|||||||
cl.setMethodsAdded();
|
cl.setMethodsAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ClassOrInterface> getAvailableClasses(JavaClassName name) throws ClassNotFoundException {
|
||||||
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
if (loadJavaTXClass(name)) {
|
||||||
|
var file = findFileForClass(name);
|
||||||
|
var sf = sourceFiles.get(file);
|
||||||
|
if (sf != null) allClasses.addAll(sf.KlassenVektor);
|
||||||
|
} else {
|
||||||
|
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
||||||
|
allClasses.add(importedClass);
|
||||||
|
}
|
||||||
|
return new ArrayList<>(allClasses);
|
||||||
|
}
|
||||||
|
|
||||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||||
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
||||||
// hinzugefuegt werden
|
// hinzugefuegt werden
|
||||||
@ -183,22 +200,8 @@ public class JavaTXCompiler {
|
|||||||
// ArrayList<>();//environment.getAllAvailableClasses();
|
// ArrayList<>();//environment.getAllAvailableClasses();
|
||||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
|
||||||
/*
|
|
||||||
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt } allClasses.addAll(importedClasses);
|
|
||||||
*
|
|
||||||
* return new TYPE(sourceFiles.values(), allClasses).getConstraints(); }
|
|
||||||
*
|
|
||||||
* public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { // PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal // hinzugefuegt werden // List<ClassOrInterface> allClasses = new // ArrayList<>();//environment.getAllAvailableClasses(); Set<ClassOrInterface> allClasses = new HashSet<>();
|
|
||||||
*
|
|
||||||
* /* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses()); }
|
|
||||||
*/
|
|
||||||
|
|
||||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
|
||||||
for (JavaClassName name : forSourceFile.getImports()) {
|
for (JavaClassName name : forSourceFile.getImports()) {
|
||||||
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
allClasses.addAll(getAvailableClasses(name));
|
||||||
ClassOrInterface importedClass = ASTFactory.createClass(classLoader.loadClass(name.toString()));
|
|
||||||
importedClasses.add(importedClass);
|
|
||||||
allClasses.addAll(importedClasses);
|
|
||||||
}
|
}
|
||||||
return new ArrayList<>(allClasses);
|
return new ArrayList<>(allClasses);
|
||||||
}
|
}
|
||||||
@ -253,7 +256,7 @@ public class JavaTXCompiler {
|
|||||||
SourceFile sf = source.getValue();
|
SourceFile sf = source.getValue();
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
allClasses.addAll(getAvailableClasses(sf));
|
||||||
allClasses.addAll(sf.getClasses());
|
allClasses.addAll(sf.getClasses());
|
||||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final ConstraintSet<Pair> cons = getConstraints();
|
final ConstraintSet<Pair> cons = getConstraints();
|
||||||
@ -262,7 +265,7 @@ public class JavaTXCompiler {
|
|||||||
// urm.addUnifyResultListener(resultListener);
|
// urm.addUnifyResultListener(resultListener);
|
||||||
try {
|
try {
|
||||||
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile;
|
||||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader);
|
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, getClassLoader());
|
||||||
System.out.println(finiteClosure);
|
System.out.println(finiteClosure);
|
||||||
urm = new UnifyResultModel(cons, finiteClosure);
|
urm = new UnifyResultModel(cons, finiteClosure);
|
||||||
urm.addUnifyResultListener(resultListener);
|
urm.addUnifyResultListener(resultListener);
|
||||||
@ -384,7 +387,7 @@ public class JavaTXCompiler {
|
|||||||
SourceFile sf = source.getValue();
|
SourceFile sf = source.getValue();
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
allClasses.addAll(getAvailableClasses(sf));
|
||||||
allClasses.addAll(sf.getClasses());
|
allClasses.addAll(sf.getClasses());
|
||||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList());
|
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), source.getKey(), this).stream().map(ASTFactory::createClass).collect(Collectors.toList());
|
||||||
for (var clazz : newClasses) {
|
for (var clazz : newClasses) {
|
||||||
// Don't load classes that get recompiled
|
// Don't load classes that get recompiled
|
||||||
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
||||||
@ -622,13 +625,52 @@ public class JavaTXCompiler {
|
|||||||
return usedTPH;
|
return usedTPH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final JavaClassRegistry classRegistry = new JavaClassRegistry();
|
||||||
|
|
||||||
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
||||||
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
||||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(tree, sourceFile, classLoader), new GenericsRegistry(null));
|
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
|
||||||
SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader);
|
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(classRegistry, new GenericsRegistry(null));
|
||||||
|
SourceFile ret = generator.convert(tree, environment.packageCrawler, this);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an import tries to import a JavaTX class it first looks it up in the cache and
|
||||||
|
* if it doesn't exist it's going to compile it and add it to the source files list
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public boolean loadJavaTXClass(JavaClassName name) {
|
||||||
|
if (classRegistry.contains(name.getClassName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = findFileForClass(name);
|
||||||
|
if (file != null) {
|
||||||
|
try {
|
||||||
|
var tree = JavaTXParser.parse(file);
|
||||||
|
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
|
||||||
|
environment.addClassesToRegistry(classRegistry, tree, file, this);
|
||||||
|
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(classRegistry, new GenericsRegistry(null));
|
||||||
|
sourceFiles.put(file, generator.convert(tree, environment.packageCrawler, this));
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public File findFileForClass(JavaClassName name) {
|
||||||
|
var packageName = name.getPackageName();
|
||||||
|
var className = name.getClassName().split("\\.")[0];
|
||||||
|
for (var cp : classPath) {
|
||||||
|
var file = new File(cp, packageName.replaceAll("\\.", "/") + "/" + className + ".jav");
|
||||||
|
if (file.exists()) return file;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void generateBytecode() throws ClassNotFoundException, IOException {
|
public void generateBytecode() throws ClassNotFoundException, IOException {
|
||||||
generateBytecode((File) null);
|
generateBytecode((File) null);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import java.net.URL;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
|
|
||||||
@ -56,21 +57,22 @@ public class CompilationEnvironment {
|
|||||||
this.packageCrawler = new PackageCrawler(librarys);
|
this.packageCrawler = new PackageCrawler(librarys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaClassRegistry getRegistry(SourceFileContext tree, File sourceFile, ClassLoader classLoader) throws ClassNotFoundException, IOException {
|
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
|
||||||
Map<String, Integer> allNames;
|
Map<String, Integer> allNames;
|
||||||
if (tree instanceof SrcfileContext srcfile) {
|
if (tree instanceof SrcfileContext srcfile) {
|
||||||
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, classLoader);
|
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, compiler);
|
||||||
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, classLoader)) {
|
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, compiler)) {
|
||||||
allNames.put(c.getName(), c.getTypeParameters().length);
|
allNames.put(c.getName(), c.getTypeParameters().length);
|
||||||
}
|
}
|
||||||
return new JavaClassRegistry(allNames);
|
registry.addNames(allNames);
|
||||||
} else {
|
} else {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, ClassLoader classLoader) throws IOException, ClassNotFoundException {
|
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, JavaTXCompiler compiler) throws IOException, ClassNotFoundException {
|
||||||
|
ClassLoader classLoader = compiler.getClassLoader();
|
||||||
List<Class> ret = new ArrayList<>();
|
List<Class> ret = new ArrayList<>();
|
||||||
// Set classLoader to include default package for this specific source file
|
// Set classLoader to include default package for this specific source file
|
||||||
File dir = sourceFile.getParentFile();
|
File dir = sourceFile.getParentFile();
|
||||||
|
@ -12,6 +12,7 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.Record;
|
import de.dhbwstuttgart.syntaxtree.Record;
|
||||||
import org.antlr.v4.runtime.CommonToken;
|
import org.antlr.v4.runtime.CommonToken;
|
||||||
@ -130,7 +131,7 @@ public class SyntaxTreeGenerator {
|
|||||||
return ctx.getText();
|
return ctx.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) throws ClassNotFoundException, NotImplementedException {
|
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, JavaTXCompiler compiler) throws ClassNotFoundException, NotImplementedException {
|
||||||
SrcfileContext srcfile;
|
SrcfileContext srcfile;
|
||||||
List<ClassOrInterface> classes = new ArrayList<>();
|
List<ClassOrInterface> classes = new ArrayList<>();
|
||||||
if (ctx instanceof Java17Parser.SrcfileContext) {
|
if (ctx instanceof Java17Parser.SrcfileContext) {
|
||||||
@ -140,7 +141,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
if (srcfile.packageDeclaration() != null)
|
if (srcfile.packageDeclaration() != null)
|
||||||
this.pkgName = convert(srcfile.packageDeclaration());
|
this.pkgName = convert(srcfile.packageDeclaration());
|
||||||
Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, classLoader);
|
Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, compiler);
|
||||||
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
|
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
|
||||||
for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) {
|
for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) {
|
||||||
ClassorinterfacedeclContext clsoif;
|
ClassorinterfacedeclContext clsoif;
|
||||||
|
@ -5,6 +5,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.environment.PackageCrawler;
|
import de.dhbwstuttgart.environment.PackageCrawler;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
@ -25,19 +27,19 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.SubclassorinterfaceContext;
|
|||||||
|
|
||||||
public class GatherNames {
|
public class GatherNames {
|
||||||
|
|
||||||
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||||
Map<String, Integer> ret = new HashMap<>();
|
Map<String, Integer> ret = new HashMap<>();
|
||||||
for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
|
for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
|
||||||
if (clsoifctx instanceof NoclassorinterfaceContext) {
|
if (clsoifctx instanceof NoclassorinterfaceContext) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, classLoader));
|
ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, compiler));
|
||||||
}
|
}
|
||||||
ret.putAll(getImports(ctx, packages, classLoader));
|
ret.putAll(getImports(ctx, packages, compiler));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||||
Map<String, Integer> ret = new HashMap<>();
|
Map<String, Integer> ret = new HashMap<>();
|
||||||
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx;
|
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx;
|
||||||
String nameString = "";
|
String nameString = "";
|
||||||
@ -56,7 +58,7 @@ public class GatherNames {
|
|||||||
}
|
}
|
||||||
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||||
ret.put(nameString, numGenerics);
|
ret.put(nameString, numGenerics);
|
||||||
ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, classLoader));
|
ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, compiler));
|
||||||
break;
|
break;
|
||||||
case "EnumDeclarationContext":
|
case "EnumDeclarationContext":
|
||||||
if (!pkgName.isEmpty()) {
|
if (!pkgName.isEmpty()) {
|
||||||
@ -71,7 +73,7 @@ public class GatherNames {
|
|||||||
for (EnumConstantContext enumConstant : enumConstants.enumConstant()) {
|
for (EnumConstantContext enumConstant : enumConstants.enumConstant()) {
|
||||||
ClassBodyContext enumConstClassBody = enumConstant.classBody();
|
ClassBodyContext enumConstClassBody = enumConstant.classBody();
|
||||||
if (!Objects.isNull(enumConstClassBody)) {
|
if (!Objects.isNull(enumConstClassBody)) {
|
||||||
ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, classLoader));
|
ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, compiler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,7 +88,7 @@ public class GatherNames {
|
|||||||
ret.put(nameString, numGenerics);
|
ret.put(nameString, numGenerics);
|
||||||
for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) {
|
for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) {
|
||||||
if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) {
|
if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) {
|
||||||
ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, classLoader));
|
ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, compiler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -101,7 +103,7 @@ public class GatherNames {
|
|||||||
for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) {
|
for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) {
|
||||||
ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface();
|
ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface();
|
||||||
if (!Objects.isNull(anClsoifctx)) {
|
if (!Objects.isNull(anClsoifctx)) {
|
||||||
ret.putAll(getNames(anClsoifctx, pkgName, packages, classLoader));
|
ret.putAll(getNames(anClsoifctx, pkgName, packages, compiler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -113,7 +115,7 @@ public class GatherNames {
|
|||||||
}
|
}
|
||||||
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0;
|
||||||
ret.put(nameString, numGenerics);
|
ret.put(nameString, numGenerics);
|
||||||
ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, classLoader));
|
ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, compiler));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@ -121,24 +123,31 @@ public class GatherNames {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Map<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||||
Map<String, Integer> ret = new HashMap<>();
|
Map<String, Integer> ret = new HashMap<>();
|
||||||
for (ClassBodyDeclarationContext clsbody : clsBodyDecl) {
|
for (ClassBodyDeclarationContext clsbody : clsBodyDecl) {
|
||||||
if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) {
|
if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) {
|
||||||
ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, classLoader));
|
ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, compiler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
|
public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, JavaTXCompiler compiler) throws ClassNotFoundException {
|
||||||
Map<String, Integer> ret = new HashMap<>();
|
Map<String, Integer> ret = new HashMap<>();
|
||||||
// ret.putAll(packages.getClassNames("java.lang"));
|
// ret.putAll(packages.getClassNames("java.lang"));
|
||||||
for (Java17Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()) {
|
for (Java17Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()) {
|
||||||
if (importDeclCtx.MUL() == null) {
|
if (importDeclCtx.MUL() == null) {
|
||||||
Class<?> cl = classLoader.loadClass(importDeclCtx.qualifiedName().getText());
|
var name = importDeclCtx.qualifiedName().getText();
|
||||||
|
var className = new JavaClassName(name);
|
||||||
|
if (compiler.loadJavaTXClass(className)) {
|
||||||
|
ret.put(name, compiler.classRegistry.getNumberOfGenerics(name));
|
||||||
|
} else {
|
||||||
|
Class<?> cl = compiler.getClassLoader().loadClass(name);
|
||||||
ret.put(cl.getName(), cl.getTypeParameters().length);
|
ret.put(cl.getName(), cl.getTypeParameters().length);
|
||||||
|
}
|
||||||
} else if (importDeclCtx.MUL() != null) {
|
} else if (importDeclCtx.MUL() != null) {
|
||||||
|
// TODO Find stuff in user defined packages
|
||||||
ret.putAll(packages.getClassNames(importDeclCtx.qualifiedName().getText()));
|
ret.putAll(packages.getClassNames(importDeclCtx.qualifiedName().getText()));
|
||||||
}
|
}
|
||||||
// Die Unterscheidungen für 'static imports' wurden herausgenommen, da sie den
|
// Die Unterscheidungen für 'static imports' wurden herausgenommen, da sie den
|
||||||
|
@ -12,6 +12,10 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class JavaClassName {
|
public class JavaClassName {
|
||||||
|
|
||||||
|
// FIXME It's very much possible to have imports to inner classes
|
||||||
|
// In that case a.package.Foo.Bar, a.package is the Package and Foo.Bar the class name
|
||||||
|
// Its impossible to decide what's the package based solely on the name of the class
|
||||||
|
|
||||||
public static final JavaClassName Void = new JavaClassName("void");
|
public static final JavaClassName Void = new JavaClassName("void");
|
||||||
private String name;
|
private String name;
|
||||||
private PackageName packageName;
|
private PackageName packageName;
|
||||||
|
@ -11,9 +11,19 @@ public class JavaClassRegistry {
|
|||||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||||
|
|
||||||
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
public JavaClassRegistry(Map<String, Integer> initialNames) {
|
||||||
for (String name : initialNames.keySet()) {
|
addNames(initialNames);
|
||||||
existingClasses.put(new JavaClassName(name), initialNames.get(name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JavaClassRegistry() {}
|
||||||
|
|
||||||
|
public void addNames(Map<String, Integer> names) {
|
||||||
|
for (String name : names.keySet()) {
|
||||||
|
existingClasses.put(new JavaClassName(name), names.get(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addName(String className, int numberOfGenerics) {
|
||||||
|
existingClasses.put(new JavaClassName(className), numberOfGenerics);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaClassName getName(String className) {
|
public JavaClassName getName(String className) {
|
||||||
|
@ -145,8 +145,8 @@ public class ASTToTargetAST {
|
|||||||
var methods = groupOverloads(input.getMethods()).stream().map(this::convert).flatMap(List::stream).toList();
|
var methods = groupOverloads(input.getMethods()).stream().map(this::convert).flatMap(List::stream).toList();
|
||||||
|
|
||||||
if (input instanceof Record)
|
if (input instanceof Record)
|
||||||
return new TargetRecord(input.getModifiers(), input.getClassName().toString(), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
||||||
else return new TargetClass(input.getModifiers(), input.getClassName().toString(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
private List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
package de.dhbwstuttgart.target.tree;
|
package de.dhbwstuttgart.target.tree;
|
||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetClass(int modifiers, String qualifiedName, TargetType superType, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces,
|
public record TargetClass(int modifiers, JavaClassName qualifiedName, TargetType superType, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces,
|
||||||
List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
||||||
|
|
||||||
public TargetClass(int modifiers, String qualifiedName) {
|
public TargetClass(int modifiers, JavaClassName qualifiedName) {
|
||||||
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
public TargetClass(int modifiers, String qualifiedName, List<TargetType> implementingInterfaces) {
|
public TargetClass(int modifiers, JavaClassName qualifiedName, List<TargetType> implementingInterfaces) {
|
||||||
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), implementingInterfaces, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), implementingInterfaces, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package de.dhbwstuttgart.target.tree;
|
package de.dhbwstuttgart.target.tree;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetRecord(int modifiers, String qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces, List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
public record TargetRecord(int modifiers, JavaClassName qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces, List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
||||||
|
|
||||||
public static final TargetType RECORD = new TargetRefType("java.lang.Record");
|
public static final TargetType RECORD = new TargetRefType("java.lang.Record");
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.tree;
|
package de.dhbwstuttgart.target.tree;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
import de.dhbwstuttgart.target.tree.expression.TargetBlock;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
public interface TargetStructure {
|
public interface TargetStructure {
|
||||||
int modifiers();
|
int modifiers();
|
||||||
String qualifiedName();
|
JavaClassName qualifiedName();
|
||||||
TargetType superType();
|
TargetType superType();
|
||||||
Set<TargetGeneric> generics();
|
Set<TargetGeneric> generics();
|
||||||
Set<TargetGeneric> txGenerics();
|
Set<TargetGeneric> txGenerics();
|
||||||
@ -18,7 +19,7 @@ public interface TargetStructure {
|
|||||||
List<TargetMethod> methods();
|
List<TargetMethod> methods();
|
||||||
|
|
||||||
default String getName() {
|
default String getName() {
|
||||||
return qualifiedName().replaceAll("\\.", "/");
|
return qualifiedName().toString().replaceAll("\\.", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
// These methods are only meant to be used for test cases, a Class record should be immutable!
|
// These methods are only meant to be used for test cases, a Class record should be immutable!
|
||||||
|
36
src/test/java/TestPackages.java
Normal file
36
src/test/java/TestPackages.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TestPackages {
|
||||||
|
|
||||||
|
private static final String bytecodeDirectory = System.getProperty("user.dir") + "/src/test/resources/testBytecode/generatedBC/";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackages() throws Exception {
|
||||||
|
var cmp = new JavaTXCompiler(
|
||||||
|
List.of(
|
||||||
|
new File("resources/packageTest/pkg/sub/Test1.jav") // This should pull in Test2
|
||||||
|
//new File("resources/packageTest/pkg/sub2/Test2.jav")
|
||||||
|
),
|
||||||
|
List.of(new File("resources/packageTest"))
|
||||||
|
);
|
||||||
|
|
||||||
|
cmp.generateBytecode(bytecodeDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPackagesCircular() throws Exception {
|
||||||
|
var cmp = new JavaTXCompiler(
|
||||||
|
List.of(
|
||||||
|
new File("resources/packageTest/pkg/sub/Cycle1.jav")
|
||||||
|
//new File("resources/packageTest/pkg/sub2/Cycle2.jav")
|
||||||
|
),
|
||||||
|
List.of(new File("resources/packageTest"))
|
||||||
|
);
|
||||||
|
|
||||||
|
cmp.generateBytecode(bytecodeDirectory);
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import de.dhbwstuttgart.core.JavaTXCompiler;
|
|||||||
import de.dhbwstuttgart.bytecode.Codegen;
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||||
import de.dhbwstuttgart.target.tree.TargetClass;
|
import de.dhbwstuttgart.target.tree.TargetClass;
|
||||||
@ -68,14 +69,14 @@ public class TestCodegen {
|
|||||||
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader) throws IOException, ClassNotFoundException {
|
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader) throws IOException, ClassNotFoundException {
|
||||||
Codegen codegen = new Codegen(clazz, new JavaTXCompiler(List.of()));
|
Codegen codegen = new Codegen(clazz, new JavaTXCompiler(List.of()));
|
||||||
var code = codegen.generate();
|
var code = codegen.generate();
|
||||||
writeClassFile(clazz.qualifiedName(), code);
|
writeClassFile(clazz.qualifiedName().getClassName(), code);
|
||||||
return classLoader.loadClass(code);
|
return classLoader.loadClass(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, JavaTXCompiler compiler) throws IOException {
|
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, JavaTXCompiler compiler) throws IOException {
|
||||||
Codegen codegen = new Codegen(clazz, compiler);
|
Codegen codegen = new Codegen(clazz, compiler);
|
||||||
var code = codegen.generate();
|
var code = codegen.generate();
|
||||||
writeClassFile(clazz.qualifiedName(), code);
|
writeClassFile(clazz.qualifiedName().getClassName(), code);
|
||||||
return classLoader.loadClass(code);
|
return classLoader.loadClass(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,14 +106,14 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyClass() throws Exception {
|
public void testEmptyClass() throws Exception {
|
||||||
var clazz = new TargetClass(Opcodes.ACC_PUBLIC, "Empty");
|
var clazz = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("Empty"));
|
||||||
clazz.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", List.of(), null, new TargetBlock(List.of()));
|
clazz.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", List.of(), null, new TargetBlock(List.of()));
|
||||||
generateClass(clazz, new ByteArrayClassLoader()).getDeclaredMethod("main").invoke(null);
|
generateClass(clazz, new ByteArrayClassLoader()).getDeclaredMethod("main").invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArithmetic() throws Exception {
|
public void testArithmetic() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Arithmetic");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("Arithmetic"));
|
||||||
|
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "sub", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Sub(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "sub", List.of(new MethodParameter(TargetType.Integer, "a"), new MethodParameter(TargetType.Integer, "b")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Sub(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"), new TargetLocalVar(TargetType.Integer, "b"))))));
|
||||||
@ -130,7 +131,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnary() throws Exception {
|
public void testUnary() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Unary");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("Unary"));
|
||||||
|
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "not", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Not(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "not", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Not(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "neg", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Negate(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "neg", List.of(new MethodParameter(TargetType.Integer, "a")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetUnaryOp.Negate(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a"))))));
|
||||||
@ -145,7 +146,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConditional() throws Exception {
|
public void testConditional() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Conditional");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("Conditional"));
|
||||||
|
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "and", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.And(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "and", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.And(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "or", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Or(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "or", List.of(new MethodParameter(TargetType.Boolean, "a"), new MethodParameter(TargetType.Boolean, "b")), TargetType.Boolean, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Or(TargetType.Boolean, new TargetLocalVar(TargetType.Boolean, "a"), new TargetLocalVar(TargetType.Boolean, "b"))))));
|
||||||
@ -162,7 +163,7 @@ public class TestCodegen {
|
|||||||
// When adding two numbers and the return type is Long it needs to convert both values to Long
|
// When adding two numbers and the return type is Long it needs to convert both values to Long
|
||||||
@Test
|
@Test
|
||||||
public void testArithmeticConvert() throws Exception {
|
public void testArithmeticConvert() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "ArithmeticConvert");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("ArithmeticConvert"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(), TargetType.Long, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Add(TargetType.Long, new TargetLiteral.CharLiteral((char) 10), new TargetLiteral.LongLiteral((long) 20))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add", List.of(), TargetType.Long, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Add(TargetType.Long, new TargetLiteral.CharLiteral((char) 10), new TargetLiteral.LongLiteral((long) 20))))));
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("add").invoke(null), (long) 30);
|
assertEquals(clazz.getDeclaredMethod("add").invoke(null), (long) 30);
|
||||||
@ -170,7 +171,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMethodCall() throws Exception {
|
public void testMethodCall() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "HelloWorld");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("HelloWorld"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "helloWorld", List.of(), null, new TargetBlock(List.of(new TargetMethodCall(null, new TargetFieldVar(new TargetRefType("java.io.PrintStream"), new TargetRefType("java.lang.System"), true, new TargetClassName(new TargetRefType("java.lang.System")), "out"), List.of(new TargetLiteral.StringLiteral("Hello World!")), new TargetRefType("java.io.PrintStream"), "println", false, false))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "helloWorld", List.of(), null, new TargetBlock(List.of(new TargetMethodCall(null, new TargetFieldVar(new TargetRefType("java.io.PrintStream"), new TargetRefType("java.lang.System"), true, new TargetClassName(new TargetRefType("java.lang.System")), "out"), List.of(new TargetLiteral.StringLiteral("Hello World!")), new TargetRefType("java.io.PrintStream"), "println", false, false))));
|
||||||
|
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
@ -179,7 +180,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIfStatement() throws Exception {
|
public void testIfStatement() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "IfStmt");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("IfStmt"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "ifStmt", List.of(new MethodParameter(TargetType.Integer, "val")), TargetType.Integer, new TargetBlock(List.of(new TargetIf(new TargetBinaryOp.Equal(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(10)), new TargetReturn(new TargetLiteral.IntLiteral(1)), new TargetIf(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(5)), new TargetReturn(new TargetLiteral.IntLiteral(2)), new TargetReturn(new TargetLiteral.IntLiteral(3)))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "ifStmt", List.of(new MethodParameter(TargetType.Integer, "val")), TargetType.Integer, new TargetBlock(List.of(new TargetIf(new TargetBinaryOp.Equal(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(10)), new TargetReturn(new TargetLiteral.IntLiteral(1)), new TargetIf(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "val"), new TargetLiteral.IntLiteral(5)), new TargetReturn(new TargetLiteral.IntLiteral(2)), new TargetReturn(new TargetLiteral.IntLiteral(3)))))));
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
var ifStmt = clazz.getDeclaredMethod("ifStmt", Integer.class);
|
var ifStmt = clazz.getDeclaredMethod("ifStmt", Integer.class);
|
||||||
@ -190,7 +191,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFor() throws Exception {
|
public void testFor() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "For");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("For"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "forLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "sum", new TargetLiteral.IntLiteral(0)), new TargetFor(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1))), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "sum"), new TargetLocalVar(TargetType.Integer, "i")))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum")))));
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||||
@ -198,7 +199,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWhile() throws Exception {
|
public void testWhile() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "While");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("While"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "whileLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetWhile(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "i")))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "whileLoop", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(TargetType.Integer, "i", new TargetLiteral.IntLiteral(0)), new TargetWhile(new TargetBinaryOp.Less(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(10)), new TargetBlock(List.of(new TargetAssign(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetBinaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "i"), new TargetLiteral.IntLiteral(1)))))), new TargetReturn(new TargetLocalVar(TargetType.Integer, "i")))));
|
||||||
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("whileLoop").invoke(null), 10);
|
assertEquals(clazz.getDeclaredMethod("whileLoop").invoke(null), 10);
|
||||||
@ -206,7 +207,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClassicSwitch() throws Exception {
|
public void testClassicSwitch() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC , "SwitchClassic");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC , new JavaClassName("SwitchClassic"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchClassic", List.of(new MethodParameter(TargetType.Integer, "i")), TargetType.Integer, new TargetBlock(List.of(
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchClassic", List.of(new MethodParameter(TargetType.Integer, "i")), TargetType.Integer, new TargetBlock(List.of(
|
||||||
new TargetVarDecl(TargetType.Integer, "res", null),
|
new TargetVarDecl(TargetType.Integer, "res", null),
|
||||||
new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of(
|
new TargetSwitch(new TargetLocalVar(TargetType.Integer, "i"), List.of(
|
||||||
@ -234,7 +235,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTypeSwitch() throws Exception {
|
public void testTypeSwitch() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "SwitchEnhanced");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("SwitchEnhanced"));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of(
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "switchType", List.of(new MethodParameter(TargetType.Object, "obj")), TargetType.Integer, new TargetBlock(List.of(
|
||||||
new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of(
|
new TargetReturn(new TargetSwitch(new TargetLocalVar(TargetType.Object, "obj"), List.of(
|
||||||
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock(
|
new TargetSwitch.Case(List.of(new TargetTypePattern(TargetType.String, "aString")), new TargetBlock(
|
||||||
@ -267,7 +268,7 @@ public class TestCodegen {
|
|||||||
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
|
// var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
|
||||||
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer));
|
var interfaceType = TargetFunNType.fromParams(List.of(TargetType.Integer));
|
||||||
|
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "CGLambda");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, new JavaClassName("CGLambda"));
|
||||||
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of(new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false))));
|
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of(new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false))));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC, "lambda", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(interfaceType, "by2", new TargetLambdaExpression(interfaceType, List.of(), List.of(new MethodParameter(TargetType.Integer, "num")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Mul(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "num"), new TargetLiteral.IntLiteral(2))))))), new TargetReturn(new TargetCast(TargetType.Integer, new TargetMethodCall(TargetType.Object, TargetType.Object, List.of(TargetType.Object), new TargetLocalVar(interfaceType, "by2"), List.of(new TargetLiteral.IntLiteral(10)), interfaceType, "apply", false, true))))));
|
targetClass.addMethod(Opcodes.ACC_PUBLIC, "lambda", List.of(), TargetType.Integer, new TargetBlock(List.of(new TargetVarDecl(interfaceType, "by2", new TargetLambdaExpression(interfaceType, List.of(), List.of(new MethodParameter(TargetType.Integer, "num")), TargetType.Integer, new TargetBlock(List.of(new TargetReturn(new TargetBinaryOp.Mul(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "num"), new TargetLiteral.IntLiteral(2))))))), new TargetReturn(new TargetCast(TargetType.Integer, new TargetMethodCall(TargetType.Object, TargetType.Object, List.of(TargetType.Object), new TargetLocalVar(interfaceType, "by2"), List.of(new TargetLiteral.IntLiteral(10)), interfaceType, "apply", false, true))))));
|
||||||
var clazz = generateClass(targetClass, classLoader);
|
var clazz = generateClass(targetClass, classLoader);
|
||||||
|
Loading…
Reference in New Issue
Block a user