diff options
author | Sergey Prigogin | 2013-08-14 03:43:34 +0000 |
---|---|---|
committer | Sergey Prigogin | 2013-08-14 16:27:35 +0000 |
commit | ca5586f8be131c5a77cf896e094d0a75bd6fada1 (patch) | |
tree | f7dad95a09e0c281645b3d32ef6985ee9ab01792 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core | |
parent | 7ae8b48608cac5073073e244241c10a03dcbb2a4 (diff) | |
download | org.eclipse.cdt-ca5586f8be131c5a77cf896e094d0a75bd6fada1.tar.gz org.eclipse.cdt-ca5586f8be131c5a77cf896e094d0a75bd6fada1.tar.xz org.eclipse.cdt-ca5586f8be131c5a77cf896e094d0a75bd6fada1.zip |
Bug 414624 - Add Include command doesn't honor Organize Includes
preferences
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core')
4 files changed, 167 insertions, 69 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java index a2184ce8502..ce28e387a5c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGenerator.java @@ -25,7 +25,6 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.ToolFactory; 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.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; @@ -547,7 +546,7 @@ public class ChangeGenerator extends ASTVisitor { if (ASTWriter.requireBlankLineInBetween(newNode, anchorNode)) { writer.newLine(); } - int insertPos = getOffsetIncludingComments(anchorNode); + int insertPos = commentMap.getOffsetIncludingComments(anchorNode); int length = 0; if (writer.getScribe().isAtBeginningOfLine()) { String tuCode = anchorNode.getTranslationUnit().getRawSignature(); @@ -573,8 +572,8 @@ public class ChangeGenerator extends ASTVisitor { addToRootEdit(node); if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) { // There is no replacement. We are deleting a piece of existing code. - int offset = getOffsetIncludingComments(node); - int endOffset = getEndOffsetIncludingComments(node); + int offset = commentMap.getOffsetIncludingComments(node); + int endOffset = commentMap.getEndOffsetIncludingComments(node); offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset); endOffset = skipTrailingBlankLines(source, endOffset); IASTNode[] siblingsList = getContainingNodeList(node); @@ -615,7 +614,7 @@ public class ChangeGenerator extends ASTVisitor { addChildEdit(new ReplaceEdit(offset, endOffset - offset, code)); if (node instanceof IASTStatement || node instanceof IASTDeclaration) { // Include trailing comments in the area to be replaced. - int commentEnd = getEndOffsetIncludingTrailingComments(node); + int commentEnd = commentMap.getEndOffsetIncludingComments(node); if (commentEnd > endOffset) addChildEdit(new DeleteEdit(endOffset, commentEnd - endOffset)); } @@ -669,7 +668,7 @@ public class ChangeGenerator extends ASTVisitor { prevNode = preprocessorStatements[preprocessorStatements.length - 1]; } } - int offset = prevNode != null ? getEndOffsetIncludingComments(prevNode) : 0; + int offset = prevNode != null ? commentMap.getEndOffsetIncludingComments(prevNode) : 0; String source = node.getRawSignature(); int endOffset = skipTrailingBlankLines(source, offset); @@ -1015,69 +1014,6 @@ public class ChangeGenerator extends ASTVisitor { } } - private int getOffsetIncludingComments(IASTNode node) { - int nodeOffset = offset(node); - - List<IASTComment> comments = commentMap.getAllCommentsForNode(node); - if (!comments.isEmpty()) { - int startOffset = nodeOffset; - for (IASTComment comment : comments) { - int commentOffset = offset(comment); - if (commentOffset < startOffset) { - startOffset = commentOffset; - } - } - nodeOffset = startOffset; - } - return nodeOffset; - } - - private int getEndOffsetIncludingComments(IASTNode node) { - int endOffset = 0; - while (true) { - IASTFileLocation fileLocation = node.getFileLocation(); - if (fileLocation != null) - endOffset = Math.max(endOffset, endOffset(fileLocation)); - List<IASTComment> comments = commentMap.getAllCommentsForNode(node); - if (!comments.isEmpty()) { - for (IASTComment comment : comments) { - int commentEndOffset = endOffset(comment); - if (commentEndOffset >= endOffset) { - endOffset = commentEndOffset; - } - } - } - IASTNode[] children = node.getChildren(); - if (children.length == 0) - break; - node = children[children.length - 1]; - } - return endOffset; - } - - private int getEndOffsetIncludingTrailingComments(IASTNode node) { - int endOffset = 0; - while (true) { - IASTFileLocation fileLocation = node.getFileLocation(); - if (fileLocation != null) - endOffset = Math.max(endOffset, endOffset(fileLocation)); - List<IASTComment> comments = commentMap.getTrailingCommentsForNode(node); - if (!comments.isEmpty()) { - for (IASTComment comment : comments) { - int commentEndOffset = endOffset(comment); - if (commentEndOffset >= endOffset) { - endOffset = commentEndOffset; - } - } - } - IASTNode[] children = node.getChildren(); - if (children.length == 0) - break; - node = children[children.length - 1]; - } - return endOffset; - } - private Map<ModificationKind, List<ASTModification>> getModifications(IASTNode node) { Map<ModificationKind, List<ASTModification>> modifications = classifiedModifications.get(node); if (modifications == null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommentMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommentMap.java index 829c2ddd4e2..74303f4def3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommentMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommentMap.java @@ -17,7 +17,9 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.dom.ast.IASTComment; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes; /** * The NodeCommentMap is the map where all the comments are assigned to a node. For better @@ -147,4 +149,43 @@ public class NodeCommentMap { comment.addAll(getTrailingCommentsForNode(node)); return comment; } + + public int getOffsetIncludingComments(IASTNode node) { + int offset = ASTNodes.offset(node); + + // TODO(sprigogin): Iterate backwards and stop at the first blank line. + List<IASTComment> comments = leadingMap.get(node); + if (comments != null && !comments.isEmpty()) { + for (IASTComment comment : comments) { + int commentOffset = ASTNodes.offset(comment); + if (commentOffset < offset) { + offset = commentOffset; + } + } + } + return offset; + } + + public int getEndOffsetIncludingComments(IASTNode node) { + int endOffset = 0; + while (true) { + IASTFileLocation fileLocation = node.getFileLocation(); + if (fileLocation != null) + endOffset = Math.max(endOffset, fileLocation.getNodeOffset() + fileLocation.getNodeLength()); + List<IASTComment> comments = trailingMap.get(node); + if (comments != null && !comments.isEmpty()) { + for (IASTComment comment : comments) { + int commentEndOffset = ASTNodes.endOffset(comment); + if (commentEndOffset >= endOffset) { + endOffset = commentEndOffset; + } + } + } + IASTNode[] children = node.getChildren(); + if (children.length == 0) + break; + node = children[children.length - 1]; + } + return endOffset; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/ASTNodes.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/ASTNodes.java new file mode 100644 index 00000000000..05b7e7aed52 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/ASTNodes.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2012 Google, Inc 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.rewrite.util; + +import static org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit.getNodeEndOffset; + +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTNode; + +/** + * Collection of helper methods for common operations on AST nodes. + */ +public class ASTNodes { + /** Not instantiatable. */ + private ASTNodes() { + } + + /** + * Returns the offset of an AST node. + */ + public static int offset(IASTNode node) { + return node.getFileLocation().getNodeOffset(); + } + + /** + * Returns the exclusive end offset of an AST node. + */ + public static int endOffset(IASTNode node) { + IASTFileLocation location = node.getFileLocation(); + return location.getNodeOffset() + location.getNodeLength(); + } + + /** + * Returns the offset of the beginning of the next line after the node, or the end-of-file + * offset if there is no line delimiter after the node. + */ + public static int skipToNextLineAfterNode(char[] text, IASTNode node) { + return TextUtil.skipToNextLine(text, getNodeEndOffset(node)); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/TextUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/TextUtil.java new file mode 100644 index 00000000000..2060abb34e5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/util/TextUtil.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, Inc 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.rewrite.util; + +/** + * Collection of methods for working with text. + */ +public class TextUtil { + /** Not instantiatable. */ + private TextUtil() {} + + /** + * Returns the offset of the beginning of the next line after the given offset, + * or the end-of-file offset if there is no line delimiter after the given offset. + */ + public static int skipToNextLine(char[] text, int offset) { + while (offset < text.length) { + if (text[offset++] == '\n') + break; + } + return offset; + } + + /** + * Returns the offset of the beginning of the line containing the given offset. + */ + public static int getLineStart(char[] text, int offset) { + while (--offset >= 0) { + if (text[offset] == '\n') + break; + } + return offset + 1; + } + + /** + * Skips whitespace characters to the left of the given offset without leaving the current line. + */ + public static int skipWhitespaceToTheLeft(char[] text, int offset) { + while (--offset >= 0) { + char c = text[offset]; + if (c == '\n' || !Character.isWhitespace(c)) + break; + } + return offset + 1; + } + + /** + * Returns {@code true} the line prior to the line corresponding to the given {@code offset} + * does not contain non-whitespace characters. + */ + public static boolean isPreviousLineBlank(char[] text, int offset) { + while (--offset >= 0) { + if (text[offset] == '\n') + break; + } + while (--offset >= 0) { + char c = text[offset]; + if (c == '\n') + return true; + if (!Character.isWhitespace(c)) + return false; + } + return false; + } +} |