Break statement in AST eingefügt

This commit is contained in:
luca9913 2023-04-01 16:27:55 +02:00
parent 4986fd0f31
commit 52b7040337
11 changed files with 720 additions and 852 deletions

View File

@ -112,9 +112,7 @@ public class StatementGenerator {
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
private GenericsRegistry generics;
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics,
Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields,
Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
this.reg = reg;
this.generics = generics;
this.fields = fields;
@ -128,12 +126,9 @@ public class StatementGenerator {
return new ParameterList(ret, new NullToken()); // Dann ist die Parameterliste leer
/*
* Restrukturierung Java17-Grammatik
* Zeile wird nicht mehr benötigt, da Regel für Parameter-Liste nicht mehr
* rekursiv ist. "lastFormalParameter" hat kein Kind "formalParameter" mehr.
* Restrukturierung Java17-Grammatik Zeile wird nicht mehr benötigt, da Regel für Parameter-Liste nicht mehr rekursiv ist. "lastFormalParameter" hat kein Kind "formalParameter" mehr.
*
* if(formalParameterListContext.lastFormalParameter().formalParameter() ==
* null) throw new NotImplementedException();
* if(formalParameterListContext.lastFormalParameter().formalParameter() == null) throw new NotImplementedException();
*/
fps = formalParameterListContext.formalParameter();
@ -272,9 +267,7 @@ public class StatementGenerator {
if (!Objects.isNull(creator.classCreatorRest())) {
ArgumentList args = convertArguments(creator.classCreatorRest().arguments().expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
.map(x -> TypePlaceholder.fresh(creator.getStart()))
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream().map(x -> TypePlaceholder.fresh(creator.getStart())).collect(Collectors.toCollection(ArrayList::new));
Statement ret = new NewClass(newclass, args, null, argTypes, creator.getStart());
ret.setStatement();
return ret;
@ -296,8 +289,7 @@ public class StatementGenerator {
throw new NotImplementedException();
}
IdentifierContext identifier = createdname.identifier();
return (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs,
identifier.getStart(), reg, generics);
return (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, identifier.getStart(), reg, generics);
}
private Statement convert(Java17Parser.InnerCreatorContext innercreator) {
@ -307,12 +299,9 @@ public class StatementGenerator {
genericArgs = innercreator.nonWildcardTypeArgumentsOrDiamond().nonWildcardTypeArguments();
}
IdentifierContext identifier = innercreator.identifier();
RefType newclass = (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs,
identifier.getStart(), reg, generics);
RefType newclass = (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, identifier.getStart(), reg, generics);
ArgumentList args = convertArguments(innercreator.classCreatorRest().arguments().expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream()
.map(x -> TypePlaceholder.fresh(innercreator.getStart()))
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream().map(x -> TypePlaceholder.fresh(innercreator.getStart())).collect(Collectors.toCollection(ArrayList::new));
Statement ret = new NewClass(newclass, args, null, argTypes, innercreator.getStart());
ret.setStatement();
return ret;
@ -394,16 +383,14 @@ public class StatementGenerator {
}
if (Objects.isNull(declaration.variableDeclarators())) {
Token offset = declaration.identifier().getStart();
ret.add(new Assign(new AssignToLocal(new LocalVar(declaration.identifier().getText(), type, offset)),
convert(declaration.expression()), offset));
ret.add(new Assign(new AssignToLocal(new LocalVar(declaration.identifier().getText(), type, offset)), convert(declaration.expression()), offset));
} else {
ret.addAll(generateLocalVariableAssignments(declaration.variableDeclarators().variableDeclarator(), type));
}
return ret;
}
private List<Statement> generateLocalVariableAssignments(
List<Java17Parser.VariableDeclaratorContext> varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type) {
private List<Statement> generateLocalVariableAssignments(List<Java17Parser.VariableDeclaratorContext> varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type) {
List<Statement> ret = new ArrayList<>();
for (Java17Parser.VariableDeclaratorContext varDecl : varDeclarators) {
IdentifierContext name = varDecl.variableDeclaratorId().identifier();
@ -417,15 +404,13 @@ public class StatementGenerator {
} else {
initValue = convert(varDecl.variableInitializer().expression());
}
ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getStart())), initValue,
name.getStart()));
ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getStart())), initValue, name.getStart()));
}
}
return ret;
}
public Statement generateFieldAssignment(Java17Parser.VariableDeclaratorContext varDecl,
RefTypeOrTPHOrWildcardOrGeneric type) {
public Statement generateFieldAssignment(Java17Parser.VariableDeclaratorContext varDecl, RefTypeOrTPHOrWildcardOrGeneric type) {
IdentifierContext name = varDecl.variableDeclaratorId().identifier();
Expression initValue;
if (varDecl.variableInitializer().arrayInitializer() != null) {
@ -433,10 +418,7 @@ public class StatementGenerator {
} else {
initValue = convert(varDecl.variableInitializer().expression());
}
return (new Assign(new AssignToField(
new FieldVar(new This(varDecl.getStart()), name.getText(),
type, varDecl.getStart())),
initValue, name.getStart()));
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
}
private Statement convert(Java17Parser.BreakstmtContext stmt) {
@ -509,9 +491,7 @@ public class StatementGenerator {
case RelationalexpressionContext comparison:
return convert(comparison);
/*
* TODO: syntaxtree for instanceof vorbereiten
* case InstanceofexpressionContext instanceof:
* case SwitchexpressionContext switchexpression:
* TODO: syntaxtree for instanceof vorbereiten case InstanceofexpressionContext instanceof: case SwitchexpressionContext switchexpression:
*/
case EqualityexpressionContext equal:
return convert(equal);
@ -566,13 +546,9 @@ public class StatementGenerator {
}
ArgumentList argumentList = convertArguments(expr.expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
.map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset))
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset),
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset),
argTypes, offset);
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), argTypes, offset);
ret.setStatement();
return ret;
}
@ -586,13 +562,9 @@ public class StatementGenerator {
name = expr.SUPER().getText();
}
ArgumentList argumentList = convertArguments(expr.expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream()
.map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset))
.collect(Collectors.toCollection(ArrayList::new));
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset),
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset),
argTypes, offset);
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), argTypes, offset);
ret.setStatement();
return ret;
}
@ -616,8 +588,7 @@ public class StatementGenerator {
}
/**
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und
* einer Klassenangabe unterscheiden.
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
*
* @param expression
* @param offset
@ -733,15 +704,12 @@ public class StatementGenerator {
String operator = expression.bop.getText();
Expression leftSide = convert(expression.expression(0));
Expression rightSide = convert(expression.expression(1));
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()),
leftSide, rightSide, expression.getStart());
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), leftSide, rightSide, expression.getStart());
}
private Expression convert(Java17Parser.RelationalexpressionContext expression) {
String operator = expression.bop.getText();
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()),
convert(expression.expression(0)),
convert(expression.expression(1)), expression.getStart());
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
}
private BinaryExpr.Operator convertBinaryOperator(String operator) {
@ -831,8 +799,7 @@ public class StatementGenerator {
if (expr instanceof PrefixexpressionContext pfe) {
throw new NotImplementedException();
}
return new CastExpr(TypeGenerator.convert(castexpr.typeType(0), reg, generics), convert(expr),
expr.getStart());
return new CastExpr(TypeGenerator.convert(castexpr.typeType(0), reg, generics), convert(expr), expr.getStart());
}
private Expression convert(Java17Parser.PrimaryContext primary) {
@ -846,8 +813,7 @@ public class StatementGenerator {
case PrimaryLiteralContext primliteral:
return convert(primliteral.literal());
case PrimaryIdentifierContext primidentifier:
return new LocalVar(primidentifier.getText(), TypePlaceholder.fresh(primidentifier.getStart()),
primidentifier.getStart());
return new LocalVar(primidentifier.getText(), TypePlaceholder.fresh(primidentifier.getStart()), primidentifier.getStart());
case PrimaryClassrefContext primclassref:
throw new NotImplementedException();
default:
@ -868,8 +834,7 @@ public class StatementGenerator {
return new Literal(type, charliteral.getText().charAt(1), charliteral.getStart());
case StringLiteralContext stringliteral:
type = new RefType(reg.getName("java.lang.String"), stringliteral.getStart());
return new Literal(type, stringliteral.getText().substring(1, stringliteral.getText().length() - 1),
stringliteral.getStart());
return new Literal(type, stringliteral.getText().substring(1, stringliteral.getText().length() - 1), stringliteral.getStart());
case BoolLiteralContext boolliteral:
type = new RefType(reg.getName("java.lang.Boolean"), boolliteral.getStart());
return new Literal(type, Boolean.parseBoolean(boolliteral.getText()), boolliteral.getStart());
@ -887,8 +852,7 @@ public class StatementGenerator {
List<FormalParameter> parameterList = new ArrayList<>();
for (IdentifierContext identifier : lambdaParams.identifier()) {
Token offset = identifier.getStart();
parameterList.add(new FormalParameter(identifier.getText(),
TypePlaceholder.fresh(offset), offset));
parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
}
params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) {
@ -898,8 +862,7 @@ public class StatementGenerator {
List<FormalParameter> parameterList = new ArrayList<>();
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
Token offset = param.getStart();
parameterList.add(new FormalParameter(param.identifier().getText(),
TypePlaceholder.fresh(offset), offset));
parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
}
params = new ParameterList(parameterList, lambdaParams.getStart());
} else {
@ -916,8 +879,7 @@ public class StatementGenerator {
Block block;
if (expression.lambdaBody().expression() != null) {
List<Statement> statements = new ArrayList<>();
statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()),
expression.lambdaBody().expression().getStart()));
statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()), expression.lambdaBody().expression().getStart()));
block = new Block(statements, expression.lambdaBody().getStart());
} else {
block = lambdaGenerator.convert(expression.lambdaBody().block(), true);

View File

@ -15,7 +15,8 @@ public class SyntacticSugar {
Statement lastStmt = statements.get(statements.size() - 1);
ReturnFinder hasReturn = new ReturnFinder();
lastStmt.accept(hasReturn);
if(hasReturn.hasReturn)return statements;
if (hasReturn.hasReturn)
return statements;
}
statements.add(new ReturnVoid(new NullToken()));
return statements;
@ -23,6 +24,7 @@ public class SyntacticSugar {
private static class ReturnFinder extends AbstractASTWalker {
public boolean hasReturn = false;
@Override
public void visit(Return aReturn) {
hasReturn = true;
@ -36,7 +38,8 @@ public class SyntacticSugar {
private static boolean hasReturn(Block block) {
for (Statement s : block.getStatements())
if(s instanceof Return)return true;
if (s instanceof Return)
return true;
return false;
}

View File

@ -177,7 +177,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
}
@Override
public void visit(LocalVarDecl localVarDecl) {
localVarDecl.getType().accept(this);
@ -190,7 +189,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
methodCall.getArgumentList().getArguments().forEach(a -> a.getType().accept((ASTVisitor) this));
}
@Override
public void visit(NewClass methodCall) {
visit((MethodCall) methodCall);
@ -222,6 +220,11 @@ public abstract class AbstractASTWalker implements ASTVisitor{
}
@Override
public void visit(Break aBreak) {
aBreak.accept(this);
}
@Override
public void visit(StaticClassName staticClassName) {

View File

@ -41,6 +41,8 @@ public interface StatementVisitor {
void visit(ReturnVoid aReturn);
void visit(Break aBreak);
void visit(StaticClassName staticClassName);
void visit(Super aSuper);

View File

@ -0,0 +1,19 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class Break extends Statement {
public Break(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
}
@Override
public void accept(StatementVisitor visitor) {
this.accept((StatementVisitor) visitor);
}
}

View File

@ -3,13 +3,10 @@ package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import org.antlr.v4.runtime.Token;
public class Return extends Statement
{
public class Return extends Statement {
public final Expression retexpr;
public Return(Expression retExpr, Token offset)
{
public Return(Expression retExpr, Token offset) {
super(retExpr.getType(), offset);
this.retexpr = retExpr;
}

View File

@ -39,7 +39,8 @@ public class OutputGenerator implements ASTVisitor{
Iterator<Expression> expressionIterator = argumentList.getArguments().iterator();
while (expressionIterator.hasNext()) {
expressionIterator.next().accept(this);
if(expressionIterator.hasNext())out.append(", ");
if (expressionIterator.hasNext())
out.append(", ");
}
out.append(")");
}
@ -63,7 +64,8 @@ public class OutputGenerator implements ASTVisitor{
out.append("<");
while (genericIterator.hasNext()) {
genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", ");
if (genericIterator.hasNext())
out.append(", ");
}
out.append(">");
}
@ -102,7 +104,8 @@ public class OutputGenerator implements ASTVisitor{
if (genericIterator.hasNext()) {
while (genericIterator.hasNext()) {
genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", ");
if (genericIterator.hasNext())
out.append(", ");
}
}
out.append(")");
@ -149,7 +152,8 @@ public class OutputGenerator implements ASTVisitor{
out.append("<");
while (genericIterator.hasNext()) {
genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", ");
if (genericIterator.hasNext())
out.append(", ");
}
out.append(">");
}
@ -298,6 +302,11 @@ public class OutputGenerator implements ASTVisitor{
out.append("return");
}
@Override
public void visit(Break aBreak) {
out.append("break");
}
@Override
public void visit(StaticClassName staticClassName) {

View File

@ -36,7 +36,8 @@ public class ASTToTargetAST {
return all.stream().map(GenericsResult::new).toList();
}
record Generics(Set<ResultPair<?, ?>> javaGenerics, Set<ResultPair<?, ?>> txGenerics) {}
record Generics(Set<ResultPair<?, ?>> javaGenerics, Set<ResultPair<?, ?>> txGenerics) {
}
class Sigma {
Map<Method, Generics> computedGenericsOfMethods = new HashMap<>();
@ -137,17 +138,11 @@ public class ASTToTargetAST {
return all;
}
private void methodFindConstraints(
ClassOrInterface owner, Method method,
Set<PairTPHsmallerTPH> simplifiedConstraints,
HashSet<TypePlaceholder> typeVariables,
HashSet<TypePlaceholder> typeVariablesOfClass,
Set<ResultPair<?, ?>> result,
Map<TypePlaceholder, TypePlaceholder> equality
) {
private void methodFindConstraints(ClassOrInterface owner, Method method, Set<PairTPHsmallerTPH> simplifiedConstraints, HashSet<TypePlaceholder> typeVariables, HashSet<TypePlaceholder> typeVariablesOfClass, Set<ResultPair<?, ?>> result, Map<TypePlaceholder, TypePlaceholder> equality) {
// Type variables with bounds that are also type variables of the method
for (var typeVariable : new HashSet<>(typeVariables)) {
if (typeVariablesOfClass.contains(typeVariable)) continue;
if (typeVariablesOfClass.contains(typeVariable))
continue;
for (var pair : simplifiedConstraints) {
if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) {
addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right)));
@ -165,17 +160,10 @@ public class ASTToTargetAST {
// Anfang es werden Paare von TPHs gespeichert, die bei den Generated Generics ueber die Methodengrenzen hinweg
// betrachtet werden muessen
// Definition 7.2 (Family of generated generics). T1 <. R1 <.^ R2 <. T2
Set<RefTypeOrTPHOrWildcardOrGeneric> T1s =
methodCall.getArgumentList()
.getArguments()
.stream()
.map(TypableStatement::getType)
.collect(Collectors.toCollection(HashSet::new))
.stream().filter(x -> x instanceof TypePlaceholder)
.map(tph -> equality.getOrDefault(tph, (TypePlaceholder) tph))
.collect(Collectors.toCollection(HashSet::new));
Set<RefTypeOrTPHOrWildcardOrGeneric> T1s = methodCall.getArgumentList().getArguments().stream().map(TypableStatement::getType).collect(Collectors.toCollection(HashSet::new)).stream().filter(x -> x instanceof TypePlaceholder).map(tph -> equality.getOrDefault(tph, (TypePlaceholder) tph)).collect(Collectors.toCollection(HashSet::new));
RefTypeOrTPHOrWildcardOrGeneric T2 = superType;
if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph);
if (T2 instanceof TypePlaceholder tph)
T2 = equality.getOrDefault(tph, tph);
System.out.println("T1s: " + T1s + "\nT2: " + T2);
// Ende
@ -190,7 +178,8 @@ public class ASTToTargetAST {
if (methodCall.receiver instanceof ExpressionReceiver expressionReceiver) {
if (expressionReceiver.expr instanceof This) {
var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
if (optMethod.isEmpty()) return;
if (optMethod.isEmpty())
return;
var method = optMethod.get();
var generics = generics(owner, method).javaGenerics();
@ -207,9 +196,9 @@ public class ASTToTargetAST {
HashSet<PairTPHsmallerTPH> newPairs = new HashSet<>();
// Loop from hell
outer:
for (var tph : typeVariables) {
if (typeVariablesOfClass.contains(tph)) continue;
outer: for (var tph : typeVariables) {
if (typeVariablesOfClass.contains(tph))
continue;
for (var generic : all) {
if (!(generic.getRight() instanceof TypePlaceholder type))
continue;
@ -222,8 +211,10 @@ public class ASTToTargetAST {
for (var pair2 : simplifiedConstraints) {
if (!(pair2.right.equals(tph2) && pair2.left.equals(type)))
continue;
if (tph.equals(tph2)) continue;
if (!T1s.contains(tph) || !tph2.equals(T2)) continue;
if (tph.equals(tph2))
continue;
if (!T1s.contains(tph) || !tph2.equals(T2))
continue;
var newPair = new PairTPHsmallerTPH(tph, tph2);
newPairs.add(newPair);
@ -241,7 +232,6 @@ public class ASTToTargetAST {
}
}
@Override
public void visit(LambdaExpression lambdaExpression) {
superType = new Void(new NullToken());
@ -393,6 +383,7 @@ public class ASTToTargetAST {
public void visit(Literal literal) {
}
@Override
public void visit(ArgumentList arglist) {
for (int i = 0; i < arglist.getArguments().size(); i++) {
@ -405,11 +396,13 @@ public class ASTToTargetAST {
var closure = transitiveClosure((Set) simplifiedConstraints);
// Type variables with bounds that are also type variables of the class
for (var typeVariable : new HashSet<>(typeVariables)) {
if (typeVariablesOfClass.contains(typeVariable)) continue;
if (typeVariablesOfClass.contains(typeVariable))
continue;
var pairs = new HashSet<PairTPHsmallerTPH>();
for (var pair : closure) {
if (!(pair instanceof PairTPHsmallerTPH ptph)) continue;
if (!(pair instanceof PairTPHsmallerTPH ptph))
continue;
if (ptph.left.equals(typeVariable) && typeVariablesOfClass.contains(ptph.right)) {
pairs.add(new PairTPHsmallerTPH(ptph.left, equality.getOrDefault(ptph.right, ptph.right)));
}
@ -433,7 +426,8 @@ public class ASTToTargetAST {
break;
}
}
if (!found) break;
if (!found)
break;
}
if (steps < minSteps) {
minSteps = steps;
@ -445,11 +439,10 @@ public class ASTToTargetAST {
addToPairs(result, minimalPair);
}
// All unbounded type variables (bounds not in method)
outer:
for (var typeVariable : typeVariables) {
if (typeVariablesOfClass.contains(typeVariable)) continue;
outer: for (var typeVariable : typeVariables) {
if (typeVariablesOfClass.contains(typeVariable))
continue;
for (var pair : result) {
if (pair.getLeft().equals(typeVariable))
continue outer;
@ -458,8 +451,7 @@ public class ASTToTargetAST {
}
// All unbounded bounds
outer:
for (var pair : simplifiedConstraints) {
outer: for (var pair : simplifiedConstraints) {
for (var pair2 : simplifiedConstraints) {
if (pair.right.equals(pair2.left))
continue outer;
@ -470,13 +462,7 @@ public class ASTToTargetAST {
}
}
private void methodFindTypeVariables(
Method method,
Set<ResultPair<?, ?>> genericsOfClass,
Set<TypePlaceholder> typeVariablesOfClass,
Set<TypePlaceholder> typeVariables,
Map<TypePlaceholder, TypePlaceholder> equality
) {
private void methodFindTypeVariables(Method method, Set<ResultPair<?, ?>> genericsOfClass, Set<TypePlaceholder> typeVariablesOfClass, Set<TypePlaceholder> typeVariables, Map<TypePlaceholder, TypePlaceholder> equality) {
for (var pair : genericsOfClass) {
typeVariablesOfClass.add((TypePlaceholder) pair.getLeft());
@ -500,7 +486,8 @@ public class ASTToTargetAST {
}
@Override
public void visit(Assign assign) {}
public void visit(Assign assign) {
}
});
}
@ -675,7 +662,8 @@ public class ASTToTargetAST {
var foundNext = false;
for (var pair : input) {
if (pair instanceof PairTPHsmallerTPH ptph && ptph.left.equals(end)) {
if (chain.contains(ptph.right)) return;
if (chain.contains(ptph.right))
return;
chain = new HashSet<>(chain);
chain.add(ptph.right);
findChain(referenced, input, output, start, ptph.right, chain);
@ -782,7 +770,8 @@ public class ASTToTargetAST {
return getTargetType(equality.get(tph), equality);
}
var type = concreteTypes.get(tph);
if (type == null) return new TargetGenericType(tph.getName());
if (type == null)
return new TargetGenericType(tph.getName());
return convert(type);
}
}
@ -806,15 +795,11 @@ public class ASTToTargetAST {
}
static Set<TypePlaceholder> allNodes(Set<ResultPair<?, ?>> input) {
return input.stream()
.filter(pair -> pair instanceof PairTPHsmallerTPH)
.flatMap(pair -> Stream.of((TypePlaceholder) pair.getLeft(), (TypePlaceholder) pair.getRight())).collect(Collectors.toSet());
return input.stream().filter(pair -> pair instanceof PairTPHsmallerTPH).flatMap(pair -> Stream.of((TypePlaceholder) pair.getLeft(), (TypePlaceholder) pair.getRight())).collect(Collectors.toSet());
}
static Set<TypePlaceholder> outgoingEdgesOf(TypePlaceholder tph, Set<ResultPair<?, ?>> input) {
return input.stream()
.filter(pair -> pair instanceof PairTPHsmallerTPH && pair.getLeft().equals(tph))
.map(pair -> (TypePlaceholder) pair.getRight()).collect(Collectors.toSet());
return input.stream().filter(pair -> pair instanceof PairTPHsmallerTPH && pair.getLeft().equals(tph)).map(pair -> (TypePlaceholder) pair.getRight()).collect(Collectors.toSet());
}
static boolean containsEdge(TypePlaceholder a, TypePlaceholder b, Set<ResultPair<?, ?>> input) {
@ -837,7 +822,8 @@ public class ASTToTargetAST {
}
var vertexIterator = allNodes(input).iterator();
if (!vertexIterator.hasNext()) return cycles;
if (!vertexIterator.hasNext())
return cycles;
TypePlaceholder startOfPath = null;
TypePlaceholder endOfPath = vertexIterator.next();
@ -895,9 +881,7 @@ public class ASTToTargetAST {
}
Optional<Method> findMethod(ClassOrInterface owner, String name, ArgumentList argumentList) {
return owner.getMethods().stream().filter(
m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)
).findFirst();
return owner.getMethods().stream().filter(m -> m.name.equals(name) && parameterEquals(m.getParameterList(), argumentList)).findFirst();
}
boolean parameterEquals(ParameterList parameterList, ArgumentList argumentList) {
@ -911,7 +895,8 @@ public class ASTToTargetAST {
var type2 = convert(arguments.get(i).getType());
if (type2 instanceof TargetGenericType && type1 instanceof TargetGenericType)
return true;
if (!type1.equals(type2)) return false;
if (!type1.equals(type2))
return false;
}
return true;
@ -961,18 +946,11 @@ public class ASTToTargetAST {
fieldInitializer = convert(input.getfieldInitializations().get().block);
TargetBlock finalFieldInitializer = fieldInitializer;
return new TargetClass(input.getModifiers(), input.getClassName().toString(), convert(input.getSuperClass()),
javaGenerics, txGenerics,
input.getSuperInterfaces().stream().map(this::convert).toList(),
input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList(),
input.getFieldDecl().stream().map(this::convert).toList(),
input.getMethods().stream().map(this::convert).flatMap(List::stream).toList()
);
return new TargetClass(input.getModifiers(), input.getClassName().toString(), convert(input.getSuperClass()), javaGenerics, txGenerics, input.getSuperInterfaces().stream().map(this::convert).toList(), input.getConstructors().stream().map(constructor -> this.convert(constructor, finalFieldInitializer)).flatMap(List::stream).toList(), input.getFieldDecl().stream().map(this::convert).toList(), input.getMethods().stream().map(this::convert).flatMap(List::stream).toList());
}
private List<MethodParameter> convert(ParameterList input) {
return input.getFormalparalist().stream()
.map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList();
return input.getFormalparalist().stream().map(param -> new MethodParameter(convert(param.getType()), param.getName())).toList();
}
private boolean hasGeneric(Set<TargetGeneric> generics, GenericRefType type) {
@ -981,8 +959,7 @@ public class ASTToTargetAST {
private Set<TargetGeneric> collectMethodGenerics(Set<ResultPair<?, ?>> generics, Map<TypePlaceholder, TypePlaceholder> equality, Method input) {
var convertedGenerics = new HashSet<>(convert(generics));
outer:
for (GenericTypeVar typeVar : input.getGenerics()) {
outer: for (GenericTypeVar typeVar : input.getGenerics()) {
for (var classGeneric : currentClass.getGenerics()) {
if (classGeneric.equals(typeVar)) {
continue outer;
@ -1038,12 +1015,7 @@ public class ASTToTargetAST {
var javaGenerics = collectMethodGenerics(generics.javaGenerics(), sigma.equality, input);
var txGenerics = collectMethodGenerics(generics.txGenerics(), sigma.txEquality, input);
result.add(new TargetMethod(
input.modifier,
input.name, javaGenerics, txGenerics, params,
convert(input.getReturnType()),
convert(input.block)
));
result.add(new TargetMethod(input.modifier, input.name, javaGenerics, txGenerics, params, convert(input.getReturnType()), convert(input.block)));
parameterSet.add(params);
}
}
@ -1062,11 +1034,7 @@ public class ASTToTargetAST {
}
private TargetField convert(Field input) {
return new TargetField(
input.modifier,
convert(input.getType()),
input.getName()
);
return new TargetField(input.modifier, convert(input.getType()), input.getName());
}
private final Set<String> usedFunN = new HashSet<>();
@ -1079,7 +1047,8 @@ public class ASTToTargetAST {
@Override
public TargetType visit(RefType refType) {
var name = refType.getName().toString();
if (name.equals("void")) return null;
if (name.equals("void"))
return null;
var params = refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList();
if (name.matches("Fun\\d+\\$\\$")) { // TODO This seems like a bad idea

View File

@ -32,20 +32,20 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override
public void visit(LambdaExpression lambdaExpression) {
var parameters = StreamSupport
.stream(lambdaExpression.params.spliterator(), false)
.map(p -> new MethodParameter(converter.convert(p.getType()), p.getName()))
.toList();
var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false).map(p -> new MethodParameter(converter.convert(p.getType()), p.getName())).toList();
List<MethodParameter> captures = new ArrayList<>();
lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
// TODO The same mechanism is implemented in Codegen, maybe use it from there?
final Stack<Set<String>> localVariables = new Stack<>();
{ localVariables.push(new HashSet<>()); }
{
localVariables.push(new HashSet<>());
}
boolean hasLocalVar(String name) {
for (var localVariables : this.localVariables) {
if (localVariables.contains(name)) return true;
if (localVariables.contains(name))
return true;
}
return false;
}
@ -72,13 +72,11 @@ public class StatementToTargetExpression implements StatementVisitor {
}
@Override
public void visit(LambdaExpression lambda) {} // Don't look at lambda expressions
public void visit(LambdaExpression lambda) {
} // Don't look at lambda expressions
});
result = new TargetLambdaExpression(
converter.convert(lambdaExpression.getType()),
captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody)
);
result = new TargetLambdaExpression(converter.convert(lambdaExpression.getType()), captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody));
}
@Override
@ -129,12 +127,7 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override
public void visit(FieldVar fieldVar) {
result = new TargetFieldVar(
converter.convert(fieldVar.getType()),
converter.convert(fieldVar.receiver.getType()),
false,
converter.convert(fieldVar.receiver),
fieldVar.fieldVarName);
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), false, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
}
@Override
@ -145,11 +138,7 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override
public void visit(IfStmt ifStmt) {
result = new TargetIf(
converter.convert(ifStmt.expr),
converter.convert(ifStmt.then_block),
converter.convert(ifStmt.else_block)
);
result = new TargetIf(converter.convert(ifStmt.expr), converter.convert(ifStmt.then_block), converter.convert(ifStmt.else_block));
}
@Override
@ -169,7 +158,8 @@ public class StatementToTargetExpression implements StatementVisitor {
}
static boolean convertsTo(TargetType from, TargetType to) {
if (to.equals(TargetType.Object)) return true; // TODO Consider type coercion and subtyping
if (to.equals(TargetType.Object))
return true; // TODO Consider type coercion and subtyping
return to.equals(from);
}
@ -179,8 +169,10 @@ public class StatementToTargetExpression implements StatementVisitor {
var clazz = converter.classLoader.loadClass(className.toString());
outer: for (var method : clazz.getMethods()) {
if (method.getParameterTypes().length != args.size()) continue;
if (!method.getName().equals(name)) continue;
if (method.getParameterTypes().length != args.size())
continue;
if (!method.getName().equals(name))
continue;
for (var i = 0; i < method.getParameterTypes().length; i++) {
var param = method.getParameterTypes()[i];
@ -188,15 +180,16 @@ public class StatementToTargetExpression implements StatementVisitor {
if (param.isPrimitive()) {
arg = TargetType.toPrimitive(arg);
}
if (!convertsTo(arg, Objects.requireNonNull(TargetType.toTargetType(param)))) continue outer;
if (!convertsTo(arg, Objects.requireNonNull(TargetType.toTargetType(param))))
continue outer;
}
return method;
}
} catch (ClassNotFoundException ignored) {}
} catch (ClassNotFoundException ignored) {
}
}
if (converter.sourceFile != null) { // TODO Multiple source files
var thisClass = converter.sourceFile.KlassenVektor.stream()
.filter(classOrInterface -> classOrInterface.getClassName().equals(className)).findFirst();
var thisClass = converter.sourceFile.KlassenVektor.stream().filter(classOrInterface -> classOrInterface.getClassName().equals(className)).findFirst();
if (thisClass.isPresent()) {
var superClass = thisClass.get().getSuperClass().getName();
@ -230,22 +223,12 @@ public class StatementToTargetExpression implements StatementVisitor {
argList = Stream.of(foundMethod.getParameterTypes()).map(TargetType::toTargetType).toList();
}
result = new TargetMethodCall(
converter.convert(methodCall.getType()),
returnType, argList,
converter.convert(methodCall.receiver),
methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
receiverType,
methodCall.name, false, isFunNType
);
result = new TargetMethodCall(converter.convert(methodCall.getType()), returnType, argList, converter.convert(methodCall.receiver), methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), receiverType, methodCall.name, false, isFunNType);
}
@Override
public void visit(NewClass newClass) {
result = new TargetNew(
new TargetRefType(newClass.name),
newClass.getArgumentList().getArguments().stream().map(converter::convert).toList()
);
result = new TargetNew(new TargetRefType(newClass.name), newClass.getArgumentList().getArguments().stream().map(converter::convert).toList());
}
@Override
@ -264,6 +247,11 @@ public class StatementToTargetExpression implements StatementVisitor {
result = new TargetReturn(null);
}
@Override
public void visit(Break aBreak) {
result = new TargetBreak();
}
@Override
public void visit(StaticClassName staticClassName) {
result = new TargetClassName(converter.convert(staticClassName.getType()));
@ -306,14 +294,7 @@ public class StatementToTargetExpression implements StatementVisitor {
var type = converter.convert(superCall.getType());
var parameters = superCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList();
result = new TargetMethodCall(
type, type,
parameters,
new TargetSuper(aSuper),
superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
aSuper,
superCall.name, false, false
);
result = new TargetMethodCall(type, type, parameters, new TargetSuper(aSuper), superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), aSuper, superCall.name, false, false);
}
@Override
@ -336,9 +317,7 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override
public void visit(Literal literal) {
if (literal.value instanceof Integer
|| literal.value instanceof Short
|| literal.value instanceof Byte) {
if (literal.value instanceof Integer || literal.value instanceof Short || literal.value instanceof Byte) {
result = new TargetLiteral.IntLiteral((int) literal.value);
} else if (literal.value instanceof Float) {

View File

@ -4,7 +4,6 @@ import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.statement.*;
// This visitor walks the entire tree, individual methods may be overridden
public abstract class TracingStatementVisitor implements StatementVisitor {
@ -102,6 +101,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
}
@Override
public void visit(Break aBreak) {
}
@Override
public void visit(StaticClassName staticClassName) {

View File

@ -41,10 +41,8 @@ public class TYPEStmt implements StatementVisitor{
}
/**
* Erstellt einen neuen GenericResolver
* Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen.
* Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen
* kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
* Erstellt einen neuen GenericResolver Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird.
*
* @return
*/
private static GenericsResolver getResolverInstance() {
@ -68,14 +66,10 @@ public class TYPEStmt implements StatementVisitor{
List<RefTypeOrTPHOrWildcardOrGeneric> lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList());
lambdaParams.add(tphRetType);
// lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getType(),
new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()),
constraintsSet.addUndConstraint(new Pair(lambdaExpression.getType(), new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
// new FunN(lambdaParams),
PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getReturnType(),
tphRetType,PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(lambdaExpression.getReturnType(), tphRetType, PairOperator.EQUALSDOT));
// Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
@ -87,8 +81,7 @@ public class TYPEStmt implements StatementVisitor{
public void visit(Assign assign) {
assign.lefSide.accept(this);
assign.rightSide.accept(this);
constraintsSet.addUndConstraint(new Pair(
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
constraintsSet.addUndConstraint(new Pair(assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
}
@Override
@ -116,8 +109,7 @@ public class TYPEStmt implements StatementVisitor{
Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance();
constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.SMALLERDOT)); // PL 2019-12-09: SMALLERDOT eingefuegt, EQUALSDOT entfernt, wenn ds Field privat ist muesste es EQUALSDOT lauten
constraint.add(new Pair(
fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
oderConstraints.add(constraint);
}
if (oderConstraints.size() == 0)
@ -176,17 +168,9 @@ public class TYPEStmt implements StatementVisitor{
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
methodConstraints.addAll(oneMethodConstraints);
/* pl 2023-01-20: in generateConstraint bereits umgesetzt
Constraint<Pair> extendsOneMethodConstraint = oneMethodConstraint.stream()
.map(x -> (x.TA1 instanceof TypePlaceholder &&
x.GetOperator() == PairOperator.EQUALSDOT &&
!(x.TA2 instanceof TypePlaceholder))
? new Pair(x.TA1, new ExtendsWildcardType(x.TA2, x.TA2.getOffset()), PairOperator.EQUALSDOT)
: x)
.collect(Collectors.toCollection(() -> new Constraint<Pair>(oneMethodConstraint.isInherited())));
oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint);
extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint);
methodConstraints.add(extendsOneMethodConstraint);
/*
* pl 2023-01-20: in generateConstraint bereits umgesetzt Constraint<Pair> extendsOneMethodConstraint = oneMethodConstraint.stream() .map(x -> (x.TA1 instanceof TypePlaceholder && x.GetOperator() == PairOperator.EQUALSDOT && !(x.TA2 instanceof TypePlaceholder)) ? new Pair(x.TA1, new ExtendsWildcardType(x.TA2, x.TA2.getOffset()), PairOperator.EQUALSDOT) : x) .collect(Collectors.toCollection(() -> new Constraint<Pair>(oneMethodConstraint.isInherited())));
* oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint); extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint); methodConstraints.add(extendsOneMethodConstraint);
*/
}
if (methodConstraints.size() < 1) {
@ -227,12 +211,10 @@ public class TYPEStmt implements StatementVisitor{
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken());
private final RefType string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
@Override
public void visit(UnaryExpr unaryExpr) {
if(unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT ||
unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT ||
unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT ||
unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT){
if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
// @see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
// Expression muss zu Numeric Convertierbar sein. also von Numeric erben
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT));
@ -249,11 +231,7 @@ public class TYPEStmt implements StatementVisitor{
public void visit(BinaryExpr binary) {
binary.lexpr.accept(this);
binary.rexpr.accept(this);
if(binary.operation.equals(BinaryExpr.Operator.DIV) ||
binary.operation.equals(BinaryExpr.Operator.MUL)||
binary.operation.equals(BinaryExpr.Operator.MOD)||
binary.operation.equals(BinaryExpr.Operator.ADD)||
binary.operation.equals(BinaryExpr.Operator.SUB)) {
if (binary.operation.equals(BinaryExpr.Operator.DIV) || binary.operation.equals(BinaryExpr.Operator.MUL) || binary.operation.equals(BinaryExpr.Operator.MOD) || binary.operation.equals(BinaryExpr.Operator.ADD) || binary.operation.equals(BinaryExpr.Operator.SUB)) {
Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
// TODO PL 2018-11-06
@ -261,8 +239,6 @@ public class TYPEStmt implements StatementVisitor{
// Auf importierte Typen einschraenken
// pruefen, ob Typen richtig bestimmt werden.
// Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer:
// see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17
// Expression muss zu Numeric Convertierbar sein. also von Numeric erben
@ -315,16 +291,11 @@ public class TYPEStmt implements StatementVisitor{
numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric);
}
/* PL auskommentiert Anfang 2018-07-17
/*
In Java passiert bei den binären Operatoren eine sogenannte Type Promotion:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben
numeric = new Constraint<>();
numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT));
numericAdditionOrStringConcatenation.add(numeric);
* PL auskommentiert Ende 2018-07-17 */
* PL auskommentiert Anfang 2018-07-17 /* In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben
*
* numeric = new Constraint<>(); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); PL auskommentiert Ende 2018-07-17
*/
if (binary.operation.equals(BinaryExpr.Operator.ADD)) {
// Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
@ -340,46 +311,14 @@ public class TYPEStmt implements StatementVisitor{
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
}
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
}else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) ||
binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) {
/* //eingefuegt PL 2018-05-24
Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>();
Constraint<Pair> numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
numericRelationConcatenation.add(numeric);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
constraintsSet.addOderConstraint(numericRelationConcatenation);
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
} else if (binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) {
/*
* //eingefuegt PL 2018-05-24 Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>(); Constraint<Pair> numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(),
* shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT));
* numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new
* Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric); numeric = new Constraint<>(); numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); numericRelationConcatenation.add(numeric);
*
* //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch constraintsSet.addOderConstraint(numericRelationConcatenation); //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/
// Testeise eingefuegt PL 2018-05-24
// Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
@ -394,8 +333,8 @@ public class TYPEStmt implements StatementVisitor{
// Rückgabetyp ist Boolean
// constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
} else if (binary.operation.equals(BinaryExpr.Operator.EQUAL) || binary.operation.equals(BinaryExpr.Operator.NOTEQUAL)) {
/*Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21
The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.
/*
* Auszug aus https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.21 The equality operators may be used to compare two operands that are convertible (§5.1.8) to numeric type, or two operands of type boolean or Boolean, or two operands that are each of either reference type or the null type. All other cases result in a compile-time error.
*/
// Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
@ -486,8 +425,7 @@ public class TYPEStmt implements StatementVisitor{
if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
return;
}
else {
} else {
throw new NotImplementedException();
}
}
@ -503,6 +441,11 @@ public class TYPEStmt implements StatementVisitor{
visit((Return) aReturn);
}
@Override
public void visit(Break aBreak) {
}
@Override
public void visit(StaticClassName staticClassName) {
// Hier entstehen keine Constraints
@ -522,8 +465,7 @@ public class TYPEStmt implements StatementVisitor{
params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
}
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(new Pair(
aThis.getType(), thisType, PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(new Pair(aThis.getType(), thisType, PairOperator.EQUALSDOT));
}
private static TypeScope createNullTypeScope() {
@ -574,24 +516,19 @@ public class TYPEStmt implements StatementVisitor{
}
/*
METHOD CALL Section:
* METHOD CALL Section:
*/
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint<Pair> methodConstraint, extendsMethodConstraint;
methodConstraint = new Constraint<>(assumption.isInherited());
extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall)
ClassOrInterface receiverCl = assumption.getReceiver();
/*
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiverCl.getGenerics()){
//Die Generics werden alle zu TPHs umgewandelt.
params.add(resolver.resolve(gtv.getName()));
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
* List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(gtv.getName())); }
*
* RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
@ -609,7 +546,6 @@ public class TYPEStmt implements StatementVisitor{
// PairOperator.EQUALSDOT));
// Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
@ -631,16 +567,13 @@ public class TYPEStmt implements StatementVisitor{
return ret;
}
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) {
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>();
for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
foMethod.arglist.getArguments().get(i).accept(this);
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
// Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
@ -650,9 +583,7 @@ public class TYPEStmt implements StatementVisitor{
return ret;
}
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver) {
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>();
for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
@ -675,12 +606,10 @@ public class TYPEStmt implements StatementVisitor{
List<GenericRefType> funNParams = new ArrayList<>();
for (int i = 0; i < numArgs + 1; i++) {
// funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(),
new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(), new NullToken()));
}
funNParams.get(funNParams.size() - 1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size()-1), funNParams.subList(0, funNParams.size()-1),
new TypeScope() {
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size() - 1), funNParams.subList(0, funNParams.size() - 1), new TypeScope() {
@Override
public Iterable<? extends GenericTypeVar> getGenerics() {
throw new NotImplementedException();
@ -694,12 +623,10 @@ public class TYPEStmt implements StatementVisitor{
}
for (ClassOrInterface cl : info.getAvailableClasses()) {
for (Method m : cl.getMethods()) {
if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){
if (m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs) {
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();// info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m), m.isInherited));
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(), info), createTypeScope(cl, m), m.isInherited));
}
}
}
@ -713,12 +640,9 @@ public class TYPEStmt implements StatementVisitor{
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info) {
// TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/*
BEispiel:
auto test = new List<String>();
test.add("hallo");
Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A>
Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
* BEispiel: auto test = new List<String>(); test.add("hallo");
*
* Hier kriegt der Receiver ja den COnstraint TPH REceiver <. List<TPH A> Dann mus bei dem Parameter der COnstraint entstehen: TPH A <. String
*/
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for (FormalParameter fp : parameterList.getFormalparalist()) {
@ -733,8 +657,7 @@ public class TYPEStmt implements StatementVisitor{
if (cl.getClassName().equals(ofType.getName())) {
for (Method m : cl.getConstructors()) {
if (m.getParameterList().getFormalparalist().size() == argList.getArguments().size()) {
ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(),
info), createTypeScope(cl, m), m.isInherited));
ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(), info), createTypeScope(cl, m), m.isInherited));
}
}
}
@ -742,13 +665,11 @@ public class TYPEStmt implements StatementVisitor{
return ret;
}
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
Constraint methodConstraint = new Constraint();
// WELCHEN SINN MACHT DIESER CONSTRAINT???
// Ist er nicht immer classname <. classname und damit redundant?
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(),
PairOperator.SMALLERDOT));
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), PairOperator.SMALLERDOT));
// WELCHEN SINN MACHT DIESER CONSTRAINT???
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver));
return methodConstraint;