diff --git a/.idea/libraries/lib.xml b/.idea/libraries/lib.xml new file mode 100644 index 00000000..6a9ec091 --- /dev/null +++ b/.idea/libraries/lib.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/classes/classes.iml b/classes/classes.iml new file mode 100644 index 00000000..8021953e --- /dev/null +++ b/classes/classes.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/doc/doc.iml b/doc/doc.iml new file mode 100644 index 00000000..8021953e --- /dev/null +++ b/doc/doc.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/JavaCompilerCore1.iml b/src/JavaCompilerCore1.iml new file mode 100644 index 00000000..b107a2dd --- /dev/null +++ b/src/JavaCompilerCore1.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 58eb92de..03c72738 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -9,12 +9,11 @@ import de.dhbwstuttgart.syntaxtree.statement.literal.*; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; -import de.dhbwstuttgart.typecheck.JavaClassName; +import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typecheck.JavaClassRegistry; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; -import java.lang.reflect.Modifier; import java.util.*; public class StatementGenerator { @@ -333,8 +332,9 @@ public class StatementGenerator { } private Statement convert(Java8Parser.WhileStatementContext stmt){ - //TODO - throw new NotImplementedException(); + Expression expr = convert(stmt.expression()); + Statement block = convert(stmt.statement()); + return new WhileStmt(expr, block,stmt.getStart()); } private Statement convert(Java8Parser.WhileStatementNoShortIfContext stmt){ @@ -343,8 +343,9 @@ public class StatementGenerator { } private Statement convert(Java8Parser.DoStatementContext stmt){ - //TODO - throw new NotImplementedException(); + Statement block = convert(stmt.statement()); + Expression expr = convert(stmt.expression()); + return new DoStmt(expr,block,stmt.getStart()); } private Statement convert(Java8Parser.ForStatementContext stmt){ @@ -393,7 +394,13 @@ public class StatementGenerator { }else{ type = TypeGenerator.convert(declaration.unannTypeOrAuto().unannType(), reg, generics); } - for(Java8Parser.VariableDeclaratorContext varDecl : declaration.variableDeclaratorList().variableDeclarator()){ + ret.addAll(generateLocalVariableAssignments(declaration.variableDeclaratorList().variableDeclarator(), type)); + return ret; + } + + private List generateLocalVariableAssignments(List varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type){ + List ret = new ArrayList<>(); + for(Java8Parser.VariableDeclaratorContext varDecl : varDeclarators){ TerminalNode name = varDecl.variableDeclaratorId().Identifier(); ret.add(new LocalVarDecl(name.getText(), type, name.getSymbol())); @@ -411,6 +418,20 @@ public class StatementGenerator { return ret; } + public Statement generateFieldAssignment(Java8Parser.VariableDeclaratorContext varDecl, RefTypeOrTPHOrWildcardOrGeneric type){ + TerminalNode name = varDecl.variableDeclaratorId().Identifier(); + Expression initValue; + if(varDecl.variableInitializer().arrayInitializer() != null){ + throw new NotImplementedException(); + }else{ + initValue = convert(varDecl.variableInitializer().expression()); + } + return (new Assign( + new FieldVar(new This(varDecl.getStart()), name.getText(), + new Void(varDecl.getStart()), varDecl.getStart()), + initValue, name.getSymbol())); + } + private Statement convert(Java8Parser.ForUpdateContext stmt){ return convert(stmt.statementExpressionList()); } @@ -441,8 +462,11 @@ public class StatementGenerator { } private Statement convert(Java8Parser.ReturnStatementContext stmt){ - return new Return(convert(stmt.expression()),stmt.getStart()); - //throw new NotImplementedException(); + if(stmt.expression() != null){ + return new Return( convert(stmt.expression()),stmt.getStart()); + }else{ + return new ReturnVoid(stmt.getStart()); + } } private Statement convert(Java8Parser.ThrowStatementContext stmt){ diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntacticSugar.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntacticSugar.java index 07b2d1fb..d758f52b 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntacticSugar.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntacticSugar.java @@ -12,7 +12,8 @@ public class SyntacticSugar { Statement lastStmt = statements.get(statements.size() - 1); if (lastStmt instanceof Return) return statements; if (lastStmt instanceof WhileStmt) { - if (hasReturn(((WhileStmt) lastStmt).loop_block)) return statements; + //TODO + //if (hasReturn(((WhileStmt) lastStmt).loopBlock)) return statements; } else if (lastStmt instanceof IfStmt) { if (hasReturn(((IfStmt) lastStmt).then_block) && hasReturn(((IfStmt) lastStmt).else_block)) return statements; diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index c27a5ac8..941e7032 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -28,6 +28,8 @@ public class SyntaxTreeGenerator{ private String pkgName = ""; List imports = new ArrayList(); + List fieldInitializations = new ArrayList<>(); + public SyntaxTreeGenerator(JavaClassRegistry reg){ this.reg = reg; } @@ -232,7 +234,7 @@ public class SyntaxTreeGenerator{ if(parentClass.equals(new JavaClassName(name))){ //TODO: Constructor darf nicht Rückgabetyp void bekommen: Hier als Rückgabetyp die Klasse inklusive generische Variablen //retType = TypeGenerator.convertTypeName(name, gtvDeclarations, header.getStart(), reg, localGenerics); - return new Constructor(name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart()); + return new Constructor(name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); }else{ return new Method(name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); } @@ -315,7 +317,7 @@ public class SyntaxTreeGenerator{ ParameterList params = new ParameterList(new ArrayList<>(), offset); //TODO: Konstruktor muss Felder initialisieren: Block block = new Block(new ArrayList<>(), offset); - return new Constructor(className, classType, modifiers, params, block, classGenerics, offset); + return new Constructor(className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations); } private RefType convert(Java8Parser.SuperclassContext superclass) { @@ -385,7 +387,7 @@ public class SyntaxTreeGenerator{ for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){ String fieldName = convert(varCtx.variableDeclaratorId()); if(varCtx.variableInitializer() != null){ - initializeField(fieldDeclarationContext); + initializeField(varCtx, fieldType, generics); } else{ ret.add(new Field(fieldName,fieldType,modifiers,varCtx.getStart())); @@ -399,9 +401,9 @@ public class SyntaxTreeGenerator{ } // Initialize a field by creating implicit constructor. - private void initializeField(Java8Parser.FieldDeclarationContext ctx){ - //TODO - throw new NotImplementedException(); + private void initializeField(Java8Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics){ + StatementGenerator statementGenerator = new StatementGenerator(reg, generics, new HashMap<>()); + fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField)); } public static int convertModifier(String modifier){ diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index 605e76b5..c1f608de 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -18,6 +18,7 @@ import de.dhbwstuttgart.typecheck.JavaClassRegistry; import org.antlr.v4.runtime.Token; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class TypeGenerator { @@ -92,7 +93,7 @@ public class TypeGenerator { public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName( String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ - if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein: + if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein if(generics.keySet().contains(name)){ return new GenericRefType(new GenericTypeName(generics.get(name),name), offset); }else{ diff --git a/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java b/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java index d7527634..fde9fc83 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java +++ b/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java @@ -4,6 +4,7 @@ import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.type.*; +import de.dhbwstuttgart.typeinference.constraints.Constraint; public interface ASTVisitor extends StatementVisitor{ @@ -21,6 +22,8 @@ public interface ASTVisitor extends StatementVisitor{ void visit(Method field); + void visit(Constructor field); + void visit(ParameterList formalParameters); void visit(ClassOrInterface classOrInterface); diff --git a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index 12696edc..420b8257 100644 --- a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -9,6 +9,10 @@ import java.lang.reflect.Modifier; import java.util.Iterator; public abstract class AbstractASTWalker implements ASTVisitor{ + @Override + public void visit(Constructor cons) { + visitMethod(cons); + } @Override public void visit(SourceFile sourceFile) { @@ -24,6 +28,11 @@ public abstract class AbstractASTWalker implements ASTVisitor{ } } + @Override + public void visit(GenericTypeVar genericTypeVar) { + + } + @Override public void visit(FormalParameter formalParameter) { formalParameter.getType().accept(this); @@ -46,6 +55,10 @@ public abstract class AbstractASTWalker implements ASTVisitor{ @Override public void visit(Method method) { + visitMethod(method); + } + + private void visitMethod(Method method){ method.getType().accept(this); method.getParameterList().accept(this); method.block.accept(this); @@ -87,11 +100,21 @@ public abstract class AbstractASTWalker implements ASTVisitor{ superWildcardType.getInnerType().accept(this); } + @Override + public void visit(TypePlaceholder typePlaceholder) { + + } + @Override public void visit(ExtendsWildcardType extendsWildcardType) { extendsWildcardType.getInnerType().accept(this); } + @Override + public void visit(GenericRefType genericRefType) { + + } + @Override public void visit(LambdaExpression lambdaExpression) { lambdaExpression.params.accept(this); @@ -104,6 +127,11 @@ public abstract class AbstractASTWalker implements ASTVisitor{ assign.rightSide.accept(this); } + @Override + public void visit(Binary binary) { + + } + @Override public void visit(Block block) { for(Statement stmt : block.getStatements()){ @@ -111,11 +139,41 @@ public abstract class AbstractASTWalker implements ASTVisitor{ } } + @Override + public void visit(CastExpr castExpr) { + + } + + @Override + public void visit(EmptyStmt emptyStmt) { + + } + @Override public void visit(FieldVar fieldVar) { fieldVar.receiver.accept(this); } + @Override + public void visit(ForStmt forStmt) { + + } + + @Override + public void visit(IfStmt ifStmt) { + + } + + @Override + public void visit(InstanceOf instanceOf) { + + } + + @Override + public void visit(LocalVar localVar) { + + } + @Override public void visit(LocalVarDecl localVarDecl) { @@ -133,6 +191,11 @@ public abstract class AbstractASTWalker implements ASTVisitor{ visit((MethodCall) methodCall); } + @Override + public void visit(NewArray newArray) { + + } + @Override public void visit(Receiver receiver) { receiver.expr.accept(this); @@ -142,4 +205,49 @@ public abstract class AbstractASTWalker implements ASTVisitor{ public void visit(Return aReturn) { aReturn.retexpr.accept(this); } + + @Override + public void visit(ReturnVoid aReturn) { + + } + + @Override + public void visit(StaticClassName staticClassName) { + + } + + @Override + public void visit(Super aSuper) { + + } + + @Override + public void visit(This aThis) { + + } + + @Override + public void visit(UnaryPlus unaryPlus) { + + } + + @Override + public void visit(WhileStmt whileStmt) { + + } + + @Override + public void visit(DoStmt whileStmt) { + + } + + @Override + public void visit(Null aNull) { + + } + + @Override + public void visit(Literal literal) { + + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 1604c8c5..1733a3ac 100755 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -82,7 +82,7 @@ public class ClassOrInterface extends SyntaxTreeNode { return this.genericClassParameters; } - public List getConstructors() { + public List getConstructors() { return constructors; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 08c0ba63..219aeefe 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -1,14 +1,43 @@ package de.dhbwstuttgart.syntaxtree; +import de.dhbwstuttgart.syntaxtree.statement.Statement; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; +import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import org.antlr.v4.runtime.Token; import de.dhbwstuttgart.syntaxtree.statement.Block; +import java.util.ArrayList; +import java.util.List; + public class Constructor extends Method { - public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block block, GenericDeclarationList gtvDeclarations, Token offset) { - super(name, returnType, modifiers, parameterList, block, gtvDeclarations, offset); + /** + * Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren + */ + private final List fieldInitializations; + + public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { + super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset); + + 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 + public void accept(ASTVisitor visitor) { + visitor.visit(this); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java index 39db3ef0..cb4a5c7b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java +++ b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java @@ -53,6 +53,8 @@ public interface StatementVisitor { void visit(WhileStmt whileStmt); + void visit(DoStmt whileStmt); + void visit(Null aNull); void visit(Literal literal); diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index 7a355c60..e46eec3a 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -78,7 +78,7 @@ public class ASTFactory { Token offset = new NullToken(); int modifier = constructor.getModifiers(); - return new de.dhbwstuttgart.syntaxtree.Constructor(name,returnType, modifier, parameterList, block, gtvDeclarations, offset); + 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){ diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/DoStmt.java b/src/de/dhbwstuttgart/syntaxtree/statement/DoStmt.java new file mode 100644 index 00000000..b24396bb --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/statement/DoStmt.java @@ -0,0 +1,18 @@ +package de.dhbwstuttgart.syntaxtree.statement; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import org.antlr.v4.runtime.Token; + +public class DoStmt extends WhileStmt +{ + public DoStmt(Expression expr, Statement loopBlock, Token offset) + { + super(expr, loopBlock, offset); + } + + @Override + public void accept(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java b/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java index 351133e6..0127a505 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/WhileStmt.java @@ -2,28 +2,23 @@ package de.dhbwstuttgart.syntaxtree.statement; import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.exceptions.NotImplementedException; +import org.antlr.v4.runtime.Token; public class WhileStmt extends Statement { - public WhileStmt(int offset, int variableLength) - { - super(null,null); - } + public final Expression expr; + public final Statement loopBlock; - public Expression expr; - public Block loop_block; - - /** - *
Author: Martin Pl�micke - * @return - */ - public String toString() + public WhileStmt(Expression expr, Statement loopBlock, Token offset) { - return "WHILE " + loop_block.toString(); + super(TypePlaceholder.fresh(offset), offset); + this.expr = expr; + this.loopBlock = loopBlock; } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index 637a5ef5..0adac8a8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.syntaxtree.visual; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; @@ -86,6 +87,14 @@ public class OutputGenerator implements ASTVisitor { out.append("\n"); } + @Override + public void visit(Constructor method) { + out.append(method.getName()); + method.getParameterList().accept(this); + method.block.accept(this); + out.append("\n"); + } + @Override public void visit(ParameterList formalParameters) { out.append("("); @@ -120,6 +129,11 @@ public class OutputGenerator implements ASTVisitor { m.accept(this); out.append("\n"); } + for(Constructor m : classOrInterface.getConstructors()){ + out.append(tabs); + m.accept(this); + out.append("\n"); + } untab(); out.append("}"); } @@ -292,7 +306,19 @@ public class OutputGenerator implements ASTVisitor { @Override public void visit(WhileStmt whileStmt) { + out.append("while("); + whileStmt.expr.accept(this); + out.append(")"); + whileStmt.loopBlock.accept(this); + } + @Override + public void visit(DoStmt whileStmt) { + out.append("do "); + whileStmt.loopBlock.accept(this); + out.append("while("); + whileStmt.expr.accept(this); + out.append(");"); } @Override diff --git a/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java b/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java index 8bda1f0a..cbd66d37 100644 --- a/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java +++ b/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java @@ -1,7 +1,6 @@ package de.dhbwstuttgart.typecheck; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * Speichert die Klassen im aktuellen Projektscope @@ -17,7 +16,7 @@ public class JavaClassRegistry { } /** - * Fügt ein gesamtes Package der ClassRegistry hinzu. + * F�gt ein gesamtes Package der ClassRegistry hinzu. * Dies geschieht beispielsweise, wenn der Benutzer ein "import package.*;" statement verwendet * @param packageName */ @@ -34,19 +33,12 @@ public class JavaClassRegistry { if(name.equals(new JavaClassName(className)))return name; } //Jetzt noch alle importierten Packages durchsuchen: - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - String shortName = JavaClassName.stripClassName(className); - for(String packageName : importedPackages) { - try { - loader.loadClass(packageName+"."+shortName); - //Keine Exception! Die Klasse existiert: - JavaClassName ret = new JavaClassName(packageName+"."+shortName); - if(ret.equals(new JavaClassName(className)))return ret; - } catch (ClassNotFoundException e) { - //Die Klasse wurde nicht gefunden! - } + JavaClassName ret = getClassFromImportedPackages(className); + if(ret == null){ + throw new TypeNotPresentException(className, new Throwable()); + }else{ + return ret; } - throw new TypeNotPresentException(className, new Throwable()); } @Override @@ -55,6 +47,34 @@ public class JavaClassRegistry { } public boolean contains(String whole) { - return existingClasses.contains(new JavaClassName(whole)); + boolean ret = existingClasses.contains(new JavaClassName(whole)); + if(ret == false){ + JavaClassName imported = getClassFromImportedPackages(whole); + if(imported != null){ + existingClasses.add(imported); + return true; + }else { + return false; + } + }else { + return true; + } } + + private JavaClassName getClassFromImportedPackages(String className){ + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + String shortName = JavaClassName.stripClassName(className); + for(String packageName : importedPackages) { + try { + loader.loadClass(packageName+"."+shortName); + //Keine Exception! Die Klasse existiert: + JavaClassName ret = new JavaClassName(packageName+"."+shortName); + if(ret.equals(new JavaClassName(className)))return ret; + } catch (ClassNotFoundException e) { + //Die Klasse wurde nicht gefunden! + } + } + return null; + } + } diff --git a/src/de/dhbwstuttgart/typedeployment/GenericInsertPair.java b/src/de/dhbwstuttgart/typedeployment/GenericInsertPair.java new file mode 100644 index 00000000..9377c063 --- /dev/null +++ b/src/de/dhbwstuttgart/typedeployment/GenericInsertPair.java @@ -0,0 +1,26 @@ +package de.dhbwstuttgart.typedeployment; + +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.constraints.Pair; + +public class GenericInsertPair { + public TypePlaceholder TA1; + public TypePlaceholder TA2; + + public GenericInsertPair(TypePlaceholder additionalTPH, TypePlaceholder superType) { + TA1 = additionalTPH; + TA2 = superType; + } + + public GenericInsertPair(Pair pair) { + TA1 = (TypePlaceholder) pair.TA1; + TA2 = (TypePlaceholder) pair.TA2; + } + + public boolean contains(TypePlaceholder additionalTPH) { + if(TA1.equals(additionalTPH))return true; + if(TA2.equals(additionalTPH))return true; + return false; + } +} diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsert.java b/src/de/dhbwstuttgart/typedeployment/TypeInsert.java index 0bd42b39..4756e49f 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsert.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsert.java @@ -20,8 +20,9 @@ public class TypeInsert { } public String insert(String intoSource){ - String ret = intoSource; List offsets = new ArrayList<>(); + String ret = point.insert(intoSource, offsets); + offsets.add(point); for(TypeInsertPoint insertPoint : inserts){ ret = insertPoint.insert(ret, offsets); offsets.add(insertPoint); diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index 2c7c6791..13c2f152 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typedeployment; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.*; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.constraints.Pair; @@ -25,36 +26,14 @@ import java.util.*; * inferieren, wenn A bereits eingesetzt wurde. Es werden dann eben zusätzliche Generics entstehen */ public class TypeInsertFactory { - public static List createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){ - List ret = new ArrayList<>(); - for(ClassOrInterface cl : forSourcefile.getClasses()){ - //Felder: - for(Field field : cl.getFieldDecl()){ - if(field.getType() instanceof TypePlaceholder){ - for(Set pairs : withResults.results) - ret.add(createInsertPoints( - field.getType(), field.getType().getOffset(), cl, null, pairs)); - } - } - for(Method m : cl.getMethods()){ - if(m.getReturnType() instanceof TypePlaceholder)for(Set 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 pairs : withResults.results) - ret.add(createInsertPoints( - param.getType(), param.getType().getOffset(), cl, m, pairs)); - } - } - } - return ret; + public static Set createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){ + return new TypeInsertPlacer().getTypeInserts(forSourcefile, withResults); } - private static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, - Set pairs) { + public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, + Set pairs) { Set ret = new HashSet<>(); TypeInsertPoint insertPoint = null; Set additionalInserts = new HashSet<>(); @@ -84,29 +63,32 @@ public class TypeInsertFactory { insertPoint = new TypeInsertPoint(offset, ((TypePlaceholder) type).getName()); additionalInserts.add(((TypePlaceholder) type)); } + //Alle Bounds finden: - Set newGenerics = new HashSet<>(); + Set newGenerics = new HashSet<>(); boolean added = true; while(added){ + //Fügt alle TPHs an, welche mit den additionalInserts in Verbindung stehen. added = false; for(Pair pair : pairs){ if (additionalInserts.contains(pair.TA1) || additionalInserts.contains(pair.TA2)) { - newGenerics.add(pair); + newGenerics.add(new GenericInsertPair(pair)); added |= additionalInserts.add((TypePlaceholder) pair.TA1); added |= additionalInserts.add((TypePlaceholder) pair.TA2); } } } - //Alle TPHs die man noch als Generics anfügen muss einsetzen: - additionalInserts.clear(); - for(Pair subtypings : newGenerics){ - if(additionalInserts.contains(subtypings.TA1)){ - additionalInserts.remove(subtypings.TA1); + //Fügt noch die Additional Inserts an, welche mit nichts in Verbindung stehen: + for(TypePlaceholder additionalTPH : additionalInserts){ + boolean inside = false; + for(GenericInsertPair p :newGenerics){ + if(p.contains(additionalTPH)){ + inside = true; + break; + } } - } - for(TypePlaceholder tph : additionalInserts){ - newGenerics.add(new Pair(tph, null)); + if(! inside)newGenerics.add(new GenericInsertPair(additionalTPH, null)); } ret.add(createGenericInsert(newGenerics, cl, m)); @@ -139,7 +121,7 @@ public class TypeInsertFactory { return insert; } - private static TypeInsertPoint createGenericInsert(Set toInsert, ClassOrInterface cl, Method m){ + private static TypeInsertPoint createGenericInsert(Set toInsert, ClassOrInterface cl, Method m){ //Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt: //Offset zum Einstzen bestimmen: Token offset; @@ -157,7 +139,7 @@ public class TypeInsertFactory { //Alle einzusetzenden Generics und deren Bounds bestimmen: HashMap> genericsAndBounds = new HashMap<>(); - for(Pair p : toInsert){ + for(GenericInsertPair p : toInsert){ if(!genericsAndBounds.containsKey(p.TA1)){ genericsAndBounds.put((TypePlaceholder) p.TA1, new HashSet<>()); } diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java new file mode 100644 index 00000000..88e7ad68 --- /dev/null +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java @@ -0,0 +1,99 @@ +package de.dhbwstuttgart.typedeployment; + +import de.dhbwstuttgart.syntaxtree.*; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.ResultSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class TypeInsertPlacer extends AbstractASTWalker{ + Set inserts = new HashSet<>(); + private ResultSet withResults; + + public Set getTypeInserts(SourceFile forSourceFile, ResultSet withResults){ + this.withResults = withResults; + forSourceFile.accept(this); + return inserts; + } + + @Override + public void visit(ClassOrInterface classOrInterface) { + TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults); + this.inserts.addAll(cl.inserts); + } + + /* + List 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 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 pairs : withResults.results) + ret.add(createInsertPoints( + param.getType(), param.getType().getOffset(), cl, m, pairs)); + } + } + } + return ret; + */ +} + +class TypeInsertPlacerClass extends AbstractASTWalker{ + private final ResultSet results; + private final ClassOrInterface cl; + public final Set inserts = new HashSet<>(); + + TypeInsertPlacerClass(ClassOrInterface forClass, ResultSet withResults){ + this.cl = forClass; + this.results = withResults; + forClass.accept(this); + } + + @Override + public void visit(Method method) { + TypeInsertPlacerMethod mWalker = new TypeInsertPlacerMethod(method); + super.visit(method); + } + + @Override + public void visit(Field field) { + if(field.getType() instanceof TypePlaceholder){ + for(Set pairs : results.results) + inserts.add(TypeInsertFactory.createInsertPoints( + field.getType(), field.getType().getOffset(), cl, null, pairs)); + } + super.visit(field); + } +} + +class TypeInsertPlacerMethod extends AbstractASTWalker{ + TypeInsertPlacerMethod(Method forMethod){ + forMethod.accept(this); + } + + @Override + public void visit(ParameterList params) { + super.visit(params); + } + + @Override + public void visit(LambdaExpression lambdaExpression) { + //Lambda-Ausdrücke brauchen keine Typeinsetzungen + } + +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertPoint.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertPoint.java index bc649413..816628e6 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertPoint.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertPoint.java @@ -11,7 +11,7 @@ public class TypeInsertPoint { public TypeInsertPoint(Token point, String toInsert){ this.point = point; - this.insertString = (toInsert.length()>1) ? toInsert + " " : toInsert; + this.insertString = (toInsert.endsWith(" ")) ? toInsert : toInsert + " " ; } public String insert(String intoSource, List additionalOffset){ diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java index ccb70002..646222eb 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java @@ -204,6 +204,11 @@ public class TYPE implements StatementVisitor{ throw new NotImplementedException(); } + @Override + public void visit(DoStmt whileStmt) { + throw new NotImplementedException(); + } + @Override public void visit(Null aNull) { throw new NotImplementedException(); diff --git a/test/javFiles/mathStruc.jav b/test/javFiles/mathStruc.jav index 2e0620fb..45121c5e 100644 --- a/test/javFiles/mathStruc.jav +++ b/test/javFiles/mathStruc.jav @@ -1,5 +1,8 @@ + class mathStruc { +a = new mathStruc(); + mathStruc(A a) { } A model(){ A a; return a; } diff --git a/test/parser/RunParserTest.java b/test/parser/RunParserTest.java index 3028ef3d..f1c63434 100644 --- a/test/parser/RunParserTest.java +++ b/test/parser/RunParserTest.java @@ -1,6 +1,8 @@ package parser; import de.dhbwstuttgart.parser.JavaTXParser; +import de.dhbwstuttgart.syntaxtree.SourceFile; +import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter; import org.junit.Test; import java.io.File; @@ -14,7 +16,8 @@ public class RunParserTest { @Test public void testMain() throws Exception { String[] args = new String[1]; - args[0] = rootDirectory+"ImportTest2.jav"; - new JavaTXParser().parse(new File(args[0])); + args[0] = rootDirectory+"WhileTest.jav"; + SourceFile sf = new JavaTXParser().parse(new File(args[0])); + System.out.println(ASTPrinter.print(sf)); } } \ No newline at end of file diff --git a/test/parser/WhileTest.jav b/test/parser/WhileTest.jav new file mode 100644 index 00000000..2ce192bd --- /dev/null +++ b/test/parser/WhileTest.jav @@ -0,0 +1,14 @@ +class WhileTest{ + void methode(){ + Boolean test; + do{ + test=test; + }while(test); + + + while(test){ + test = test; + } + return; + } +} \ No newline at end of file diff --git a/test/test.iml b/test/test.iml new file mode 100644 index 00000000..a6c28e92 --- /dev/null +++ b/test/test.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index dbd924a4..a129b13e 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -22,6 +22,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.junit.Assert.*; @@ -44,7 +45,7 @@ public class JavaTXCompilerTest extends JavaTXCompiler { for(File f : filesToTest){ SourceFile sf = this.parse(f); System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1))); - List result = TypeInsertFactory.createTypeInsertPoints(sf, this.typeInference()); + Set result = TypeInsertFactory.createTypeInsertPoints(sf, this.typeInference()); String content = readFile(f.getPath(), StandardCharsets.UTF_8); for(TypeInsert tip : result){ System.out.println(tip.insert(content)); diff --git a/tools/tools.iml b/tools/tools.iml new file mode 100644 index 00000000..8021953e --- /dev/null +++ b/tools/tools.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file