Added SwitchStmt including Type & GuardedPattern to AST

This commit is contained in:
luca9913 2023-07-04 15:27:29 +02:00
parent 1a89920430
commit 359f3e68ab
14 changed files with 283 additions and 49 deletions

View File

@ -0,0 +1,41 @@
import java.lang.Integer;
import java.lang.String;
import java.lang.Boolean;
class SwitchStatement {
boolean switchStandard(){
str = "SwitchMe";
switch(str){
case String s: return true;
default: return false;
}
}
boolean switchInteger(){
i = 5;
switch(i){
case Integer j:
case String s: i = 6; break;
default: i = 0; break;
}
return (i==0);
}
boolean guardedPattern(){
var i = 1;
switch(i){
case Integer j && j == 1: return true;
default: return false;
}
}
/* boolean enclosedPattern(){
var i = "Test";
var j = switch(i){
case (String s)->{ yield 0;}
case Integer i ->{ yield 1;}
};
return (j==0);
} */
}

View File

@ -575,8 +575,10 @@ switchBlockStatementGroup
;
switchLabel
: CASE (constantExpression=expression | enumConstantName=IDENTIFIER | pattern) ':'
| DEFAULT ':'
: CASE constantExpression=expression ':' #switchLabelConst
| CASE enumConstantName=IDENTIFIER ':' #switchLabelEnum
| CASE pattern ':' #switchLabelPattern
| DEFAULT ':' #switchLabelDefault
;
forControl
@ -720,7 +722,7 @@ switchLabeledRule
// Java17
guardedPattern
: variableModifier* typeType? annotation* identifier ('&&' expression)*
: variableModifier* typeType annotation* identifier ('&&' expression)*
| guardedPattern '&&' expression
;

View File

@ -34,6 +34,8 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.EqualityexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ExpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.FltLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ForloopContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.GuardedPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.IdentifierContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.InstanceofexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.IntLiteralContext;
@ -48,6 +50,7 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.NewinstanceexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.NullLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.OrexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PostfixexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrefixexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.PrimaryClassrefContext;
@ -64,6 +67,11 @@ import de.dhbwstuttgart.parser.antlr.Java17Parser.SemistmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ShiftexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.StmtexpressionContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.StringLiteralContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchBlockStatementGroupContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelConstContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelDefaultContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchLabelPatternContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchexpressionstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SwitchstmtContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SynchronizedstmtContext;
@ -78,18 +86,19 @@ import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.TypePattern;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Break;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.GuardedPattern;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
@ -104,7 +113,11 @@ import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.Statement;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.Switch;
import de.dhbwstuttgart.syntaxtree.statement.SwitchBlock;
import de.dhbwstuttgart.syntaxtree.statement.SwitchLabel;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.Pattern;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.type.RefType;
@ -324,8 +337,11 @@ public class StatementGenerator {
}
private Statement convert(Java17Parser.SwitchstmtContext stmt) {
// TODO
throw new NotImplementedException();
List<SwitchBlock> switchBlocks = new ArrayList<>();
for (SwitchBlockStatementGroupContext blockstmt : stmt.switchBlockStatementGroup()) {
switchBlocks.add(convert(blockstmt));
}
return new Switch(switchBlocks, convert(stmt.parExpression().expression()).getType(), true, stmt.getStart());
}
private Statement convert(Java17Parser.SwitchexpressionstmtContext switchexpression) {
@ -338,9 +354,65 @@ public class StatementGenerator {
throw new NotImplementedException();
}
private Statement convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
// TODO
throw new NotImplementedException();
private SwitchBlock convert(Java17Parser.SwitchBlockStatementGroupContext stmt) {
List<SwitchLabel> labels = new ArrayList<>();
stmt.switchLabel().forEach((label) -> {
labels.add(convert(label));
});
List<Statement> block = new ArrayList<>();
stmt.blockStatement().stream().forEach((blockStmt) -> {
block.addAll(convert(blockStmt));
});
return new SwitchBlock(labels, block, stmt.getStart());
}
private SwitchLabel convert(SwitchLabelContext switchLabel) {
Expression caseExpression = switch (switchLabel) {
case SwitchLabelConstContext cons -> {
yield convert(cons.constantExpression);
}
case SwitchLabelPatternContext pattern -> {
yield convert(pattern.pattern());
}
case SwitchLabelDefaultContext def -> {
yield null;
}
default -> throw new NotImplementedException();
};
Token offset = switchLabel.getStart();
if (Objects.isNull(caseExpression)) {
return new SwitchLabel(null, TypePlaceholder.fresh(offset), offset);
} else {
return new SwitchLabel(caseExpression, caseExpression.getType(), offset);
}
}
private Pattern convert(PatternContext pattern) {
return switch (pattern) {
case PPatternContext pPattern -> {
yield convert(pPattern.primaryPattern());
}
case GPatternContext gPattern -> {
GuardedPatternContext guarded = gPattern.guardedPattern();
List<Expression> conditions = guarded.expression().stream().map((expr) -> {
return convert(expr);
}).toList();
yield new GuardedPattern(conditions, guarded.identifier().getText(), TypeGenerator.convert(guarded.typeType(), reg, generics), guarded.getStart());
}
default -> throw new NotImplementedException();
};
}
private Pattern convert(PrimaryPatternContext pPattern) {
switch (pPattern) {
case TPatternContext tPattern:
TypePatternContext typePattern = tPattern.typePattern();
return new Pattern(typePattern.identifier().getText(), TypeGenerator.convert(typePattern.typeType(), reg, generics), typePattern.getStart());
default:
throw new NotImplementedException();
}
}
private Statement convert(Java17Parser.WhileloopContext stmt) {
@ -421,8 +493,13 @@ public class StatementGenerator {
}
private Statement convert(Java17Parser.BreakstmtContext stmt) {
// TODO
throw new NotImplementedException();
Token offset = stmt.getStart();
if (!Objects.isNull(stmt.identifier())) {
return new Break(localVars.get(stmt.identifier().getText()), offset);
} else {
return new Break(TypePlaceholder.fresh(offset), offset);
}
}
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
@ -723,7 +800,7 @@ public class StatementGenerator {
String localVarName = typePatternCtx.identifier().getText();
RefTypeOrTPHOrWildcardOrGeneric localVarType = TypeGenerator.convert(typePatternCtx.typeType(), reg, generics);
localVars.put(localVarName, localVarType);
return new InstanceOf(left, new TypePattern(localVarName, localVarType, typePatternCtx.getStart()), offset);
return new InstanceOf(left, new Pattern(localVarName, localVarType, typePatternCtx.getStart()), offset);
default:
throw new NotImplementedException();
}

View File

@ -1,12 +0,0 @@
package de.dhbwstuttgart.syntaxtree;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class TypePattern extends FormalParameter {
// TypePattern und FormalParameter sind exakt gleich aufgebaut
public TypePattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
}
}

View File

@ -1,4 +1,5 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.*;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
@ -7,20 +8,15 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import org.antlr.v4.runtime.Token;
public class Block extends Statement
{
public class Block extends Statement {
public Block(List<Statement> statements, Token offset) {
super(TypePlaceholder.fresh(offset), offset);
this.statements = statements;
}
super(TypePlaceholder.fresh(offset), offset);
this.statements = statements;
}
public List<Statement> statements = new ArrayList<>();
public List<Statement> getStatements()
{
public List<Statement> getStatements() {
return statements;
}
@ -29,5 +25,3 @@ public class Block extends Statement
visitor.visit(this);
}
}

View File

@ -0,0 +1,22 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class GuardedPattern extends Pattern {
private List<Expression> conditions;
public GuardedPattern(List<Expression> conditions, String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(name, type, offset);
this.conditions = conditions;
}
public List<Expression> getConditions() {
return conditions;
}
}

View File

@ -7,17 +7,13 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import org.antlr.v4.runtime.Token;
public class IfStmt extends Statement
{
public class IfStmt extends Statement {
public final Expression expr;
public final Statement then_block;
public final Statement else_block;
public IfStmt(RefTypeOrTPHOrWildcardOrGeneric type,
Expression expr, Statement thenBlock, Statement elseBlock, Token offset)
{
super(type,offset);
public IfStmt(RefTypeOrTPHOrWildcardOrGeneric type, Expression expr, Statement thenBlock, Statement elseBlock, Token offset) {
super(type, offset);
this.expr = expr;
this.then_block = thenBlock;
this.else_block = elseBlock;

View File

@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.TypePattern;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@ -16,7 +15,7 @@ public class InstanceOf extends BinaryExpr {
this.reftype = reftype;
}
public InstanceOf(Expression expr, TypePattern pattern, Token offset) {
public InstanceOf(Expression expr, Pattern pattern, Token offset) {
super(BinaryExpr.Operator.INSTOF, TypePlaceholder.fresh(offset), expr, new LocalVar(pattern.getName(), pattern.getType(), pattern.getOffset()), offset);
this.reftype = pattern.getType();
this.name = pattern.getName();

View File

@ -0,0 +1,27 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class Pattern extends Expression {
private String name;
public Pattern(String name, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.name = name;
}
public String getName() {
return name;
}
@Override
public void accept(StatementVisitor visitor) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'accept'");
}
}

View File

@ -1,5 +1,8 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
@ -7,15 +10,18 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class Switch extends Statement {
public Switch(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
private List<SwitchBlock> blocks = new ArrayList<>();
public Switch(List<SwitchBlock> blocks, RefTypeOrTPHOrWildcardOrGeneric type, Boolean isStatement, Token offset) {
super(type, offset);
// TODO Auto-generated constructor stub
if (isStatement)
setStatement();
this.blocks = blocks;
}
@Override
public void accept(StatementVisitor visitor) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'accept'");
// visitor.visit(this);
}
}

View File

@ -0,0 +1,29 @@
package de.dhbwstuttgart.syntaxtree.statement;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.Token;
public class SwitchBlock extends Block {
private List<SwitchLabel> labels = new ArrayList<>();
private Boolean defaultBlock = false;
public SwitchBlock(List<SwitchLabel> labels, List<Statement> statements, Token offset) {
super(statements, offset);
this.labels = labels;
}
public SwitchBlock(List<SwitchLabel> labels, List<Statement> statements, Boolean isDefault, Token offset) {
super(statements, offset);
this.labels = labels;
this.defaultBlock = isDefault;
}
public Boolean isDefault() {
return defaultBlock;
}
}

View File

@ -0,0 +1,34 @@
package de.dhbwstuttgart.syntaxtree.statement;
import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class SwitchLabel extends Expression {
private Expression caseExpression;
private Boolean defaultCase = false;
public SwitchLabel(Expression caseExpression, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.caseExpression = caseExpression;
}
public SwitchLabel(Expression caseExpression, Boolean def, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
super(type, offset);
this.caseExpression = caseExpression;
this.defaultCase = def;
}
public Boolean isDefault() {
return this.defaultCase;
}
@Override
public void accept(StatementVisitor visitor) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'accept'");
}
}

View File

@ -68,6 +68,25 @@ public class TestNewFeatures {
fail("An error occured while generating the AST for applyLambda.jav");
}
}
@Test
public void switchTest() {
try {
/*
* FileInputStream fileIn = new FileInputStream(javFiles.get("Record")[1]); String expectedAST = new String(fileIn.readAllBytes()); fileIn.close(); expectedAST = expectedAST.replaceAll("TPH [A-Z]+", "TPH");
*/
File srcfile = javFiles.get("Switch")[0];
JavaTXCompiler compiler = new JavaTXCompiler(srcfile);
String resultingAST = new String(ASTPrinter.print(compiler.sourceFiles.get(srcfile)));
resultingAST = resultingAST.replaceAll("TPH [A-Z]+", "TPH");
// System.out.println("Expected:\n" + new String(expectedAST));
System.out.println("Result:\n" + new String(resultingAST));
// assertEquals("Comparing expected and resulting AST for applyLambda.jav", expectedAST, resultingAST);
} catch (Exception exc) {
exc.printStackTrace();
fail("An error occured while generating the AST for applyLambda.jav");
}
}
}
class JavFilter implements FileFilter {