Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2

This commit is contained in:
Fayez Abu Alia 2017-08-30 14:43:31 +02:00
commit 866429ffe7
27 changed files with 576 additions and 452 deletions

View File

@ -14,6 +14,7 @@ import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
@ -29,15 +30,13 @@ public class JavaTXCompiler {
protected List<SourceFile> sourceFiles = new ArrayList<>(); protected List<SourceFile> sourceFiles = new ArrayList<>();
public ResultSet typeInference(){ public ResultSet typeInference(){
ConstraintSet<Pair> cons = new ConstraintSet<>();
List<ClassOrInterface> allClasses = new ArrayList<>(); List<ClassOrInterface> allClasses = new ArrayList<>();
for(SourceFile sf : sourceFiles){ for(SourceFile sf : sourceFiles){
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
} }
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
for(SourceFile sf : sourceFiles){ ConstraintSet<Pair> cons = new ConstraintSet<>();
cons.addAll(sf.getConstraints(sf.getTypeInferenceInformation(sourceFiles))); cons = new TYPE(sourceFiles).getConstraints();
}
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
TypeUnify unify = new TypeUnify(); TypeUnify unify = new TypeUnify();

View File

@ -0,0 +1,20 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
public class AssignToLocal extends AssignLeftSide {
public final LocalVar localVar;
public AssignToLocal(LocalVar leftSide) {
super(leftSide.getType(), leftSide.getOffset());
localVar = leftSide;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -288,12 +288,15 @@ public class StatementGenerator {
} }
private Statement convert(Java8Parser.AssignmentContext stmt) { private Statement convert(Java8Parser.AssignmentContext stmt) {
Expression leftHandSide = convert(stmt.leftHandSide()); AssignLeftSide leftHandSide = convert(stmt.leftHandSide());
return new Assign(leftHandSide, convert(stmt.expression()), stmt.getStart()); return new Assign(leftHandSide, convert(stmt.expression()), stmt.getStart());
} }
private Expression convert(Java8Parser.LeftHandSideContext leftHandSide) { private AssignLeftSide convert(Java8Parser.LeftHandSideContext leftHandSide) {
return generateLocalOrFieldVarOrClassName(leftHandSide.getText(), leftHandSide.getStart()); Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide.getText(), leftHandSide.getStart());
if(leftSide instanceof FieldVar)return new AssignToField((FieldVar) leftSide);
else if (leftSide instanceof LocalVar)return new AssignToLocal((LocalVar) leftSide);
else throw new NotImplementedException();
} }
private Statement convert(Java8Parser.IfThenStatementContext stmt){ private Statement convert(Java8Parser.IfThenStatementContext stmt){
@ -412,7 +415,8 @@ public class StatementGenerator {
}else{ }else{
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
ret.add(new Assign(new LocalVar(name.getText(), type, name.getSymbol()), initValue, name.getSymbol())); ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getSymbol()))
, initValue, name.getSymbol()));
} }
} }
return ret; return ret;
@ -426,9 +430,9 @@ public class StatementGenerator {
}else{ }else{
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
return (new Assign( return (new Assign(new AssignToField(
new FieldVar(new This(varDecl.getStart()), name.getText(), new FieldVar(new This(varDecl.getStart()), name.getText(),
new Void(varDecl.getStart()), varDecl.getStart()), new Void(varDecl.getStart()), varDecl.getStart())),
initValue, name.getSymbol())); initValue, name.getSymbol()));
} }

View File

@ -290,7 +290,7 @@ public class SyntaxTreeGenerator{
if(ctx.superclass() != null){ if(ctx.superclass() != null){
superClass = convert(ctx.superclass()); superClass = convert(ctx.superclass());
}else{ }else{
superClass = new ASTFactory(reg).createObjectClass().getType(); superClass = ASTFactory.createObjectClass().getType();
} }
Boolean isInterface = false; Boolean isInterface = false;
List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = convert(ctx.superinterfaces(), generics); List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = convert(ctx.superinterfaces(), generics);
@ -474,7 +474,7 @@ public class SyntaxTreeGenerator{
}else{ }else{
genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); genericParams = createEmptyGenericDeclarationList(ctx.Identifier());
} }
RefType superClass = new ASTFactory(reg).createObjectClass().getType(); RefType superClass = ASTFactory.createObjectClass().getType();
List<RefTypeOrTPHOrWildcardOrGeneric> extendedInterfaces = convert(ctx.extendsInterfaces(), generics); List<RefTypeOrTPHOrWildcardOrGeneric> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);

View File

@ -76,7 +76,7 @@ public class TypeGenerator {
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
if(typeBoundContext == null){ if(typeBoundContext == null){
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
ret.add(new ASTFactory(reg).createObjectClass().getType()); ret.add(ASTFactory.createObjectClass().getType());
return ret; return ret;
} }

View File

@ -1,5 +1,7 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
@ -61,7 +63,8 @@ public abstract class AbstractASTWalker implements ASTVisitor{
private void visitMethod(Method method){ private void visitMethod(Method method){
method.getType().accept(this); method.getType().accept(this);
method.getParameterList().accept(this); method.getParameterList().accept(this);
method.block.accept(this); if(method.block != null)
method.block.accept(this);
} }
@Override @Override
@ -250,4 +253,14 @@ public abstract class AbstractASTWalker implements ASTVisitor{
public void visit(Literal literal) { public void visit(Literal literal) {
} }
@Override
public void visit(AssignToField assignLeftSide) {
assignLeftSide.field.accept(this);
}
@Override
public void visit(AssignToLocal assignLeftSide) {
assignLeftSide.localVar.accept(this);
}
} }

View File

@ -58,14 +58,6 @@ public class ClassOrInterface extends SyntaxTreeNode {
return this.methods; return this.methods;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
for(Method m : this.getMethods()){
ret.addAll(m.getConstraints(info, this));
}
return ret;
}
public RefType getType() { public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
} }

View File

@ -6,6 +6,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Block;
@ -19,7 +20,7 @@ public class Constructor extends Method {
/** /**
* Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren * Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren
*/ */
private final List<Statement> fieldInitializations; public final List<Statement> fieldInitializations;
public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) { public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset); super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset);
@ -27,15 +28,6 @@ public class Constructor extends Method {
this.fieldInitializations = fieldInitializations; this.fieldInitializations = fieldInitializations;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) {
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null);
TYPE methodScope = new TYPE(blockInfo);
for(Statement stmt : fieldInitializations)stmt.accept(methodScope);
ConstraintSet ret = super.getConstraints(info, currentClass);
ret.addAll(methodScope.getConstraints());
return ret;
}
@Override @Override
public void accept(ASTVisitor visitor) { public void accept(ASTVisitor visitor) {
visitor.visit(this); visitor.visit(this);

View File

@ -8,6 +8,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
@ -36,14 +37,6 @@ public class Method extends Field implements IItemWithOffset, TypeScope
this.generics = gtvDeclarations; this.generics = gtvDeclarations;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) {
if(block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, this);
TYPE methodScope = new TYPE(blockInfo);
block.accept(methodScope);
return methodScope.getConstraints();
}
public ParameterList getParameterList() { public ParameterList getParameterList() {
return parameterlist; return parameterlist;
} }

View File

@ -13,8 +13,8 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
public class SourceFile extends SyntaxTreeNode{ public class SourceFile extends SyntaxTreeNode{
private String pkgName; private String pkgName;
private final List<ClassOrInterface> KlassenVektor; public final List<ClassOrInterface> KlassenVektor;
private final List<JavaClassName> imports; public final List<JavaClassName> imports;
/** /**
* Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
@ -36,23 +36,6 @@ public class SourceFile extends SyntaxTreeNode{
return this.imports; return this.imports;
} }
public ConstraintSet getConstraints(TypeInferenceInformation info) {
ConstraintSet ret = new ConstraintSet();
for (ClassOrInterface cl : this.KlassenVektor) {
ret.addAll(cl.getConstraints(info));
}
return ret;
}
public TypeInferenceInformation getTypeInferenceInformation(List<SourceFile> sourceFiles){
Set<ClassOrInterface> classes = new HashSet<>();
for(SourceFile sourceFile : sourceFiles){
classes.addAll(sourceFile.KlassenVektor);
}
return new TypeInferenceInformation(classes);
}
public List<ClassOrInterface> getClasses() { public List<ClassOrInterface> getClasses() {
return KlassenVektor; return KlassenVektor;
} }

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
@ -58,4 +59,8 @@ public interface StatementVisitor {
void visit(Null aNull); void visit(Null aNull);
void visit(Literal literal); void visit(Literal literal);
void visit(AssignToField assignLeftSide);
void visit(AssignToLocal assignLeftSide);
} }

View File

@ -25,15 +25,9 @@ import org.antlr.v4.runtime.Token;
* dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen. * dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen.
*/ */
public class ASTFactory { public class ASTFactory {
private final JavaClassRegistry names;
public static ClassOrInterface createClass(java.lang.Class jreClass){
public ASTFactory(JavaClassRegistry scope){ JavaClassName name = new JavaClassName(jreClass.getName());
names = scope;
}
public ClassOrInterface createClass(java.lang.Class jreClass){
JavaClassName name = names.getName(jreClass.getName());
List<Method> methoden = new ArrayList<>(); List<Method> methoden = new ArrayList<>();
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>(); List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){ for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
@ -63,13 +57,13 @@ public class ASTFactory {
return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset); return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
} }
private de.dhbwstuttgart.syntaxtree.Constructor createConstructor(Constructor constructor, Class inClass) { private static de.dhbwstuttgart.syntaxtree.Constructor createConstructor(Constructor constructor, Class inClass) {
String name = constructor.getName(); String name = constructor.getName();
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass, names.getName(inClass.getName()), name); RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass, new JavaClassName(inClass.getName()), name);
Parameter[] jreParams = constructor.getParameters(); Parameter[] jreParams = constructor.getParameters();
List<FormalParameter> params = new ArrayList<>(); List<FormalParameter> params = new ArrayList<>();
for(Parameter jreParam : jreParams){ for(Parameter jreParam : jreParams){
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),names.getName(inClass.getName()), name); RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),new JavaClassName(inClass.getName()), name);
params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken())); params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken()));
} }
ParameterList parameterList = new ParameterList(params, new NullToken()); ParameterList parameterList = new ParameterList(params, new NullToken());
@ -81,14 +75,14 @@ public class ASTFactory {
return new de.dhbwstuttgart.syntaxtree.Constructor(name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); return new de.dhbwstuttgart.syntaxtree.Constructor(name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>());
} }
public Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName(); String name = jreMethod.getName();
RefTypeOrTPHOrWildcardOrGeneric returnType; RefTypeOrTPHOrWildcardOrGeneric returnType;
returnType = createType(jreMethod.getReturnType(),names.getName(inClass.getName()), name); returnType = createType(jreMethod.getReturnType(),new JavaClassName(inClass.getName()), name);
Parameter[] jreParams = jreMethod.getParameters(); Parameter[] jreParams = jreMethod.getParameters();
List<FormalParameter> params = new ArrayList<>(); List<FormalParameter> params = new ArrayList<>();
for(Parameter jreParam : jreParams){ for(Parameter jreParam : jreParams){
RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),names.getName(inClass.getName()), name); RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),new JavaClassName(inClass.getName()), name);
params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken())); params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken()));
} }
ParameterList parameterList = new ParameterList(params, new NullToken()); ParameterList parameterList = new ParameterList(params, new NullToken());
@ -100,7 +94,7 @@ public class ASTFactory {
return new Method(name,returnType, modifier, parameterList, block, gtvDeclarations, offset); return new Method(name,returnType, modifier, parameterList, block, gtvDeclarations, offset);
} }
public GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){ public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>(); List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
for(TypeVariable jreTV : typeParameters){ for(TypeVariable jreTV : typeParameters){
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName); de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
@ -120,23 +114,23 @@ public class ASTFactory {
} }
*/ */
public RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type, JavaClassName parentClass, String parentMethod){ public static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type, JavaClassName parentClass, String parentMethod){
if(type.getTypeName().equals("void")){ if(type.getTypeName().equals("void")){
return new Void(new NullToken()); return new Void(new NullToken());
}else if(type.getTypeName().equals("int")){ }else if(type.getTypeName().equals("int")){
return new RefType(this.names.getName("java.lang.Integer"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("byte")){ }else if(type.getTypeName().equals("byte")){
return new RefType(this.names.getName("java.lang.Byte"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("boolean")){ }else if(type.getTypeName().equals("boolean")){
return new RefType(this.names.getName("java.lang.Boolean"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("char")){ }else if(type.getTypeName().equals("char")){
return new RefType(this.names.getName("java.lang.Char"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("short")){ }else if(type.getTypeName().equals("short")){
return new RefType(this.names.getName("java.lang.Short"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("double")){ }else if(type.getTypeName().equals("double")){
return new RefType(this.names.getName("java.lang.Double"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken());
}else if(type.getTypeName().equals("long")){ }else if(type.getTypeName().equals("long")){
return new RefType(this.names.getName("java.lang.Long"), new ArrayList<>(), new NullToken()); return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken());
}else{ }else{
if(type instanceof TypeVariable){ if(type instanceof TypeVariable){
//GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()" //GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()"
@ -150,13 +144,13 @@ public class ASTFactory {
params.add(createType(t, parentClass, parentMethod)); params.add(createType(t, parentClass, parentMethod));
} }
} }
RefType ret = new RefType(this.names.getName(type.getTypeName()), params, new NullToken()); RefType ret = new RefType(new JavaClassName(type.getTypeName()), params, new NullToken());
return ret; return ret;
} }
} }
public de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){ public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){
JavaClassName parentClass = names.getName(context.getName()); JavaClassName parentClass = new JavaClassName(context.getName());
List<RefType> genericBounds = new ArrayList<>(); List<RefType> genericBounds = new ArrayList<>();
java.lang.reflect.Type[] bounds = jreTypeVar.getBounds(); java.lang.reflect.Type[] bounds = jreTypeVar.getBounds();
if(bounds.length > 0){ if(bounds.length > 0){
@ -169,8 +163,8 @@ public class ASTFactory {
, genericBounds, new NullToken(), new NullToken()); , genericBounds, new NullToken(), new NullToken());
} }
public ClassOrInterface createObjectClass() { public static ClassOrInterface createObjectClass() {
return this.createClass(Object.class); return createClass(Object.class);
} }
/* /*

View File

@ -8,13 +8,16 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
/*
Aufbau:
rightSide = leftSide
*/
public class Assign extends Statement public class Assign extends Statement
{ {
public final Expression rightSide; public final Expression rightSide;
public final Expression lefSide; public final AssignLeftSide lefSide;
public Assign(Expression leftHandSide, Expression value, Token offset) { public Assign(AssignLeftSide leftHandSide, Expression value, Token offset) {
super(leftHandSide.getType(), offset); super(leftHandSide.getType(), offset);
this.rightSide = value; this.rightSide = value;
this.lefSide = leftHandSide; this.lefSide = leftHandSide;

View File

@ -0,0 +1,12 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
public abstract class AssignLeftSide extends TypableStatement{
public AssignLeftSide(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
}
}

View File

@ -0,0 +1,16 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
public class AssignToField extends AssignLeftSide{
public final FieldVar field;
public AssignToField(FieldVar fieldVar) {
super(fieldVar.getType(), fieldVar.getOffset());
field = fieldVar;
}
@Override
public void accept(StatementVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -9,24 +9,9 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
public abstract class Expression extends SyntaxTreeNode public abstract class Expression extends TypableStatement
{ {
private RefTypeOrTPHOrWildcardOrGeneric type;
public Expression(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){ public Expression(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){
super(offset); super(type, offset);
if(type == null)throw new NullPointerException();
this.type = type;
}
public RefTypeOrTPHOrWildcardOrGeneric getType(){
return type;
}
public abstract void accept(StatementVisitor visitor);
@Override
public void accept(ASTVisitor visitor) {
this.accept((StatementVisitor)visitor);
} }
} }

View File

@ -0,0 +1,28 @@
package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token;
public abstract class TypableStatement extends SyntaxTreeNode{
private RefTypeOrTPHOrWildcardOrGeneric type;
public TypableStatement(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){
super(offset);
if(type == null)throw new NullPointerException();
this.type = type;
}
public RefTypeOrTPHOrWildcardOrGeneric getType(){
return type;
}
public abstract void accept(StatementVisitor visitor);
@Override
public void accept(ASTVisitor visitor) {
this.accept((StatementVisitor)visitor);
}
}

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.syntaxtree.visual; package de.dhbwstuttgart.syntaxtree.visual;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
@ -83,7 +84,8 @@ public class OutputGenerator implements ASTVisitor {
method.getType().accept(this); method.getType().accept(this);
out.append(" " + method.getName()); out.append(" " + method.getName());
method.getParameterList().accept(this); method.getParameterList().accept(this);
method.block.accept(this); if(method.block != null)
method.block.accept(this);
out.append("\n"); out.append("\n");
} }
@ -330,4 +332,14 @@ public class OutputGenerator implements ASTVisitor {
public void visit(Literal literal) { public void visit(Literal literal) {
} }
@Override
public void visit(AssignToField assignLeftSide) {
assignLeftSide.field.accept(this);
}
@Override
public void visit(AssignToLocal assignLeftSide) {
assignLeftSide.localVar.accept(this);
}
} }

View File

@ -15,13 +15,9 @@ public class GenericTypeName extends JavaClassName {
this.methodName = genericContext.parentMethod; this.methodName = genericContext.parentMethod;
} }
public String toString(){ public String getUniqueIdentifier() {
return parentClass.toString() return parentClass.toString()
+ DELIMITER + methodName + DELIMITER + methodName
+ DELIMITER + super.toString(); + DELIMITER + super.toString();
} }
public String getShortName() {
return super.toString();
}
} }

View File

@ -1,15 +1,12 @@
package de.dhbwstuttgart.typedeployment; package de.dhbwstuttgart.typedeployment;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.lang.reflect.Type;
import java.util.*; import java.util.*;
/** /**
@ -59,9 +56,15 @@ public class TypeInsertFactory {
} }
} }
} }
if(insertPoint == null){ //Dann muss es ein TPH sein, welcher nicht im Result auftaucht if(insertPoint == null ){ //Dann muss es ein TPH sein, welcher nicht im Result auftaucht
insertPoint = new TypeInsertPoint(offset, ((TypePlaceholder) type).getName()); if(type instanceof TypePlaceholder){
additionalInserts.add(((TypePlaceholder) type)); insertPoint = new TypeInsertPoint(offset, ((TypePlaceholder) type).getName());
additionalInserts.add(((TypePlaceholder) type));
}else if(type instanceof GenericRefType){
insertPoint = new TypeInsertPoint(offset, ((GenericRefType) type).getName().toString());
}else if(type instanceof RefType){
insertPoint = new TypeInsertPoint(offset, ((RefType) type).getName().toString());
}else throw new NotImplementedException();
} }
//Alle Bounds finden: //Alle Bounds finden:
@ -90,8 +93,8 @@ public class TypeInsertFactory {
} }
if(! inside)newGenerics.add(new GenericInsertPair(additionalTPH, null)); if(! inside)newGenerics.add(new GenericInsertPair(additionalTPH, null));
} }
if(newGenerics.size() > 0)
ret.add(createGenericInsert(newGenerics, cl, m)); ret.add(createGenericInsert(newGenerics, cl, m));
//return ret; //return ret;
return new TypeInsert(insertPoint, ret); return new TypeInsert(insertPoint, ret);

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.typedeployment; package de.dhbwstuttgart.typedeployment;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
@ -26,36 +27,11 @@ public class TypeInsertPlacer extends AbstractASTWalker{
TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults); TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults);
this.inserts.addAll(cl.inserts); this.inserts.addAll(cl.inserts);
} }
/*
List<TypeInsert> ret = new ArrayList<>();
for(ClassOrInterface cl : forSourcefile.getClasses()){
//Felder:
for(Field field : cl.getFieldDecl()){
}
for(Method m : cl.getMethods()){
if(m.getReturnType() instanceof TypePlaceholder)for(Set<Pair> pairs : withResults.results) {
ret.add(createInsertPoints(
m.getReturnType(), m.getReturnType().getOffset(), cl, m, pairs));
}
for(FormalParameter param : m.getParameterList().getFormalparalist()){
if(param.getType() instanceof TypePlaceholder)for(Set<Pair> pairs : withResults.results)
ret.add(createInsertPoints(
param.getType(), param.getType().getOffset(), cl, m, pairs));
}
}
}
return ret;
*/
} }
class TypeInsertPlacerClass extends AbstractASTWalker{ class TypeInsertPlacerClass extends AbstractASTWalker{
private final ResultSet results; protected final ResultSet results;
private final ClassOrInterface cl; protected final ClassOrInterface cl;
public final Set<TypeInsert> inserts = new HashSet<>(); public final Set<TypeInsert> inserts = new HashSet<>();
TypeInsertPlacerClass(ClassOrInterface forClass, ResultSet withResults){ TypeInsertPlacerClass(ClassOrInterface forClass, ResultSet withResults){
@ -66,7 +42,9 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
@Override @Override
public void visit(Method method) { public void visit(Method method) {
TypeInsertPlacerMethod mWalker = new TypeInsertPlacerMethod(method); for(Set<Pair> pairs : results.results)
inserts.add(TypeInsertFactory.createInsertPoints(
method.getReturnType(), method.getReturnType().getOffset(), cl, null, pairs));
super.visit(method); super.visit(method);
} }
@ -79,15 +57,14 @@ class TypeInsertPlacerClass extends AbstractASTWalker{
} }
super.visit(field); super.visit(field);
} }
}
class TypeInsertPlacerMethod extends AbstractASTWalker{
TypeInsertPlacerMethod(Method forMethod){
forMethod.accept(this);
}
@Override @Override
public void visit(ParameterList params) { public void visit(ParameterList params) {
for(FormalParameter param : params){
for(Set<Pair> pairs : results.results)
inserts.add(TypeInsertFactory.createInsertPoints(
param.getType(), param.getType().getOffset(), cl, null, pairs));
}
super.visit(params); super.visit(params);
} }
@ -95,5 +72,4 @@ class TypeInsertPlacerMethod extends AbstractASTWalker{
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
//Lambda-Ausdrücke brauchen keine Typeinsetzungen //Lambda-Ausdrücke brauchen keine Typeinsetzungen
} }
}
}

View File

@ -1,307 +1,77 @@
package de.dhbwstuttgart.typeinference.typeAlgo; package de.dhbwstuttgart.typeinference.typeAlgo;
//import com.sun.org.apache.xpath.internal.Arg; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class TYPE implements StatementVisitor{ public class TYPE {
private final TypeInferenceBlockInformation info; private final List<SourceFile> sfs;
private final ConstraintSet constraintsSet = new ConstraintSet();
public TYPE(TypeInferenceBlockInformation info){ public TYPE(List<SourceFile> sourceFiles){
this.info = info; sfs = sourceFiles;
} }
public ConstraintSet getConstraints() { public ConstraintSet getConstraints() {
return constraintsSet; ConstraintSet ret = new ConstraintSet();
} TypeInferenceInformation info = getTypeInferenceInformation();
for(SourceFile sf : sfs)
@Override for (ClassOrInterface cl : sf.KlassenVektor) {
public void visit(LambdaExpression lambdaExpression) { ret.addAll(getConstraintsClass(cl ,info));
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
//lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT,info));
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getReturnType(),
tphRetType,info));
//Constraints des Bodys generieren:
TYPE lambdaScope = new TYPE(new TypeInferenceBlockInformation(info, lambdaExpression));
lambdaExpression.methodBody.accept(lambdaScope);
constraintsSet.addAll(lambdaScope.getConstraints());
}
@Override
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info));
}
@Override
public void visit(Binary binary) {
throw new NotImplementedException();
}
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()){
stmt.accept(this);
}
}
@Override
public void visit(CastExpr castExpr) {
throw new NotImplementedException();
}
@Override
public void visit(EmptyStmt emptyStmt) {
//Nothing :)
}
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint();
constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info));
constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info));
oderConstraints.add(constraint);
}
if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
}
@Override
public void visit(ForStmt forStmt) {
throw new NotImplementedException();
}
@Override
public void visit(IfStmt ifStmt) {
throw new NotImplementedException();
}
@Override
public void visit(InstanceOf instanceOf) {
throw new NotImplementedException();
}
@Override
public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig
}
@Override
public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
}
@Override
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
methodConstraints.add(generateConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewClass methodCall) {
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){
methodConstraints.add(generateConstructorConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewArray newArray) {
throw new NotImplementedException();
}
@Override
public void visit(Receiver receiver) {
receiver.expr.accept(this);
}
@Override
public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(ReturnVoid aReturn) {
visit((Return) aReturn);
}
@Override
public void visit(StaticClassName staticClassName) {
throw new NotImplementedException();
}
@Override
public void visit(Super aSuper) {
throw new NotImplementedException();
}
@Override
public void visit(This aThis) {
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(UnaryPlus unaryPlus) {
throw new NotImplementedException();
}
@Override
public void visit(WhileStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(DoStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(Null aNull) {
throw new NotImplementedException();
}
@Override
public void visit(Literal literal) {
throw new NotImplementedException();
}
/*
METHOD CALL Section:
*/
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info));
return methodConstraint;
}
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) {
Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){
ret.add(ConstraintsFactory.createPair(foMethod.arglist.getArguments().get(i).getType(),
assumption.getArgTypes().get(i), PairOperator.SMALLERDOT, info));
} }
return ret; return ret;
} }
private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) {
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { ConstraintSet ret = new ConstraintSet();
List<MethodAssumption> ret = new ArrayList<>(); for(Method m : cl.getMethods()){
if(name.equals("apply")){ ret.addAll(getConstraintsMethod(m,info, cl));
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
funNParams.add(TypePlaceholder.fresh(new NullToken()));
}
ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size())));
} }
for(ClassOrInterface cl : info.getAvailableClasses()){ for(Constructor m : cl.getConstructors()){
for(Method m : cl.getMethods()){ ret.addAll(getConstraintsConstructor(m,info, cl));
if(m.getName().equals(name) && }
m.getParameterList().getFormalparalist().size() == numArgs){ return ret;
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); }
ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info))); private TypeInferenceInformation getTypeInferenceInformation() {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Set<ClassOrInterface> classes = new HashSet<>();
for(SourceFile sourceFile : sfs){
for(JavaClassName importName : sourceFile.imports){
System.out.println(importName);
try {
classes.add(ASTFactory.createClass(classLoader.loadClass(importName.toString())));
} catch (ClassNotFoundException e) {
throw new DebugException("Klasse " + importName + " konnte nicht geladen werden");
} }
} }
classes.addAll(sourceFile.KlassenVektor);
} }
return new TypeInferenceInformation(classes);
}
private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) {
if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m);
TYPEStmt methodScope = new TYPEStmt(blockInfo);
m.block.accept(methodScope);
return methodScope.getConstraints();
}
private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) {
TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null);
TYPEStmt methodScope = new TYPEStmt(blockInfo);
for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope);
ConstraintSet ret = this.getConstraintsMethod(m, info, currentClass);
ret.addAll(methodScope.getConstraints());
return ret; return ret;
} }
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(info.checkGTV(fp.getType()));
}
return params;
}
public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) {
TYPE ret = new TYPE(info);
for(int i = 0;i<forMethod.arglist.getArguments().size();i++){
forMethod.arglist.getArguments().get(i).accept(ret);
}
return ret.constraintsSet;
}
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){
if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info)));
}
}
}
}
return ret;
}
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info));
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info));
return methodConstraint;
}
} }

View File

@ -0,0 +1,322 @@
package de.dhbwstuttgart.typeinference.typeAlgo;
//import com.sun.org.apache.xpath.internal.Arg;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class TYPEStmt implements StatementVisitor{
private final TypeInferenceBlockInformation info;
private final ConstraintSet constraintsSet = new ConstraintSet();
public TYPEStmt(TypeInferenceBlockInformation info){
this.info = info;
}
public ConstraintSet getConstraints() {
return constraintsSet;
}
@Override
public void visit(LambdaExpression lambdaExpression) {
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
//lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT,info));
constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getReturnType(),
tphRetType,info));
//Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
lambdaExpression.methodBody.accept(lambdaScope);
constraintsSet.addAll(lambdaScope.getConstraints());
}
@Override
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info));
}
@Override
public void visit(Binary binary) {
throw new NotImplementedException();
}
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()){
stmt.accept(this);
}
}
@Override
public void visit(CastExpr castExpr) {
throw new NotImplementedException();
}
@Override
public void visit(EmptyStmt emptyStmt) {
//Nothing :)
}
@Override
public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint();
constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info));
constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info));
oderConstraints.add(constraint);
}
if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
}
@Override
public void visit(ForStmt forStmt) {
throw new NotImplementedException();
}
@Override
public void visit(IfStmt ifStmt) {
throw new NotImplementedException();
}
@Override
public void visit(InstanceOf instanceOf) {
throw new NotImplementedException();
}
@Override
public void visit(LocalVar localVar) {
// Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig
}
@Override
public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
}
@Override
public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this);
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){
methodConstraints.add(generateConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewClass methodCall) {
constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info));
//Overloading:
Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){
methodConstraints.add(generateConstructorConstraint(methodCall, m, info));
}
if(methodConstraints.size()<1){
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset());
}
constraintsSet.addOderConstraint(methodConstraints);
}
@Override
public void visit(NewArray newArray) {
throw new NotImplementedException();
}
@Override
public void visit(Receiver receiver) {
receiver.expr.accept(this);
}
@Override
public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(ReturnVoid aReturn) {
visit((Return) aReturn);
}
@Override
public void visit(StaticClassName staticClassName) {
throw new NotImplementedException();
}
@Override
public void visit(Super aSuper) {
throw new NotImplementedException();
}
@Override
public void visit(This aThis) {
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info));
}
@Override
public void visit(UnaryPlus unaryPlus) {
throw new NotImplementedException();
}
@Override
public void visit(WhileStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(DoStmt whileStmt) {
throw new NotImplementedException();
}
@Override
public void visit(Null aNull) {
throw new NotImplementedException();
}
@Override
public void visit(Literal literal) {
throw new NotImplementedException();
}
@Override
public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
@Override
public void visit(AssignToLocal assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
}
/*
METHOD CALL Section:
*/
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info));
return methodConstraint;
}
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) {
Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){
ret.add(ConstraintsFactory.createPair(foMethod.arglist.getArguments().get(i).getType(),
assumption.getArgTypes().get(i), PairOperator.SMALLERDOT, info));
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>();
if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
funNParams.add(TypePlaceholder.fresh(new NullToken()));
}
ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size())));
}
for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){
if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info)));
}
}
}
return ret;
}
public static List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
return getMethods(name, arglist.getArguments().size(), info);
}
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){
params.add(info.checkGTV(fp.getType()));
}
return params;
}
public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) {
TYPEStmt ret = new TYPEStmt(info);
for(int i = 0;i<forMethod.arglist.getArguments().size();i++){
forMethod.arglist.getArguments().get(i).accept(ret);
}
return ret.constraintsSet;
}
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){
if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info)));
}
}
}
}
return ret;
}
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){
Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info));
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info));
return methodConstraint;
}
}

8
test/javFiles/Import.jav Normal file
View File

@ -0,0 +1,8 @@
import java.util.Vector;
class Import {
void methode(){
Vector v;
v.add(v);
}
}

View File

@ -1,14 +1,13 @@
class Matrix extends Menge<Menge<Integer>> { import java.util.Vector;
class Matrix extends Vector<Vector<Integer>> {
Matrix mul_rec(Matrix m) { Matrix mul_rec(Matrix m) {
v1; auto v1 = new Vector<Integer>();
v1 = new Menge<Integer>(); auto v2 = new Vector<Integer>();
v2; auto i = 0;
v2 = new Menge<Integer>();
i;
i = 0;
while(i < m.size()) { while(i < m.size()) {
v; auto v;
v = m.elementAt(i); v = m.elementAt(i);
v2.addElement(v.remove(v.size()-1)); v2.addElement(v.remove(v.size()-1));
i++; i++;
@ -21,14 +20,14 @@ class Matrix extends Menge<Menge<Integer>> {
ret = new Matrix(); ret = new Matrix();
i = 0; i = 0;
while (i < this.size()) { while (i < this.size()) {
ret.addElement(new Menge<Integer>()); ret.addElement(new Vector<Integer>());
i++; i++;
} }
} }
i = 0; i = 0;
while (i < this.size()) { while (i < this.size()) {
int erg = 0; int erg = 0;
j; auto j;
j = 0; j = 0;
while (j < v2.size()) { while (j < v2.size()) {
erg = erg + this.elementAt(i).elementAt(j).intValue() erg = erg + this.elementAt(i).elementAt(j).intValue()

View File

@ -1,8 +1,6 @@
class mathStruc<A> { class mathStruc<A> {
a = new mathStruc<String>();
mathStruc(A a) { } mathStruc(A a) { }
A model(){ A a; return a; } A model(){ A a; return a; }

View File

@ -42,6 +42,7 @@ public class JavaTXCompilerTest extends JavaTXCompiler {
//filesToTest.add(new File(rootDirectory+"Generics.jav")); //filesToTest.add(new File(rootDirectory+"Generics.jav"));
//filesToTest.add(new File(rootDirectory+"MethodsEasy.jav")); //filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
//filesToTest.add(new File(rootDirectory+"Matrix.jav")); //filesToTest.add(new File(rootDirectory+"Matrix.jav"));
//filesToTest.add(new File(rootDirectory+"Import.jav"));
for(File f : filesToTest){ for(File f : filesToTest){
SourceFile sf = this.parse(f); SourceFile sf = this.parse(f);
System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1))); System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1)));