Package me.pixodro.j2cpp.core.rewrite

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

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

import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
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.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;

/**
* Generates source code of declaration nodes. The actual string operations are delegated
* to the <code>Scribe</code> class.
*
* @see Scribe
* @see IASTDeclaration
* @author Emanuel Graf IFS
*/
public class DeclarationWriter extends NodeWriter {
  private static final String ASM_END = ")"; //$NON-NLS-1$
  private static final String ASM_START = "asm("; //$NON-NLS-1$
  private static final String TEMPLATE_DECLARATION = "template<"; //$NON-NLS-1$
  private static final String TEMPLATE_SPECIALIZATION = "template <> "; //$NON-NLS-1$
  private boolean printSemicolon;

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

  protected void writeDeclaration(final IASTDeclaration declaration) throws ProblemRuntimeException {
    writeDeclaration(declaration, true);
  }

  protected void writeDeclaration(final IASTDeclaration declaration, final boolean writeSemicolon) {
    boolean addNewLine = true;
    printSemicolon = writeSemicolon;
    if (declaration instanceof IASTASMDeclaration) {
      writeASMDeclatation((IASTASMDeclaration) declaration);
    } else if (declaration instanceof IASTFunctionDefinition) {
      writeFunctionDefinition((IASTFunctionDefinition) declaration);
      addNewLine = false;
    } else if (declaration instanceof IASTProblemDeclaration) {
      throw new ProblemRuntimeException((IASTProblemDeclaration) declaration);
    } else if (declaration instanceof IASTSimpleDeclaration) {
      writeSimpleDeclaration((IASTSimpleDeclaration) declaration);
    } else if (declaration instanceof ICPPASTExplicitTemplateInstantiation) {
      writeExplicitTemplateInstantiation((ICPPASTExplicitTemplateInstantiation) declaration);
      addNewLine = false;
    } else if (declaration instanceof ICPPASTLinkageSpecification) {
      writeLinkageSpecification((ICPPASTLinkageSpecification) declaration);
    } else if (declaration instanceof ICPPASTNamespaceAlias) {
      writeNamespaceAlias((ICPPASTNamespaceAlias) declaration);
    } else if (declaration instanceof ICPPASTTemplateDeclaration) {
      writeTemplateDeclaration((ICPPASTTemplateDeclaration) declaration);
      addNewLine = false;
    } else if (declaration instanceof ICPPASTTemplateSpecialization) {
      writeTemplateSpecialization((ICPPASTTemplateSpecialization) declaration);
      addNewLine = false;
    } else if (declaration instanceof ICPPASTUsingDeclaration) {
      writeUsingDeclaration((ICPPASTUsingDeclaration) declaration);
    } else if (declaration instanceof ICPPASTUsingDirective) {
      writeUsingDirective((ICPPASTUsingDirective) declaration);
    } else if (declaration instanceof ICPPASTVisibilityLabel) {
      writeVisibilityLabel((ICPPASTVisibilityLabel) declaration);
    }

    writeTrailingComments(declaration, addNewLine);
    if (hasFreestandingComments(declaration)) {
      if (declaration instanceof IASTFunctionDefinition) {
        scribe.newLine();
      }
      writeFreestandingComments(declaration);
    }
  }

  private void writeVisibilityLabel(final ICPPASTVisibilityLabel visiblityLabel) {
    scribe.decrementIndentationLevel();
    switch (visiblityLabel.getVisibility()) {
    case ICPPASTVisibilityLabel.v_private:
      scribe.print(Keywords.PRIVATE);
      scribe.print(':');
      break;
    case ICPPASTVisibilityLabel.v_protected:
      scribe.print(Keywords.PROTECTED);
      scribe.print(':');
      break;
    case ICPPASTVisibilityLabel.v_public:
      scribe.print(Keywords.PUBLIC);
      scribe.print(':');
      break;
    default:
      return;
    }
    scribe.incrementIndentationLevel();
  }

  private void writeUsingDirective(final ICPPASTUsingDirective usingDirective) {
    scribe.printStringSpace(Keywords.USING);
    scribe.printStringSpace(Keywords.NAMESPACE);
    usingDirective.getQualifiedName().accept(visitor);
    scribe.printSemicolon();
  }

  private void writeUsingDeclaration(final ICPPASTUsingDeclaration usingDeclaration) {
    scribe.printStringSpace(Keywords.USING);
    if (usingDeclaration.isTypename()) {
      scribe.printStringSpace(Keywords.TYPENAME);
    }
    usingDeclaration.getName().accept(visitor);
    scribe.printSemicolon();
  }

  private void writeTemplateSpecialization(final ICPPASTTemplateSpecialization templateSpecialization) {
    scribe.print(TEMPLATE_SPECIALIZATION);
    templateSpecialization.getDeclaration().accept(visitor);
  }

  protected void writeTemplateDeclaration(final ICPPASTTemplateDeclaration templateDeclaration) {
    if (templateDeclaration.isExported()) {
      scribe.printStringSpace(Keywords.EXPORT);
    }
    scribe.print(TEMPLATE_DECLARATION);
    final ICPPASTTemplateParameter[] paraDecls = templateDeclaration.getTemplateParameters();
    for (int i = 0; i < paraDecls.length; ++i) {
      paraDecls[i].accept(visitor);
      if ((i + 1) < paraDecls.length) {
        scribe.print(',');
        scribe.printSpaces(1);
      }
    }
    scribe.print('>');
    scribe.printSpace();
    templateDeclaration.getDeclaration().accept(visitor);
  }

  protected void writeDeclaration(final ICPPASTNamespaceDefinition declaration) {
    printSemicolon = true;
    writeNamespaceDefinition(declaration);
  }

  private void writeNamespaceDefinition(final ICPPASTNamespaceDefinition namespaceDefinition) {
    scribe.printStringSpace(Keywords.NAMESPACE);
    namespaceDefinition.getName().accept(visitor);
    if (!hasTrailingComments(namespaceDefinition.getName())) {
      scribe.newLine();
    }
    scribe.print('{');
    scribe.newLine(2);
    writeDeclarationsInNamespace(namespaceDefinition, namespaceDefinition.getDeclarations());
    if (hasFreestandingComments(namespaceDefinition)) {
      writeFreestandingComments(namespaceDefinition);
    }
    scribe.newLine();
    scribe.print('}');

    if (hasTrailingComments(namespaceDefinition)) {
      writeTrailingComments(namespaceDefinition);
    } else {
      scribe.newLine();
    }
  }

  protected void writeDeclarationsInNamespace(final ICPPASTNamespaceDefinition namespaceDefinition, final IASTDeclaration[] declarations) {
    for (final IASTDeclaration declaration : declarations) {
      declaration.accept(visitor);
    }
  }

  private void writeNamespaceAlias(final ICPPASTNamespaceAlias namespaceAliasDefinition) {
    scribe.printStringSpace(Keywords.NAMESPACE);
    namespaceAliasDefinition.getAlias().accept(visitor);
    scribe.print(EQUALS);
    namespaceAliasDefinition.getMappingName().accept(visitor);
    printSemicolon();
  }

  private void writeLinkageSpecification(final ICPPASTLinkageSpecification linkageSpecification) {
    scribe.printStringSpace(Keywords.EXTERN);
    scribe.printStringSpace(linkageSpecification.getLiteral());

    final IASTDeclaration[] declarations = linkageSpecification.getDeclarations();
    if (declarations.length > 1) {
      scribe.printLBrace();
      scribe.decrementIndentationLevel();
      scribe.newLine();
      for (final IASTDeclaration declaration : declarations) {
        declaration.accept(visitor);
      }
      scribe.printRBrace();
      scribe.incrementIndentationLevel();
    } else if (declarations.length > 0) {
      visitNodeIfNotNull(declarations[0]);
    }
  }

  private void writeExplicitTemplateInstantiation(final ICPPASTExplicitTemplateInstantiation explicitTemplateInstantiation) {
    switch (explicitTemplateInstantiation.getModifier()) {
    case ICPPASTExplicitTemplateInstantiation.EXTERN:
      scribe.printStringSpace(Keywords.EXTERN);
      break;
    case ICPPASTExplicitTemplateInstantiation.INLINE:
      scribe.printStringSpace(Keywords.INLINE);
      break;
    case ICPPASTExplicitTemplateInstantiation.STATIC:
      scribe.printStringSpace(Keywords.STATIC);
      break;
    }

    scribe.printStringSpace(Keywords.TEMPLATE);
    explicitTemplateInstantiation.getDeclaration().accept(visitor);
  }

  private void writeASMDeclatation(final IASTASMDeclaration asmDeclaration) {
    scribe.print(ASM_START);
    scribe.print(asmDeclaration.getAssembly());
    scribe.print(ASM_END);
    printSemicolon();
  }

  private void printSemicolon() {
    if (printSemicolon) {
      scribe.printSemicolon();
    }
  }

  private void writeFunctionDefinition(final IASTFunctionDefinition funcDef) {
    final IASTDeclSpecifier declSpecifier = funcDef.getDeclSpecifier();
    if (declSpecifier != null) {
      declSpecifier.accept(visitor);
    }
    if (declSpecifier instanceof IASTSimpleDeclSpecifier) {
      final IASTSimpleDeclSpecifier simDeclSpec = (IASTSimpleDeclSpecifier) declSpecifier;
      if (simDeclSpec.getType() != IASTSimpleDeclSpecifier.t_unspecified) {
        visitor.setSpaceNeededBeforeName(true);
      }
    } else {
      visitor.setSpaceNeededBeforeName(true);
    }
    final IASTDeclarator declarator = ASTQueries.findOutermostDeclarator(funcDef.getDeclarator());
    declarator.accept(visitor);

    if (funcDef instanceof ICPPASTFunctionWithTryBlock) {
      scribe.newLine();
      scribe.print(Keywords.TRY);
    }

    if (funcDef instanceof ICPPASTFunctionDefinition) {
      final ICPPASTFunctionDefinition cppFuncDef = (ICPPASTFunctionDefinition) funcDef;
      writeCtorChainInitializer(cppFuncDef, cppFuncDef.getMemberInitializers());
    }
    scribe.newLine();

    funcDef.getBody().accept(visitor);

    if (funcDef instanceof ICPPASTFunctionWithTryBlock) {
      final ICPPASTFunctionWithTryBlock tryblock = (ICPPASTFunctionWithTryBlock) funcDef;
      final ICPPASTCatchHandler[] catches = tryblock.getCatchHandlers();
      for (final ICPPASTCatchHandler handler : catches) {
        handler.accept(visitor);
      }
    }
  }

  protected void writeCtorChainInitializer(final ICPPASTFunctionDefinition funcDec, final ICPPASTConstructorChainInitializer[] ctorInitChain) {
    if (ctorInitChain.length != 0) {
      scribe.newLine();
      scribe.print(':');
    }
    for (int i = 0; i < ctorInitChain.length; ++i) {
      final ICPPASTConstructorChainInitializer initializer = ctorInitChain[i];
      initializer.accept(visitor);
      if ((i + 1) < ctorInitChain.length) {
        scribe.print(COMMA_SPACE);
      }
    }
  }

  private void writeSimpleDeclaration(final IASTSimpleDeclaration simpDec) {
    final IASTDeclSpecifier declSpecifier = simpDec.getDeclSpecifier();
    final IASTDeclarator[] decls = simpDec.getDeclarators();

    declSpecifier.accept(visitor);
    boolean noSpace = false;
    if (declSpecifier instanceof IASTSimpleDeclSpecifier) {
      final IASTSimpleDeclSpecifier simpleDeclSpecifier = (IASTSimpleDeclSpecifier) declSpecifier;
      if (simpleDeclSpecifier.getType() == IASTSimpleDeclSpecifier.t_unspecified) {
        noSpace = true;
      }
    }

    if (decls.length > 0) {
      if (decls.length == 1) {
        if (!noSpace) {
          visitor.setSpaceNeededBeforeName(true);
        }
        decls[0].accept(visitor);
      } else {
        if (!noSpace) {
          scribe.printSpace();
        }
        writeNodeList(decls);
      }
    }

    printSemicolon();
  }
}
TOP

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

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.