forked from JavaTX/JavaCompilerCore
Lambda-TYPE anpassen. Beginnen mit TypeInsert
This commit is contained in:
parent
5f31150dc8
commit
7a337843e6
@ -8,6 +8,7 @@ import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertFactory;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertPoint;
|
||||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||||
@ -28,7 +29,7 @@ public class JavaTXCompiler {
|
||||
|
||||
private List<SourceFile> sourceFiles = new ArrayList<>();
|
||||
|
||||
public List<TypeInsertPoint> getTypeInserts(File forFile){
|
||||
public List<TypeInsert> getTypeInserts(File forFile){
|
||||
ResultSet result = typeInference();
|
||||
for(SourceFile sf : sourceFiles){
|
||||
if(sf.getFile().equals(forFile)){
|
||||
|
@ -150,7 +150,7 @@ public class UnifyTypeFactory {
|
||||
|
||||
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
|
||||
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
|
||||
RefType ret = new RefType(JavaClassName.Void,convert(t.getTypeParams(), tphs),new NullToken());
|
||||
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.typecheck.JavaClassName;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -13,22 +16,17 @@ import java.util.List;
|
||||
*
|
||||
*/
|
||||
public class FunN extends RefType {
|
||||
|
||||
private RefTypeOrTPHOrWildcardOrGeneric R;
|
||||
private List<? extends RefTypeOrTPHOrWildcardOrGeneric> T;
|
||||
|
||||
/**
|
||||
* @author Andreas Stadelmeier, a10023
|
||||
* Benötigt für den Typinferenzalgorithmus für Java 8
|
||||
* Generiert einen RefType auf eine FunN<R,T1,...,TN> - Klasse.
|
||||
* @param R
|
||||
* @param T
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
public FunN(RefTypeOrTPHOrWildcardOrGeneric R, List<? extends RefTypeOrTPHOrWildcardOrGeneric> T) {
|
||||
super(null,null);
|
||||
public FunN(List<RefTypeOrTPHOrWildcardOrGeneric> params) {
|
||||
super(new JavaClassName("Fun"+params.size()), params, new NullToken());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Spezieller Konstruktor um eine FunN ohne Returntype zu generieren
|
||||
|
||||
|
31
src/de/dhbwstuttgart/typedeployment/TypeInsert.java
Normal file
31
src/de/dhbwstuttgart/typedeployment/TypeInsert.java
Normal file
@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TypeInsert {
|
||||
Set<TypeInsertPoint> inserts;
|
||||
|
||||
public TypeInsert(Token point, String toInsert){
|
||||
inserts = new HashSet<>();
|
||||
inserts.add(new TypeInsertPoint(point, toInsert));
|
||||
}
|
||||
|
||||
public TypeInsert(Set<TypeInsertPoint> points){
|
||||
inserts = points;
|
||||
}
|
||||
|
||||
public String insert(String intoSource){
|
||||
String ret = intoSource;
|
||||
List<TypeInsertPoint> offsets = new ArrayList<>();
|
||||
for(TypeInsertPoint insertPoint : inserts){
|
||||
ret = insertPoint.insert(ret, offsets);
|
||||
offsets.add(insertPoint);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
@ -7,46 +7,98 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* Falls in Feldern Generics entstehen, dann werden diese als Klassenparameter eingesetzt
|
||||
* Für die Instanzierung von Klassen kann man dann beispielsweise nur noch den Diamond-Operator verwenden
|
||||
*
|
||||
* Es müssen zu einem TPH alle in Beziehung stehenden Constraints gefunden werden
|
||||
*/
|
||||
public class TypeInsertFactory {
|
||||
public static List<TypeInsertPoint> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){
|
||||
List<TypeInsertPoint> ret = new ArrayList<>();
|
||||
public static List<TypeInsert> createTypeInsertPoints(SourceFile forSourcefile, ResultSet withResults){
|
||||
List<TypeInsert> ret = new ArrayList<>();
|
||||
for(ClassOrInterface cl : forSourcefile.getClasses()){
|
||||
//Felder:
|
||||
for(Field field : cl.getFieldDecl()){
|
||||
if(field.getType() instanceof TypePlaceholder){
|
||||
RefTypeOrTPHOrWildcardOrGeneric resolved = withResults.resolveType(field.getType());
|
||||
String toInsert = getString(resolved) + " ";
|
||||
ret.add(new TypeInsertPoint(field.getType().getOffset(), toInsert));
|
||||
for(Set<Pair> pairs : withResults.results)
|
||||
ret.add(new TypeInsert(createInsertPoints(
|
||||
field.getType(), field.getType().getOffset(), cl, null, pairs)));
|
||||
}
|
||||
}
|
||||
|
||||
for(Method m : cl.getMethods()){
|
||||
RefTypeOrTPHOrWildcardOrGeneric resolved = withResults.resolveType(m.getReturnType());
|
||||
String toInsert = getString(resolved) + " ";
|
||||
ret.add(new TypeInsertPoint(m.getReturnType().getOffset(), toInsert));
|
||||
for(Set<Pair> pairs : withResults.results)
|
||||
ret.add(new TypeInsert(createInsertPoints(
|
||||
m.getReturnType(), m.getReturnType().getOffset(), cl, m, pairs)));
|
||||
|
||||
for(FormalParameter param : m.getParameterList().getFormalparalist()){
|
||||
resolved = withResults.resolveType(param.getType());
|
||||
toInsert = getString(resolved) + " ";
|
||||
ret.add(new TypeInsertPoint(param.getType().getOffset(), toInsert));
|
||||
|
||||
for(Set<Pair> pairs : withResults.results)
|
||||
ret.add(new TypeInsert(createInsertPoints(
|
||||
param.getType(), param.getType().getOffset(), cl, m, pairs)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String getString(RefTypeOrTPHOrWildcardOrGeneric resolved) {
|
||||
private static Set<TypeInsertPoint> createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, Set<Pair> pairs) {
|
||||
Set<TypeInsertPoint> ret = new HashSet<>();
|
||||
for(Pair pair : pairs){
|
||||
RefTypeOrTPHOrWildcardOrGeneric relatedType = null;
|
||||
if(pair.TA1.equals(type) ){
|
||||
relatedType = pair.TA2;
|
||||
} else if(pair.TA2.equals(type)){
|
||||
relatedType = pair.TA1;
|
||||
}
|
||||
if(relatedType != null){
|
||||
//Es wurde ein direkter Treffer gefunden:
|
||||
if(pair.OperatorEqual()){ //type ist vom Typ TypePlaceholder
|
||||
type = relatedType;
|
||||
}else{
|
||||
ret.addAll(createInsertPoints(relatedType, offset, cl, m, pairs));
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.addAll(new TypeInsertPointCreator(type, offset).createPoints());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
class TypeInsertPointCreator{
|
||||
|
||||
private final RefTypeOrTPHOrWildcardOrGeneric type;
|
||||
private final Token offset;
|
||||
List<TypeInsertPoint> ret = new ArrayList<>();
|
||||
|
||||
TypeInsertPointCreator(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){
|
||||
this.type = type;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public List<TypeInsertPoint> createPoints(){
|
||||
if(type instanceof RefType){
|
||||
RefType refType = ((RefType) type);
|
||||
String insert = refType.getName().toString()+"<";
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
|
||||
}
|
||||
insert += ">";
|
||||
ret.add(new TypeInsertPoint(offset, insert));
|
||||
}else {
|
||||
ret.add(new TypeInsertPoint(offset, getInsertString(type)));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String getInsertString(RefTypeOrTPHOrWildcardOrGeneric resolved) {
|
||||
if(resolved instanceof RefType){
|
||||
//TODO: Kontrollieren, ob der Reftype und seine Parameter bekannt sind, ansonsten auch einsetzen
|
||||
return ((RefType) resolved).getName().toString();
|
||||
}else if(resolved instanceof TypePlaceholder){
|
||||
return ((TypePlaceholder) resolved).getName();
|
||||
@ -56,4 +108,4 @@ public class TypeInsertFactory {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,16 +2,23 @@ package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TypeInsertPoint {
|
||||
Token point;
|
||||
private String insertString;
|
||||
|
||||
public TypeInsertPoint(Token point, String toInsert){
|
||||
this.point = point;
|
||||
this.insertString = toInsert;
|
||||
this.insertString = toInsert + " ";
|
||||
}
|
||||
|
||||
public String insert(String intoSource){
|
||||
return new StringBuilder(intoSource).insert(point.getStartIndex(), insertString).toString();
|
||||
public String insert(String intoSource, List<TypeInsertPoint> additionalOffset){
|
||||
int offset = additionalOffset.stream().filter((token ->
|
||||
//token.point.getLine() != point.getLine() && token.point.getCharPositionInLine() <= point.getCharPositionInLine()))
|
||||
token.point.getStartIndex() <= point.getStartIndex()))
|
||||
.mapToInt((typeInsertPoint -> typeInsertPoint.insertString.length())).sum();
|
||||
return new StringBuilder(intoSource).insert(point.getStartIndex()+offset, insertString).toString();
|
||||
}
|
||||
}
|
||||
|
@ -7,30 +7,30 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ResultSet {
|
||||
Set<Set<Pair>> results;
|
||||
public final Set<Set<Pair>> results;
|
||||
public ResultSet(Set<Set<Pair>> results){
|
||||
this.results = results;
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
public List<Pair> resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
/*//Probleme:
|
||||
* Es müssen teilweise mehrere TPH eingesetzt werden
|
||||
* Es werden alle eingesetzt, welch in der Kette stehen!
|
||||
* TPHs müssen zu eindeutigen Namen aufgelöst werden
|
||||
*/
|
||||
final RefTypeOrTPHOrWildcardOrGeneric ret;
|
||||
final List<Pair> ret = new ArrayList<>();
|
||||
for(Set<Pair> pairs : results)for(Pair pair : pairs){
|
||||
if(pair.OperatorEqual()){ //type ist vom Typ TypePlaceholder
|
||||
if(pair.TA1.equals(type)){
|
||||
return pair.TA2;
|
||||
}else if(pair.TA2.equals(type)){
|
||||
return pair.TA1;
|
||||
}
|
||||
//if(pair.OperatorEqual()){ //type ist vom Typ TypePlaceholder
|
||||
if(pair.TA1.equals(type) || pair.TA2.equals(type)){
|
||||
ret.add(pair);
|
||||
}
|
||||
//}
|
||||
}
|
||||
return type;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,15 @@ package de.dhbwstuttgart.typeinference.typeAlgo;
|
||||
import com.sun.org.apache.xpath.internal.Arg;
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
||||
import de.dhbwstuttgart.syntaxtree.type.FunN;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
|
||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
|
||||
@ -19,6 +22,7 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TYPE implements StatementVisitor{
|
||||
|
||||
@ -35,18 +39,34 @@ public class TYPE implements StatementVisitor{
|
||||
|
||||
@Override
|
||||
public void visit(LambdaExpression lambdaExpression) {
|
||||
/*
|
||||
List<MethodAssumption> methodAssumptionss = getMethods("apply", lambdaExpression.params.getFormalparalist().size(), info);
|
||||
//TODO: Nur FunN-Interface als mögliche Typen verwenden
|
||||
//methodAssumptionss.stream().filter((methodAssumption -> methodAssumption.getReceiverType().getName().toString()))
|
||||
Set<Constraint> possibleLambdaTypes = new HashSet<>();
|
||||
|
||||
for(MethodAssumption mAss : methodAssumptionss){
|
||||
Constraint cons = new Constraint();
|
||||
cons.add(
|
||||
ConstraintsFactory.createPair(lambdaExpression.methodBody.getType(),mAss.getReturnType(),info));
|
||||
cons.add(
|
||||
ConstraintsFactory.createPair(lambdaExpression.getType(),mAss.getReceiverType(),PairOperator.EQUALSDOT, info));
|
||||
possibleLambdaTypes.add(cons);
|
||||
}
|
||||
if(methodAssumptionss.size() == 0)throw new TypeinferenceException("Kein passendes Funktionales Interface für Lambda Ausdruck gefunden", lambdaExpression.getOffset());
|
||||
|
||||
constraintsSet.addOderConstraint(possibleLambdaTypes);
|
||||
*/
|
||||
TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
|
||||
lambdaParams.add(tphRetType);
|
||||
constraintsSet.addUndConstraint(
|
||||
ConstraintsFactory.createPair(lambdaExpression.getType(),
|
||||
new FunN(lambdaParams),PairOperator.EQUALSDOT,info));
|
||||
constraintsSet.addUndConstraint(
|
||||
ConstraintsFactory.createPair(lambdaExpression.getReturnType(),
|
||||
tphRetType,info));
|
||||
|
||||
//Constraints des Bodys generieren:
|
||||
TYPE lambdaScope = new TYPE(new TypeInferenceBlockInformation(info, lambdaExpression));
|
||||
lambdaExpression.methodBody.accept(lambdaScope);
|
||||
|
@ -1,5 +1,4 @@
|
||||
class Lambda{
|
||||
|
||||
String var;
|
||||
|
||||
methode(){
|
||||
@ -8,7 +7,10 @@ methode(){
|
||||
return var;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface Fun0<A>{
|
||||
A apply();
|
||||
}
|
||||
|
||||
interface Fun1<A,B>{
|
||||
|
@ -3,6 +3,7 @@ package typeinference;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.ClassNotFoundException;
|
||||
import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsert;
|
||||
import de.dhbwstuttgart.typedeployment.TypeInsertPoint;
|
||||
import de.dhbwstuttgart.typeinference.ResultSet;
|
||||
import org.junit.Test;
|
||||
@ -35,9 +36,9 @@ public class JavaTXCompilerTest {
|
||||
JavaTXCompiler compiler = new JavaTXCompiler();
|
||||
for(File f : filesToTest){
|
||||
compiler.parse(f);
|
||||
List<TypeInsertPoint> result = compiler.getTypeInserts(f);
|
||||
List<TypeInsert> result = compiler.getTypeInserts(f);
|
||||
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
|
||||
for(TypeInsertPoint tip : result){
|
||||
for(TypeInsert tip : result){
|
||||
System.out.println(tip.insert(content));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user