Lambdas einführen

This commit is contained in:
JanUlrich 2017-04-20 18:51:27 +02:00
parent e5d3d67dad
commit caa7f7deee
9 changed files with 94 additions and 29 deletions

View File

@ -33,7 +33,6 @@ public class StatementGenerator {
this.generics = generics; this.generics = generics;
} }
public Method convert(Java8Parser.MethodDeclarationContext methodDeclarationContext, JavaClassName parentClass) { public Method convert(Java8Parser.MethodDeclarationContext methodDeclarationContext, JavaClassName parentClass) {
Java8Parser.MethodHeaderContext header = methodDeclarationContext.methodHeader(); Java8Parser.MethodHeaderContext header = methodDeclarationContext.methodHeader();
String name = header.methodDeclarator().Identifier().getText(); String name = header.methodDeclarator().Identifier().getText();
@ -742,6 +741,8 @@ public class StatementGenerator {
private Expression convert(Java8Parser.ClassInstanceCreationExpression_lfno_primaryContext newExpression) { private Expression convert(Java8Parser.ClassInstanceCreationExpression_lfno_primaryContext newExpression) {
if(newExpression.expressionName()!= null)throw new NotImplementedException(); if(newExpression.expressionName()!= null)throw new NotImplementedException();
if(newExpression.typeArgumentsOrDiamond()!= null)throw new NotImplementedException();
if(newExpression.typeArguments()!= null)throw new NotImplementedException();
TerminalNode identifier = newExpression.Identifier(0); TerminalNode identifier = newExpression.Identifier(0);
RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),identifier.getSymbol(),reg,generics); RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),identifier.getSymbol(),reg,generics);
@ -827,8 +828,13 @@ public class StatementGenerator {
}else{ }else{
block = convert(expression.lambdaBody().block()); block = convert(expression.lambdaBody().block());
} }
return new LambdaExpression(TypePlaceholder.fresh(expression.getStart()), List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
params, block, expression.getStart()); funNParams.add(TypePlaceholder.fresh(expression.getStart()));//ret-Type
params.getFormalparalist().forEach(formalParameter -> //Für jeden Parameter einen TPH anfügen:
funNParams.add(TypePlaceholder.fresh(expression.getStart())));
RefType lambdaType = new RefType(reg.getName("Fun"+params.getFormalparalist().size()),
funNParams, expression.getStart());
return new LambdaExpression(lambdaType, params, block, expression.getStart());
} }
} }

View File

@ -2,7 +2,6 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.InvalidClassNameException; import de.dhbwstuttgart.parser.InvalidClassNameException;
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.*;

View File

@ -5,11 +5,8 @@ import java.util.ArrayList;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.IItemWithOffset;
@ -23,7 +20,7 @@ import de.dhbwstuttgart.syntaxtree.statement.Block;
* @author janulrich * @author janulrich
* *
*/ */
public class Method extends Field implements IItemWithOffset public class Method extends Field implements IItemWithOffset, TypeScope
{ {
private Block block; private Block block;
private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken()); private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken());
@ -56,4 +53,9 @@ public class Method extends Field implements IItemWithOffset
public Iterable<? extends GenericTypeVar> getGenerics() { public Iterable<? extends GenericTypeVar> getGenerics() {
return generics; return generics;
} }
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return this.getType();
}
} }

View File

@ -0,0 +1,10 @@
package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public interface TypeScope {
Iterable<? extends GenericTypeVar> getGenerics();
RefTypeOrTPHOrWildcardOrGeneric getReturnType();
}

View File

@ -1,11 +1,19 @@
package de.dhbwstuttgart.syntaxtree.statement; package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.util.ArrayList;
/** /**
* @author A10023 - Andreas Stadelmeier * @author A10023 - Andreas Stadelmeier
@ -14,7 +22,7 @@ import org.antlr.v4.runtime.Token;
* LambdaExpression Aufbau: * LambdaExpression Aufbau:
* ( ParameterList ) -> { methodBody }; * ( ParameterList ) -> { methodBody };
*/ */
public class LambdaExpression extends Expression{ public class LambdaExpression extends Expression implements TypeScope {
private Block methodBody; private Block methodBody;
private ParameterList params; private ParameterList params;
@ -24,9 +32,23 @@ public class LambdaExpression extends Expression{
this.params = params; this.params = params;
} }
@Override @Override
public ConstraintSet getConstraints(TypeInferenceBlockInformation info) { public ConstraintSet getConstraints(TypeInferenceBlockInformation info) {
TypeInferenceBlockInformation lambdaScope = new TypeInferenceBlockInformation(info, this);
ConstraintSet ret = methodBody.getConstraints(lambdaScope);
throw new NotImplementedException(); throw new NotImplementedException();
//return ret;
}
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
//Lambda-Ausdrücke haben keine Generics
return new ArrayList<>();
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
RefType type = (RefType) this.getType();
return type.getParaList().get(0);
} }
} }

View File

@ -2,7 +2,6 @@ package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@ -21,7 +20,7 @@ public class Return extends Statement
public ConstraintSet getConstraints(TypeInferenceBlockInformation info) { public ConstraintSet getConstraints(TypeInferenceBlockInformation info) {
ConstraintSet ret = retexpr.getConstraints(info); ConstraintSet ret = retexpr.getConstraints(info);
ret.addUndConstraint(ConstraintsFactory.createPair( ret.addUndConstraint(ConstraintsFactory.createPair(
this.getType(),info.getCurrentMethod().getType(), info)); this.getType(),info.getCurrentTypeScope().getReturnType(), info));
return ret; return ret;
} }
} }

View File

@ -1,25 +1,60 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import java.util.Stack;
import java.util.stream.Collectors;
public class TypeInferenceBlockInformation extends TypeInferenceInformation { public class TypeInferenceBlockInformation extends TypeInferenceInformation {
private Method methodContext; private TypeScope methodContext;
private ClassOrInterface currentClass; private ClassOrInterface currentClass;
public TypeInferenceBlockInformation(Set<ClassOrInterface> availableClasses, ClassOrInterface currentClass, Method methodContext) { public TypeInferenceBlockInformation(Set<ClassOrInterface> availableClasses,
ClassOrInterface currentClass, TypeScope methodContext) {
super(availableClasses); super(availableClasses);
this.methodContext = methodContext; this.methodContext = methodContext;
this.currentClass = currentClass; this.currentClass = currentClass;
} }
public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) {
this(oldScope.getAvailableClasses(), oldScope.currentClass, oldScope.methodContext);
methodContext = new TypeScopeContainer(methodContext, newScope);
}
public ClassOrInterface getCurrentClass() { public ClassOrInterface getCurrentClass() {
return currentClass; return currentClass;
} }
public Method getCurrentMethod() { public TypeScope getCurrentTypeScope() {
return methodContext; return methodContext;
} }
private class TypeScopeContainer implements TypeScope{
ArrayList<TypeScope> scopes = new ArrayList<>();
Stack<RefTypeOrTPHOrWildcardOrGeneric> types = new Stack<>();
public TypeScopeContainer(TypeScope scope1, TypeScope scope2){
scopes.add(scope1);
scopes.add(scope2);
types.push(scope1.getReturnType());
types.push(scope2.getReturnType());
}
public void add(TypeScope scope){
}
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
return Iterables.concat(scopes.stream().
map(TypeScope::getGenerics).collect(Collectors.toList()).toArray(new Iterable[0]));
}
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return types.peek();
}
}
} }

View File

@ -9,7 +9,6 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
public class ConstraintsFactory { public class ConstraintsFactory {
@ -24,15 +23,7 @@ public class ConstraintsFactory {
private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, TypeInferenceBlockInformation info){ private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, TypeInferenceBlockInformation info){
if(type instanceof GenericRefType){ if(type instanceof GenericRefType){
List<GenericTypeVar> genericsInContext = new ArrayList<>(); for(GenericTypeVar genericTypeVar : info.getCurrentTypeScope().getGenerics()){
for(GenericTypeVar genericTypeVar : info.getCurrentClass().getGenerics()){
genericsInContext.add(genericTypeVar);
}
if(info.getCurrentMethod() != null)for(GenericTypeVar genericTypeVar : info.getCurrentMethod().getGenerics()){
genericsInContext.add(genericTypeVar);
}
for(GenericTypeVar genericTypeVar : genericsInContext){
if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){ if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){
return new RefType(((GenericRefType)type).getName(),type.getOffset()); return new RefType(((GenericRefType)type).getName(),type.getOffset());
} }

View File

@ -18,7 +18,8 @@ public class JavaTXCompilerTest {
JavaTXCompiler compiler = new JavaTXCompiler(); JavaTXCompiler compiler = new JavaTXCompiler();
//compiler.parse(new File(rootDirectory+"Methods.jav")); //compiler.parse(new File(rootDirectory+"Methods.jav"));
//compiler.parse(new File(rootDirectory+"Generics.jav")); //compiler.parse(new File(rootDirectory+"Generics.jav"));
compiler.parse(new File(rootDirectory+"Lambda.jav")); compiler.parse(new File(rootDirectory+"MethodsEasy.jav"));
//compiler.parse(new File(rootDirectory+"Lambda.jav"));
compiler.typeInference(); compiler.typeInference();
} }
} }