Compare commits
15 Commits
a314013f40
...
LSP-Interf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1007cce30 | ||
|
|
4cfc070289 | ||
|
|
2920dfe68f | ||
| acce38e8b1 | |||
| dbd7f4fcfe | |||
| 9114642370 | |||
| 8ac0f96bd6 | |||
|
|
c9d38728af | ||
|
|
b7fad6e3c7 | ||
|
|
3cb9b74df1 | ||
|
|
effc31782f | ||
|
|
2a24eab9d3 | ||
|
|
b29eb71238 | ||
|
|
e9ce071e2b | ||
| 3567bae0d7 |
4
pom.xml
4
pom.xml
@@ -73,8 +73,8 @@ http://maven.apache.org/maven-v4_0_0.xsd">
|
|||||||
<version>3.14.0</version>
|
<version>3.14.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<compilerArgs>--enable-preview</compilerArgs>
|
<compilerArgs>--enable-preview</compilerArgs>
|
||||||
<source>23</source>
|
<source>24</source>
|
||||||
<target>23</target>
|
<target>24</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import java.lang.Integer;
|
|||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
|
|
||||||
public class MatrixOP extends Vector<Vector<Integer>> {
|
public class MatrixOP extends Vector<Vector<Integer>> {
|
||||||
|
|
||||||
MatrixOP () {
|
MatrixOP () {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,8 +36,8 @@ public class MatrixOP extends Vector<Vector<Integer>> {
|
|||||||
v2.addElement(erg);
|
v2.addElement(erg);
|
||||||
j++; }
|
j++; }
|
||||||
ret.addElement(v2);
|
ret.addElement(v2);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -132,6 +132,7 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void boxPrimitive(State state, TargetType type) {
|
private void boxPrimitive(State state, TargetType type) {
|
||||||
|
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
|
if (type.equals(TargetType.Boolean) || type.equals(TargetType.boolean_)) {
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
@@ -153,6 +154,7 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void unboxPrimitive(State state, TargetType type) {
|
private void unboxPrimitive(State state, TargetType type) {
|
||||||
|
if (type instanceof TargetExtendsWildcard ew) type = ew.innerType();
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (type.equals(TargetType.Boolean)) {
|
if (type.equals(TargetType.Boolean)) {
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
||||||
@@ -228,6 +230,9 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void convertTo(State state, TargetType source, TargetType dest) {
|
private void convertTo(State state, TargetType source, TargetType dest) {
|
||||||
|
if (source instanceof TargetExtendsWildcard ew) source = ew.innerType();
|
||||||
|
if (dest instanceof TargetExtendsWildcard ew) dest = ew.innerType();
|
||||||
|
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (source.equals(dest))
|
if (source.equals(dest))
|
||||||
return;
|
return;
|
||||||
@@ -640,7 +645,7 @@ public class Codegen {
|
|||||||
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
||||||
generate(state, fieldVar.left());
|
generate(state, fieldVar.left());
|
||||||
mv.visitInsn(SWAP);
|
mv.visitInsn(SWAP);
|
||||||
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toSignature());
|
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getInternalName(), fieldVar.right(), fieldVar.type().toDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,7 +808,7 @@ public class Codegen {
|
|||||||
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
var handle = new Handle(state.isStatic ? H_INVOKESTATIC : H_INVOKEVIRTUAL, clazz.getName(), impl.name(), implSignature.getDescriptor(), false);
|
||||||
|
|
||||||
var params = new ArrayList<TargetType>();
|
var params = new ArrayList<TargetType>();
|
||||||
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().getClassName()));
|
if(!state.isStatic) params.add(new TargetRefType(clazz.qualifiedName().toString()));
|
||||||
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
params.addAll(lambda.captures().stream().map(mp -> mp.pattern().type()).toList());
|
||||||
|
|
||||||
if (!state.isStatic)
|
if (!state.isStatic)
|
||||||
@@ -942,7 +947,7 @@ public class Codegen {
|
|||||||
mv.visitInsn(DUP);
|
mv.visitInsn(DUP);
|
||||||
else
|
else
|
||||||
mv.visitInsn(DUP_X1);
|
mv.visitInsn(DUP_X1);
|
||||||
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toSignature());
|
mv.visitFieldInsn(dot.isStatic() ? PUTSTATIC : PUTFIELD, dot.owner().getInternalName(), dot.right(), fieldType.toDescriptor());
|
||||||
}
|
}
|
||||||
default -> throw new CodeGenException("Invalid assignment");
|
default -> throw new CodeGenException("Invalid assignment");
|
||||||
}
|
}
|
||||||
@@ -959,7 +964,7 @@ public class Codegen {
|
|||||||
case TargetFieldVar dot: {
|
case TargetFieldVar dot: {
|
||||||
if (!dot.isStatic())
|
if (!dot.isStatic())
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toSignature());
|
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getInternalName(), dot.right(), dot.type().toDescriptor());
|
||||||
unboxPrimitive(state, dot.type());
|
unboxPrimitive(state, dot.type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1423,7 +1428,7 @@ public class Codegen {
|
|||||||
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
throw new CodeGenException("Couldn't find suitable field accessor for '" + type.name() + "'");
|
||||||
var field = clazz.getFieldDecl().get(i);
|
var field = clazz.getFieldDecl().get(i);
|
||||||
var fieldType = converter.convert(field.getType());
|
var fieldType = converter.convert(field.getType());
|
||||||
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toSignature(), false);
|
state.mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), field.getName(), "()" + fieldType.toDescriptor(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
private void bindPattern(State state, TargetType type, TargetPattern pat, Label start, int index, int depth) {
|
||||||
@@ -1528,7 +1533,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.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
cw.visitField(access, field.name(), field.type().toDescriptor(), field.type().toSignature(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateStaticConstructor(TargetMethod constructor) {
|
private void generateStaticConstructor(TargetMethod constructor) {
|
||||||
@@ -1604,7 +1609,7 @@ public class Codegen {
|
|||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
mv.visitMethodInsn(INVOKESTATIC, "java/util/List", "of", "([Ljava/lang/Object;)Ljava/util/List;", true);
|
||||||
mv.visitMethodInsn(INVOKESTATIC, className, "main", "(Ljava/util/List;)V", false);
|
mv.visitMethodInsn(INVOKESTATIC, new TargetRefType(clazz.qualifiedName().toString()).getInternalName(), "main", "(Ljava/util/List;)V", false);
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
@@ -1661,12 +1666,12 @@ public class Codegen {
|
|||||||
if (!generics.isEmpty()) {
|
if (!generics.isEmpty()) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
ret += generic.name() + ":" + generic.bound().toSignature();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
if (clazz.superType() != null)
|
if (clazz.superType() != null)
|
||||||
ret += clazz.superType().toDescriptor();
|
ret += clazz.superType().toSignature();
|
||||||
for (var intf : clazz.implementingInterfaces()) {
|
for (var intf : clazz.implementingInterfaces()) {
|
||||||
ret += intf.toSignature();
|
ret += intf.toSignature();
|
||||||
}
|
}
|
||||||
@@ -1778,7 +1783,7 @@ public class Codegen {
|
|||||||
|
|
||||||
cw2.visitEnd();
|
cw2.visitEnd();
|
||||||
var bytes = cw2.toByteArray();
|
var bytes = cw2.toByteArray();
|
||||||
converter.auxiliaries.put(className, bytes);
|
compiler.auxiliaries.put(className, bytes);
|
||||||
|
|
||||||
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
// TODO These class loading shenanigans happen in a few places, the tests load the classes individually.
|
||||||
// Instead we should just look at the folder.
|
// Instead we should just look at the folder.
|
||||||
@@ -1821,7 +1826,7 @@ public class Codegen {
|
|||||||
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
bootstrapArgs[1] = String.join(";", clazz.fields().stream().map(TargetField::name).toArray(String[]::new));
|
||||||
for (var i = 0; i < clazz.fields().size(); i++) {
|
for (var i = 0; i < clazz.fields().size(); i++) {
|
||||||
var field = clazz.fields().get(i);
|
var field = clazz.fields().get(i);
|
||||||
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toSignature(), false);
|
var fieldRef = new Handle(H_GETFIELD, clazz.getName(), field.name(), field.type().toDescriptor(), false);
|
||||||
bootstrapArgs[i + 2] = fieldRef;
|
bootstrapArgs[i + 2] = fieldRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class FunNGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String applySignature(TargetType a) { return a.toSignature(); }
|
private static String applySignature(TargetType a) { return a.toSignature(); }
|
||||||
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", applySignature(a)); }
|
private static String applyNameDescriptor(TargetType a){ return a instanceof TargetGenericType ? "LTPH;" : String.format("%s", a.toDescriptor()); }
|
||||||
|
|
||||||
public static String encodeType(TargetType type) {
|
public static String encodeType(TargetType type) {
|
||||||
if (type == null) return VOID;
|
if (type == null) return VOID;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package de.dhbwstuttgart.core;
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Codegen;
|
import de.dhbwstuttgart.bytecode.Codegen;
|
||||||
|
import de.dhbwstuttgart.bytecode.FunNGenerator;
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
import de.dhbwstuttgart.environment.DirectoryClassLoader;
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
import de.dhbwstuttgart.exceptions.DebugException;
|
||||||
@@ -74,6 +75,11 @@ public class JavaTXCompiler {
|
|||||||
public final List<File> classPath;
|
public final List<File> classPath;
|
||||||
private final File outputPath;
|
private final File outputPath;
|
||||||
|
|
||||||
|
public final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
||||||
|
public final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
||||||
|
|
||||||
|
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
||||||
|
|
||||||
public DirectoryClassLoader getClassLoader() {
|
public DirectoryClassLoader getClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
@@ -726,7 +732,7 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
generatedGenerics.put(sf, converter.javaGenerics());
|
generatedGenerics.put(sf, converter.javaGenerics());
|
||||||
converter.generateFunNTypes();
|
converter.generateFunNTypes();
|
||||||
converter.auxiliaries.forEach((name, source) -> {
|
auxiliaries.forEach((name, source) -> {
|
||||||
generatedClasses.put(new JavaClassName(name), source);
|
generatedClasses.put(new JavaClassName(name), source);
|
||||||
});
|
});
|
||||||
return generatedClasses;
|
return generatedClasses;
|
||||||
|
|||||||
@@ -49,27 +49,27 @@ public class LanguageServerInterface {
|
|||||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
||||||
*
|
*
|
||||||
* @param pathAsString the URI of the File. See Example.
|
* @param pathAsString the URI of the File. See Example.
|
||||||
* @throws IOException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws URISyntaxException
|
|
||||||
*/
|
*/
|
||||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString) throws IOException, ClassNotFoundException, URISyntaxException {
|
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String pathAsString){
|
||||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
||||||
|
try {
|
||||||
|
var uri = new URI(pathAsString);
|
||||||
|
var path = Path.of(uri);
|
||||||
|
var file = path.toFile();
|
||||||
|
Files.createDirectories(path.getParent().resolve("out"));
|
||||||
|
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile());
|
||||||
|
|
||||||
var uri = new URI(pathAsString);
|
var parsedSource = compiler.sourceFiles.get(file);
|
||||||
var path = Path.of(uri);
|
var tiResults = compiler.typeInference(file);
|
||||||
var file = path.toFile();
|
|
||||||
Files.createDirectories(path.getParent().resolve("out"));
|
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(path.getParent().toFile()), path.getParent().resolve("out").toFile());
|
|
||||||
|
|
||||||
var parsedSource = compiler.sourceFiles.get(file);
|
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
|
||||||
var tiResults = compiler.typeInference(file);
|
Files.createDirectories(path.getParent().resolve("out"));
|
||||||
|
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
|
||||||
|
|
||||||
Map<JavaClassName, byte[]> bytecode = compiler.generateBytecode(parsedSource, tiResults);
|
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
||||||
Files.createDirectories(path.getParent().resolve("out"));
|
}catch (Exception e){
|
||||||
compiler.writeClassFile(bytecode, path.getParent().resolve("out").toFile(), false);
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
return new LanguageServerTransferObject(tiResults, parsedSource, "", compiler.getGeneratedGenerics());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,138 +112,9 @@ public class LanguageServerInterface {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeClassFile(String name, byte[] code, Path outputPath) throws IOException {
|
|
||||||
Files.createDirectories(outputPath);
|
|
||||||
Files.write(outputPath.resolve(name + ".class"), code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, ? extends Class<?>> generateClassFiles(IByteArrayClassLoader classLoader, Path path, Path outputPath, String... files) throws IOException, ClassNotFoundException {
|
|
||||||
Files.createDirectories(outputPath);
|
|
||||||
var filenames = Arrays.stream(files).map(filename -> Path.of(path.toString(), filename).toFile()).toList();
|
|
||||||
var compiler = new JavaTXCompiler(filenames, List.of(path.toFile(), outputPath.toFile()), outputPath.toFile());
|
|
||||||
|
|
||||||
var result = new HashMap<String, Class<?>>();
|
|
||||||
for (var file : filenames) {
|
|
||||||
var resultSet = compiler.typeInference(file);
|
|
||||||
|
|
||||||
var sourceFile = compiler.sourceFiles.get(file);
|
|
||||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
|
||||||
|
|
||||||
result.putAll(classes.stream().map(cli -> {
|
|
||||||
try {
|
|
||||||
return generateClass(converter.convert(cli), classLoader, converter, outputPath);
|
|
||||||
} catch (IOException exception) {
|
|
||||||
throw new RuntimeException(exception);
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toMap(Class::getName, Function.identity())));
|
|
||||||
|
|
||||||
converter.generateFunNTypes();
|
|
||||||
|
|
||||||
for (var entry : converter.auxiliaries.entrySet()) {
|
|
||||||
writeClassFile(entry.getKey(), entry.getValue(), outputPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var entry : compiler.loadedClasses.entrySet()) {
|
|
||||||
var name = entry.getKey().toString();
|
|
||||||
result.put(name, classLoader.loadClass(Path.of(entry.getValue().classFile().toURI())));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Class<?> generateClass(TargetStructure clazz, IByteArrayClassLoader classLoader, ASTToTargetAST converter, Path outputPath) throws IOException {
|
|
||||||
Codegen codegen = new Codegen(clazz, converter.compiler, converter);
|
|
||||||
var code = codegen.generate();
|
|
||||||
writeClassFile(clazz.qualifiedName().getClassName(), code, outputPath);
|
|
||||||
return classLoader.loadClass(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, ? extends Class<?>> generateClassFiles(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
|
||||||
var file = Path.of(filePath, filename).toFile();
|
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
|
||||||
var resultSet = compiler.typeInference(file);
|
|
||||||
|
|
||||||
var sourceFile = compiler.sourceFiles.get(file);
|
|
||||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
|
||||||
|
|
||||||
var result = classes.stream().map(cli -> {
|
|
||||||
try {
|
|
||||||
return generateClass(converter.convert(cli), classLoader, converter, Path.of(filePath + "/out/"));
|
|
||||||
} catch (IOException exception) {
|
|
||||||
throw new RuntimeException(exception);
|
|
||||||
}
|
|
||||||
}).collect(Collectors.toMap(Class::getName, Function.identity()));
|
|
||||||
|
|
||||||
converter.generateFunNTypes();
|
|
||||||
|
|
||||||
for (var entry : converter.auxiliaries.entrySet()) {
|
|
||||||
writeClassFile(entry.getKey(), entry.getValue(), Path.of(filePath + "/out/"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
|
public static SourceFile getAST(String filename, String filePath) throws IOException, ClassNotFoundException {
|
||||||
var file = Path.of(filePath, filename).toFile();
|
var file = Path.of(filePath, filename).toFile();
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
||||||
return compiler.sourceFiles.get(file);
|
return compiler.sourceFiles.get(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LanguageServerTransferObject getLanguageServerTransferObject(String filename, IByteArrayClassLoader classLoader, String filePath) throws IOException, ClassNotFoundException {
|
|
||||||
var file = Path.of(filePath, filename).toFile();
|
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
|
||||||
var resultSet = compiler.typeInference(file);
|
|
||||||
|
|
||||||
var sourceFile = compiler.sourceFiles.get(file);
|
|
||||||
var converter = new ASTToTargetAST(compiler, resultSet, sourceFile, classLoader);
|
|
||||||
compiler.generateBytecode();
|
|
||||||
converter.generateFunNTypes();
|
|
||||||
|
|
||||||
var ta = converter.javaGenerics();
|
|
||||||
var tb = converter.txGenerics();
|
|
||||||
Map<SourceFile, List<GenericsResult>> generics = new HashMap<>();
|
|
||||||
|
|
||||||
ArrayList<GenericsResult> genericsResults = new ArrayList<>();
|
|
||||||
genericsResults.addAll(ta);
|
|
||||||
genericsResults.addAll(tb);
|
|
||||||
generics.put(converter.compiler.sourceFiles.values().stream().findFirst().get(), ta);
|
|
||||||
var test = new LanguageServerTransferObject(resultSet, converter.compiler.sourceFiles.values().stream().findFirst().get(), "", compiler.getGeneratedGenerics());
|
|
||||||
return test;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* generates Bytecode for the given Path of the File.
|
|
||||||
* The Generated Bytecode can be found in the same place as the path, except the File lies in an /out/ Directory
|
|
||||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
|
||||||
*
|
|
||||||
* @param uri the URI of the File. See Example.
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws URISyntaxException
|
|
||||||
*/
|
|
||||||
public void generateBytecode(URI uri) throws IOException, ClassNotFoundException, URISyntaxException {
|
|
||||||
|
|
||||||
// System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// File inputDir = new File(uri.getPath());
|
|
||||||
// File outFile = new File(uri.getPath() + "/out");
|
|
||||||
// FileUtils.cleanDirectory(outFile);
|
|
||||||
// String[] allowedEndings = {".jav"};
|
|
||||||
// ArrayList<File> files = new ArrayList<>();
|
|
||||||
//
|
|
||||||
// try (Stream<Path> stream = Files.walk(Paths.get(inputDir.toURI()))) {
|
|
||||||
// stream.filter(Files::isRegularFile)
|
|
||||||
// .forEach(el -> files.add(el.toFile()));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// List<String> javFiles = files.stream().filter(el -> el.getName().split("\\.").length >= 2 && el.getName().split("\\.")[el.getName().split("\\.").length - 1].contains("jav")).map(el -> el.getPath().replace(inputDir.getPath(), "").substring(1)).toList();
|
|
||||||
// //TODO: Link between Files
|
|
||||||
// generateClassFiles(new ByteArrayClassLoader(), Path.of(inputDir.toURI()), Path.of(outFile.toURI()), javFiles.toArray(new String[0]));
|
|
||||||
// System.setOut(System.out);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ public class StatementGenerator {
|
|||||||
} else {
|
} else {
|
||||||
type = methodparameters?
|
type = methodparameters?
|
||||||
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
TypePlaceholder.fresh(fp.getStart(), 1, false)
|
||||||
: TypePlaceholder.fresh(fp.getStart());
|
: TypePlaceholder.fresh(fp.getStart(), 1, false);
|
||||||
}
|
}
|
||||||
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
ret.add(new FormalParameter(paramName, type, fp.getStart()));
|
||||||
localVars.put(paramName, type);
|
localVars.put(paramName, type);
|
||||||
@@ -1065,7 +1065,7 @@ public class StatementGenerator {
|
|||||||
List<Pattern> parameterList = new ArrayList<>();
|
List<Pattern> parameterList = new ArrayList<>();
|
||||||
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
for (IdentifierContext identifier : lambdaParams.identifier()) {
|
||||||
Token offset = identifier.getStart();
|
Token offset = identifier.getStart();
|
||||||
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
|
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
||||||
}
|
}
|
||||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||||
} else if (lambdaParams.formalParameterList() != null) {
|
} else if (lambdaParams.formalParameterList() != null) {
|
||||||
@@ -1075,7 +1075,7 @@ public class StatementGenerator {
|
|||||||
List<Pattern> parameterList = new ArrayList<>();
|
List<Pattern> parameterList = new ArrayList<>();
|
||||||
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
|
||||||
Token offset = param.getStart();
|
Token offset = param.getStart();
|
||||||
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
|
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset, 1, false), offset));
|
||||||
}
|
}
|
||||||
params = new ParameterList(parameterList, lambdaParams.getStart());
|
params = new ParameterList(parameterList, lambdaParams.getStart());
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.target.tree.TargetGeneric;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
|
||||||
@@ -31,6 +33,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
private List<RefType> implementedInterfaces;
|
private List<RefType> implementedInterfaces;
|
||||||
private List<RefType> permittedSubtypes;
|
private List<RefType> permittedSubtypes;
|
||||||
private List<Constructor> constructors;
|
private List<Constructor> constructors;
|
||||||
|
private Set<GenericTypeVar> userDefinedGenerics;
|
||||||
|
|
||||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
|
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, Boolean isFunctionalInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset, String fileName) {
|
||||||
super(offset);
|
super(offset);
|
||||||
@@ -199,4 +202,22 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(name);
|
return Objects.hash(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<GenericTypeVar> getUserDefinedGenerics() {
|
||||||
|
if (this.userDefinedGenerics != null) return this.userDefinedGenerics;
|
||||||
|
|
||||||
|
var genericsIter = getGenerics().iterator();
|
||||||
|
if (genericsIter.hasNext()) {
|
||||||
|
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
||||||
|
this.userDefinedGenerics = new HashSet<>();
|
||||||
|
while (genericsIter.hasNext()) {
|
||||||
|
var next = genericsIter.next();
|
||||||
|
userDefinedGenerics.add(next);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.userDefinedGenerics = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.userDefinedGenerics;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import java.util.*;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
//import sun.security.x509.X509CertInfo;
|
//import sun.security.x509.X509CertInfo;
|
||||||
|
|
||||||
public class SourceFile extends SyntaxTreeNode {
|
public class SourceFile extends SyntaxTreeNode {
|
||||||
@@ -18,6 +20,7 @@ public class SourceFile extends SyntaxTreeNode {
|
|||||||
private boolean isGenerated;
|
private boolean isGenerated;
|
||||||
|
|
||||||
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
public List<ClassOrInterface> availableClasses = new ArrayList<>();
|
||||||
|
public List<ASTToTargetAST.Generics> generics = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
|
||||||
@@ -40,6 +43,10 @@ public class SourceFile extends SyntaxTreeNode {
|
|||||||
this.imports = new HashSet<>(sf.imports);
|
this.imports = new HashSet<>(sf.imports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addResultSet(ResultSet rs) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void setPackageName(String packageName) {
|
public void setPackageName(String packageName) {
|
||||||
this.pkgName = packageName;
|
this.pkgName = packageName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class ASTToTargetAST {
|
|||||||
public Generics generics;
|
public Generics generics;
|
||||||
public List<Generics> currentMethodOverloads;
|
public List<Generics> currentMethodOverloads;
|
||||||
|
|
||||||
final Map<ClassOrInterface, Set<GenericTypeVar>> userDefinedGenerics = new HashMap<>();
|
|
||||||
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
final Map<Method, Set<SignaturePair>> tphsInMethods = new HashMap<>();
|
||||||
private Method currentMethod;
|
private Method currentMethod;
|
||||||
|
|
||||||
@@ -62,9 +61,11 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
public record Generics(JavaGenerics javaGenerics, TxGenerics txGenerics) {
|
||||||
|
public Generics(JavaTXCompiler compiler, ResultSet set) {
|
||||||
|
this(new JavaGenerics(compiler, set), new TxGenerics(compiler, set));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IByteArrayClassLoader classLoader;
|
public IByteArrayClassLoader classLoader;
|
||||||
protected SourceFile sourceFile;
|
protected SourceFile sourceFile;
|
||||||
|
|
||||||
@@ -82,9 +83,9 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
all = new ArrayList<>();
|
all = new ArrayList<>();
|
||||||
for (var set : resultSets) {
|
for (var set : resultSets) {
|
||||||
all.add(new Generics(new JavaGenerics(this, set), new TxGenerics(this, set)));
|
all.add(new Generics(compiler, set));
|
||||||
}
|
}
|
||||||
this.generics = all.get(0);
|
this.generics = all.getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
public void addSignaturePair(TypePlaceholder signature, RefTypeOrTPHOrWildcardOrGeneric parameter) {
|
||||||
@@ -94,9 +95,13 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList) {
|
||||||
|
return findMethod(owner, name, argumentList, this.generics.javaGenerics, this.compiler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Method> findMethod(ClassOrInterface owner, String name, List<TargetType> argumentList, GenerateGenerics generics, JavaTXCompiler compiler) {
|
||||||
Optional<Method> method = Optional.empty();
|
Optional<Method> method = Optional.empty();
|
||||||
while (method.isEmpty()) {
|
while (method.isEmpty()) {
|
||||||
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
|
method = owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList, generics)).findFirst();
|
||||||
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
if (owner.getClassName().toString().equals("java.lang.Object")) break;
|
||||||
owner = compiler.getClass(owner.getSuperClass().getName());
|
owner = compiler.getClass(owner.getSuperClass().getName());
|
||||||
}
|
}
|
||||||
@@ -104,16 +109,16 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
Optional<Constructor> findConstructor(ClassOrInterface owner, List<TargetType> argumentList) {
|
||||||
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList)).findFirst();
|
return owner.getConstructors().stream().filter(c -> parameterEquals(c.getParameterList(), argumentList, generics.javaGenerics)).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments) {
|
static boolean parameterEquals(ParameterList parameterList, List<TargetType> arguments, GenerateGenerics generics) {
|
||||||
var pars = parameterList.getFormalparalist();
|
var pars = parameterList.getFormalparalist();
|
||||||
if (pars.size() != arguments.size())
|
if (pars.size() != arguments.size())
|
||||||
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 = generics.getTargetType(pars.get(i).getType());
|
||||||
var type2 = arguments.get(i);
|
var type2 = arguments.get(i);
|
||||||
if (type1 instanceof TargetGenericType)
|
if (type1 instanceof TargetGenericType)
|
||||||
return true;
|
return true;
|
||||||
@@ -351,19 +356,14 @@ public class ASTToTargetAST {
|
|||||||
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
Set<TargetGeneric> javaGenerics = new HashSet<>();
|
||||||
Set<TargetGeneric> txGenerics = new HashSet<>();
|
Set<TargetGeneric> txGenerics = new HashSet<>();
|
||||||
|
|
||||||
var genericsIter = input.getGenerics().iterator();
|
var userDefinedGenerics = input.getUserDefinedGenerics();
|
||||||
if (genericsIter.hasNext()) {
|
if (!userDefinedGenerics.isEmpty()) {
|
||||||
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
// Add empty set of generics to cache so that it doesn't try to calculate it later
|
||||||
var userDefinedGenerics = new HashSet<GenericTypeVar>();
|
for (var generic : userDefinedGenerics) {
|
||||||
this.userDefinedGenerics.put(input, userDefinedGenerics);
|
// TODO Support multiple bouds
|
||||||
while (genericsIter.hasNext()) {
|
javaGenerics.add(new TargetGeneric(generic.getName(), convert(generic.getBounds().getFirst())));
|
||||||
var next = genericsIter.next();
|
|
||||||
userDefinedGenerics.add(next);
|
|
||||||
// TODO Support multiple bounds
|
|
||||||
javaGenerics.add(new TargetGeneric(next.getName(), convert(next.getBounds().get(0))));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.userDefinedGenerics.put(input, new HashSet<>());
|
|
||||||
// Generate generics only if there are no user defined ones
|
// Generate generics only if there are no user defined ones
|
||||||
javaGenerics = convert(generics.javaGenerics.generics(input), generics.javaGenerics);
|
javaGenerics = convert(generics.javaGenerics.generics(input), generics.javaGenerics);
|
||||||
txGenerics = convert(generics.txGenerics.generics(input), generics.txGenerics);
|
txGenerics = convert(generics.txGenerics.generics(input), generics.txGenerics);
|
||||||
@@ -425,7 +425,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
private List<TargetConstructor> convert(ClassOrInterface currentClass, Constructor input, TargetBlock fieldInitializer) {
|
||||||
generics = all.get(0);
|
generics = all.getFirst();
|
||||||
List<TargetConstructor> result = new ArrayList<>();
|
List<TargetConstructor> result = new ArrayList<>();
|
||||||
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
Set<List<MethodParameter>> parameterSet = new HashSet<>();
|
||||||
this.currentMethod = input;
|
this.currentMethod = input;
|
||||||
@@ -469,13 +469,6 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TargetType unwrap(TargetType type) {
|
|
||||||
if (type instanceof TargetRefType ref) {
|
|
||||||
if (!ref.params().isEmpty()) return new TargetRefType(ref.name());
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||||
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||||
if (methods.size() == 1) {
|
if (methods.size() == 1) {
|
||||||
@@ -746,11 +739,6 @@ public class ASTToTargetAST {
|
|||||||
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
return new TargetField(input.modifier, convert(input.getType(), generics.javaGenerics), input.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, FunNGenerator.GenericParameters> usedFunN = new HashMap<>();
|
|
||||||
private final Set<Integer> usedFunNSuperTypes = new HashSet<>();
|
|
||||||
|
|
||||||
public Map<String, byte[]> auxiliaries = new HashMap<>();
|
|
||||||
|
|
||||||
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
||||||
return convert(input, generics.javaGenerics);
|
return convert(input, generics.javaGenerics);
|
||||||
}
|
}
|
||||||
@@ -819,20 +807,24 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void generateFunNTypes() {
|
public void generateFunNTypes() {
|
||||||
for (var entry : usedFunN.entrySet()) {
|
for (var entry : compiler.usedFunN.entrySet()) {
|
||||||
var gep = entry.getValue();
|
var gep = entry.getValue();
|
||||||
var superInterfaces = usedFunN.values().stream()
|
var superInterfaces = compiler.usedFunN.values().stream()
|
||||||
.filter(g -> !g.equals(gep))
|
.filter(g -> !g.equals(gep))
|
||||||
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
.filter(genericParameters -> isSubtype(gep, genericParameters))
|
||||||
.map(FunNGenerator::getSpecializedClassName)
|
.map(FunNGenerator::getSpecializedClassName)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
var code = FunNGenerator.generateSpecializedBytecode(gep, superInterfaces);
|
||||||
auxiliaries.put(entry.getKey(), code);
|
compiler.auxiliaries.put(entry.getKey(), code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
public TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics) {
|
||||||
|
return convert(input, generics, compiler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input, GenerateGenerics generics, JavaTXCompiler compiler) {
|
||||||
return input.acceptTV(new TypeVisitor<>() {
|
return input.acceptTV(new TypeVisitor<>() {
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(RefType refType) {
|
public TargetType visit(RefType refType) {
|
||||||
@@ -844,31 +836,31 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var params = refType.getParaList().stream().map(type -> {
|
var params = refType.getParaList().stream().map(type -> {
|
||||||
return convert(type, generics);
|
return convert(type, generics, compiler);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea
|
||||||
var returnType = FunNGenerator.getReturnType(params);
|
var returnType = FunNGenerator.getReturnType(params);
|
||||||
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
var className = FunNGenerator.getSpecializedClassName(FunNGenerator.getArguments(params), returnType);
|
||||||
if (!usedFunNSuperTypes.contains(params.size())) {
|
if (!compiler.usedFunNSuperTypes.contains(params.size())) {
|
||||||
usedFunNSuperTypes.add(params.size());
|
compiler.usedFunNSuperTypes.add(params.size());
|
||||||
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
var code = FunNGenerator.generateSuperBytecode(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
var superClassName = FunNGenerator.getSuperClassName(params.size() - 1, returnType != null ? 1 : 0);
|
||||||
try {
|
try {
|
||||||
classLoader.findClass(superClassName);
|
compiler.classLoader.findClass(superClassName);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
try {
|
try {
|
||||||
classLoader.loadClass(superClassName, code);
|
compiler.classLoader.loadClass(superClassName, code);
|
||||||
} catch (LinkageError ignored) {}
|
} catch (LinkageError ignored) {}
|
||||||
}
|
}
|
||||||
auxiliaries.put(superClassName, code);
|
compiler.auxiliaries.put(superClassName, code);
|
||||||
}
|
}
|
||||||
FunNGenerator.GenericParameters gep = null;
|
FunNGenerator.GenericParameters gep = null;
|
||||||
if (!usedFunN.containsKey(className)) {
|
if (!compiler.usedFunN.containsKey(className)) {
|
||||||
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
gep = new FunNGenerator.GenericParameters(params, returnType != null ? 1 : 0);
|
||||||
usedFunN.put(className, gep);
|
compiler.usedFunN.put(className, gep);
|
||||||
} else {
|
} else {
|
||||||
gep = usedFunN.get(className);
|
gep = compiler.usedFunN.get(className);
|
||||||
}
|
}
|
||||||
return flattenFunNType(params, gep);
|
return flattenFunNType(params, gep);
|
||||||
}
|
}
|
||||||
@@ -877,7 +869,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(SuperWildcardType superWildcardType) {
|
public TargetType visit(SuperWildcardType superWildcardType) {
|
||||||
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics));
|
return new TargetSuperWildcard(convert(superWildcardType.getInnerType(), generics, compiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -887,7 +879,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
public TargetType visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics));
|
return new TargetExtendsWildcard(convert(extendsWildcardType.getInnerType(), generics, compiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
@@ -18,7 +20,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public abstract class GenerateGenerics {
|
public abstract class GenerateGenerics {
|
||||||
|
|
||||||
private final ASTToTargetAST astToTargetAST;
|
private final JavaTXCompiler compiler;
|
||||||
|
|
||||||
public class TPH {
|
public class TPH {
|
||||||
private final TypePlaceholder wrap;
|
private final TypePlaceholder wrap;
|
||||||
@@ -134,8 +136,8 @@ public abstract class GenerateGenerics {
|
|||||||
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
Map<TPH, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
|
||||||
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
Map<TypePlaceholder, TypePlaceholder> equality = new HashMap<>();
|
||||||
|
|
||||||
GenerateGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
GenerateGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||||
this.astToTargetAST = astToTargetAST;
|
this.compiler = compiler;
|
||||||
for (var constraint : constraints.results) {
|
for (var constraint : constraints.results) {
|
||||||
if (constraint instanceof PairTPHsmallerTPH p) {
|
if (constraint instanceof PairTPHsmallerTPH p) {
|
||||||
System.out.println(p.left + " " + p.left.getVariance());
|
System.out.println(p.left + " " + p.left.getVariance());
|
||||||
@@ -281,7 +283,7 @@ public abstract class GenerateGenerics {
|
|||||||
Set<TPH> typeVariablesOfClass,
|
Set<TPH> typeVariablesOfClass,
|
||||||
Set<Pair> result
|
Set<Pair> result
|
||||||
) {
|
) {
|
||||||
var userDefinedGenericsOfClass = astToTargetAST.userDefinedGenerics.get(owner);
|
var userDefinedGenericsOfClass = owner.getUserDefinedGenerics();
|
||||||
|
|
||||||
// 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 +331,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(x -> getTargetType(x)).toList(), GenerateGenerics.this, compiler);
|
||||||
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());
|
||||||
@@ -1005,8 +1007,8 @@ public abstract class GenerateGenerics {
|
|||||||
}
|
}
|
||||||
var type = concreteTypes.get(new TPH(tph));
|
var type = concreteTypes.get(new TPH(tph));
|
||||||
if (type == null) return new TargetGenericType(tph.getName());
|
if (type == null) return new TargetGenericType(tph.getName());
|
||||||
return astToTargetAST.convert(type, this);
|
return ASTToTargetAST.convert(type, this, compiler);
|
||||||
}
|
}
|
||||||
return astToTargetAST.convert(in, this);
|
return ASTToTargetAST.convert(in, this, compiler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,8 +69,4 @@ public class GenericsResult {
|
|||||||
return this.generics.getType(tph);
|
return this.generics.getType(tph);
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetType resolveTarget(RefTypeOrTPHOrWildcardOrGeneric type) {
|
|
||||||
return this.generics.getTargetType(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@@ -7,8 +8,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
final class JavaGenerics extends GenerateGenerics {
|
final class JavaGenerics extends GenerateGenerics {
|
||||||
JavaGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
JavaGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||||
super(astToTargetAST, constraints);
|
super(compiler, constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@@ -7,8 +8,8 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
final class TxGenerics extends GenerateGenerics {
|
final class TxGenerics extends GenerateGenerics {
|
||||||
TxGenerics(ASTToTargetAST astToTargetAST, ResultSet constraints) {
|
TxGenerics(JavaTXCompiler compiler, ResultSet constraints) {
|
||||||
super(astToTargetAST, constraints);
|
super(compiler, constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -36,30 +36,30 @@ public record TargetMethod(int access, String name, TargetBlock block, Signature
|
|||||||
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
public static String getDescriptor(TargetType returnType, TargetType... parameters) {
|
||||||
String ret = "(";
|
String ret = "(";
|
||||||
for (var parameterType : parameters) {
|
for (var parameterType : parameters) {
|
||||||
ret += parameterType.toSignature();
|
ret += parameterType.toDescriptor();
|
||||||
}
|
}
|
||||||
ret += ")";
|
ret += ")";
|
||||||
if (returnType == null) ret += "V";
|
if (returnType == null) ret += "V";
|
||||||
else ret += returnType.toSignature();
|
else ret += returnType.toDescriptor();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
public static String getSignature(Set<TargetGeneric> generics, List<MethodParameter> parameters, TargetType returnType) {
|
||||||
String ret = "";
|
String ret = "";
|
||||||
if (generics.size() > 0) {
|
if (!generics.isEmpty()) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var generic : generics) {
|
for (var generic : generics) {
|
||||||
ret += generic.name() + ":" + generic.bound().toDescriptor();
|
ret += generic.name() + ":" + generic.bound().toSignature();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
ret += "(";
|
ret += "(";
|
||||||
for (var param : parameters) {
|
for (var param : parameters) {
|
||||||
ret += param.pattern().type().toDescriptor();
|
ret += param.pattern().type().toSignature();
|
||||||
}
|
}
|
||||||
ret += ")";
|
ret += ")";
|
||||||
if (returnType == null) ret += "V";
|
if (returnType == null) ret += "V";
|
||||||
else ret += returnType.toDescriptor();
|
else ret += returnType.toSignature();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return innerType.toSignature();
|
return "+" + innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toDescriptor() {
|
||||||
return "+" + innerType.toDescriptor();
|
return innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -33,9 +33,4 @@ public record TargetFunNType(String name, List<TargetType> funNParams, List<Targ
|
|||||||
public String getInternalName() {
|
public String getInternalName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toSignature() {
|
|
||||||
return "L" + getInternalName() + ";";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
|
|
||||||
public record TargetGenericType(String name) implements TargetType {
|
public record TargetGenericType(String name) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toDescriptor() {
|
||||||
return "Ljava/lang/Object;"; // TODO Use bounds for this?
|
return "Ljava/lang/Object;"; // TODO Use bounds for this?
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toSignature() {
|
||||||
return "T" + getInternalName() + ";";
|
return "T" + getInternalName() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
|
|||||||
return this.name.replaceAll("\\.", "/");
|
return this.name.replaceAll("\\.", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toSignature() {
|
|
||||||
return "L" + getInternalName() + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type erasure means we need to override hashCode and equals to only consider the name
|
// Type erasure means we need to override hashCode and equals to only consider the name
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
|||||||
@@ -6,16 +6,21 @@ public sealed interface TargetSpecializedType extends TargetType permits TargetF
|
|||||||
List<TargetType> params();
|
List<TargetType> params();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default String toDescriptor() {
|
default String toSignature() {
|
||||||
String ret = "L" + getInternalName();
|
String ret = "L" + getInternalName();
|
||||||
if (params().size() > 0) {
|
if (!params().isEmpty()) {
|
||||||
ret += "<";
|
ret += "<";
|
||||||
for (var param : params()) {
|
for (var param : params()) {
|
||||||
ret += param.toDescriptor();
|
ret += param.toSignature();
|
||||||
}
|
}
|
||||||
ret += ">";
|
ret += ">";
|
||||||
}
|
}
|
||||||
ret += ";";
|
ret += ";";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default String toDescriptor() {
|
||||||
|
return "L" + getInternalName() + ";";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return innerType.toSignature();
|
return "-" + innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toDescriptor() {
|
public String toDescriptor() {
|
||||||
return "-" + innerType.toDescriptor();
|
return innerType.toDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
package languageServerInterfaceTest;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
|
||||||
import de.dhbwstuttgart.languageServerInterface.LanguageServerInterface;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
public class LangaugeServerInterfaceTest {
|
|
||||||
@Test
|
|
||||||
@Ignore
|
|
||||||
public void consoleInterfaceTest() throws IOException, ClassNotFoundException, URISyntaxException {
|
|
||||||
|
|
||||||
|
|
||||||
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
|
||||||
var resp = languageServerInterface.getResultSetAndAbstractSyntax("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav");
|
|
||||||
|
|
||||||
System.out.println("\n-----------------------------------------\n");
|
|
||||||
System.out.println(ASTPrinter.print(resp.getAst()));
|
|
||||||
System.out.println("\n-----------------------------------------\n");
|
|
||||||
|
|
||||||
LanguageServerInterface languageServerInterface2 = new LanguageServerInterface();
|
|
||||||
var ast = languageServerInterface2.getAst("/home/ruben/code/JavaCompilerCore/src/test/java/languageServerInterfaceTest/test.jav", "N");
|
|
||||||
|
|
||||||
System.out.println("\n-----------------------------------------\n");
|
|
||||||
System.out.println(ASTPrinter.print(ast));
|
|
||||||
System.out.println("\n-----------------------------------------\n");
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore
|
|
||||||
public void testBytecodeGen() throws IOException, ClassNotFoundException, URISyntaxException {
|
|
||||||
|
|
||||||
//TODO: Ordner und Datei löschen wenn sie bereits existieren
|
|
||||||
LanguageServerInterface languageServerInterface = new LanguageServerInterface();
|
|
||||||
languageServerInterface.generateBytecode(new URI("c%3A/Users/ruben/Neuer%20Ordner%20%282%29/LSP-Vortrag/images/"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -66,7 +66,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
converter.generateFunNTypes();
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
for (var entry : converter.auxiliaries.entrySet()) {
|
for (var entry : compiler.auxiliaries.entrySet()) {
|
||||||
writeClassFile(entry.getKey(), entry.getValue());
|
writeClassFile(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ public class TestCodegen {
|
|||||||
|
|
||||||
converter.generateFunNTypes();
|
converter.generateFunNTypes();
|
||||||
|
|
||||||
for (var entry : converter.auxiliaries.entrySet()) {
|
for (var entry : compiler.auxiliaries.entrySet()) {
|
||||||
writeClassFile(entry.getKey(), entry.getValue());
|
writeClassFile(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user