Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/gast/abualia/test/JavaCompilerCore into bytecode2

This commit is contained in:
Fayez Abu Alia 2017-08-23 17:27:23 +02:00
commit 6e72bbab16
30 changed files with 527 additions and 93 deletions

22
.idea/libraries/lib.xml Normal file
View File

@ -0,0 +1,22 @@
<component name="libraryTable">
<library name="lib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/log4j-1.2.12.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/guava-10.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/bcel-6.1-SNAPSHOT.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/bcel-6.1-SNAPSHOT-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/annotations-2.0.1.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/guava-15.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/junit-4.0.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/commons-bcel6-6.0-SNAPSHOT.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/reflections-0.9.10-javadoc.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/reflections-0.9.10.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/cloning.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/javassist-3.19.0-GA.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/reflections-0.9.10-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/antlr-complete.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

9
classes/classes.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

9
doc/doc.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

11
src/JavaCompilerCore1.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -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<Statement> generateLocalVariableAssignments(List<Java8Parser.VariableDeclaratorContext> varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type){
List<Statement> 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){

View File

@ -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;

View File

@ -28,6 +28,8 @@ public class SyntaxTreeGenerator{
private String pkgName = "";
List<JavaClassName> imports = new ArrayList();
List<Statement> 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){

View File

@ -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{

View File

@ -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);

View File

@ -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) {
}
}

View File

@ -82,7 +82,7 @@ public class ClassOrInterface extends SyntaxTreeNode {
return this.genericClassParameters;
}
public List<? extends Method> getConstructors() {
public List<Constructor> getConstructors() {
return constructors;
}

View File

@ -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<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);
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);
}
}

View File

@ -53,6 +53,8 @@ public interface StatementVisitor {
void visit(WhileStmt whileStmt);
void visit(DoStmt whileStmt);
void visit(Null aNull);
void visit(Literal literal);

View File

@ -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){

View File

@ -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);
}
}

View File

@ -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;
/**
* <br/>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

View File

@ -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

View File

@ -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<EFBFBD>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;
}
}

View File

@ -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;
}
}

View File

@ -20,8 +20,9 @@ public class TypeInsert {
}
public String insert(String intoSource){
String ret = intoSource;
List<TypeInsertPoint> offsets = new ArrayList<>();
String ret = point.insert(intoSource, offsets);
offsets.add(point);
for(TypeInsertPoint insertPoint : inserts){
ret = insertPoint.insert(ret, offsets);
offsets.add(insertPoint);

View File

@ -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<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){
List<TypeInsert> ret = new ArrayList<>();
for(ClassOrInterface cl : forSourcefile.getClasses()){
//Felder:
for(Field field : cl.getFieldDecl()){
if(field.getType() instanceof TypePlaceholder){
for(Set<Pair> 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<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;
public static Set<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){
return new TypeInsertPlacer().getTypeInserts(forSourcefile, withResults);
}
private static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
Set<Pair> pairs) {
public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
Set<Pair> pairs) {
Set<TypeInsertPoint> ret = new HashSet<>();
TypeInsertPoint insertPoint = null;
Set<TypePlaceholder> 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<Pair> newGenerics = new HashSet<>();
Set<GenericInsertPair> 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<Pair> toInsert, ClassOrInterface cl, Method m){
private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> 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<TypePlaceholder, HashSet<TypePlaceholder>> genericsAndBounds = new HashMap<>();
for(Pair p : toInsert){
for(GenericInsertPair p : toInsert){
if(!genericsAndBounds.containsKey(p.TA1)){
genericsAndBounds.put((TypePlaceholder) p.TA1, new HashSet<>());
}

View File

@ -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<TypeInsert> inserts = new HashSet<>();
private ResultSet withResults;
public Set<TypeInsert> 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<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{
private final ResultSet results;
private final ClassOrInterface cl;
public final Set<TypeInsert> 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<Pair> 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
}
}

View File

@ -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<TypeInsertPoint> additionalOffset){

View File

@ -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();

View File

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

View File

@ -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));
}
}

14
test/parser/WhileTest.jav Normal file
View File

@ -0,0 +1,14 @@
class WhileTest{
void methode(){
Boolean test;
do{
test=test;
}while(test);
while(test){
test = test;
}
return;
}
}

11
test/test.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -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<TypeInsert> result = TypeInsertFactory.createTypeInsertPoints(sf, this.typeInference());
Set<TypeInsert> result = TypeInsertFactory.createTypeInsertPoints(sf, this.typeInference());
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
for(TypeInsert tip : result){
System.out.println(tip.insert(content));

9
tools/tools.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>