FunVoidN einführen

This commit is contained in:
JanUlrich 2015-07-08 17:46:54 +02:00
parent 4f9b4c0e16
commit 44599246b2
11 changed files with 249 additions and 9 deletions

View File

@ -38,6 +38,7 @@ import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ByteCodeResult;
import de.dhbwstuttgart.typeinference.FunNInterface;
import de.dhbwstuttgart.typeinference.FunVoidNInterface;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
@ -550,6 +551,10 @@ public class MyCompiler implements MyCompilerAPI
FunNInterface funN = new FunNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
for(int i = 0; i<6; i++){
FunVoidNInterface funN = new FunVoidNInterface(i);
ret.add(funN.getPublicFieldAssumptions());
}
return ret;

View File

@ -31,6 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.FunN;
import de.dhbwstuttgart.typeinference.FunVoidN;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.ResultSet;
@ -175,17 +176,21 @@ public class LambdaExpression extends Expr{
//retType bleibt unverändert
}
}else{
retType = new ExtendsWildcardType((ObjectType) retType);
//Die LambdaExpression kann zu diesem Zeit schon feststellen, ob der Return-Type Void ist (Kein Return-Statement):
if(!typeIsVoid(retType)){ //Nur, wenn es nicht void ist, kann der ExtendsWildcardType gebildet werden.
retType = new ExtendsWildcardType((ObjectType) retType);
}
}
//Die LambdaExpression kann zu diesem Zeit schon feststellen, ob der Return-Type Void ist (Kein Return-Statement):
if(retType.getName().equals(new JavaClassName("Void"))){
System.out.println("Void rettype");
if(typeIsVoid(retType)){//In diesem Fall, muss der Typ des LambdaAusdrucks FunVoid sein
ret.add(new SingleConstraint(new FunVoidN(modifiedParamTypes).TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
}else{
ret.add(new SingleConstraint(new FunN(retType, modifiedParamTypes).TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
}
ret.add(new SingleConstraint(new FunN(retType, modifiedParamTypes).TYPE(assumptions, this),this.getType().TYPE(assumptions, this)));
return ret;
}
private boolean typeIsVoid(Type type){
return type.getName().equals(new JavaClassName("void"));
}
@Override
public ConstraintsSet TYPEStmt(TypeAssumptions ass){
throw new TypeinferenceException("Eine LambdaExpression darf nicht als Statement verwendet werden.", this);

View File

@ -44,6 +44,16 @@ public class FunN extends RefType {
this.name = new JavaClassName("Fun"+T.size());//getName();
}
/**
* Spezieller Konstruktor um eine FunN ohne Returntype zu generieren
*/
protected FunN(Menge<Type> T){
super("",null,0);
if(T==null)throw new NullPointerException();
setT(T);
this.name = new JavaClassName("Fun"+T.size());//getName();
}
/**
* Erstellt eine FunN:
* FunN<R, T1, ..., TparameterCount>

View File

@ -22,7 +22,6 @@ public class FunNInterface extends Class{
//TODO: Diese Klasse sollte eigentlich von Interface erben
//TODO: getType muss einen Typ mit der ParameterListe zurückliefern.
//private Menge<GenericTypeVar> gtvparalist;
/**

View File

@ -0,0 +1,64 @@
package de.dhbwstuttgart.typeinference;
import java.util.Iterator;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
/**
* @see Spezifikation "Complete Typeinference in Java 8" von Martin Plümicke
* "interface FunN<R,T1, T2, ... ,TN> { R apply(T1 arg1, T2 arg2, ... , TN argN); }"
* @author A10023 - Andreas Stadelmeier
*
* Bemerkung:
* FunN ist ein RefType. Der RefType ist nicht mit einem FunNInterface verbunden.
*
*/
public class FunVoidN extends FunN {
private Type R;
private Menge<Type> T;
/**
* @author Andreas Stadelmeier, a10023
* BenÃtigt ¼r den Typinferenzalgorithmus ¼r Java 8
* Generiert einen RefType auf eine FunVoidN<T1,...,TN> - Klasse.
* @param T
* @return
*/
public FunVoidN(Menge<Type> T) {
super(T);
this.name = new JavaClassName("FunVoid"+T.size());
}
/**
* Erstellt eine FunVoidN:
* FunN<T1, ..., TparameterCount>
* T1 - TparameterCount werden mit TypePlaceholdern besetzt.
* @param parameterCount
*/
public FunVoidN(int parameterCount) {
super(parameterCount);
this.name = new JavaClassName("FunVoid"+T.size());
}
/**
* Muss nach jeder Änderung von T oder R aufgerufen werden.
* Dabei werden bestimmte, von RefType geerbte, Parameter angepasst. Dies ist wichtig ¼r den Typinferenzalgorithmus.
*/
private void calculateNewParalist(){
Menge<Type> t = new Menge<Type>();
if(T!=null)t.addAll(T);
this.set_ParaList(t);
}
}

View File

@ -0,0 +1,64 @@
package de.dhbwstuttgart.typeinference;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
/**
* Stellt das Interface FunVoidN dar.
* @author janulrich
*
*/
public class FunVoidNInterface extends Class{
//TODO: Diese Klasse sollte eigentlich von Interface erben
//TODO: getType muss einen Typ mit der ParameterListe zurückliefern.
//private Menge<GenericTypeVar> gtvparalist;
/**
* Ein FunN-Interface enthält nur eine Methode (namens apply). Ist also ein Funktionales Interface.
* @param N - Die Anzahl der Parameter der apply-Methode. Beispiel N = 1 ergibt <code>R apply(T1 par1);</code>
*/
public FunVoidNInterface(int N) {
super("FunVoid"+N, null, new Modifiers(), FunVoidNInterface.makeParaList(N));
}
private static Menge<String> makeParaList(int n) {
Menge<String> ret = new Menge<>();
for(int i = 1; i<=n;i++){
ret.add("T"+i);
}
return ret;
}
/**
* @return Im Falle von einem FunN-Interface ist dies die apply-Methode
*/
@Override
public TypeAssumptions getPublicFieldAssumptions() {
//return super.getPublicFieldAssumptions();
TypeAssumptions ret = new TypeAssumptions();
ret.addAssumption(new MethodAssumption(this.getApplyFunction(), this));
ret.addClassAssumption(new ClassAssumption(this));
for(GenericTypeVar gtv : this.getGenericParameter())ret.addGenericVarAssumption(gtv);
return ret;
}
/**
* Erstellt die nach Definition des Typinferenzalgorithmus von Martin Plümicke, in jedem FunN-Interface enthaltene apply-Methode
* @return
*/
private FunVoidNMethod getApplyFunction(){
return new FunVoidNMethod(this.get_ParaList(),this);
}
}

View File

@ -0,0 +1,63 @@
package de.dhbwstuttgart.typeinference;
import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Class;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;
public class FunVoidNMethod extends Method{
/**
*
* @param N - Anzahl der Parameter (Beispiel: Fun2<R, T1, T2>)
*/
public FunVoidNMethod(Menge<? extends Type> paralist, Class parent){
super(0); //Hat keinen Offset, da nur theoretisch gedachte Methode
int N = paralist.size();
this.setType(new Void(this, -1));
this.set_DeclId(new DeclId("apply"));
ParameterList pl = new ParameterList();
Menge<FormalParameter> fpList = new Menge<FormalParameter>();
for(int i = 0;i<N;i++){ //Alle Elemente in der übergebenen paralist durchgehen.
DeclId paramName = new DeclId("T"+i);
FormalParameter parameter = new FormalParameter(paramName);
parameter.setType(paralist.get(i));
fpList.add(parameter);
}
pl.formalparameter = fpList;
this.parameterlist = pl;
this.parserPostProcessing(parent);
}
/*
public FunNMethod(int N){
super(0); //Hat keinen Offset, da nur theoretisch gedachte Methode
this.setType(TypePlaceholder.fresh(this));
this.set_DeclId(new DeclId("apply"));
ParameterList pl = new ParameterList();
Menge<FormalParameter> fpList = new Menge<FormalParameter>();
for(int i = 1;i<=N;i++){ //Alle verbleibenden Elemente in der übergebenen paralist durchgehen.
DeclId paramName = new DeclId("T"+i);
FormalParameter parameter = new FormalParameter(paramName);
parameter.setType(TypePlaceholder.fresh(parameter));
//parameter.set_DeclId(paramName);
fpList.add(parameter);
}
pl.formalparameter = fpList;
this.parameterlist = pl;
this.parserPostProcessing(new Class("Fun"+N, 0));
}
*/
@Override
public TypeInsertPoint createTypeInsertPoint(TypePlaceholder tph,
ResultSet resultSet) {
return null;
}
}

View File

@ -696,7 +696,7 @@ public class Unify
}
SetView<Menge<Menge<Pair>>> difference = Sets.difference(cartProduktSets, temp);
log.debug("Ausgelöschte Constraints: "+difference.toString());
//cartProduktSets = temp;
cartProduktSets = temp;
/*
Unifier filterUnify = (pairs)->{
String pairsString = pairs.toString();

View File

@ -0,0 +1,5 @@
class FunTest{
funVoid = ()->{};
}

View File

@ -0,0 +1,19 @@
package plugindevelopment.TypeInsertTests;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.typeinference.Menge;
import org.junit.Test;
public class FunVoid {
private static final String TEST_FILE = "FunVoid.jav";
@Test
public void run(){
Menge<String> mustContain = new Menge<String>();
//mustContain.add("TestIfStmt var");
MultipleTypesInsertTester.testSingleInsert(this.TEST_FILE, mustContain);
ArrayList l = new ArrayList();
}
}

View File

@ -106,5 +106,11 @@ public class MultipleTypesInsertTester extends TypeInsertTester{
for(String containString : mustContain){
TestCase.assertTrue("\""+containString+"\" muss in den inferierten Lösungen vorkommen",gesamterSrc.contains(containString));
}
try {
Files.write(Logger.getWholeLog().getBytes(),new File(rootDirectory+sourceFileToInfere+".log"));
} catch (IOException e) {
e.printStackTrace();
TestCase.fail();
}
}
}