mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 414624 - Add Include command doesn't honor Organize Includes
preferences
This commit is contained in:
parent
7ae8b48608
commit
ca5586f8be
31 changed files with 847 additions and 726 deletions
|
@ -62,7 +62,7 @@ Export-Package: org.eclipse.cdt.core,
|
||||||
org.eclipse.cdt.internal.core.dom.rewrite.astwriter;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.dom.rewrite.astwriter;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;x-internal:=true,
|
org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.dom.rewrite.commenthandler;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.dom.rewrite.commenthandler;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.dom.rewrite.util;x-internal:=true,
|
org.eclipse.cdt.internal.core.dom.rewrite.util;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.envvar;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.managedbuilder.core",
|
org.eclipse.cdt.internal.core.envvar;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.managedbuilder.core",
|
||||||
org.eclipse.cdt.internal.core.index;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.index;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.index.composite;x-internal:=true,
|
org.eclipse.cdt.internal.core.index.composite;x-internal:=true,
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.ToolFactory;
|
import org.eclipse.cdt.core.ToolFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
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.IASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
@ -547,7 +546,7 @@ public class ChangeGenerator extends ASTVisitor {
|
||||||
if (ASTWriter.requireBlankLineInBetween(newNode, anchorNode)) {
|
if (ASTWriter.requireBlankLineInBetween(newNode, anchorNode)) {
|
||||||
writer.newLine();
|
writer.newLine();
|
||||||
}
|
}
|
||||||
int insertPos = getOffsetIncludingComments(anchorNode);
|
int insertPos = commentMap.getOffsetIncludingComments(anchorNode);
|
||||||
int length = 0;
|
int length = 0;
|
||||||
if (writer.getScribe().isAtBeginningOfLine()) {
|
if (writer.getScribe().isAtBeginningOfLine()) {
|
||||||
String tuCode = anchorNode.getTranslationUnit().getRawSignature();
|
String tuCode = anchorNode.getTranslationUnit().getRawSignature();
|
||||||
|
@ -573,8 +572,8 @@ public class ChangeGenerator extends ASTVisitor {
|
||||||
addToRootEdit(node);
|
addToRootEdit(node);
|
||||||
if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) {
|
if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) {
|
||||||
// There is no replacement. We are deleting a piece of existing code.
|
// There is no replacement. We are deleting a piece of existing code.
|
||||||
int offset = getOffsetIncludingComments(node);
|
int offset = commentMap.getOffsetIncludingComments(node);
|
||||||
int endOffset = getEndOffsetIncludingComments(node);
|
int endOffset = commentMap.getEndOffsetIncludingComments(node);
|
||||||
offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset);
|
offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset);
|
||||||
endOffset = skipTrailingBlankLines(source, endOffset);
|
endOffset = skipTrailingBlankLines(source, endOffset);
|
||||||
IASTNode[] siblingsList = getContainingNodeList(node);
|
IASTNode[] siblingsList = getContainingNodeList(node);
|
||||||
|
@ -615,7 +614,7 @@ public class ChangeGenerator extends ASTVisitor {
|
||||||
addChildEdit(new ReplaceEdit(offset, endOffset - offset, code));
|
addChildEdit(new ReplaceEdit(offset, endOffset - offset, code));
|
||||||
if (node instanceof IASTStatement || node instanceof IASTDeclaration) {
|
if (node instanceof IASTStatement || node instanceof IASTDeclaration) {
|
||||||
// Include trailing comments in the area to be replaced.
|
// Include trailing comments in the area to be replaced.
|
||||||
int commentEnd = getEndOffsetIncludingTrailingComments(node);
|
int commentEnd = commentMap.getEndOffsetIncludingComments(node);
|
||||||
if (commentEnd > endOffset)
|
if (commentEnd > endOffset)
|
||||||
addChildEdit(new DeleteEdit(endOffset, commentEnd - endOffset));
|
addChildEdit(new DeleteEdit(endOffset, commentEnd - endOffset));
|
||||||
}
|
}
|
||||||
|
@ -669,7 +668,7 @@ public class ChangeGenerator extends ASTVisitor {
|
||||||
prevNode = preprocessorStatements[preprocessorStatements.length - 1];
|
prevNode = preprocessorStatements[preprocessorStatements.length - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int offset = prevNode != null ? getEndOffsetIncludingComments(prevNode) : 0;
|
int offset = prevNode != null ? commentMap.getEndOffsetIncludingComments(prevNode) : 0;
|
||||||
String source = node.getRawSignature();
|
String source = node.getRawSignature();
|
||||||
int endOffset = skipTrailingBlankLines(source, offset);
|
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) {
|
private Map<ModificationKind, List<ASTModification>> getModifications(IASTNode node) {
|
||||||
Map<ModificationKind, List<ASTModification>> modifications = classifiedModifications.get(node);
|
Map<ModificationKind, List<ASTModification>> modifications = classifiedModifications.get(node);
|
||||||
if (modifications == null)
|
if (modifications == null)
|
||||||
|
|
|
@ -17,7 +17,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
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.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
|
* 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));
|
comment.addAll(getTrailingCommentsForNode(node));
|
||||||
return comment;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Sergey Prigogin (Google) - initial API and implementation
|
* Sergey Prigogin (Google) - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.corext.util;
|
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.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -17,8 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
* Collection of helper methods for common operations on AST nodes.
|
* Collection of helper methods for common operations on AST nodes.
|
||||||
*/
|
*/
|
||||||
public class ASTNodes {
|
public class ASTNodes {
|
||||||
|
/** Not instantiatable. */
|
||||||
// Not instantiatable.
|
|
||||||
private ASTNodes() {
|
private ASTNodes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,4 +37,12 @@ public class ASTNodes {
|
||||||
IASTFileLocation location = node.getFileLocation();
|
IASTFileLocation location = node.getFileLocation();
|
||||||
return location.getNodeOffset() + location.getNodeLength();
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
#include "A.h"
|
|
||||||
#include "OverloadedFunction.h"
|
#include "OverloadedFunction.h"
|
||||||
|
|
||||||
|
#include "A.h"
|
||||||
|
|
||||||
using ns3::func;
|
using ns3::func;
|
||||||
|
|
||||||
void test() {
|
void test() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "ResolvedName.h"
|
|
||||||
#include "UnresolvedName.h"
|
#include "UnresolvedName.h"
|
||||||
|
|
||||||
|
#include "ResolvedName.h"
|
||||||
|
|
||||||
using ns4::A;
|
using ns4::A;
|
||||||
using ns5::B;
|
using ns5::B;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "VariableTypeHelper.h"
|
|
||||||
#include "VariableType.h"
|
#include "VariableType.h"
|
||||||
|
|
||||||
|
#include "VariableTypeHelper.h"
|
||||||
|
|
||||||
namespace ns2 {
|
namespace ns2 {
|
||||||
|
|
||||||
void VT::method() {
|
void VT::method() {
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Sergey Prigogin (Google) - initial API and implementation
|
* Sergey Prigogin (Google) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.tests.text;
|
package org.eclipse.cdt.ui.tests.text;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.ListResourceBundle;
|
import java.util.ListResourceBundle;
|
||||||
|
|
||||||
import junit.extensions.TestSetup;
|
import junit.extensions.TestSetup;
|
||||||
|
@ -31,8 +32,9 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
|
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
|
||||||
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
|
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.editor.AddIncludeOnSelectionAction;
|
import org.eclipse.cdt.internal.ui.editor.AddIncludeAction;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.includes.IElementSelector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the AddIncludeOnSelectionAction.
|
* Tests the AddIncludeOnSelectionAction.
|
||||||
|
@ -94,8 +96,20 @@ public class AddIncludeTest extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAddIncludeResult() throws Exception {
|
private void assertAddIncludeResult() throws Exception {
|
||||||
AddIncludeOnSelectionAction.sIsJUnitTest= true;
|
AddIncludeAction action = new AddIncludeAction(fEditor);
|
||||||
new AddIncludeOnSelectionAction(fEditor).run();
|
action.setAmbiguityResolver(new IElementSelector() {
|
||||||
|
@Override
|
||||||
|
public <T> T selectElement(Collection<T> elements) {
|
||||||
|
switch (elements.size()) {
|
||||||
|
case 0:
|
||||||
|
return null;
|
||||||
|
case 1:
|
||||||
|
return elements.iterator().next();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Ambiguous input: " + elements); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
});
|
||||||
|
action.run();
|
||||||
|
|
||||||
String file= createFileName(".expected");
|
String file= createFileName(".expected");
|
||||||
String expected= ResourceTestHelper.read(file).toString();
|
String expected= ResourceTestHelper.read(file).toString();
|
||||||
|
|
|
@ -1,272 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2000, 2013 IBM Corporation 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:
|
|
||||||
* IBM Corporation - initial API and implementation
|
|
||||||
* QNX Software Systems
|
|
||||||
* Sergey Prigogin (Google)
|
|
||||||
* Markus Schorn (Wind River Systems)
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.internal.corext.codemanipulation;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
|
||||||
import org.eclipse.core.runtime.IAdaptable;
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
|
||||||
import org.eclipse.jface.text.IDocument;
|
|
||||||
import org.eclipse.text.edits.InsertEdit;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
|
||||||
import org.eclipse.cdt.core.model.IBuffer;
|
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
|
||||||
import org.eclipse.cdt.core.model.IMacro;
|
|
||||||
import org.eclipse.cdt.core.model.ISourceRange;
|
|
||||||
import org.eclipse.cdt.core.model.ISourceReference;
|
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds includes and 'using' declarations to a translation unit.
|
|
||||||
* If the translation unit is open in an editor, be sure to pass over its working copy.
|
|
||||||
*/
|
|
||||||
public class AddIncludesOperation implements IWorkspaceRunnable {
|
|
||||||
private final ITranslationUnit fTranslationUnit;
|
|
||||||
private final int fBeforeOffset;
|
|
||||||
private final List<IncludeInfo> fIncludes;
|
|
||||||
private final List<String> fUsings;
|
|
||||||
private String fNewLine;
|
|
||||||
private IBuffer fBuffer;
|
|
||||||
private List<ICElement> fExistingIncludes;
|
|
||||||
private List<ICElement> fExistingUsings;
|
|
||||||
private InsertEdit fIncludesInsert;
|
|
||||||
private InsertEdit fUsingsInsert;
|
|
||||||
private int fIncludesPos= -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param tu a translation unit.
|
|
||||||
* @param beforeOffset includes and 'using' declarations have to be inserted before this offset.
|
|
||||||
* @param includes '#include' statements to insert.
|
|
||||||
* @param usings 'using' statements to insert.
|
|
||||||
*/
|
|
||||||
public AddIncludesOperation(ITranslationUnit tu, int beforeOffset, List<IncludeInfo> includes,
|
|
||||||
List<String> usings) {
|
|
||||||
fTranslationUnit = tu;
|
|
||||||
fBeforeOffset = beforeOffset;
|
|
||||||
fIncludes= includes;
|
|
||||||
fUsings = usings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns the scheduling rule for this operation
|
|
||||||
*/
|
|
||||||
public ISchedulingRule getSchedulingRule() {
|
|
||||||
return ResourcesPlugin.getWorkspace().getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run(IProgressMonitor monitor) throws CoreException {
|
|
||||||
if (monitor == null) {
|
|
||||||
monitor= new NullProgressMonitor();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
monitor.beginTask(CEditorMessages.AddIncludesOperation_description, 3);
|
|
||||||
|
|
||||||
fBuffer = fTranslationUnit.getBuffer();
|
|
||||||
fNewLine= getLineSeparator();
|
|
||||||
fExistingIncludes = fTranslationUnit.getChildrenOfType(ICElement.C_INCLUDE);
|
|
||||||
fIncludesInsert = getIncludesInsert();
|
|
||||||
monitor.worked(1);
|
|
||||||
if (!fUsings.isEmpty()) {
|
|
||||||
fExistingUsings = fTranslationUnit.getChildrenOfType(ICElement.C_USING);
|
|
||||||
}
|
|
||||||
fUsingsInsert = getUsingsInsert();
|
|
||||||
monitor.worked(1);
|
|
||||||
|
|
||||||
if (fIncludesInsert != null) {
|
|
||||||
fBuffer.replace(fIncludesInsert.getOffset(), 0, fIncludesInsert.getText());
|
|
||||||
}
|
|
||||||
if (fUsingsInsert != null) {
|
|
||||||
int offset = fUsingsInsert.getOffset();
|
|
||||||
if (fIncludesInsert != null && offset >= fIncludesInsert.getOffset()) {
|
|
||||||
offset += fIncludesInsert.getText().length();
|
|
||||||
}
|
|
||||||
fBuffer.replace(offset, 0, fUsingsInsert.getText());
|
|
||||||
}
|
|
||||||
monitor.worked(1);
|
|
||||||
} finally {
|
|
||||||
monitor.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private InsertEdit getIncludesInsert() throws CoreException {
|
|
||||||
if (fIncludes.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<IncludeInfo> toAdd = new ArrayList<IncludeInfo>();
|
|
||||||
for (IncludeInfo include : fIncludes) {
|
|
||||||
String name = include.getName();
|
|
||||||
boolean found = false;
|
|
||||||
for (ICElement element : fExistingIncludes) {
|
|
||||||
ISourceRange range = ((ISourceReference) element).getSourceRange();
|
|
||||||
if (range.getStartPos() + range.getLength() > fBeforeOffset) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (name.equals(element.getElementName())) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
toAdd.add(include);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (toAdd.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// So we have our list. Now insert.
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
for (IncludeInfo include : toAdd) {
|
|
||||||
buf.append("#include ").append(include.toString()).append(fNewLine); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
int pos= getIncludeInsertionPosition();
|
|
||||||
return new InsertEdit(pos, buf.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getIncludeInsertionPosition() throws CModelException {
|
|
||||||
if (fIncludesPos < 0) {
|
|
||||||
if (fExistingIncludes.isEmpty()) {
|
|
||||||
fIncludesPos= getOffsetAfterLeadingMacroDefinitions();
|
|
||||||
} else {
|
|
||||||
fIncludesPos = getOffsetAfterLast(fExistingIncludes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fIncludesPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
private InsertEdit getUsingsInsert() throws CoreException {
|
|
||||||
if (fUsings.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<String> toAdd = new ArrayList<String>(fUsings.size());
|
|
||||||
for (String name : fUsings) {
|
|
||||||
boolean found = false;
|
|
||||||
for (ICElement element : fExistingUsings) {
|
|
||||||
ISourceRange range = ((ISourceReference) element).getSourceRange();
|
|
||||||
if (range.getStartPos() + range.getLength() > fBeforeOffset) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (name.equals(element.getElementName())) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
toAdd.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (toAdd.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// So we have our list. Now insert.
|
|
||||||
StringBuilder buf = new StringBuilder();
|
|
||||||
for (String using : toAdd) {
|
|
||||||
buf.append("using ").append(using).append(';').append(fNewLine); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
int pos = getOffsetAfterLast(fExistingUsings);
|
|
||||||
int pos2 = getIncludeInsertionPosition();
|
|
||||||
if (pos <= pos2) {
|
|
||||||
pos = pos2;
|
|
||||||
buf.insert(0, fNewLine); // Add a blank line between #include and using statements.
|
|
||||||
}
|
|
||||||
|
|
||||||
return new InsertEdit(pos, buf.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the last of elements located before fBeforeOffset and returns offset of the following line.
|
|
||||||
* @param elements source elements to consider.
|
|
||||||
* @return offset of the line after the last of elements located before fBeforeOffset, or
|
|
||||||
* zero, if there is no such element.
|
|
||||||
* @throws CModelException
|
|
||||||
*/
|
|
||||||
private int getOffsetAfterLast(List<ICElement> elements) throws CModelException {
|
|
||||||
for (int i = elements.size(); --i >= 0;) {
|
|
||||||
ISourceRange range = ((ISourceReference) elements.get(i)).getSourceRange();
|
|
||||||
int end = range.getStartPos() + range.getLength();
|
|
||||||
if (end <= fBeforeOffset) {
|
|
||||||
return findNewLine(range.getStartPos() + range.getLength());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the last leading macro definition before <code>fBeforeOffset</code>.
|
|
||||||
* And returns the offset of the line after.
|
|
||||||
*/
|
|
||||||
private int getOffsetAfterLeadingMacroDefinitions() throws CModelException {
|
|
||||||
ISourceRange found= null;
|
|
||||||
for (ICElement child: fTranslationUnit.getChildren()) {
|
|
||||||
if (!(child instanceof IMacro) || !(child instanceof ISourceReference))
|
|
||||||
break;
|
|
||||||
|
|
||||||
final ISourceReference sourceRef = (ISourceReference) child;
|
|
||||||
if (!sourceRef.isActive())
|
|
||||||
break;
|
|
||||||
|
|
||||||
ISourceRange range= sourceRef.getSourceRange();
|
|
||||||
if (range.getStartPos() + range.getLength() > fBeforeOffset)
|
|
||||||
break;
|
|
||||||
|
|
||||||
found= range;
|
|
||||||
}
|
|
||||||
if (found != null) {
|
|
||||||
return findNewLine(found.getStartPos() + found.getLength());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int findNewLine(int pos) {
|
|
||||||
while (fBuffer.getChar(pos) != '\n') {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
if (fBuffer.getChar(pos) == '\r') {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
return pos + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getLineSeparator() {
|
|
||||||
try {
|
|
||||||
if (fBuffer instanceof IAdaptable) {
|
|
||||||
IDocument doc= (IDocument) ((IAdaptable) fBuffer).getAdapter(IDocument.class);
|
|
||||||
if (doc != null) {
|
|
||||||
String delim= doc.getLineDelimiter(0);
|
|
||||||
if (delim != null) {
|
|
||||||
return delim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (BadLocationException e) {
|
|
||||||
}
|
|
||||||
return System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -89,6 +89,10 @@ public class IncludeInfo implements Comparable<IncludeInfo> {
|
||||||
return (isSystem ? '<' : '"') + name + (isSystem ? '>' : '"');
|
return (isSystem ? '<' : '"') + name + (isSystem ? '>' : '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String composeIncludeStatement() {
|
||||||
|
return "#include " + toString(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(IncludeInfo other) {
|
public int compareTo(IncludeInfo other) {
|
||||||
if (isSystem != other.isSystem)
|
if (isSystem != other.isSystem)
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
|
||||||
/**
|
/**
|
||||||
* Represents a new or an existing include statement together with the style associated with it.
|
* Represents a new or an existing include statement together with the style associated with it.
|
||||||
*/
|
*/
|
||||||
public class StyledInclude implements Comparable<StyledInclude> {
|
public class StyledInclude {
|
||||||
private final IPath header; // null for existing unresolved includes
|
private final IPath header; // null for existing unresolved includes
|
||||||
private final IncludeInfo includeInfo; // never null
|
private final IncludeInfo includeInfo; // never null
|
||||||
private final IncludeGroupStyle style;
|
private final IncludeGroupStyle style;
|
||||||
|
@ -66,11 +66,6 @@ public class StyledInclude implements Comparable<StyledInclude> {
|
||||||
this.existingInclude = existingInclude;
|
this.existingInclude = existingInclude;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(StyledInclude other) {
|
|
||||||
return includeInfo.compareTo(other.includeInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (header != null)
|
if (header != null)
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.corext.util.ASTNodes;
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
|
||||||
|
|
||||||
public class InputFlowAnalyzer extends FlowAnalyzer {
|
public class InputFlowAnalyzer extends FlowAnalyzer {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.ui.editor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.ITextSelection;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.LabelProvider;
|
||||||
|
import org.eclipse.jface.window.Window;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.text.edits.MalformedTreeException;
|
||||||
|
import org.eclipse.text.edits.MultiTextEdit;
|
||||||
|
import org.eclipse.text.edits.TextEdit;
|
||||||
|
import org.eclipse.text.undo.DocumentUndoManagerRegistry;
|
||||||
|
import org.eclipse.text.undo.IDocumentUndoManager;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
|
||||||
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
import org.eclipse.ui.texteditor.TextEditorAction;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexManager;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.SharedASTJob;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.BusyCursorJobRunner;
|
||||||
|
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.includes.IElementSelector;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeCreator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organizes the include directives and forward declarations of a source or header file.
|
||||||
|
*/
|
||||||
|
public class AddIncludeAction extends TextEditorAction {
|
||||||
|
private IElementSelector fAmbiguityResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param editor The editor on which this Add Include action should operate.
|
||||||
|
*/
|
||||||
|
public AddIncludeAction(ITextEditor editor) {
|
||||||
|
super(CEditorMessages.getBundleForConstructedKeys(), "AddInclude.", editor); //$NON-NLS-1$
|
||||||
|
CUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(this, ICHelpContextIds.ADD_INCLUDE_ON_SELECTION_ACTION);
|
||||||
|
final Shell shell = editor.getEditorSite().getShell();
|
||||||
|
fAmbiguityResolver = new IElementSelector() {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T> T selectElement(final Collection<T> elements) {
|
||||||
|
final Object[] result = new Object[1];
|
||||||
|
runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ElementListSelectionDialog dialog=
|
||||||
|
new ElementListSelectionDialog(shell, new LabelProvider());
|
||||||
|
dialog.setElements(elements.toArray());
|
||||||
|
dialog.setTitle(CEditorMessages.AddInclude_label);
|
||||||
|
dialog.setMessage(CEditorMessages.AddInclude_description);
|
||||||
|
if (dialog.open() == Window.OK)
|
||||||
|
result[0] = dialog.getFirstResult();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (T) result[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final ITextEditor editor = getTextEditor();
|
||||||
|
final ITranslationUnit tu = getTranslationUnit(editor);
|
||||||
|
if (tu == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ISelection selection= getTextEditor().getSelectionProvider().getSelection();
|
||||||
|
if (selection.isEmpty() || !(selection instanceof ITextSelection)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!validateEditorInputState()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String lineDelimiter = getLineDelimiter(editor);
|
||||||
|
final List<TextEdit> edits = new ArrayList<TextEdit>();
|
||||||
|
SharedASTJob job = new SharedASTJob(CEditorMessages.AddInclude_action, tu) {
|
||||||
|
@Override
|
||||||
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
||||||
|
IIndex index= CCorePlugin.getIndexManager().getIndex(tu.getCProject(),
|
||||||
|
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
||||||
|
try {
|
||||||
|
index.acquireReadLock();
|
||||||
|
IncludeCreator creator = new IncludeCreator(tu, index, lineDelimiter, fAmbiguityResolver);
|
||||||
|
edits.addAll(creator.createInclude(ast, (ITextSelection) selection));
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return Status.CANCEL_STATUS;
|
||||||
|
} finally {
|
||||||
|
index.releaseReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
IStatus status = BusyCursorJobRunner.execute(job);
|
||||||
|
if (status.isOK()) {
|
||||||
|
if (!edits.isEmpty()) {
|
||||||
|
// Apply text edits.
|
||||||
|
MultiTextEdit edit = new MultiTextEdit();
|
||||||
|
edit.addChildren(edits.toArray(new TextEdit[edits.size()]));
|
||||||
|
IEditorInput editorInput = editor.getEditorInput();
|
||||||
|
IDocument document = editor.getDocumentProvider().getDocument(editorInput);
|
||||||
|
IDocumentUndoManager manager= DocumentUndoManagerRegistry.getDocumentUndoManager(document);
|
||||||
|
manager.beginCompoundChange();
|
||||||
|
try {
|
||||||
|
edit.apply(document);
|
||||||
|
} catch (MalformedTreeException e) {
|
||||||
|
CUIPlugin.log(e);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
CUIPlugin.log(e);
|
||||||
|
}
|
||||||
|
manager.endCompoundChange();
|
||||||
|
}
|
||||||
|
} else if (status.matches(IStatus.ERROR)) {
|
||||||
|
ErrorDialog.openError(editor.getEditorSite().getShell(),
|
||||||
|
CEditorMessages.AddInclude_error_title,
|
||||||
|
CEditorMessages.AddInclude_insertion_failed, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void runInUIThread(Runnable runnable) {
|
||||||
|
if (Display.getCurrent() != null) {
|
||||||
|
runnable.run();
|
||||||
|
} else {
|
||||||
|
Display.getDefault().syncExec(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLineDelimiter(ITextEditor editor) {
|
||||||
|
try {
|
||||||
|
IEditorInput editorInput = editor.getEditorInput();
|
||||||
|
IDocument document = editor.getDocumentProvider().getDocument(editorInput);
|
||||||
|
String delim= document.getLineDelimiter(0);
|
||||||
|
if (delim != null) {
|
||||||
|
return delim;
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
|
return System.getProperty("line.separator", "\n"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
ITextEditor editor = getTextEditor();
|
||||||
|
setEnabled(editor != null && getTranslationUnit(editor) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the translation unit of the given editor.
|
||||||
|
* @param editor The editor.
|
||||||
|
* @return The translation unit.
|
||||||
|
*/
|
||||||
|
private static ITranslationUnit getTranslationUnit(ITextEditor editor) {
|
||||||
|
if (editor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For tests only.
|
||||||
|
*/
|
||||||
|
public void setAmbiguityResolver(IElementSelector fAmbiguityResolver) {
|
||||||
|
this.fAmbiguityResolver = fAmbiguityResolver;
|
||||||
|
}
|
||||||
|
}
|
|
@ -228,7 +228,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.ADD_BLOCK_COMMENT, getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.ADD_BLOCK_COMMENT, getAction(textEditor, "AddBlockComment")); //$NON-NLS-1$
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddInclude")); //$NON-NLS-1$
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.ORGANIZE_INCLUDES, getAction(textEditor, "OrganizeIncludes")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.ORGANIZE_INCLUDES, getAction(textEditor, "OrganizeIncludes")); //$NON-NLS-1$
|
||||||
bars.setGlobalActionHandler(CdtActionConstants.SORT_LINES, getAction(textEditor, "SortLines")); //$NON-NLS-1$
|
bars.setGlobalActionHandler(CdtActionConstants.SORT_LINES, getAction(textEditor, "SortLines")); //$NON-NLS-1$
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
* Tomasz Wesolowski
|
* Tomasz Wesolowski
|
||||||
* Alvaro Sanchez-Leon (Ericsson AB)
|
* Alvaro Sanchez-Leon (Ericsson AB)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
|
@ -31,12 +32,11 @@ public final class CEditorMessages extends NLS {
|
||||||
return fgBundleForConstructedKeys;
|
return fgBundleForConstructedKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String AddIncludeOnSelection_label;
|
public static String AddInclude_label;
|
||||||
public static String AddIncludeOnSelection_description;
|
public static String AddInclude_description;
|
||||||
public static String AddIncludeOnSelection_error_title;
|
public static String AddInclude_action;
|
||||||
public static String AddIncludeOnSelection_insertion_failed;
|
public static String AddInclude_error_title;
|
||||||
public static String AddIncludeOnSelection_help_provider_error;
|
public static String AddInclude_insertion_failed;
|
||||||
public static String AddIncludesOperation_description;
|
|
||||||
public static String OrganizeIncludes_label;
|
public static String OrganizeIncludes_label;
|
||||||
public static String OrganizeIncludes_description;
|
public static String OrganizeIncludes_description;
|
||||||
public static String OrganizeIncludes_action;
|
public static String OrganizeIncludes_action;
|
||||||
|
|
|
@ -22,6 +22,11 @@ AddIncludeOnSelection_error_title=Error Adding Include
|
||||||
AddIncludeOnSelection_insertion_failed=Adding include statements failed
|
AddIncludeOnSelection_insertion_failed=Adding include statements failed
|
||||||
AddIncludeOnSelection_help_provider_error=Help provider error
|
AddIncludeOnSelection_help_provider_error=Help provider error
|
||||||
AddIncludesOperation_description=Adding include statement
|
AddIncludesOperation_description=Adding include statement
|
||||||
|
AddInclude_label=Add Include
|
||||||
|
AddInclude_description=Add include statement for selected name
|
||||||
|
AddInclude_action=Adding include statement
|
||||||
|
ADdInclude_error_title=Error Adding Include Statement
|
||||||
|
AddInclude_insertion_failed=Adding include statement failed
|
||||||
|
|
||||||
OrganizeIncludes_label=Organize Includes
|
OrganizeIncludes_label=Organize Includes
|
||||||
OrganizeIncludes_description=Organize includes for current file
|
OrganizeIncludes_description=Organize includes for current file
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (c) 2005, 2010 IBM Corporation and others.
|
# Copyright (c) 2005, 2013 IBM Corporation and others.
|
||||||
# All rights reserved. This program and the accompanying materials
|
# All rights reserved. This program and the accompanying materials
|
||||||
# are made available under the terms of the Eclipse Public License v1.0
|
# are made available under the terms of the Eclipse Public License v1.0
|
||||||
# which accompanies this distribution, and is available at
|
# which accompanies this distribution, and is available at
|
||||||
|
@ -14,9 +14,9 @@
|
||||||
# Tomasz Wesolowski
|
# Tomasz Wesolowski
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
AddIncludeOnSelection.label=A&dd Include
|
AddInclude.label=A&dd Include
|
||||||
AddIncludeOnSelection.description=Add include statement for selected name
|
AddInclude.tooltip=Add Include Statement for Selected Name
|
||||||
AddIncludeOnSelection.tooltip=Adds an include statement for selected name
|
AddInclude.description=Adds an include statement for selected name
|
||||||
|
|
||||||
OrganizeIncludes.label=Or&ganize Includes
|
OrganizeIncludes.label=Or&ganize Includes
|
||||||
OrganizeIncludes.tooltip=Evaluate All Required Includes and Replace the Current Ones
|
OrganizeIncludes.tooltip=Evaluate All Required Includes and Replace the Current Ones
|
||||||
|
@ -27,11 +27,11 @@ SortLines.tooltip=Sort Selected Lines Alphabetically
|
||||||
SortLines.description=Sorts selected lines alphabetically
|
SortLines.description=Sorts selected lines alphabetically
|
||||||
|
|
||||||
OpenOutline.label= Quick Out&line
|
OpenOutline.label= Quick Out&line
|
||||||
OpenOutline.tooltip= Shows the Quick Outline of Editor Input
|
OpenOutline.tooltip= Show the Quick Outline of Editor Input
|
||||||
OpenOutline.description= Shows the quick outline for the editor input
|
OpenOutline.description= Shows the quick outline for the editor input
|
||||||
|
|
||||||
OpenHierarchy.label= Quick Type Hierarchy
|
OpenHierarchy.label= Quick Type Hierarchy
|
||||||
OpenHierarchy.tooltip= Shows the Quick Type Hierarchy of Editor Input
|
OpenHierarchy.tooltip= Show the Quick Type Hierarchy of Editor Input
|
||||||
OpenHierarchy.description= Shows the quick type hierarchy for the editor input
|
OpenHierarchy.description= Shows the quick type hierarchy for the editor input
|
||||||
|
|
||||||
TogglePresentation.label=Show Source of Selected Element Only
|
TogglePresentation.label=Show Source of Selected Element Only
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class IncludeStyleBlock extends TabConfigurationBlock {
|
||||||
IncludeKind includeKind = style.getIncludeKind();
|
IncludeKind includeKind = style.getIncludeKind();
|
||||||
Key key = KEY_MAP.get(includeKind);
|
Key key = KEY_MAP.get(includeKind);
|
||||||
if (includeKind != IncludeKind.MATCHING_PATTERN) {
|
if (includeKind != IncludeKind.MATCHING_PATTERN) {
|
||||||
setValue(key, style.toString());
|
setValue(key, style.toXmlString());
|
||||||
} else {
|
} else {
|
||||||
// TODO(sprigogin): Support custom include categories.
|
// TODO(sprigogin): Support custom include categories.
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class IncludeStyleBlock extends TabConfigurationBlock {
|
||||||
IncludeGroupStyle style = null;
|
IncludeGroupStyle style = null;
|
||||||
String str = getValue(entry.getValue());
|
String str = getValue(entry.getValue());
|
||||||
if (str != null)
|
if (str != null)
|
||||||
style = IncludeGroupStyle.fromString(str, includeKind);
|
style = IncludeGroupStyle.fromXmlString(str, includeKind);
|
||||||
if (style == null)
|
if (style == null)
|
||||||
style = new IncludeGroupStyle(includeKind);
|
style = new IncludeGroupStyle(includeKind);
|
||||||
styles.add(style);
|
styles.add(style);
|
||||||
|
|
|
@ -46,12 +46,12 @@ import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||||
import org.eclipse.cdt.internal.corext.refactoring.code.flow.FlowContext;
|
import org.eclipse.cdt.internal.corext.refactoring.code.flow.FlowContext;
|
||||||
import org.eclipse.cdt.internal.corext.refactoring.code.flow.FlowInfo;
|
import org.eclipse.cdt.internal.corext.refactoring.code.flow.FlowInfo;
|
||||||
import org.eclipse.cdt.internal.corext.refactoring.code.flow.InputFlowAnalyzer;
|
import org.eclipse.cdt.internal.corext.refactoring.code.flow.InputFlowAnalyzer;
|
||||||
import org.eclipse.cdt.internal.corext.refactoring.code.flow.Selection;
|
import org.eclipse.cdt.internal.corext.refactoring.code.flow.Selection;
|
||||||
import org.eclipse.cdt.internal.corext.util.ASTNodes;
|
|
||||||
|
|
||||||
public class NodeContainer {
|
public class NodeContainer {
|
||||||
private final List<IASTNode> nodes;
|
private final List<IASTNode> nodes;
|
||||||
|
|
|
@ -391,22 +391,6 @@ public class BindingClassifier {
|
||||||
declareBinding(typeBinding);
|
declareBinding(typeBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the given type to the list of bindings which have to be defined. Typedefs and
|
|
||||||
* enumerations without fixed underlying type are skipped since they must be defined in the file
|
|
||||||
* that references them by name. If the type is explicitly referenced in this translation unit,
|
|
||||||
* it will be defined independently from this method.
|
|
||||||
*
|
|
||||||
* @param type The type to add.
|
|
||||||
*/
|
|
||||||
private void defineTypeExceptTypedefOrNonFixedEnum(IType type) {
|
|
||||||
IBinding typeBinding = getTypeBinding(type);
|
|
||||||
if (typeBinding != null && !(typeBinding instanceof ITypedef)
|
|
||||||
&& !isEnumerationWithoutFixedUnderlyingType(typeBinding)) {
|
|
||||||
defineBinding(typeBinding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given type to the list of bindings which have to be declared. Typedefs and
|
* Adds the given type to the list of bindings which have to be declared. Typedefs and
|
||||||
* enumerations without fixed underlying type are skipped since they must be defined in the file
|
* enumerations without fixed underlying type are skipped since they must be defined in the file
|
||||||
|
@ -423,6 +407,22 @@ public class BindingClassifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given type to the list of bindings which have to be defined. Typedefs and
|
||||||
|
* enumerations without fixed underlying type are skipped since they must be defined in the file
|
||||||
|
* that references them by name. If the type is explicitly referenced in this translation unit,
|
||||||
|
* it will be defined independently from this method.
|
||||||
|
*
|
||||||
|
* @param type The type to add.
|
||||||
|
*/
|
||||||
|
private void defineTypeExceptTypedefOrNonFixedEnum(IType type) {
|
||||||
|
IBinding typeBinding = getTypeBinding(type);
|
||||||
|
if (typeBinding != null && !(typeBinding instanceof ITypedef)
|
||||||
|
&& !isEnumerationWithoutFixedUnderlyingType(typeBinding)) {
|
||||||
|
defineBinding(typeBinding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given binding to the list of bindings which have to be defined.
|
* Adds the given binding to the list of bindings which have to be defined.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.ui.refactoring.includes;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for selecting one of a set of elements.
|
||||||
|
*/
|
||||||
|
public interface IElementSelector {
|
||||||
|
/**
|
||||||
|
* Selects one element from a set of elements.
|
||||||
|
*
|
||||||
|
* @param elements the objects to select from
|
||||||
|
* @return the selected element or {@code null} if nothing was selected
|
||||||
|
*/
|
||||||
|
public <T> T selectElement(Collection<T> elements);
|
||||||
|
}
|
|
@ -11,17 +11,20 @@
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||||
|
|
||||||
import static org.eclipse.cdt.core.index.IndexLocationFactory.getAbsolutePath;
|
import static org.eclipse.cdt.core.index.IndexLocationFactory.getAbsolutePath;
|
||||||
|
import static org.eclipse.cdt.internal.ui.refactoring.includes.IncludeUtil.isContainedInRegion;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -30,26 +33,24 @@ import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Path;
|
||||||
import org.eclipse.core.runtime.content.IContentType;
|
import org.eclipse.core.runtime.content.IContentType;
|
||||||
import org.eclipse.jface.operation.IRunnableWithProgress;
|
import org.eclipse.jface.operation.IRunnableWithProgress;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
import org.eclipse.jface.text.ITextSelection;
|
import org.eclipse.jface.text.ITextSelection;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.text.edits.InsertEdit;
|
||||||
import org.eclipse.jface.viewers.LabelProvider;
|
import org.eclipse.text.edits.TextEdit;
|
||||||
import org.eclipse.jface.window.Window;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
import org.eclipse.swt.widgets.Shell;
|
|
||||||
import org.eclipse.ui.PlatformUI;
|
import org.eclipse.ui.PlatformUI;
|
||||||
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
|
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import com.ibm.icu.text.Collator;
|
||||||
import org.eclipse.ui.texteditor.TextEditorAction;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
|
@ -71,148 +72,55 @@ import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IIndexFile;
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||||
import org.eclipse.cdt.core.index.IIndexMacro;
|
import org.eclipse.cdt.core.index.IIndexMacro;
|
||||||
import org.eclipse.cdt.core.index.IIndexManager;
|
|
||||||
import org.eclipse.cdt.core.index.IIndexName;
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
import org.eclipse.cdt.core.index.IndexFilter;
|
import org.eclipse.cdt.core.index.IndexFilter;
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.parser.Keywords;
|
import org.eclipse.cdt.core.parser.Keywords;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.IFunctionSummary;
|
import org.eclipse.cdt.ui.IFunctionSummary;
|
||||||
import org.eclipse.cdt.ui.IRequiredInclude;
|
import org.eclipse.cdt.ui.IRequiredInclude;
|
||||||
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
|
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
|
||||||
import org.eclipse.cdt.ui.text.SharedASTJob;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
|
||||||
|
import org.eclipse.cdt.internal.core.model.ASTStringUtil;
|
||||||
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
import org.eclipse.cdt.internal.corext.codemanipulation.AddIncludesOperation;
|
|
||||||
import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo;
|
import org.eclipse.cdt.internal.corext.codemanipulation.IncludeInfo;
|
||||||
import org.eclipse.cdt.internal.corext.codemanipulation.InclusionContext;
|
import org.eclipse.cdt.internal.corext.codemanipulation.StyledInclude;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
|
import org.eclipse.cdt.internal.ui.CHelpProviderManager;
|
||||||
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
|
||||||
import org.eclipse.cdt.internal.ui.actions.WorkbenchRunnableAdapter;
|
|
||||||
import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an include statement and, optionally, a 'using' declaration for the currently
|
* Adds an include statement and, optionally, a 'using' declaration for the currently
|
||||||
* selected name.
|
* selected name.
|
||||||
*/
|
*/
|
||||||
public class AddIncludeOnSelectionAction extends TextEditorAction {
|
public class IncludeCreator {
|
||||||
public static boolean sIsJUnitTest = false;
|
private static final Collator COLLATOR = Collator.getInstance();
|
||||||
|
|
||||||
private ITranslationUnit fTu;
|
private final String fLineDelimiter;
|
||||||
private IProject fProject;
|
private final IElementSelector fAmbiguityResolver;
|
||||||
private final List<IncludeInfo> fRequiredIncludes = new ArrayList<IncludeInfo>();
|
private final IncludeCreationContext fContext;
|
||||||
private final List<String> fUsingDeclarations = new ArrayList<String>();
|
|
||||||
protected InclusionContext fContext;
|
|
||||||
|
|
||||||
public AddIncludeOnSelectionAction(ITextEditor editor) {
|
public IncludeCreator(ITranslationUnit tu, IIndex index, String lineDelimiter,
|
||||||
super(CEditorMessages.getBundleForConstructedKeys(), "AddIncludeOnSelection.", editor); //$NON-NLS-1$
|
IElementSelector ambiguityResolver) {
|
||||||
|
fLineDelimiter = lineDelimiter;
|
||||||
CUIPlugin.getDefault().getWorkbench().getHelpSystem().setHelp(this,
|
fAmbiguityResolver = ambiguityResolver;
|
||||||
ICHelpContextIds.ADD_INCLUDE_ON_SELECTION_ACTION);
|
fContext = new IncludeCreationContext(tu, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertInclude(List<IncludeInfo> includes, List<String> usings, int beforeOffset) {
|
public List<TextEdit> createInclude(IASTTranslationUnit ast, ITextSelection selection)
|
||||||
AddIncludesOperation op= new AddIncludesOperation(fTu, beforeOffset, includes, usings);
|
|
||||||
try {
|
|
||||||
PlatformUI.getWorkbench().getProgressService().runInUI(
|
|
||||||
PlatformUI.getWorkbench().getProgressService(),
|
|
||||||
new WorkbenchRunnableAdapter(op), op.getSchedulingRule());
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
ExceptionHandler.handle(e, getShell(), CEditorMessages.AddIncludeOnSelection_error_title,
|
|
||||||
CEditorMessages.AddIncludeOnSelection_insertion_failed);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// Do nothing. Operation has been canceled.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ITranslationUnit getTranslationUnit(ITextEditor editor) {
|
|
||||||
if (editor == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Shell getShell() {
|
|
||||||
return getTextEditor().getSite().getShell();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
fTu = getTranslationUnit(getTextEditor());
|
|
||||||
if (fTu == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fProject = fTu.getCProject().getProject();
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ISelection selection= getTextEditor().getSelectionProvider().getSelection();
|
|
||||||
if (selection.isEmpty() || !(selection instanceof ITextSelection)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!validateEditorInputState()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String[] lookupName = new String[1];
|
|
||||||
final IIndex index= CCorePlugin.getIndexManager().getIndex(fTu.getCProject(), IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
|
||||||
SharedASTJob job = new SharedASTJob(CEditorMessages.AddIncludeOnSelection_label, fTu) {
|
|
||||||
@Override
|
|
||||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
|
||||||
deduceInclude((ITextSelection) selection, index, ast, lookupName);
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
job.schedule();
|
|
||||||
job.join();
|
|
||||||
|
|
||||||
if (fRequiredIncludes.isEmpty() && lookupName[0].length() > 0) {
|
|
||||||
// Try contribution from plug-ins.
|
|
||||||
IFunctionSummary fs = findContribution(lookupName[0]);
|
|
||||||
if (fs != null) {
|
|
||||||
IRequiredInclude[] functionIncludes = fs.getIncludes();
|
|
||||||
if (functionIncludes != null) {
|
|
||||||
for (IRequiredInclude include : functionIncludes) {
|
|
||||||
fRequiredIncludes.add(new IncludeInfo(include.getIncludeName(), include.isStandard()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String ns = fs.getNamespace();
|
|
||||||
if (ns != null && ns.length() > 0) {
|
|
||||||
fUsingDeclarations.add(fs.getNamespace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!fRequiredIncludes.isEmpty()) {
|
|
||||||
insertInclude(fRequiredIncludes, fUsingDeclarations, ((ITextSelection) selection).getOffset());
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
} catch (CoreException e) {
|
|
||||||
CUIPlugin.log("Cannot perform 'Add Include'", e); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts the includes for the given selection. This can be both used to perform
|
|
||||||
* the work as well as being invoked when there is a change.
|
|
||||||
* @param selection a text selection.
|
|
||||||
* @param ast an AST.
|
|
||||||
* @param lookupName a one-element array used to return the selected name.
|
|
||||||
*/
|
|
||||||
private void deduceInclude(ITextSelection selection, IIndex index, IASTTranslationUnit ast, String[] lookupName)
|
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
fContext = new InclusionContext(fTu);
|
ITranslationUnit tu = fContext.getTranslationUnit();
|
||||||
IASTNodeSelector selector = ast.getNodeSelector(fTu.getLocation().toOSString());
|
IASTNodeSelector selector = ast.getNodeSelector(tu.getLocation().toOSString());
|
||||||
IASTName name = selector.findEnclosingName(selection.getOffset(), selection.getLength());
|
IASTName name = selector.findEnclosingName(selection.getOffset(), selection.getLength());
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
return;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
char[] nameChars = name.toCharArray();
|
char[] nameChars = name.toCharArray();
|
||||||
lookupName[0] = new String(nameChars);
|
String lookupName = new String(nameChars);
|
||||||
IBinding binding = name.resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
if (binding instanceof ICPPVariable) {
|
if (binding instanceof ICPPVariable) {
|
||||||
IType type = ((ICPPVariable) binding).getType();
|
IType type = ((ICPPVariable) binding).getType();
|
||||||
|
@ -224,87 +132,274 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nameChars.length == 0) {
|
if (nameChars.length == 0) {
|
||||||
return;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<String, IncludeCandidate> candidatesMap= new HashMap<String, IncludeCandidate>();
|
final Map<String, IncludeCandidate> candidatesMap= new HashMap<String, IncludeCandidate>();
|
||||||
final IndexFilter filter = IndexFilter.getDeclaredBindingFilter(ast.getLinkage().getLinkageID(), false);
|
final IndexFilter filter = IndexFilter.getDeclaredBindingFilter(ast.getLinkage().getLinkageID(), false);
|
||||||
|
|
||||||
|
final List<IncludeInfo> requiredIncludes = new ArrayList<IncludeInfo>();
|
||||||
|
final List<UsingDeclaration> usingDeclarations = new ArrayList<UsingDeclaration>();
|
||||||
|
|
||||||
List<IIndexBinding> bindings = new ArrayList<IIndexBinding>();
|
List<IIndexBinding> bindings = new ArrayList<IIndexBinding>();
|
||||||
IIndexBinding adaptedBinding= index.adaptBinding(binding);
|
try {
|
||||||
if (adaptedBinding == null) {
|
IIndex index = fContext.getIndex();
|
||||||
bindings.addAll(Arrays.asList(index.findBindings(nameChars, false, filter, new NullProgressMonitor())));
|
IIndexBinding adaptedBinding= index.adaptBinding(binding);
|
||||||
} else {
|
if (adaptedBinding == null) {
|
||||||
bindings.add(adaptedBinding);
|
bindings.addAll(Arrays.asList(index.findBindings(nameChars, false, filter, new NullProgressMonitor())));
|
||||||
while (adaptedBinding instanceof ICPPSpecialization) {
|
} else {
|
||||||
adaptedBinding= index.adaptBinding(((ICPPSpecialization) adaptedBinding).getSpecializedBinding());
|
bindings.add(adaptedBinding);
|
||||||
if (adaptedBinding != null) {
|
while (adaptedBinding instanceof ICPPSpecialization) {
|
||||||
bindings.add(adaptedBinding);
|
adaptedBinding= index.adaptBinding(((ICPPSpecialization) adaptedBinding).getSpecializedBinding());
|
||||||
}
|
if (adaptedBinding != null) {
|
||||||
}
|
bindings.add(adaptedBinding);
|
||||||
}
|
|
||||||
|
|
||||||
for (IIndexBinding indexBinding : bindings) {
|
|
||||||
// Replace ctor with the class itself.
|
|
||||||
if (indexBinding instanceof ICPPConstructor) {
|
|
||||||
indexBinding = indexBinding.getOwner();
|
|
||||||
}
|
|
||||||
IIndexName[] definitions= null;
|
|
||||||
// class, struct, union, enum-type, enum-item
|
|
||||||
if (indexBinding instanceof ICompositeType || indexBinding instanceof IEnumeration || indexBinding instanceof IEnumerator) {
|
|
||||||
definitions= index.findDefinitions(indexBinding);
|
|
||||||
} else if (indexBinding instanceof ITypedef || (indexBinding instanceof IFunction)) {
|
|
||||||
definitions = index.findDeclarations(indexBinding);
|
|
||||||
}
|
|
||||||
if (definitions != null) {
|
|
||||||
for (IIndexName definition : definitions) {
|
|
||||||
considerForInclusion(definition, indexBinding, index, candidatesMap);
|
|
||||||
}
|
|
||||||
if (definitions.length > 0 && adaptedBinding != null)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IIndexMacro[] macros = index.findMacros(nameChars, filter, new NullProgressMonitor());
|
|
||||||
for (IIndexMacro macro : macros) {
|
|
||||||
IIndexName definition = macro.getDefinition();
|
|
||||||
considerForInclusion(definition, macro, index, candidatesMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArrayList<IncludeCandidate> candidates = new ArrayList<IncludeCandidate>(candidatesMap.values());
|
|
||||||
if (candidates.size() > 1) {
|
|
||||||
if (sIsJUnitTest) {
|
|
||||||
throw new RuntimeException("ambiguous input"); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
runInUIThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ElementListSelectionDialog dialog=
|
|
||||||
new ElementListSelectionDialog(getShell(), new LabelProvider());
|
|
||||||
dialog.setElements(candidates.toArray());
|
|
||||||
dialog.setTitle(CEditorMessages.AddIncludeOnSelection_label);
|
|
||||||
dialog.setMessage(CEditorMessages.AddIncludeOnSelection_description);
|
|
||||||
if (dialog.open() == Window.OK) {
|
|
||||||
candidates.clear();
|
|
||||||
candidates.add((IncludeCandidate) dialog.getFirstResult());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
for (IIndexBinding indexBinding : bindings) {
|
||||||
|
// Replace ctor with the class itself.
|
||||||
|
if (indexBinding instanceof ICPPConstructor) {
|
||||||
|
indexBinding = indexBinding.getOwner();
|
||||||
|
}
|
||||||
|
IIndexName[] definitions= null;
|
||||||
|
// class, struct, union, enum-type, enum-item
|
||||||
|
if (indexBinding instanceof ICompositeType || indexBinding instanceof IEnumeration || indexBinding instanceof IEnumerator) {
|
||||||
|
definitions= index.findDefinitions(indexBinding);
|
||||||
|
} else if (indexBinding instanceof ITypedef || (indexBinding instanceof IFunction)) {
|
||||||
|
definitions = index.findDeclarations(indexBinding);
|
||||||
|
}
|
||||||
|
if (definitions != null) {
|
||||||
|
for (IIndexName definition : definitions) {
|
||||||
|
considerForInclusion(definition, indexBinding, index, candidatesMap);
|
||||||
|
}
|
||||||
|
if (definitions.length > 0 && adaptedBinding != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IIndexMacro[] macros = index.findMacros(nameChars, filter, new NullProgressMonitor());
|
||||||
|
for (IIndexMacro macro : macros) {
|
||||||
|
IIndexName definition = macro.getDefinition();
|
||||||
|
considerForInclusion(definition, macro, index, candidatesMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArrayList<IncludeCandidate> candidates = new ArrayList<IncludeCandidate>(candidatesMap.values());
|
||||||
|
if (candidates.size() > 1) {
|
||||||
|
IncludeCandidate candidate = fAmbiguityResolver.selectElement(candidates);
|
||||||
|
if (candidate == null)
|
||||||
|
return Collections.emptyList();
|
||||||
|
candidates.clear();
|
||||||
|
candidates.add(candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidates.size() == 1) {
|
||||||
|
IncludeCandidate candidate = candidates.get(0);
|
||||||
|
requiredIncludes.add(candidate.include);
|
||||||
|
IIndexBinding indexBinding = candidate.binding;
|
||||||
|
|
||||||
|
if (indexBinding instanceof ICPPBinding && !(indexBinding instanceof IIndexMacro)) {
|
||||||
|
// Decide what 'using' declaration, if any, should be added along with the include.
|
||||||
|
UsingDeclaration usingDeclaration = deduceUsingDeclaration(binding, indexBinding, ast);
|
||||||
|
if (usingDeclaration != null)
|
||||||
|
usingDeclarations.add(usingDeclaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CUIPlugin.log(e);
|
||||||
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
fRequiredIncludes.clear();
|
if (requiredIncludes.isEmpty() && !lookupName.isEmpty()) {
|
||||||
fUsingDeclarations.clear();
|
// Try contribution from plug-ins.
|
||||||
if (candidates.size() == 1) {
|
IFunctionSummary fs = findContribution(lookupName);
|
||||||
IncludeCandidate candidate = candidates.get(0);
|
if (fs != null) {
|
||||||
fRequiredIncludes.add(candidate.getInclude());
|
IRequiredInclude[] functionIncludes = fs.getIncludes();
|
||||||
IIndexBinding indexBinding = candidate.getBinding();
|
if (functionIncludes != null) {
|
||||||
|
for (IRequiredInclude include : functionIncludes) {
|
||||||
if (indexBinding instanceof ICPPBinding && !(indexBinding instanceof IIndexMacro)) {
|
requiredIncludes.add(new IncludeInfo(include.getIncludeName(), include.isStandard()));
|
||||||
// Decide what 'using' declaration, if any, should be added along with the include.
|
}
|
||||||
String usingDeclaration = deduceUsingDeclaration(binding, indexBinding, ast);
|
}
|
||||||
if (usingDeclaration != null)
|
String ns = fs.getNamespace();
|
||||||
fUsingDeclarations.add(usingDeclaration);
|
if (ns != null && !ns.isEmpty()) {
|
||||||
|
usingDeclarations.add(new UsingDeclaration(ns + "::" + fs.getName())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return createEdits(requiredIncludes, usingDeclarations, ast, selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TextEdit> createEdits(List<IncludeInfo> includes,
|
||||||
|
List<UsingDeclaration> usingDeclarations, IASTTranslationUnit ast,
|
||||||
|
ITextSelection selection) {
|
||||||
|
NodeCommentMap commentedNodeMap = ASTCommenter.getCommentedNodeMap(ast);
|
||||||
|
char[] contents = fContext.getSourceContents();
|
||||||
|
IRegion includeRegion =
|
||||||
|
IncludeOrganizer.getSafeIncludeReplacementRegion(contents, ast, commentedNodeMap);
|
||||||
|
|
||||||
|
IncludePreferences preferences = fContext.getPreferences();
|
||||||
|
|
||||||
|
List<TextEdit> edits = new ArrayList<TextEdit>();
|
||||||
|
|
||||||
|
IASTPreprocessorIncludeStatement[] existingIncludes = ast.getIncludeDirectives();
|
||||||
|
fContext.addHeadersIncludedPreviously(existingIncludes);
|
||||||
|
|
||||||
|
List<StyledInclude> styledIncludes = new ArrayList<StyledInclude>();
|
||||||
|
// Put the new includes into styledIncludes.
|
||||||
|
for (IncludeInfo includeInfo : includes) {
|
||||||
|
IPath header = fContext.resolveInclude(includeInfo);
|
||||||
|
if (!fContext.wasIncludedPreviously(header)) {
|
||||||
|
IncludeGroupStyle style = fContext.getIncludeStyle(includeInfo);
|
||||||
|
StyledInclude prototype = new StyledInclude(header, includeInfo, style);
|
||||||
|
styledIncludes.add(prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(styledIncludes, preferences);
|
||||||
|
|
||||||
|
// Populate list of existing includes in the include insertion region.
|
||||||
|
List<StyledInclude> mergedIncludes = new ArrayList<StyledInclude>();
|
||||||
|
for (IASTPreprocessorIncludeStatement include : existingIncludes) {
|
||||||
|
if (include.isPartOfTranslationUnitFile() && isContainedInRegion(include, includeRegion)) {
|
||||||
|
String name = new String(include.getName().getSimpleID());
|
||||||
|
IncludeInfo includeInfo = new IncludeInfo(name, include.isSystemInclude());
|
||||||
|
String path = include.getPath();
|
||||||
|
// An empty path means that the include was not resolved.
|
||||||
|
IPath header = path.isEmpty() ? null : Path.fromOSString(path);
|
||||||
|
IncludeGroupStyle style =
|
||||||
|
header != null ? fContext.getIncludeStyle(header) : fContext.getIncludeStyle(includeInfo);
|
||||||
|
StyledInclude prototype = new StyledInclude(header, includeInfo, style, include);
|
||||||
|
mergedIncludes.add(prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preferences.allowReordering) {
|
||||||
|
// Since the order of existing include statements may not match the include order
|
||||||
|
// preferences, we find positions for the new include statements by pushing them from
|
||||||
|
// them up from the bottom of the include insertion region.
|
||||||
|
for (StyledInclude include : styledIncludes) {
|
||||||
|
int i = mergedIncludes.size();
|
||||||
|
while (--i >= 0 && preferences.compare(include, mergedIncludes.get(i)) < 0) {}
|
||||||
|
mergedIncludes.add(i + 1, include);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mergedIncludes.addAll(styledIncludes);
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = includeRegion.getOffset();
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
StyledInclude previousInclude = null;
|
||||||
|
for (StyledInclude include : mergedIncludes) {
|
||||||
|
if (include.getExistingInclude() == null) {
|
||||||
|
if (previousInclude != null) {
|
||||||
|
IASTNode previousNode = previousInclude.getExistingInclude();
|
||||||
|
if (previousNode != null) {
|
||||||
|
offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode);
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
if (contents[offset - 1] != '\n')
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
}
|
||||||
|
if (include.getStyle().isBlankLineNeededAfter(previousInclude.getStyle(), preferences.includeStyles))
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
}
|
||||||
|
text.append(include.getIncludeInfo().composeIncludeStatement());
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
} else {
|
||||||
|
if (previousInclude != null && previousInclude.getExistingInclude() == null &&
|
||||||
|
include.getStyle().isBlankLineNeededAfter(previousInclude.getStyle(), preferences.includeStyles)) {
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
}
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
}
|
||||||
|
previousInclude = include;
|
||||||
|
}
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
|
||||||
|
List<UsingDeclaration> mergedUsingDeclarations = getUsingDeclarations(ast);
|
||||||
|
for (UsingDeclaration usingDeclaration : mergedUsingDeclarations) {
|
||||||
|
for (Iterator<UsingDeclaration> iter = usingDeclarations.iterator(); iter.hasNext();) {
|
||||||
|
UsingDeclaration using = iter.next();
|
||||||
|
if (using.equals(usingDeclaration.name))
|
||||||
|
iter.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usingDeclarations.isEmpty())
|
||||||
|
return edits;
|
||||||
|
|
||||||
|
List<UsingDeclaration> temp = null;
|
||||||
|
for (Iterator<UsingDeclaration> iter = mergedUsingDeclarations.iterator(); iter.hasNext();) {
|
||||||
|
UsingDeclaration usingDeclaration = iter.next();
|
||||||
|
if (usingDeclaration.existingDeclaration.isPartOfTranslationUnitFile() &&
|
||||||
|
ASTNodes.endOffset(usingDeclaration.existingDeclaration) <= selection.getOffset()) {
|
||||||
|
if (temp == null)
|
||||||
|
temp = new ArrayList<UsingDeclaration>();
|
||||||
|
temp.add(usingDeclaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (temp == null) {
|
||||||
|
mergedUsingDeclarations.clear();
|
||||||
|
} else {
|
||||||
|
mergedUsingDeclarations = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(usingDeclarations);
|
||||||
|
|
||||||
|
if (mergedUsingDeclarations.isEmpty()) {
|
||||||
|
offset = includeRegion.getOffset() + includeRegion.getLength();
|
||||||
|
text.append(fLineDelimiter); // Blank line between includes and using declarations.
|
||||||
|
} else {
|
||||||
|
offset = commentedNodeMap.getOffsetIncludingComments(mergedUsingDeclarations.get(0).existingDeclaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the order of existing using declarations may not be alphabetical, we find positions
|
||||||
|
// for the new using declarations by pushing them from them up from the bottom of
|
||||||
|
// the using declaration list.
|
||||||
|
for (UsingDeclaration using : usingDeclarations) {
|
||||||
|
int i = mergedUsingDeclarations.size();
|
||||||
|
while (--i >= 0 && using.compareTo(mergedUsingDeclarations.get(i)) < 0) {}
|
||||||
|
mergedUsingDeclarations.add(i + 1, using);
|
||||||
|
}
|
||||||
|
|
||||||
|
UsingDeclaration previousUsing = null;
|
||||||
|
for (UsingDeclaration using : mergedUsingDeclarations) {
|
||||||
|
if (using.existingDeclaration == null) {
|
||||||
|
if (previousUsing != null) {
|
||||||
|
IASTNode previousNode = previousUsing.existingDeclaration;
|
||||||
|
if (previousNode != null) {
|
||||||
|
offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode);
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
if (contents[offset - 1] != '\n')
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text.append(using.composeDirective());
|
||||||
|
text.append(fLineDelimiter);
|
||||||
|
} else {
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
}
|
||||||
|
previousUsing = using;
|
||||||
|
}
|
||||||
|
flushEditBuffer(offset, text, edits);
|
||||||
|
|
||||||
|
return edits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<UsingDeclaration> getUsingDeclarations(IASTTranslationUnit ast) {
|
||||||
|
List<UsingDeclaration> usingDeclarations = new ArrayList<UsingDeclaration>();
|
||||||
|
IASTDeclaration[] declarations = ast.getDeclarations();
|
||||||
|
for (IASTDeclaration declaration : declarations) {
|
||||||
|
if (declaration instanceof ICPPASTUsingDeclaration) {
|
||||||
|
usingDeclarations.add(new UsingDeclaration((ICPPASTUsingDeclaration) declaration));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usingDeclarations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flushEditBuffer(int offset, StringBuilder text, List<TextEdit> edits) {
|
||||||
|
if (text.length() != 0) {
|
||||||
|
edits.add(new InsertEdit(offset, text.toString()));
|
||||||
|
text.delete(0, text.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,7 +426,8 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String deduceUsingDeclaration(IBinding source, IBinding target, IASTTranslationUnit ast) {
|
private UsingDeclaration deduceUsingDeclaration(IBinding source, IBinding target,
|
||||||
|
IASTTranslationUnit ast) {
|
||||||
if (source.equals(target)) {
|
if (source.equals(target)) {
|
||||||
return null; // No using declaration is needed.
|
return null; // No using declaration is needed.
|
||||||
}
|
}
|
||||||
|
@ -379,7 +475,7 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
buf.append(targetChain.get(i));
|
buf.append(targetChain.get(i));
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return new UsingDeclaration(buf.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean match(IASTName name, ArrayList<String> usingChain, boolean excludeLast) {
|
private boolean match(IASTName name, ArrayList<String> usingChain, boolean excludeLast) {
|
||||||
|
@ -438,7 +534,7 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
while (!front.isEmpty()) {
|
while (!front.isEmpty()) {
|
||||||
IIndexFile file = front.remove();
|
IIndexFile file = front.remove();
|
||||||
// A header without an extension is a good candidate for inclusion into a C++ source file.
|
// A header without an extension is a good candidate for inclusion into a C++ source file.
|
||||||
if (fTu.isCXXLanguage() && !hasExtension(getPath(file))) {
|
if (fContext.isCXXLanguage() && !hasExtension(getPath(file))) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
IIndexInclude[] includes = index.findIncludedBy(file, 0);
|
IIndexInclude[] includes = index.findIncludedBy(file, 0);
|
||||||
|
@ -473,7 +569,7 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
return path.indexOf('.', path.lastIndexOf('/') + 1) >= 0;
|
return path.indexOf('.', path.lastIndexOf('/') + 1) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IFunctionSummary findContribution(final String name) {
|
private IFunctionSummary findContribution(final String name) throws CoreException {
|
||||||
final IFunctionSummary[] fs = new IFunctionSummary[1];
|
final IFunctionSummary[] fs = new IFunctionSummary[1];
|
||||||
IRunnableWithProgress op = new IRunnableWithProgress() {
|
IRunnableWithProgress op = new IRunnableWithProgress() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -481,12 +577,12 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
ICHelpInvocationContext context = new ICHelpInvocationContext() {
|
ICHelpInvocationContext context = new ICHelpInvocationContext() {
|
||||||
@Override
|
@Override
|
||||||
public IProject getProject() {
|
public IProject getProject() {
|
||||||
return fProject;
|
return fContext.getProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ITranslationUnit getTranslationUnit() {
|
public ITranslationUnit getTranslationUnit() {
|
||||||
return fTu;
|
return fContext.getTranslationUnit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -496,34 +592,21 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
try {
|
try {
|
||||||
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
|
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op);
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
ExceptionHandler.handle(e, getShell(), CEditorMessages.AddIncludeOnSelection_error_title,
|
throw new CoreException(CUIPlugin.createErrorStatus(Messages.AddInclude_help_provider_error, e));
|
||||||
CEditorMessages.AddIncludeOnSelection_help_provider_error);
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Do nothing. Operation has been canceled.
|
// Do nothing. Operation has been canceled.
|
||||||
}
|
}
|
||||||
return fs[0];
|
return fs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runInUIThread(Runnable runnable) {
|
|
||||||
if (Display.getCurrent() != null) {
|
|
||||||
runnable.run();
|
|
||||||
} else {
|
|
||||||
Display.getDefault().syncExec(runnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update() {
|
|
||||||
ITextEditor editor = getTextEditor();
|
|
||||||
setEnabled(editor != null && getTranslationUnit(editor) != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a file is a source file (.c, .cpp, .cc, etc). Header files are not considered source files.
|
* Checks if a file is a source file (.c, .cpp, .cc, etc). Header files are not considered
|
||||||
* @return Returns <code>true</code> if the the file is a source file.
|
* source files.
|
||||||
|
*
|
||||||
|
* @return Returns {@code true} if the the file is a source file.
|
||||||
*/
|
*/
|
||||||
private boolean isSource(String filename) {
|
private boolean isSource(String filename) {
|
||||||
IContentType ct= CCorePlugin.getContentType(fProject, filename);
|
IContentType ct= CCorePlugin.getContentType(fContext.getProject(), filename);
|
||||||
if (ct != null) {
|
if (ct != null) {
|
||||||
String id = ct.getId();
|
String id = ct.getId();
|
||||||
if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id) || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
|
if (CCorePlugin.CONTENT_TYPE_CSOURCE.equals(id) || CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(id)) {
|
||||||
|
@ -623,27 +706,43 @@ public class AddIncludeOnSelectionAction extends TextEditorAction {
|
||||||
* definitions for "add include" when there are more than one to choose from.
|
* definitions for "add include" when there are more than one to choose from.
|
||||||
*/
|
*/
|
||||||
private static class IncludeCandidate {
|
private static class IncludeCandidate {
|
||||||
private final IIndexBinding binding;
|
final IIndexBinding binding;
|
||||||
private final IncludeInfo include;
|
final IncludeInfo include;
|
||||||
private final String label;
|
final String label;
|
||||||
|
|
||||||
public IncludeCandidate(IIndexBinding binding, IncludeInfo include) throws CoreException {
|
IncludeCandidate(IIndexBinding binding, IncludeInfo include) throws CoreException {
|
||||||
this.binding = binding;
|
this.binding = binding;
|
||||||
this.include = include;
|
this.include = include;
|
||||||
this.label = getBindingQualifiedName(binding) + " - " + include.toString(); //$NON-NLS-1$
|
this.label = getBindingQualifiedName(binding) + " - " + include.toString(); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public IIndexBinding getBinding() {
|
|
||||||
return binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncludeInfo getInclude() {
|
|
||||||
return include;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class UsingDeclaration implements Comparable<UsingDeclaration> {
|
||||||
|
final String name;
|
||||||
|
final ICPPASTUsingDeclaration existingDeclaration;
|
||||||
|
|
||||||
|
UsingDeclaration(String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.existingDeclaration = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsingDeclaration(ICPPASTUsingDeclaration existingDeclaration) {
|
||||||
|
this.name = ASTStringUtil.getQualifiedName(existingDeclaration.getName());
|
||||||
|
this.existingDeclaration = existingDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(UsingDeclaration other) {
|
||||||
|
return COLLATOR.compare(name, other.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
String composeDirective() {
|
||||||
|
return "using " + name + ';'; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -227,8 +227,7 @@ public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
|
||||||
memento.putInteger(TAG_ORDER, order);
|
memento.putInteger(TAG_ORDER, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String toXmlString() {
|
||||||
public String toString() {
|
|
||||||
XMLMemento memento = XMLMemento.createWriteRoot(TAG_STYLE);
|
XMLMemento memento = XMLMemento.createWriteRoot(TAG_STYLE);
|
||||||
saveToMemento(memento);
|
saveToMemento(memento);
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
|
@ -240,7 +239,7 @@ public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IncludeGroupStyle fromString(String str, IncludeKind includeKind) {
|
public static IncludeGroupStyle fromXmlString(String str, IncludeKind includeKind) {
|
||||||
StringReader reader = new StringReader(str);
|
StringReader reader = new StringReader(str);
|
||||||
XMLMemento memento;
|
XMLMemento memento;
|
||||||
try {
|
try {
|
||||||
|
@ -251,6 +250,12 @@ public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
|
||||||
return fromMemento(memento, includeKind);
|
return fromMemento(memento, includeKind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For debugging only */
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return includeKind.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares styles according to their sorting order.
|
* Compares styles according to their sorting order.
|
||||||
*/
|
*/
|
||||||
|
@ -264,7 +269,6 @@ public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
|
||||||
return includeKind.ordinal() - other.includeKind.ordinal();
|
return includeKind.ordinal() - other.includeKind.ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IncludeGroupStyle getGroupingStyle(Map<IncludeKind, IncludeGroupStyle> stylesMap) {
|
public IncludeGroupStyle getGroupingStyle(Map<IncludeKind, IncludeGroupStyle> stylesMap) {
|
||||||
if (keepTogether)
|
if (keepTogether)
|
||||||
return this;
|
return this;
|
||||||
|
@ -274,10 +278,25 @@ public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
|
||||||
return stylesMap.get(IncludeKind.OTHER);
|
return stylesMap.get(IncludeKind.OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IncludeGroupStyle getParentStyle(Map<IncludeKind, IncludeGroupStyle> stylesMap) {
|
private IncludeGroupStyle getParentStyle(Map<IncludeKind, IncludeGroupStyle> stylesMap) {
|
||||||
IncludeKind kind = includeKind.parent;
|
IncludeKind kind = includeKind.parent;
|
||||||
if (kind == null)
|
if (kind == null)
|
||||||
return null;
|
return null;
|
||||||
return stylesMap.get(kind);
|
return stylesMap.get(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBlankLineNeededAfter(IncludeGroupStyle previousIncludeStyle,
|
||||||
|
Map<IncludeKind, IncludeGroupStyle> stylesMap) {
|
||||||
|
if (previousIncludeStyle == null)
|
||||||
|
return false;
|
||||||
|
IncludeGroupStyle groupingStyle = getGroupingStyle(stylesMap);
|
||||||
|
IncludeGroupStyle previousGroupingStyle = previousIncludeStyle.getGroupingStyle(stylesMap);
|
||||||
|
if (groupingStyle != previousGroupingStyle && groupingStyle.isBlankLineBefore())
|
||||||
|
return true;
|
||||||
|
IncludeGroupStyle parentStyle = groupingStyle.getParentStyle(stylesMap);
|
||||||
|
IncludeGroupStyle previousParentStyle = previousGroupingStyle.getParentStyle(stylesMap);
|
||||||
|
return parentStyle != null && previousParentStyle != null &&
|
||||||
|
parentStyle != previousParentStyle && parentStyle.isKeepTogether() &&
|
||||||
|
parentStyle.isBlankLineBefore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,8 @@ import org.eclipse.cdt.utils.PathUtil;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
|
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
|
||||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.ASTNodes;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.util.TextUtil;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.CharArray;
|
import org.eclipse.cdt.internal.core.parser.scanner.CharArray;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.IncludeGuardDetection;
|
import org.eclipse.cdt.internal.core.parser.scanner.IncludeGuardDetection;
|
||||||
|
@ -95,7 +97,8 @@ import org.eclipse.cdt.internal.corext.codemanipulation.StyledInclude;
|
||||||
* Organizes the include directives and forward declarations of a source or header file.
|
* Organizes the include directives and forward declarations of a source or header file.
|
||||||
*/
|
*/
|
||||||
public class IncludeOrganizer {
|
public class IncludeOrganizer {
|
||||||
private static boolean DEBUG_HEADER_SUBSTITUTION = "true".equalsIgnoreCase(Platform.getDebugOption(CUIPlugin.PLUGIN_ID + "/debug/includeOrganizer/headerSubstitution")); //$NON-NLS-1$ //$NON-NLS-2$
|
private static boolean DEBUG_HEADER_SUBSTITUTION =
|
||||||
|
"true".equalsIgnoreCase(Platform.getDebugOption(CUIPlugin.PLUGIN_ID + "/debug/includeOrganizer/headerSubstitution")); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
private static final Collator COLLATOR = Collator.getInstance();
|
private static final Collator COLLATOR = Collator.getInstance();
|
||||||
|
|
||||||
|
@ -227,19 +230,16 @@ public class IncludeOrganizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> includeDirectives = new ArrayList<String>();
|
List<String> includeDirectives = new ArrayList<String>();
|
||||||
IncludeGroupStyle previousParentStyle = null;
|
IncludeGroupStyle previousStyle = null;
|
||||||
for (List<IncludePrototype> prototypes : groupedPrototypes) {
|
for (List<IncludePrototype> prototypes : groupedPrototypes) {
|
||||||
if (prototypes != null && !prototypes.isEmpty()) {
|
if (prototypes != null && !prototypes.isEmpty()) {
|
||||||
Collections.sort(prototypes);
|
Collections.sort(prototypes, preferences);
|
||||||
IncludeGroupStyle style = prototypes.get(0).getStyle();
|
IncludeGroupStyle style = prototypes.get(0).getStyle();
|
||||||
IncludeGroupStyle groupingStyle = style.getGroupingStyle(preferences.includeStyles);
|
if (!includeDirectives.isEmpty() &&
|
||||||
IncludeGroupStyle parentStyle = groupingStyle.getParentStyle(preferences.includeStyles);
|
style.isBlankLineNeededAfter(previousStyle, preferences.includeStyles)) {
|
||||||
boolean blankLineBefore = groupingStyle.isBlankLineBefore() ||
|
|
||||||
(parentStyle != null && parentStyle != previousParentStyle &&
|
|
||||||
parentStyle.isKeepTogether() && parentStyle.isBlankLineBefore());
|
|
||||||
previousParentStyle = parentStyle;
|
|
||||||
if (!includeDirectives.isEmpty() && blankLineBefore)
|
|
||||||
includeDirectives.add(""); // Blank line separator //$NON-NLS-1$
|
includeDirectives.add(""); // Blank line separator //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
previousStyle = style;
|
||||||
for (IncludePrototype prototype : prototypes) {
|
for (IncludePrototype prototype : prototypes) {
|
||||||
String trailingComment = ""; //$NON-NLS-1$
|
String trailingComment = ""; //$NON-NLS-1$
|
||||||
IASTPreprocessorIncludeStatement include = prototype.getExistingInclude();
|
IASTPreprocessorIncludeStatement include = prototype.getExistingInclude();
|
||||||
|
@ -295,15 +295,15 @@ public class IncludeOrganizer {
|
||||||
int length = includeReplacementRegion.getLength();
|
int length = includeReplacementRegion.getLength();
|
||||||
if (allowReordering) {
|
if (allowReordering) {
|
||||||
if (buf.length() != 0) {
|
if (buf.length() != 0) {
|
||||||
if (offset != 0 && !isPreviousLineBlank(offset))
|
if (offset != 0 && !TextUtil.isPreviousLineBlank(fContext.getSourceContents(), offset))
|
||||||
buf.insert(0, fLineDelimiter); // Blank line before.
|
buf.insert(0, fLineDelimiter); // Blank line before.
|
||||||
if (!isBlankLineOrEndOfFile(offset + length))
|
if (!isBlankLineOrEndOfFile(offset + length))
|
||||||
buf.append(fLineDelimiter); // Blank line after.
|
buf.append(fLineDelimiter); // Blank line after.
|
||||||
}
|
}
|
||||||
|
|
||||||
String text = buf.toString();
|
String text = buf.toString();
|
||||||
// TODO(sprigogin): Add a diff algorithm and produce more narrow replacements.
|
// TODO(sprigogin): Add a diff algorithm and produce narrower replacements.
|
||||||
if (!CharArrayUtils.equals(fContext.getTranslationUnit().getContents(), offset, length, text)) {
|
if (!CharArrayUtils.equals(fContext.getSourceContents(), offset, length, text)) {
|
||||||
edits.add(new ReplaceEdit(offset, length, text));
|
edits.add(new ReplaceEdit(offset, length, text));
|
||||||
}
|
}
|
||||||
} else if (buf.length() != 0) {
|
} else if (buf.length() != 0) {
|
||||||
|
@ -470,7 +470,7 @@ public class IncludeOrganizer {
|
||||||
IASTFileLocation location = include.getFileLocation();
|
IASTFileLocation location = include.getFileLocation();
|
||||||
int offset = location.getNodeOffset();
|
int offset = location.getNodeOffset();
|
||||||
if (fContext.getTranslationUnit().isCXXLanguage()) {
|
if (fContext.getTranslationUnit().isCXXLanguage()) {
|
||||||
offset = getLineStart(fContext.getSourceContents(), offset);
|
offset = TextUtil.getLineStart(fContext.getSourceContents(), offset);
|
||||||
edits.add(new InsertEdit(offset, "//")); //$NON-NLS-1$
|
edits.add(new InsertEdit(offset, "//")); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
edits.add(new InsertEdit(offset, "/*")); //$NON-NLS-1$
|
edits.add(new InsertEdit(offset, "/*")); //$NON-NLS-1$
|
||||||
|
@ -483,8 +483,8 @@ public class IncludeOrganizer {
|
||||||
IASTFileLocation location = include.getFileLocation();
|
IASTFileLocation location = include.getFileLocation();
|
||||||
int offset = location.getNodeOffset();
|
int offset = location.getNodeOffset();
|
||||||
int endOffset = offset + location.getNodeLength();
|
int endOffset = offset + location.getNodeLength();
|
||||||
offset = getLineStart(fContext.getSourceContents(), offset);
|
offset = TextUtil.getLineStart(fContext.getSourceContents(), offset);
|
||||||
endOffset = skipToNextLine(fContext.getSourceContents(), endOffset);
|
endOffset = TextUtil.skipToNextLine(fContext.getSourceContents(), endOffset);
|
||||||
edits.add(new DeleteEdit(offset, endOffset - offset));
|
edits.add(new DeleteEdit(offset, endOffset - offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ public class IncludeOrganizer {
|
||||||
}
|
}
|
||||||
if (includeOffset < 0) {
|
if (includeOffset < 0) {
|
||||||
if (includeGuardEndOffset >= 0) {
|
if (includeGuardEndOffset >= 0) {
|
||||||
includeOffset = skipToNextLine(contents, includeGuardEndOffset);
|
includeOffset = TextUtil.skipToNextLine(contents, includeGuardEndOffset);
|
||||||
} else {
|
} else {
|
||||||
includeOffset = 0;
|
includeOffset = 0;
|
||||||
}
|
}
|
||||||
|
@ -546,7 +546,7 @@ public class IncludeOrganizer {
|
||||||
}
|
}
|
||||||
includeEndOffset = includeOffset;
|
includeEndOffset = includeOffset;
|
||||||
} else {
|
} else {
|
||||||
includeEndOffset = skipToNextLine(contents, includeEndOffset);
|
includeEndOffset = TextUtil.skipToNextLine(contents, includeEndOffset);
|
||||||
}
|
}
|
||||||
return new Region(includeOffset, includeEndOffset - includeOffset);
|
return new Region(includeOffset, includeEndOffset - includeOffset);
|
||||||
}
|
}
|
||||||
|
@ -587,32 +587,12 @@ public class IncludeOrganizer {
|
||||||
return CharArrayUtils.equals(((IASTPreprocessorPragmaStatement) statement).getMessage(), "once"); //$NON-NLS-1$
|
return CharArrayUtils.equals(((IASTPreprocessorPragmaStatement) statement).getMessage(), "once"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int skipToNextLine(char[] text, int offset) {
|
|
||||||
while (offset < text.length) {
|
|
||||||
if (text[offset++] == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getLineStart(char[] text, int offset) {
|
|
||||||
while (--offset >= 0) {
|
|
||||||
if (text[offset] == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return offset + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int skipToNextLineAfterNode(char[] text, IASTNode node) {
|
|
||||||
return skipToNextLine(text, getNodeEndOffset(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if there are no non-whitespace characters between the given
|
* Returns {@code true} if there are no non-whitespace characters between the given
|
||||||
* {@code offset} and the end of the line.
|
* {@code offset} and the end of the line.
|
||||||
*/
|
*/
|
||||||
private boolean isBlankLineOrEndOfFile(int offset) {
|
private boolean isBlankLineOrEndOfFile(int offset) {
|
||||||
char[] contents = fContext.getTranslationUnit().getContents();
|
char[] contents = fContext.getSourceContents();
|
||||||
while (offset < contents.length) {
|
while (offset < contents.length) {
|
||||||
char c = contents[offset++];
|
char c = contents[offset++];
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
|
@ -623,26 +603,6 @@ public class IncludeOrganizer {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} the line prior to the line corresponding to the given {@code offset}
|
|
||||||
* does not contain non-whitespace characters.
|
|
||||||
*/
|
|
||||||
private boolean isPreviousLineBlank(int offset) {
|
|
||||||
char[] contents = fContext.getTranslationUnit().getContents();
|
|
||||||
while (--offset >= 0) {
|
|
||||||
if (contents[offset] == '\n')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
while (--offset >= 0) {
|
|
||||||
char c = contents[offset];
|
|
||||||
if (c == '\n')
|
|
||||||
return true;
|
|
||||||
if (!Character.isWhitespace(c))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the whitespace preceding the given node. The newline character in not considered
|
* Returns the whitespace preceding the given node. The newline character in not considered
|
||||||
* whitespace for the purpose of this method.
|
* whitespace for the purpose of this method.
|
||||||
|
@ -650,7 +610,7 @@ public class IncludeOrganizer {
|
||||||
private String getPrecedingWhitespace(IASTNode node) {
|
private String getPrecedingWhitespace(IASTNode node) {
|
||||||
int offset = getNodeOffset(node);
|
int offset = getNodeOffset(node);
|
||||||
if (offset >= 0) {
|
if (offset >= 0) {
|
||||||
char[] contents = fContext.getTranslationUnit().getContents();
|
char[] contents = fContext.getSourceContents();
|
||||||
int i = offset;
|
int i = offset;
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
char c = contents[i];
|
char c = contents[i];
|
||||||
|
@ -697,11 +657,11 @@ public class IncludeOrganizer {
|
||||||
for (int j = 1; j < leadingComments.size(); j++) {
|
for (int j = 1; j < leadingComments.size(); j++) {
|
||||||
comment = leadingComments.get(j);
|
comment = leadingComments.get(j);
|
||||||
if (getStartingLineNumber(comment) > getEndingLineNumber(previous) + 1)
|
if (getStartingLineNumber(comment) > getEndingLineNumber(previous) + 1)
|
||||||
return skipToNextLineAfterNode(contents, previous);
|
return ASTNodes.skipToNextLineAfterNode(contents, previous);
|
||||||
previous = comment;
|
previous = comment;
|
||||||
}
|
}
|
||||||
if (getStartingLineNumber(node) > getEndingLineNumber(previous) + 1)
|
if (getStartingLineNumber(node) > getEndingLineNumber(previous) + 1)
|
||||||
return skipToNextLineAfterNode(contents, previous);
|
return ASTNodes.skipToNextLineAfterNode(contents, previous);
|
||||||
}
|
}
|
||||||
node = inverseFreestandingMap.get(comment);
|
node = inverseFreestandingMap.get(comment);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
@ -710,7 +670,7 @@ public class IncludeOrganizer {
|
||||||
for (int j = 1; j < freestandingComments.size(); j++) {
|
for (int j = 1; j < freestandingComments.size(); j++) {
|
||||||
comment = freestandingComments.get(j);
|
comment = freestandingComments.get(j);
|
||||||
if (getStartingLineNumber(comment) > getEndingLineNumber(previous) + 1)
|
if (getStartingLineNumber(comment) > getEndingLineNumber(previous) + 1)
|
||||||
return skipToNextLineAfterNode(contents, previous);
|
return ASTNodes.skipToNextLineAfterNode(contents, previous);
|
||||||
previous = comment;
|
previous = comment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1059,8 +1019,7 @@ public class IncludeOrganizer {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf.append("#include "); //$NON-NLS-1$
|
buf.append(include.getIncludeInfo().composeIncludeStatement());
|
||||||
buf.append(include.getIncludeInfo().toString());
|
|
||||||
buf.append(lineComment);
|
buf.append(lineComment);
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -21,12 +22,14 @@ import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.corext.codemanipulation.StyledInclude;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
|
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences for managing of includes.
|
* Preferences for managing of includes.
|
||||||
*/
|
*/
|
||||||
public class IncludePreferences {
|
public class IncludePreferences implements Comparator<StyledInclude> {
|
||||||
private static final String DEFAULT_PARTNER_FILE_SUFFIXES = "test,unittest"; //$NON-NLS-1$
|
private static final String DEFAULT_PARTNER_FILE_SUFFIXES = "test,unittest"; //$NON-NLS-1$
|
||||||
|
|
||||||
public static enum UnusedStatementDisposition { REMOVE, COMMENT_OUT, KEEP }
|
public static enum UnusedStatementDisposition { REMOVE, COMMENT_OUT, KEEP }
|
||||||
|
@ -111,7 +114,7 @@ public class IncludePreferences {
|
||||||
String value = PreferenceConstants.getPreference(preferenceKey, project, null);
|
String value = PreferenceConstants.getPreference(preferenceKey, project, null);
|
||||||
IncludeGroupStyle style = null;
|
IncludeGroupStyle style = null;
|
||||||
if (value != null)
|
if (value != null)
|
||||||
style = IncludeGroupStyle.fromString(value, includeKind);
|
style = IncludeGroupStyle.fromXmlString(value, includeKind);
|
||||||
if (style == null)
|
if (style == null)
|
||||||
style = new IncludeGroupStyle(includeKind);
|
style = new IncludeGroupStyle(includeKind);
|
||||||
includeStyles.put(includeKind, style);
|
includeStyles.put(includeKind, style);
|
||||||
|
@ -124,41 +127,41 @@ public class IncludePreferences {
|
||||||
*/
|
*/
|
||||||
public static void initializeDefaultValues(IPreferenceStore store) {
|
public static void initializeDefaultValues(IPreferenceStore store) {
|
||||||
IncludeGroupStyle style = new IncludeGroupStyle(IncludeKind.RELATED);
|
IncludeGroupStyle style = new IncludeGroupStyle(IncludeKind.RELATED);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_RELATED, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_RELATED, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.PARTNER);
|
style = new IncludeGroupStyle(IncludeKind.PARTNER);
|
||||||
style.setKeepTogether(true);
|
style.setKeepTogether(true);
|
||||||
style.setBlankLineBefore(true);
|
style.setBlankLineBefore(true);
|
||||||
style.setOrder(0);
|
style.setOrder(0);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_PARTNER, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_PARTNER, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.IN_SAME_FOLDER);
|
style = new IncludeGroupStyle(IncludeKind.IN_SAME_FOLDER);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_FOLDER, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_FOLDER, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.IN_SUBFOLDER);
|
style = new IncludeGroupStyle(IncludeKind.IN_SUBFOLDER);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SUBFOLDER, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SUBFOLDER, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.SYSTEM);
|
style = new IncludeGroupStyle(IncludeKind.SYSTEM);
|
||||||
style.setKeepTogether(true);
|
style.setKeepTogether(true);
|
||||||
style.setBlankLineBefore(true);
|
style.setBlankLineBefore(true);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITH_EXTENSION);
|
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITH_EXTENSION);
|
||||||
style.setKeepTogether(true);
|
style.setKeepTogether(true);
|
||||||
style.setAngleBrackets(true);
|
style.setAngleBrackets(true);
|
||||||
style.setOrder(1);
|
style.setOrder(1);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION);
|
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION);
|
||||||
style.setKeepTogether(true);
|
style.setKeepTogether(true);
|
||||||
style.setAngleBrackets(true);
|
style.setAngleBrackets(true);
|
||||||
style.setOrder(2);
|
style.setOrder(2);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.OTHER);
|
style = new IncludeGroupStyle(IncludeKind.OTHER);
|
||||||
style.setKeepTogether(true);
|
style.setKeepTogether(true);
|
||||||
style.setBlankLineBefore(true);
|
style.setBlankLineBefore(true);
|
||||||
style.setOrder(3);
|
style.setOrder(3);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.IN_SAME_PROJECT);
|
style = new IncludeGroupStyle(IncludeKind.IN_SAME_PROJECT);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_PROJECT, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_SAME_PROJECT, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.IN_OTHER_PROJECT);
|
style = new IncludeGroupStyle(IncludeKind.IN_OTHER_PROJECT);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER_PROJECT, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_OTHER_PROJECT, style.toXmlString());
|
||||||
style = new IncludeGroupStyle(IncludeKind.EXTERNAL);
|
style = new IncludeGroupStyle(IncludeKind.EXTERNAL);
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_EXTERNAL, style.toString());
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_EXTERNAL, style.toXmlString());
|
||||||
store.setDefault(PreferenceConstants.INCLUDE_STYLE_MATCHING_PATTERN, ""); //$NON-NLS-1$
|
store.setDefault(PreferenceConstants.INCLUDE_STYLE_MATCHING_PATTERN, ""); //$NON-NLS-1$
|
||||||
|
|
||||||
store.setDefault(PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, DEFAULT_PARTNER_FILE_SUFFIXES);
|
store.setDefault(PreferenceConstants.INCLUDES_PARTNER_FILE_SUFFIXES, DEFAULT_PARTNER_FILE_SUFFIXES);
|
||||||
|
@ -178,4 +181,13 @@ public class IncludePreferences {
|
||||||
store.setDefault(PreferenceConstants.INCLUDES_SYMBOL_EXPORTING_HEADERS,
|
store.setDefault(PreferenceConstants.INCLUDES_SYMBOL_EXPORTING_HEADERS,
|
||||||
SymbolExportMap.serializeMaps(Collections.singletonList(GCCHeaderSubstitutionMaps.getSymbolExportMap())));
|
SymbolExportMap.serializeMaps(Collections.singletonList(GCCHeaderSubstitutionMaps.getSymbolExportMap())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(StyledInclude include1, StyledInclude include2) {
|
||||||
|
int c = include1.getStyle().getGroupingStyle(includeStyles).getOrder() -
|
||||||
|
include2.getStyle().getGroupingStyle(includeStyles).getOrder();
|
||||||
|
if (c != 0)
|
||||||
|
return c;
|
||||||
|
return include1.getIncludeInfo().compareTo(include2.getIncludeInfo());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
|
||||||
import org.eclipse.osgi.util.NLS;
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
public final class Messages extends NLS {
|
public final class Messages extends NLS {
|
||||||
|
public static String AddInclude_help_provider_error;
|
||||||
|
|
||||||
public static String GCCHeaderSubstitutionMaps_c_map;
|
public static String GCCHeaderSubstitutionMaps_c_map;
|
||||||
public static String GCCHeaderSubstitutionMaps_cpp_map;
|
public static String GCCHeaderSubstitutionMaps_cpp_map;
|
||||||
|
|
||||||
|
|
|
@ -9,5 +9,7 @@
|
||||||
# Sergey Prigogin (Google) - initial API and implementation
|
# Sergey Prigogin (Google) - initial API and implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
AddInclude_help_provider_error=Help provider error
|
||||||
|
|
||||||
GCCHeaderSubstitutionMaps_c_map=GCC C Header Substitution
|
GCCHeaderSubstitutionMaps_c_map=GCC C Header Substitution
|
||||||
GCCHeaderSubstitutionMaps_cpp_map=GCC C++ Header Substitution
|
GCCHeaderSubstitutionMaps_cpp_map=GCC C++ Header Substitution
|
||||||
|
|
|
@ -730,25 +730,18 @@ public class NewClassCodeGenerator {
|
||||||
includes.add(new StyledInclude(baseClassLocation, includeInfo, style));
|
includes.add(new StyledInclude(baseClassLocation, includeInfo, style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(includes);
|
IncludePreferences preferences = inclusionContext.getPreferences();
|
||||||
|
Collections.sort(includes, preferences);
|
||||||
|
|
||||||
StringBuilder text = new StringBuilder();
|
StringBuilder text = new StringBuilder();
|
||||||
IncludePreferences preferences = inclusionContext.getPreferences();
|
IncludeGroupStyle previousStyle = null;
|
||||||
IncludeGroupStyle previousParentStyle = null;
|
|
||||||
for (StyledInclude include : includes) {
|
for (StyledInclude include : includes) {
|
||||||
IncludeGroupStyle style = include.getStyle();
|
IncludeGroupStyle style = include.getStyle();
|
||||||
IncludeGroupStyle groupingStyle = style.getGroupingStyle(preferences.includeStyles);
|
if (style.isBlankLineNeededAfter(previousStyle, preferences.includeStyles))
|
||||||
IncludeGroupStyle parentStyle = groupingStyle.getParentStyle(preferences.includeStyles);
|
|
||||||
if (groupingStyle.isBlankLineBefore() ||
|
|
||||||
(parentStyle != null && previousParentStyle != null &&
|
|
||||||
parentStyle != previousParentStyle && parentStyle.isKeepTogether() &&
|
|
||||||
parentStyle.isBlankLineBefore())) {
|
|
||||||
text.append(lineDelimiter);
|
text.append(lineDelimiter);
|
||||||
}
|
text.append(include.getIncludeInfo().composeIncludeStatement());
|
||||||
text.append("#include "); //$NON-NLS-1$
|
|
||||||
text.append(include.getIncludeInfo().toString());
|
|
||||||
text.append(lineDelimiter);
|
text.append(lineDelimiter);
|
||||||
previousParentStyle = parentStyle;
|
previousStyle = style;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor.done();
|
monitor.done();
|
||||||
|
@ -756,7 +749,7 @@ public class NewClassCodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the base classes need to be verified (ie they must exist in the project)
|
* Checks if the base classes need to be verified (i.e. they must exist in the project)
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if the base classes should be verified
|
* @return <code>true</code> if the base classes should be verified
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -317,7 +317,7 @@ public class CUIPlugin extends AbstractUIPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(String message, Throwable e) {
|
public static void log(String message, Throwable e) {
|
||||||
log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, e));
|
log(createErrorStatus(message, e));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(IStatus status) {
|
public static void log(IStatus status) {
|
||||||
|
@ -339,9 +339,17 @@ public class CUIPlugin extends AbstractUIPlugin {
|
||||||
log(new Status(IStatus.ERROR, PLUGIN_ID, ICStatusConstants.INTERNAL_ERROR, message, null));
|
log(new Status(IStatus.ERROR, PLUGIN_ID, ICStatusConstants.INTERNAL_ERROR, message, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an error status.
|
||||||
|
*
|
||||||
|
* @since 5.7
|
||||||
|
*/
|
||||||
|
public static Status createErrorStatus(String message, Throwable e) {
|
||||||
|
return new Status(IStatus.ERROR, PLUGIN_ID, IStatus.ERROR, message, e);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method with conventions
|
* Utility method with conventions
|
||||||
* @param logError TODO
|
|
||||||
*/
|
*/
|
||||||
public static void errorDialog(Shell shell, String title, String message, IStatus s, boolean logError) {
|
public static void errorDialog(Shell shell, String title, String message, IStatus s, boolean logError) {
|
||||||
if (logError)
|
if (logError)
|
||||||
|
@ -357,7 +365,6 @@ public class CUIPlugin extends AbstractUIPlugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method with conventions
|
* Utility method with conventions
|
||||||
* @param logError TODO
|
|
||||||
*/
|
*/
|
||||||
public static void errorDialog(Shell shell, String title, String message, Throwable t, boolean logError) {
|
public static void errorDialog(Shell shell, String title, String message, Throwable t, boolean logError) {
|
||||||
if (logError)
|
if (logError)
|
||||||
|
|
|
@ -49,7 +49,7 @@ import org.eclipse.cdt.ui.refactoring.actions.RefactoringAction;
|
||||||
import org.eclipse.cdt.internal.ui.IContextMenuConstants;
|
import org.eclipse.cdt.internal.ui.IContextMenuConstants;
|
||||||
import org.eclipse.cdt.internal.ui.actions.ActionMessages;
|
import org.eclipse.cdt.internal.ui.actions.ActionMessages;
|
||||||
import org.eclipse.cdt.internal.ui.actions.CDTQuickMenuCreator;
|
import org.eclipse.cdt.internal.ui.actions.CDTQuickMenuCreator;
|
||||||
import org.eclipse.cdt.internal.ui.editor.AddIncludeOnSelectionAction;
|
import org.eclipse.cdt.internal.ui.editor.AddIncludeAction;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||||
import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds;
|
import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds;
|
||||||
import org.eclipse.cdt.internal.ui.editor.OrganizeIncludesAction;
|
import org.eclipse.cdt.internal.ui.editor.OrganizeIncludesAction;
|
||||||
|
@ -115,7 +115,7 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
|
||||||
private List<ISelectionChangedListener> fRegisteredSelectionListeners;
|
private List<ISelectionChangedListener> fRegisteredSelectionListeners;
|
||||||
private List<RefactoringAction> fRefactorActions= new ArrayList<RefactoringAction>();
|
private List<RefactoringAction> fRefactorActions= new ArrayList<RefactoringAction>();
|
||||||
|
|
||||||
private AddIncludeOnSelectionAction fAddInclude;
|
private AddIncludeAction fAddInclude;
|
||||||
// private OverrideMethodsAction fOverrideMethods;
|
// private OverrideMethodsAction fOverrideMethods;
|
||||||
// private GenerateHashCodeEqualsAction fHashCodeEquals;
|
// private GenerateHashCodeEqualsAction fHashCodeEquals;
|
||||||
private GettersAndSettersAction fAddGetterSetter;
|
private GettersAndSettersAction fAddGetterSetter;
|
||||||
|
@ -155,9 +155,9 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
|
||||||
fEditor= editor;
|
fEditor= editor;
|
||||||
fGroupName= groupName;
|
fGroupName= groupName;
|
||||||
|
|
||||||
fAddInclude= new AddIncludeOnSelectionAction(editor);
|
fAddInclude= new AddIncludeAction(editor);
|
||||||
fAddInclude.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_INCLUDE);
|
fAddInclude.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_INCLUDE);
|
||||||
editor.setAction("AddIncludeOnSelection", fAddInclude); //$NON-NLS-1$
|
editor.setAction("AddInclude", fAddInclude); //$NON-NLS-1$
|
||||||
|
|
||||||
fOrganizeIncludes= new OrganizeIncludesAction(editor);
|
fOrganizeIncludes= new OrganizeIncludesAction(editor);
|
||||||
fOrganizeIncludes.setActionDefinitionId(ICEditorActionDefinitionIds.ORGANIZE_INCLUDES);
|
fOrganizeIncludes.setActionDefinitionId(ICEditorActionDefinitionIds.ORGANIZE_INCLUDES);
|
||||||
|
|
Loading…
Add table
Reference in a new issue