Typeinsetzen erweitert

This commit is contained in:
JanUlrich 2017-06-15 02:17:46 +02:00
parent 44481b4140
commit 70ca62202d
9 changed files with 86 additions and 109 deletions

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.ClassNotFoundException; import de.dhbwstuttgart.parser.ClassNotFoundException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.PackageCrawler; import de.dhbwstuttgart.parser.PackageCrawler;
import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
@ -19,6 +20,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
//import jdk.internal.dynalink.support.TypeConverterFactory; //import jdk.internal.dynalink.support.TypeConverterFactory;
import org.antlr.v4.runtime.CommonToken;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNode; import org.antlr.v4.runtime.tree.TerminalNode;
@ -213,6 +215,8 @@ public class SyntaxTreeGenerator{
GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart());
if(header.typeParameters() != null){ if(header.typeParameters() != null){
gtvDeclarations = TypeGenerator.convert(header.typeParameters(), parentClass, name,reg, localGenerics); gtvDeclarations = TypeGenerator.convert(header.typeParameters(), parentClass, name,reg, localGenerics);
}else{
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart());
} }
RefTypeOrTPHOrWildcardOrGeneric retType; RefTypeOrTPHOrWildcardOrGeneric retType;
if(header.result() != null){ if(header.result() != null){
@ -263,7 +267,14 @@ public class SyntaxTreeGenerator{
JavaClassName name = reg.getName(ctx.Identifier().getText()); JavaClassName name = reg.getName(ctx.Identifier().getText());
GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, ""); GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "");
Token offset = ctx.getStart(); Token offset = ctx.getStart();
GenericDeclarationList genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); GenericDeclarationList genericClassParameters;
if(ctx.typeParameters() == null){
CommonToken gtvOffset = new CommonToken(ctx.Identifier().getSymbol());
gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine()+ctx.Identifier().getText().length());
genericClassParameters = new GenericDeclarationList(new ArrayList<>(), gtvOffset);
}else{
genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics);
}
List<Field> fielddecl = convertFields(ctx.classBody(), generics); List<Field> fielddecl = convertFields(ctx.classBody(), generics);
List<Method> methods = convertMethods(ctx.classBody(), name, generics); List<Method> methods = convertMethods(ctx.classBody(), name, generics);
List<Constructor> konstruktoren = new ArrayList<>(); List<Constructor> konstruktoren = new ArrayList<>();
@ -464,8 +475,14 @@ public class SyntaxTreeGenerator{
List<Field> fields = convertFields(ctx.interfaceBody()); List<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, generics); List<Method> methods = convertMethods(ctx.interfaceBody(), name, generics);
GenericDeclarationList genericParams;
GenericDeclarationList genericParams = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); if(ctx.typeParameters() != null){
genericParams = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics);
}else{
CommonToken gtvOffset = new CommonToken(ctx.Identifier().getSymbol());
gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine()+ctx.Identifier().getText().length());
genericParams = new GenericDeclarationList(new ArrayList<>(), gtvOffset);
}
RefType superClass = new ASTFactory(reg).createObjectClass().getType(); RefType superClass = new ASTFactory(reg).createObjectClass().getType();
List<RefTypeOrTPHOrWildcardOrGeneric> extendedInterfaces = convert(ctx.extendsInterfaces(), generics); List<RefTypeOrTPHOrWildcardOrGeneric> extendedInterfaces = convert(ctx.extendsInterfaces(), generics);

View File

@ -4,7 +4,6 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@ -55,9 +54,6 @@ public class TypeGenerator {
} }
public static GenericDeclarationList convert(Java8Parser.TypeParametersContext typeParametersContext, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) { public static GenericDeclarationList convert(Java8Parser.TypeParametersContext typeParametersContext, JavaClassName parentClass, String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) {
if(typeParametersContext == null){
return new GenericDeclarationList(new ArrayList<>(), new NullToken());
}
Token endOffset = typeParametersContext.getStop(); Token endOffset = typeParametersContext.getStop();
List<GenericTypeVar> typeVars = new ArrayList<>(); List<GenericTypeVar> typeVars = new ArrayList<>();
for(Java8Parser.TypeParameterContext typeParameter : typeParametersContext.typeParameterList().typeParameter()){ for(Java8Parser.TypeParameterContext typeParameter : typeParametersContext.typeParameterList().typeParameter()){

View File

@ -15,7 +15,7 @@ import java.util.List;
/** /**
* Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces * Stellt jede Art von Klasse dar. Auch abstrakte Klassen und Interfaces
*/ */
public class ClassOrInterface extends GTVDeclarationContext implements IItemWithOffset, Generic{ public class ClassOrInterface implements IItemWithOffset{
protected int modifiers; protected int modifiers;
protected JavaClassName name; protected JavaClassName name;
private List<Field> fields = new ArrayList<>(); private List<Field> fields = new ArrayList<>();
@ -29,25 +29,15 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
RefTypeOrTPHOrWildcardOrGeneric superClass, Boolean isInterface, List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces, Token offset){ RefTypeOrTPHOrWildcardOrGeneric superClass, Boolean isInterface, List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces, Token offset){
super(offset);
this.modifiers = modifiers;
if(name != null){
this.name = name;
}
if(fielddecl != null){
this.fields = fielddecl;
}
if(genericClassParameters != null){
this.genericClassParameters = genericClassParameters;
}
this.offset = offset; this.offset = offset;
if(superClass != null){ this.modifiers = modifiers;
this.name = name;
this.fields = fielddecl;
this.genericClassParameters = genericClassParameters;
this.offset = offset;
this.superClass = superClass; this.superClass = superClass;
}
this.isInterface = isInterface; this.isInterface = isInterface;
if(implementedInterfaces != null){
this.implementedInterfaces = implementedInterfaces; this.implementedInterfaces = implementedInterfaces;
}
this.methods = methods; this.methods = methods;
this.constructors = constructors; this.constructors = constructors;
} }
@ -96,4 +86,9 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith
public List<? extends Method> getConstructors() { public List<? extends Method> getConstructors() {
return constructors; return constructors;
} }
@Override
public Token getOffset() {
return offset;
}
} }

View File

@ -3,7 +3,7 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
public class Field extends GTVDeclarationContext implements Generic { public class Field extends SyntaxTreeNode{
private String name; private String name;
private RefTypeOrTPHOrWildcardOrGeneric type; private RefTypeOrTPHOrWildcardOrGeneric type;

View File

@ -1,13 +0,0 @@
package de.dhbwstuttgart.syntaxtree;
import org.antlr.v4.runtime.Token;
/**
* Beischreibt eine SyntaxTreeNode, welcher die Eigenschaft besitzt,
* dass bei seiner Deklaration auch Generische Typvariablen deklariert wurden.
*/
public abstract class GTVDeclarationContext extends SyntaxTreeNode {
public GTVDeclarationContext(Token offset) {
super(offset);
}
}

View File

@ -1,9 +0,0 @@
package de.dhbwstuttgart.syntaxtree;
/**
* Wird von allen Klassen implementiert, welche generische Parameter halten nnen. (Class, Method und Field)
* @author janulrich
*
*/
public interface Generic {
}

View File

@ -10,6 +10,7 @@ import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.lang.reflect.Type;
import java.util.*; import java.util.*;
/** /**
@ -47,65 +48,72 @@ public class TypeInsertFactory {
return ret; return ret;
} }
private static Set<TypeInsertPoint> createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, Set<Pair> pairs) { private static Set<TypeInsertPoint> createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
Set<Pair> pairs) {
Set<TypeInsertPoint> ret = new HashSet<>(); Set<TypeInsertPoint> ret = new HashSet<>();
for(Pair pair : pairs){ Set<TypePlaceholder> additionalInserts = new HashSet<>();
for (Pair pair : pairs) {
RefTypeOrTPHOrWildcardOrGeneric relatedType = null; RefTypeOrTPHOrWildcardOrGeneric relatedType = null;
if(pair.TA1.equals(type) ){ if (pair.TA1.equals(type)) {
relatedType = pair.TA2; relatedType = pair.TA2;
} else if(pair.TA2.equals(type)){ } else if (pair.TA2.equals(type)) {
relatedType = pair.TA1; relatedType = pair.TA1;
} }
if(relatedType != null){ if (relatedType != null) {
//Es wurde ein direkter Treffer gefunden: //Es wurde ein direkter Treffer gefunden:
if(pair.OperatorEqual()){ //type ist vom Typ TypePlaceholder if (pair.OperatorEqual()) { //resolved ist vom Typ RefType
type = relatedType; RefType resolved = ((RefType) relatedType);
}else{ String insert = createInsertString(resolved, additionalInserts);
ret.addAll(createInsertPoints(relatedType, offset, cl, m, pairs)); ret.add(new TypeInsertPoint(offset, insert));
} else { //Ansonsten ist es ein TPH
additionalInserts.add((TypePlaceholder) type);
//Dann wurde er nicht aufgelöst und es kann nur der TPH als Generic eingesetzt werden:
ret.add(new TypeInsertPoint(offset, ((TypePlaceholder) type).getName()));
} }
} }
} }
ret.addAll(new TypeInsertPointCreator(type, offset).createPoints()); //Alle TPHs die man noch als Generics anfügen muss einsetzen:
//TODO
return ret; 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()){
private static String createInsertString(RefType resolved, Set<TypePlaceholder> additionalInserts) {
String insert = resolved.getName().toString();
if(resolved.getParaList().size() > 0){
insert += "<";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> iterator = resolved.getParaList().iterator();
while(iterator.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric typeParam = iterator.next();
if(typeParam instanceof TypePlaceholder){
insert += ((TypePlaceholder) typeParam).getName();
additionalInserts.add((TypePlaceholder) typeParam);
}else if(typeParam instanceof RefType){
insert += createInsertString((RefType) typeParam, additionalInserts);
}else throw new NotImplementedException();
if(iterator.hasNext())insert += ", ";
} }
insert += ">"; insert += ">";
ret.add(new TypeInsertPoint(offset, insert));
}else {
ret.add(new TypeInsertPoint(offset, getInsertString(type)));
} }
return ret; return insert;
} }
private String getInsertString(RefTypeOrTPHOrWildcardOrGeneric resolved) { private static TypeInsertPoint createGenericInsert(TypePlaceholder tph, TypePlaceholder bound, ClassOrInterface cl, Method m){
if(resolved instanceof RefType){ //Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt:
//TODO: Kontrollieren, ob der Reftype und seine Parameter bekannt sind, ansonsten auch einsetzen Token offset;
return ((RefType) resolved).getName().toString(); String insert = "";
}else if(resolved instanceof TypePlaceholder){ String end =" ";
return ((TypePlaceholder) resolved).getName(); if(cl.getGenerics().iterator().hasNext()){
}else if(resolved instanceof GenericRefType){ offset = cl.getGenerics().iterator().next().getOffset();
return ((GenericRefType)resolved).getName().getShortName().toString();
}else{ }else{
throw new NotImplementedException(); offset = cl.getGenerics().getOffset();
insert += "<";
end = ">";
} }
insert += tph.getName();
if(bound != null){
insert += " extends " + bound.getName();
}
return new TypeInsertPoint(offset, insert + end);
} }
} }

View File

@ -39,27 +39,10 @@ public class TYPE implements StatementVisitor{
@Override @Override
public void visit(LambdaExpression lambdaExpression) { 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()); TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken());
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
lambdaParams.add(tphRetType); //lambdaParams.add(tphRetType);
lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
ConstraintsFactory.createPair(lambdaExpression.getType(), ConstraintsFactory.createPair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT,info)); new FunN(lambdaParams),PairOperator.EQUALSDOT,info));

View File

@ -1,14 +1,14 @@
class Lambda{ class Lambda{
String var;
methode(){ methode(){
String var;
return () -> (f) -> { return () -> (f) -> {
f.apply(this, var); f.apply(this, var);
return var; return var;
}; };
} }
} }
/*
interface Fun0<A>{ interface Fun0<A>{
A apply(); A apply();
} }
@ -16,7 +16,7 @@ interface Fun0<A>{
interface Fun1<A,B>{ interface Fun1<A,B>{
A apply(B b); A apply(B b);
} }
*/
interface Fun2<A,B,C>{ interface Fun2<A,B,C>{
A apply(B b, C c); A apply(B b, C c);
} }