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 Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
private GenericsRegistry generics; private GenericsRegistry generics;
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields,
Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
this.reg = reg; this.reg = reg;
this.generics = generics; this.generics = generics;
this.fields = fields; this.fields = fields;
@ -128,12 +126,9 @@ public class StatementGenerator {
return new ParameterList(ret, new NullToken()); // Dann ist die Parameterliste leer return new ParameterList(ret, new NullToken()); // Dann ist die Parameterliste leer
/* /*
* Restrukturierung Java17-Grammatik * 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.
* 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() == * if(formalParameterListContext.lastFormalParameter().formalParameter() == null) throw new NotImplementedException();
* null) throw new NotImplementedException();
*/ */
fps = formalParameterListContext.formalParameter(); fps = formalParameterListContext.formalParameter();
@ -158,46 +153,46 @@ public class StatementGenerator {
private Statement convert(Java17Parser.StatementContext stmt) { private Statement convert(Java17Parser.StatementContext stmt) {
switch (stmt) { switch (stmt) {
case BlockstmtContext blockstmt: case BlockstmtContext blockstmt:
return convert(blockstmt.block(), false); return convert(blockstmt.block(), false);
case ConditionalstmtContext condition: case ConditionalstmtContext condition:
return convert(condition); return convert(condition);
case WhileloopContext whileloop: case WhileloopContext whileloop:
return convert(whileloop); return convert(whileloop);
case DowhileloopContext dowhileloop: case DowhileloopContext dowhileloop:
return convert(dowhileloop); return convert(dowhileloop);
case SwitchstmtContext switchstmt: case SwitchstmtContext switchstmt:
return convert(switchstmt); return convert(switchstmt);
case SwitchexpressionstmtContext switchexpression: case SwitchexpressionstmtContext switchexpression:
return convert(switchexpression); return convert(switchexpression);
case ReturnstmtContext returnstmt: case ReturnstmtContext returnstmt:
return convert(returnstmt); return convert(returnstmt);
case YieldstmtContext yieldstmt: case YieldstmtContext yieldstmt:
return convert(yieldstmt); return convert(yieldstmt);
case StmtexpressionContext stmtexpression: case StmtexpressionContext stmtexpression:
return convert(stmtexpression); return convert(stmtexpression);
case AssertstmtContext assertstmt: case AssertstmtContext assertstmt:
return convert(assertstmt); return convert(assertstmt);
case ForloopContext forloop: case ForloopContext forloop:
return convert(forloop); return convert(forloop);
case TrycatchblockContext trycatchblock: case TrycatchblockContext trycatchblock:
return convert(trycatchblock); return convert(trycatchblock);
case TrycatchresourceContext trycatchresource: case TrycatchresourceContext trycatchresource:
return convert(trycatchresource); return convert(trycatchresource);
case SynchronizedstmtContext synchronizedstmt: case SynchronizedstmtContext synchronizedstmt:
return convert(synchronizedstmt); return convert(synchronizedstmt);
case ThrowstmtContext throwstmt: case ThrowstmtContext throwstmt:
return convert(throwstmt); return convert(throwstmt);
case BreakstmtContext breakstmt: case BreakstmtContext breakstmt:
return convert(breakstmt); return convert(breakstmt);
case ContinuestmtContext continuestmt: case ContinuestmtContext continuestmt:
return convert(continuestmt); return convert(continuestmt);
case SemistmtContext semistmt: case SemistmtContext semistmt:
return convert(semistmt); return convert(semistmt);
case LabeledstmtContext labeledstmt: case LabeledstmtContext labeledstmt:
return convert(labeledstmt); return convert(labeledstmt);
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@ -231,26 +226,26 @@ public class StatementGenerator {
ExpressionContext expr = stmt.statementExpression; ExpressionContext expr = stmt.statementExpression;
Token offset = stmt.getStart(); Token offset = stmt.getStart();
switch (expr) { switch (expr) {
case DottedexpressionContext dotted: case DottedexpressionContext dotted:
return convertToStatement(dotted, offset); return convertToStatement(dotted, offset);
case MethodcallexpressionContext methodc: case MethodcallexpressionContext methodc:
return convert(methodc.methodCall(), offset); return convert(methodc.methodCall(), offset);
case NewinstanceexpressionContext newinstance: case NewinstanceexpressionContext newinstance:
return convert(newinstance.creator()); return convert(newinstance.creator());
case AssignexpressionContext assignment: case AssignexpressionContext assignment:
Statement ret = convert(assignment); Statement ret = convert(assignment);
ret.setStatement(); ret.setStatement();
return ret; return ret;
case PostfixexpressionContext postfix: case PostfixexpressionContext postfix:
ret = convert(postfix); ret = convert(postfix);
ret.setStatement(); ret.setStatement();
return ret; return ret;
case PrefixexpressionContext prefix: case PrefixexpressionContext prefix:
ret = convert(prefix); ret = convert(prefix);
ret.setStatement(); ret.setStatement();
return ret; return ret;
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@ -272,9 +267,7 @@ public class StatementGenerator {
if (!Objects.isNull(creator.classCreatorRest())) { if (!Objects.isNull(creator.classCreatorRest())) {
ArgumentList args = convertArguments(creator.classCreatorRest().arguments().expressionList()); ArgumentList args = convertArguments(creator.classCreatorRest().arguments().expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream() ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream().map(x -> TypePlaceholder.fresh(creator.getStart())).collect(Collectors.toCollection(ArrayList::new));
.map(x -> TypePlaceholder.fresh(creator.getStart()))
.collect(Collectors.toCollection(ArrayList::new));
Statement ret = new NewClass(newclass, args, null, argTypes, creator.getStart()); Statement ret = new NewClass(newclass, args, null, argTypes, creator.getStart());
ret.setStatement(); ret.setStatement();
return ret; return ret;
@ -296,8 +289,7 @@ public class StatementGenerator {
throw new NotImplementedException(); throw new NotImplementedException();
} }
IdentifierContext identifier = createdname.identifier(); IdentifierContext identifier = createdname.identifier();
return (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, return (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, identifier.getStart(), reg, generics);
identifier.getStart(), reg, generics);
} }
private Statement convert(Java17Parser.InnerCreatorContext innercreator) { private Statement convert(Java17Parser.InnerCreatorContext innercreator) {
@ -307,12 +299,9 @@ public class StatementGenerator {
genericArgs = innercreator.nonWildcardTypeArgumentsOrDiamond().nonWildcardTypeArguments(); genericArgs = innercreator.nonWildcardTypeArgumentsOrDiamond().nonWildcardTypeArguments();
} }
IdentifierContext identifier = innercreator.identifier(); IdentifierContext identifier = innercreator.identifier();
RefType newclass = (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, RefType newclass = (RefType) TypeGenerator.convertTypeName(identifier.getText(), genericArgs, identifier.getStart(), reg, generics);
identifier.getStart(), reg, generics);
ArgumentList args = convertArguments(innercreator.classCreatorRest().arguments().expressionList()); ArgumentList args = convertArguments(innercreator.classCreatorRest().arguments().expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream() ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = args.getArguments().stream().map(x -> TypePlaceholder.fresh(innercreator.getStart())).collect(Collectors.toCollection(ArrayList::new));
.map(x -> TypePlaceholder.fresh(innercreator.getStart()))
.collect(Collectors.toCollection(ArrayList::new));
Statement ret = new NewClass(newclass, args, null, argTypes, innercreator.getStart()); Statement ret = new NewClass(newclass, args, null, argTypes, innercreator.getStart());
ret.setStatement(); ret.setStatement();
return ret; return ret;
@ -394,16 +383,14 @@ public class StatementGenerator {
} }
if (Objects.isNull(declaration.variableDeclarators())) { if (Objects.isNull(declaration.variableDeclarators())) {
Token offset = declaration.identifier().getStart(); Token offset = declaration.identifier().getStart();
ret.add(new Assign(new AssignToLocal(new LocalVar(declaration.identifier().getText(), type, offset)), ret.add(new Assign(new AssignToLocal(new LocalVar(declaration.identifier().getText(), type, offset)), convert(declaration.expression()), offset));
convert(declaration.expression()), offset));
} else { } else {
ret.addAll(generateLocalVariableAssignments(declaration.variableDeclarators().variableDeclarator(), type)); ret.addAll(generateLocalVariableAssignments(declaration.variableDeclarators().variableDeclarator(), type));
} }
return ret; return ret;
} }
private List<Statement> generateLocalVariableAssignments( private List<Statement> generateLocalVariableAssignments(List<Java17Parser.VariableDeclaratorContext> varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type) {
List<Java17Parser.VariableDeclaratorContext> varDeclarators, RefTypeOrTPHOrWildcardOrGeneric type) {
List<Statement> ret = new ArrayList<>(); List<Statement> ret = new ArrayList<>();
for (Java17Parser.VariableDeclaratorContext varDecl : varDeclarators) { for (Java17Parser.VariableDeclaratorContext varDecl : varDeclarators) {
IdentifierContext name = varDecl.variableDeclaratorId().identifier(); IdentifierContext name = varDecl.variableDeclaratorId().identifier();
@ -417,15 +404,13 @@ public class StatementGenerator {
} else { } else {
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getStart())), initValue, ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getStart())), initValue, name.getStart()));
name.getStart()));
} }
} }
return ret; return ret;
} }
public Statement generateFieldAssignment(Java17Parser.VariableDeclaratorContext varDecl, public Statement generateFieldAssignment(Java17Parser.VariableDeclaratorContext varDecl, RefTypeOrTPHOrWildcardOrGeneric type) {
RefTypeOrTPHOrWildcardOrGeneric type) {
IdentifierContext name = varDecl.variableDeclaratorId().identifier(); IdentifierContext name = varDecl.variableDeclaratorId().identifier();
Expression initValue; Expression initValue;
if (varDecl.variableInitializer().arrayInitializer() != null) { if (varDecl.variableInitializer().arrayInitializer() != null) {
@ -433,10 +418,7 @@ public class StatementGenerator {
} else { } else {
initValue = convert(varDecl.variableInitializer().expression()); initValue = convert(varDecl.variableInitializer().expression());
} }
return (new Assign(new AssignToField( return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
new FieldVar(new This(varDecl.getStart()), name.getText(),
type, varDecl.getStart())),
initValue, name.getStart()));
} }
private Statement convert(Java17Parser.BreakstmtContext stmt) { private Statement convert(Java17Parser.BreakstmtContext stmt) {
@ -488,55 +470,53 @@ public class StatementGenerator {
private Expression convert(Java17Parser.ExpressionContext expression) { private Expression convert(Java17Parser.ExpressionContext expression) {
switch (expression) { switch (expression) {
case PrimaryexpressionContext primary: case PrimaryexpressionContext primary:
return convert(primary.primary()); return convert(primary.primary());
case DottedexpressionContext dotted: case DottedexpressionContext dotted:
return convert((DottedexpressionContext) expression, expression.getStart()); return convert((DottedexpressionContext) expression, expression.getStart());
case MethodcallexpressionContext methodcall: case MethodcallexpressionContext methodcall:
return convert(methodcall.methodCall(), methodcall.getStart()); return convert(methodcall.methodCall(), methodcall.getStart());
case NewinstanceexpressionContext newinstance: case NewinstanceexpressionContext newinstance:
return convert(newinstance.creator()); return convert(newinstance.creator());
case CastexpressionContext castexpr: case CastexpressionContext castexpr:
return convert(castexpr); return convert(castexpr);
case PostfixexpressionContext postfexpr: case PostfixexpressionContext postfexpr:
return convert(postfexpr); return convert(postfexpr);
case PrefixexpressionContext prefexpr: case PrefixexpressionContext prefexpr:
return convert(prefexpr); return convert(prefexpr);
case MathmuldivmodexpressionContext mathexpr: case MathmuldivmodexpressionContext mathexpr:
return convert(mathexpr); return convert(mathexpr);
case MathaddsubexpressionContext mathexpr: case MathaddsubexpressionContext mathexpr:
return convert(mathexpr); return convert(mathexpr);
case RelationalexpressionContext comparison: case RelationalexpressionContext comparison:
return convert(comparison); return convert(comparison);
/* /*
* TODO: syntaxtree for instanceof vorbereiten * TODO: syntaxtree for instanceof vorbereiten case InstanceofexpressionContext instanceof: case SwitchexpressionContext switchexpression:
* case InstanceofexpressionContext instanceof: */
* case SwitchexpressionContext switchexpression: case EqualityexpressionContext equal:
*/ return convert(equal);
case EqualityexpressionContext equal: case AssignexpressionContext assignment:
return convert(equal); return convert(assignment);
case AssignexpressionContext assignment: case LambdaexpressionContext lambdaexpr:
return convert(assignment); return convert(lambdaexpr.lambdaExpression());
case LambdaexpressionContext lambdaexpr: case ArrayaccessexpressionContext arrayaccess:
return convert(lambdaexpr.lambdaExpression()); return convert(arrayaccess);
case ArrayaccessexpressionContext arrayaccess: case ShiftexpressionContext shiftexpr:
return convert(arrayaccess); return convert(shiftexpr);
case ShiftexpressionContext shiftexpr: case BitwiseandexpressionContext bitwiseand:
return convert(shiftexpr); return convert(bitwiseand);
case BitwiseandexpressionContext bitwiseand: case BitwisexorexpressionContext bitwisexor:
return convert(bitwiseand); return convert(bitwisexor);
case BitwisexorexpressionContext bitwisexor: case BitwiseorexpressionContext bitwiseor:
return convert(bitwisexor); return convert(bitwiseor);
case BitwiseorexpressionContext bitwiseor: case AndexpressionContext andexpr:
return convert(bitwiseor); return convert(andexpr);
case AndexpressionContext andexpr: case OrexpressionContext orexpr:
return convert(andexpr); return convert(orexpr);
case OrexpressionContext orexpr: case ConditionalassignexpressionContext condassign:
return convert(orexpr); return convert(condassign);
case ConditionalassignexpressionContext condassign: default:
return convert(condassign); throw new NotImplementedException();
default:
throw new NotImplementedException();
} }
} }
@ -566,13 +546,9 @@ public class StatementGenerator {
} }
ArgumentList argumentList = convertArguments(expr.expressionList()); ArgumentList argumentList = convertArguments(expr.expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream() ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
.map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset))
.collect(Collectors.toCollection(ArrayList::new));
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), argTypes, offset);
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset),
argTypes, offset);
ret.setStatement(); ret.setStatement();
return ret; return ret;
} }
@ -586,13 +562,9 @@ public class StatementGenerator {
name = expr.SUPER().getText(); name = expr.SUPER().getText();
} }
ArgumentList argumentList = convertArguments(expr.expressionList()); ArgumentList argumentList = convertArguments(expr.expressionList());
ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream() ArrayList<RefTypeOrTPHOrWildcardOrGeneric> argTypes = argumentList.getArguments().stream().map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset)).collect(Collectors.toCollection(ArrayList::new));
.map(x -> (RefTypeOrTPHOrWildcardOrGeneric) TypePlaceholder.fresh(offset))
.collect(Collectors.toCollection(ArrayList::new));
MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), MethodCall ret = new MethodCall(TypePlaceholder.fresh(offset), getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset), argTypes, offset);
getReceiver(receiver), name, argumentList, TypePlaceholder.fresh(offset),
argTypes, offset);
ret.setStatement(); ret.setStatement();
return ret; return ret;
} }
@ -616,8 +588,7 @@ public class StatementGenerator {
} }
/** /**
* Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und * Der Parser kann nicht zwischen einer lokalen Variable, einem Feldzugriff und einer Klassenangabe unterscheiden.
* einer Klassenangabe unterscheiden.
* *
* @param expression * @param expression
* @param offset * @param offset
@ -686,24 +657,24 @@ public class StatementGenerator {
private Statement convert(AssignexpressionContext expr) { private Statement convert(AssignexpressionContext expr) {
switch (expr.bop.getText()) { switch (expr.bop.getText()) {
case "=": case "=":
ExpressionContext leftside = expr.expression(0); ExpressionContext leftside = expr.expression(0);
AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart()); AssignLeftSide leftHandSide = convert(leftside.getText(), leftside.getStart());
Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart()); Statement ret = new Assign(leftHandSide, convert(expr.expression(1)), expr.getStart());
return ret; return ret;
case "+=": case "+=":
case "-=": case "-=":
case "*=": case "*=":
case "/=": case "/=":
case "&=": case "&=":
case "|=": case "|=":
case "^=": case "^=":
case ">>=": case ">>=":
case ">>>=": case ">>>=":
case "<<=": case "<<=":
case "%=": case "%=":
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@ -733,15 +704,12 @@ public class StatementGenerator {
String operator = expression.bop.getText(); String operator = expression.bop.getText();
Expression leftSide = convert(expression.expression(0)); Expression leftSide = convert(expression.expression(0));
Expression rightSide = convert(expression.expression(1)); Expression rightSide = convert(expression.expression(1));
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), leftSide, rightSide, expression.getStart());
leftSide, rightSide, expression.getStart());
} }
private Expression convert(Java17Parser.RelationalexpressionContext expression) { private Expression convert(Java17Parser.RelationalexpressionContext expression) {
String operator = expression.bop.getText(); String operator = expression.bop.getText();
return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), return new BinaryExpr(convertBinaryOperator(operator), TypePlaceholder.fresh(expression.getStart()), convert(expression.expression(0)), convert(expression.expression(1)), expression.getStart());
convert(expression.expression(0)),
convert(expression.expression(1)), expression.getStart());
} }
private BinaryExpr.Operator convertBinaryOperator(String operator) { private BinaryExpr.Operator convertBinaryOperator(String operator) {
@ -817,12 +785,12 @@ public class StatementGenerator {
Expression expr = convert(postfixexpr.expression()); Expression expr = convert(postfixexpr.expression());
Token op = postfixexpr.postfix; Token op = postfixexpr.postfix;
switch (op.getText()) { switch (op.getText()) {
case "++": case "++":
return new UnaryExpr(UnaryExpr.Operation.POSTINCREMENT, expr, TypePlaceholder.fresh(op), op); return new UnaryExpr(UnaryExpr.Operation.POSTINCREMENT, expr, TypePlaceholder.fresh(op), op);
case "--": case "--":
return new UnaryExpr(UnaryExpr.Operation.POSTDECREMENT, expr, TypePlaceholder.fresh(op), op); return new UnaryExpr(UnaryExpr.Operation.POSTDECREMENT, expr, TypePlaceholder.fresh(op), op);
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@ -831,52 +799,49 @@ public class StatementGenerator {
if (expr instanceof PrefixexpressionContext pfe) { if (expr instanceof PrefixexpressionContext pfe) {
throw new NotImplementedException(); throw new NotImplementedException();
} }
return new CastExpr(TypeGenerator.convert(castexpr.typeType(0), reg, generics), convert(expr), return new CastExpr(TypeGenerator.convert(castexpr.typeType(0), reg, generics), convert(expr), expr.getStart());
expr.getStart());
} }
private Expression convert(Java17Parser.PrimaryContext primary) { private Expression convert(Java17Parser.PrimaryContext primary) {
switch (primary) { switch (primary) {
case PrimaryExpressionContext primexpression: case PrimaryExpressionContext primexpression:
return convert(primexpression.expression()); return convert(primexpression.expression());
case PrimaryThisContext primthis: case PrimaryThisContext primthis:
return new This(primthis.getStart()); return new This(primthis.getStart());
case PrimarySuperContext primsuper: case PrimarySuperContext primsuper:
throw new NotImplementedException(); throw new NotImplementedException();
case PrimaryLiteralContext primliteral: case PrimaryLiteralContext primliteral:
return convert(primliteral.literal()); return convert(primliteral.literal());
case PrimaryIdentifierContext primidentifier: case PrimaryIdentifierContext primidentifier:
return new LocalVar(primidentifier.getText(), TypePlaceholder.fresh(primidentifier.getStart()), return new LocalVar(primidentifier.getText(), TypePlaceholder.fresh(primidentifier.getStart()), primidentifier.getStart());
primidentifier.getStart()); case PrimaryClassrefContext primclassref:
case PrimaryClassrefContext primclassref: throw new NotImplementedException();
throw new NotImplementedException(); default:
default: throw new NotImplementedException();
throw new NotImplementedException();
} }
} }
private Expression convert(Java17Parser.LiteralContext literal) { private Expression convert(Java17Parser.LiteralContext literal) {
switch (literal) { switch (literal) {
case IntLiteralContext intliteral: case IntLiteralContext intliteral:
Number value = Integer.parseInt(intliteral.getText()); Number value = Integer.parseInt(intliteral.getText());
return new Literal(TypePlaceholder.fresh(literal.getStart()), value, intliteral.getStart()); return new Literal(TypePlaceholder.fresh(literal.getStart()), value, intliteral.getStart());
case FltLiteralContext floatliteral: case FltLiteralContext floatliteral:
value = Double.parseDouble(floatliteral.getText()); value = Double.parseDouble(floatliteral.getText());
return new Literal(TypePlaceholder.fresh(literal.getStart()), value, floatliteral.getStart()); return new Literal(TypePlaceholder.fresh(literal.getStart()), value, floatliteral.getStart());
case CharLiteralContext charliteral: case CharLiteralContext charliteral:
RefType type = new RefType(reg.getName("java.lang.Character"), charliteral.getStart()); RefType type = new RefType(reg.getName("java.lang.Character"), charliteral.getStart());
return new Literal(type, charliteral.getText().charAt(1), charliteral.getStart()); return new Literal(type, charliteral.getText().charAt(1), charliteral.getStart());
case StringLiteralContext stringliteral: case StringLiteralContext stringliteral:
type = new RefType(reg.getName("java.lang.String"), stringliteral.getStart()); type = new RefType(reg.getName("java.lang.String"), stringliteral.getStart());
return new Literal(type, stringliteral.getText().substring(1, stringliteral.getText().length() - 1), return new Literal(type, stringliteral.getText().substring(1, stringliteral.getText().length() - 1), stringliteral.getStart());
stringliteral.getStart()); case BoolLiteralContext boolliteral:
case BoolLiteralContext boolliteral: type = new RefType(reg.getName("java.lang.Boolean"), boolliteral.getStart());
type = new RefType(reg.getName("java.lang.Boolean"), boolliteral.getStart()); return new Literal(type, Boolean.parseBoolean(boolliteral.getText()), boolliteral.getStart());
return new Literal(type, Boolean.parseBoolean(boolliteral.getText()), boolliteral.getStart()); case NullLiteralContext nullliteral:
case NullLiteralContext nullliteral: return new Literal(TypePlaceholder.fresh(nullliteral.getStart()), null, nullliteral.getStart());
return new Literal(TypePlaceholder.fresh(nullliteral.getStart()), null, nullliteral.getStart()); default:
default: throw new NotImplementedException();
throw new NotImplementedException();
} }
} }
@ -887,8 +852,7 @@ public class StatementGenerator {
List<FormalParameter> parameterList = new ArrayList<>(); List<FormalParameter> parameterList = new ArrayList<>();
for (IdentifierContext identifier : lambdaParams.identifier()) { for (IdentifierContext identifier : lambdaParams.identifier()) {
Token offset = identifier.getStart(); Token offset = identifier.getStart();
parameterList.add(new FormalParameter(identifier.getText(), parameterList.add(new FormalParameter(identifier.getText(), TypePlaceholder.fresh(offset), offset));
TypePlaceholder.fresh(offset), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else if (lambdaParams.formalParameterList() != null) { } else if (lambdaParams.formalParameterList() != null) {
@ -898,8 +862,7 @@ public class StatementGenerator {
List<FormalParameter> parameterList = new ArrayList<>(); List<FormalParameter> parameterList = new ArrayList<>();
for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) { for (LambdaLVTIParameterContext param : lambdaParams.lambdaLVTIList().lambdaLVTIParameter()) {
Token offset = param.getStart(); Token offset = param.getStart();
parameterList.add(new FormalParameter(param.identifier().getText(), parameterList.add(new FormalParameter(param.identifier().getText(), TypePlaceholder.fresh(offset), offset));
TypePlaceholder.fresh(offset), offset));
} }
params = new ParameterList(parameterList, lambdaParams.getStart()); params = new ParameterList(parameterList, lambdaParams.getStart());
} else { } else {
@ -916,8 +879,7 @@ public class StatementGenerator {
Block block; Block block;
if (expression.lambdaBody().expression() != null) { if (expression.lambdaBody().expression() != null) {
List<Statement> statements = new ArrayList<>(); List<Statement> statements = new ArrayList<>();
statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()), statements.add(new Return(lambdaGenerator.convert(expression.lambdaBody().expression()), expression.lambdaBody().expression().getStart()));
expression.lambdaBody().expression().getStart()));
block = new Block(statements, expression.lambdaBody().getStart()); block = new Block(statements, expression.lambdaBody().getStart());
} else { } else {
block = lambdaGenerator.convert(expression.lambdaBody().block(), true); block = lambdaGenerator.convert(expression.lambdaBody().block(), true);

View File

@ -10,19 +10,21 @@ import java.util.List;
public class SyntacticSugar { public class SyntacticSugar {
public static List<Statement> addTrailingReturn(List<Statement> statements){ public static List<Statement> addTrailingReturn(List<Statement> statements) {
if(statements.size()!=0) { if (statements.size() != 0) {
Statement lastStmt = statements.get(statements.size() - 1); Statement lastStmt = statements.get(statements.size() - 1);
ReturnFinder hasReturn = new ReturnFinder(); ReturnFinder hasReturn = new ReturnFinder();
lastStmt.accept(hasReturn); lastStmt.accept(hasReturn);
if(hasReturn.hasReturn)return statements; if (hasReturn.hasReturn)
return statements;
} }
statements.add(new ReturnVoid(new NullToken())); statements.add(new ReturnVoid(new NullToken()));
return statements; return statements;
} }
private static class ReturnFinder extends AbstractASTWalker{ private static class ReturnFinder extends AbstractASTWalker {
public boolean hasReturn = false; public boolean hasReturn = false;
@Override @Override
public void visit(Return aReturn) { public void visit(Return aReturn) {
hasReturn = true; hasReturn = true;
@ -34,9 +36,10 @@ public class SyntacticSugar {
} }
} }
private static boolean hasReturn(Block block){ private static boolean hasReturn(Block block) {
for(Statement s : block.getStatements()) for (Statement s : block.getStatements())
if(s instanceof Return)return true; if (s instanceof Return)
return true;
return false; return false;
} }

View File

@ -7,7 +7,7 @@ import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.Iterator; import java.util.Iterator;
public abstract class AbstractASTWalker implements ASTVisitor{ public abstract class AbstractASTWalker implements ASTVisitor {
@Override @Override
public void visit(Constructor cons) { public void visit(Constructor cons) {
visitMethod(cons); visitMethod(cons);
@ -15,14 +15,14 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(SourceFile sourceFile) { public void visit(SourceFile sourceFile) {
for(ClassOrInterface cl : sourceFile.getClasses()){ for (ClassOrInterface cl : sourceFile.getClasses()) {
cl.accept(this); cl.accept(this);
} }
} }
@Override @Override
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
for(Expression expr : argumentList.getArguments()){ for (Expression expr : argumentList.getArguments()) {
expr.accept(this); expr.accept(this);
} }
} }
@ -40,8 +40,8 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(GenericDeclarationList genericTypeVars) { public void visit(GenericDeclarationList genericTypeVars) {
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator(); Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
if(genericIterator.hasNext()){ if (genericIterator.hasNext()) {
while(genericIterator.hasNext()){ while (genericIterator.hasNext()) {
genericIterator.next().accept(this); genericIterator.next().accept(this);
} }
} }
@ -57,18 +57,18 @@ public abstract class AbstractASTWalker implements ASTVisitor{
visitMethod(method); visitMethod(method);
} }
private void visitMethod(Method method){ private void visitMethod(Method method) {
method.getReturnType().accept(this); method.getReturnType().accept(this);
method.getParameterList().accept(this); method.getParameterList().accept(this);
if(method.block != null) if (method.block != null)
method.block.accept(this); method.block.accept(this);
} }
@Override @Override
public void visit(ParameterList formalParameters) { public void visit(ParameterList formalParameters) {
Iterator<FormalParameter> it = formalParameters.getFormalparalist().iterator(); Iterator<FormalParameter> it = formalParameters.getFormalparalist().iterator();
if(it.hasNext()){ if (it.hasNext()) {
while(it.hasNext()){ while (it.hasNext()) {
it.next().accept(this); it.next().accept(this);
} }
} }
@ -77,13 +77,13 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
classOrInterface.getGenerics().accept(this); classOrInterface.getGenerics().accept(this);
for(Field f : classOrInterface.getFieldDecl()){ for (Field f : classOrInterface.getFieldDecl()) {
f.accept(this); f.accept(this);
} }
for(Constructor c : classOrInterface.getConstructors()){ for (Constructor c : classOrInterface.getConstructors()) {
c.accept(this); c.accept(this);
} }
for(Method m : classOrInterface.getMethods()){ for (Method m : classOrInterface.getMethods()) {
m.accept(this); m.accept(this);
} }
} }
@ -91,8 +91,8 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(RefType refType) { public void visit(RefType refType) {
Iterator<RefTypeOrTPHOrWildcardOrGeneric> genericIterator = refType.getParaList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> genericIterator = refType.getParaList().iterator();
if(genericIterator.hasNext()){ if (genericIterator.hasNext()) {
while(genericIterator.hasNext()){ while (genericIterator.hasNext()) {
genericIterator.next().accept(this); genericIterator.next().accept(this);
} }
} }
@ -136,7 +136,7 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(Block block) { public void visit(Block block) {
for(Statement stmt : block.getStatements()){ for (Statement stmt : block.getStatements()) {
stmt.accept(this); stmt.accept(this);
} }
} }
@ -177,7 +177,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
} }
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
localVarDecl.getType().accept(this); localVarDecl.getType().accept(this);
@ -190,7 +189,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
methodCall.getArgumentList().getArguments().forEach(a -> a.getType().accept((ASTVisitor) this)); methodCall.getArgumentList().getArguments().forEach(a -> a.getType().accept((ASTVisitor) this));
} }
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
visit((MethodCall) methodCall); visit((MethodCall) methodCall);
@ -222,6 +220,11 @@ public abstract class AbstractASTWalker implements ASTVisitor{
} }
@Override
public void visit(Break aBreak) {
aBreak.accept(this);
}
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
@ -264,6 +267,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
this.visit((MethodCall)superCall); this.visit((MethodCall) superCall);
} }
} }

View File

@ -41,6 +41,8 @@ public interface StatementVisitor {
void visit(ReturnVoid aReturn); void visit(ReturnVoid aReturn);
void visit(Break aBreak);
void visit(StaticClassName staticClassName); void visit(StaticClassName staticClassName);
void visit(Super aSuper); 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,14 +3,11 @@ package de.dhbwstuttgart.syntaxtree.statement;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
public class Return extends Statement {
public class Return extends Statement
{
public final Expression retexpr; public final Expression retexpr;
public Return(Expression retExpr, Token offset) public Return(Expression retExpr, Token offset) {
{ super(retExpr.getType(), offset);
super(retExpr.getType(),offset);
this.retexpr = retExpr; this.retexpr = retExpr;
} }

View File

@ -9,12 +9,12 @@ import java.lang.reflect.Modifier;
import java.util.Iterator; import java.util.Iterator;
import java.util.Optional; import java.util.Optional;
public class OutputGenerator implements ASTVisitor{ public class OutputGenerator implements ASTVisitor {
private static final String TAB = " "; private static final String TAB = " ";
String tabs = ""; String tabs = "";
protected final StringBuilder out; protected final StringBuilder out;
public OutputGenerator(StringBuilder out){ public OutputGenerator(StringBuilder out) {
this.out = out; this.out = out;
} }
@ -23,12 +23,12 @@ public class OutputGenerator implements ASTVisitor{
} }
public void untab() { public void untab() {
tabs = tabs.substring(0,tabs.length()-TAB.length()); tabs = tabs.substring(0, tabs.length() - TAB.length());
} }
@Override @Override
public void visit(SourceFile sourceFile) { public void visit(SourceFile sourceFile) {
for(ClassOrInterface cl : sourceFile.getClasses()){ for (ClassOrInterface cl : sourceFile.getClasses()) {
cl.accept(this); cl.accept(this);
} }
} }
@ -37,9 +37,10 @@ public class OutputGenerator implements ASTVisitor{
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
out.append("("); out.append("(");
Iterator<Expression> expressionIterator = argumentList.getArguments().iterator(); Iterator<Expression> expressionIterator = argumentList.getArguments().iterator();
while(expressionIterator.hasNext()){ while (expressionIterator.hasNext()) {
expressionIterator.next().accept(this); expressionIterator.next().accept(this);
if(expressionIterator.hasNext())out.append(", "); if (expressionIterator.hasNext())
out.append(", ");
} }
out.append(")"); out.append(")");
} }
@ -59,11 +60,12 @@ public class OutputGenerator implements ASTVisitor{
@Override @Override
public void visit(GenericDeclarationList genericTypeVars) { public void visit(GenericDeclarationList genericTypeVars) {
Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator(); Iterator<GenericTypeVar> genericIterator = genericTypeVars.iterator();
if(genericIterator.hasNext()){ if (genericIterator.hasNext()) {
out.append("<"); out.append("<");
while(genericIterator.hasNext()){ while (genericIterator.hasNext()) {
genericIterator.next().accept(this); genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", "); if (genericIterator.hasNext())
out.append(", ");
} }
out.append(">"); out.append(">");
} }
@ -82,7 +84,7 @@ public class OutputGenerator implements ASTVisitor{
method.getReturnType().accept(this); method.getReturnType().accept(this);
out.append(" " + method.getName()); out.append(" " + method.getName());
method.getParameterList().accept(this); method.getParameterList().accept(this);
if(method.block != null) if (method.block != null)
method.block.accept(this); method.block.accept(this);
out.append("\n"); out.append("\n");
} }
@ -99,10 +101,11 @@ public class OutputGenerator implements ASTVisitor{
public void visit(ParameterList formalParameters) { public void visit(ParameterList formalParameters) {
out.append("("); out.append("(");
Iterator<FormalParameter> genericIterator = formalParameters.getFormalparalist().iterator(); Iterator<FormalParameter> genericIterator = formalParameters.getFormalparalist().iterator();
if(genericIterator.hasNext()){ if (genericIterator.hasNext()) {
while(genericIterator.hasNext()){ while (genericIterator.hasNext()) {
genericIterator.next().accept(this); genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", "); if (genericIterator.hasNext())
out.append(", ");
} }
} }
out.append(")"); out.append(")");
@ -110,29 +113,29 @@ public class OutputGenerator implements ASTVisitor{
@Override @Override
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
if((Modifier.INTERFACE & classOrInterface.getModifiers()) == 1){ if ((Modifier.INTERFACE & classOrInterface.getModifiers()) == 1) {
out.append("interface "); out.append("interface ");
}else{ } else {
out.append("class "); out.append("class ");
} }
out.append(classOrInterface.getClassName().toString()); out.append(classOrInterface.getClassName().toString());
classOrInterface.getGenerics().accept(this); classOrInterface.getGenerics().accept(this);
out.append(" {\n\n"); out.append(" {\n\n");
tab(); tab();
for(Field f : classOrInterface.getFieldDecl()){ for (Field f : classOrInterface.getFieldDecl()) {
out.append(tabs); out.append(tabs);
f.accept(this); f.accept(this);
out.append("\n"); out.append("\n");
} }
if (classOrInterface.getfieldInitializations().isPresent()) {//PL 2019-11-28: Zum Ausdrucken der Fieldinitializer if (classOrInterface.getfieldInitializations().isPresent()) {// PL 2019-11-28: Zum Ausdrucken der Fieldinitializer
classOrInterface.getfieldInitializations().get().accept(this); classOrInterface.getfieldInitializations().get().accept(this);
} }
for(Method m : classOrInterface.getMethods()){ for (Method m : classOrInterface.getMethods()) {
out.append(tabs); out.append(tabs);
m.accept(this); m.accept(this);
out.append("\n"); out.append("\n");
} }
for(Constructor m : classOrInterface.getConstructors()){ for (Constructor m : classOrInterface.getConstructors()) {
out.append(tabs); out.append(tabs);
m.accept(this); m.accept(this);
out.append("\n"); out.append("\n");
@ -145,11 +148,12 @@ public class OutputGenerator implements ASTVisitor{
public void visit(RefType refType) { public void visit(RefType refType) {
out.append(refType.getName().toString()); out.append(refType.getName().toString());
Iterator<RefTypeOrTPHOrWildcardOrGeneric> genericIterator = refType.getParaList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> genericIterator = refType.getParaList().iterator();
if(genericIterator.hasNext()){ if (genericIterator.hasNext()) {
out.append("<"); out.append("<");
while(genericIterator.hasNext()){ while (genericIterator.hasNext()) {
genericIterator.next().accept(this); genericIterator.next().accept(this);
if(genericIterator.hasNext())out.append(", "); if (genericIterator.hasNext())
out.append(", ");
} }
out.append(">"); out.append(">");
} }
@ -163,7 +167,7 @@ public class OutputGenerator implements ASTVisitor{
@Override @Override
public void visit(TypePlaceholder typePlaceholder) { public void visit(TypePlaceholder typePlaceholder) {
out.append("TPH "+ typePlaceholder.getName()); out.append("TPH " + typePlaceholder.getName());
} }
@Override @Override
@ -202,7 +206,7 @@ public class OutputGenerator implements ASTVisitor{
public void visit(Block block) { public void visit(Block block) {
tab(); tab();
out.append("{\n"); out.append("{\n");
for(Statement stmt : block.getStatements()){ for (Statement stmt : block.getStatements()) {
out.append(tabs); out.append(tabs);
stmt.accept(this); stmt.accept(this);
out.append(";\n"); out.append(";\n");
@ -242,7 +246,7 @@ public class OutputGenerator implements ASTVisitor{
out.append(tabs); out.append(tabs);
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
untab(); untab();
if(ifStmt.else_block != null){ if (ifStmt.else_block != null) {
out.append("\n" + tabs + "else\n"); out.append("\n" + tabs + "else\n");
tab(); tab();
out.append(tabs); out.append(tabs);
@ -270,8 +274,8 @@ public class OutputGenerator implements ASTVisitor{
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
out.append("."+methodCall.name); out.append("." + methodCall.name);
out.append(" Signature: "+methodCall.signature); out.append(" Signature: " + methodCall.signature);
methodCall.getArgumentList().accept(this); methodCall.getArgumentList().accept(this);
} }
@ -298,6 +302,11 @@ public class OutputGenerator implements ASTVisitor{
out.append("return"); out.append("return");
} }
@Override
public void visit(Break aBreak) {
out.append("break");
}
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
@ -354,23 +363,23 @@ public class OutputGenerator implements ASTVisitor{
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
if(unaryExpr.operation == UnaryExpr.Operation.MINUS){ if (unaryExpr.operation == UnaryExpr.Operation.MINUS) {
out.append("-"); out.append("-");
} }
if(unaryExpr.operation == UnaryExpr.Operation.PLUS){ if (unaryExpr.operation == UnaryExpr.Operation.PLUS) {
out.append("+"); out.append("+");
} }
if(unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT){ if (unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT) {
out.append("--"); out.append("--");
} }
if(unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT){ if (unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
out.append("++"); out.append("++");
} }
unaryExpr.expr.accept(this); unaryExpr.expr.accept(this);
if(unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT){ if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT) {
out.append("--"); out.append("--");
} }
if(unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT){ if (unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT) {
out.append("++"); out.append("++");
} }
} }

View File

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

View File

@ -32,20 +32,20 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override @Override
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
var parameters = StreamSupport var parameters = StreamSupport.stream(lambdaExpression.params.spliterator(), false).map(p -> new MethodParameter(converter.convert(p.getType()), p.getName())).toList();
.stream(lambdaExpression.params.spliterator(), false)
.map(p -> new MethodParameter(converter.convert(p.getType()), p.getName()))
.toList();
List<MethodParameter> captures = new ArrayList<>(); List<MethodParameter> captures = new ArrayList<>();
lambdaExpression.methodBody.accept(new TracingStatementVisitor() { lambdaExpression.methodBody.accept(new TracingStatementVisitor() {
// TODO The same mechanism is implemented in Codegen, maybe use it from there? // TODO The same mechanism is implemented in Codegen, maybe use it from there?
final Stack<Set<String>> localVariables = new Stack<>(); final Stack<Set<String>> localVariables = new Stack<>();
{ localVariables.push(new HashSet<>()); } {
localVariables.push(new HashSet<>());
}
boolean hasLocalVar(String name) { boolean hasLocalVar(String name) {
for (var localVariables : this.localVariables) { for (var localVariables : this.localVariables) {
if (localVariables.contains(name)) return true; if (localVariables.contains(name))
return true;
} }
return false; return false;
} }
@ -72,13 +72,11 @@ public class StatementToTargetExpression implements StatementVisitor {
} }
@Override @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( result = new TargetLambdaExpression(converter.convert(lambdaExpression.getType()), captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody));
converter.convert(lambdaExpression.getType()),
captures, parameters, converter.convert(lambdaExpression.getReturnType()), converter.convert(lambdaExpression.methodBody)
);
} }
@Override @Override
@ -96,19 +94,19 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override @Override
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
result = switch (binary.operation) { result = switch (binary.operation) {
case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case ADD -> new TargetBinaryOp.Add(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case SUB -> new TargetBinaryOp.Sub(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case MUL -> new TargetBinaryOp.Mul(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case MOD -> new TargetBinaryOp.Rem(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case AND -> new TargetBinaryOp.And(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case AND -> new TargetBinaryOp.And(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case OR -> new TargetBinaryOp.Or(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case OR -> new TargetBinaryOp.Or(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case DIV -> new TargetBinaryOp.Div(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case LESSTHAN -> new TargetBinaryOp.Less(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case BIGGERTHAN -> new TargetBinaryOp.Greater(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case LESSEQUAL -> new TargetBinaryOp.LessOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case BIGGEREQUAL -> new TargetBinaryOp.GreaterOrEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case EQUAL -> new TargetBinaryOp.Equal(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr)); case NOTEQUAL -> new TargetBinaryOp.NotEqual(converter.convert(binary.getType()), converter.convert(binary.lexpr), converter.convert(binary.rexpr));
}; };
} }
@ -129,12 +127,7 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
result = new TargetFieldVar( result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), false, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
converter.convert(fieldVar.getType()),
converter.convert(fieldVar.receiver.getType()),
false,
converter.convert(fieldVar.receiver),
fieldVar.fieldVarName);
} }
@Override @Override
@ -145,11 +138,7 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
result = new TargetIf( result = new TargetIf(converter.convert(ifStmt.expr), converter.convert(ifStmt.then_block), converter.convert(ifStmt.else_block));
converter.convert(ifStmt.expr),
converter.convert(ifStmt.then_block),
converter.convert(ifStmt.else_block)
);
} }
@Override @Override
@ -169,7 +158,8 @@ public class StatementToTargetExpression implements StatementVisitor {
} }
static boolean convertsTo(TargetType from, TargetType to) { 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); return to.equals(from);
} }
@ -179,8 +169,10 @@ public class StatementToTargetExpression implements StatementVisitor {
var clazz = converter.classLoader.loadClass(className.toString()); var clazz = converter.classLoader.loadClass(className.toString());
outer: for (var method : clazz.getMethods()) { outer: for (var method : clazz.getMethods()) {
if (method.getParameterTypes().length != args.size()) continue; if (method.getParameterTypes().length != args.size())
if (!method.getName().equals(name)) continue; continue;
if (!method.getName().equals(name))
continue;
for (var i = 0; i < method.getParameterTypes().length; i++) { for (var i = 0; i < method.getParameterTypes().length; i++) {
var param = method.getParameterTypes()[i]; var param = method.getParameterTypes()[i];
@ -188,15 +180,16 @@ public class StatementToTargetExpression implements StatementVisitor {
if (param.isPrimitive()) { if (param.isPrimitive()) {
arg = TargetType.toPrimitive(arg); 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; return method;
} }
} catch (ClassNotFoundException ignored) {} } catch (ClassNotFoundException ignored) {
}
} }
if (converter.sourceFile != null) { // TODO Multiple source files if (converter.sourceFile != null) { // TODO Multiple source files
var thisClass = converter.sourceFile.KlassenVektor.stream() var thisClass = converter.sourceFile.KlassenVektor.stream().filter(classOrInterface -> classOrInterface.getClassName().equals(className)).findFirst();
.filter(classOrInterface -> classOrInterface.getClassName().equals(className)).findFirst();
if (thisClass.isPresent()) { if (thisClass.isPresent()) {
var superClass = thisClass.get().getSuperClass().getName(); var superClass = thisClass.get().getSuperClass().getName();
@ -230,22 +223,12 @@ public class StatementToTargetExpression implements StatementVisitor {
argList = Stream.of(foundMethod.getParameterTypes()).map(TargetType::toTargetType).toList(); argList = Stream.of(foundMethod.getParameterTypes()).map(TargetType::toTargetType).toList();
} }
result = new TargetMethodCall( 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);
converter.convert(methodCall.getType()),
returnType, argList,
converter.convert(methodCall.receiver),
methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
receiverType,
methodCall.name, false, isFunNType
);
} }
@Override @Override
public void visit(NewClass newClass) { public void visit(NewClass newClass) {
result = new TargetNew( result = new TargetNew(new TargetRefType(newClass.name), newClass.getArgumentList().getArguments().stream().map(converter::convert).toList());
new TargetRefType(newClass.name),
newClass.getArgumentList().getArguments().stream().map(converter::convert).toList()
);
} }
@Override @Override
@ -264,6 +247,11 @@ public class StatementToTargetExpression implements StatementVisitor {
result = new TargetReturn(null); result = new TargetReturn(null);
} }
@Override
public void visit(Break aBreak) {
result = new TargetBreak();
}
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
result = new TargetClassName(converter.convert(staticClassName.getType())); result = new TargetClassName(converter.convert(staticClassName.getType()));
@ -306,14 +294,7 @@ public class StatementToTargetExpression implements StatementVisitor {
var type = converter.convert(superCall.getType()); var type = converter.convert(superCall.getType());
var parameters = superCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList(); var parameters = superCall.arglist.getArguments().stream().map(par -> converter.convert(par.getType())).toList();
result = new TargetMethodCall( result = new TargetMethodCall(type, type, parameters, new TargetSuper(aSuper), superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(), aSuper, superCall.name, false, false);
type, type,
parameters,
new TargetSuper(aSuper),
superCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
aSuper,
superCall.name, false, false
);
} }
@Override @Override
@ -324,21 +305,19 @@ public class StatementToTargetExpression implements StatementVisitor {
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
result = switch (unaryExpr.operation) { result = switch (unaryExpr.operation) {
case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case NOT -> new TargetUnaryOp.Not(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case MINUS -> new TargetUnaryOp.Negate(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case PREINCREMENT -> new TargetUnaryOp.PreIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case PREDECREMENT -> new TargetUnaryOp.PreDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case POSTINCREMENT -> new TargetUnaryOp.PostIncrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case PLUS -> new TargetUnaryOp.Add(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr)); case POSTDECREMENT -> new TargetUnaryOp.PostDecrement(converter.convert(unaryExpr.getType()), converter.convert(unaryExpr.expr));
}; };
} }
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
if (literal.value instanceof Integer if (literal.value instanceof Integer || literal.value instanceof Short || literal.value instanceof Byte) {
|| literal.value instanceof Short
|| literal.value instanceof Byte) {
result = new TargetLiteral.IntLiteral((int) literal.value); result = new TargetLiteral.IntLiteral((int) literal.value);
} else if (literal.value instanceof Float) { } else if (literal.value instanceof Float) {

View File

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

View File

@ -27,12 +27,12 @@ import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
public class TYPEStmt implements StatementVisitor{ public class TYPEStmt implements StatementVisitor {
private final TypeInferenceBlockInformation info; private final TypeInferenceBlockInformation info;
private final ConstraintSet constraintsSet = new ConstraintSet(); private final ConstraintSet constraintsSet = new ConstraintSet();
public TYPEStmt(TypeInferenceBlockInformation info){ public TYPEStmt(TypeInferenceBlockInformation info) {
this.info = info; this.info = info;
} }
@ -41,13 +41,11 @@ public class TYPEStmt implements StatementVisitor{
} }
/** /**
* Erstellt einen neuen GenericResolver * 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.
* 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 * @return
*/ */
private static GenericsResolver getResolverInstance(){ private static GenericsResolver getResolverInstance() {
return new GenericsResolverSameName(); return new GenericsResolverSameName();
} }
@ -57,8 +55,8 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(ArgumentList arglist) { public void visit(ArgumentList arglist) {
for(int i = 0;i<arglist.getArguments().size();i++){ for (int i = 0; i < arglist.getArguments().size(); i++) {
arglist.getArguments().get(i).accept(this); arglist.getArguments().get(i).accept(this);
} }
} }
@ -67,17 +65,13 @@ public class TYPEStmt implements StatementVisitor{
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); // lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(new Pair(lambdaExpression.getType(), new RefType(new JavaClassName("Fun" + (lambdaParams.size() - 1) + "$$"), lambdaParams, new NullToken()),
new Pair(lambdaExpression.getType(), // new FunN(lambdaParams),
new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()), PairOperator.EQUALSDOT));
//new FunN(lambdaParams), constraintsSet.addUndConstraint(new Pair(lambdaExpression.getReturnType(), tphRetType, PairOperator.EQUALSDOT));
PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getReturnType(),
tphRetType,PairOperator.EQUALSDOT));
//Constraints des Bodys generieren: // Constraints des Bodys generieren:
TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression)); TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression));
lambdaExpression.methodBody.accept(lambdaScope); lambdaExpression.methodBody.accept(lambdaScope);
constraintsSet.addAll(lambdaScope.getConstraints()); constraintsSet.addAll(lambdaScope.getConstraints());
@ -87,13 +81,12 @@ public class TYPEStmt implements StatementVisitor{
public void visit(Assign assign) { public void visit(Assign assign) {
assign.lefSide.accept(this); assign.lefSide.accept(this);
assign.rightSide.accept(this); assign.rightSide.accept(this);
constraintsSet.addUndConstraint(new Pair( constraintsSet.addUndConstraint(new Pair(assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT));
} }
@Override @Override
public void visit(Block block) { public void visit(Block block) {
for(Statement stmt : block.getStatements()){ for (Statement stmt : block.getStatements()) {
stmt.accept(this); stmt.accept(this);
} }
} }
@ -105,23 +98,22 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(EmptyStmt emptyStmt) { public void visit(EmptyStmt emptyStmt) {
//Nothing :) // Nothing :)
} }
@Override @Override
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
Set<Constraint> oderConstraints = new HashSet<>(); Set<Constraint> oderConstraints = new HashSet<>();
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ for (FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)) {
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); 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.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( constraint.add(new Pair(fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if(oderConstraints.size() == 0) if (oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld " + fieldVar.fieldVarName + " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
} }
@ -133,15 +125,15 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken()); RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
//Expression inferieren: // Expression inferieren:
ifStmt.expr.accept(this); ifStmt.expr.accept(this);
//Expression muss boolean sein: // Expression muss boolean sein:
constraintsSet.addUndConstraint(new Pair(ifStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT));
//Blöcke inferieren: // Blöcke inferieren:
ifStmt.then_block.accept(this); ifStmt.then_block.accept(this);
//Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt // Beide Blöcke müssen den gleichen Supertyp haben, welcher den Rückgabetyp des If-Stmts darstellt
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
if(ifStmt.else_block != null){ if (ifStmt.else_block != null) {
ifStmt.else_block.accept(this); ifStmt.else_block.accept(this);
constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT)); constraintsSet.addUndConstraint(new Pair(ifStmt.else_block.getType(), ifStmt.getType(), PairOperator.SMALLERDOT));
} }
@ -160,50 +152,42 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
//Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ // Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ
} }
@Override @Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen // Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler) // und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
//Overloading: // Overloading:
Set<Constraint<Pair>> methodConstraints = new HashSet<>(); Set<Constraint<Pair>> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){ for (MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)) {
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver); Set<Constraint<Pair>> oneMethodConstraints = generateConstraint(methodCall, m, info, resolver);
methodConstraints.addAll(oneMethodConstraints); methodConstraints.addAll(oneMethodConstraints);
/* pl 2023-01-20: in generateConstraint bereits umgesetzt /*
Constraint<Pair> extendsOneMethodConstraint = oneMethodConstraint.stream() * 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())));
.map(x -> (x.TA1 instanceof TypePlaceholder && * oneMethodConstraint.setExtendConstraint(extendsOneMethodConstraint); extendsOneMethodConstraint.setExtendConstraint(oneMethodConstraint); methodConstraints.add(extendsOneMethodConstraint);
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){ if (methodConstraints.size() < 1) {
throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset()); throw new TypeinferenceException("Methode " + methodCall.name + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
} }
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
//Overloading: // Overloading:
Set<Constraint> methodConstraints = new HashSet<>(); Set<Constraint> methodConstraints = new HashSet<>();
for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){ for (MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())) {
methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance())); methodConstraints.add(generateConstructorConstraint(methodCall, m, info, getResolverInstance()));
} }
if(methodConstraints.size()<1){ if (methodConstraints.size() < 1) {
throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset()); throw new TypeinferenceException("Konstruktor in Klasse " + methodCall.getType().toString() + " ist nicht vorhanden!", methodCall.getOffset());
} }
constraintsSet.addOderConstraint(methodConstraints); constraintsSet.addOderConstraint(methodConstraints);
} }
@ -226,276 +210,230 @@ public class TYPEStmt implements StatementVisitor{
private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken()); private final RefType floatt = new RefType(ASTFactory.createClass(Float.class).getClassName(), new NullToken());
private final RefType doublee = new RefType(ASTFactory.createClass(Double.class).getClassName(), new NullToken()); 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 string = new RefType(ASTFactory.createClass(String.class).getClassName(), new NullToken());
private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken()); private final RefType bool = new RefType(ASTFactory.createClass(Boolean.class).getClassName(), new NullToken());
@Override @Override
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
if(unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT || unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) {
unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT || // @see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT || // Expression muss zu Numeric Convertierbar sein. also von Numeric erben
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)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), number, PairOperator.SMALLERNEQDOT));
//The type of the postfix increment expression is the type of the variable // The type of the postfix increment expression is the type of the variable
constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(unaryExpr.expr.getType(), unaryExpr.getType(), PairOperator.EQUALSDOT));
}else{ } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@Override @Override
//Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen // Es wird in OderConstraints davon ausgegangen dass die Bedingungen für die Typen der Argumente links stehen
//und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler) // und die Typen der Rückgabewerte immer rechts stehen (vgl. JavaTXCompiler)
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
binary.lexpr.accept(this); binary.lexpr.accept(this);
binary.rexpr.accept(this); binary.rexpr.accept(this);
if(binary.operation.equals(BinaryExpr.Operator.DIV) || 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)) {
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<>(); Set<Constraint<Pair>> numericAdditionOrStringConcatenation = new HashSet<>();
// TODO PL 2018-11-06 // TODO PL 2018-11-06
// Auf importierte Typen einschraenken // Auf importierte Typen einschraenken
// pruefen, ob Typen richtig bestimmt werden. // 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
//Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer: // Expression muss zu Numeric Convertierbar sein. also von Numeric erben
//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
Constraint<Pair> numeric; Constraint<Pair> numeric;
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); 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.rexpr.getType(), bytee, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT)); 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.rexpr.getType(), shortt, PairOperator.SMALLERDOT));
numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT)); numeric.add(new Pair(binary.getType(), integer, PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); 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.rexpr.getType(), integer, PairOperator.SMALLERDOT));
numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(integer, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); 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.rexpr.getType(), longg, PairOperator.SMALLERDOT));
numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(longg, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); 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.rexpr.getType(), floatt, PairOperator.SMALLERDOT));
numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(floatt, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
//PL eingefuegt 2018-07-17 // PL eingefuegt 2018-07-17
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) { if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) {
numeric = new Constraint<>(); numeric = new Constraint<>();
numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); 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.rexpr.getType(), doublee, PairOperator.SMALLERDOT));
numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT)); numeric.add(new Pair(doublee, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(numeric); numericAdditionOrStringConcatenation.add(numeric);
} }
/* PL auskommentiert Anfang 2018-07-17
/* /*
In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: * 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
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
*/
numeric = new Constraint<>(); if (binary.operation.equals(BinaryExpr.Operator.ADD)) {
numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); // Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2)
numericAdditionOrStringConcatenation.add(numeric); if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) {
* PL auskommentiert Ende 2018-07-17 */ Constraint<Pair> stringConcat = new Constraint<>();
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT));
if(binary.operation.equals(BinaryExpr.Operator.ADD)) { stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT));
//Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2) stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT));
if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) { numericAdditionOrStringConcatenation.add(stringConcat);
Constraint<Pair> stringConcat = new Constraint<>(); }
stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT));
stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT));
stringConcat.add(new Pair(string, binary.getType(), PairOperator.EQUALSDOT));
numericAdditionOrStringConcatenation.add(stringConcat);
}
} }
if(numericAdditionOrStringConcatenation.size()<1){ if (numericAdditionOrStringConcatenation.size() < 1) {
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset()); throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
} }
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
}else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || } 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)) {
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || /*
binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || * //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(),
binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) { * 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));
/* //eingefuegt PL 2018-05-24 * 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
Set<Constraint<Pair>> numericRelationConcatenation = new HashSet<>(); * 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);
Constraint<Pair> numeric = new Constraint<>(); *
numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); * //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch constraintsSet.addOderConstraint(numericRelationConcatenation); //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); */
numeric.add(new Pair(binary.getType(), bool, PairOperator.SMALLERDOT)); // Testeise eingefuegt PL 2018-05-24
numericRelationConcatenation.add(numeric); // Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
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
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT));
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT));
//Rückgabetyp ist Boolean // Rückgabetyp ist Boolean
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
//auskommentiert PL 2018-05-24 // auskommentiert PL 2018-05-24
//constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT)); // constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERDOT));
//constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT)); // constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERDOT));
//Rückgabetyp ist Boolean // Rückgabetyp ist Boolean
//constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); // constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
}else if(binary.operation.equals(BinaryExpr.Operator.EQUAL) || binary.operation.equals(BinaryExpr.Operator.NOTEQUAL)){ } 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 // Der Equals Operator geht mit fast allen Typen, daher werden hier keine Constraints gesetzt
constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(bool, binary.getType(), PairOperator.EQUALSDOT));
}else{ } else {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
//Nothing to do here. Literale erzeugen keine Constraints // Nothing to do here. Literale erzeugen keine Constraints
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden // PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen // wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
//funktionieren // funktionieren
if (literal.value instanceof Short) { if (literal.value instanceof Short) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Byte) { if (literal.value instanceof Byte) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Float) { if (literal.value instanceof Float) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Double) { if (literal.value instanceof Double) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Long) { if (literal.value instanceof Long) {
constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Integer) { if (literal.value instanceof Integer) {
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT)); // constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT));
// /* // /*
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)); HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new));
Set<Constraint> oderConstraints = new HashSet<>(); Set<Constraint> oderConstraints = new HashSet<>();
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) { if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) {
constraint = new Constraint(); constraint = new Constraint();
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT)); constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
oderConstraints.add(constraint); oderConstraints.add(constraint);
} }
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
// */ // */
return; return;
} }
if (literal.value instanceof Short) { if (literal.value instanceof Short) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),shortt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Byte) { if (literal.value instanceof Byte) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),bytee, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Float) { if (literal.value instanceof Float) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),floatt, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof String) { if (literal.value instanceof String) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),string, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), string, PairOperator.EQUALSDOT));
return; return;
} }
if (literal.value instanceof Boolean) { if (literal.value instanceof Boolean) {
constraintsSet.addUndConstraint(new Pair(literal.getType(),bool, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(literal.getType(), bool, PairOperator.EQUALSDOT));
return; return;
} } else {
else { throw new NotImplementedException();
throw new NotImplementedException(); }
}
} }
@Override @Override
public void visit(Return returnExpr) { public void visit(Return returnExpr) {
returnExpr.retexpr.accept(this); returnExpr.retexpr.accept(this);
constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(returnExpr.getType(), info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT));
} }
@Override @Override
@ -503,9 +441,14 @@ public class TYPEStmt implements StatementVisitor{
visit((Return) aReturn); visit((Return) aReturn);
} }
@Override
public void visit(Break aBreak) {
}
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
//Hier entstehen keine Constraints // Hier entstehen keine Constraints
} }
@Override @Override
@ -515,15 +458,14 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden. // Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
ClassOrInterface currentClass = info.getCurrentClass(); ClassOrInterface currentClass = info.getCurrentClass();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : currentClass.getGenerics()){ for (GenericTypeVar gtv : currentClass.getGenerics()) {
params.add(new GenericRefType(gtv.getName(), aThis.getOffset())); params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
} }
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset()); RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(new Pair( constraintsSet.addUndConstraint(new Pair(aThis.getType(), thisType, PairOperator.EQUALSDOT));
aThis.getType(), thisType, PairOperator.EQUALSDOT));
} }
private static TypeScope createNullTypeScope() { private static TypeScope createNullTypeScope() {
@ -543,11 +485,11 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(WhileStmt whileStmt) { public void visit(WhileStmt whileStmt) {
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken()); RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
//Expression inferieren: // Expression inferieren:
whileStmt.expr.accept(this); whileStmt.expr.accept(this);
//Expression muss boolean sein: // Expression muss boolean sein:
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT));
//LoopBlock inferieren: // LoopBlock inferieren:
whileStmt.loopBlock.accept(this); whileStmt.loopBlock.accept(this);
} }
@ -558,57 +500,51 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(AssignToField assignLeftSide) { public void visit(AssignToField assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert // Hier ist kein Code nötig. Es werden keine extra Constraints generiert
//HIER muss Code rein PL 2018-10-24 // HIER muss Code rein PL 2018-10-24
assignLeftSide.field.accept(this); assignLeftSide.field.accept(this);
} }
@Override @Override
public void visit(AssignToLocal assignLeftSide) { public void visit(AssignToLocal assignLeftSide) {
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert // Hier ist kein Code nötig. Es werden keine extra Constraints generiert
} }
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
//TODO: Für einen super-Call werden keine Constraints erzeugt bisher // TODO: Für einen super-Call werden keine Constraints erzeugt bisher
} }
/* /*
METHOD CALL Section: * METHOD CALL Section:
*/ */
protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption, protected Set<Constraint<Pair>> generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
TypeInferenceBlockInformation info, GenericsResolver resolver){
Constraint<Pair> methodConstraint, extendsMethodConstraint; Constraint<Pair> methodConstraint, extendsMethodConstraint;
methodConstraint = new Constraint<>(assumption.isInherited()); methodConstraint = new Constraint<>(assumption.isInherited());
extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall) extendsMethodConstraint = new Constraint<>(assumption.isInherited());// PL 2023-01-24: Ersetzt die Dopplung in visit(MethodCall)
ClassOrInterface receiverCl = assumption.getReceiver(); ClassOrInterface receiverCl = assumption.getReceiver();
/* /*
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); * List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(gtv.getName())); }
for(GenericTypeVar gtv : receiverCl.getGenerics()){ *
//Die Generics werden alle zu TPHs umgewandelt. * RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
params.add(resolver.resolve(gtv.getName())); */
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
*/
RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver); RefTypeOrTPHOrWildcardOrGeneric receiverType = assumption.getReceiverType(resolver);
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));//PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind. methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, PairOperator.EQUALSDOT));// PL 2020-03-17 SMALLERDOT in EQUALSDOT umgewandelt, weil alle geerbten Methoden in den jeweilen Klassen enthalten sind.
//PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt // PL 2023-01-24: dafuer ? extends receiverType noch ergaenzt
extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT)); extendsMethodConstraint.add(new Pair(forMethod.receiver.getType(), new ExtendsWildcardType(receiverType, receiverType.getOffset()), PairOperator.EQUALSDOT));
//gegenseite Verschraenkung der beiden Mengen von Typannahmen // gegenseite Verschraenkung der beiden Mengen von Typannahmen
methodConstraint.setExtendConstraint(extendsMethodConstraint); methodConstraint.setExtendConstraint(extendsMethodConstraint);
extendsMethodConstraint.setExtendConstraint(methodConstraint); extendsMethodConstraint.setExtendConstraint(methodConstraint);
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
//methodConstraint.add(new Pair(forMethod.receiverType, retType, // methodConstraint.add(new Pair(forMethod.receiverType, retType,
// PairOperator.EQUALSDOT)); // PairOperator.EQUALSDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT)); extendsMethodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(), PairOperator.EQUALSDOT));
@ -631,75 +567,66 @@ public class TYPEStmt implements StatementVisitor{
return ret; return ret;
} }
protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, protected Set<Pair> generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>(); Set<Pair> ret = new HashSet<>();
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){ for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
foMethod.arglist.getArguments().get(i).accept(this); foMethod.arglist.getArguments().get(i).accept(this);
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType(); RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i); RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT)); ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ANFANG
// ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT)); // ret.add(new Pair(foMethod.argTypes.get(i), assType, PairOperator.EQUALSDOT));
//Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE // Fuer Bytecodegenerierung PL 2020-03-09 wird derzeit nicht benutzt ENDE
} }
return ret; return ret;
} }
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>();
protected Set<Pair> generatemethodSignatureConstraint(MethodCall foMethod, MethodAssumption assumption, for (int i = 0; i < foMethod.arglist.getArguments().size(); i++) {
TypeInferenceBlockInformation info, GenericsResolver resolver) {
Set<Pair> ret = new HashSet<>();
for(int i = 0; i<foMethod.arglist.getArguments().size(); i++){ // Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params)
ret.add(new Pair(foMethod.signature.get(i), assumption.getArgTypes().get(i), PairOperator.EQUALSDOT));
//Zuordnung von MethoCall.signature (Argumenttypen) zu der Argumenttypen der ausgewaehlten Methode (assumption.params) }
ret.add(new Pair(foMethod.signature.get(i), assumption.getArgTypes().get(i), PairOperator.EQUALSDOT));
} // Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
//Zuordnung von MethodCall.signature(ReturnType) zu dem ReturnType der ausgewaehlten Methode (assumption.returnType)
System.out.println(foMethod.name); System.out.println(foMethod.name);
ret.add(new Pair(foMethod.signature.get(foMethod.signature.size()-1), assumption.getReturnType(), PairOperator.EQUALSDOT)); ret.add(new Pair(foMethod.signature.get(foMethod.signature.size() - 1), assumption.getReturnType(), PairOperator.EQUALSDOT));
return ret; return ret;
} }
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
//TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken) // TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken)
if(name.equals("apply")){ if (name.equals("apply")) {
List<GenericRefType> funNParams = new ArrayList<>(); List<GenericRefType> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){ for (int i = 0; i < numArgs + 1; i++) {
//funNParams.add(TypePlaceholder.fresh(new NullToken())); // funNParams.add(TypePlaceholder.fresh(new NullToken()));
funNParams.add(new GenericRefType(NameGenerator.makeNewName(), funNParams.add(new GenericRefType(NameGenerator.makeNewName(), new NullToken()));
new NullToken()));
} }
funNParams.get(funNParams.size()-1); funNParams.get(funNParams.size() - 1);
ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size()-1), funNParams.subList(0, funNParams.size()-1), ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(funNParams.size() - 1), funNParams.subList(0, funNParams.size() - 1), new TypeScope() {
new TypeScope() { @Override
@Override public Iterable<? extends GenericTypeVar> getGenerics() {
public Iterable<? extends GenericTypeVar> getGenerics() { throw new NotImplementedException();
throw new NotImplementedException(); }
}
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
throw new NotImplementedException(); throw new NotImplementedException();
} }
}, false)); }, false));
} }
for(ClassOrInterface cl : info.getAvailableClasses()){ for (ClassOrInterface cl : info.getAvailableClasses()) {
for(Method m : cl.getMethods()){ for (Method m : cl.getMethods()) {
if(m.getName().equals(name) && if (m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs) {
m.getParameterList().getFormalparalist().size() == numArgs){ RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();// info.checkGTV(m.getReturnType());
RefTypeOrTPHOrWildcardOrGeneric retType = m.getReturnType();//info.checkGTV(m.getReturnType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info), ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(), info), createTypeScope(cl, m), m.isInherited));
createTypeScope(cl, m), m.isInherited));
} }
} }
} }
@ -710,31 +637,27 @@ public class TYPEStmt implements StatementVisitor{
return getMethods(name, arglist.getArguments().size(), info); return getMethods(name, arglist.getArguments().size(), info);
} }
protected static List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){ 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 // TODO: Hier müssen die Parameter mit den TPHs in den GEnerics des Receivers verknüpft werden
/* /*
BEispiel: * BEispiel: auto test = new List<String>(); test.add("hallo");
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
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<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(FormalParameter fp : parameterList.getFormalparalist()){ for (FormalParameter fp : parameterList.getFormalparalist()) {
params.add(fp.getType()); //info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben params.add(fp.getType()); // info.checkGTV(fp.getType())); //PL 2018-06-22 GTV sollen in Argumenten erhalten bleiben
} }
return params; return params;
} }
public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){ public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
for(ClassOrInterface cl : info.getAvailableClasses()){ for (ClassOrInterface cl : info.getAvailableClasses()) {
if(cl.getClassName().equals(ofType.getName())){ if (cl.getClassName().equals(ofType.getName())) {
for(Method m : cl.getConstructors()){ for (Method m : cl.getConstructors()) {
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ if (m.getParameterList().getFormalparalist().size() == argList.getArguments().size()) {
ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(), ret.add(new MethodAssumption(cl, cl.generateTypeOfThisClass(), convertParams(m.getParameterList(), info), createTypeScope(cl, m), m.isInherited));
info), createTypeScope(cl, m), m.isInherited));
} }
} }
} }
@ -742,14 +665,12 @@ public class TYPEStmt implements StatementVisitor{
return ret; return ret;
} }
protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, protected Constraint<Pair> generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver) {
TypeInferenceBlockInformation info, GenericsResolver resolver){
Constraint methodConstraint = new Constraint(); Constraint methodConstraint = new Constraint();
//WELCHEN SINN MACHT DIESER CONSTRAINT??? // WELCHEN SINN MACHT DIESER CONSTRAINT???
//Ist er nicht immer classname <. classname und damit redundant? // Ist er nicht immer classname <. classname und damit redundant?
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), methodConstraint.add(new Pair(assumption.getReturnType(resolver), forConstructor.getType(), PairOperator.SMALLERDOT));
PairOperator.SMALLERDOT)); // WELCHEN SINN MACHT DIESER CONSTRAINT???
//WELCHEN SINN MACHT DIESER CONSTRAINT???
methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver)); methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver));
return methodConstraint; return methodConstraint;
} }