Compare commits
1 Commits
LSP-Interf
...
patternMat
Author | SHA1 | Date | |
---|---|---|---|
|
007d55ea3f |
@@ -15,7 +15,7 @@ jobs:
|
|||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '23'
|
java-version: '22'
|
||||||
cache: 'maven'
|
cache: 'maven'
|
||||||
- name: Compile project
|
- name: Compile project
|
||||||
run: |
|
run: |
|
||||||
|
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>23</source>
|
<source>22</source>
|
||||||
<target>23</target>
|
<target>22</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@@ -9,4 +9,12 @@ public class Box {
|
|||||||
set(x) {
|
set(x) {
|
||||||
a = x;
|
a = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
m(b) {
|
||||||
|
//b.set(b.get());
|
||||||
|
}
|
||||||
}
|
}
|
@@ -23,9 +23,7 @@ public class Matrix extends Vector<Vector<Integer>> {
|
|||||||
|
|
||||||
public mul(m) {
|
public mul(m) {
|
||||||
var ret = new Matrix();
|
var ret = new Matrix();
|
||||||
var i = 0;
|
for(v1 : this) {
|
||||||
while(i < size()) {
|
|
||||||
var v1 = this.elementAt(i);
|
|
||||||
var v2 = new Vector<Integer>();
|
var v2 = new Vector<Integer>();
|
||||||
var j = 0;
|
var j = 0;
|
||||||
while(j < v1.size()) {
|
while(j < v1.size()) {
|
||||||
@@ -39,7 +37,6 @@ public class Matrix extends Vector<Vector<Integer>> {
|
|||||||
v2.addElement(erg);
|
v2.addElement(erg);
|
||||||
j++; }
|
j++; }
|
||||||
ret.addElement(v2);
|
ret.addElement(v2);
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,24 @@ package de.dhbwstuttgart.bytecode;
|
|||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.Pattern;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
|
import de.dhbwstuttgart.target.generate.StatementToTargetExpression;
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
|
import org.antlr.v4.codegen.Target;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.lang.invoke.*;
|
import java.lang.invoke.*;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||||
@@ -1306,17 +1313,16 @@ public class Codegen {
|
|||||||
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class);
|
var mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Object[].class);
|
||||||
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/runtime/SwitchBootstraps", "typeSwitch", mt.toMethodDescriptorString(), false);
|
var bootstrap = new Handle(H_INVOKESTATIC, "java/lang/runtime/SwitchBootstraps", "typeSwitch", mt.toMethodDescriptorString(), false);
|
||||||
|
|
||||||
var types = new ArrayList<>(aSwitch.cases().size());
|
var types = new ArrayList<Object>(aSwitch.cases().size());
|
||||||
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
|
for (var cse : aSwitch.cases()) for (var label : cse.labels()) {
|
||||||
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern) {
|
if (label instanceof TargetTypePattern || label instanceof TargetComplexPattern)
|
||||||
if (label.type() instanceof TargetGenericType) types.add(Type.getType(Object.class));
|
types.add(Type.getObjectType(label.type().getInternalName()));
|
||||||
else types.add(Type.getObjectType(label.type().getInternalName()));
|
else if (label instanceof TargetLiteral lit)
|
||||||
} else if (label instanceof TargetLiteral lit) {
|
|
||||||
types.add(lit.value());
|
types.add(lit.value());
|
||||||
} else if (label instanceof TargetGuard guard) {
|
else if (label instanceof TargetGuard guard)
|
||||||
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
types.add(Type.getObjectType(guard.inner().type().getInternalName()));
|
||||||
// TODO Same here we need to evaluate constant;
|
// TODO Same here we need to evaluate constant;
|
||||||
} else {
|
else {
|
||||||
System.out.println(label);
|
System.out.println(label);
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@@ -1463,27 +1469,10 @@ public class Codegen {
|
|||||||
// TODO Check if class is a Record
|
// TODO Check if class is a Record
|
||||||
|
|
||||||
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
for (var i = 0; i < cp.subPatterns().size(); i++) {
|
||||||
var subPattern = cp.subPatterns().get(i);
|
|
||||||
|
|
||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
|
|
||||||
|
var subPattern = cp.subPatterns().get(i);
|
||||||
extractField(state, cp.type(), i, clazz);
|
extractField(state, cp.type(), i, clazz);
|
||||||
|
|
||||||
if (subPattern.type() instanceof TargetRefType || subPattern.type() instanceof TargetExtendsWildcard) {
|
|
||||||
state.mv.visitInsn(DUP);
|
|
||||||
state.mv.visitTypeInsn(INSTANCEOF, subPattern.type().getInternalName());
|
|
||||||
|
|
||||||
var cont = new Label();
|
|
||||||
state.mv.visitJumpInsn(IFNE, cont);
|
|
||||||
for (var j = 0; j < depth + 1; j++) {
|
|
||||||
state.mv.visitInsn(POP);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.mv.visitVarInsn(ALOAD, state.switchResultValue.peek());
|
|
||||||
state.mv.visitLdcInsn(index + 1);
|
|
||||||
state.mv.visitJumpInsn(GOTO, start);
|
|
||||||
state.mv.visitLabel(cont);
|
|
||||||
}
|
|
||||||
|
|
||||||
bindPattern(state, subPattern.type(), subPattern, start, index, depth + 1);
|
bindPattern(state, subPattern.type(), subPattern, start, index, depth + 1);
|
||||||
}
|
}
|
||||||
state.mv.visitInsn(POP);
|
state.mv.visitInsn(POP);
|
||||||
@@ -1569,8 +1558,7 @@ public class Codegen {
|
|||||||
state.mv.visitInsn(DUP);
|
state.mv.visitInsn(DUP);
|
||||||
|
|
||||||
extractField(state, cp.type(), i, clazz);
|
extractField(state, cp.type(), i, clazz);
|
||||||
if (subPattern.type() instanceof TargetRefType)
|
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
||||||
state.mv.visitTypeInsn(CHECKCAST, subPattern.type().getInternalName());
|
|
||||||
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
offset = state.createVariable(subPattern.name(), subPattern.type()).index;
|
||||||
state.mv.visitVarInsn(ASTORE, offset);
|
state.mv.visitVarInsn(ASTORE, offset);
|
||||||
if (subPattern instanceof TargetComplexPattern cp2) {
|
if (subPattern instanceof TargetComplexPattern cp2) {
|
||||||
|
@@ -5,7 +5,6 @@ import de.dhbwstuttgart.bytecode.Codegen;
|
|||||||
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;
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
@@ -458,85 +457,6 @@ public class JavaTXCompiler {
|
|||||||
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* TEMPORARY - Only for Language Server Usage
|
|
||||||
*/
|
|
||||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(File file) throws IOException, ClassNotFoundException {
|
|
||||||
var sf = sourceFiles.get(file);
|
|
||||||
if(sf == null){
|
|
||||||
sf = sourceFiles.values().stream().findFirst().get();
|
|
||||||
}
|
|
||||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
|
||||||
allClasses.addAll(sf.getClasses());
|
|
||||||
var newClasses = CompilationEnvironment.loadDefaultPackageClasses(sf.getPkgName(), file, this).stream().map(ASTFactory::createClass).collect(Collectors.toSet());
|
|
||||||
for (var clazz : newClasses) {
|
|
||||||
// Don't load classes that get recompiled
|
|
||||||
if (sf.getClasses().stream().anyMatch(nf -> nf.getClassName().equals(clazz.getClassName())))
|
|
||||||
continue;
|
|
||||||
if (allClasses.stream().noneMatch(old -> old.getClassName().equals(clazz.getClassName())))
|
|
||||||
allClasses.add(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ConstraintSet<Pair> cons = getConstraints(file);
|
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
|
||||||
try {
|
|
||||||
Writer logFile = new OutputStreamWriter(new NullOutputStream());
|
|
||||||
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses.stream().toList(), logFile, classLoader, this);
|
|
||||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(this, cons);
|
|
||||||
Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
|
|
||||||
UnifyType lhs, rhs;
|
|
||||||
if (((lhs = x.getLhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType) && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|
|
||||||
((PlaceholderType) lhs).setInnerType(true);
|
|
||||||
((PlaceholderType) rhs).setInnerType(true);
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
unifyCons = unifyCons.map(distributeInnerVars);
|
|
||||||
TypeUnify unify = new TypeUnify();
|
|
||||||
Set<PlaceholderType> varianceTPHold;
|
|
||||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
|
||||||
varianceTPH = varianceInheritanceConstraintSet(unifyCons);
|
|
||||||
|
|
||||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints();
|
|
||||||
|
|
||||||
if (resultmodel) {
|
|
||||||
/* UnifyResultModel Anfang */
|
|
||||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
|
||||||
UnifyResultListenerImpl li = new UnifyResultListenerImpl();
|
|
||||||
urm.addUnifyResultListener(li);
|
|
||||||
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, usedTasks);
|
|
||||||
generateBytecode(sf, li.getResults());
|
|
||||||
return new LanguageServerTransferObject(li.getResults(), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
|
||||||
}
|
|
||||||
/* UnifyResultModel End */
|
|
||||||
else {
|
|
||||||
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
|
|
||||||
results.addAll(result);
|
|
||||||
|
|
||||||
results = results.stream().map(x -> {
|
|
||||||
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
|
||||||
if (y.getPairOp() == PairOperator.SMALLERDOTWC)
|
|
||||||
y.setPairOp(PairOperator.EQUALSDOT);
|
|
||||||
return y; // alle Paare a <.? b erden durch a =. b ersetzt
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new)));
|
|
||||||
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
|
|
||||||
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
|
||||||
} else
|
|
||||||
return x; // wenn nichts veraendert wurde wird x zurueckgegeben
|
|
||||||
}).collect(Collectors.toCollection(HashSet::new));
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
}
|
|
||||||
generateBytecode(sf, results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()));
|
|
||||||
return new LanguageServerTransferObject(results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()), sf, ASTTypePrinter.print(sf), generatedGenerics);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine Variance !=0 hat auf alle Typvariablen in Theta.
|
||||||
*
|
*
|
||||||
|
@@ -1,277 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface;
|
|
||||||
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Codegen;
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
||||||
import de.dhbwstuttgart.environment.ByteArrayClassLoader;
|
|
||||||
import de.dhbwstuttgart.environment.IByteArrayClassLoader;
|
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.LanguageServerTransferObject;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
|
||||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
|
||||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.file.DirectoryStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of an Interface for the Language-Server to get the Resultset and abstract Syntax.
|
|
||||||
*/
|
|
||||||
public class LanguageServerInterface {
|
|
||||||
|
|
||||||
|
|
||||||
public LanguageServerTransferObject getResultSetAndAbastractSyntax(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
|
||||||
NameGenerator.resetTo(resetNamesTo);
|
|
||||||
return getResultSetAndAbstractSyntax(path);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceFile getAst(String path, String resetNamesTo) throws IOException, URISyntaxException, ClassNotFoundException {
|
|
||||||
NameGenerator.resetTo(resetNamesTo);
|
|
||||||
return getAST(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the ResultSets, GenericResultSet and the AST
|
|
||||||
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
|
||||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
|
||||||
*
|
|
||||||
* @param path the URI of the File. See Example.
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws URISyntaxException
|
|
||||||
*/
|
|
||||||
public LanguageServerTransferObject getResultSetAndAbstractSyntax(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
|
||||||
|
|
||||||
|
|
||||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
|
||||||
|
|
||||||
|
|
||||||
URI uri = new URI(path);
|
|
||||||
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
|
||||||
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
|
||||||
String stringPathWithoutName = "";
|
|
||||||
|
|
||||||
for (String i : pathWithoutName) {
|
|
||||||
stringPathWithoutName += "/" + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
(new File(stringPathWithoutName + "/out")).mkdirs();
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
var test = getLanguageServerTransferObject(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new ByteArrayClassLoader(), new File(stringPathWithoutName).getPath());
|
|
||||||
System.setOut(System.out);
|
|
||||||
return test;
|
|
||||||
// File oldTempSourcefile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".tmp"));
|
|
||||||
// File oldTempOutFile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".class"));
|
|
||||||
// Files.deleteIfExists(oldTempSourcefile.toPath());
|
|
||||||
// Files.deleteIfExists(oldTempOutFile.toPath());
|
|
||||||
// FileUtils.deleteDirectory(oldTempSourcefile);
|
|
||||||
//
|
|
||||||
// File tempSourcefile = new File(stringPathWithoutName + "/out/" + uri.getPath().split("/")[uri.getPath().split("/").length - 1].replace(".jav", ".tmp"));
|
|
||||||
// File tempOutFile = new File(stringPathWithoutName + "/out/");
|
|
||||||
// FileUtils.writeStringToFile(tempSourcefile, input, "UTF-8");
|
|
||||||
//
|
|
||||||
// //TODO: Enable for multiple Class-Files
|
|
||||||
// JavaTXCompiler tx = new JavaTXCompiler(new ArrayList<File>(List.of(tempSourcefile)), new ArrayList<File>(List.of((tempSourcefile))), tempOutFile);
|
|
||||||
// var result = tx.getResultSetAndAbstractSyntax(tempSourcefile);
|
|
||||||
// System.setOut(System.out);
|
|
||||||
// tempSourcefile.delete();
|
|
||||||
// tempOutFile.delete();
|
|
||||||
// return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the AST without calculating the result
|
|
||||||
* You have to give the input as well as the path because of potential locks when the File is currently opened in an IDE.
|
|
||||||
* Example: file:///c:/test/main.jav -> file:///c:/test/out/main.class
|
|
||||||
*
|
|
||||||
* @param path the URI of the File. See Example.
|
|
||||||
* @throws IOException
|
|
||||||
* @throws ClassNotFoundException
|
|
||||||
* @throws URISyntaxException
|
|
||||||
*/
|
|
||||||
public SourceFile getAST(String path) throws IOException, ClassNotFoundException, URISyntaxException {
|
|
||||||
|
|
||||||
|
|
||||||
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
|
|
||||||
|
|
||||||
|
|
||||||
URI uri = new URI(path);
|
|
||||||
ArrayList<String> pathWithoutName = new ArrayList<>(List.of(uri.getPath().split("/")));
|
|
||||||
pathWithoutName.remove(List.of(uri.getPath().split("/")).size() - 1);
|
|
||||||
String stringPathWithoutName = "";
|
|
||||||
|
|
||||||
for (String i : pathWithoutName) {
|
|
||||||
stringPathWithoutName += "/" + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
FileUtils.cleanDirectory(new File(stringPathWithoutName + "/out"));
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
(new File(stringPathWithoutName + "/out")).mkdirs();
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
var test = getAST(uri.getPath().split("/")[uri.getPath().split("/").length - 1], new File(stringPathWithoutName).getPath());
|
|
||||||
System.setOut(System.out);
|
|
||||||
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 {
|
|
||||||
var file = Path.of(filePath, filename).toFile();
|
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), Path.of(filePath + "/out").toFile());
|
|
||||||
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(), "", generics);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,40 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.CustomParserErrorHandler;
|
|
||||||
import de.dhbwstuttgart.languageServerInterface.model.ParserError;
|
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17ParserBaseListener;
|
|
||||||
import org.antlr.v4.runtime.CharStream;
|
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
|
||||||
import org.antlr.v4.runtime.tree.ParseTree;
|
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ParserInterface {
|
|
||||||
|
|
||||||
public List<ParserError> getParseErrors(String input){
|
|
||||||
|
|
||||||
CustomParserErrorHandler errorListener = new CustomParserErrorHandler();
|
|
||||||
CharStream charStream = CharStreams.fromString(input);
|
|
||||||
|
|
||||||
Java17Lexer lexer = new Java17Lexer(charStream);
|
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
|
||||||
|
|
||||||
Java17Parser parser = new Java17Parser(tokens);
|
|
||||||
parser.removeErrorListeners();
|
|
||||||
parser.addErrorListener(errorListener);
|
|
||||||
|
|
||||||
|
|
||||||
ParseTree tree = parser.sourceFile();
|
|
||||||
ParseTreeWalker walker = new ParseTreeWalker();
|
|
||||||
Java17ParserBaseListener listener = new Java17ParserBaseListener();
|
|
||||||
walker.walk(listener, tree);
|
|
||||||
|
|
||||||
return errorListener.getErrorMessages();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface.model;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import org.antlr.v4.runtime.*;
|
|
||||||
import org.antlr.v4.runtime.atn.ATNConfigSet;
|
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.BitSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CustomParserErrorHandler implements ANTLRErrorListener {
|
|
||||||
private final List<ParserError> errorMessages = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
|
||||||
int endCharPosition = charPositionInLine;
|
|
||||||
if (offendingSymbol instanceof Token) {
|
|
||||||
Token offendingToken = (Token) offendingSymbol;
|
|
||||||
endCharPosition = charPositionInLine + offendingToken.getText().length();
|
|
||||||
}
|
|
||||||
|
|
||||||
ParserError parserError = new ParserError(line, charPositionInLine, endCharPosition, msg);
|
|
||||||
errorMessages.add(parserError);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ParserError> getErrorMessages() {
|
|
||||||
return errorMessages;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface.model;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
|
||||||
import de.dhbwstuttgart.target.generate.GenericsResult;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class LanguageServerTransferObject {
|
|
||||||
List<ResultSet> resultSets;
|
|
||||||
SourceFile Ast;
|
|
||||||
String printedAst;
|
|
||||||
Map<SourceFile, List<GenericsResult>> generatedGenerics = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
public LanguageServerTransferObject(List<ResultSet> resultSets, SourceFile Ast, String printedAst, Map<SourceFile, List<GenericsResult>> generatedGenerics) {
|
|
||||||
this.resultSets = resultSets;
|
|
||||||
this.Ast = Ast;
|
|
||||||
this.printedAst = printedAst;
|
|
||||||
this.generatedGenerics = generatedGenerics;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResultSet> getResultSets() {return resultSets;}
|
|
||||||
public SourceFile getAst() {return Ast;}
|
|
||||||
public String getPrintedAst() {return printedAst;}
|
|
||||||
public Map<SourceFile, List<GenericsResult>> getGeneratedGenerics() {return generatedGenerics;}
|
|
||||||
}
|
|
@@ -1,48 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface.model;
|
|
||||||
|
|
||||||
public class ParserError {
|
|
||||||
|
|
||||||
private int line;
|
|
||||||
private int charPositionInLine;
|
|
||||||
private int endCharPosition;
|
|
||||||
String msg;
|
|
||||||
|
|
||||||
public ParserError(int line, int charPositionInLine, int endCharPosition, String msg) {
|
|
||||||
this.line = line;
|
|
||||||
this.charPositionInLine = charPositionInLine;
|
|
||||||
this. endCharPosition = endCharPosition;
|
|
||||||
this.msg = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEndCharPosition() {
|
|
||||||
return endCharPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEndCharPosition(int endCharPosition) {
|
|
||||||
this.endCharPosition = endCharPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCharPositionInLine(int charPositionInLine) {
|
|
||||||
this.charPositionInLine = charPositionInLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLine(int line) {
|
|
||||||
this.line = line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMsg(String msg) {
|
|
||||||
this.msg = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCharPositionInLine() {
|
|
||||||
return charPositionInLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLine() {
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMsg() {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
package de.dhbwstuttgart.languageServerInterface.model;
|
|
||||||
|
|
||||||
|
|
||||||
import com.google.common.reflect.TypeResolver;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultEvent;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
|
|
||||||
|
|
||||||
public class ResultSetListener implements UnifyResultListener {
|
|
||||||
|
|
||||||
TypeResolver typeResolver;
|
|
||||||
|
|
||||||
public ResultSetListener(TypeResolver typeResolver){
|
|
||||||
this.typeResolver = typeResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNewTypeResultFound(UnifyResultEvent evt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -176,9 +176,8 @@ public class ASTFactory {
|
|||||||
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
for (Type jreInterface : jreClass.getGenericInterfaces()) {
|
||||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||||
}
|
}
|
||||||
List<RefType> permittedSubtypes = null;
|
List<RefType> permittedSubtypes = new ArrayList<>();
|
||||||
if (jreClass.isSealed()) {
|
if (jreClass.isSealed()) {
|
||||||
permittedSubtypes = new ArrayList<>();
|
|
||||||
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
for (Class subclass : jreClass.getPermittedSubclasses()) {
|
||||||
permittedSubtypes.add((RefType) createType(subclass));
|
permittedSubtypes.add((RefType) createType(subclass));
|
||||||
}
|
}
|
||||||
|
@@ -13,10 +13,6 @@ public class NameGenerator {
|
|||||||
public static void reset() {
|
public static void reset() {
|
||||||
strNextName = "A";
|
strNextName = "A";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void resetTo(String name) {
|
|
||||||
strNextName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
* Berechnet einen neuen, eindeutigen Namen f�r eine neue
|
||||||
|
@@ -17,6 +17,7 @@ import de.dhbwstuttgart.target.tree.expression.*;
|
|||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
|
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -144,25 +145,49 @@ public class ASTToTargetAST {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is used to serve as a custom equality to signature that performs a weak check without going into record patterns.
|
||||||
|
// The two signatures are considered equal if all the argument types match.
|
||||||
|
// This also turns equal if both types implement a sealed super interface
|
||||||
|
class PatternSignature {
|
||||||
|
final TargetMethod.Signature signature;
|
||||||
|
final String name;
|
||||||
|
PatternSignature(String name, TargetMethod.Signature signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof PatternSignature other)) return false;
|
||||||
|
if (!this.name.equals(other.name)) return false;
|
||||||
|
if (other.signature.parameters().size() != signature.parameters().size()) return false;
|
||||||
|
for (var i = 0; i < signature.parameters().size(); i++) {
|
||||||
|
var p1 = signature.parameters().get(i).pattern().type();
|
||||||
|
var p2 = other.signature.parameters().get(i).pattern().type();
|
||||||
|
if (p1 instanceof TargetGenericType && p2 instanceof TargetGenericType) continue;
|
||||||
|
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1, p2).isEmpty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return signature.parameters().size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This finds a common sealed interface type to group together methods that use different records
|
// This finds a common sealed interface type to group together methods that use different records
|
||||||
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
private List<ClassOrInterface> commonSuperInterfaceTypes(TargetType a, TargetType b) {
|
||||||
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createObjectClass());
|
if (a instanceof TargetGenericType && b instanceof TargetGenericType) return List.of(ASTFactory.createClass(Object.class));
|
||||||
if (a instanceof TargetRefType ta && b instanceof TargetGenericType)
|
|
||||||
return List.of(compiler.getClass(new JavaClassName(ta.name())));
|
|
||||||
if (b instanceof TargetRefType tb && a instanceof TargetGenericType)
|
|
||||||
return List.of(compiler.getClass(new JavaClassName(tb.name())));
|
|
||||||
|
|
||||||
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
|
if (a instanceof TargetRefType ta && b instanceof TargetRefType tb) {
|
||||||
var res = new HashSet<ClassOrInterface>();
|
var res = new HashSet<ClassOrInterface>();
|
||||||
|
|
||||||
var cla = compiler.getClass(new JavaClassName(ta.name()));
|
var cla = compiler.getClass(new JavaClassName(ta.name()));
|
||||||
var clb = compiler.getClass(new JavaClassName(tb.name()));
|
var clb = compiler.getClass(new JavaClassName(tb.name()));
|
||||||
|
|
||||||
if (cla.equals(clb)) return List.of(cla);
|
while (!cla.equals(ASTFactory.createClass(Object.class))) {
|
||||||
|
|
||||||
while (!cla.equals(ASTFactory.createObjectClass())) {
|
|
||||||
var clb2 = clb;
|
var clb2 = clb;
|
||||||
while (!clb2.equals(ASTFactory.createObjectClass())) {
|
while (!clb2.equals(ASTFactory.createClass(Object.class))) {
|
||||||
for (var intfa : cla.getSuperInterfaces()) {
|
for (var intfa : cla.getSuperInterfaces()) {
|
||||||
for (var intfb : clb.getSuperInterfaces()) {
|
for (var intfb : clb.getSuperInterfaces()) {
|
||||||
if (intfa.equals(intfb)) {
|
if (intfa.equals(intfb)) {
|
||||||
@@ -182,167 +207,38 @@ public class ASTToTargetAST {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO This is ugly and probably doesn't work right
|
|
||||||
private boolean patternStrictlyEquals(TargetComplexPattern a, TargetComplexPattern b) {
|
|
||||||
if (!a.name().equals(b.name())) return false;
|
|
||||||
if (a.subPatterns().size() != b.subPatterns().size()) return false;
|
|
||||||
for (var i = 0; i < a.subPatterns().size(); i++) {
|
|
||||||
var p1 = a.subPatterns().get(i);
|
|
||||||
var p2 = b.subPatterns().get(i);
|
|
||||||
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
|
||||||
patternStrictlyEquals(pc1, pc2)) return false;
|
|
||||||
if (p1 instanceof TargetTypePattern pt1 && p2 instanceof TargetTypePattern pt2) {
|
|
||||||
if (pt1.type() instanceof TargetGenericType && pt2.type() instanceof TargetGenericType) continue;
|
|
||||||
}
|
|
||||||
if (!p1.type().equals(p2.type()) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean canCombine(TargetMethod m1, TargetMethod m2) {
|
|
||||||
if (!m1.name().equals(m2.name())) return false;
|
|
||||||
var s1 = m1.signature();
|
|
||||||
var s2 = m2.signature();
|
|
||||||
if (s1.parameters().size() != s2.parameters().size()) return false;
|
|
||||||
if (s1.parameters().isEmpty()) return false;
|
|
||||||
for (var i = 0; i < s1.parameters().size(); i++) {
|
|
||||||
var p1 = s1.parameters().get(i).pattern();
|
|
||||||
var p2 = s2.parameters().get(i).pattern();
|
|
||||||
if (p1.type() instanceof TargetGenericType || p2.type() instanceof TargetGenericType) continue;
|
|
||||||
if (p1 instanceof TargetComplexPattern pc1 && p2 instanceof TargetComplexPattern pc2 &&
|
|
||||||
patternStrictlyEquals(pc1, pc2)) return false;
|
|
||||||
if (!p1.equals(p2) && commonSuperInterfaceTypes(p1.type(), p2.type()).isEmpty()) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private record Combination(TargetMethod a, TargetMethod b) {
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (!(o instanceof Combination(TargetMethod a1, TargetMethod b1))) return false;
|
|
||||||
return this.a.equals(a1) && this.b.equals(b1) ||
|
|
||||||
this.a.equals(b1) && this.b.equals(a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(a) + Objects.hashCode(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
public List<List<TargetMethod>> groupOverloads(ClassOrInterface input, List<Method> methods) {
|
||||||
var mapOfTargetMethods = new HashMap<Generics, TargetMethod[]>();
|
var mapOfSignatures = new HashMap<PatternSignature, List<TargetMethod>>();
|
||||||
for (var generics : all) {
|
for (var method : methods) {
|
||||||
mapOfTargetMethods.put(generics, new TargetMethod[methods.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < methods.size(); i++) {
|
|
||||||
var method = methods.get(i);
|
|
||||||
// Convert all methods
|
// Convert all methods
|
||||||
var methodsWithTphs = convert(input, method);
|
var methodsWithTphs = convert(input, method);
|
||||||
for (var m : methodsWithTphs) {
|
// Then check for methods with the same signature
|
||||||
var resultMethods = mapOfTargetMethods.get(m.generics);
|
var resMethods = new HashSet<MethodWithTphs>();
|
||||||
resultMethods[i] = m.method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*System.out.println("============== INPUT ==============");
|
|
||||||
for (var m : mapOfTargetMethods.values()) {
|
|
||||||
for (var v : m) System.out.println(v.name() + " " + v.getSignature());
|
|
||||||
System.out.println();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var allCombinations = new HashSet<Set<Combination>>();
|
outer:
|
||||||
// Combine methods based on their signature and position in the result set
|
for (var m1 : methodsWithTphs) {
|
||||||
for (var g1 : all) {
|
for (var m2 : methodsWithTphs) {
|
||||||
var resMeth1 = mapOfTargetMethods.get(g1);
|
for (var i = 0; i < m1.args.size(); i++) {
|
||||||
for (var i = 0; i < methods.size(); i++) {
|
var arg1 = m1.args.get(i);
|
||||||
var m1 = resMeth1[i];
|
var arg2 = m2.args.get(i);
|
||||||
if (m1 == null) continue;
|
if (arg1.parameter.equals(arg2.parameter)) {
|
||||||
|
if (isSupertype(arg1.signature, arg2.signature) &&
|
||||||
for (var g2 : all) {
|
!arg1.signature.equals(arg2.signature)) continue outer;
|
||||||
if (g1 == g2) continue; // No need to combine the same method
|
|
||||||
var resMeth2 = mapOfTargetMethods.get(g2);
|
|
||||||
var m2 = resMeth2[i];
|
|
||||||
if (m2 == null) continue;
|
|
||||||
|
|
||||||
var combinations = new HashSet<Combination>();
|
|
||||||
|
|
||||||
if (canCombine(m1, m2)) {
|
|
||||||
//System.out.println(" Combining " + m1.getSignature() + " and " + m2.getSignature());
|
|
||||||
combinations.add(new Combination(m1, m2));
|
|
||||||
for (var j = 0; j < methods.size(); j++) {
|
|
||||||
if (j == i) continue;
|
|
||||||
var m3 = resMeth2[j];
|
|
||||||
if (m3 == null) continue;
|
|
||||||
var m4 = resMeth1[j];
|
|
||||||
if (m4 == null) continue;
|
|
||||||
combinations.add(new Combination(m4, m3));
|
|
||||||
//System.out.println("Also Combining " + m4.getSignature() + " and " + m3.getSignature());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//System.out.println(" Not Combining " + m1.getSignature() + " and " + m2.getSignature());
|
|
||||||
}
|
|
||||||
if (!combinations.isEmpty()) allCombinations.add(combinations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allCombinations.isEmpty()) allCombinations.add(new HashSet<>());
|
|
||||||
|
|
||||||
// Combine back into output format
|
|
||||||
var r0 = new HashSet<Set<TargetMethod>>();
|
|
||||||
for (var combinations : allCombinations) {
|
|
||||||
var r1 = new HashSet<Set<TargetMethod>>();
|
|
||||||
// This is used to weed out duplicates
|
|
||||||
var uniqued = new HashSet<TargetMethod>();
|
|
||||||
// We go over all methods in the result
|
|
||||||
for (var g : all) for (var i = 0; i < methods.size(); i++) {
|
|
||||||
var r2 = new HashSet<TargetMethod>();
|
|
||||||
var m = mapOfTargetMethods.get(g)[i];
|
|
||||||
if (m == null) continue;
|
|
||||||
if (!uniqued.contains(m)) {
|
|
||||||
// Add the method to r2
|
|
||||||
r2.add(m);
|
|
||||||
uniqued.add(m);
|
|
||||||
} else continue;
|
|
||||||
// Find all combinations that contain the method and add them to the result
|
|
||||||
// if not filtered out by uniqued
|
|
||||||
for (var c : combinations) {
|
|
||||||
if (c.a.equals(m) || c.b.equals(m)) {
|
|
||||||
if (!uniqued.contains(c.a)) {
|
|
||||||
r2.add(c.a);
|
|
||||||
uniqued.add(c.a);
|
|
||||||
}
|
|
||||||
if (!uniqued.contains(c.b)) {
|
|
||||||
r2.add(c.b);
|
|
||||||
uniqued.add(c.b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r1.add(r2);
|
resMethods.add(m1);
|
||||||
}
|
}
|
||||||
outer: for (var s1 : r1) {
|
|
||||||
for (var s2 : new HashSet<>(r0)) {
|
for (var m : resMethods) {
|
||||||
if (s2.containsAll(s1)) {
|
var signature = new PatternSignature(m.method.name(), m.method.signature());
|
||||||
continue outer;
|
var methodsWithSameSignature = mapOfSignatures.getOrDefault(signature, new ArrayList<>());
|
||||||
} else if (s1.containsAll(s2)) {
|
methodsWithSameSignature.add(m.method);
|
||||||
r0.remove(s2);
|
mapOfSignatures.put(signature, methodsWithSameSignature);
|
||||||
r0.add(s1);
|
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r0.add(s1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = r0.stream().map(l -> l.stream().toList()).toList();
|
return mapOfSignatures.values().stream().toList();
|
||||||
|
|
||||||
System.out.println("============== OUTPUT ==============");
|
|
||||||
for (var l : result) {
|
|
||||||
for (var m : l) System.out.println(m.name() + " " + m.getSignature());
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TargetStructure convert(ClassOrInterface input) {
|
public TargetStructure convert(ClassOrInterface input) {
|
||||||
@@ -375,8 +271,7 @@ public class ASTToTargetAST {
|
|||||||
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
var superInterfaces = input.getSuperInterfaces().stream().map(clazz -> convert(clazz, generics.javaGenerics)).toList();
|
||||||
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
var constructors = input.getConstructors().stream().map(constructor -> this.convert(input, constructor, finalFieldInitializer)).flatMap(List::stream).toList();
|
||||||
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
||||||
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream)
|
var methods = groupOverloads(input, input.getMethods()).stream().map(m -> generatePatternOverloads(input, m)).flatMap(List::stream).toList();
|
||||||
.collect(Collectors.toSet()).stream().toList(); // Unique generated methods
|
|
||||||
|
|
||||||
TargetMethod staticConstructor = null;
|
TargetMethod staticConstructor = null;
|
||||||
if (input.getStaticInitializer().isPresent())
|
if (input.getStaticInitializer().isPresent())
|
||||||
@@ -498,7 +393,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cases = new ArrayList<TargetSwitch.Case>();
|
var cases = new ArrayList<TargetSwitch.Case>();
|
||||||
var usedPatterns = new HashSet<TargetPattern>();
|
var usedPatterns = new HashSet<TargetType>();
|
||||||
|
|
||||||
for (var method : methods) {
|
for (var method : methods) {
|
||||||
var patternsRec = new ArrayList<>(patterns);
|
var patternsRec = new ArrayList<>(patterns);
|
||||||
@@ -518,8 +413,9 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lastPattern = patternsRec.getLast();
|
var lastPattern = patternsRec.getLast();
|
||||||
if (usedPatterns.contains(lastPattern)) continue;
|
var type = unwrap(lastPattern.type());
|
||||||
usedPatterns.add(lastPattern);
|
if (usedPatterns.contains(type)) continue;
|
||||||
|
usedPatterns.add(type);
|
||||||
|
|
||||||
var candidates = methods.stream().filter(m -> {
|
var candidates = methods.stream().filter(m -> {
|
||||||
var j = 0;
|
var j = 0;
|
||||||
@@ -565,12 +461,9 @@ public class ASTToTargetAST {
|
|||||||
var t3 = m.signature().parameters().get(i).pattern().type();
|
var t3 = m.signature().parameters().get(i).pattern().type();
|
||||||
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
|
commonSubTypes.retainAll(commonSuperInterfaceTypes(t1, t3));
|
||||||
}
|
}
|
||||||
if (commonSubTypes.size() > 1) throw new DebugException("Invalid overload");
|
if (commonSubTypes.size() != 1) throw new DebugException("Invalid overload");
|
||||||
// TODO accept multiple types
|
// TODO accept multiple types
|
||||||
var superType = ASTFactory.createObjectClass();
|
var superType = commonSubTypes.iterator().next();
|
||||||
if (!commonSubTypes.isEmpty())
|
|
||||||
superType = commonSubTypes.iterator().next();
|
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
if (p1 instanceof TargetComplexPattern) name = "__var" + i;
|
if (p1 instanceof TargetComplexPattern) name = "__var" + i;
|
||||||
else name = p1.name();
|
else name = p1.name();
|
||||||
@@ -640,19 +533,7 @@ public class ASTToTargetAST {
|
|||||||
}).findFirst();
|
}).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
record MethodWithTphs(TargetMethod method, Generics generics, List<SignaturePairTarget> args) {
|
record MethodWithTphs(TargetMethod method, List<SignaturePairTarget> args) {}
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (!(o instanceof MethodWithTphs that)) return false;
|
|
||||||
return Objects.equals(method, that.method) && Objects.equals(args, that.args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(method, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
|
record Signature(TargetMethod.Signature java, TargetMethod.Signature tx, Generics generics) {}
|
||||||
|
|
||||||
@@ -701,7 +582,7 @@ public class ASTToTargetAST {
|
|||||||
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
|
var newMethod = new TargetMethod(method.modifier, method.name, convert(method.block), signature.java, signature.tx);
|
||||||
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
|
var concreteParams = tphsInMethods.getOrDefault(method, new HashSet<>()).stream().map(sig -> new SignaturePairTarget(convert(sig.signature), convert(sig.parameter))).toList();
|
||||||
|
|
||||||
result.add(new MethodWithTphs(newMethod, generics, concreteParams));
|
result.add(new MethodWithTphs(newMethod, concreteParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -55,7 +55,7 @@ public class AllgemeinTest {
|
|||||||
//String className = "VectorNotObject";
|
//String className = "VectorNotObject";
|
||||||
//String className = "WildcardCaptureConversionTest";
|
//String className = "WildcardCaptureConversionTest";
|
||||||
//String className = "CaptureConversion";
|
//String className = "CaptureConversion";
|
||||||
//String className = "Pair";
|
String className = "Pair2";
|
||||||
//String className = "UseWildcardPair";
|
//String className = "UseWildcardPair";
|
||||||
//String className = "Assign";
|
//String className = "Assign";
|
||||||
//String className = "StreamTest";
|
//String className = "StreamTest";
|
||||||
@@ -64,8 +64,8 @@ public class AllgemeinTest {
|
|||||||
//String className = "Cycle";
|
//String className = "Cycle";
|
||||||
//String className = "TripleTest";
|
//String className = "TripleTest";
|
||||||
//String className = "WildcardList";
|
//String className = "WildcardList";
|
||||||
String className = "List";
|
//String className = "List";
|
||||||
//String className = "Box";
|
//String className = "BoxUse";
|
||||||
//String className = "GenBox";
|
//String className = "GenBox";
|
||||||
//String className = "InnerInf";
|
//String className = "InnerInf";
|
||||||
//String className = "Foo";
|
//String className = "Foo";
|
||||||
|
@@ -835,7 +835,6 @@ public class TestComplete {
|
|||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringSwitch() throws Exception {
|
public void testStringSwitch() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchString.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "SwitchString.jav");
|
||||||
@@ -857,7 +856,6 @@ public class TestComplete {
|
|||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testOverloadPattern() throws Exception {
|
public void testOverloadPattern() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadPattern.jav");
|
||||||
@@ -883,7 +881,6 @@ public class TestComplete {
|
|||||||
assertEquals(m3.invoke(instance, 10), 10);
|
assertEquals(m3.invoke(instance, 10), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testOverloadNestedPattern() throws Exception {
|
public void testOverloadNestedPattern() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "OverloadNestedPattern.jav");
|
||||||
@@ -905,7 +902,7 @@ public class TestComplete {
|
|||||||
assertEquals(m.invoke(instance, r1, r1), 3);
|
assertEquals(m.invoke(instance, r1, r1), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
//@Ignore("Not implemented")
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingHaskellStyle() throws Exception {
|
public void testPatternMatchingHaskellStyle() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingHaskellStyle.jav");
|
||||||
@@ -928,7 +925,6 @@ public class TestComplete {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore("Not implemented")
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingListAppend() throws Exception {
|
public void testPatternMatchingListAppend() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "PatternMatchingListAppend.jav");
|
||||||
@@ -944,9 +940,6 @@ public class TestComplete {
|
|||||||
|
|
||||||
var list1 = ConsCtor.newInstance(1, ConsCtor.newInstance(2, ConsCtor.newInstance(3, EmptyCtor.newInstance())));
|
var list1 = ConsCtor.newInstance(1, ConsCtor.newInstance(2, ConsCtor.newInstance(3, EmptyCtor.newInstance())));
|
||||||
var list2 = ConsCtor.newInstance(4, ConsCtor.newInstance(5, ConsCtor.newInstance(6, EmptyCtor.newInstance())));
|
var list2 = ConsCtor.newInstance(4, ConsCtor.newInstance(5, ConsCtor.newInstance(6, EmptyCtor.newInstance())));
|
||||||
|
|
||||||
var append = clazz.getDeclaredMethod("append", Cons, Cons);
|
|
||||||
System.out.println(append.invoke(instance, list1, list2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -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/"));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
public class t{
|
|
||||||
public mofus(){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user