mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 04:15:35 +02:00
Javadoc for the ast-rewrite facility, by Emanuel Graf, bug 226239.
This commit is contained in:
parent
b5ad408a60
commit
e4ae8a89a7
20 changed files with 371 additions and 147 deletions
|
@ -14,11 +14,19 @@ package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.ASTModificationStore;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.changegenerator.ChangeGeneratorWriterVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* ASTWriter main class. Generates source code from <code>IASTNode</code>. Uses a
|
||||
* <codeC>hangeGeneratorWriterVisitor</code> to generate the code for the given
|
||||
* nodes.
|
||||
*
|
||||
* @see ChangeGeneratorWriterVisitor
|
||||
*
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ASTWriter {
|
||||
|
||||
|
@ -27,19 +35,47 @@ public class ASTWriter {
|
|||
private String givenIndentation = ""; //$NON-NLS-1$
|
||||
|
||||
|
||||
/**
|
||||
* Creates a <code>ASTWriter</code>.
|
||||
*/
|
||||
public ASTWriter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>ASTWriter</code> that indents the code.
|
||||
*
|
||||
* @param givenIndentation The indention added to each line
|
||||
*/
|
||||
public ASTWriter(String givenIndentation) {
|
||||
super();
|
||||
this.givenIndentation = givenIndentation;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Genereates the source code representing this node.
|
||||
*
|
||||
* @param rootNode Node to write.
|
||||
* @return A <code>String</code> representing the source code for the node.
|
||||
* @throws ProblemRuntimeException if the node or one of it's children is a <code>IASTProblemNode</code>.
|
||||
*/
|
||||
public String write(IASTNode rootNode) throws ProblemRuntimeException {
|
||||
return write(rootNode, null, new NodeCommentMap());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Genereates the source code representing this node including comments.
|
||||
*
|
||||
* @param rootNode Node to write.
|
||||
* @param fileScope
|
||||
* @param commentMap Node Comment Map <code>ASTCommenter</code>
|
||||
* @return A <code>String</code> representing the source code for the node.
|
||||
* @throws ProblemRuntimeException if the node or one of it's children is a <code>IASTProblemNode</code>.
|
||||
*
|
||||
* @see ASTCommenter#getCommentedNodeMap(org.eclipse.cdt.core.dom.ast.IASTTranslationUnit)
|
||||
*/
|
||||
public String write(IASTNode rootNode, String fileScope, NodeCommentMap commentMap) throws ProblemRuntimeException {
|
||||
transformationVisitor = new ChangeGeneratorWriterVisitor(modificationStore, givenIndentation, fileScope, commentMap);
|
||||
rootNode.accept(transformationVisitor);
|
||||
|
|
|
@ -30,6 +30,17 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
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>NodeWriters</code>.
|
||||
*
|
||||
* @see NodeWriter
|
||||
* @see MacroExpansionHandler
|
||||
*
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class ASTWriterVisitor extends CPPASTVisitor {
|
||||
|
||||
protected Scribe scribe = new Scribe();
|
||||
|
|
|
@ -20,9 +20,15 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* This class serves as a container to pass several nodes to the
|
||||
* <code>ASTWriter</code>. This container is used if source code for several sibling nodes but
|
||||
* for their common parent node should be generated.
|
||||
*
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class ContainerNode extends ASTNode {
|
||||
|
||||
|
|
|
@ -35,9 +35,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of declaration specifier nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see IASTDeclSpecifier
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class DeclSpecWriter extends NodeWriter {
|
||||
private static final String MUTABLE = "mutable "; //$NON-NLS-1$
|
||||
|
@ -76,16 +83,15 @@ public class DeclSpecWriter extends NodeWriter {
|
|||
int type = simpDeclSpec.getType();
|
||||
if(type <= IASTSimpleDeclSpecifier.t_last) {
|
||||
return getASTSimpleDecSpecifier(type);
|
||||
}else {
|
||||
switch (type) {
|
||||
case ICPPASTSimpleDeclSpecifier.t_bool:
|
||||
return CPP_BOOL;
|
||||
case ICPPASTSimpleDeclSpecifier.t_wchar_t:
|
||||
return WCHAR_T;
|
||||
default:
|
||||
System.err.println("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case ICPPASTSimpleDeclSpecifier.t_bool:
|
||||
return CPP_BOOL;
|
||||
case ICPPASTSimpleDeclSpecifier.t_wchar_t:
|
||||
return WCHAR_T;
|
||||
default:
|
||||
System.err.println("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,14 +99,13 @@ public class DeclSpecWriter extends NodeWriter {
|
|||
int type = simpDeclSpec.getType();
|
||||
if(type <= IASTSimpleDeclSpecifier.t_last) {
|
||||
return getASTSimpleDecSpecifier(type);
|
||||
}else {
|
||||
switch (type) {
|
||||
case ICASTSimpleDeclSpecifier.t_Bool:
|
||||
return _BOOL;
|
||||
default:
|
||||
System.err.println("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case ICASTSimpleDeclSpecifier.t_Bool:
|
||||
return _BOOL;
|
||||
default:
|
||||
System.err.println("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unknow Specifiertype: " + type); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,16 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* 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{
|
||||
|
||||
|
|
|
@ -35,9 +35,16 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of declarator nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see IASTDeclarator
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class DeclaratorWriter extends NodeWriter {
|
||||
|
||||
|
|
|
@ -41,9 +41,16 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTUnaryExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTBinaryExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of expression nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see IASTExpression
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class ExpressionWriter extends NodeWriter{
|
||||
|
||||
|
@ -243,23 +250,22 @@ public class ExpressionWriter extends NodeWriter{
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
}else {
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_throw:
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_throw:
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -278,17 +284,16 @@ public class ExpressionWriter extends NodeWriter{
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
}else {
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
return unaryExpressionType == ICPPASTUnaryExpression.op_typeid;
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
return unaryExpressionType == ICPPASTUnaryExpression.op_typeid;
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -322,27 +327,26 @@ public class ExpressionWriter extends NodeWriter{
|
|||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else {
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_throw:
|
||||
return THROW;
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return TYPEID_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
return ALIGNOF_OP;
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return TYPEOF_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_throw:
|
||||
return THROW;
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return TYPEID_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
return ALIGNOF_OP;
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return TYPEOF_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
System.err.println("Unkwown unaryExpressionType: " + unaryExpressionType); //$NON-NLS-1$
|
||||
|
@ -363,24 +367,23 @@ public class ExpressionWriter extends NodeWriter{
|
|||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else {
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return CLOSING_BRACKET_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return CLOSING_BRACKET_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
if (unExp instanceof ICPPASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case ICPPASTUnaryExpression.op_typeid:
|
||||
return CLOSING_BRACKET_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}else if (unExp instanceof IGNUASTUnaryExpression) {
|
||||
switch (unaryExpressionType) {
|
||||
case IGNUASTUnaryExpression.op_alignOf:
|
||||
case IGNUASTUnaryExpression.op_typeof:
|
||||
return CLOSING_BRACKET_OP;
|
||||
default:
|
||||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
System.err.println("Unkwown unaryExpressionType " + unaryExpressionType); //$NON-NLS-1$
|
||||
|
|
|
@ -23,9 +23,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
|||
import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of initializer nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see IASTInitializer
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class InitializerWriter extends NodeWriter{
|
||||
|
||||
|
|
|
@ -16,6 +16,13 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
|
||||
/**
|
||||
*
|
||||
* Recognizes nodes that are the result of an macro expansion and replaces them
|
||||
* with a suitable macro call.
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class MacroExpansionHandler {
|
||||
|
||||
private int lastMacroExpOffset;
|
||||
|
@ -61,13 +68,12 @@ public class MacroExpansionHandler {
|
|||
|
||||
if (macroNode.asFileLocation().getNodeOffset() == lastMacroExpOffset) {
|
||||
return true;
|
||||
} else {
|
||||
if (write) {
|
||||
lastMacroExpOffset = macroNode.asFileLocation().getNodeOffset();
|
||||
scribe.print(node.getRawSignature());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (write) {
|
||||
lastMacroExpOffset = macroNode.asFileLocation().getNodeOffset();
|
||||
scribe.print(node.getRawSignature());
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of name nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see IASTName
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class NameWriter extends NodeWriter {
|
||||
|
||||
|
@ -97,15 +104,13 @@ public class NameWriter extends NodeWriter {
|
|||
ICPPASTTemplateId tempId, int i) {
|
||||
if(i <= 0){
|
||||
return false;
|
||||
}else{
|
||||
if (qname.getNames()[i-1] instanceof ICPPASTTemplateId) {
|
||||
return true;
|
||||
}else{
|
||||
IBinding binding = qname.getNames()[i-1].resolveBinding();
|
||||
if (binding instanceof CPPTemplateTypeParameter) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (qname.getNames()[i-1] instanceof ICPPASTTemplateId) {
|
||||
return true;
|
||||
}
|
||||
IBinding binding = qname.getNames()[i-1].resolveBinding();
|
||||
if (binding instanceof CPPTemplateTypeParameter) {
|
||||
return true;
|
||||
}
|
||||
return isDependentName(qname, tempId, i-1);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,14 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base class for node writers. This class contains methods and string constants
|
||||
* used by multiple node writers.
|
||||
*
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class NodeWriter {
|
||||
|
||||
protected Scribe scribe;
|
||||
|
|
|
@ -11,8 +11,18 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblemHolder;
|
||||
|
||||
/**
|
||||
*
|
||||
* This exception is thrown if a problem nod is passed to the astwriter. The Exception
|
||||
* contains the <code>IASTProblemHolder</code> that was passed to the writer.
|
||||
*
|
||||
* @see IASTProblem
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class ProblemRuntimeException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = -3661425564246498786L;
|
||||
|
|
|
@ -11,6 +11,15 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class is responsible for the string concatination and the management of
|
||||
* the indentations.
|
||||
*
|
||||
* @since 5.0
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class Scribe {
|
||||
|
||||
|
||||
|
|
|
@ -45,6 +45,16 @@ import org.eclipse.cdt.internal.core.dom.rewrite.util.FileContentHelper;
|
|||
import org.eclipse.cdt.internal.core.dom.rewrite.util.FileHelper;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* 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$
|
||||
|
|
|
@ -19,9 +19,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emanuel Graf
|
||||
*
|
||||
*
|
||||
* Generates source code of template parameter nodes. The actual string operations are delegated
|
||||
* to the <code>Scribe</code> class.
|
||||
*
|
||||
* @see Scribe
|
||||
* @see ICPPASTTemplateParameter
|
||||
* @author Emanuel Graf IFS
|
||||
*
|
||||
*/
|
||||
public class TemplateParameterWriter extends NodeWriter {
|
||||
|
||||
|
|
|
@ -22,11 +22,25 @@ import org.eclipse.core.runtime.Path;
|
|||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* @author Guido Zgraggen IFS
|
||||
*
|
||||
* This is the startpoint of the whole comment handling process. The creation of the
|
||||
* NodeCommentMap is based on the IASTTranslationUnit. From this TranslationUnit the comments
|
||||
* are extracted and skipped if they belong not to the same workspace. An ASTCommenterVisitor
|
||||
* is initialized with this collection of comments. And the visit process can start.
|
||||
*
|
||||
* @see org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommenter
|
||||
* @see org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap
|
||||
*
|
||||
* @author Guido Zgraggen IFS
|
||||
*/
|
||||
public class ASTCommenter {
|
||||
|
||||
/**
|
||||
* Creates a NodeCommentMap for the given TranslationUnit. This is the only way
|
||||
* to get a NodeCommentMap which contains all the comments mapped against nodes.
|
||||
*
|
||||
* @param transUnit TranslationUnit
|
||||
* @return NodeCommentMap
|
||||
*/
|
||||
public static NodeCommentMap getCommentedNodeMap(IASTTranslationUnit transUnit){
|
||||
if(transUnit== null) {
|
||||
return new NodeCommentMap();
|
||||
|
|
|
@ -32,8 +32,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
|
||||
|
||||
/**
|
||||
* @author Guido Zgraggen IFS
|
||||
* A visitor for the comments. Calls the NodeCommenter to assign the comments.
|
||||
*
|
||||
* @see org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommenter
|
||||
*
|
||||
* @author Guido Zgraggen IFS
|
||||
*/
|
||||
public class ASTCommenterVisitor extends CPPASTVisitor {
|
||||
|
||||
|
|
|
@ -16,8 +16,11 @@ import java.util.Vector;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||
|
||||
/**
|
||||
* @author Guido Zgraggen IFS
|
||||
* The CommentHandler is initialized with all the comment which should be processed.
|
||||
* During the process of comment assignment this comment collection is work through one
|
||||
* after another until no more comments are left.
|
||||
*
|
||||
* @author Guido Zgraggen IFS
|
||||
*/
|
||||
public class CommentHandler {
|
||||
|
||||
|
|
|
@ -18,14 +18,22 @@ import org.eclipse.cdt.core.dom.ast.IASTComment;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
||||
/**
|
||||
* The NodeCommentMap is the map where all the comments are assigned to a node. For better
|
||||
* performance the comments are stored in three different maps which have the same name as
|
||||
* the relative position of the comment.
|
||||
*
|
||||
* @author Guido Zgraggen IFS
|
||||
*
|
||||
*/
|
||||
public class NodeCommentMap {
|
||||
protected final HashMap<IASTNode, ArrayList<IASTComment>> leadingMap = new HashMap<IASTNode, ArrayList<IASTComment>>();
|
||||
protected final HashMap<IASTNode, ArrayList<IASTComment>> trailingMap = new HashMap<IASTNode, ArrayList<IASTComment>>();
|
||||
protected final HashMap<IASTNode, ArrayList<IASTComment>> freestandingMap = new HashMap<IASTNode, ArrayList<IASTComment>>();
|
||||
|
||||
/**
|
||||
* Add a comment to the map with the trailing comments.
|
||||
* @param node The node is the key.
|
||||
* @param comment The comment is the value
|
||||
*/
|
||||
public void addTrailingCommentToNode(IASTNode node, IASTComment comment){
|
||||
ArrayList<IASTComment> comments = trailingMap.get(node);
|
||||
if(comments == null){
|
||||
|
@ -35,6 +43,13 @@ public class NodeCommentMap {
|
|||
trailingMap.put(node, comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ArrayList for the given node. This ArrayList contains all the comments
|
||||
* which are assigned to this specific node. If no comments are available an empty
|
||||
* ArrayList is returned.
|
||||
* @param node The key to fetch the associated comments.
|
||||
* @return ArrayList
|
||||
*/
|
||||
public ArrayList<IASTComment> getTrailingCommentsForNode(IASTNode node){
|
||||
if(trailingMap.get(node) == null) {
|
||||
return new ArrayList<IASTComment>();
|
||||
|
@ -42,6 +57,11 @@ public class NodeCommentMap {
|
|||
return trailingMap.get(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment to the map with the leading comments.
|
||||
* @param node The node is the key.
|
||||
* @param comment The comment is the value
|
||||
*/
|
||||
public void addLeadingCommentToNode(IASTNode node, IASTComment comment){
|
||||
ArrayList<IASTComment> comments = leadingMap.get(node);
|
||||
if(comments == null){
|
||||
|
@ -51,6 +71,13 @@ public class NodeCommentMap {
|
|||
leadingMap.put(node, comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ArrayList for the given node. This ArrayList contains all the comments
|
||||
* which are assigned to this specific node. If no comments are available an empty
|
||||
* ArrayList is returned.
|
||||
* @param node The key to fetch the associated comments.
|
||||
* @return ArrayList
|
||||
*/
|
||||
public ArrayList<IASTComment> getLeadingCommentsForNode(IASTNode node){
|
||||
if(leadingMap.get(node) == null) {
|
||||
return new ArrayList<IASTComment>();
|
||||
|
@ -58,6 +85,11 @@ public class NodeCommentMap {
|
|||
return leadingMap.get(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment to the map with the freestanding comments.
|
||||
* @param node The node is the key.
|
||||
* @param comment The comment is the value
|
||||
*/
|
||||
public void addFreestandingCommentToNode(IASTNode node, IASTComment comment){
|
||||
ArrayList<IASTComment> comments = freestandingMap.get(node);
|
||||
if(comments == null){
|
||||
|
@ -67,6 +99,13 @@ public class NodeCommentMap {
|
|||
freestandingMap.put(node, comments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ArrayList for the given node. This ArrayList contains all the comments
|
||||
* which are assigned to this specific node. If no comments are available an empty
|
||||
* ArrayList is returned.
|
||||
* @param node The key to fetch the associated comments.
|
||||
* @return ArrayList
|
||||
*/
|
||||
public ArrayList<IASTComment> getFreestandingCommentsForNode(IASTNode node){
|
||||
if(freestandingMap.get(node) == null) {
|
||||
return new ArrayList<IASTComment>();
|
||||
|
@ -74,15 +113,26 @@ public class NodeCommentMap {
|
|||
return freestandingMap.get(node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the HashMap with all leading maps. Used only for test purpose
|
||||
* @return HashMap of all leading comments
|
||||
*/
|
||||
public HashMap<IASTNode, ArrayList<IASTComment>> getLeadingMap() {
|
||||
return leadingMap;
|
||||
}
|
||||
/**
|
||||
* Returns the HashMap with all trailing maps. Used only for test purpose
|
||||
* @return HashMap of all trailing comments
|
||||
*/
|
||||
public HashMap<IASTNode, ArrayList<IASTComment>> getTrailingMap() {
|
||||
return trailingMap;
|
||||
}
|
||||
/**
|
||||
* Returns the HashMap with all freestanding maps. Used only for test purpose
|
||||
* @return HashMap of all freestanding comments
|
||||
*/
|
||||
public HashMap<IASTNode, ArrayList<IASTComment>> getFreestandingMap() {
|
||||
return freestandingMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -41,8 +41,27 @@ import org.eclipse.core.runtime.IPath;
|
|||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* @author Guido Zgraggen IFS
|
||||
* The NodeCommenter contains all the logic that is needed for the ASTCommentVisitor to assign the comments
|
||||
* to the suitable node. Together with the ASTCommenterVisitor it fills all the comments with the correspondent
|
||||
* node into the NodeCommentMap.
|
||||
*
|
||||
* Following, a little explanation of the assignment logic. It is only a loose illustration a detailed description
|
||||
* would include a combined explanation of ASTCommenterVisitor and NodeCommenter.<br>
|
||||
* To understand the logic we define the three types of comments:<br>
|
||||
* leading comments - Comments before a statement, declaration, or definition.<br>
|
||||
* trailing comments - Comments right after the AST node on the same line.<br>
|
||||
* freestanding comments - Comments before a closing brace such as they occur in
|
||||
* namespace-, class- and method-definitions or at the end of a file.<br>
|
||||
*
|
||||
* The first comment is fetched and the position of it is compared to the position of the actual node. If
|
||||
* the position of the comment is smaller than the comment is added to the node as leading. If it is behind the node
|
||||
* but on the same line it is added as trailing. If one of these possibilities match the next comment is fetched for
|
||||
* the same check. If it doesn't match the same procedure is done for all the child nodes. After checking the sub nodes
|
||||
* the actual node is checked again if the comment is trailing. Then there is also the possibility that this comment is
|
||||
* freestanding. This is the case when the comment is not added to any child node but the position is smaller den
|
||||
* the end position of the node.
|
||||
*
|
||||
* @author Guido Zgraggen IFS
|
||||
*/
|
||||
public class NodeCommenter {
|
||||
|
||||
|
@ -130,31 +149,29 @@ public class NodeCommenter {
|
|||
if(OffsetHelper.getNodeOffset(com) < OffsetHelper.getNodeEndPoint(node) + 2) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
IPath path = new Path(node.getContainingFilename());
|
||||
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
|
||||
IPath path = new Path(node.getContainingFilename());
|
||||
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
|
||||
|
||||
//XXX HSR Guido: Possible Performance Issue (File access)
|
||||
try {
|
||||
InputStream is = file.getContents();
|
||||
|
||||
//XXX HSR Guido: Possible Performance Issue (File access)
|
||||
try {
|
||||
InputStream is = file.getContents();
|
||||
|
||||
int length = OffsetHelper.getNodeOffset(com)-OffsetHelper.getNodeEndPoint(node);
|
||||
byte[] b = new byte[length];
|
||||
int length = OffsetHelper.getNodeOffset(com)-OffsetHelper.getNodeEndPoint(node);
|
||||
byte[] b = new byte[length];
|
||||
|
||||
is.skip(OffsetHelper.getNodeEndPoint(node));
|
||||
is.read(b, 0, length);
|
||||
is.skip(OffsetHelper.getNodeEndPoint(node));
|
||||
is.read(b, 0, length);
|
||||
|
||||
for(byte bb : b) {
|
||||
if(!Character.isWhitespace(bb)) {
|
||||
is.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
is.close();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
for(byte bb : b) {
|
||||
if(!Character.isWhitespace(bb)) {
|
||||
is.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
is.close();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue