Package me.pixodro.j2cpp.core.rewrite

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

/*******************************************************************************
* Copyright (c) 2008, 2012 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
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package me.pixodro.j2cpp.core.rewrite;

import java.util.List;

import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTLiteralNode;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;

/**
* Visits all nodes, prints leading comments and handles macro expansions. The
* source code generation is delegated to severals {@code NodeWriter}s.
*
* @see MacroExpansionHandler
*
* @author Emanuel Graf IFS
*/
public class ASTWriterVisitor extends ASTVisitor {
  protected final Scribe scribe = new Scribe();
  protected NodeCommentMap commentMap;
  protected ExpressionWriter expWriter;
  protected DeclSpecWriter declSpecWriter;
  protected StatementWriter statementWriter;
  protected DeclaratorWriter declaratorWriter;
  protected DeclarationWriter declarationWriter;
  protected InitializerWriter initializerWriter;
  protected NameWriter nameWriter;
  protected TemplateParameterWriter tempParameterWriter;
  protected MacroExpansionHandler macroHandler;
  private boolean insertLeadingBlankLine;
  private boolean suppressLeadingBlankLine;
  private boolean spaceNeededBeforeName;

  {
    shouldVisitArrayModifiers = true;
    shouldVisitBaseSpecifiers = true;
    shouldVisitDeclarations = true;
    shouldVisitDeclarators = true;
    shouldVisitDeclSpecifiers = true;
    shouldVisitExpressions = true;
    shouldVisitInitializers = true;
    shouldVisitNames = true;
    shouldVisitNamespaces = true;
    shouldVisitParameterDeclarations = true;
    shouldVisitPointerOperators = true;
    shouldVisitStatements = true;
    shouldVisitTemplateParameters = true;
    shouldVisitTranslationUnit = true;
    shouldVisitTypeIds = true;
  }

  /**
   * Creates a writer with an empty comment map.
   */
  public ASTWriterVisitor() {
    this(new NodeCommentMap());
  }

  public ASTWriterVisitor(final NodeCommentMap commentMap) {
    super();
    init(commentMap);
    this.commentMap = commentMap;
    suppressLeadingBlankLine = true;
  }

  private void init(final NodeCommentMap commentMap) {
    macroHandler = new MacroExpansionHandler(scribe);
    statementWriter = new StatementWriter(scribe, this, commentMap);
    declaratorWriter = new DeclaratorWriter(scribe, this, commentMap);
    declarationWriter = new DeclarationWriter(scribe, this, commentMap);
    declSpecWriter = new DeclSpecWriter(scribe, this, commentMap);
    expWriter = new ExpressionWriter(scribe, this, macroHandler, commentMap);
    initializerWriter = new InitializerWriter(scribe, this, commentMap);
    // ppStmtWriter = new PreprocessorStatementWriter(scribe, this, commentMap);
    nameWriter = new NameWriter(scribe, this, commentMap);
    tempParameterWriter = new TemplateParameterWriter(scribe, this, commentMap);
  }

  @Override
  public String toString() {
    return scribe.toString();
  }

  @Override
  public int leave(final IASTTranslationUnit tu) {
    for (final IASTComment comment : commentMap.getFreestandingCommentsForNode(tu)) {
      scribe.print(comment.getComment());
      scribe.newLine();
    }
    return super.leave(tu);
  }

  private void writeLeadingComments(final IASTNode node) {
    for (final IASTComment comment : getLeadingComments(node)) {
      scribe.print(comment.getComment());
      scribe.newLine();
    }
  }

  private List<IASTComment> getLeadingComments(final IASTNode node) {
    final List<IASTComment> leadingComments = commentMap.getLeadingCommentsForNode(node);
    final IASTNode originalNode = node.getOriginalNode();
    if (originalNode != node) {
      leadingComments.addAll(commentMap.getLeadingCommentsForNode(originalNode));
    }
    return leadingComments;
  }

  public void visit(final ASTLiteralNode lit) {
    insertBlankLineIfNeeded(lit);
    scribe.print(lit.getRawSignature());
  }

  @Override
  public int visit(final IASTName name) {
    if (spaceNeededBeforeName && (name.getSimpleID().length != 0)) {
      scribe.printSpace();
      spaceNeededBeforeName = false;
    }
    writeLeadingComments(name);
    if (!macroHandler.checkisMacroExpansionNode(name)) {
      nameWriter.writeName(name);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTDeclSpecifier declSpec) {
    writeLeadingComments(declSpec);
    declSpecWriter.writeDelcSpec(declSpec);
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTExpression expression) {
    writeLeadingComments(expression);
    if (!macroHandler.checkisMacroExpansionNode(expression)) {
      if (expression instanceof IGNUASTCompoundStatementExpression) {
        final IGNUASTCompoundStatementExpression gnuCompStmtExp = (IGNUASTCompoundStatementExpression) expression;
        gnuCompStmtExp.getCompoundStatement().accept(this);
      } else {
        expWriter.writeExpression(expression);
      }
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTStatement statement) {
    insertBlankLineIfNeeded(statement);
    writeLeadingComments(statement);
    try {
      if (macroHandler.isStatementWithMixedLocation(statement) && !(statement instanceof IASTCompoundStatement)) {
        return statementWriter.writeMixedStatement(statement);
      }
      if (macroHandler.checkisMacroExpansionNode(statement)) {
        return ASTVisitor.PROCESS_SKIP;
      }
      return statementWriter.writeStatement(statement, true);
    } finally {
      setLeadingBlankLineFlags(statement);
    }
  }

  @Override
  public int visit(final IASTDeclaration declaration) {
    insertBlankLineIfNeeded(declaration);
    writeLeadingComments(declaration);
    if (!macroHandler.checkisMacroExpansionNode(declaration)) {
      declarationWriter.writeDeclaration(declaration);
      setLeadingBlankLineFlags(declaration);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTDeclarator declarator) {
    writeLeadingComments(declarator);
    if (!macroHandler.checkisMacroExpansionNode(declarator)) {
      declaratorWriter.writeDeclarator(declarator);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTArrayModifier amod) {
    if (!macroHandler.checkisMacroExpansionNode(amod)) {
      declaratorWriter.writeArrayModifier(amod);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTInitializer initializer) {
    writeLeadingComments(initializer);
    if (!macroHandler.checkisMacroExpansionNode(initializer)) {
      initializerWriter.writeInitializer(initializer);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTParameterDeclaration parameterDeclaration) {
    writeLeadingComments(parameterDeclaration);
    if (!macroHandler.checkisMacroExpansionNode(parameterDeclaration)) {
      parameterDeclaration.getDeclSpecifier().accept(this);
      final IASTDeclarator declarator = getParameterDeclarator(parameterDeclaration);

      spaceNeededBeforeName = true;
      declarator.accept(this);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final IASTPointerOperator pointerOperator) {
    writeLeadingComments(pointerOperator);
    if (!macroHandler.checkisMacroExpansionNode(pointerOperator)) {
      declaratorWriter.writePointerOperator(pointerOperator);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  protected IASTName getParameterName(final IASTDeclarator declarator) {
    return declarator.getName();
  }

  protected IASTDeclarator getParameterDeclarator(final IASTParameterDeclaration parameterDeclaration) {
    return parameterDeclaration.getDeclarator();
  }

  @Override
  public int visit(final ICPPASTNamespaceDefinition namespace) {
    insertBlankLineIfNeeded(namespace);
    writeLeadingComments(namespace);
    if (!macroHandler.checkisMacroExpansionNode(namespace)) {
      declarationWriter.writeDeclaration(namespace);
      setLeadingBlankLineFlags(namespace);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  @Override
  public int visit(final ICPPASTTemplateParameter parameter) {
    writeLeadingComments(parameter);
    if (!macroHandler.checkisMacroExpansionNode(parameter)) {
      tempParameterWriter.writeTemplateParameter(parameter);
    }
    return ASTVisitor.PROCESS_SKIP;
  }

  public void cleanCache() {
    scribe.cleanCache();
    macroHandler.reset();
  }

  private void insertBlankLineIfNeeded(final IASTNode node) {
    if (!suppressLeadingBlankLine && (insertLeadingBlankLine || ASTWriter.requiresLeadingBlankLine(node))) {
      scribe.newLine();
    }
    insertLeadingBlankLine = false;
    suppressLeadingBlankLine = false;
  }

  private void setLeadingBlankLineFlags(final IASTNode node) {
    insertLeadingBlankLine = ASTWriter.requiresTrailingBlankLine(node);
    suppressLeadingBlankLine = ASTWriter.suppressesTrailingBlankLine(node);
  }

  public boolean isSuppressLeadingBlankLine() {
    return suppressLeadingBlankLine;
  }

  public void setSuppressLeadingBlankLine(final boolean value) {
    suppressLeadingBlankLine = value;
  }

  public boolean isSpaceNeededBeforeName() {
    return spaceNeededBeforeName;
  }

  public void setSpaceNeededBeforeName(final boolean value) {
    spaceNeededBeforeName = value;
  }

  public Scribe getScribe() {
    return scribe;
  }

  public void newLine() {
    scribe.newLine();
  }
}
TOP

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

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.