From caa7f7deee3fbaa9aa0a8e107a4edf94597d738d Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 20 Apr 2017 18:51:27 +0200 Subject: [PATCH] =?UTF-8?q?Lambdas=20einf=C3=BChren?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatementGenerator.java | 12 +++-- .../SyntaxTreeGenerator.java | 1 - src/de/dhbwstuttgart/syntaxtree/Method.java | 10 +++-- .../dhbwstuttgart/syntaxtree/TypeScope.java | 10 +++++ .../statement/LambdaExpression.java | 28 ++++++++++-- .../syntaxtree/statement/Return.java | 3 +- .../TypeInferenceBlockInformation.java | 45 ++++++++++++++++--- .../constraints/ConstraintsFactory.java | 11 +---- test/typeinference/JavaTXCompilerTest.java | 3 +- 9 files changed, 94 insertions(+), 29 deletions(-) create mode 100644 src/de/dhbwstuttgart/syntaxtree/TypeScope.java diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 9ffd2508..c75f6166 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -33,7 +33,6 @@ public class StatementGenerator { this.generics = generics; } - public Method convert(Java8Parser.MethodDeclarationContext methodDeclarationContext, JavaClassName parentClass) { Java8Parser.MethodHeaderContext header = methodDeclarationContext.methodHeader(); String name = header.methodDeclarator().Identifier().getText(); @@ -742,6 +741,8 @@ public class StatementGenerator { private Expression convert(Java8Parser.ClassInstanceCreationExpression_lfno_primaryContext newExpression) { 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); RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),identifier.getSymbol(),reg,generics); @@ -827,8 +828,13 @@ public class StatementGenerator { }else{ block = convert(expression.lambdaBody().block()); } - return new LambdaExpression(TypePlaceholder.fresh(expression.getStart()), - params, block, expression.getStart()); + List funNParams = new ArrayList<>(); + 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()); } } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 944922c1..35c0d94e 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -2,7 +2,6 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.InvalidClassNameException; -import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.PackageCrawler; import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index af33f453..7b9480e4 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -5,11 +5,8 @@ import java.util.ArrayList; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; 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 de.dhbwstuttgart.core.IItemWithOffset; @@ -23,7 +20,7 @@ import de.dhbwstuttgart.syntaxtree.statement.Block; * @author janulrich * */ -public class Method extends Field implements IItemWithOffset +public class Method extends Field implements IItemWithOffset, TypeScope { private Block block; private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken()); @@ -56,4 +53,9 @@ public class Method extends Field implements IItemWithOffset public Iterable getGenerics() { return generics; } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return this.getType(); + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java new file mode 100644 index 00000000..3631eb2e --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java @@ -0,0 +1,10 @@ +package de.dhbwstuttgart.syntaxtree; + +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + + +public interface TypeScope { + Iterable getGenerics(); + + RefTypeOrTPHOrWildcardOrGeneric getReturnType(); +} diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index 857377c6..2d9cf941 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -1,11 +1,19 @@ 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.TypeScope; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; +import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; import org.antlr.v4.runtime.Token; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; + +import java.util.ArrayList; /** * @author A10023 - Andreas Stadelmeier @@ -14,7 +22,7 @@ import org.antlr.v4.runtime.Token; * LambdaExpression Aufbau: * ( ParameterList ) -> { methodBody }; */ -public class LambdaExpression extends Expression{ +public class LambdaExpression extends Expression implements TypeScope { private Block methodBody; private ParameterList params; @@ -24,9 +32,23 @@ public class LambdaExpression extends Expression{ this.params = params; } - @Override public ConstraintSet getConstraints(TypeInferenceBlockInformation info) { + TypeInferenceBlockInformation lambdaScope = new TypeInferenceBlockInformation(info, this); + ConstraintSet ret = methodBody.getConstraints(lambdaScope); throw new NotImplementedException(); + //return ret; + } + + @Override + public Iterable getGenerics() { + //Lambda-Ausdrücke haben keine Generics + return new ArrayList<>(); + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + RefType type = (RefType) this.getType(); + return type.getParaList().get(0); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java index b2a754ca..6cfb719a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java @@ -2,7 +2,6 @@ package de.dhbwstuttgart.syntaxtree.statement; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import org.antlr.v4.runtime.Token; @@ -21,7 +20,7 @@ public class Return extends Statement public ConstraintSet getConstraints(TypeInferenceBlockInformation info) { ConstraintSet ret = retexpr.getConstraints(info); ret.addUndConstraint(ConstraintsFactory.createPair( - this.getType(),info.getCurrentMethod().getType(), info)); + this.getType(),info.getCurrentTypeScope().getReturnType(), info)); return ret; } } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceBlockInformation.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceBlockInformation.java index 5cd7dab7..b0d459df 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceBlockInformation.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceBlockInformation.java @@ -1,25 +1,60 @@ 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.FormalParameter; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; 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.Stack; +import java.util.stream.Collectors; public class TypeInferenceBlockInformation extends TypeInferenceInformation { - private Method methodContext; + private TypeScope methodContext; private ClassOrInterface currentClass; - public TypeInferenceBlockInformation(Set availableClasses, ClassOrInterface currentClass, Method methodContext) { + public TypeInferenceBlockInformation(Set availableClasses, + ClassOrInterface currentClass, TypeScope methodContext) { super(availableClasses); this.methodContext = methodContext; this.currentClass = currentClass; } - + public TypeInferenceBlockInformation(TypeInferenceBlockInformation oldScope, TypeScope newScope) { + this(oldScope.getAvailableClasses(), oldScope.currentClass, oldScope.methodContext); + methodContext = new TypeScopeContainer(methodContext, newScope); + } public ClassOrInterface getCurrentClass() { return currentClass; } - public Method getCurrentMethod() { + public TypeScope getCurrentTypeScope() { return methodContext; } + + private class TypeScopeContainer implements TypeScope{ + ArrayList scopes = new ArrayList<>(); + Stack 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 getGenerics() { + return Iterables.concat(scopes.stream(). + map(TypeScope::getGenerics).collect(Collectors.toList()).toArray(new Iterable[0])); + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return types.peek(); + } + } } diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java index 6a13da40..51274131 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java @@ -9,7 +9,6 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; public class ConstraintsFactory { @@ -24,15 +23,7 @@ public class ConstraintsFactory { private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, TypeInferenceBlockInformation info){ if(type instanceof GenericRefType){ - List genericsInContext = new ArrayList<>(); - 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){ + for(GenericTypeVar genericTypeVar : info.getCurrentTypeScope().getGenerics()){ if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){ return new RefType(((GenericRefType)type).getName(),type.getOffset()); } diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index 9b506f24..7a73974b 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -18,7 +18,8 @@ public class JavaTXCompilerTest { JavaTXCompiler compiler = new JavaTXCompiler(); //compiler.parse(new File(rootDirectory+"Methods.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(); } } \ No newline at end of file