Neuimplementierung von automatischer Einsetzung der benötigten Generischen Variablen durch TypeInsertSet

This commit is contained in:
JanUlrich 2014-04-23 12:05:57 +02:00
parent 258c172f80
commit eab2c7ef93
17 changed files with 6949 additions and 7508 deletions

View File

@ -881,7 +881,9 @@ Beispiel: var = 2;
Bei einer lokalen Variable lässt sich hier nicht ermitteln ob die Variable deklariert werden soll oder bereits deklariert wurde und ihr nur ein Wert zugewiesen werden soll.
Dieses Problem ist bei Feldern nicht der Fall.
*/
fielddeclarator : type variabledeclarator '=' expression
fielddeclarator :
/*
type variabledeclarator '=' expression
{
FieldDeclaration ret = new FieldDeclaration($2.getOffset());
ret.setType($1);
@ -889,7 +891,9 @@ fielddeclarator : type variabledeclarator '=' expression
ret.setWert($4);
$$=ret;
}
| variabledeclarator '=' expression
|
*/
variabledeclarator '=' expression
{
FieldDeclaration ret = new FieldDeclaration($1.getOffset());
ret.set_DeclId($1);
@ -901,15 +905,15 @@ fielddeclaration : fielddeclarator ';'
{
$$=$1;
}
| type fielddeclarator
| type fielddeclarator ';'
{
$2.setType($1);
$$=$2;
}
| '<' boundedMethodParameters '>' type fielddeclarator
| '<' boundedMethodParameters '>' type fielddeclarator ';'
{//angefügt von Andreas Stadelmeier
$5.setGenericParameter($2);
$5.setType($4);
$5.setGenericParameter($2);
$$=$5;
}
|

File diff suppressed because it is too large Load Diff

View File

@ -881,7 +881,9 @@ Beispiel: var = 2;
Bei einer lokalen Variable lässt sich hier nicht ermitteln ob die Variable deklariert werden soll oder bereits deklariert wurde und ihr nur ein Wert zugewiesen werden soll.
Dieses Problem ist bei Feldern nicht der Fall.
*/
fielddeclarator : type variabledeclarator '=' expression
fielddeclarator :
/*
type variabledeclarator '=' expression
{
FieldDeclaration ret = new FieldDeclaration($2.getOffset());
ret.setType($1);
@ -889,7 +891,9 @@ fielddeclarator : type variabledeclarator '=' expression
ret.setWert($4);
$$=ret;
}
| variabledeclarator '=' expression
|
*/
variabledeclarator '=' expression
{
FieldDeclaration ret = new FieldDeclaration($1.getOffset());
ret.set_DeclId($1);
@ -901,15 +905,15 @@ fielddeclaration : fielddeclarator ';'
{
$$=$1;
}
| type fielddeclarator
| type fielddeclarator ';'
{
$2.setType($1);
$$=$2;
}
| '<' boundedMethodParameters '>' type fielddeclarator
| '<' boundedMethodParameters '>' type fielddeclarator ';'
{//angefügt von Andreas Stadelmeier
$5.setGenericParameter($2);
$5.setType($4);
$5.setGenericParameter($2);
$$=$5;
}
|

View File

@ -750,6 +750,7 @@ public class RefType extends Type implements IMatchable
@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;
@ -757,6 +758,8 @@ public class RefType extends Type implements IMatchable
if(eq instanceof TypePlaceholder)ret.add((TypePlaceholder)eq);
}
}
*/
ret.addAll(this.printJavaCode(resultSet).getUnresolvedTPH());
return ret;
}

View File

@ -268,6 +268,15 @@ public class Type implements IItemWithOffset
public Vector<TypePlaceholder> getUnresolvedTPH(ResultSet resultSet) {
return new Vector<TypePlaceholder>();
}
/**
* Prüft ob der Typ von dem übergebenen TypPlaceholder abhängt.
* @param tph
* @return
*/
public boolean involves(TypePlaceholder tph) {
return false;
}
}
// ino.end

View File

@ -523,8 +523,8 @@ public class TypePlaceholder extends Type implements IReplaceTypeEventProvider
* @return
* @see TypeInsertPoint
*/
public TypeInsertSet getTypeInsertPoints(ResultSet result) {
TypeInsertSet ret = new TypeInsertSet();
public Vector<TypeInsertPoint> getTypeInsertPoints(ResultSet result) {
Vector<TypeInsertPoint> ret = new Vector<TypeInsertPoint>();
for(ITypeReplacementListener ti : this.m_ReplacementListeners){
if(ti instanceof TypeInsertable){
TypeInsertPoint toAdd = ((TypeInsertable) ti).createTypeInsertPoint(this, result);

View File

@ -109,13 +109,39 @@ public class TypeinferenceResultSet
/**
* Berechnet alle möglichen Punkte zum Einsetzen eines Typs im Quelltext
* Dabei entstehen TypeInsertSets. Für jeden gesammelten TypeInsertPoint werden alle Abhängigkeiten berechnet.
*
* @return
*/
public Vector<TypeInsertSet> getTypeInsertionPoints(){
Vector<TypeInsertSet> ret = new Vector<TypeInsertSet>();
for(Pair p : constraints){
for(TypePlaceholder tph : p.getTypePlaceholder()){
TypeInsertSet toAdd = tph.getTypeInsertPoints(this.unifiedConstraints);
//Alle TypeInsertPoints dieses TPH ermitteln:
Vector<TypeInsertPoint> tips = tph.getTypeInsertPoints(this.unifiedConstraints);
/*
//Anschließend alle TPHs ermitteln, welche mit den ermittelten TIPs in Verbindung stehen:
Vector<TypePlaceholder> tphs = new Vector<TypePlaceholder>();
for(TypeInsertPoint tip : tips){
tphs.addAll(tip.getUnresolvedTPH()); //Alle in Verbindung stehenden TPHs ermitteln...
//... welche anschließend als Generische Variablen im Quelltext eingesetzt werden würden.
for(Type type : this.unifiedConstraints.getTypesInvolving(tip.getUnresolvedTPH())){
//Alle Typen, welche diesen tph enthalten auch mit diesem TypInsertSet einsetzen
//TODO: Typeplaceholder, welche diesen Typ einsetzen (im ResultSet-equal sind) zu tphs adden
}
}
for(TypePlaceholder tphTemp : tphs){
tips.addAll(tphTemp.getTypeInsertPoints(this.unifiedConstraints));
}
*/
TypeInsertSet toAdd = new TypeInsertSet();
for(int i = 0; i<tips.size();i++){
TypeInsertPoint tip = tips.elementAt(i);
for(TypePlaceholder involvedTPH : toAdd.add(tip)){ //TIP anfügen...
tips.addAll(involvedTPH.getTypeInsertPoints(unifiedConstraints)); //... und alle mit ihm in Verbindung stehenden TIPs in die anzufügende Liste anhängen.
};
}
if(!ret.contains(toAdd))ret.add(toAdd);
}
}
@ -127,7 +153,7 @@ public class TypeinferenceResultSet
* Dabei wird die codegen-Methode der inferierten Klasse mit diesem ResultSet aufgerufen.
*/
public void codegen(){
//TODO: Alles!
}
}

View File

@ -39,6 +39,11 @@ public class JavaCodeResult{
unresolvedTPHs.add(typePlaceholder);
}
/**
* Liefert alle TPHs, welche in diesem JavaCodeResult nicht zu einem Typ aufgelöst wurden.
* Diese TPHs stehen dadurch im JavaCode als Variablennamen ohne zugeordnetem Typ.
* @return
*/
public Vector<TypePlaceholder> getUnresolvedTPH(){
return unresolvedTPHs;
}

View File

@ -101,4 +101,20 @@ public class ResultSet implements Iterable<Pair> {
return ret;
}
/**
* Durchsucht das ResultSet nach Typen, die die übergebenen unresolvedTPHs als generische Variablen einbinden.
* @param unresolvedTPH
* @return
*/
public Vector<Type> getTypesInvolving(Vector<TypePlaceholder> unresolvedTPH) {
Vector<Type> ret = new Vector<Type>();
for(Pair p : this.resultPairs){
for(TypePlaceholder tph : unresolvedTPH){
if(p.TA1.involves(tph))ret.add(p.TA1);
if(p.TA2.involves(tph))ret.add(p.TA2);
}
}
return ret;
}
}

View File

@ -18,14 +18,29 @@ import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListe
*/
public class TypeInsertPoint implements Comparable<TypeInsertPoint>{
private IItemWithOffset point;
private Type type;
private ResultSet resultSet;
protected IItemWithOffset point;
protected Type type;
protected ResultSet resultSet;
protected Vector<TypePlaceholder> generics = null;
public TypeInsertPoint(IItemWithOffset insertPoint, Type insertType, ResultSet resultSet){
this(insertPoint, insertType, resultSet, null);
this.generics = this.getUnresolvedTPH();//Alle im insertType vorkommenden TPH müssen als Generics eingesetzt werden.
}
/**
* Dieser Konstruktor erstellt einen TypInsertPoint, welcher nicht nur insertType einsetzt,
* sonder auch die übergebenen generischen Variablen einsetzt.
* @param insertPoint
* @param insertType
* @param resultSet
* @param generics - die generischen Parameter des einzusetzenden Typs
*/
public TypeInsertPoint(IItemWithOffset insertPoint, Type insertType, ResultSet resultSet, Vector<TypePlaceholder> generics){
this.point = insertPoint;
this.type = insertType;
this.resultSet = resultSet;
this.generics = generics;
}
/**
@ -35,9 +50,9 @@ public class TypeInsertPoint implements Comparable<TypeInsertPoint>{
* @return
*/
public JavaCodeResult insertType(String fileContent, int additionalOffset) {
String anfang = fileContent.substring(0, point.getOffset()+additionalOffset);
String anfang = fileContent.substring(0, this.getInsertNode().getOffset()+additionalOffset);
JavaCodeResult mitte = this.getTypeInsertString();
String ende = fileContent.substring(point.getOffset()+additionalOffset);
String ende = fileContent.substring(this.getInsertNode().getOffset()+additionalOffset);
return new JavaCodeResult(anfang).attach(mitte).attach(ende);
}
@ -45,12 +60,18 @@ public class TypeInsertPoint implements Comparable<TypeInsertPoint>{
return this.getTypeInsertString().toString().length();
}
public Vector<TypePlaceholder> getUnresolvedTPH(){
Vector<TypePlaceholder> ret = new Vector<TypePlaceholder>();
ret.addAll(this.type.getUnresolvedTPH(resultSet));
return ret;
}
/**
*
* @return Der Offset des TypeInsertPoints in dem geparsten Source für dessen Klasse er erstellt wurde.
*/
public int getOffset(){
return this.point.getOffset();
return this.getInsertNode().getOffset();
}
/**
@ -97,7 +118,7 @@ public class TypeInsertPoint implements Comparable<TypeInsertPoint>{
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");
throw new DebugException(this.getInsertNode().toString()+" hat kein Feld oder Klasse als Elternelement");
}
}
return (IItemWithOffset)ret;

View File

@ -1,9 +1,11 @@
package typinferenz;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import mycompiler.IItemWithOffset;
import mycompiler.SyntaxTreeNode;
import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.Pair;
@ -13,26 +15,36 @@ import mycompiler.mytype.TypePlaceholder;
/**
* Bündelt ein Set von TypeInsertPoints, die alle zu einem TypePlaceholder gehören.
* Diese müssen gemeinsam eingesetzt werden.
* Das TypeInsertSet löst zudem Abhängigkeiten auf. Wird eine Generische Variable eingesetzt,
* müssen alle mit ihr in Verbindung stehenden Typen ebenfalls eingesetzt werden.
* @author janulrich
*
*/
public class TypeInsertSet {
public Vector<TypeInsertPoint> points = new Vector<TypeInsertPoint>();
public TypeInsertSet(TypeInsertPoint p){
points.add(p);
}
public TypeInsertSet() {
}
public void add(TypeInsertPoint typeInsertPoint) {
points.add(typeInsertPoint);
/**
* Fügt einen TypeInsertPoint dem TypeInsertSet hinzu.
* Dabei werden alle involvierten TPHs berechnet und zurückgeliefert.
* Die von diesen TPHs abhängigen Typen müssen anschließend ebenfalls dem TypeInsertSet angefügt werden.
* @param typeInsertPoint
* @return
*/
public Vector<TypePlaceholder> add(TypeInsertPoint typeInsertPoint) {
if( ! this.points.contains(typeInsertPoint)){ //Nur falls typeInsertPoint noch nicht im Set vorhanden ist:
points.add(typeInsertPoint);
return typeInsertPoint.getUnresolvedTPH();
}
return new Vector<TypePlaceholder>();
}
/**
* Fügt alle Typen dieses TypeInsertSets in den übergebenen Quellcode ein
* TODO: Beim Einsetzen eines Typs alle Abhängigkeiten auflösen. Benutze Generische Variablen müssen an allen Punkte eingesetzt werden
* @param fileContent
* @return
*/
@ -40,7 +52,25 @@ public class TypeInsertSet {
int additionalOffset = 0;
String ret = fileContent;
Vector<GenericTypeInsertPoint> genericTIPs = new Vector<GenericTypeInsertPoint>();
for(TypeInsertPoint p : points){
GenericTypeInsertPoint toAdd = new GenericTypeInsertPoint(p);
for(Pair genericPair : p.getResultSet().getConstraintsFor(p.getUnresolvedTPH())){
toAdd.addGenericPair(genericPair);
}
genericTIPs.add(toAdd);
}
for(GenericTypeInsertPoint p : genericTIPs){
for(GenericTypeInsertPoint p2 : genericTIPs){
//Doppelte Generische Variablen definitionen ausschließen:
for(TypeInsertPoint toAdd : p.merge(p2))this.add(toAdd);
}
//this.add(p);
}
Collections.sort(points);
for(TypeInsertPoint p : points){
/*
//TODO: Verbessern. Momentan noch komischer Hack:
@ -61,6 +91,7 @@ public class TypeInsertSet {
//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.
@ -79,8 +110,8 @@ public class TypeInsertSet {
//Jetzt das gesamte Offset korrigieren:
additionalOffset += tip.getInsertLength();
}
*/
additionalOffset += p.getInsertLength();
}
return ret;
}

View File

@ -8,5 +8,4 @@ public class ParserError extends TypeinferenceException{
public ParserError(yyException exc){
super(exc.getMessage(), exc.token.getOffset());
}
}

View File

@ -26,6 +26,7 @@ public class TypeinferenceException extends RuntimeException {
public TypeinferenceException(String message, int offset){
this.message=message;
this.offset = offset;
}
/**

View File

@ -1,3 +1,3 @@
class Matrix{
<AH extends AL, AI extends AH, B extends AK, B extends AK, AI extends AH, AH extends AL> Fun1<Fun1<AL, Fun2<AI, Matrix, AK>>, B> op = (m) -> ( f) -> f.apply(this, m);
<A extends B, C extends B> String op = "String";
}

View File

@ -28,8 +28,8 @@ public class GeneralParserTest{
@Test
public void run(){
Vector<String> filenames = new Vector<String>();
//filenames.add("FieldInitializationTest.jav");
//filenames.add("ImportTest.jav");
filenames.add("FieldInitializationTest.jav");
filenames.add("ImportTest.jav");
filenames.add("BoundedParameter.jav");
MyCompilerAPI compiler = MyCompiler.getAPI();
try{

View File

@ -55,7 +55,8 @@ public class TRMEqualTest {
pair.SetOperator(PairOperator.Equal);
resultContent.add(pair);
ResultSet resultSet = new ResultSet(resultContent);
TypeInsertSet toAdd = tph.getTypeInsertPoints(resultSet);
Vector<TypeInsertPoint> tphs = tph.getTypeInsertPoints(resultSet);
TypeInsertSet toAdd = new TypeInsertSet(tphs);
System.out.println("Füge hinzu: "+toAdd);
if(!replaceSet.contains(toAdd))replaceSet.add(toAdd);
}

File diff suppressed because it is too large Load Diff