Neuimplementierung von automatischer Einsetzung der benötigten Generischen Variablen durch TypeInsertSet
This commit is contained in:
parent
258c172f80
commit
eab2c7ef93
@ -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
@ -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;
|
||||
}
|
||||
|
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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!
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -8,5 +8,4 @@ public class ParserError extends TypeinferenceException{
|
||||
public ParserError(yyException exc){
|
||||
super(exc.getMessage(), exc.token.getOffset());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public class TypeinferenceException extends RuntimeException {
|
||||
|
||||
public TypeinferenceException(String message, int offset){
|
||||
this.message=message;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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);
|
||||
}
|
||||
|
11686
tools/y.output
11686
tools/y.output
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user