forked from JavaTX/JavaCompilerCore
merge
This commit is contained in:
commit
a733eee8b5
8
pom.xml
8
pom.xml
@ -73,6 +73,14 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>9</source>
|
||||
<target>9</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
|
@ -10,6 +10,10 @@ import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||
@ -51,9 +55,9 @@ public class BytecodeGen implements ASTVisitor {
|
||||
@Override
|
||||
public void visit(SourceFile sourceFile) {
|
||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||||
System.out.println("in Class: " + cl.getClassName().toString());
|
||||
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
||||
cl.accept(classGen);
|
||||
System.out.println("In CLASS: "+(cl.getClassName().toString()));
|
||||
classGen.writeClass(cl.getClassName().toString());
|
||||
}
|
||||
}
|
||||
@ -79,9 +83,10 @@ public class BytecodeGen implements ASTVisitor {
|
||||
public void visit(ClassOrInterface classOrInterface) {
|
||||
className = classOrInterface.getClassName().toString();
|
||||
|
||||
isInterface = (classOrInterface.getModifiers()&512)==512;
|
||||
System.out.println("IS Interface = "+"modifiers= "+classOrInterface.getModifiers()+" ->"+(classOrInterface.getModifiers()&512) + isInterface);
|
||||
cw.visitSource(className +".jav", null);
|
||||
|
||||
isInterface = (classOrInterface.getModifiers()&512)==512;
|
||||
|
||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
||||
String sig = null;
|
||||
/* if class has generics then creates signature
|
||||
@ -90,8 +95,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
*/
|
||||
if(classOrInterface.getGenerics().iterator().hasNext()) {
|
||||
Signature signature = new Signature(classOrInterface, genericsAndBounds);
|
||||
|
||||
System.out.println(signature.toString());
|
||||
sig = signature.toString();
|
||||
}
|
||||
// needs implemented Interfaces?
|
||||
@ -100,8 +103,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
// for each field in the class
|
||||
for(Field f : classOrInterface.getFieldDecl()) {
|
||||
System.out.println("get Fields");
|
||||
System.out.println(f.getName());
|
||||
f.accept(this);
|
||||
}
|
||||
|
||||
@ -112,7 +113,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
for(Method m : classOrInterface.getMethods()) {
|
||||
m.accept(this);
|
||||
}
|
||||
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,24 +121,25 @@ public class BytecodeGen implements ASTVisitor {
|
||||
|
||||
String desc = null;
|
||||
boolean hasGen = false;
|
||||
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
genericsAndBounds.containsKey(paramName);
|
||||
hasGen = true;
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
if(genericsAndBounds.containsKey(typeOfParam)) {
|
||||
hasGen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String sig = null;
|
||||
if(hasGen) {
|
||||
System.out.println("IM IN CONST HAS Gens");
|
||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes);
|
||||
sig = signature.toString();
|
||||
System.out.println(sig);
|
||||
}
|
||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
||||
mv.visitCode();
|
||||
System.out.println("-----Constructor-----");
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw,
|
||||
genericsAndBoundsMethod,genericsAndBounds,isInterface);
|
||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
||||
if(!field.getParameterList().iterator().hasNext()) {
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
}
|
||||
@ -155,45 +156,41 @@ public class BytecodeGen implements ASTVisitor {
|
||||
String methDesc = null;
|
||||
|
||||
// Method getModifiers() ?
|
||||
int acc = isInterface?Opcodes.ACC_ABSTRACT:0;
|
||||
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
|
||||
|
||||
System.out.println("-----Method-----");
|
||||
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(method.getReturnType().acceptTV(new TypeToDescriptor()));
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()));
|
||||
if(!hasGenInParameterList) {
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
if(genericsAndBounds.containsKey(paramName)) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
if(genericsAndBounds.containsKey(typeOfParam)) {
|
||||
hasGenInParameterList = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
|
||||
//than create the descriptor with the new syntax.
|
||||
|
||||
String sig = null;
|
||||
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||
// Wenn ReturnType has Generics?? Fun1<...> wie testet man das generic hat??
|
||||
System.out.println(method.getReturnType().acceptTV(new TypeToString()));
|
||||
// if(method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
|
||||
// Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
|
||||
// sig = signature.toString();
|
||||
// System.out.println(sig);
|
||||
// }
|
||||
/* if method has generics, create signature */
|
||||
if(hasGen) {
|
||||
|
||||
/* if method has generics or return type is TPH, create signature */
|
||||
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
|
||||
// resultset hier zum testen
|
||||
Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
|
||||
sig = signature.toString();
|
||||
System.out.println(sig);
|
||||
|
||||
}
|
||||
|
||||
System.out.println(sig);
|
||||
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
||||
methDesc = meth.accept(new DescriptorToString(resultSet));
|
||||
System.out.println("methDesc" + methDesc);
|
||||
System.out.println(methDesc);
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
|
||||
|
||||
mv.visitCode();
|
||||
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,genericsAndBounds,genericsAndBounds,isInterface);
|
||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,
|
||||
genericsAndBounds,genericsAndBounds,isInterface,classFiles);
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
@ -207,7 +204,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
paramsAndLocals.put(fp.getName(), i);
|
||||
methodParamsAndTypes.put(fp.getName(), fp.getType());
|
||||
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
|
||||
fp.accept(this);
|
||||
i++;
|
||||
}
|
||||
@ -250,7 +247,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
// ??
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
System.out.println("in fieldvar");
|
||||
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
||||
fv.visitEnd();
|
||||
@ -259,7 +255,6 @@ public class BytecodeGen implements ASTVisitor {
|
||||
// access flages?? modifiers
|
||||
@Override
|
||||
public void visit(Field field) {
|
||||
System.out.println("in field");
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
@ -15,12 +19,21 @@ import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
@ -30,28 +43,27 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
private MethodVisitor mv;
|
||||
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||
private String className;
|
||||
private int lamCounter;
|
||||
private int lamCounter = -1;
|
||||
private ClassWriter cw;
|
||||
private ResultSet resultSet;
|
||||
private boolean isInterface;
|
||||
HashMap<String, String> genericsAndBoundsMethod;
|
||||
private HashMap<String,String> genericsAndBounds;
|
||||
private boolean isBinaryExp = false;
|
||||
|
||||
//for tests **
|
||||
private String fieldName;
|
||||
private String fieldDesc;
|
||||
private Expression rightSideTemp;
|
||||
private String where;
|
||||
private boolean isRightSideALambda = false;
|
||||
private KindOfLambda kindOfLambda;
|
||||
private HashMap<String, byte[]> classFiles;
|
||||
|
||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
|
||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||
|
||||
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw,
|
||||
HashMap<String, String> genericsAndBoundsMethod, HashMap<String,String> genericsAndBounds, boolean isInterface) {
|
||||
|
||||
this.where = "<<<<<< NORMAL METHOD >>>>>>";
|
||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||
HashMap<String,String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||
|
||||
this.className = className;
|
||||
this.resultSet = resultSet;
|
||||
@ -62,31 +74,20 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.isInterface = isInterface;
|
||||
this.lamCounter = -1;
|
||||
|
||||
this.varsFunInterface = new ArrayList<>();
|
||||
System.out.println("PARAMS = "+this.paramsAndLocals.size());
|
||||
this.classFiles = classFiles;
|
||||
|
||||
if(!isInterface)
|
||||
this.m.block.accept(this);
|
||||
|
||||
// System.out.println("PARAMS = "+this.paramsAndLocals.size());
|
||||
// for(int i = 0; i<this.paramsAndLocals.size();i++) {
|
||||
// System.out.println(this.paramsAndLocals.keySet().toArray()[i]);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
|
||||
int indexOfFirstParamLam, boolean isInterface) {
|
||||
System.out.println("\t\t++++++IN LAMBDA -------");
|
||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||
|
||||
this.where = "<<<<<< LAMBDA METHOD >>>>>>";
|
||||
this.resultSet = resultSet;
|
||||
this.mv = mv;
|
||||
this.isInterface = isInterface;
|
||||
this.lamCounter = -1;
|
||||
this.varsFunInterface = new ArrayList<>();
|
||||
this.classFiles = classFiles;
|
||||
|
||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||
int i = indexOfFirstParamLam;
|
||||
@ -99,7 +100,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
}
|
||||
|
||||
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
// return resultSet.resolveType(type).resolvedType.toString().replace(".", "/");
|
||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
}
|
||||
|
||||
@ -107,10 +107,8 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
for(Statement stmt : block.getStatements()) {
|
||||
System.out.println(where);
|
||||
System.out.println("Stmt : " + stmt.toString());
|
||||
// System.out.println(where);
|
||||
stmt.accept(this);
|
||||
System.out.println("--------------------------\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,58 +116,67 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
public void visit(SuperCall superCall) {
|
||||
superCall.receiver.accept(this);
|
||||
superCall.arglist.accept(this);
|
||||
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
|
||||
}
|
||||
|
||||
// ??
|
||||
@Override
|
||||
public void visit(LocalVar localVar) {
|
||||
System.out.println("in Local Var: " + localVar.name);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
||||
if(isBinaryExp) {
|
||||
getVlaue(getResolvedType(localVar.getType()));
|
||||
}
|
||||
}
|
||||
// ??
|
||||
@Override
|
||||
public void visit(LocalVarDecl localVarDecl) {
|
||||
// Integer i;
|
||||
// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
|
||||
System.out.println("In localVarDecl :: "+localVarDecl.getName());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Assign assign) {
|
||||
System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide);
|
||||
|
||||
// if the right side is a lambda => the left side must be a functional interface
|
||||
if(assign.rightSide.getClass().equals(LambdaExpression.class)) {
|
||||
if(assign.rightSide instanceof LambdaExpression) {
|
||||
isRightSideALambda = true;
|
||||
}else {
|
||||
isRightSideALambda = false;
|
||||
}
|
||||
|
||||
System.out.println("\t isRight Side lambda: " + isRightSideALambda);
|
||||
if(assign.lefSide.getClass().equals(AssignToField.class)) {
|
||||
if(assign.rightSide instanceof BinaryExpr)
|
||||
isBinaryExp = true;
|
||||
|
||||
if(assign.lefSide instanceof AssignToField) {
|
||||
// load_0, ldc or .. then putfield
|
||||
this.rightSideTemp = assign.rightSide;
|
||||
assign.lefSide.accept(this);
|
||||
}else {
|
||||
assign.rightSide.accept(this);
|
||||
assign.lefSide.accept(this);
|
||||
}
|
||||
if(isBinaryExp) {
|
||||
doAssign(getResolvedType(assign.lefSide.getType()));
|
||||
isBinaryExp = false;
|
||||
}
|
||||
assign.lefSide.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
System.out.println("\t++ In Binary: ");
|
||||
binary.lexpr.accept(this);
|
||||
binary.rexpr.accept(this);
|
||||
switch (binary.operation.toString()) {
|
||||
case "ADD":
|
||||
mv.visitInsn(Opcodes.IADD);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
System.out.println("\n++ In Lambda: ");
|
||||
this.lamCounter++;
|
||||
|
||||
System.out.println("Lam Hs Gens: " + lambdaExpression.getGenerics().iterator().hasNext());
|
||||
System.out.println("Lam Hs Gens: " + lambdaExpression.getReturnType().acceptTV(new TypeToString()));
|
||||
Lambda lam = new Lambda(lambdaExpression);
|
||||
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
||||
//Call site, which, when invoked, returns an instance of the functional interface to which
|
||||
@ -181,10 +188,20 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
|
||||
"metafactory", mt.toMethodDescriptorString(), false);
|
||||
String methodName = "lambda$new$" + this.lamCounter;
|
||||
// String typeErasure = "(Ljava/lang/Object;)Ljava/lang/Object;";
|
||||
|
||||
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die Typlöschung)
|
||||
|
||||
String typeErasure = "(";
|
||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||
while(itr.hasNext()) {
|
||||
itr.next();
|
||||
typeErasure += "L"+Type.getInternalName(Object.class) + ";";
|
||||
}
|
||||
|
||||
typeErasure += ")L"+Type.getInternalName(Object.class) + ";";
|
||||
// Type erasure
|
||||
// Type arg1 = Type.getMethodType(typeErasure);
|
||||
Type arg1 = Type.getMethodType(lamDesc);
|
||||
Type arg1 = Type.getMethodType(typeErasure);
|
||||
// Type arg1 = Type.getMethodType(lamDesc);
|
||||
// real Type
|
||||
Type arg3 = Type.getMethodType(lamDesc);
|
||||
|
||||
@ -209,20 +226,64 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
||||
// Desc: (this/nothing)TargetType
|
||||
String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet));
|
||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap,
|
||||
arg1, arg2,arg3);
|
||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3);
|
||||
|
||||
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
||||
methodName, arg3.toString(), null, null);
|
||||
|
||||
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface);
|
||||
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface,
|
||||
classFiles);
|
||||
|
||||
mvLambdaBody.visitMaxs(0, 0);
|
||||
mvLambdaBody.visitEnd();
|
||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||
|
||||
// generateBCForFunN(lambdaExpression,typeErasure);
|
||||
}
|
||||
|
||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||
ClassWriter classWriter =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
SignatureWriter methSig = new SignatureWriter();
|
||||
|
||||
int numberOfParams = 0;
|
||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||
while(itr.hasNext()) {
|
||||
numberOfParams++;
|
||||
// getBounds
|
||||
paramVisitor.visitTypeVariable("T"+numberOfParams);
|
||||
itr.next();
|
||||
}
|
||||
methSig.visitReturnType().visitTypeVariable("R");
|
||||
// ")"+lam.getReturn.getBounds
|
||||
Signature sig = new Signature(lambdaExpression,numberOfParams);
|
||||
String name = "Fun"+numberOfParams;
|
||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE+Opcodes.ACC_ABSTRACT, name,
|
||||
sig.toString(), Type.getInternalName(Object.class), null);
|
||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "apply",
|
||||
methDesc, methSig.toString(), null);
|
||||
mvApply.visitEnd();
|
||||
writeClassFile(classWriter.toByteArray(),name);
|
||||
}
|
||||
|
||||
public void writeClassFile(byte[] bytecode, String name) {
|
||||
FileOutputStream output;
|
||||
try {
|
||||
System.out.println("generating "+name+ ".class file...");
|
||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
|
||||
output.write(bytecode);
|
||||
output.close();
|
||||
System.out.println(name+".class file generated");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(CastExpr castExpr) {
|
||||
// TODO Auto-generated method stub
|
||||
@ -237,7 +298,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(FieldVar fieldVar) {
|
||||
System.out.println("in fieldVar " + fieldVar.fieldVarName + " ** receiver: "+fieldVar.receiver);
|
||||
|
||||
fieldName = fieldVar.fieldVarName;
|
||||
fieldDesc = "L"+getResolvedType(fieldVar.getType())+";";
|
||||
@ -261,7 +321,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(IfStmt ifStmt) {
|
||||
System.out.println("++ IF-Statment: ");
|
||||
System.out.println("If");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -272,14 +332,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(MethodCall methodCall) {
|
||||
System.out.println(" In Methodcall: (" +methodCall.name+")" );
|
||||
System.out.print("\t\tMethod-Receiver: ");
|
||||
if(methodCall.receiver instanceof ExpressionReceiver){
|
||||
System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n");
|
||||
}else{
|
||||
System.out.print(((StaticClassName) methodCall.receiver).getType().toString() + "\n");
|
||||
}
|
||||
|
||||
methodCall.receiver.accept(this);
|
||||
methodCall.arglist.accept(this);
|
||||
|
||||
@ -287,14 +339,11 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
genericsAndBoundsMethod,genericsAndBounds);
|
||||
String mDesc = method.accept(new DescriptorToString(resultSet));
|
||||
|
||||
System.out.println("is Vars empty: "+varsFunInterface.isEmpty());
|
||||
|
||||
// is methodCall.receiver functional Interface)?
|
||||
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
||||
methodCall.name, mDesc, false);
|
||||
}else {
|
||||
System.out.println("mDesc = " + mDesc);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
|
||||
methodCall.name, mDesc, isInterface);
|
||||
}
|
||||
@ -306,8 +355,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(NewClass methodCall) {
|
||||
System.out.println("In NewClass: ");
|
||||
System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver);
|
||||
|
||||
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
@ -330,14 +377,12 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(ExpressionReceiver receiver) {
|
||||
System.out.println(" in Receiver");
|
||||
System.out.println(" expr : " + receiver.expr);
|
||||
receiver.expr.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(UnaryExpr unaryExpr) {
|
||||
throw new NotImplementedException();
|
||||
System.out.println(unaryExpr.operation.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -353,7 +398,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
System.out.println("In StaticClassName: ");
|
||||
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
||||
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()),
|
||||
@ -362,19 +406,18 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(Super aSuper) {
|
||||
System.out.println(">> In Super: ");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(This aThis) {
|
||||
System.out.println("-> IN This");
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WhileStmt whileStmt) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
whileStmt.expr.accept(this);
|
||||
whileStmt.loopBlock.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -385,17 +428,209 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(Literal literal) {
|
||||
// value?
|
||||
mv.visitLdcInsn(getResolvedType(literal.getType()));
|
||||
Object value = literal.value;
|
||||
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(this.isBinaryExp) {
|
||||
getVlaue(typeOfLiteral);
|
||||
}else {
|
||||
doAssign(typeOfLiteral, value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void getVlaue(String typeOfLiteral) {
|
||||
switch (typeOfLiteral) {
|
||||
case "java/lang/String":
|
||||
break;
|
||||
case "java/lang/Boolean":
|
||||
break;
|
||||
case "java/lang/Byte":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||
"(B)Ljava/lang/Byte;", false);
|
||||
break;
|
||||
case "java/lang/Short":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||
"(S)Ljava/lang/Short;", false);
|
||||
break;
|
||||
case "java/lang/Integer":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
||||
"()I", false);
|
||||
break;
|
||||
case "java/lang/Long":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||
"(J)Ljava/lang/Long;", false);
|
||||
break;
|
||||
case "java/lang/Float":
|
||||
break;
|
||||
case "java/lang/Double":
|
||||
break;
|
||||
case "java/lang/Character":
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void doAssign(String type, Object value) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitLdcInsn(String.valueOf(value));
|
||||
break;
|
||||
case "java/lang/Boolean":
|
||||
visitBooleanLiteral((Boolean) value);
|
||||
break;
|
||||
case "java/lang/Byte":
|
||||
visitByteLiteral(((Double) value).byteValue(),false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||
"(B)Ljava/lang/Byte;", false);
|
||||
break;
|
||||
case "java/lang/Short":
|
||||
visitShortLiteral(((Double) value).shortValue(),false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||
"(S)Ljava/lang/Short;", false);
|
||||
break;
|
||||
case "java/lang/Integer":
|
||||
//zweite Argument isLong
|
||||
visitIntegerLiteral(((Double) value).intValue(), false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
||||
"(I)Ljava/lang/Integer;", false);
|
||||
break;
|
||||
case "java/lang/Long":
|
||||
visitLongLiteral(((Double) value).longValue(), true);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||
"(J)Ljava/lang/Long;", false);
|
||||
break;
|
||||
case "java/lang/Float":
|
||||
visitFloatLiteral(((Double) value).floatValue());
|
||||
break;
|
||||
case "java/lang/Double":
|
||||
visitDoubleLiteral((Double) value);
|
||||
break;
|
||||
case "java/lang/Character":
|
||||
visitCharLiteral((Character) value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void doAssign(String type) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
break;
|
||||
case "java/lang/Boolean":
|
||||
break;
|
||||
case "java/lang/Byte":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
||||
"(B)Ljava/lang/Byte;", false);
|
||||
break;
|
||||
case "java/lang/Short":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
||||
"(S)Ljava/lang/Short;", false);
|
||||
break;
|
||||
case "java/lang/Integer":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
||||
"(I)Ljava/lang/Integer;", false);
|
||||
break;
|
||||
case "java/lang/Long":
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
||||
"(J)Ljava/lang/Long;", false);
|
||||
break;
|
||||
case "java/lang/Float":
|
||||
break;
|
||||
case "java/lang/Double":
|
||||
break;
|
||||
case "java/lang/Character":
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCharLiteral(Character value) {
|
||||
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
|
||||
"(C)Ljava/lang/Character;", false);
|
||||
}
|
||||
|
||||
private void visitDoubleLiteral(Double value) {
|
||||
if(value == 0) {
|
||||
mv.visitInsn(Opcodes.DCONST_0);
|
||||
}else if(value == 1) {
|
||||
mv.visitInsn(Opcodes.DCONST_1);
|
||||
}else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
|
||||
"(D)Ljava/lang/Double;", false);
|
||||
}
|
||||
|
||||
private void visitFloatLiteral(Float value) {
|
||||
if(value.intValue()>-1 && value.intValue() < 3) {
|
||||
//Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw
|
||||
mv.visitInsn(value.intValue()+11);
|
||||
}else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
|
||||
"(F)Ljava/lang/Float;", false);
|
||||
}
|
||||
|
||||
private void visitLongLiteral(Long value, boolean isLong) {
|
||||
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||
visitShortLiteral(value.shortValue(),isLong);
|
||||
}else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitShortLiteral(Short value,boolean isLong) {
|
||||
if(value< 128 || (value>-129 && value<-1)) {
|
||||
visitByteLiteral(value.byteValue(), isLong);
|
||||
}else if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitByteLiteral(Byte value, boolean isLong) {
|
||||
|
||||
if(!isLong && value<6 && value>-1) {
|
||||
//Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw
|
||||
mv.visitInsn(value+3);
|
||||
}else if(isLong && value>-1 && value<2){
|
||||
//Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10
|
||||
mv.visitInsn(value+9);
|
||||
}else {
|
||||
mv.visitIntInsn(Opcodes.BIPUSH, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void visitIntegerLiteral(Integer value, boolean isLong) {
|
||||
|
||||
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
||||
visitShortLiteral(value.shortValue(),isLong);
|
||||
}else {
|
||||
mv.visitLdcInsn(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void visitBooleanLiteral(Boolean b) {
|
||||
if(b) {
|
||||
mv.visitInsn(Opcodes.ICONST_1);
|
||||
}else {
|
||||
mv.visitInsn(Opcodes.ICONST_0);
|
||||
}
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
|
||||
"(Z)Ljava/lang/Boolean;", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArgumentList argumentList) {
|
||||
System.out.println("in ArgumentList: ");
|
||||
for(Expression al : argumentList.getArguments()) {
|
||||
al.accept(this);
|
||||
}
|
||||
System.out.println("out from Argumentlist");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -414,7 +649,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(AssignToLocal assignLeftSide) {
|
||||
System.out.println("In Assign To Local: ");
|
||||
if(isRightSideALambda)
|
||||
varsFunInterface.add(assignLeftSide.localVar.getType());
|
||||
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1);
|
||||
|
@ -1,14 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
public class ClassFile {
|
||||
|
||||
String name;
|
||||
byte[] bytecode;
|
||||
|
||||
public ClassFile(String name, byte[] bytecode) {
|
||||
this.name = name;
|
||||
this.bytecode = bytecode;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
public class SamMethod {
|
||||
|
@ -1,150 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
|
||||
public class Test {
|
||||
private static final String rootDirectory = System.getProperty("user.dir") + "/bin/de/dhbwstuttgart/bytecode/";
|
||||
|
||||
protected static ClassLoader getClassLoader() throws Exception {
|
||||
File file = new File(rootDirectory);
|
||||
URL url = file.toURI().toURL();
|
||||
URL[] urls = new URL[] { url };
|
||||
System.out.println(urls[0]);
|
||||
return new URLClassLoader(urls);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Test Lambda
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "TestClass", null, "java/lang/Object", null);
|
||||
|
||||
cw.visitSource("TestClass.java", null);
|
||||
|
||||
// Create Constructor
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
|
||||
|
||||
// mv.visitMethodInsn(INVOKEDYNAMIC, "#0", "run", "()Ljava/lang/Runnable");
|
||||
//Call site, which, when invoked, returns an instance of the functional interface to which
|
||||
//the lambda is being converted
|
||||
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
||||
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||
|
||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
||||
mt.toMethodDescriptorString());
|
||||
Handle arg2 = new Handle(Opcodes.H_INVOKESTATIC, "TestClass", "lambda$0", "()V");
|
||||
|
||||
mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bootstrap,
|
||||
Type.getMethodType("()V"), arg2,
|
||||
Type.getMethodType("()V"));
|
||||
|
||||
mv.visitVarInsn(Opcodes.ASTORE, 1);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 1);
|
||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Runnable", "run", "()V");
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
|
||||
// creates bridge method, contains lambdas body
|
||||
MethodVisitor mvl = cw.visitMethod(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, "lambda$0",
|
||||
"()V", null, null);
|
||||
mvl.visitCode();
|
||||
mvl.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
|
||||
mvl.visitLdcInsn("lambda");
|
||||
mvl.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
|
||||
mvl.visitInsn(Opcodes.RETURN);
|
||||
mvl.visitMaxs(2, 0);
|
||||
mvl.visitEnd();
|
||||
|
||||
mv.visitMaxs(1, 2);
|
||||
mv.visitEnd();
|
||||
|
||||
|
||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||
cw.visitEnd();
|
||||
|
||||
byte[] b = cw.toByteArray();
|
||||
|
||||
// Test if statement
|
||||
/*
|
||||
* ClassWriter cw = new
|
||||
* ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||
*
|
||||
* cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_SUPER, "TestIf", null,
|
||||
* "java/lang/Object", null); MethodVisitor mv =
|
||||
* cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(Ljava/lang/Boolean;)V", null,
|
||||
* null); mv.visitCode();
|
||||
*
|
||||
* // Label l0 = new Label(); // mv.visitLabel(l0);
|
||||
*
|
||||
* mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
*
|
||||
* mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>",
|
||||
* "()V");
|
||||
*
|
||||
* // Label l1 = new Label(); // mv.visitLabel(l1);
|
||||
* mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
|
||||
* "java/lang/Boolean", "booleanValue", "()Z");
|
||||
*
|
||||
* Label label = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, label);
|
||||
*
|
||||
* mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out",
|
||||
* "Ljava/io/PrintStream;"); mv.visitLdcInsn("1");
|
||||
* mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
|
||||
* "(Ljava/lang/String;)V");
|
||||
*
|
||||
* Label endLabel = new Label(); mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||
*
|
||||
* mv.visitLabel(label); mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
* "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("0");
|
||||
* mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
|
||||
* "(Ljava/lang/String;)V");
|
||||
*
|
||||
*
|
||||
*
|
||||
* mv.visitLabel(endLabel); mv.visitInsn(Opcodes.RETURN);
|
||||
*
|
||||
* // Label l2 = new Label(); // mv.visitLabel(l2);
|
||||
*
|
||||
* // mv.visitLocalVariable("this", "LTestIf;", null, l0, l2, 0); //
|
||||
* mv.visitLocalVariable("b", "Ljava/lang/Boolean;", null, l0, l2, 1);
|
||||
* mv.visitMaxs(2, 2); mv.visitEnd();
|
||||
*
|
||||
* cw.visitEnd(); byte[] b = cw.toByteArray();
|
||||
*/
|
||||
FileOutputStream output;
|
||||
|
||||
try {
|
||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/TestClass.class"));
|
||||
output.write(b);
|
||||
output.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
public class TestClass {
|
||||
public TestClass() {
|
||||
Runnable lam = () -> System.out.println("lambda");
|
||||
lam.run();
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
public class TestFields {
|
||||
private static final String rootDirectory = System.getProperty("user.dir") + "/bin/de/dhbwstuttgart/bytecode/";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// TODO Auto-generated method stub
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, "TetsF", null, "java/lang/Object", null);
|
||||
|
||||
cw.visitSource("TetsF.java", null);
|
||||
|
||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, "z", Type.INT_TYPE.getDescriptor(), null, null);
|
||||
fv.visitEnd();
|
||||
|
||||
FieldVisitor fvS = cw.visitField(Opcodes.ACC_PUBLIC, "s", "Ljava/lang/String;", null, null);
|
||||
fvS.visitEnd();
|
||||
// Create Constructor
|
||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||
mv.visitLdcInsn("");
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, "TetsF", "s", "Ljava/lang/String;");
|
||||
mv.visitInsn(Opcodes.RETURN);
|
||||
mv.visitMaxs(2, 1);
|
||||
mv.visitEnd();
|
||||
|
||||
byte[] b = cw.toByteArray();
|
||||
|
||||
FileOutputStream output;
|
||||
|
||||
try {
|
||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/TetsF.class"));
|
||||
output.write(b);
|
||||
output.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
public class TestIf {
|
||||
public TestIf(Boolean b) {
|
||||
if(b) {
|
||||
System.out.println("1");
|
||||
}else {
|
||||
System.out.println("0");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
public class TestMeth {
|
||||
private int z;
|
||||
public String s;
|
||||
public TestMeth(int temp) {
|
||||
this.z = temp;
|
||||
}
|
||||
public void m1(int a, int b) {
|
||||
int y = m2(1,2,3,4);
|
||||
}
|
||||
|
||||
public int m2(int a, int b, int x, int y) {
|
||||
Integer c = 55;
|
||||
Integer g;
|
||||
return a+b+y+c;
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
public class TetsF {
|
||||
private int z;
|
||||
public String s = "";
|
||||
}
|
@ -1,9 +1,16 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
package de.dhbwstuttgart.bytecode.descriptor;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Lambda;
|
||||
import de.dhbwstuttgart.bytecode.MethodFromMethodCall;
|
||||
import de.dhbwstuttgart.bytecode.NormalConstructor;
|
||||
import de.dhbwstuttgart.bytecode.NormalMethod;
|
||||
import de.dhbwstuttgart.bytecode.SamMethod;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
@ -30,6 +37,8 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
// System.out.println(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature()));
|
||||
// System.out.println("Parmetrisierte typ ? "+ ((RefType) fp.getType()).getParaList().size());
|
||||
if(method.hasGen()) {
|
||||
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
|
||||
if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) {
|
||||
@ -39,7 +48,11 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
}else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
}
|
||||
}else {
|
||||
}
|
||||
// else if(((RefType) fp.getType()).getParaList().size() > 0){
|
||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "%").replace("<", "%%").replace(">", "%%")+ ";";
|
||||
// }
|
||||
else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
}
|
||||
}
|
||||
@ -71,16 +84,16 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
while(itr.hasNext()) {
|
||||
FormalParameter fp = itr.next();
|
||||
if(constructor.hasGen()) {
|
||||
System.out.println("Cons has Gens");
|
||||
// System.out.println("Cons has Gens");
|
||||
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
|
||||
System.out.println(fpDesc);
|
||||
// System.out.println(fpDesc);
|
||||
if(constructor.getGenericsAndBounds().containsKey(fpDesc)){
|
||||
desc += "L"+constructor.getGenericsAndBounds().get(fpDesc)+ ";";
|
||||
}else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
}
|
||||
}else {
|
||||
System.out.println("Cons has NOT Gens");
|
||||
// System.out.println("Cons has NOT Gens");
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
}
|
||||
}
|
||||
@ -96,7 +109,6 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
FormalParameter fp = itr.next();
|
||||
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
|
||||
}
|
||||
System.out.println("LamReturnType: "+lambdaExpression.getReturnType().acceptTV(new TypeToString()));
|
||||
desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet);
|
||||
return desc;
|
||||
}
|
@ -1,4 +1,10 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
package de.dhbwstuttgart.bytecode.descriptor;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Lambda;
|
||||
import de.dhbwstuttgart.bytecode.MethodFromMethodCall;
|
||||
import de.dhbwstuttgart.bytecode.NormalConstructor;
|
||||
import de.dhbwstuttgart.bytecode.NormalMethod;
|
||||
import de.dhbwstuttgart.bytecode.SamMethod;
|
||||
|
||||
public interface DescriptorVisitor {
|
||||
public String visit(NormalMethod method);
|
@ -1,4 +1,4 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
package de.dhbwstuttgart.bytecode.descriptor;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
@ -1,16 +1,21 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
package de.dhbwstuttgart.bytecode.signature;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
import org.objectweb.asm.signature.SignatureWriter;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
|
||||
@ -49,6 +54,29 @@ public class Signature {
|
||||
createSignatureForConsOrMethod(this.method,false);
|
||||
}
|
||||
|
||||
public Signature(LambdaExpression lambdaExpression,int numberOfParams) {
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForFunN(lambdaExpression, numberOfParams);
|
||||
}
|
||||
|
||||
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
|
||||
|
||||
sw.visitFormalTypeParameter("R");
|
||||
// getBounds vom Return-Type
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
for(int i = 0;i<numberOfParams;i++) {
|
||||
int j = i+1;
|
||||
sw.visitFormalTypeParameter("T"+ j);
|
||||
// getBounds von Params
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
// TODO: prüfe ob Return-Type = void,
|
||||
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));;
|
||||
sw.visitEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates signature for a method or constructor with @see {@link SignatureWriter}
|
||||
* Signature looks like:
|
||||
@ -96,16 +124,18 @@ public class Signature {
|
||||
}
|
||||
switch (type) {
|
||||
case "RT":
|
||||
sv.visitClassType(t.acceptTV(new TypeToDescriptor()));
|
||||
sv.visitClassType(t.acceptTV(new TypeToSignature()));
|
||||
break;
|
||||
case "GRT":
|
||||
GenericRefType g = (GenericRefType) t;
|
||||
sv.visitTypeVariable(g.getParsedName());
|
||||
sv.visitTypeVariable(g.acceptTV(new TypeToSignature()));
|
||||
break;
|
||||
case "TPH":
|
||||
System.out.println(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor()));
|
||||
// sv.visitInterface().visitClassType(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor())+"<Ljava/lang/Integer;Ljava/lang/Integer;>;");
|
||||
|
||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
||||
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH "))
|
||||
sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
// sv.visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||
break;
|
||||
default:
|
||||
if(!isParameterType)
|
||||
@ -141,6 +171,7 @@ public class Signature {
|
||||
while(bItr.hasNext()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric b =bItr.next();
|
||||
String boundDesc = b.acceptTV(new TypeToDescriptor());
|
||||
// System.out.println("GetBounds: " + boundDesc);
|
||||
// Ensure that <...> extends java.lang.Object OR ...
|
||||
sw.visitClassBound().visitClassType(boundDesc);
|
||||
genAndBounds.put(g.getParsedName(), boundDesc);
|
53
src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java
Normal file
53
src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java
Normal file
@ -0,0 +1,53 @@
|
||||
package de.dhbwstuttgart.bytecode.signature;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
|
||||
|
||||
public class TypeToSignature implements TypeVisitor<String> {
|
||||
|
||||
@Override
|
||||
public String visit(RefType refType) {
|
||||
// return refType.toString().replace(".", "/");
|
||||
String params = "";
|
||||
if(refType.getParaList().size()>0){
|
||||
params += "<";
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = refType.getParaList().iterator();
|
||||
while(it.hasNext()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||
params += "L"+param.toString().replace(".", "/");
|
||||
if(it.hasNext())params += ";";
|
||||
}
|
||||
params += ";>";
|
||||
}
|
||||
return refType.getName().toString().replace(".", "/") + params+";";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(SuperWildcardType superWildcardType) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(TypePlaceholder typePlaceholder) {
|
||||
return typePlaceholder.toString().replace(".", "/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visit(GenericRefType genericRefType) {
|
||||
return genericRefType.getParsedName().replace(".", "/");
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
package de.dhbwstuttgart.bytecode.signature;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
@ -40,17 +40,29 @@ public class CompilationEnvironment {
|
||||
* @param sourceFiles die zu kompilierenden Dateien
|
||||
*/
|
||||
public CompilationEnvironment(List<File> sourceFiles) {
|
||||
String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
/**
|
||||
* Java 9 bringt einige Änderungen am Classloader
|
||||
* So funktioniert der BootClassLoader nicht mehr.
|
||||
* hier gibts ein paar Quellen zum nachlesen:
|
||||
* http://java9.wtf/class-loading/
|
||||
* https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9
|
||||
*
|
||||
*/
|
||||
//String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
// ClassLoader cl = ClassLoader.getPlatformClassLoader();
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
String bootClassPath = System.getProperty("java.class.path");
|
||||
librarys = new ArrayList<>();
|
||||
if(bootClassPath != null){
|
||||
for(String path : bootClassPath.split(File.pathSeparator)) {
|
||||
try {
|
||||
librarys.add(new URL("file:"+path));
|
||||
} catch (MalformedURLException e) {
|
||||
new DebugException("Fehler im Classpath auf diesem System");
|
||||
}
|
||||
for(String path : bootClassPath.split(File.pathSeparator)) {
|
||||
try {
|
||||
librarys.add(new URL("file:"+path));
|
||||
} catch (MalformedURLException e) {
|
||||
new DebugException("Fehler im Classpath auf diesem System");
|
||||
}
|
||||
}
|
||||
}
|
||||
//URLClassLoader loader = new URLClassLoader(new URL[0], cl);
|
||||
//librarys = Arrays.asList(loader.getURLs());
|
||||
|
||||
this.sourceFiles = sourceFiles;
|
||||
this.packageCrawler = new PackageCrawler(librarys);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
@ -11,6 +12,7 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FCGenerator {
|
||||
/**
|
||||
@ -19,12 +21,15 @@ public class FCGenerator {
|
||||
*
|
||||
* @param availableClasses - Alle geparsten Klassen
|
||||
*/
|
||||
public static Set<UnifyPair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
HashSet<UnifyPair> pairs = new HashSet<>();
|
||||
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
return toFC(availableClasses).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
HashSet<Pair> pairs = new HashSet<>();
|
||||
for(ClassOrInterface cly : availableClasses){
|
||||
pairs.addAll(getSuperTypes(cly, availableClasses));
|
||||
}
|
||||
System.out.println("Pairs: " + pairs);
|
||||
return pairs;
|
||||
}
|
||||
|
||||
@ -35,20 +40,20 @@ public class FCGenerator {
|
||||
* @param forType
|
||||
* @return
|
||||
*/
|
||||
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>());
|
||||
}
|
||||
|
||||
//TODO: implements Interface auch als superklassen beachten
|
||||
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, HashMap<String, UnifyType> gtvs) throws ClassNotFoundException {
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) throws ClassNotFoundException {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
//Die GTVs, die in forType hinzukommen:
|
||||
HashMap<String, UnifyType> newGTVs = new HashMap<>();
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
|
||||
//Generics mit gleichem Namen müssen den selben TPH bekommen
|
||||
for(GenericTypeVar gtv : forType.getGenerics()){
|
||||
if(!gtvs.containsKey(gtv.getParsedName())){
|
||||
gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
|
||||
newGTVs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
|
||||
gtvs.put(gtv.getParsedName(), TypePlaceholder.fresh(new NullToken()));
|
||||
newGTVs.put(gtv.getParsedName(), TypePlaceholder.fresh(new NullToken()));
|
||||
}
|
||||
params.add(gtvs.get(gtv.getParsedName()));
|
||||
}
|
||||
@ -73,27 +78,26 @@ public class FCGenerator {
|
||||
while(itGenParams.hasNext()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next();
|
||||
//In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen:
|
||||
UnifyType setSetType = setType.acceptTV(new TypeExchanger(gtvs));
|
||||
RefTypeOrTPHOrWildcardOrGeneric setSetType = setType.acceptTV(new TypeExchanger(gtvs));
|
||||
newGTVs.put(itGenParams.next().getParsedName(), setSetType);
|
||||
}
|
||||
|
||||
UnifyType superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs));
|
||||
RefTypeOrTPHOrWildcardOrGeneric superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs));
|
||||
|
||||
TypeParams paramList = new TypeParams(params);
|
||||
UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList);
|
||||
UnifyType t2 = superType;
|
||||
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken());
|
||||
RefTypeOrTPHOrWildcardOrGeneric t2 = superType;
|
||||
|
||||
UnifyPair ret = UnifyTypeFactory.generateSmallerPair(t1, t2);
|
||||
Pair ret = new Pair(t1, t2, PairOperator.SMALLER);
|
||||
|
||||
List<UnifyPair> superTypes;
|
||||
List<Pair> superTypes;
|
||||
//Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse:
|
||||
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
|
||||
superTypes = Arrays.asList(UnifyTypeFactory.generateSmallerPair(UnifyTypeFactory.convert(ASTFactory.createObjectType()), UnifyTypeFactory.convert(ASTFactory.createObjectType())));
|
||||
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
|
||||
}else{
|
||||
superTypes = getSuperTypes(superClass, availableClasses, newGTVs);
|
||||
}
|
||||
|
||||
List<UnifyPair> retList = new ArrayList<>();
|
||||
List<Pair> retList = new ArrayList<>();
|
||||
retList.add(ret);
|
||||
retList.addAll(superTypes);
|
||||
|
||||
@ -103,42 +107,41 @@ public class FCGenerator {
|
||||
/**
|
||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
||||
*/
|
||||
private static class TypeExchanger implements TypeVisitor<UnifyType>{
|
||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
|
||||
private final HashMap<String, UnifyType> gtvs;
|
||||
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||
|
||||
TypeExchanger(HashMap<String, UnifyType> gtvs){
|
||||
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
|
||||
this.gtvs = gtvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(RefType refType) {
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
params.add(param.acceptTV(this));
|
||||
}
|
||||
TypeParams paramList = new TypeParams(params);
|
||||
UnifyType ret = new ReferenceType(refType.getName().toString(), paramList);
|
||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(SuperWildcardType superWildcardType) {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(TypePlaceholder typePlaceholder) {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(ExtendsWildcardType extendsWildcardType) {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(GenericRefType genericRefType) {
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||
if(! gtvs.containsKey(genericRefType.getParsedName()))
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
//TODO: Diesen Dirty-Hack beseitigen. Fehler tritt bei java.lang.invoke.LambdaFormEditor$Transform$Kind auf.
|
||||
|
@ -7,6 +7,7 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
@ -278,13 +279,14 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) {
|
||||
//TODO
|
||||
throw new NotImplementedException();
|
||||
Expression argument = convert(stmt.unaryExpression());
|
||||
Token offset = stmt.getStart();
|
||||
return new UnaryExpr(UnaryExpr.Operation.PREINCREMENT, argument, TypePlaceholder.fresh(offset), offset);
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) {
|
||||
//TODO
|
||||
throw new NotImplementedException();
|
||||
private Statement convert(Java8Parser.PreDecrementExpressionContext stmt) {
|
||||
return new UnaryExpr(UnaryExpr.Operation.PREDECREMENT, convert(stmt.unaryExpression()),
|
||||
TypePlaceholder.fresh(stmt.getStart()), stmt.getStart());
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.PostIncrementExpressionContext stmt) {
|
||||
@ -293,8 +295,8 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.PostDecrementExpressionContext stmt) {
|
||||
//TODO
|
||||
throw new NotImplementedException();
|
||||
return new UnaryExpr(UnaryExpr.Operation.POSTDECREMENT, convert(stmt.postfixExpression()),
|
||||
TypePlaceholder.fresh(stmt.getStart()), stmt.getStart());
|
||||
}
|
||||
|
||||
private Statement convert(Java8Parser.AssignmentContext stmt) {
|
||||
@ -599,8 +601,31 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private BinaryExpr.Operator convertBinaryOperator(String operator) {
|
||||
|
||||
return null;
|
||||
//return BinaryExpr.Operator.ADD;
|
||||
if(operator.equals("+")) {
|
||||
return BinaryExpr.Operator.ADD;
|
||||
}else if(operator.equals("-")) {
|
||||
return BinaryExpr.Operator.SUB;
|
||||
}else if(operator.equals("*")) {
|
||||
return BinaryExpr.Operator.MUL;
|
||||
}else if(operator.equals("&")) {
|
||||
return BinaryExpr.Operator.AND;
|
||||
}else if(operator.equals("|")) {
|
||||
return BinaryExpr.Operator.OR;
|
||||
}else if(operator.equals("/")) {
|
||||
return BinaryExpr.Operator.DIV;
|
||||
}else if(operator.equals("<")) {
|
||||
return BinaryExpr.Operator.LESSTHAN;
|
||||
}else if(operator.equals(">")) {
|
||||
return BinaryExpr.Operator.BIGGERTHAN;
|
||||
}else if(operator.equals(">=")) {
|
||||
return BinaryExpr.Operator.BIGGEREQUAL;
|
||||
} else if(operator.equals("<=")) {
|
||||
return BinaryExpr.Operator.LESSEQUAL;
|
||||
} else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Expression convert(Java8Parser.ShiftExpressionContext expression) {
|
||||
@ -612,12 +637,15 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Expression convert(Java8Parser.AdditiveExpressionContext expression) {
|
||||
if(expression.additiveExpression() != null){
|
||||
return convert(expression.additiveExpression());
|
||||
}else if(expression.multiplicativeExpression() != null){
|
||||
|
||||
if(expression.additiveExpression() == null){
|
||||
return convert(expression.multiplicativeExpression());
|
||||
}else{
|
||||
throw new NotImplementedException();
|
||||
}else {
|
||||
Expression leftSide = convert(expression.additiveExpression());
|
||||
Expression rightSide = convert(expression.multiplicativeExpression());
|
||||
BinaryExpr.Operator op = convertBinaryOperator(expression.getChild(1).getText());
|
||||
Token offset = expression.getStart();
|
||||
return new BinaryExpr(op, TypePlaceholder.fresh(expression.getStart()), leftSide, rightSide, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,7 +653,11 @@ public class StatementGenerator {
|
||||
if(expression.multiplicativeExpression() == null){
|
||||
return convert(expression.unaryExpression());
|
||||
}else{
|
||||
throw new NotImplementedException();
|
||||
Expression leftSide = convert(expression.multiplicativeExpression());
|
||||
Expression rightSide = convert(expression.unaryExpression());
|
||||
BinaryExpr.Operator op = convertBinaryOperator(expression.getChild(1).getText());
|
||||
Token offset = expression.getStart();
|
||||
return new BinaryExpr(op, TypePlaceholder.fresh(offset), leftSide, rightSide, offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,7 +825,9 @@ public class StatementGenerator {
|
||||
}else if(literal.CharacterLiteral() != null){
|
||||
RefType type = new RefType(reg.getName("java.lang.Character"),literal.getStart());
|
||||
return new Literal(type,
|
||||
literal.CharacterLiteral().getText().charAt(0),
|
||||
// das gibt immer ' zurück, der Char befindet sich in Position 1
|
||||
//literal.CharacterLiteral().getText().charAt(0),
|
||||
literal.CharacterLiteral().getText().charAt(1),
|
||||
literal.getStart());
|
||||
}else if(literal.StringLiteral()!=null){
|
||||
RefType type = new RefType(reg.getName("java.lang.String"),literal.getStart());
|
||||
|
@ -164,7 +164,12 @@ public class SyntaxTreeGenerator{
|
||||
modifiers += newModifier;
|
||||
}
|
||||
}
|
||||
JavaClassName name = reg.getName(ctx.Identifier().getText());
|
||||
String className = this.pkgName + (this.pkgName.length()>0?".":"") + ctx.Identifier().getText();
|
||||
JavaClassName name = reg.getName(className);
|
||||
if(! name.toString().equals(className)){
|
||||
throw new TypeinferenceException("Name " + className + " bereits vorhanden in " + reg.getName(className).toString()
|
||||
,ctx.getStart());
|
||||
}
|
||||
GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "", reg, new GenericsRegistry(globalGenerics));
|
||||
Token offset = ctx.getStart();
|
||||
GenericDeclarationList genericClassParameters;
|
||||
|
17
src/de/dhbwstuttgart/sat/asp/ASPStringConverter.java
Normal file
17
src/de/dhbwstuttgart/sat/asp/ASPStringConverter.java
Normal file
@ -0,0 +1,17 @@
|
||||
package de.dhbwstuttgart.sat.asp;
|
||||
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
|
||||
public class ASPStringConverter {
|
||||
public static String toConstant(JavaClassName name){
|
||||
return toConstant(name.toString().replace(".", "_"));
|
||||
}
|
||||
|
||||
public static String toConstant(String name){
|
||||
return "c" + name.toString().replace(".", "_");
|
||||
}
|
||||
|
||||
public static String fromConstant(String s){
|
||||
return s.replace("_", ".").substring(1);
|
||||
}
|
||||
}
|
@ -17,16 +17,20 @@ public class Clingo {
|
||||
private static final List<File> programFiles = new ArrayList<>();
|
||||
static{
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/basis.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/finiteclosure.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/subst.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/reduce1.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/reduce2.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/reduce.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/unify.lp"));
|
||||
programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/adapt.lp"));
|
||||
}
|
||||
|
||||
public Clingo(List<File> inputFiles){
|
||||
this.input = inputFiles;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Clingo per Java Wrapper https://stackoverflow.com/questions/3356200/using-java-to-wrap-over-c
|
||||
*/
|
||||
public String runClingo() throws IOException, InterruptedException {
|
||||
String pathToClingo =
|
||||
"/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/clingo-5.2.1-linux-x86_64/clingo";
|
||||
|
@ -8,8 +8,9 @@ public enum ASPRule {
|
||||
ASP_PARAMLIST_NAME("param"),
|
||||
ASP_PARAMLISTNUMERATION_NAME("paramNum"),
|
||||
ASP_PARAMLIST_END_POINTER("null"),
|
||||
ASP_TYPE("type")
|
||||
;
|
||||
ASP_TYPE("type"),
|
||||
ASP_FCTYPE("typeFC"),
|
||||
ASP_TYPE_VAR("typeVar");
|
||||
|
||||
private final String text;
|
||||
|
||||
|
@ -1,17 +1,187 @@
|
||||
package de.dhbwstuttgart.sat.asp.parser;
|
||||
|
||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.sat.asp.ASPStringConverter;
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.parser.model.ParsedType;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.writer.model.ASPParameterList;
|
||||
import de.dhbwstuttgart.sat.asp.writer.model.ASPRefType;
|
||||
import de.dhbwstuttgart.sat.asp.writer.model.ASPType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonArray;
|
||||
import javax.json.JsonObject;
|
||||
import java.io.StringReader;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Ablauf:
|
||||
* - Erst werden alle benötigten Statements eingelesen. Die Pointer bleiben als Strings erhalten
|
||||
* - Anschließend müssen diese wieder zu einem Unify Ergebnis zurückgewandelt werden
|
||||
* - Hier nicht die Typen aus dem unify.model packages verwenden.
|
||||
* TODO: Überlegen welche Informationen noch nach der Unifizierung gebraucht werden
|
||||
* -> Eigentlich nur die korrekten Namen der Typen und TPHs
|
||||
*/
|
||||
public class ASPParser {
|
||||
ResultSet parse(String result){
|
||||
Set<ResultPair> ret = new HashSet<>();
|
||||
for(String pair : result.split(",")){
|
||||
private final Collection<TypePlaceholder> originalTPHs;
|
||||
private ResultSet resultSet;
|
||||
private Map<String, ParsedType> types = new HashMap<>();
|
||||
private Set<String> tphs = new HashSet<>();
|
||||
private Map<String, ParameterListNode> parameterLists = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Parst clingo output welcher als JSON (option --outf=2) ausgibt
|
||||
* @param toParse
|
||||
* @return
|
||||
*/
|
||||
public static ResultSet parse(String toParse, Collection<TypePlaceholder> oldPlaceholders){
|
||||
return new ASPParser(toParse, oldPlaceholders).resultSet;
|
||||
}
|
||||
|
||||
|
||||
private ASPParser(String toParse, Collection<TypePlaceholder> oldPlaceholders){
|
||||
this.originalTPHs = oldPlaceholders;
|
||||
JsonObject jsonResult = Json.createReader(new StringReader(toParse)).readObject();
|
||||
JsonArray results = jsonResult.getJsonArray("Call").getJsonObject(0).
|
||||
getJsonArray("Witnesses").getJsonObject(0).
|
||||
getJsonArray("Value");
|
||||
|
||||
/*
|
||||
Diese Funktion läuft im folgenden mehrmals über das Result aus dem ASP Programm.
|
||||
Dabei werden Schritt für Schritt die Felder dieser Klasse befüllt die am Schluss das ResultSet ergeben
|
||||
*/
|
||||
Set<ResultPair> ret = new HashSet<>();
|
||||
//Zuerst die params und typeVars:
|
||||
for(int i = 0; i<results.size();i++){
|
||||
String aspStatement = results.getString(i);
|
||||
parseParameter(aspStatement);
|
||||
parseTypeVar(aspStatement);
|
||||
}
|
||||
return new ResultSet(ret);
|
||||
//Dann die Typen, das ist wichtig, da die Typen auf die Parameter referenzieren:
|
||||
for(int i = 0; i<results.size();i++){
|
||||
String aspStatement = results.getString(i);
|
||||
parseType(aspStatement);
|
||||
}
|
||||
//Dann die Equalsdot Statements
|
||||
for(int i = 0; i<results.size();i++){
|
||||
String aspStatement = results.getString(i);
|
||||
ResultPair p = parseEqualsDot(aspStatement);
|
||||
if(p != null)ret.add(p);
|
||||
p = parseSmallerDot(aspStatement);
|
||||
if(p != null)ret.add(p);
|
||||
}
|
||||
|
||||
this.resultSet = new ResultSet(ret);
|
||||
}
|
||||
|
||||
private ResultPair parseSmallerDot(String statement) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
private ResultPair parseEqualsDot(String statement){
|
||||
Pattern p = Pattern.compile(ASPRule.ASP_PAIR_EQUALS_NAME+"\\(([^,]+),([^,]+)\\)");
|
||||
Matcher m = p.matcher(statement);
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
if(m.groupCount()<2)throw new DebugException("Fehler in Regex");
|
||||
String ls = m.group(1);
|
||||
String rs = m.group(2);
|
||||
RefTypeOrTPHOrWildcardOrGeneric lsType = this.getType(ls);
|
||||
RefTypeOrTPHOrWildcardOrGeneric rsType = this.getType(rs);
|
||||
if(lsType instanceof TypePlaceholder && rsType instanceof RefType)
|
||||
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) lsType, rsType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RefTypeOrTPHOrWildcardOrGeneric getType(String name) {
|
||||
if(tphs.contains(name)){
|
||||
name = ASPStringConverter.fromConstant(name);
|
||||
for(TypePlaceholder tph : originalTPHs){
|
||||
if(tph.getName().equals(name))return tph;
|
||||
}
|
||||
return TypePlaceholder.fresh(new NullToken());
|
||||
}else
|
||||
if(types.containsKey(name)){
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
ParsedType t = types.get(name);
|
||||
for(String param : t.params){
|
||||
params.add(this.getType(param));
|
||||
}
|
||||
return new RefType(new JavaClassName(ASPStringConverter.fromConstant(t.name)), params, new NullToken());
|
||||
}else throw new DebugException("Der Typ " + name + " konnte nicht bestimmt werden");
|
||||
}
|
||||
|
||||
private static class ParameterListNode{
|
||||
final String type;
|
||||
final String nextNode;
|
||||
|
||||
public ParameterListNode(String type, String next) {
|
||||
this.type = type;
|
||||
this.nextNode = next;
|
||||
}
|
||||
}
|
||||
private void parseParameter(String statement){
|
||||
Pattern p = Pattern.compile(ASPRule.ASP_PARAMLIST_NAME+"\\(([^,]+),([^,]+),([^,]+)\\)");
|
||||
Matcher m = p.matcher(statement);
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
if(m.groupCount()<3)throw new DebugException("Fehler in Regex");
|
||||
String pointer = m.group(1);
|
||||
String type = m.group(2);
|
||||
String next = m.group(2);
|
||||
if(next.equals(ASPRule.ASP_PARAMLIST_END_POINTER.toString()))next = null;
|
||||
if(this.parameterLists.containsKey(pointer)){
|
||||
throw new DebugException("Fehler in Ergebnisparsen");
|
||||
}
|
||||
this.parameterLists.put(pointer,new ParameterListNode(type, next));
|
||||
}
|
||||
}
|
||||
|
||||
private void parseTypeVar(String statement){
|
||||
Pattern p = Pattern.compile(ASPRule.ASP_TYPE_VAR+"\\(([^,]+)\\)");
|
||||
Matcher m = p.matcher(statement);
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
if(m.groupCount()<1)throw new DebugException("Fehler in Regex");
|
||||
String name = m.group(1);
|
||||
this.tphs.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseType(String statement){
|
||||
Pattern p = Pattern.compile(ASPRule.ASP_TYPE+"\\(([^,]+),([^,]+)\\)");
|
||||
Matcher m = p.matcher(statement);
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
if(m.groupCount()<2)throw new DebugException("Fehler in Regex");
|
||||
String ls = m.group(1);
|
||||
String rs = m.group(2);
|
||||
List<String> params = this.getParams(rs);
|
||||
this.types.put(ls,new ParsedType(ls, params));
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getParams(String pointer) {
|
||||
List<String> params = new ArrayList<>();
|
||||
if(pointer.equals(ASPRule.ASP_PARAMLIST_END_POINTER.toString()))return params;
|
||||
while(pointer != null){
|
||||
if(!parameterLists.containsKey(pointer))
|
||||
throw new DebugException("Fehler in Ergebnisparsen");
|
||||
ParameterListNode param = parameterLists.get(pointer);
|
||||
pointer = param.nextNode;
|
||||
params.add(param.type);
|
||||
}
|
||||
return params;
|
||||
//Optional<ASPParameterList> ret = parameterLists.stream().filter(aspParameterList -> aspParameterList.name.equals(rs)).findAny();
|
||||
//return ret.get();
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package de.dhbwstuttgart.sat.asp.parser.model;
|
||||
|
||||
public class ParsedASPStatement {
|
||||
public ParsedASPStatement(String statement){
|
||||
|
||||
}
|
||||
}
|
12
src/de/dhbwstuttgart/sat/asp/parser/model/ParsedType.java
Normal file
12
src/de/dhbwstuttgart/sat/asp/parser/model/ParsedType.java
Normal file
@ -0,0 +1,12 @@
|
||||
package de.dhbwstuttgart.sat.asp.parser.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ParsedType {
|
||||
public final String name;
|
||||
public final List<String> params;
|
||||
public ParsedType(String name, List<String> params){
|
||||
this.name = name;
|
||||
this.params = params;
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.sat.asp.ASPStringConverter;
|
||||
import de.dhbwstuttgart.sat.asp.writer.model.*;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
@ -19,25 +21,24 @@ public class ASPGenerator {
|
||||
ASPWriter writer = new ASPWriter();
|
||||
private final String asp;
|
||||
|
||||
public ASPGenerator(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses){
|
||||
public ASPGenerator(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses) throws ClassNotFoundException {
|
||||
List<Constraint<Pair>> constraints1 = constraints.cartesianProduct().iterator().next();
|
||||
List<Pair> constraintPairs = new ArrayList<>();
|
||||
for(Constraint<Pair> constraint : constraints1){
|
||||
System.out.println(UnifyTypeFactory.convert(constraint));
|
||||
constraintPairs.addAll(constraint);
|
||||
}
|
||||
asp = toASP(constraintPairs, fcClasses);
|
||||
asp = toASP(constraintPairs, FCGenerator.toFC(fcClasses));
|
||||
}
|
||||
|
||||
public String getASP(){
|
||||
return asp;
|
||||
}
|
||||
|
||||
private String toASP(List<Pair> constraintSet, Collection<ClassOrInterface> fcClasses){
|
||||
private String toASP(List<Pair> constraintSet, Collection<Pair> fc){
|
||||
TypeConverter converter = new TypeConverter();
|
||||
for(ClassOrInterface cl : fcClasses){
|
||||
ASPType superClass = cl.getSuperClass().acceptTV(converter);
|
||||
ASPPairSmaller fcEntry = new ASPPairSmaller(convert(cl), superClass);
|
||||
for(Pair fcp : fc){
|
||||
//Wenn dieser Cast fehlschlägt stimmt etwas nicht. Alle Paare in der FC müssen smaller Operatoren haen
|
||||
ASPPairSmaller fcEntry = (ASPPairSmaller) convert(fcp);
|
||||
writer.add(new ASPStatement(fcEntry.toASP()));
|
||||
}
|
||||
for(Pair cons : constraintSet){
|
||||
@ -52,27 +53,22 @@ public class ASPGenerator {
|
||||
ASPType ls = pair.TA1.acceptTV(converter);
|
||||
ASPType rs = pair.TA2.acceptTV(converter);
|
||||
if(pair.OperatorEqual()){
|
||||
return new ASPPairEquals(ls, rs);
|
||||
return new ASPPairEquals(ls, rs,writer);
|
||||
}else if(pair.OperatorSmallerDot()){
|
||||
return new ASPPairSmallerDot(ls, rs);
|
||||
return new ASPPairSmallerDot(ls, rs, writer);
|
||||
}else if(pair.OperatorSmaller()){
|
||||
//Diese Cast müssen auch immer funktionieren, da in smaller Constraints nur RefTypes vorkommen
|
||||
return new ASPPairSmaller(new ASPFCType((ASPRefType) ls), new ASPFCType((ASPRefType) rs), writer);
|
||||
}else throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private ASPType convert(ClassOrInterface cl){
|
||||
private ASPRefType convert(ClassOrInterface cl){
|
||||
List<ASPType> paramList = new ArrayList<>();
|
||||
for(GenericTypeVar gtv : cl.getGenerics()){
|
||||
paramList.add(new ASPGenericType(toConstant(gtv.getName())));
|
||||
paramList.add(new ASPGenericType(ASPStringConverter.toConstant(gtv.getName())));
|
||||
}
|
||||
ASPParameterList params = new ASPParameterList(paramList, writer);
|
||||
return new ASPRefType(toConstant(cl.getClassName()), params);
|
||||
}
|
||||
|
||||
public static String toConstant(JavaClassName name){
|
||||
return toConstant(name.toString().replace(".", "_"));
|
||||
}
|
||||
|
||||
public static String toConstant(String name){
|
||||
return "c" + name.toString().replace(".", "_");
|
||||
return new ASPRefType(ASPStringConverter.toConstant(cl.getClassName()), params);
|
||||
}
|
||||
|
||||
private class TypeConverter implements TypeVisitor<ASPType>{
|
||||
@ -84,7 +80,7 @@ public class ASPGenerator {
|
||||
paramList.add(gtv.acceptTV(this));
|
||||
}
|
||||
ASPParameterList params = new ASPParameterList(paramList, writer);
|
||||
return new ASPRefType(toConstant(type.getName()), params);
|
||||
return new ASPRefType(ASPStringConverter.toConstant(type.getName()), params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,7 +90,7 @@ public class ASPGenerator {
|
||||
|
||||
@Override
|
||||
public ASPType visit(TypePlaceholder typePlaceholder) {
|
||||
return new ASPTypeVar(toConstant(typePlaceholder.getName()));
|
||||
return new ASPTypeVar(ASPStringConverter.toConstant(typePlaceholder.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -104,7 +100,7 @@ public class ASPGenerator {
|
||||
|
||||
@Override
|
||||
public ASPType visit(GenericRefType genericRefType) {
|
||||
return new ASPRefType(toConstant(genericRefType.getName()),
|
||||
return new ASPRefType(ASPStringConverter.toConstant(genericRefType.getName()),
|
||||
new ASPParameterList(new ArrayList<>(), writer));
|
||||
}
|
||||
}
|
||||
|
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPFCType.java
Normal file
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPFCType.java
Normal file
@ -0,0 +1,14 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
|
||||
public class ASPFCType extends ASPRefType {
|
||||
public ASPFCType(ASPRefType refType){
|
||||
super(refType.name, refType.params);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return ASPRule.ASP_FCTYPE + "(" + name +"," + params.name + ")";
|
||||
}
|
||||
}
|
@ -12,4 +12,14 @@ public class ASPGenericType implements ASPType{
|
||||
public String toString(){
|
||||
return ASPRule.ASP_GENERIC_TYPE_NAME + "(" + name + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toASP() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointer() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,20 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
|
||||
public abstract class ASPPair {
|
||||
public final ASPType leftSide;
|
||||
public final ASPType rightSide;
|
||||
|
||||
public ASPPair(ASPType ls, ASPType rs){
|
||||
public ASPPair(ASPType ls, ASPType rs, ASPWriter writer){
|
||||
this.leftSide = ls;
|
||||
this.rightSide = rs;
|
||||
writer.add(new ASPStatement(ls.toASP()));
|
||||
writer.add(new ASPStatement(rs.toASP()));
|
||||
}
|
||||
|
||||
public String toASP(){
|
||||
return this.getRuleName() + "(" + leftSide + ","+ rightSide + ")";
|
||||
return this.getRuleName() + "(" + leftSide.getPointer() + ","+ rightSide.getPointer() + ")";
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
|
@ -1,10 +1,11 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
|
||||
public class ASPPairEquals extends ASPPair{
|
||||
public ASPPairEquals(ASPType ls, ASPType rs){
|
||||
super(ls, rs);
|
||||
public ASPPairEquals(ASPType ls, ASPType rs, ASPWriter writer){
|
||||
super(ls, rs, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,12 +1,13 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ASPPairSmaller extends ASPPair{
|
||||
public ASPPairSmaller(ASPType ls, ASPType rs){
|
||||
super(ls, rs);
|
||||
public ASPPairSmaller(ASPFCType ls, ASPFCType rs, ASPWriter writer){
|
||||
super(ls, rs, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,10 +1,11 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
|
||||
public class ASPPairSmallerDot extends ASPPair{
|
||||
public ASPPairSmallerDot(ASPType ls, ASPType rs){
|
||||
super(ls, rs);
|
||||
public ASPPairSmallerDot(ASPType ls, ASPType rs, ASPWriter writer){
|
||||
super(ls, rs, writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.ASPStringConverter;
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPWriter;
|
||||
@ -30,13 +31,12 @@ public class ASPParameterList {
|
||||
writer.add(new ASPStatement(ASPRule.ASP_PARAMLIST_NAME + "(" + param + ")"));
|
||||
writer.add(new ASPStatement(ASPRule.ASP_PARAMLISTNUMERATION_NAME + "(" + name + "," +t + "," + paramNum + ")"));
|
||||
paramNum++;
|
||||
//paramDefinitions.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String newName() {
|
||||
return ASPGenerator.toConstant(NameGenerator.makeNewName());
|
||||
return ASPStringConverter.toConstant(NameGenerator.makeNewName());
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
|
@ -3,8 +3,8 @@ package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
|
||||
public class ASPRefType implements ASPType {
|
||||
private final ASPParameterList params;
|
||||
private final String name;
|
||||
protected final ASPParameterList params;
|
||||
protected final String name;
|
||||
|
||||
public ASPRefType(String name, ASPParameterList params){
|
||||
this.name = name;
|
||||
@ -18,4 +18,14 @@ public class ASPRefType implements ASPType {
|
||||
public String toString(){
|
||||
return ASPRule.ASP_TYPE + "(" + name +"," + params.name + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toASP() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointer() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
public interface ASPType {
|
||||
String toASP();
|
||||
|
||||
String getPointer();
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
|
||||
public class ASPTypeVar implements ASPType{
|
||||
private final String name;
|
||||
|
||||
@ -9,6 +11,16 @@ public class ASPTypeVar implements ASPType{
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "typeVar("+ name +")";
|
||||
return ASPRule.ASP_TYPE_VAR+"("+ name +")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toASP() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPointer() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
@ -8,8 +10,9 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.sat.asp.model.ASPRule;
|
||||
import de.dhbwstuttgart.sat.asp.parser.ASPParser;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
||||
@ -35,7 +38,7 @@ public class UnifyTypeFactory {
|
||||
Generell dürfen sie immer die gleichen Namen haben.
|
||||
TODO: die transitive Hülle bilden
|
||||
*/
|
||||
return new FiniteClosure(FCGenerator.toFC(fromClasses));
|
||||
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses));
|
||||
}
|
||||
|
||||
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
|
||||
@ -74,6 +77,16 @@ public class UnifyTypeFactory {
|
||||
}
|
||||
|
||||
public static UnifyType convert(RefType t){
|
||||
//Check if it is a FunN Type:
|
||||
Pattern p = Pattern.compile("Fun(\\d+)");
|
||||
Matcher m = p.matcher(t.getName().toString());
|
||||
boolean b = m.matches();
|
||||
if(b){
|
||||
Integer N = Integer.valueOf(m.group(1));
|
||||
if((N + 1) == t.getParaList().size()){
|
||||
return convert(new FunN(t.getParaList()));
|
||||
}
|
||||
}
|
||||
UnifyType ret;
|
||||
if(t.getParaList() != null && t.getParaList().size() > 0){
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
@ -129,10 +142,13 @@ public class UnifyTypeFactory {
|
||||
UnifyPair ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1)
|
||||
, UnifyTypeFactory.convert(p.TA2));
|
||||
return ret;
|
||||
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)){
|
||||
}else if(p.GetOperator().equals(PairOperator.EQUALSDOT)) {
|
||||
UnifyPair ret = generateEqualDotPair(UnifyTypeFactory.convert(p.TA1)
|
||||
, UnifyTypeFactory.convert(p.TA2));
|
||||
return ret;
|
||||
}else if(p.GetOperator().equals(PairOperator.SMALLER)){
|
||||
return generateSmallerPair(UnifyTypeFactory.convert(p.TA1),
|
||||
UnifyTypeFactory.convert(p.TA2));
|
||||
}else throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,17 @@ public class BinaryExpr extends Expression
|
||||
}
|
||||
|
||||
public enum Operator{
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
AND,
|
||||
OR,
|
||||
DIV,
|
||||
LESSTHAN,
|
||||
BIGGERTHAN,
|
||||
LESSEQUAL,
|
||||
BIGGEREQUAL
|
||||
ADD, // +
|
||||
SUB, // -
|
||||
MUL, // *
|
||||
MOD, // Modulo Operator %
|
||||
AND, // &&
|
||||
OR, // ||
|
||||
DIV, // /
|
||||
LESSTHAN, // <
|
||||
BIGGERTHAN, // >
|
||||
LESSEQUAL, // <=
|
||||
BIGGEREQUAL // >=
|
||||
}
|
||||
|
||||
public final Operator operation;
|
||||
|
@ -29,14 +29,17 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String params = "<";
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
||||
while(it.hasNext()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||
params += param.toString();
|
||||
if(it.hasNext())params += ", ";
|
||||
String params = "";
|
||||
if(parameter.size()>0){
|
||||
params += "<";
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> it = parameter.iterator();
|
||||
while(it.hasNext()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric param = it.next();
|
||||
params += param.toString();
|
||||
if(it.hasNext())params += ", ";
|
||||
}
|
||||
params += ">";
|
||||
}
|
||||
params += ">";
|
||||
return this.name.toString() + params;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ public class PairTPHEqualTPH extends ResultPair<TypePlaceholder, TypePlaceholder
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public class PairTPHsmallerTPH extends ResultPair{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
public void accept(ResultPairVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
||||
private final A left;
|
||||
private final B right;
|
||||
|
||||
public abstract void accept(ResultSetVisitor visitor);
|
||||
public abstract void accept(ResultPairVisitor visitor);
|
||||
|
||||
public ResultPair(A left, B right){
|
||||
this.left = left;
|
||||
|
@ -0,0 +1,7 @@
|
||||
package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
public interface ResultPairVisitor {
|
||||
void visit(PairTPHsmallerTPH p);
|
||||
void visit(PairTPHequalRefTypeOrWildcardType p);
|
||||
void visit(PairTPHEqualTPH p);
|
||||
}
|
@ -2,10 +2,7 @@ package de.dhbwstuttgart.typeinference.result;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
|
||||
public interface ResultSetVisitor {
|
||||
void visit(PairTPHsmallerTPH p);
|
||||
void visit(PairTPHequalRefTypeOrWildcardType p);
|
||||
void visit(PairTPHEqualTPH p);
|
||||
public interface ResultSetVisitor extends ResultPairVisitor{
|
||||
|
||||
void visit(RefType refType);
|
||||
|
||||
|
@ -81,11 +81,6 @@ public class TYPEStmt implements StatementVisitor{
|
||||
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Block block) {
|
||||
for(Statement stmt : block.getStatements()){
|
||||
@ -190,6 +185,8 @@ public class TYPEStmt implements StatementVisitor{
|
||||
receiver.expr.accept(this);
|
||||
}
|
||||
|
||||
private final RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), new NullToken());
|
||||
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
|
||||
@Override
|
||||
public void visit(UnaryExpr unaryExpr) {
|
||||
if(unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT ||
|
||||
@ -198,7 +195,6 @@ public class TYPEStmt implements StatementVisitor{
|
||||
unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT){
|
||||
//@see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
|
||||
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben
|
||||
RefType number = new RefType(ASTFactory.createClass(Number.class).getClassName(), unaryExpr.getOffset());
|
||||
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERDOT));
|
||||
//The type of the postfix increment expression is the type of the variable
|
||||
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT));
|
||||
@ -207,9 +203,40 @@ public class TYPEStmt implements StatementVisitor{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
if(binary.operation.equals(BinaryExpr.Operator.DIV) ||
|
||||
binary.operation.equals(BinaryExpr.Operator.MUL)||
|
||||
binary.operation.equals(BinaryExpr.Operator.MOD)||
|
||||
binary.operation.equals(BinaryExpr.Operator.ADD)){
|
||||
Set<Constraint> numericAdditionOrStringConcatenation = new HashSet<>();
|
||||
Constraint<Pair> numeric = new Constraint<>();
|
||||
//Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer:
|
||||
//see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
|
||||
//Expression muss zu Numeric Convertierbar sein. also von Numeric erben
|
||||
numeric.add(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT));
|
||||
//The type of a multiplicative expression is the promoted type of its operands.
|
||||
numeric.add(new Pair(binary.rexpr.getType(), binary.getType(), PairOperator.SMALLERDOT));
|
||||
numeric.add(new Pair(binary.lexpr.getType(), binary.getType(), PairOperator.SMALLERDOT));
|
||||
numericAdditionOrStringConcatenation.add(numeric);
|
||||
if(binary.operation.equals(BinaryExpr.Operator.ADD)) {
|
||||
//Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
|
||||
Constraint<Pair> stringConcat = new Constraint<>();
|
||||
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT));
|
||||
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT));
|
||||
stringConcat.add(new Pair(binary.getType(), string, PairOperator.EQUALSDOT));
|
||||
numericAdditionOrStringConcatenation.add(stringConcat);
|
||||
}
|
||||
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
|
||||
}else {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Literal literal) {
|
||||
//Nothing to do here. Literale kriegen beim parsen den korrekten Typ.
|
||||
//Nothing to do here. Literale erzeugen keine Constraints
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,25 +1,30 @@
|
||||
package asp;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.sat.asp.parser.ASPParser;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.Clingo;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonObject;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ClingoTest {
|
||||
public static final String rootDirectory = "~/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards";
|
||||
public static final String tempDirectory = "/tmp/";
|
||||
|
||||
private final TypePlaceholder testType = TypePlaceholder.fresh(new NullToken());
|
||||
@Test
|
||||
public void test() throws IOException, InterruptedException {
|
||||
public void test() throws IOException, InterruptedException, ClassNotFoundException {
|
||||
String content = "";
|
||||
content = new ASPGenerator(this.getPairs(), this.getFC()).getASP();
|
||||
|
||||
@ -28,19 +33,21 @@ public class ClingoTest {
|
||||
writer.close();
|
||||
|
||||
Clingo clingo = new Clingo(Arrays.asList(new File(tempDirectory + "test.lp")));
|
||||
System.out.println(clingo.runClingo());
|
||||
String result = clingo.runClingo();
|
||||
System.out.println(result);
|
||||
ResultSet resultSet = ASPParser.parse(result, Arrays.asList(testType));
|
||||
RefTypeOrTPHOrWildcardOrGeneric resolvedType = resultSet.resolveType(testType).resolvedType;
|
||||
assert resolvedType.toString().equals(ASTFactory.createObjectType().toString());
|
||||
}
|
||||
|
||||
public Collection<ClassOrInterface> getFC() {
|
||||
Set<ClassOrInterface> ret = new HashSet<>();
|
||||
ret.add(ASTFactory.createObjectClass());
|
||||
ret.add(ASTFactory.createClass(java.util.List.class));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getPairs() {
|
||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
||||
ret.addUndConstraint(new Pair(TypePlaceholder.fresh(new NullToken()), ASTFactory.createObjectType(), PairOperator.SMALLERDOT));
|
||||
ret.addUndConstraint(new Pair(testType, ASTFactory.createObjectType(), PairOperator.EQUALSDOT));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
29
test/asp/UnifyWithoutWildcards.java
Normal file
29
test/asp/UnifyWithoutWildcards.java
Normal file
@ -0,0 +1,29 @@
|
||||
package asp;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class UnifyWithoutWildcards {
|
||||
|
||||
public Collection<ClassOrInterface> getFC() {
|
||||
Set<ClassOrInterface> ret = new HashSet<>();
|
||||
ret.add(ASTFactory.createObjectClass());
|
||||
ret.add(ASTFactory.createClass(java.util.List.class));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getPairs() {
|
||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
||||
ret.addUndConstraint(new Pair(TypePlaceholder.fresh(new NullToken()), ASTFactory.createObjectType(), PairOperator.SMALLERDOT));
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -14,7 +14,9 @@ import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ASPTest {
|
||||
|
||||
@ -44,9 +46,9 @@ public class ASPTest {
|
||||
//filesToTest.add(new File(rootDirectory+"Matrix.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Import.jav"));
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
for(SourceFile sf : compiler.sourceFiles.values()) {
|
||||
//allClasses.addAll(compiler.getAvailableClasses(sf));
|
||||
allClasses.addAll(compiler.getAvailableClasses(sf));
|
||||
}
|
||||
for(SourceFile sf : compiler.sourceFiles.values()) {
|
||||
allClasses.addAll(sf.getClasses());
|
||||
|
8
test/bytecode/ATest.java
Normal file
8
test/bytecode/ATest.java
Normal file
@ -0,0 +1,8 @@
|
||||
package bytecode;
|
||||
|
||||
public class ATest extends JavaTXCompilerTest {
|
||||
public ATest() {
|
||||
fileName = "Example";
|
||||
}
|
||||
|
||||
}
|
30
test/bytecode/AssignToLit.jav
Normal file
30
test/bytecode/AssignToLit.jav
Normal file
@ -0,0 +1,30 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Boolean;
|
||||
import java.lang.String;
|
||||
import java.lang.Byte;
|
||||
import java.lang.Short;
|
||||
import java.lang.Long;
|
||||
import java.lang.Float;
|
||||
import java.lang.Double;
|
||||
import java.lang.Character;
|
||||
|
||||
class AssignToLit {
|
||||
void m(){
|
||||
// String s = "Test";
|
||||
// Boolean b = false;
|
||||
// Byte byte1 = 5;
|
||||
// Byte byte2 = 55;
|
||||
// Short short1 = 5;
|
||||
// Short short2 = 55;
|
||||
// Integer int1 = 5;
|
||||
// Integer int2 = 8888888;
|
||||
// Long long1 = 1;
|
||||
// Long long2 = 5;
|
||||
// Long long3 = 89989898;
|
||||
// Float float1 = 1;
|
||||
// Float float2 = 55;
|
||||
// Double d1 = 1;
|
||||
// Double d2 = 55;
|
||||
Character c = 'A';
|
||||
}
|
||||
}
|
7
test/bytecode/AssignToLitTest.java
Normal file
7
test/bytecode/AssignToLitTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class AssignToLitTest extends JavaTXCompilerTest {
|
||||
public AssignToLitTest() {
|
||||
this.fileName = "AssignToLit";
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
public class DuMethod{
|
||||
|
||||
method(a){
|
||||
return a;
|
||||
return a+a;
|
||||
}
|
||||
|
||||
method(a){
|
||||
|
7
test/bytecode/DuMethodTest.java
Normal file
7
test/bytecode/DuMethodTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class DuMethodTest extends JavaTXCompilerTest{
|
||||
public DuMethodTest() {
|
||||
this.fileName = "DuMethod";
|
||||
}
|
||||
}
|
9
test/bytecode/Example.jav
Normal file
9
test/bytecode/Example.jav
Normal file
@ -0,0 +1,9 @@
|
||||
import java.lang.String;
|
||||
|
||||
public class Example {
|
||||
|
||||
public m() {
|
||||
String x = "X";
|
||||
return x;
|
||||
}
|
||||
}
|
3
test/bytecode/Exceptions.jav
Normal file
3
test/bytecode/Exceptions.jav
Normal file
@ -0,0 +1,3 @@
|
||||
public class Exceptions {
|
||||
// m(Integer i) throws
|
||||
}
|
30
test/bytecode/For.jav
Normal file
30
test/bytecode/For.jav
Normal file
@ -0,0 +1,30 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Boolean;
|
||||
|
||||
class For{
|
||||
Integer m(Integer x){
|
||||
var c = x + 2;
|
||||
// Boolean b = true;
|
||||
// c = 5;
|
||||
// c++;
|
||||
// ++c;
|
||||
// c--;
|
||||
// --c;
|
||||
// while(x<2){
|
||||
// x = x +1;
|
||||
// b = false;
|
||||
// }
|
||||
return c;
|
||||
// for(int i = 0;i<10;i++) {
|
||||
// x = x + 5;
|
||||
// }
|
||||
}
|
||||
|
||||
// m2(Integer x){
|
||||
// if(x<2) {
|
||||
// return 1;
|
||||
// }else {
|
||||
// return 2;
|
||||
// }
|
||||
// }
|
||||
}
|
11
test/bytecode/ForTest.java
Normal file
11
test/bytecode/ForTest.java
Normal file
@ -0,0 +1,11 @@
|
||||
package bytecode;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class ForTest extends JavaTXCompilerTest {
|
||||
|
||||
public ForTest() {
|
||||
this.fileName = "For";
|
||||
}
|
||||
|
||||
}
|
8
test/bytecode/Import.jav
Normal file
8
test/bytecode/Import.jav
Normal file
@ -0,0 +1,8 @@
|
||||
import java.util.Vector;
|
||||
|
||||
class Import {
|
||||
void methode(){
|
||||
Vector v = new Vector<>();
|
||||
v.add("X");
|
||||
}
|
||||
}
|
7
test/bytecode/ImportTest.java
Normal file
7
test/bytecode/ImportTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class ImportTest extends JavaTXCompilerTest{
|
||||
public ImportTest() {
|
||||
this.fileName = "Import";
|
||||
}
|
||||
}
|
@ -34,17 +34,16 @@ public class JavaTXCompilerTest {
|
||||
filesToTest.add(new File(rootDirectory+fileName+".jav"));
|
||||
System.out.println(rootDirectory+fileName+".jav");
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
|
||||
System.out.println("test");
|
||||
for(File f : filesToTest){
|
||||
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
|
||||
List<ResultSet> typeinferenceResult = compiler.typeInference();
|
||||
HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0));
|
||||
|
||||
for(ResultPair ep : typeinferenceResult.get(0).results) {
|
||||
System.out.println(ep.getLeft() + " ->" + ep.getRight());
|
||||
}
|
||||
// for(ResultPair ep : typeinferenceResult.get(0).results) {
|
||||
// System.out.println(ep.getLeft() + " ->" + ep.getRight());
|
||||
// }
|
||||
|
||||
String name = "";
|
||||
String name;
|
||||
int pos = f.getName().lastIndexOf(".");
|
||||
if(pos != -1) {
|
||||
name = f.getName().substring(0, pos);
|
||||
@ -67,7 +66,7 @@ public class JavaTXCompilerTest {
|
||||
for(String name : classFiles.keySet()) {
|
||||
byte[] bytecode = classFiles.get(name);
|
||||
try {
|
||||
System.out.println("generating"+name+ ".class file");
|
||||
System.out.println("generating "+name+ ".class file ...");
|
||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
||||
output.write(bytecode);
|
||||
output.close();
|
||||
|
@ -11,5 +11,5 @@ class LamAssign {
|
||||
}
|
||||
|
||||
interface Fun1<A,B>{
|
||||
A apply(B b);
|
||||
}
|
||||
public A apply(B b);
|
||||
}
|
14
test/bytecode/Methods.jav
Normal file
14
test/bytecode/Methods.jav
Normal file
@ -0,0 +1,14 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class Methods {
|
||||
|
||||
m(a,b){
|
||||
var c=a+b;
|
||||
return c;
|
||||
}
|
||||
|
||||
method2(x){
|
||||
Integer i = this.m(x,2);
|
||||
return i;
|
||||
}
|
||||
}
|
7
test/bytecode/MethodsTest.java
Normal file
7
test/bytecode/MethodsTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class MethodsTest extends JavaTXCompilerTest {
|
||||
public MethodsTest() {
|
||||
this.fileName = "Methods";
|
||||
}
|
||||
}
|
12
test/bytecode/Op.jav
Normal file
12
test/bytecode/Op.jav
Normal file
@ -0,0 +1,12 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class Op {
|
||||
m(Integer a, Integer b) {
|
||||
Integer c = a+b;
|
||||
// d = a-b;
|
||||
// e = a*b;
|
||||
// f = a/b;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
7
test/bytecode/OpTest.java
Normal file
7
test/bytecode/OpTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class OpTest extends JavaTXCompilerTest {
|
||||
public OpTest() {
|
||||
this.fileName = "Op";
|
||||
}
|
||||
}
|
11
test/bytecode/OverlaodGen.jav
Normal file
11
test/bytecode/OverlaodGen.jav
Normal file
@ -0,0 +1,11 @@
|
||||
import java.util.Vector;
|
||||
|
||||
class OverlaodGen {
|
||||
void method(Vector<Integer> v) {
|
||||
// Integer i = v.get(0);
|
||||
}
|
||||
|
||||
void method(Vector<String> v) {
|
||||
// String s = v.get(0);
|
||||
}
|
||||
}
|
7
test/bytecode/OverlaodGenTest.java
Normal file
7
test/bytecode/OverlaodGenTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class OverlaodGenTest extends JavaTXCompilerTest {
|
||||
public OverlaodGenTest() {
|
||||
this.fileName = "OverlaodGen";
|
||||
}
|
||||
}
|
7
test/bytecode/TestIfTest.java
Normal file
7
test/bytecode/TestIfTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class TestIfTest extends JavaTXCompilerTest{
|
||||
public TestIfTest() {
|
||||
this.fileName = "IfTest";
|
||||
}
|
||||
}
|
8
test/javFiles/Expressions.jav
Normal file
8
test/javFiles/Expressions.jav
Normal file
@ -0,0 +1,8 @@
|
||||
class Expressions{
|
||||
|
||||
void test(){
|
||||
var x = 2;
|
||||
x = x + 2;
|
||||
}
|
||||
|
||||
}
|
@ -6,14 +6,10 @@ class Faculty {
|
||||
return x;
|
||||
}
|
||||
|
||||
Fun1<java.lang.Integer,java.lang.Integer> m () {
|
||||
m () {
|
||||
var fact = (Integer x) -> {
|
||||
return mul(x, fact.apply(x));
|
||||
};
|
||||
return fact;
|
||||
}
|
||||
}
|
||||
|
||||
interface Fun1<A,B>{
|
||||
B apply(A a);
|
||||
}
|
19
test/javFiles/FacultyTyped.jav
Normal file
19
test/javFiles/FacultyTyped.jav
Normal file
@ -0,0 +1,19 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class Faculty {
|
||||
|
||||
Integer mul(Integer x, Integer y) {
|
||||
return x;
|
||||
}
|
||||
|
||||
Fun1<java.lang.Integer,java.lang.Integer> m () {
|
||||
var fact = (Integer x) -> {
|
||||
return mul(x, fact.apply(x));
|
||||
};
|
||||
return fact;
|
||||
}
|
||||
}
|
||||
|
||||
interface Fun1<A,B>{
|
||||
B apply(A a);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import java.util.Vector;
|
||||
|
||||
class Vector{
|
||||
class MyVector{
|
||||
|
||||
id(x){
|
||||
return id2(x);
|
||||
|
@ -41,7 +41,8 @@ public class GeneralParserTest{
|
||||
filenames.add("FieldVarTest.jav");
|
||||
filenames.add("StructuralTypes.jav");
|
||||
*/
|
||||
filenames.add("ExtendsTest.jav");
|
||||
// filenames.add("ExtendsTest.jav");
|
||||
filenames.add("OpratorTest.jav");
|
||||
try{
|
||||
new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList()));
|
||||
}catch(Exception exc){
|
||||
|
12
test/parser/OpratorTest.jav
Normal file
12
test/parser/OpratorTest.jav
Normal file
@ -0,0 +1,12 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
class OpratorTest {
|
||||
m(Integer a, Integer b) {
|
||||
c = a+b;
|
||||
// d = a-b;
|
||||
// e = a*b;
|
||||
// f = a/b;
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FacultyTest extends JavaTXCompilerTest{
|
||||
public FacultyTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Faculty.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FiniteClosureTest extends JavaTXCompilerTest{
|
||||
public FiniteClosureTest() {
|
||||
// this.fileToTest = new File(rootDirectory+"fc.jav");
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
//TODO: Hier gibt es einen Fehler. Das erstellte ConstraintSet stimmt nicht
|
||||
public class GenericsTest extends JavaTXCompilerTest{
|
||||
public GenericsTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Generics.jav");
|
||||
}
|
||||
}
|
@ -23,19 +23,61 @@ import java.util.Set;
|
||||
public class JavaTXCompilerTest {
|
||||
|
||||
public static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/";
|
||||
private static final List<File> filesToTest = new ArrayList<>();
|
||||
protected File fileToTest = null;
|
||||
|
||||
public JavaTXCompilerTest(){
|
||||
@Test
|
||||
public void finiteClosure() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"fc.jav"));
|
||||
}
|
||||
@Test
|
||||
public void test() throws IOException, ClassNotFoundException {
|
||||
if(fileToTest != null)filesToTest.add(fileToTest);
|
||||
else return;
|
||||
//filesToTest.add(new File(rootDirectory+"Faculty.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"test.jav"));
|
||||
filesToTest.add(new File(rootDirectory+"EmptyMethod.jav"));
|
||||
public void lambda() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Lambda.jav"));
|
||||
}
|
||||
@Test
|
||||
public void lambda2() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Lambda2.jav"));
|
||||
}
|
||||
@Test
|
||||
public void lambda3() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Lambda3.jav"));
|
||||
}
|
||||
@Test
|
||||
public void mathStruc() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"mathStruc.jav"));
|
||||
}
|
||||
@Test
|
||||
public void generics() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Generics.jav"));
|
||||
}
|
||||
@Test
|
||||
public void faculty() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Faculty.jav"));
|
||||
}
|
||||
@Test
|
||||
public void facultyTyped() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"FacultyTyped.jav"));
|
||||
}
|
||||
@Test
|
||||
public void matrix() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Matrix.jav"));
|
||||
}
|
||||
@Test
|
||||
public void vector() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Vector.jav"));
|
||||
}
|
||||
@Test
|
||||
public void lambdaRunnable() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"LambdaRunnable.jav"));
|
||||
}
|
||||
@Test
|
||||
public void expressions() throws IOException, ClassNotFoundException {
|
||||
execute(new File(rootDirectory+"Expressions.jav"));
|
||||
}
|
||||
|
||||
private static class TestResultSet{
|
||||
|
||||
}
|
||||
|
||||
public TestResultSet execute(File fileToTest) throws IOException, ClassNotFoundException {
|
||||
//filesToTest.add(new File(rootDirectory+"fc.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Lambda.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
|
||||
@ -45,6 +87,9 @@ public class JavaTXCompilerTest {
|
||||
//filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Matrix.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Import.jav"));
|
||||
// //filesToTest.add(new File(rootDirectory+"Faculty.jav"));
|
||||
// //filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
|
||||
// //filesToTest.add(new File(rootDirectory+"test.jav"));
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
|
||||
for(File f : compiler.sourceFiles.keySet()){
|
||||
SourceFile sf = compiler.sourceFiles.get(f);
|
||||
@ -72,6 +117,7 @@ public class JavaTXCompilerTest {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
return new TestResultSet();
|
||||
}
|
||||
|
||||
static String readFile(String path, Charset encoding)
|
||||
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Lambda2Test extends JavaTXCompilerTest{
|
||||
public Lambda2Test() {
|
||||
this.fileToTest = new File(rootDirectory+"Lambda2.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Lambda3Test extends JavaTXCompilerTest{
|
||||
public Lambda3Test() {
|
||||
this.fileToTest = new File(rootDirectory+"Lambda3.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LambdaTest extends JavaTXCompilerTest{
|
||||
public LambdaTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Lambda.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MatrixTest extends JavaTXCompilerTest{
|
||||
public MatrixTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Matrix.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class RunnableTest extends JavaTXCompilerTest{
|
||||
public RunnableTest() {
|
||||
this.fileToTest = new File(rootDirectory+"LambdaRunnable.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class VectorTest extends JavaTXCompilerTest{
|
||||
public VectorTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Vector.jav");
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class mathStrucTest extends JavaTXCompilerTest{
|
||||
public mathStrucTest() {
|
||||
this.fileToTest = new File(rootDirectory+"mathStruc.jav");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user