diff --git a/src/mycompiler/myclass/Class.java b/src/mycompiler/myclass/Class.java index 957112849..97692dac1 100755 --- a/src/mycompiler/myclass/Class.java +++ b/src/mycompiler/myclass/Class.java @@ -10,6 +10,7 @@ import java.util.Iterator; import java.util.Vector; import mycompiler.AClassOrInterface; +import mycompiler.IItemWithOffset; import mycompiler.SyntaxTreeNode; import mycompiler.mybytecode.ClassFile; import mycompiler.myexception.CTypeReconstructionException; @@ -60,6 +61,7 @@ import org.apache.log4j.Logger; + import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.ConstraintsSet; import typinferenz.JavaCodeResult; @@ -75,7 +77,7 @@ import typinferenz.*; // ino.class.Class.23010.declaration -public class Class extends SyntaxTreeNode implements AClassOrInterface +public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset // ino.end // ino.class.Class.23010.body { @@ -1209,7 +1211,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface public void createGenericTypeVars(Vector tphs){ this.genericClassParameters = new Vector(); for(TypePlaceholder tph : tphs){ - GenericTypeVar toAdd = new GenericTypeVar(tph); + GenericTypeVar toAdd = new GenericTypeVar(tph,this.getOffset()); if(!this.genericClassParameters.contains(toAdd))this.genericClassParameters.add(toAdd); } } @@ -1225,7 +1227,7 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface if(pair.TA2 instanceof TypePlaceholder && pair.TA1 instanceof TypePlaceholder){// if(pair.OperatorSmallerExtends() || pair.OperatorSmaller()){ Type ta1=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA1); Type ta2=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA2); - this.genericClassParameters.add(new GenericTypeVar(new Pair(ta1,ta2))); + this.genericClassParameters.add(new GenericTypeVar(new Pair(ta1,ta2),this.getOffset())); } /* // Auf SuperWildcardTypes überprüfen: @@ -1239,14 +1241,19 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface for(Pair pair : reconstructionResult.getConstraints()){ if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA1)){ - this.genericClassParameters.add(new GenericTypeVar(pair.TA1)); + this.genericClassParameters.add(new GenericTypeVar(pair.TA1,this.getOffset())); } if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA2)){ - this.genericClassParameters.add(new GenericTypeVar(pair.TA2)); + this.genericClassParameters.add(new GenericTypeVar(pair.TA2, this.getOffset())); } } } + public int getOffset(){ + //TODO: richtiges Offset: + return 0; + } + /** * Erstellt einen RefType, welcher auf diese Klasse verweist * Ersetzt alle Generischen Variablen in der Parameterliste mit TPH @@ -1346,5 +1353,10 @@ public class Class extends SyntaxTreeNode implements AClassOrInterface public String getDescription(){ return "class "+this.getName(); } + @Override + public int getVariableLength() { + // TODO Auto-generated method stub + return 0; + } } // ino.end diff --git a/src/mycompiler/myclass/Field.java b/src/mycompiler/myclass/Field.java index 4d5620d11..c736a3514 100644 --- a/src/mycompiler/myclass/Field.java +++ b/src/mycompiler/myclass/Field.java @@ -103,7 +103,7 @@ public abstract class Field extends SyntaxTreeNode implements TypeInsertable, Ty @Override public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph, ResultSet resultSet) { - return new TypeInsertPoint(tph, this, resultSet.getTypeEqualTo(tph), resultSet); + return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph), resultSet); } /** diff --git a/src/mycompiler/myclass/FormalParameter.java b/src/mycompiler/myclass/FormalParameter.java index ee1d9d869..06aabbcd6 100755 --- a/src/mycompiler/myclass/FormalParameter.java +++ b/src/mycompiler/myclass/FormalParameter.java @@ -259,7 +259,7 @@ public class FormalParameter extends SyntaxTreeNode implements ITypeReplacementL public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph, ResultSet resultSet) { if(this.getOffset()<=0)return null; - return new TypeInsertPoint(tph, this, resultSet.getTypeEqualTo(tph), resultSet); + return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph), resultSet); } diff --git a/src/mycompiler/mystatement/LambdaExpression.java b/src/mycompiler/mystatement/LambdaExpression.java index 1df56c084..b2df8159d 100755 --- a/src/mycompiler/mystatement/LambdaExpression.java +++ b/src/mycompiler/mystatement/LambdaExpression.java @@ -197,6 +197,7 @@ public class LambdaExpression extends Expr{ public Vector getChildren() { Vector ret = new Vector(); ret.add(this.method_body); + for(FormalParameter fp : this.params)ret.add(fp); return ret; } diff --git a/src/mycompiler/mystatement/LocalVarDecl.java b/src/mycompiler/mystatement/LocalVarDecl.java index 370360d77..a96de1d06 100755 --- a/src/mycompiler/mystatement/LocalVarDecl.java +++ b/src/mycompiler/mystatement/LocalVarDecl.java @@ -515,7 +515,7 @@ public class LocalVarDecl extends Statement implements TypeInsertable @Override public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph, ResultSet resultSet) { - return new TypeInsertPoint(tph, this, resultSet.getTypeEqualTo(tph),resultSet); + return new TypeInsertPoint(this, resultSet.getTypeEqualTo(tph),resultSet); } } // ino.end diff --git a/src/mycompiler/mytype/BoundedGenericTypeVar.java b/src/mycompiler/mytype/BoundedGenericTypeVar.java index c8bbdc175..4d2bd011d 100755 --- a/src/mycompiler/mytype/BoundedGenericTypeVar.java +++ b/src/mycompiler/mytype/BoundedGenericTypeVar.java @@ -5,6 +5,8 @@ package mycompiler.mytype; // ino.module.BoundedGenericTypeVar.8669.import import java.util.Vector; + +import sun.reflect.generics.reflectiveObjects.NotImplementedException; // ino.end // ino.class.BoundedGenericTypeVar.26464.description type=javadoc @@ -39,6 +41,7 @@ public class BoundedGenericTypeVar extends GenericTypeVar // ino.method.BoundedGenericTypeVar.26471.body { super(s, offset); + throw new NotImplementedException(); } // ino.end @@ -49,6 +52,7 @@ public class BoundedGenericTypeVar extends GenericTypeVar { super(s, offset); this.bounds = bounds; + throw new NotImplementedException(); } // ino.end diff --git a/src/mycompiler/mytype/GenericTypeVar.java b/src/mycompiler/mytype/GenericTypeVar.java index db7249833..b8139dbd1 100755 --- a/src/mycompiler/mytype/GenericTypeVar.java +++ b/src/mycompiler/mytype/GenericTypeVar.java @@ -10,9 +10,14 @@ import java.util.Vector; + + +import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; +import typinferenz.TypeInsertPoint; +import typinferenz.TypeInsertable; // ino.class.GenericTypeVar.26505.description type=javadoc @@ -42,8 +47,8 @@ public class GenericTypeVar extends Type * * @param genericTypeVarExtendsVar */ - public GenericTypeVar(Pair genericTypeVarExtendsVar){ - super(0); + public GenericTypeVar(Pair genericTypeVarExtendsVar, int offset){ + super(offset); genericTypeVar = genericTypeVarExtendsVar; this.name = genericTypeVar.toString(); } @@ -58,8 +63,8 @@ public class GenericTypeVar extends Type } // ino.end - public GenericTypeVar(Type tA1) { - this(new Pair(tA1,null)); + public GenericTypeVar(Type tA1, int offset) { + this(new Pair(tA1,null),offset); } // ino.method.clone.26512.defdescription type=javadoc @@ -77,7 +82,8 @@ public class GenericTypeVar extends Type } // ino.end - // ino.method.equals.26515.defdescription type=javadoc + + // ino.method.equals.26515.defdescription type=javadoc /** *
Author: J�rg B�uerle * @param obj @@ -146,10 +152,10 @@ public class GenericTypeVar extends Type } public TypePlaceholder getTypePlaceHolder() { - if(!this.tph.containsKey(this)){ - this.tph.put(this, TypePlaceholder.fresh()); + if(!GenericTypeVar.tph.containsKey(this)){ + GenericTypeVar.tph.put(this, TypePlaceholder.fresh()); } - return this.tph.get(this); + return GenericTypeVar.tph.get(this); //if(this.tph == null)this.tph = TypePlaceholder.fresh(); //return this.tph; } diff --git a/src/mycompiler/mytype/RefType.java b/src/mycompiler/mytype/RefType.java index d6b7e4243..1096dd282 100755 --- a/src/mycompiler/mytype/RefType.java +++ b/src/mycompiler/mytype/RefType.java @@ -19,9 +19,11 @@ import org.apache.log4j.Logger; + import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; +import typinferenz.TypeInsertable; @@ -260,7 +262,9 @@ public class RefType extends Type implements IMatchable return getName(); } - // ino.method.getName.26658.definition + + + // ino.method.getName.26658.definition public String getName() // ino.end // ino.method.getName.26658.body @@ -611,7 +615,7 @@ public class RefType extends Type implements IMatchable // ino.end // ino.method.modifyToGenericTypeVar.26694.definition - public GenericTypeVar modifyToGenericTypeVar() + public GenericTypeVar modifyToGenericTypeVar(TypeInsertable parent) // ino.end // ino.method.modifyToGenericTypeVar.26694.body { @@ -742,6 +746,19 @@ public class RefType extends Type implements IMatchable } return ret; } + + @Override + public Vector getUnresolvedTPH(ResultSet resultSet) { + Vector ret = super.getUnresolvedTPH(resultSet); + if(this.parameter!=null)for(Type t : this.parameter){ + if(t instanceof TypePlaceholder){ + TypePlaceholder tph = (TypePlaceholder)t; + Type eq = resultSet.getTypeEqualTo(tph); + if(eq instanceof TypePlaceholder)ret.add((TypePlaceholder)eq); + } + } + return ret; + } } // ino.end diff --git a/src/mycompiler/mytype/Type.java b/src/mycompiler/mytype/Type.java index 15b23b94d..261d5e799 100755 --- a/src/mycompiler/mytype/Type.java +++ b/src/mycompiler/mytype/Type.java @@ -8,6 +8,7 @@ import java.util.Vector; import typinferenz.JavaCodeResult; import typinferenz.ResultSet; import mycompiler.IItemWithOffset; +import mycompiler.SyntaxTreeNode; import mycompiler.mybytecode.JVMCode; import mycompiler.myclass.UsedId; // ino.end @@ -58,6 +59,10 @@ public class Type implements IItemWithOffset } // ino.end + public void setOffset(int offset){ + this.offset = offset; + } + // ino.method.getVariableLength.26738.definition public int getVariableLength() // ino.end @@ -254,6 +259,15 @@ public class Type implements IItemWithOffset if(this instanceof SuperWildcardType)ret.add((SuperWildcardType)this); return ret; } + + /** + * Sucht nach TPHs in diesem Typ, denen das resultSet keinen Typ zuordnen kann. + * @param resultSet + * @return + */ + public Vector getUnresolvedTPH(ResultSet resultSet) { + return new Vector(); + } } // ino.end diff --git a/src/mycompiler/mytype/TypePlaceholder.java b/src/mycompiler/mytype/TypePlaceholder.java index 3dcf4fd68..142f1bd95 100755 --- a/src/mycompiler/mytype/TypePlaceholder.java +++ b/src/mycompiler/mytype/TypePlaceholder.java @@ -534,6 +534,16 @@ public class TypePlaceholder extends Type implements IReplaceTypeEventProvider } return ret; } + + @Override + public Vector getUnresolvedTPH(ResultSet resultSet) { + Vector ret = super.getUnresolvedTPH(resultSet); + Type t = resultSet.getTypeEqualTo(this); + if(t instanceof TypePlaceholder){ + ret.add((TypePlaceholder)t); + } + return ret; + } } // ino.end diff --git a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java index 1eeef9998..14fe034f9 100755 --- a/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java +++ b/src/mycompiler/mytypereconstruction/TypeinferenceResultSet.java @@ -57,7 +57,7 @@ public class TypeinferenceResultSet // ino.end // ino.method.CTypeReconstructionResult.27256.body { - this.ownerOfResultSet = inferedClass; + this.ownerOfResultSet = inferedClass; this.constraints = constraints; this.unifiedConstraints = unifiedConstraints; } @@ -108,7 +108,7 @@ public class TypeinferenceResultSet } /** - * Berechnet alle möglichen Punkte zum Einsetzen eines Typs im Quelltext an der Stelle dieses TypePlaceholders + * Berechnet alle möglichen Punkte zum Einsetzen eines Typs im Quelltext * @return */ public Vector getTypeInsertionPoints(){ diff --git a/src/typinferenz/ResultSet.java b/src/typinferenz/ResultSet.java index ac4ab89df..df133c87a 100755 --- a/src/typinferenz/ResultSet.java +++ b/src/typinferenz/ResultSet.java @@ -5,6 +5,7 @@ import java.util.Vector; import mycompiler.mytype.Pair; import mycompiler.mytype.Type; +import mycompiler.mytype.TypePlaceholder; /** * Im Grunde Sammlung von Pair s mit Equal-Operatoren. @@ -75,4 +76,29 @@ public class ResultSet implements Iterable { public boolean equals(Object obj){ return true; } + + + /** + * Sammelt alle Constraints, welche mit den übergebenen TPH's in Verbindung stehen. + * Auch alle Constraints, welche wiederum mit den gesammelten Constraints in Verbindung stehen werden gesammelt. + * @return + */ + public Vector getConstraintsFor(Vector typePlaceholders) { + Vector ret = new Vector(); + Vector tphs = (Vector) typePlaceholders.clone(); + for(int i = 0;i{ - private TypePlaceholder tph; - private TypeInsertable point; + private IItemWithOffset point; private Type type; private ResultSet resultSet; - public TypeInsertPoint(TypePlaceholder tph, TypeInsertable insertPoint, Type insertType, ResultSet resultSet){ - this.tph = tph; + public TypeInsertPoint(IItemWithOffset insertPoint, Type insertType, ResultSet resultSet){ this.point = insertPoint; this.type = insertType; this.resultSet = resultSet; @@ -24,15 +34,15 @@ public class TypeInsertPoint implements Comparable{ * @param additionalOffset - Falls mehrere Typen in einen Quellcode eingesetzet werden muss die Verschiebung der Offsets mit einbezogen werden. * @return */ - public String insertType(String fileContent, int additionalOffset) { + public JavaCodeResult insertType(String fileContent, int additionalOffset) { String anfang = fileContent.substring(0, point.getOffset()+additionalOffset); - String mitte = this.getTypeInsertString(); + JavaCodeResult mitte = this.getTypeInsertString(); String ende = fileContent.substring(point.getOffset()+additionalOffset); - return anfang + mitte + ende; + return new JavaCodeResult(anfang).attach(mitte).attach(ende); } public int getInsertLength() { - return this.getTypeInsertString().length(); + return this.getTypeInsertString().toString().length(); } /** @@ -47,15 +57,15 @@ public class TypeInsertPoint implements Comparable{ * Die Zeichenkette die durch diesen TypeInsertPoint eingesetzt wird. (Der Typ als String) * @return */ - public String getTypeInsertString(){ - String ret = type.printJavaCode(this.resultSet).toString()+" "; + public JavaCodeResult getTypeInsertString(){ + JavaCodeResult ret = type.printJavaCode(this.resultSet).attach(" "); return ret; } /** * @return - Der Punkt (Knoten) im Syntaxbaum, für den dieser TypeInsertPoint gilt. */ - public TypeInsertable getInsertNode(){ + public IItemWithOffset getInsertNode(){ return this.point; } @@ -64,7 +74,6 @@ public class TypeInsertPoint implements Comparable{ if(! (obj instanceof TypeInsertPoint))return false; TypeInsertPoint equals = (TypeInsertPoint) obj; if(!(equals.point.equals(this.point)))return false; - if(!(equals.tph.equals(this.tph)))return false; if(!(equals.resultSet.equals(this.resultSet)))return false; if(!(equals.type.equals(this.type)))return false; @@ -75,4 +84,23 @@ public class TypeInsertPoint implements Comparable{ public int compareTo(TypeInsertPoint arg0) { return new Integer(this.getOffset()).compareTo(new Integer(arg0.getOffset())); } + + public ResultSet getResultSet() { + return resultSet; + } + + public IItemWithOffset getGenericTypeVarInsertNode() { + if(! (this.point instanceof SyntaxTreeNode)){ + throw new DebugException("Ein IItemWithOffset muss immer auch ein SyntaxTreeNode sein"); + } + SyntaxTreeNode ret = (SyntaxTreeNode)this.point; + while(!(ret instanceof Field || ret instanceof Class)){ + ret = ret.getParent(); + if(ret == null){ + throw new DebugException(this.point.toString()+" hat kein Feld oder Klasse als Elternelement"); + } + } + return (IItemWithOffset)ret; + } + } diff --git a/src/typinferenz/TypeInsertSet.java b/src/typinferenz/TypeInsertSet.java index 6509fa6d6..c732dbe86 100644 --- a/src/typinferenz/TypeInsertSet.java +++ b/src/typinferenz/TypeInsertSet.java @@ -1,9 +1,14 @@ package typinferenz; import java.util.Collections; +import java.util.Iterator; import java.util.Vector; import mycompiler.SyntaxTreeNode; +import mycompiler.mytype.GenericTypeVar; +import mycompiler.mytype.Pair; +import mycompiler.mytype.RefType; +import mycompiler.mytype.TypePlaceholder; /** * Bündelt ein Set von TypeInsertPoints, die alle zu einem TypePlaceholder gehören. @@ -32,12 +37,47 @@ public class TypeInsertSet { * @return */ public String insertAllTypes(String fileContent) { + int additionalOffset = 0; String ret = fileContent; Collections.sort(points); for(TypeInsertPoint p : points){ - ret = p.insertType(ret, additionalOffset); + /* + //TODO: Verbessern. Momentan noch komischer Hack: + //Kontrollieren ob beim Einsetzen Generische Typvariablen entstehen: + Iterator it = p.getUnresolvedPairs().iterator(); + String genericTypeParameters = "<"; + while(it.hasNext()){ + genericTypeParameters += new GenericTypeVar(it.next(), 0).printJavaCode(p.getResultSet()); + if(it.hasNext())genericTypeParameters += ", "; + } + genericTypeParameters += ">"; + //HACK: Reftype mit dem Typ der einzusetzenden Generischen Variablen: + TypeInsertPoint tip = new TypeInsertPoint(p.getGenericTypeVarInsertNode(), new RefType(genericTypeParameters,0), p.getResultSet()); + //ret = tip.insertType(fileContent, additionalOffset); + //additionalOffset += tip.getInsertLength(); + */ + + //Zuerst den Typ einsetzen + JavaCodeResult insertCode = p.insertType(ret, additionalOffset); + ret = insertCode.toString(); + //Das additional Offset noch nicht korrigieren, da die generischen Parameter noch vor den Typ müssen. + + //Jetzt sind die übriggebliebenen TPHs bekannt und die benötigten Generischen Variablen können berechnet werden. + Iterator it = p.getResultSet().getConstraintsFor(insertCode.getUnresolvedTPH()).iterator(); + String genericTypeParameters = "<"; + while(it.hasNext()){ + genericTypeParameters += new GenericTypeVar(it.next(), 0).printJavaCode(p.getResultSet()); + if(it.hasNext())genericTypeParameters += ", "; + } + genericTypeParameters += ">"; + //Der Generische Variablen String zum Einsetzen ist nun vorhanden + TypeInsertPoint tip = new TypeInsertPoint(p.getGenericTypeVarInsertNode(), new RefType(genericTypeParameters,0), p.getResultSet()); + ret = tip.insertType(insertCode.toString(), additionalOffset).toString(); + //Jetzt das gesamte Offset korrigieren: + additionalOffset += tip.getInsertLength(); additionalOffset += p.getInsertLength(); + } return ret; } diff --git a/src/typinferenz/exceptions/DebugException.java b/src/typinferenz/exceptions/DebugException.java new file mode 100644 index 000000000..b7c082d3e --- /dev/null +++ b/src/typinferenz/exceptions/DebugException.java @@ -0,0 +1,7 @@ +package typinferenz.exceptions; + +public class DebugException extends RuntimeException { + + public DebugException(String message) { + } +} diff --git a/src/typinferenz/exceptions/TypeinferenceException.java b/src/typinferenz/exceptions/TypeinferenceException.java index 676496003..46e763ebe 100755 --- a/src/typinferenz/exceptions/TypeinferenceException.java +++ b/src/typinferenz/exceptions/TypeinferenceException.java @@ -28,4 +28,16 @@ public class TypeinferenceException extends RuntimeException { this.message=message; } + /** + * + * @return Der Offset an dem im Quellcode der Fehler aufgetreten ist. + */ + public int getOffset(){ + return offset; + } + + public String getMessage(){ + return this.message; + } + } diff --git a/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.jav b/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.jav new file mode 100644 index 000000000..3f552dbca --- /dev/null +++ b/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.jav @@ -0,0 +1,3 @@ +class GenericVarInsertTest{ + op = (m) -> (f) -> f; +} \ No newline at end of file diff --git a/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.java b/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.java new file mode 100644 index 000000000..453e46e71 --- /dev/null +++ b/test/plugindevelopment/TypeInsertTests/GenericVarInsertTest.java @@ -0,0 +1,16 @@ +package plugindevelopment.TypeInsertTests; + +import java.util.Vector; + +import org.junit.Test; + +public class GenericVarInsertTest { + private static final String TEST_FILE = "GenericVarInsertTest.jav"; + + @Test + public void run(){ + Vector mustContain = new Vector(); + mustContain.add("Fun1, Object2>, Object1> op"); + MultipleTypesInsertTester.test(this.TEST_FILE, mustContain); + } +}