package de.dhbwstuttgart.syntaxtree.visual; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.type.*; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; public class OutputGenerator implements ASTVisitor { private static final String TAB = " "; String tabs = ""; protected final StringBuilder out; public OutputGenerator(StringBuilder out) { this.out = out; } public void tab() { tabs += TAB; } public void untab() { tabs = tabs.substring(0, tabs.length() - TAB.length()); } @Override public void visit(SourceFile sourceFile) { for (ClassOrInterface cl : sourceFile.getClasses()) { cl.accept(this); } } @Override public void visit(ArgumentList argumentList) { out.append("("); Iterator expressionIterator = argumentList.getArguments().iterator(); while (expressionIterator.hasNext()) { expressionIterator.next().accept(this); if (expressionIterator.hasNext()) out.append(", "); } out.append(")"); } @Override public void visit(GenericTypeVar genericTypeVar) { out.append(genericTypeVar.getName().toString()); } @Override public void visit(FormalParameter formalParameter) { formalParameter.getType().accept(this); out.append(" "); out.append(formalParameter.getName()); } @Override public void visit(GenericDeclarationList genericTypeVars) { Iterator genericIterator = genericTypeVars.iterator(); if (genericIterator.hasNext()) { out.append("<"); while (genericIterator.hasNext()) { genericIterator.next().accept(this); if (genericIterator.hasNext()) out.append(", "); } out.append(">"); } } @Override public void visit(Field field) { field.getType().accept(this); out.append(" "); out.append(field.getName()); out.append(";"); } @Override public void visit(Method method) { method.getReturnType().accept(this); out.append(" " + method.getName()); method.getParameterList().accept(this); if (method.block != null) method.block.accept(this); out.append("\n"); } @Override public void visit(Constructor method) { out.append(method.getName()); method.getParameterList().accept(this); method.block.accept(this); out.append("\n"); } @Override public void visit(ParameterList formalParameters) { out.append("("); Iterator genericIterator = formalParameters.getFormalparalist().iterator(); if (genericIterator.hasNext()) { while (genericIterator.hasNext()) { genericIterator.next().accept(this); if (genericIterator.hasNext()) out.append(", "); } } out.append(")"); } @Override public void visit(ClassOrInterface classOrInterface) { if (classOrInterface.isInterface()) { out.append("interface "); } else { out.append("class "); } out.append(classOrInterface.getClassName().toString()); classOrInterface.getGenerics().accept(this); out.append(" {\n\n"); tab(); for (Field f : classOrInterface.getFieldDecl()) { out.append(tabs); f.accept(this); out.append("\n"); } if (classOrInterface.getfieldInitializations().isPresent()) {// PL 2019-11-28: Zum Ausdrucken der Fieldinitializer classOrInterface.getfieldInitializations().get().accept(this); } for (Method m : classOrInterface.getMethods()) { out.append(tabs); m.accept(this); out.append("\n"); } for (Constructor m : classOrInterface.getConstructors()) { out.append(tabs); m.accept(this); out.append("\n"); } untab(); out.append("}"); } @Override public void visit(RefType refType) { out.append(refType.getName().toString()); Iterator genericIterator = refType.getParaList().iterator(); if (genericIterator.hasNext()) { out.append("<"); while (genericIterator.hasNext()) { genericIterator.next().accept(this); if (genericIterator.hasNext()) out.append(", "); } out.append(">"); } } @Override public void visit(SuperWildcardType superWildcardType) { out.append("? super "); superWildcardType.getInnerType().accept(this); } @Override public void visit(TypePlaceholder typePlaceholder) { out.append("TPH " + typePlaceholder.getName()); } @Override public void visit(ExtendsWildcardType extendsWildcardType) { out.append("? extends "); extendsWildcardType.getInnerType().accept(this); } @Override public void visit(GenericRefType genericRefType) { out.append(genericRefType.getParsedName().toString()); } @Override public void visit(LambdaExpression lambdaExpression) { lambdaExpression.params.accept(this); out.append(" -> "); lambdaExpression.methodBody.accept(this); } @Override public void visit(Assign assign) { assign.lefSide.accept(this); out.append(" = "); assign.rightSide.accept(this); } @Override public void visit(BinaryExpr binary) { binary.lexpr.accept(this); out.append(" op "); binary.rexpr.accept(this); } @Override public void visit(BoolExpression logical) { logical.lexpr.accept(this); out.append(" op "); logical.rexpr.accept(this); } @Override public void visit(Block block) { tab(); out.append("{\n"); for (Statement stmt : block.getStatements()) { out.append(tabs); stmt.accept(this); out.append(";\n"); } untab(); out.append(tabs); out.append("}"); } @Override public void visit(CastExpr castExpr) { } @Override public void visit(EmptyStmt emptyStmt) { } @Override public void visit(FieldVar fieldVar) { fieldVar.receiver.accept(this); out.append("." + fieldVar.fieldVarName); } @Override public void visit(ForStmt forStmt) { } @Override public void visit(ForEachStmt forEachStmt) { out.append("for("); forEachStmt.statement.accept(this); out.append(" : "); forEachStmt.expression.accept(this); out.append(")\n"); tab(); out.append(tabs); forEachStmt.block.accept(this); untab(); } @Override public void visit(IfStmt ifStmt) { out.append("if("); ifStmt.expr.accept(this); out.append(")\n"); tab(); out.append(tabs); ifStmt.then_block.accept(this); untab(); if (ifStmt.else_block != null) { out.append("\n" + tabs + "else\n"); tab(); out.append(tabs); ifStmt.else_block.accept(this); untab(); } } @Override public void visit(InstanceOf instanceOf) { instanceOf.getExpression().accept(this); out.append(" instanceof "); instanceOf.getPattern().accept(this); } @Override public void visit(LocalVar localVar) { if (localVar.name.isEmpty()) { localVar.getType().accept(this); } else { out.append(localVar.name); } } @Override public void visit(LocalVarDecl localVarDecl) { localVarDecl.getType().accept(this); out.append(" " + localVarDecl.getName()); } @Override public void visit(MethodCall methodCall) { methodCall.receiver.accept(this); out.append("." + methodCall.name); out.append(" Signature: " + methodCall.signature); methodCall.getArgumentList().accept(this); } @Override public void visit(NewClass methodCall) { out.append("new "); out.append(methodCall.name); methodCall.getArgumentList().accept(this); } @Override public void visit(NewArray newArray) { } @Override public void visit(Return aReturn) { out.append("return "); aReturn.retexpr.accept(this); } @Override public void visit(ReturnVoid aReturn) { out.append("return"); } @Override public void visit(Break aBreak) { out.append("break"); } @Override public void visit(StaticClassName staticClassName) { } @Override public void visit(Super aSuper) { } @Override public void visit(This aThis) { out.append("this"); } @Override public void visit(WhileStmt whileStmt) { out.append("while("); whileStmt.expr.accept(this); out.append(")"); whileStmt.loopBlock.accept(this); } @Override public void visit(DoStmt whileStmt) { out.append("do "); whileStmt.loopBlock.accept(this); out.append("while("); whileStmt.expr.accept(this); out.append(");"); } @Override public void visit(AssignToField assignLeftSide) { assignLeftSide.field.accept(this); } @Override public void visit(AssignToLocal assignLeftSide) { assignLeftSide.localVar.accept(this); } @Override public void visit(SuperCall superCall) { out.append("super("); superCall.arglist.accept(this); out.append(")"); } @Override public void visit(ExpressionReceiver receiver) { receiver.expr.accept(this); } @Override public void visit(UnaryExpr unaryExpr) { if (unaryExpr.operation == UnaryExpr.Operation.MINUS) { out.append("-"); } if (unaryExpr.operation == UnaryExpr.Operation.PLUS) { out.append("+"); } if (unaryExpr.operation == UnaryExpr.Operation.PREDECREMENT) { out.append("--"); } if (unaryExpr.operation == UnaryExpr.Operation.PREINCREMENT) { out.append("++"); } unaryExpr.expr.accept(this); if (unaryExpr.operation == UnaryExpr.Operation.POSTDECREMENT) { out.append("--"); } if (unaryExpr.operation == UnaryExpr.Operation.POSTINCREMENT) { out.append("++"); } } @Override public void visit(de.dhbwstuttgart.syntaxtree.statement.Literal literal) { out.append(literal.value); } @Override public void visit(Throw aThrow) { // TODO implement } @Override public void visit(Switch switchStmt) { out.append("switch("); switchStmt.getSwitch().accept(this); out.append("){\n"); tab(); for (SwitchBlock switchBlock : switchStmt.getBlocks()) { switchBlock.accept(this); } untab(); out.append(tabs); out.append("}::"); switchStmt.getType().accept(this); } @Override public void visit(SwitchBlock switchBlock) { switchBlock.getLabels().stream().forEach((label) -> { out.append(tabs); label.accept(this); }); tab(); switchBlock.getStatements().stream().forEach((stmt) -> { out.append(tabs); stmt.accept(this); out.append(";\n"); }); out.append("\n"); untab(); } @Override public void visit(SwitchLabel switchLabel) { if (switchLabel.isDefault()) { out.append("default"); } else { out.append("case "); switchLabel.getPattern().accept(this); } out.append(":\n"); } @Override public void visit(Yield aYield) { out.append("yield ("); aYield.retexpr.accept(this); out.append(")::"); aYield.getType().accept(this); } @Override public void visit(ExpressionPattern aPattern) { aPattern.getType().accept(this); out.append(" "); aPattern.getExpression().accept(this); } @Override public void visit(RecordPattern aRecordPattern) { aRecordPattern.getType().accept(this); out.append("("); List subPatterns = aRecordPattern.getSubPattern(); int i; for (i = 0; i < subPatterns.size() - 1; i++) { subPatterns.get(i).accept(this); out.append(", "); } subPatterns.get(i).accept(this); String name; if ((name = aRecordPattern.getName()) != null) out.append(name); out.append(")"); } @Override public void visit(GuardedPattern aGuardedPattern) { aGuardedPattern.getNestedPattern().accept(this); out.append(" with "); aGuardedPattern.getCondition().accept(this); } }