Package me.pixodro.j2cpp.core.rewrite

Source Code of me.pixodro.j2cpp.core.rewrite.StatementWriter

/*******************************************************************************
* Copyright (c) 2008, 2010 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
*******************************************************************************/
package me.pixodro.j2cpp.core.rewrite;

import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblemStatement;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;

/**
* Generates source code of statement nodes. The actual string operations are delegated
* to the <code>Scribe</code> class.
*
* @see Scribe
* @see IASTStatement
* @author Emanuel Graf IFS
*/
public class StatementWriter extends NodeWriter {
  private static final String DEFAULT = "default:"; //$NON-NLS-1$
  private static final String CASE = "case "; //$NON-NLS-1$
  private static final String WHILE = "while ("; //$NON-NLS-1$
  private static final String TRY = "try "; //$NON-NLS-1$
  private static final String CATCH = "catch ("; //$NON-NLS-1$
  private static final String RETURN = "return"; //$NON-NLS-1$
  private static final String GOTO = "goto "; //$NON-NLS-1$
  private static final String CONTINUE = "continue"; //$NON-NLS-1$
  private static final String BREAK = "break"; //$NON-NLS-1$
  private static final String ELSE = "else"; //$NON-NLS-1$
  private static final String IF = "if ("; //$NON-NLS-1$
  private static final String FOR = "for ("; //$NON-NLS-1$
  private static final String DO_WHILE = " while ("; //$NON-NLS-1$
  private static final String DO = "do"; //$NON-NLS-1$
  private static final String SWITCH_BRACKET = "switch ("; //$NON-NLS-1$
  private boolean compoundNoNewLine = false;
  private boolean switchIsNew;
  private boolean decrementIndentationLevelOneMore = false;
  private final DeclarationWriter declWriter;

  public StatementWriter(final Scribe scribe, final ASTWriterVisitor visitor, final NodeCommentMap commentMap) {
    super(scribe, visitor, commentMap);
    declWriter = new DeclarationWriter(scribe, visitor, commentMap);
  }

  /**
   * Prints a statement.
   *
   * @param statement
   *          the statement
   * @param newLine
   *          if true print a newline if statement usually have one.
   * @return {@link ASTVisitor#PROCESS_SKIP}
   */
  protected int writeStatement(final IASTStatement statement, boolean newLine) {
    if (statement instanceof IASTAmbiguousStatement) {
      // TODO HSR Leo test
      statement.accept(visitor);
      newLine = false;
    } else if (statement instanceof IASTExpressionStatement) {
      writeExpressionStatement((IASTExpressionStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTDeclarationStatement) {
      writeDeclarationStatement((IASTDeclarationStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTNullStatement) {
      writeNullStatement((IASTNullStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTReturnStatement) {
      writeReturnStatement((IASTReturnStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTGotoStatement) {
      writeGotoStatement((IASTGotoStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTLabelStatement) {
      writeLabelStatement((IASTLabelStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTCaseStatement) {
      writeCaseStatement((IASTCaseStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTDefaultStatement) {
      writeDefaultStatement((IASTDefaultStatement) statement);
    } else if (statement instanceof IASTContinueStatement) {
      writeContinueStatement((IASTContinueStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTCompoundStatement) {
      if (compoundNoNewLine) {
        newLine = false;
        compoundNoNewLine = false;
      }
      writeCompoundStatement((IASTCompoundStatement) statement);
    } else if (statement instanceof IASTBreakStatement) {
      writeBreakStatement((IASTBreakStatement) statement);
      // usually newLine
    } else if (statement instanceof IASTSwitchStatement) {
      writeSwitchStatement((IASTSwitchStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTIfStatement) {
      writeIfStatement((IASTIfStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTWhileStatement) {
      writeWhileStatement((IASTWhileStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTForStatement) {
      writeForStatement((IASTForStatement) statement);
      newLine = false;
    } else if (statement instanceof ICPPASTRangeBasedForStatement) {
      writeForStatement((ICPPASTRangeBasedForStatement) statement);
      newLine = false;
    } else if (statement instanceof IASTDoStatement) {
      writeDoStatement((IASTDoStatement) statement);
      newLine = true;
    } else if (statement instanceof ICPPASTTryBlockStatement) {
      writeTryBlockStatement((ICPPASTTryBlockStatement) statement);
      newLine = false;
    } else if (statement instanceof ICPPASTCatchHandler) {
      writeCatchHandler((ICPPASTCatchHandler) statement);
      newLine = false;
    } else if (statement instanceof IASTProblemStatement) {
      throw new ProblemRuntimeException((IASTProblemStatement) statement);
    }

    writeTrailingComments(statement, newLine);

    return ASTVisitor.PROCESS_SKIP;
  }

  private void writeDoStatement(final IASTDoStatement doStatement) {
    nextCompoundNoNewLine();

    scribe.print(DO);
    writeBodyStatement(doStatement.getBody(), true);
    scribe.print(DO_WHILE);
    doStatement.getCondition().accept(visitor);
    scribe.print(')');
    scribe.printSemicolon();
  }

  private void writeForStatement(final IASTForStatement forStatement) {
    scribe.noNewLines();
    scribe.print(FOR);
    writeStatement(forStatement.getInitializerStatement(), false);
    if (forStatement instanceof ICPPASTForStatement) {
      final ICPPASTForStatement cppForStatment = (ICPPASTForStatement) forStatement;
      final IASTDeclaration cppConditionDeclaration = cppForStatment.getConditionDeclaration();
      if (cppConditionDeclaration == null) {
        visitNodeIfNotNull(cppForStatment.getConditionExpression());
        scribe.printSemicolon();
      } else {
        cppConditionDeclaration.accept(visitor);
      }
    } else {
      if (forStatement.getConditionExpression() != null) {
        forStatement.getConditionExpression().accept(visitor);
        scribe.printSemicolon();
      }
    }

    visitNodeIfNotNull(forStatement.getIterationExpression());
    scribe.print(')');
    scribe.newLines();
    nextCompoundNoNewLine();
    writeBodyStatement(forStatement.getBody(), false);
  }

  private void writeForStatement(final ICPPASTRangeBasedForStatement forStatment) {
    scribe.noNewLines();
    scribe.print(FOR);
    writeDeclarationWithoutSemicolon(forStatment.getDeclaration());
    scribe.print(COLON_SPACE);
    visitNodeIfNotNull(forStatment.getInitializerClause());
    scribe.print(')');
    scribe.newLines();
    nextCompoundNoNewLine();
    writeBodyStatement(forStatment.getBody(), false);
  }

  private void writeIfStatement(final IASTIfStatement ifStatement) {
    scribe.print(IF);
    scribe.noNewLines();
    if (ifStatement instanceof ICPPASTIfStatement) {
      final ICPPASTIfStatement cppIfStatment = (ICPPASTIfStatement) ifStatement;

      if (cppIfStatment.getConditionDeclaration() == null) {
        cppIfStatment.getConditionExpression().accept(visitor);
      } else {
        writeDeclarationWithoutSemicolon(cppIfStatment.getConditionDeclaration());
      }
    } else {
      ifStatement.getConditionExpression().accept(visitor);
    }

    scribe.print(')');
    scribe.newLines();
    nextCompoundNoNewLine();
    final IASTStatement elseClause = ifStatement.getElseClause();
    writeBodyStatement(ifStatement.getThenClause(), elseClause != null);

    if (elseClause != null) {
      scribe.print(ELSE);
      nextCompoundNoNewLine();
      writeBodyStatement(elseClause, false);
    }
  }

  protected void writeDeclarationWithoutSemicolon(final IASTDeclaration declaration) {
    declWriter.writeDeclaration(declaration, false);
  }

  private void writeBreakStatement(final IASTBreakStatement statement) {
    scribe.print(BREAK);
    scribe.printSemicolon();
  }

  private void writeContinueStatement(final IASTContinueStatement statement) {
    scribe.print(CONTINUE);
    scribe.printSemicolon();
  }

  private void writeLabelStatement(final IASTLabelStatement labelStatement) {
    labelStatement.getName().accept(visitor);
    scribe.print(':');
    scribe.newLine();
    labelStatement.getNestedStatement().accept(visitor);
  }

  private void writeGotoStatement(final IASTGotoStatement gotoStatement) {
    scribe.print(GOTO);
    gotoStatement.getName().accept(visitor);
    scribe.printSemicolon();
  }

  private void writeReturnStatement(final IASTReturnStatement returnStatement) {
    scribe.noNewLines();
    scribe.print(RETURN);
    final IASTExpression returnValue = returnStatement.getReturnValue();
    if (returnValue != null) {
      scribe.printSpaces(1);
      returnValue.accept(visitor);
    }
    scribe.newLines();
    scribe.printSemicolon();
  }

  private void writeNullStatement(final IASTNullStatement nullStmt) {
    scribe.printSemicolon();
  }

  private void writeDeclarationStatement(final IASTDeclarationStatement decStmt) {
    decStmt.getDeclaration().accept(visitor);
  }

  private void writeExpressionStatement(final IASTExpressionStatement expStmt) {
    expStmt.getExpression().accept(visitor);
    scribe.printSemicolon();
  }

  private void writeCatchHandler(final ICPPASTCatchHandler catchStatement) {
    scribe.print(CATCH);
    if (catchStatement.isCatchAll()) {
      scribe.print(VAR_ARGS);
    } else {
      scribe.noSemicolon();
      scribe.noNewLines();
      catchStatement.getDeclaration().accept(visitor);
      scribe.newLines();
    }
    scribe.print(')');
    writeBodyStatement(catchStatement.getCatchBody(), true);
  }

  private void writeTryBlockStatement(final ICPPASTTryBlockStatement tryStatement) {
    scribe.print(TRY);
    tryStatement.getTryBody().accept(visitor);
    for (final ICPPASTCatchHandler catchStatement : tryStatement.getCatchHandlers()) {
      writeStatement(catchStatement, false);
    }
  }

  private void writeWhileStatement(final IASTWhileStatement whileStatment) {
    scribe.print(WHILE);
    scribe.noNewLines();
    if (whileStatment instanceof ICPPASTWhileStatement) {
      final ICPPASTWhileStatement cppWhileStatment = (ICPPASTWhileStatement) whileStatment;
      if (cppWhileStatment.getConditionDeclaration() == null) {
        cppWhileStatment.getCondition().accept(visitor);
      } else {
        writeDeclarationWithoutSemicolon(cppWhileStatment.getConditionDeclaration());
      }
    } else {
      whileStatment.getCondition().accept(visitor);
    }
    scribe.print(')');
    scribe.newLines();
    nextCompoundNoNewLine();
    writeBodyStatement(whileStatment.getBody(), false);
  }

  private void writeCaseStatement(final IASTCaseStatement caseStatement) {
    nextCompoundIndentationLevelOneMore();

    if (!switchIsNew) {
      scribe.decrementIndentationLevel();
    }
    scribe.print(CASE);
    caseStatement.getExpression().accept(visitor);
    scribe.print(':');
    scribe.incrementIndentationLevel();
    switchIsNew = false;
  }

  private void writeSwitchStatement(final IASTSwitchStatement switchStatement) {
    switchIsNew = true;

    scribe.print(SWITCH_BRACKET);
    scribe.noNewLines();
    if (switchStatement instanceof ICPPASTSwitchStatement) {
      final ICPPASTSwitchStatement cppSwitchStatement = (ICPPASTSwitchStatement) switchStatement;
      if (cppSwitchStatement.getControllerDeclaration() == null) {
        cppSwitchStatement.getControllerExpression().accept(visitor);
      } else {
        declWriter.writeDeclaration(cppSwitchStatement.getControllerDeclaration(), false);
      }
    } else {
      switchStatement.getControllerExpression().accept(visitor);
    }
    scribe.print(')');
    scribe.newLines();
    nextCompoundNoNewLine();
    writeBodyStatement(switchStatement.getBody(), false);

    switchIsNew = false;
  }

  private void writeDefaultStatement(final IASTDefaultStatement defaultStatement) {
    nextCompoundIndentationLevelOneMore();

    if (!switchIsNew) {
      scribe.decrementIndentationLevel();
    }
    scribe.print(DEFAULT);
    scribe.incrementIndentationLevel();
    switchIsNew = false;
  }

  private void writeCompoundStatement(final IASTCompoundStatement compoundStatement) {
    scribe.printLBrace();
    scribe.newLine();
    for (final IASTStatement statements : getNestedStatements(compoundStatement)) {
      statements.accept(visitor);
    }

    if (hasFreestandingComments(compoundStatement)) {
      writeFreestandingComments(compoundStatement);
    }

    if (decrementIndentationLevelOneMore) {
      scribe.decrementIndentationLevel();
      decrementIndentationLevelOneMore = false;
    }
    scribe.printRBrace();
  }

  protected IASTStatement[] getNestedStatements(final IASTCompoundStatement compoundStatement) {
    return compoundStatement.getStatements();
  }

  // TODO(sprigogin): Invert and rename second parameter
  protected void writeBodyStatement(final IASTStatement statement, final boolean isDoStatement) {
    if (statement instanceof IASTCompoundStatement) {
      // TODO hsr existiert noch eine methode
      statement.accept(visitor);
      if (!isDoStatement) {
        scribe.newLine();
      }
      compoundNoNewLine = false;
    } else if (statement instanceof IASTNullStatement) {
      statement.accept(visitor);
      scribe.newLine();
    } else {
      scribe.incrementIndentationLevel();
      scribe.newLine();
      statement.accept(visitor);
      scribe.decrementIndentationLevel();
    }
  }

  /**
   * Write no new line after the next compound statement
   */
  protected void nextCompoundNoNewLine() {
    compoundNoNewLine = true;
  }

  /**
   * Indent one time more at the end (before the closing brackets)
   * of a compound statement
   */
  protected void nextCompoundIndentationLevelOneMore() {
    decrementIndentationLevelOneMore = true;
  }

  protected int writeMixedStatement(final IASTStatement statement) {
    final String code = statement.getRawSignature();
    scribe.println(code);
    return ASTVisitor.PROCESS_SKIP;
  }
}
TOP

Related Classes of me.pixodro.j2cpp.core.rewrite.StatementWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.