GenerischeTypvariablen werden beim Einsetzen in den Quelltext mit eingesetzt

This commit is contained in:
JanUlrich 2014-04-16 16:02:16 +02:00
parent 87e4f2fd36
commit 1005dabacb
18 changed files with 230 additions and 34 deletions

View File

@ -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<TypePlaceholder> tphs){
this.genericClassParameters = new Vector<GenericTypeVar>();
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

View File

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

View File

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

View File

@ -197,6 +197,7 @@ public class LambdaExpression extends Expr{
public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
ret.add(this.method_body);
for(FormalParameter fp : this.params)ret.add(fp);
return ret;
}

View File

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

View File

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

View File

@ -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
/**
* <br/>Author: J<EFBFBD>rg B<EFBFBD>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;
}

View File

@ -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<TypePlaceholder> getUnresolvedTPH(ResultSet resultSet) {
Vector<TypePlaceholder> 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

View File

@ -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<TypePlaceholder> getUnresolvedTPH(ResultSet resultSet) {
return new Vector<TypePlaceholder>();
}
}
// ino.end

View File

@ -534,6 +534,16 @@ public class TypePlaceholder extends Type implements IReplaceTypeEventProvider
}
return ret;
}
@Override
public Vector<TypePlaceholder> getUnresolvedTPH(ResultSet resultSet) {
Vector<TypePlaceholder> ret = super.getUnresolvedTPH(resultSet);
Type t = resultSet.getTypeEqualTo(this);
if(t instanceof TypePlaceholder){
ret.add((TypePlaceholder)t);
}
return ret;
}
}
// ino.end

View File

@ -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<TypeInsertSet> getTypeInsertionPoints(){

View File

@ -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<Pair> {
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<Pair> getConstraintsFor(Vector<TypePlaceholder> typePlaceholders) {
Vector<Pair> ret = new Vector<Pair>();
Vector<TypePlaceholder> tphs = (Vector<TypePlaceholder>) typePlaceholders.clone();
for(int i = 0;i<tphs.size();i++){
TypePlaceholder tph = tphs.get(i);
for(Pair p : this.resultPairs){
if(p.TA1.equals(tph)){
ret.add(p);
if(p.TA2 instanceof TypePlaceholder && !tphs.contains(p.TA2))tphs.add((TypePlaceholder)p.TA2);
}else if(p.TA2.equals(tph)){
ret.add(p);
if(p.TA1 instanceof TypePlaceholder && !tphs.contains(p.TA1))tphs.add((TypePlaceholder)p.TA1);
}
}
}
return ret;
}
}

View File

@ -1,18 +1,28 @@
package typinferenz;
import java.util.Vector;
import typinferenz.exceptions.DebugException;
import mycompiler.myclass.*;
import mycompiler.myclass.Class;
import mycompiler.IItemWithOffset;
import mycompiler.SyntaxTreeNode;
import mycompiler.mytype.*;
import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener;
/**
* Stellt eine Einsetzungsmöglichkeit für einen Typ an einem (Typeable)Punkt im Syntaxbaum dar.
* Mehrere TypeInsertPoint's werden in einem TypInsertSet zusammengefasst.
* @author janulrich
*
*/
public class TypeInsertPoint implements Comparable<TypeInsertPoint>{
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<TypeInsertPoint>{
* @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<TypeInsertPoint>{
* 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<TypeInsertPoint>{
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<TypeInsertPoint>{
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;
}
}

View File

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

View File

@ -0,0 +1,7 @@
package typinferenz.exceptions;
public class DebugException extends RuntimeException {
public DebugException(String message) {
}
}

View File

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

View File

@ -0,0 +1,3 @@
class GenericVarInsertTest{
op = (m) -> (f) -> f;
}

View File

@ -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<String> mustContain = new Vector<String>();
mustContain.add("Fun1<Fun1<Fun1<void, Object3>, Object2>, Object1> op");
MultipleTypesInsertTester.test(this.TEST_FILE, mustContain);
}
}