New UI and other improvements for Extract Function refactoring .
|
@ -10,14 +10,18 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.rewrite;
|
package org.eclipse.cdt.core.dom.rewrite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
|
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
|
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,4 +63,12 @@ public class TypeHelper {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IType createType(IASTDeclarator declarator) {
|
||||||
|
if (declarator.getTranslationUnit() instanceof ICPPASTTranslationUnit) {
|
||||||
|
return CPPVisitor.createType(declarator);
|
||||||
|
} else {
|
||||||
|
return CVisitor.createType(declarator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,11 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||||
|
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -1864,6 +1868,8 @@ public class CPPVisitor extends ASTQueries {
|
||||||
boolean isPackExpansion= false;
|
boolean isPackExpansion= false;
|
||||||
if (parent instanceof IASTSimpleDeclaration) {
|
if (parent instanceof IASTSimpleDeclaration) {
|
||||||
declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||||
|
} else if (parent instanceof IASTParameterDeclaration) {
|
||||||
|
declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||||
} else if (parent instanceof IASTFunctionDefinition) {
|
} else if (parent instanceof IASTFunctionDefinition) {
|
||||||
declSpec = ((IASTFunctionDefinition) parent).getDeclSpecifier();
|
declSpec = ((IASTFunctionDefinition) parent).getDeclSpecifier();
|
||||||
} else if (parent instanceof ICPPASTTypeId) {
|
} else if (parent instanceof ICPPASTTypeId) {
|
||||||
|
@ -2506,4 +2512,21 @@ public class CPPVisitor extends ASTQueries {
|
||||||
public static ICPPASTDeclarator findInnermostDeclarator(ICPPASTDeclarator dtor) {
|
public static ICPPASTDeclarator findInnermostDeclarator(ICPPASTDeclarator dtor) {
|
||||||
return (ICPPASTDeclarator) ASTQueries.findInnermostDeclarator(dtor);
|
return (ICPPASTDeclarator) ASTQueries.findInnermostDeclarator(dtor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traverses parent chain of the given node and returns the first node of the given type.
|
||||||
|
* @param node the start node
|
||||||
|
* @param type the type to look for
|
||||||
|
* @return the node itself or its closest ancestor that has the given type, or {@code null}
|
||||||
|
* if no such node is found.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends IASTNode> T findAncestorWithType(IASTNode node, Class<T> type) {
|
||||||
|
do {
|
||||||
|
if (type.isInstance(node)) {
|
||||||
|
return (T) node;
|
||||||
|
}
|
||||||
|
} while ((node = node.getParent()) != null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,13 +105,13 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
||||||
returnedDeclSpec = declSpec;
|
returnedDeclSpec = declSpec;
|
||||||
} else if (type instanceof ICPPTemplateInstance) {
|
} else if (type instanceof ICPPTemplateInstance) {
|
||||||
returnedDeclSpec = getDeclSpecForTemplate((ICPPTemplateInstance) type);
|
returnedDeclSpec = getDeclSpecForTemplate((ICPPTemplateInstance) type);
|
||||||
|
|
||||||
} else if (type instanceof IBinding) { /* ITypedef, ICompositeType... */
|
} else if (type instanceof IBinding) { /* ITypedef, ICompositeType... */
|
||||||
// BTW - we need to distinguish (and fail explicitly) on literal composites like:
|
// BTW - we need to distinguish (and fail explicitly) on literal composites like:
|
||||||
// struct { } aSingleInstance;
|
// struct { } aSingleInstance;
|
||||||
returnedDeclSpec = getDeclSpecForBinding((IBinding) type);
|
returnedDeclSpec = getDeclSpecForBinding((IBinding) type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(sprigogin): Be honest and return null instead of void.
|
||||||
// Fallback...
|
// Fallback...
|
||||||
if (returnedDeclSpec == null) {
|
if (returnedDeclSpec == null) {
|
||||||
IASTSimpleDeclSpecifier specifier = factory.newSimpleDeclSpecifier();
|
IASTSimpleDeclSpecifier specifier = factory.newSimpleDeclSpecifier();
|
||||||
|
@ -129,7 +129,7 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
||||||
// Addition of pointer operators has to be in reverse order, so it's deferred until the end
|
// Addition of pointer operators has to be in reverse order, so it's deferred until the end
|
||||||
Map<IASTDeclarator, LinkedList<IASTPointerOperator>> pointerOperatorMap = new HashMap<IASTDeclarator, LinkedList<IASTPointerOperator>>();
|
Map<IASTDeclarator, LinkedList<IASTPointerOperator>> pointerOperatorMap = new HashMap<IASTDeclarator, LinkedList<IASTPointerOperator>>();
|
||||||
|
|
||||||
IASTName newName = (name != null) ? factory.newName(name) : factory.newName();
|
IASTName newName = name != null ? factory.newName(name) : factory.newName();
|
||||||
|
|
||||||
// If the type is an array of something, create a declaration of a pointer to something instead
|
// If the type is an array of something, create a declaration of a pointer to something instead
|
||||||
// (to allow assignment, etc)
|
// (to allow assignment, etc)
|
||||||
|
@ -311,8 +311,8 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
||||||
ICPPNodeFactory cppFactory = (ICPPNodeFactory) factory;
|
ICPPNodeFactory cppFactory = (ICPPNodeFactory) factory;
|
||||||
ICPPASTTemplateId tempId = cppFactory.newTemplateId(templateName.copy());
|
ICPPASTTemplateId tempId = cppFactory.newTemplateId(templateName.copy());
|
||||||
for (ICPPTemplateArgument arg : type.getTemplateArguments()) {
|
for (ICPPTemplateArgument arg : type.getTemplateArguments()) {
|
||||||
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ? arg
|
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ?
|
||||||
.getTypeValue() : arg.getTypeOfNonTypeValue());
|
arg.getTypeValue() : arg.getTypeOfNonTypeValue());
|
||||||
IASTTypeId typeId = cppFactory.newTypeId(argDeclSpec, null);
|
IASTTypeId typeId = cppFactory.newTypeId(argDeclSpec, null);
|
||||||
tempId.addTemplateArgument(typeId);
|
tempId.addTemplateArgument(typeId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||||
* @author Emanuel Graf
|
* @author Emanuel Graf
|
||||||
*/
|
*/
|
||||||
public class ASTWriter {
|
public class ASTWriter {
|
||||||
private ASTModificationStore modificationStore = new ASTModificationStore();
|
private final ASTModificationStore modificationStore = new ASTModificationStore();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a <code>ASTWriter</code>.
|
* Creates a <code>ASTWriter</code>.
|
||||||
|
@ -63,7 +63,7 @@ public class ASTWriter {
|
||||||
* Generates the source code representing this node including comments.
|
* Generates the source code representing this node including comments.
|
||||||
*
|
*
|
||||||
* @param rootNode Node to write.
|
* @param rootNode Node to write.
|
||||||
* @param commentMap Node Comment Map <code>ASTCommenter</code>
|
* @param commentMap comments for the translation unit
|
||||||
* @return A <code>String</code> representing the source code for the node.
|
* @return A <code>String</code> representing the source code for the node.
|
||||||
* @throws ProblemRuntimeException if the node or one of it's children is
|
* @throws ProblemRuntimeException if the node or one of it's children is
|
||||||
* an <code>IASTProblemNode</code>.
|
* an <code>IASTProblemNode</code>.
|
||||||
|
@ -79,10 +79,6 @@ public class ASTWriter {
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModificationStore(ASTModificationStore modificationStore) {
|
|
||||||
this.modificationStore = modificationStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if the node should be separated by a blank line from the node
|
* Returns <code>true</code> if the node should be separated by a blank line from the node
|
||||||
* before it.
|
* before it.
|
||||||
|
|
|
@ -80,6 +80,13 @@ public class ASTWriterVisitor extends ASTVisitor {
|
||||||
shouldVisitTypeIds = true;
|
shouldVisitTypeIds = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a writer with an empty comment map.
|
||||||
|
*/
|
||||||
|
public ASTWriterVisitor() {
|
||||||
|
this(new NodeCommentMap());
|
||||||
|
}
|
||||||
|
|
||||||
public ASTWriterVisitor(NodeCommentMap commentMap) {
|
public ASTWriterVisitor(NodeCommentMap commentMap) {
|
||||||
super();
|
super();
|
||||||
init(commentMap);
|
init(commentMap);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2001, 2011 IBM Corporation and others.
|
* Copyright (c) 2001, 2012 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
|
||||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.cdt.core.formatter;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2011 IBM Corporation and others.
|
* Copyright (c) 2000, 2012 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
|
||||||
|
@ -10,15 +10,20 @@
|
||||||
* Sergey Prigogin (Google)
|
* Sergey Prigogin (Google)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.formatter;
|
package org.eclipse.cdt.core.formatter;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Code formatter options.
|
||||||
|
*
|
||||||
|
* @noextend This class is not intended to be subclassed by clients.
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
public class DefaultCodeFormatterOptions {
|
public class DefaultCodeFormatterOptions {
|
||||||
public static final int TAB = 1;
|
public static final int TAB = 1;
|
||||||
public static final int SPACE = 2;
|
public static final int SPACE = 2;
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||||
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
|
|
@ -141,6 +141,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
||||||
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
|
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
|
||||||
|
|
|
@ -1502,8 +1502,8 @@ public:
|
||||||
return mClass;
|
return mClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setClass(int _class) {
|
void setClass(int clazz) {
|
||||||
mClass = _class;
|
mClass = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -12,6 +12,8 @@ package org.eclipse.cdt.ui.tests.refactoring.utils;
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
||||||
|
@ -46,42 +48,42 @@ public class NameComposerTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testTrimFieldName() {
|
public void testTrimFieldName() {
|
||||||
assertEquals("f", NameComposer.trimFieldName("f_"));
|
assertEquals("f", StubUtility.trimFieldName("f_"));
|
||||||
assertEquals("F", NameComposer.trimFieldName("F_"));
|
assertEquals("F", StubUtility.trimFieldName("F_"));
|
||||||
assertEquals("oo", NameComposer.trimFieldName("F_oo"));
|
assertEquals("oo", StubUtility.trimFieldName("F_oo"));
|
||||||
assertEquals("o", NameComposer.trimFieldName("f_o"));
|
assertEquals("o", StubUtility.trimFieldName("f_o"));
|
||||||
|
|
||||||
assertEquals("M", NameComposer.trimFieldName("a_M_"));
|
assertEquals("M", StubUtility.trimFieldName("a_M_"));
|
||||||
assertEquals("bs", NameComposer.trimFieldName("a_bs_"));
|
assertEquals("bs", StubUtility.trimFieldName("a_bs_"));
|
||||||
assertEquals("foo_bar", NameComposer.trimFieldName("foo_bar"));
|
assertEquals("foo_bar", StubUtility.trimFieldName("foo_bar"));
|
||||||
assertEquals("foo_bar", NameComposer.trimFieldName("foo_bar_"));
|
assertEquals("foo_bar", StubUtility.trimFieldName("foo_bar_"));
|
||||||
|
|
||||||
assertEquals("foo_b", NameComposer.trimFieldName("foo_b_"));
|
assertEquals("foo_b", StubUtility.trimFieldName("foo_b_"));
|
||||||
|
|
||||||
assertEquals("foo", NameComposer.trimFieldName("foo"));
|
assertEquals("foo", StubUtility.trimFieldName("foo"));
|
||||||
assertEquals("foo", NameComposer.trimFieldName("_foo"));
|
assertEquals("foo", StubUtility.trimFieldName("_foo"));
|
||||||
assertEquals("bar", NameComposer.trimFieldName("_f_bar"));
|
assertEquals("bar", StubUtility.trimFieldName("_f_bar"));
|
||||||
|
|
||||||
assertEquals("f", NameComposer.trimFieldName("f__"));
|
assertEquals("f", StubUtility.trimFieldName("f__"));
|
||||||
assertEquals("f", NameComposer.trimFieldName("__f"));
|
assertEquals("f", StubUtility.trimFieldName("__f"));
|
||||||
assertEquals("O__b", NameComposer.trimFieldName("fO__b"));
|
assertEquals("O__b", StubUtility.trimFieldName("fO__b"));
|
||||||
assertEquals("Oo", NameComposer.trimFieldName("fOo"));
|
assertEquals("Oo", StubUtility.trimFieldName("fOo"));
|
||||||
assertEquals("O", NameComposer.trimFieldName("fO"));
|
assertEquals("O", StubUtility.trimFieldName("fO"));
|
||||||
assertEquals("MyStatic", NameComposer.trimFieldName("sMyStatic"));
|
assertEquals("MyStatic", StubUtility.trimFieldName("sMyStatic"));
|
||||||
assertEquals("MyMember", NameComposer.trimFieldName("mMyMember"));
|
assertEquals("MyMember", StubUtility.trimFieldName("mMyMember"));
|
||||||
|
|
||||||
assertEquals("8", NameComposer.trimFieldName("_8"));
|
assertEquals("8", StubUtility.trimFieldName("_8"));
|
||||||
|
|
||||||
assertEquals("8bar", NameComposer.trimFieldName("_8bar_"));
|
assertEquals("8bar", StubUtility.trimFieldName("_8bar_"));
|
||||||
assertEquals("8bar_8", NameComposer.trimFieldName("_8bar_8"));
|
assertEquals("8bar_8", StubUtility.trimFieldName("_8bar_8"));
|
||||||
assertEquals("8bAr", NameComposer.trimFieldName("_8bAr"));
|
assertEquals("8bAr", StubUtility.trimFieldName("_8bAr"));
|
||||||
assertEquals("b8Ar", NameComposer.trimFieldName("_b8Ar"));
|
assertEquals("b8Ar", StubUtility.trimFieldName("_b8Ar"));
|
||||||
|
|
||||||
assertEquals("Id", NameComposer.trimFieldName("Id"));
|
assertEquals("Id", StubUtility.trimFieldName("Id"));
|
||||||
assertEquals("ID", NameComposer.trimFieldName("ID"));
|
assertEquals("ID", StubUtility.trimFieldName("ID"));
|
||||||
assertEquals("IDS", NameComposer.trimFieldName("IDS"));
|
assertEquals("IDS", StubUtility.trimFieldName("IDS"));
|
||||||
assertEquals("ID", NameComposer.trimFieldName("bID"));
|
assertEquals("ID", StubUtility.trimFieldName("bID"));
|
||||||
assertEquals("Id", NameComposer.trimFieldName("MId"));
|
assertEquals("Id", StubUtility.trimFieldName("MId"));
|
||||||
assertEquals("IdA", NameComposer.trimFieldName("IdA"));
|
assertEquals("IdA", StubUtility.trimFieldName("IdA"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,12 @@ import org.eclipse.jface.text.TabsToSpacesConverter;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy;
|
import org.eclipse.cdt.ui.text.doctools.DefaultMultilineCommentAutoEditStrategy;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
|
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
|
||||||
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
|
|
|
@ -22,9 +22,9 @@ import org.eclipse.jface.text.source.LineRange;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
|
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
|
||||||
import org.eclipse.cdt.internal.ui.editor.IndentUtil;
|
import org.eclipse.cdt.internal.ui.editor.IndentUtil;
|
||||||
|
|
|
@ -27,10 +27,10 @@ import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
|
import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage;
|
||||||
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
import org.eclipse.cdt.core.formatter.CodeFormatter;
|
||||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
|
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
|
||||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
|
||||||
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
import org.eclipse.cdt.internal.formatter.align.Alignment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.4 KiB |
BIN
core/org.eclipse.cdt.ui/icons/wizban/refactor_field_wiz.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
core/org.eclipse.cdt.ui/icons/wizban/refactor_method_wiz.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
core/org.eclipse.cdt.ui/icons/wizban/refactor_tu_wiz.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
core/org.eclipse.cdt.ui/icons/wizban/refactor_type_wiz.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 3.4 KiB |
|
@ -17,6 +17,7 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
|
@ -27,6 +28,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.preferences.IPreferencesService;
|
||||||
import org.eclipse.core.runtime.preferences.IScopeContext;
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
@ -45,13 +47,19 @@ import org.eclipse.text.edits.InsertEdit;
|
||||||
import org.eclipse.text.edits.MalformedTreeException;
|
import org.eclipse.text.edits.MalformedTreeException;
|
||||||
import org.eclipse.text.edits.MultiTextEdit;
|
import org.eclipse.text.edits.MultiTextEdit;
|
||||||
|
|
||||||
|
import com.ibm.icu.text.BreakIterator;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CConventions;
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||||
|
import org.eclipse.cdt.core.dom.parser.AbstractCLikeLanguage;
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.IBuffer;
|
import org.eclipse.cdt.core.model.IBuffer;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.cdt.core.model.ISourceRoot;
|
import org.eclipse.cdt.core.model.ISourceRoot;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
@ -64,6 +72,8 @@ import org.eclipse.cdt.internal.corext.template.c.FileTemplateContext;
|
||||||
import org.eclipse.cdt.internal.corext.template.c.FileTemplateContextType;
|
import org.eclipse.cdt.internal.corext.template.c.FileTemplateContextType;
|
||||||
import org.eclipse.cdt.internal.corext.util.Strings;
|
import org.eclipse.cdt.internal.corext.util.Strings;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CBreakIterator;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.ProjectTemplateStore;
|
import org.eclipse.cdt.internal.ui.viewsupport.ProjectTemplateStore;
|
||||||
|
|
||||||
public class StubUtility {
|
public class StubUtility {
|
||||||
|
@ -747,4 +757,205 @@ public class StubUtility {
|
||||||
}
|
}
|
||||||
return result.toArray(new Template[result.size()]);
|
return result.toArray(new Template[result.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a suggested name for a getter that is guaranteed to be a valid identifier
|
||||||
|
* and not collide with a set of given names.
|
||||||
|
*
|
||||||
|
* @param baseName the name used as an inspiration
|
||||||
|
* @param bool <code>true</code> if the getter is for a boolean field
|
||||||
|
* @param excluded the set of excluded names, can be {@code null}
|
||||||
|
* @param context the translation unit for which the code is intended, can be {@code null}
|
||||||
|
* @return the suggested name, or {@code null} if all possible names are taken
|
||||||
|
*/
|
||||||
|
public static String suggestGetterName(String baseName, boolean bool, Set<String> excluded, ITranslationUnit context) {
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION,
|
||||||
|
PreferenceConstants.NAME_STYLE_CAPITALIZATION_CAMEL_CASE, null);
|
||||||
|
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
||||||
|
String prefix = bool ?
|
||||||
|
preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is", null) : //$NON-NLS-1$
|
||||||
|
preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_GETTER_PREFIX, "get", null); //$NON-NLS-1$
|
||||||
|
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_GETTER_SUFFIX, "", null); //$NON-NLS-1$
|
||||||
|
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
||||||
|
return adjustName(composer.compose(baseName), excluded, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a suggested name for a setter that is guaranteed to be a valid identifier
|
||||||
|
* and not collide with a set of given names.
|
||||||
|
*
|
||||||
|
* @param baseName the name used as an inspiration
|
||||||
|
* @param excluded the set of excluded names, can be {@code null}
|
||||||
|
* @param context the translation unit for which the code is intended, can be {@code null}
|
||||||
|
* @return the suggested name, or {@code null} if all possible names are taken
|
||||||
|
*/
|
||||||
|
public static String suggestSetterName(String baseName, Set<String> excluded, ITranslationUnit context) {
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_SETTER_CAPITALIZATION,
|
||||||
|
PreferenceConstants.NAME_STYLE_CAPITALIZATION_CAMEL_CASE, null);
|
||||||
|
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_SETTER_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
||||||
|
String prefix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_SETTER_PREFIX, "set", null); //$NON-NLS-1$
|
||||||
|
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_SETTER_SUFFIX, "", null); //$NON-NLS-1$
|
||||||
|
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
||||||
|
return adjustName(composer.compose(baseName), excluded, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a suggested name for a function parameter that is guaranteed to be a valid identifier
|
||||||
|
* and not collide with a set of given names.
|
||||||
|
*
|
||||||
|
* @param baseName the name used as an inspiration
|
||||||
|
* @param excluded the set of excluded names, can be {@code null}
|
||||||
|
* @param context the translation unit for which the code is intended, can be {@code null}
|
||||||
|
* @return the suggested name, or {@code null} if all possible names are taken
|
||||||
|
*/
|
||||||
|
public static String suggestParameterName(String baseName, Set<String> excluded, ITranslationUnit context) {
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_VARIABLE_CAPITALIZATION,
|
||||||
|
PreferenceConstants.NAME_STYLE_CAPITALIZATION_ORIGINAL, null);
|
||||||
|
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_VARIABLE_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
||||||
|
String prefix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_VARIABLE_PREFIX, "", null); //$NON-NLS-1$
|
||||||
|
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_VARIABLE_SUFFIX, "", null); //$NON-NLS-1$
|
||||||
|
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
||||||
|
return adjustName(composer.compose(baseName), excluded, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a suggested name for a method that is guaranteed to be a valid identifier
|
||||||
|
* and not collide with a set of given names.
|
||||||
|
*
|
||||||
|
* @param baseName the name used as an inspiration
|
||||||
|
* @param excluded the set of excluded names, can be {@code null}
|
||||||
|
* @param context the translation unit for which the code is intended, can be {@code null}
|
||||||
|
* @return the suggested name, or {@code null} if all possible names are taken
|
||||||
|
*/
|
||||||
|
public static String suggestMethodName(String baseName, Set<String> excluded, ITranslationUnit context) {
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_METHOD_CAPITALIZATION,
|
||||||
|
PreferenceConstants.NAME_STYLE_CAPITALIZATION_ORIGINAL, null);
|
||||||
|
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_METHOD_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
||||||
|
String prefix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_METHOD_PREFIX, "", null); //$NON-NLS-1$
|
||||||
|
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.NAME_STYLE_METHOD_SUFFIX, "", null); //$NON-NLS-1$
|
||||||
|
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
||||||
|
return adjustName(composer.compose(baseName), excluded, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks is the given name is valid and, if not, tries to adjust it by adding a numeric suffix
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* @param name the name to check and, possibly, adjust
|
||||||
|
* @param namesToAvoid the set of names to avoid
|
||||||
|
* @param context the translation unit, can be {@code null}
|
||||||
|
* @return the adjusted name, or <code>null</code> if a valid name could not be generated.
|
||||||
|
*/
|
||||||
|
private static String adjustName(String name, Set<String> namesToAvoid, ITranslationUnit context) {
|
||||||
|
ILanguage language = null;
|
||||||
|
try {
|
||||||
|
if (context != null)
|
||||||
|
language = context.getLanguage();
|
||||||
|
} catch (CoreException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
return adjustName(name, namesToAvoid, language);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks is the given name is valid and, if not, tries to adjust it by adding a numeric suffix
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* @param name the name to check and, possibly, adjust
|
||||||
|
* @param namesToAvoid the set of names to avoid
|
||||||
|
* @param language the language of the translation unit, can be {@code null}
|
||||||
|
* @return the adjusted name, or <code>null</code> if a valid name could not be generated.
|
||||||
|
*/
|
||||||
|
private static String adjustName(String name, Set<String> namesToAvoid, ILanguage language) {
|
||||||
|
if (language == null) {
|
||||||
|
language = GPPLanguage.getDefault();
|
||||||
|
}
|
||||||
|
String originalName = name;
|
||||||
|
if (!isValidIdentifier(name, language)) {
|
||||||
|
if ("class".equals(name)) { //$NON-NLS-1$
|
||||||
|
name = "clazz"; //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
name = '_' + name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int numTries = namesToAvoid != null ? namesToAvoid.size() + 1 : 1;
|
||||||
|
for (int i = 1; i <= numTries; i++) {
|
||||||
|
if ((namesToAvoid == null || !namesToAvoid.contains(name)) &&
|
||||||
|
isValidIdentifier(name, language)) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
name = originalName + i;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidIdentifier(String name, ILanguage language) {
|
||||||
|
if (language instanceof AbstractCLikeLanguage) {
|
||||||
|
return CConventions.validateIdentifier(name, (AbstractCLikeLanguage) language).isOK();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the trimmed field name. Leading and trailing non-alphanumeric characters are trimmed.
|
||||||
|
* If the first word of the name consists of a single letter and the name contains more than
|
||||||
|
* one word, the first word is removed.
|
||||||
|
*
|
||||||
|
* @param fieldName a field name to trim
|
||||||
|
* @return the trimmed field name
|
||||||
|
*/
|
||||||
|
public static String trimFieldName(String fieldName) {
|
||||||
|
CBreakIterator iterator = new CBreakIterator();
|
||||||
|
iterator.setText(fieldName);
|
||||||
|
int firstWordStart = -1;
|
||||||
|
int firstWordEnd = -1;
|
||||||
|
int secondWordStart = -1;
|
||||||
|
int lastWordEnd = -1;
|
||||||
|
int end;
|
||||||
|
for (int start = iterator.first(); (end = iterator.next()) != BreakIterator.DONE; start = end) {
|
||||||
|
if (Character.isLetterOrDigit(fieldName.charAt(start))) {
|
||||||
|
int pos = end;
|
||||||
|
while (--pos >= start && !Character.isLetterOrDigit(fieldName.charAt(pos))) {
|
||||||
|
}
|
||||||
|
lastWordEnd = pos + 1;
|
||||||
|
if (firstWordStart < 0) {
|
||||||
|
firstWordStart = start;
|
||||||
|
firstWordEnd = lastWordEnd;
|
||||||
|
} else if (secondWordStart < 0) {
|
||||||
|
secondWordStart = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Skip the first word if it consists of a single letter and the name contains more than
|
||||||
|
// one word.
|
||||||
|
if (firstWordStart >= 0 && firstWordStart + 1 == firstWordEnd && secondWordStart >= 0) {
|
||||||
|
firstWordStart = secondWordStart;
|
||||||
|
}
|
||||||
|
if (firstWordStart < 0) {
|
||||||
|
return fieldName;
|
||||||
|
} else {
|
||||||
|
return fieldName.substring(firstWordStart, lastWordEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,9 +417,10 @@ public class CPluginImages {
|
||||||
/** @deprecated as of CDT 8.0. Use {@link CDTSharedImages#getImageDescriptor(String)}. */
|
/** @deprecated as of CDT 8.0. Use {@link CDTSharedImages#getImageDescriptor(String)}. */
|
||||||
@Deprecated public static final ImageDescriptor DESC_REFACTORING_INFO= createManaged ( T_OBJ, IMG_OBJS_REFACTORING_INFO);
|
@Deprecated public static final ImageDescriptor DESC_REFACTORING_INFO= createManaged ( T_OBJ, IMG_OBJS_REFACTORING_INFO);
|
||||||
|
|
||||||
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD= createUnManaged(T_WIZBAN, "fieldrefact_wiz.gif"); //$NON-NLS-1$
|
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TU= createUnManaged(T_WIZBAN, "refactor_tu_wiz.png"); //$NON-NLS-1$
|
||||||
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD= createUnManaged(T_WIZBAN, "methrefact_wiz.gif"); //$NON-NLS-1$
|
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_FIELD= createUnManaged(T_WIZBAN, "refactor_field_wiz.png"); //$NON-NLS-1$
|
||||||
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE= createUnManaged(T_WIZBAN, "typerefact_wiz.gif"); //$NON-NLS-1$
|
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_METHOD= createUnManaged(T_WIZBAN, "refactor_method_wiz.png"); //$NON-NLS-1$
|
||||||
|
public static final ImageDescriptor DESC_WIZBAN_REFACTOR_TYPE= createUnManaged(T_WIZBAN, "refactor_type_wiz.png"); //$NON-NLS-1$
|
||||||
|
|
||||||
public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE= createUnManaged(T_OBJ, "change.gif"); //$NON-NLS-1$
|
public static final ImageDescriptor DESC_OBJS_DEFAULT_CHANGE= createUnManaged(T_OBJ, "change.gif"); //$NON-NLS-1$
|
||||||
public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE= createUnManaged(T_OBJ, "composite_change.gif"); //$NON-NLS-1$
|
public static final ImageDescriptor DESC_OBJS_COMPOSITE_CHANGE= createUnManaged(T_OBJ, "composite_change.gif"); //$NON-NLS-1$
|
||||||
|
|
|
@ -120,6 +120,7 @@ public interface ICHelpContextIds {
|
||||||
public static final String RENAME_TYPE_WIZARD_PAGE= PREFIX + "rename_type_wizard_page_context"; //$NON-NLS-1$
|
public static final String RENAME_TYPE_WIZARD_PAGE= PREFIX + "rename_type_wizard_page_context"; //$NON-NLS-1$
|
||||||
public static final String RENAME_FIELD_WIZARD_PAGE= PREFIX + "rename_field_wizard_page_context"; //$NON-NLS-1$
|
public static final String RENAME_FIELD_WIZARD_PAGE= PREFIX + "rename_field_wizard_page_context"; //$NON-NLS-1$
|
||||||
public static final String RENAME_RESOURCE_WIZARD_PAGE= PREFIX + "rename_resource_wizard_page_context"; //$NON-NLS-1$
|
public static final String RENAME_RESOURCE_WIZARD_PAGE= PREFIX + "rename_resource_wizard_page_context"; //$NON-NLS-1$
|
||||||
|
public static final String EXTRACT_FUNCTION_WIZARD_PAGE= PREFIX + "extract_function_wizard_page_context"; //$NON-NLS-1$
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
public static final String EDIT_TEMPLATE_DIALOG = PREFIX + "edit_template_dialog_context"; //$NON-NLS-1$
|
public static final String EDIT_TEMPLATE_DIALOG = PREFIX + "edit_template_dialog_context"; //$NON-NLS-1$
|
||||||
|
|
|
@ -0,0 +1,452 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2005, 2012 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
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.dialogs;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
|
||||||
|
import org.eclipse.jface.viewers.CellEditor;
|
||||||
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||||
|
import org.eclipse.jface.viewers.TableViewer;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.FocusAdapter;
|
||||||
|
import org.eclipse.swt.events.FocusEvent;
|
||||||
|
import org.eclipse.swt.events.KeyAdapter;
|
||||||
|
import org.eclipse.swt.events.KeyEvent;
|
||||||
|
import org.eclipse.swt.events.ModifyEvent;
|
||||||
|
import org.eclipse.swt.events.ModifyListener;
|
||||||
|
import org.eclipse.swt.events.MouseAdapter;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.events.TraverseEvent;
|
||||||
|
import org.eclipse.swt.events.TraverseListener;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>TableTextCellEditor</code> is a copy of TextCellEditor, with the
|
||||||
|
* following changes:
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li> modify events are sent out as the text is changed, and not only after
|
||||||
|
* editing is done </li>
|
||||||
|
*
|
||||||
|
* <li>a content assistant is supported</li>
|
||||||
|
*
|
||||||
|
* <li>the user can go to the next/previous row with up and down keys</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class TableTextCellEditor extends CellEditor {
|
||||||
|
public interface IActivationListener {
|
||||||
|
public void activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final TableViewer fTableViewer;
|
||||||
|
private final int fColumn;
|
||||||
|
private final String fProperty;
|
||||||
|
/**
|
||||||
|
* The editor's value on activation. This value is reset to the
|
||||||
|
* cell when the editor is left via ESC key.
|
||||||
|
*/
|
||||||
|
String fOriginalValue;
|
||||||
|
SubjectControlContentAssistant fContentAssistant;
|
||||||
|
private IActivationListener fActivationListener;
|
||||||
|
|
||||||
|
protected Text text;
|
||||||
|
|
||||||
|
private boolean isSelection;
|
||||||
|
private boolean isDeleteable;
|
||||||
|
private boolean isSelectable;
|
||||||
|
|
||||||
|
private static final int defaultStyle = SWT.SINGLE;
|
||||||
|
private ModifyListener fModifyListener;
|
||||||
|
|
||||||
|
public TableTextCellEditor(TableViewer tableViewer, int column) {
|
||||||
|
super(tableViewer.getTable(), defaultStyle);
|
||||||
|
fTableViewer= tableViewer;
|
||||||
|
fColumn= column;
|
||||||
|
fProperty= (String) tableViewer.getColumnProperties()[column];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activate() {
|
||||||
|
super.activate();
|
||||||
|
if (fActivationListener != null)
|
||||||
|
fActivationListener.activate();
|
||||||
|
fOriginalValue= text.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireModifyEvent(Object newValue) {
|
||||||
|
fTableViewer.getCellModifier().modify(
|
||||||
|
((IStructuredSelection) fTableViewer.getSelection()).getFirstElement(),
|
||||||
|
fProperty, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void focusLost() {
|
||||||
|
if (fContentAssistant != null && fContentAssistant.hasProposalPopupFocus()) {
|
||||||
|
// skip focus lost if it went to the content assist popup
|
||||||
|
} else {
|
||||||
|
super.focusLost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentAssistant(SubjectControlContentAssistant assistant) {
|
||||||
|
fContentAssistant= assistant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivationListener(IActivationListener listener) {
|
||||||
|
fActivationListener= listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Text getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkDeleteable() {
|
||||||
|
boolean oldIsDeleteable = isDeleteable;
|
||||||
|
isDeleteable = isDeleteEnabled();
|
||||||
|
if (oldIsDeleteable != isDeleteable) {
|
||||||
|
fireEnablementChanged(DELETE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkSelectable() {
|
||||||
|
boolean oldIsSelectable = isSelectable;
|
||||||
|
isSelectable = isSelectAllEnabled();
|
||||||
|
if (oldIsSelectable != isSelectable) {
|
||||||
|
fireEnablementChanged(SELECT_ALL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkSelection() {
|
||||||
|
boolean oldIsSelection = isSelection;
|
||||||
|
isSelection = text.getSelectionCount() > 0;
|
||||||
|
if (oldIsSelection != isSelection) {
|
||||||
|
fireEnablementChanged(COPY);
|
||||||
|
fireEnablementChanged(CUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModifyListener getModifyListener() {
|
||||||
|
if (fModifyListener == null) {
|
||||||
|
fModifyListener = new ModifyListener() {
|
||||||
|
@Override
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
editOccured(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return fModifyListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* Method declared on CellEditor.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Control createControl(Composite parent) {
|
||||||
|
text= new Text(parent, getStyle());
|
||||||
|
text.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
handleDefaultSelection(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
text.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
// support switching rows while editing:
|
||||||
|
if (e.stateMask == SWT.MOD1 || e.stateMask == SWT.MOD2) {
|
||||||
|
if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
|
||||||
|
// allow starting multi-selection even if in edit mode
|
||||||
|
deactivate();
|
||||||
|
e.doit= false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.stateMask != SWT.NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case SWT.ARROW_DOWN:
|
||||||
|
e.doit= false;
|
||||||
|
int nextRow= fTableViewer.getTable().getSelectionIndex() + 1;
|
||||||
|
if (nextRow >= fTableViewer.getTable().getItemCount())
|
||||||
|
break;
|
||||||
|
editRow(nextRow);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SWT.ARROW_UP:
|
||||||
|
e.doit= false;
|
||||||
|
int prevRow= fTableViewer.getTable().getSelectionIndex() - 1;
|
||||||
|
if (prevRow < 0)
|
||||||
|
break;
|
||||||
|
editRow(prevRow);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SWT.F2:
|
||||||
|
e.doit= false;
|
||||||
|
deactivate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editRow(int row) {
|
||||||
|
fTableViewer.getTable().setSelection(row);
|
||||||
|
IStructuredSelection newSelection= (IStructuredSelection) fTableViewer.getSelection();
|
||||||
|
if (newSelection.size() == 1)
|
||||||
|
fTableViewer.editElement(newSelection.getFirstElement(), fColumn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
text.addKeyListener(new KeyAdapter() {
|
||||||
|
// hook key pressed - see PR 14201
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
keyReleaseOccured(e);
|
||||||
|
|
||||||
|
// as a result of processing the above call, clients may have
|
||||||
|
// disposed this cell editor
|
||||||
|
if ((getControl() == null) || getControl().isDisposed())
|
||||||
|
return;
|
||||||
|
checkSelection(); // see explaination below
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
text.addTraverseListener(new TraverseListener() {
|
||||||
|
@Override
|
||||||
|
public void keyTraversed(TraverseEvent e) {
|
||||||
|
if (e.detail == SWT.TRAVERSE_ESCAPE
|
||||||
|
|| e.detail == SWT.TRAVERSE_RETURN) {
|
||||||
|
e.doit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// We really want a selection listener but it is not supported so we
|
||||||
|
// use a key listener and a mouse listener to know when selection changes
|
||||||
|
// may have occurred
|
||||||
|
text.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseUp(MouseEvent e) {
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
text.addFocusListener(new FocusAdapter() {
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
e.display.asyncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// without the asyncExec, focus has not had a chance to go to the content assist proposals
|
||||||
|
TableTextCellEditor.this.focusLost();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
text.setFont(parent.getFont());
|
||||||
|
text.setBackground(parent.getBackground());
|
||||||
|
text.setText("");//$NON-NLS-1$
|
||||||
|
text.addModifyListener(getModifyListener());
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fireCancelEditor() {
|
||||||
|
/* bug 58540: change signature refactoring interaction: validate as you type [refactoring] */
|
||||||
|
text.setText(fOriginalValue);
|
||||||
|
super.fireApplyEditorValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>TextCellEditor</code> implementation of
|
||||||
|
* this <code>CellEditor</code> framework method returns
|
||||||
|
* the text string.
|
||||||
|
*
|
||||||
|
* @return the text string
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Object doGetValue() {
|
||||||
|
return text.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doSetFocus() {
|
||||||
|
if (text != null) {
|
||||||
|
text.selectAll();
|
||||||
|
text.setFocus();
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <code>TextCellEditor2</code> implementation of
|
||||||
|
* this <code>CellEditor</code> framework method accepts
|
||||||
|
* a text string (type <code>String</code>).
|
||||||
|
*
|
||||||
|
* @param value a text string (type <code>String</code>)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void doSetValue(Object value) {
|
||||||
|
Assert.isTrue(text != null && (value instanceof String));
|
||||||
|
text.removeModifyListener(getModifyListener());
|
||||||
|
text.setText((String) value);
|
||||||
|
text.addModifyListener(getModifyListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a modify event that occurred in this text cell editor.
|
||||||
|
* This framework method performs validation and sets the error message
|
||||||
|
* accordingly, and then reports a change via <code>fireEditorValueChanged</code>.
|
||||||
|
* Subclasses should call this method at appropriate times. Subclasses
|
||||||
|
* may extend or reimplement.
|
||||||
|
*
|
||||||
|
* @param e the SWT modify event
|
||||||
|
*/
|
||||||
|
protected void editOccured(ModifyEvent e) {
|
||||||
|
String value = text.getText();
|
||||||
|
boolean oldValidState = isValueValid();
|
||||||
|
boolean newValidState = isCorrect(value);
|
||||||
|
if (!newValidState) {
|
||||||
|
// Try to insert the current value into the error message.
|
||||||
|
setErrorMessage(NLS.bind(getErrorMessage(), value));
|
||||||
|
}
|
||||||
|
valueChanged(oldValidState, newValidState);
|
||||||
|
fireModifyEvent(text.getText()); // update model on-the-fly
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LayoutData getLayoutData() {
|
||||||
|
return new LayoutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleDefaultSelection(SelectionEvent event) {
|
||||||
|
// same with enter-key handling code in keyReleaseOccured(e);
|
||||||
|
fireApplyEditorValue();
|
||||||
|
deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCopyEnabled() {
|
||||||
|
if (text == null || text.isDisposed())
|
||||||
|
return false;
|
||||||
|
return text.getSelectionCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCutEnabled() {
|
||||||
|
if (text == null || text.isDisposed())
|
||||||
|
return false;
|
||||||
|
return text.getSelectionCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeleteEnabled() {
|
||||||
|
if (text == null || text.isDisposed())
|
||||||
|
return false;
|
||||||
|
return text.getSelectionCount() > 0
|
||||||
|
|| text.getCaretPosition() < text.getCharCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPasteEnabled() {
|
||||||
|
if (text == null || text.isDisposed())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelectAllEnabled() {
|
||||||
|
if (text == null || text.isDisposed())
|
||||||
|
return false;
|
||||||
|
return text.getCharCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void keyReleaseOccured(KeyEvent keyEvent) {
|
||||||
|
if (keyEvent.character == '\r') { // Return key
|
||||||
|
// Enter is handled in handleDefaultSelection.
|
||||||
|
// Do not apply the editor value in response to an Enter key event
|
||||||
|
// since this can be received from the IME when the intent is -not-
|
||||||
|
// to apply the value.
|
||||||
|
// See bug 39074 [CellEditors] [DBCS] canna input mode fires bogus event from Text Control
|
||||||
|
//
|
||||||
|
// An exception is made for Ctrl+Enter for multi-line texts, since
|
||||||
|
// a default selection event is not sent in this case.
|
||||||
|
if (text != null && !text.isDisposed() && (text.getStyle() & SWT.MULTI) != 0) {
|
||||||
|
if ((keyEvent.stateMask & SWT.CTRL) != 0) {
|
||||||
|
super.keyReleaseOccured(keyEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.keyReleaseOccured(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performCopy() {
|
||||||
|
text.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performCut() {
|
||||||
|
text.cut();
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performDelete() {
|
||||||
|
if (text.getSelectionCount() > 0) {
|
||||||
|
// remove the contents of the current selection
|
||||||
|
text.insert(""); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
// remove the next character
|
||||||
|
int pos = text.getCaretPosition();
|
||||||
|
if (pos < text.getCharCount()) {
|
||||||
|
text.setSelection(pos, pos + 1);
|
||||||
|
text.insert(""); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performPaste() {
|
||||||
|
text.paste();
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
checkSelectable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performSelectAll() {
|
||||||
|
text.selectAll();
|
||||||
|
checkSelection();
|
||||||
|
checkDeleteable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean dependsOnExternalFocusListener() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,527 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2005, 2011 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
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.dialogs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.commands.Command;
|
||||||
|
import org.eclipse.core.commands.CommandManager;
|
||||||
|
import org.eclipse.core.commands.ParameterizedCommand;
|
||||||
|
import org.eclipse.core.commands.common.NotDefinedException;
|
||||||
|
import org.eclipse.core.commands.contexts.ContextManager;
|
||||||
|
import org.eclipse.jface.bindings.BindingManager;
|
||||||
|
import org.eclipse.jface.bindings.Scheme;
|
||||||
|
import org.eclipse.jface.bindings.TriggerSequence;
|
||||||
|
import org.eclipse.jface.bindings.keys.KeySequence;
|
||||||
|
import org.eclipse.jface.bindings.keys.SWTKeySupport;
|
||||||
|
import org.eclipse.jface.util.Util;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.StyledText;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
|
import org.eclipse.swt.events.FocusEvent;
|
||||||
|
import org.eclipse.swt.events.FocusListener;
|
||||||
|
import org.eclipse.swt.events.KeyAdapter;
|
||||||
|
import org.eclipse.swt.events.KeyEvent;
|
||||||
|
import org.eclipse.swt.events.MouseAdapter;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.widgets.Combo;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.commands.ICommandService;
|
||||||
|
import org.eclipse.ui.keys.IBindingService;
|
||||||
|
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
|
||||||
|
|
||||||
|
import com.ibm.icu.text.BreakIterator;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CWordIterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for camelCase-aware sub-word navigation in dialog fields.
|
||||||
|
*/
|
||||||
|
public class TextFieldNavigationHandler {
|
||||||
|
|
||||||
|
public static void install(Text text) {
|
||||||
|
new FocusHandler(new TextNavigable(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void install(StyledText styledText) {
|
||||||
|
new FocusHandler(new StyledTextNavigable(styledText));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void install(Combo combo) {
|
||||||
|
new FocusHandler(new ComboNavigable(combo));
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class WorkaroundNavigable extends Navigable {
|
||||||
|
/* workarounds for:
|
||||||
|
* - bug 103630: Add API: Combo#getCaretPosition()
|
||||||
|
* - bug 106024: Text#setSelection(int, int) does not handle start > end with SWT.SINGLE
|
||||||
|
*/
|
||||||
|
Point fLastSelection;
|
||||||
|
int fCaretPosition;
|
||||||
|
|
||||||
|
void selectionChanged() {
|
||||||
|
Point selection= getSelection();
|
||||||
|
if (selection.equals(fLastSelection)) {
|
||||||
|
// leave caret position
|
||||||
|
} else if (selection.x == selection.y) { //empty range
|
||||||
|
fCaretPosition= selection.x;
|
||||||
|
} else if (fLastSelection.y == selection.y) {
|
||||||
|
fCaretPosition= selection.x; //same end -> assume caret at start
|
||||||
|
} else {
|
||||||
|
fCaretPosition= selection.y;
|
||||||
|
}
|
||||||
|
fLastSelection= selection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class Navigable {
|
||||||
|
public abstract Control getControl();
|
||||||
|
|
||||||
|
public abstract String getText();
|
||||||
|
|
||||||
|
public abstract void setText(String text);
|
||||||
|
|
||||||
|
public abstract Point getSelection();
|
||||||
|
|
||||||
|
public abstract void setSelection(int start, int end);
|
||||||
|
|
||||||
|
public abstract int getCaretPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TextNavigable extends WorkaroundNavigable {
|
||||||
|
static final boolean BUG_106024_TEXT_SELECTION=
|
||||||
|
"win32".equals(SWT.getPlatform()) //$NON-NLS-1$
|
||||||
|
// on carbon, getCaretPosition() always returns getSelection().x
|
||||||
|
|| Util.isMac();
|
||||||
|
|
||||||
|
private final Text fText;
|
||||||
|
|
||||||
|
public TextNavigable(Text text) {
|
||||||
|
fText= text;
|
||||||
|
// workaround for bug 106024:
|
||||||
|
if (BUG_106024_TEXT_SELECTION) {
|
||||||
|
fLastSelection= getSelection();
|
||||||
|
fCaretPosition= fLastSelection.y;
|
||||||
|
fText.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
selectionChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fText.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseUp(MouseEvent e) {
|
||||||
|
selectionChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Control getControl() {
|
||||||
|
return fText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return fText.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text) {
|
||||||
|
fText.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Point getSelection() {
|
||||||
|
return fText.getSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCaretPosition() {
|
||||||
|
if (BUG_106024_TEXT_SELECTION) {
|
||||||
|
selectionChanged();
|
||||||
|
return fCaretPosition;
|
||||||
|
} else {
|
||||||
|
return fText.getCaretPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelection(int start, int end) {
|
||||||
|
fText.setSelection(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StyledTextNavigable extends Navigable {
|
||||||
|
private final StyledText fStyledText;
|
||||||
|
|
||||||
|
public StyledTextNavigable(StyledText styledText) {
|
||||||
|
fStyledText= styledText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Control getControl() {
|
||||||
|
return fStyledText;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return fStyledText.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text) {
|
||||||
|
fStyledText.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Point getSelection() {
|
||||||
|
return fStyledText.getSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCaretPosition() {
|
||||||
|
return fStyledText.getCaretOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelection(int start, int end) {
|
||||||
|
fStyledText.setSelection(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ComboNavigable extends WorkaroundNavigable {
|
||||||
|
private final Combo fCombo;
|
||||||
|
|
||||||
|
public ComboNavigable(Combo combo) {
|
||||||
|
fCombo= combo;
|
||||||
|
// workaround for bug 103630:
|
||||||
|
fLastSelection= getSelection();
|
||||||
|
fCaretPosition= fLastSelection.y;
|
||||||
|
fCombo.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
selectionChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fCombo.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseUp(MouseEvent e) {
|
||||||
|
selectionChanged();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Control getControl() {
|
||||||
|
return fCombo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return fCombo.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text) {
|
||||||
|
fCombo.setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Point getSelection() {
|
||||||
|
return fCombo.getSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCaretPosition() {
|
||||||
|
selectionChanged();
|
||||||
|
return fCaretPosition;
|
||||||
|
// return fCombo.getCaretPosition(); // not available: bug 103630
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelection(int start, int end) {
|
||||||
|
fCombo.setSelection(new Point(start, end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FocusHandler implements FocusListener {
|
||||||
|
private static final String EMPTY_TEXT= ""; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private final CWordIterator fIterator;
|
||||||
|
private final Navigable fNavigable;
|
||||||
|
private KeyAdapter fKeyListener;
|
||||||
|
|
||||||
|
private FocusHandler(Navigable navigable) {
|
||||||
|
fIterator= new CWordIterator();
|
||||||
|
fNavigable= navigable;
|
||||||
|
|
||||||
|
Control control= navigable.getControl();
|
||||||
|
control.addFocusListener(this);
|
||||||
|
if (control.isFocusControl())
|
||||||
|
activate();
|
||||||
|
control.addDisposeListener(new DisposeListener() {
|
||||||
|
@Override
|
||||||
|
public void widgetDisposed(DisposeEvent e) {
|
||||||
|
deactivate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void activate() {
|
||||||
|
fNavigable.getControl().addKeyListener(getKeyListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deactivate() {
|
||||||
|
if (fKeyListener != null) {
|
||||||
|
Control control= fNavigable.getControl();
|
||||||
|
if (! control.isDisposed())
|
||||||
|
control.removeKeyListener(fKeyListener);
|
||||||
|
fKeyListener= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyAdapter getKeyListener() {
|
||||||
|
if (fKeyListener == null) {
|
||||||
|
fKeyListener= new KeyAdapter() {
|
||||||
|
private final boolean IS_WORKAROUND= (fNavigable instanceof ComboNavigable)
|
||||||
|
|| (fNavigable instanceof TextNavigable && TextNavigable.BUG_106024_TEXT_SELECTION);
|
||||||
|
private List<Submission> fSubmissions;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if (IS_WORKAROUND) {
|
||||||
|
if (e.keyCode == SWT.ARROW_LEFT && e.stateMask == SWT.MOD2) {
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
if (caretPosition != 0) {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
if (caretPosition == selection.x)
|
||||||
|
fNavigable.setSelection(selection.y, caretPosition - 1);
|
||||||
|
else
|
||||||
|
fNavigable.setSelection(selection.x, caretPosition - 1);
|
||||||
|
}
|
||||||
|
e.doit= false;
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (e.keyCode == SWT.ARROW_RIGHT && e.stateMask == SWT.MOD2) {
|
||||||
|
String text= fNavigable.getText();
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
if (caretPosition != text.length()) {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
if (caretPosition == selection.y)
|
||||||
|
fNavigable.setSelection(selection.x, caretPosition + 1);
|
||||||
|
else
|
||||||
|
fNavigable.setSelection(selection.y, caretPosition + 1);
|
||||||
|
}
|
||||||
|
e.doit= false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
|
||||||
|
KeySequence keySequence = KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator));
|
||||||
|
for (Submission submission : getSubmissions()) {
|
||||||
|
TriggerSequence[] triggerSequences= submission.getTriggerSequences();
|
||||||
|
for (int i= 0; i < triggerSequences.length; i++) {
|
||||||
|
if (triggerSequences[i].equals(keySequence)) { // XXX does not work for multi-stroke bindings
|
||||||
|
e.doit= false;
|
||||||
|
submission.execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Submission> getSubmissions() {
|
||||||
|
if (fSubmissions != null)
|
||||||
|
return fSubmissions;
|
||||||
|
|
||||||
|
fSubmissions= new ArrayList<Submission>();
|
||||||
|
|
||||||
|
ICommandService commandService= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
|
||||||
|
IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
|
||||||
|
if (commandService == null || bindingService == null)
|
||||||
|
return fSubmissions;
|
||||||
|
|
||||||
|
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=184502 ,
|
||||||
|
// similar to CodeAssistAdvancedConfigurationBlock.getKeyboardShortcut(..):
|
||||||
|
BindingManager localBindingManager= new BindingManager(new ContextManager(), new CommandManager());
|
||||||
|
final Scheme[] definedSchemes= bindingService.getDefinedSchemes();
|
||||||
|
if (definedSchemes != null) {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < definedSchemes.length; i++) {
|
||||||
|
Scheme scheme= definedSchemes[i];
|
||||||
|
Scheme localSchemeCopy= localBindingManager.getScheme(scheme.getId());
|
||||||
|
localSchemeCopy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId());
|
||||||
|
}
|
||||||
|
} catch (final NotDefinedException e) {
|
||||||
|
CUIPlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
localBindingManager.setLocale(bindingService.getLocale());
|
||||||
|
localBindingManager.setPlatform(bindingService.getPlatform());
|
||||||
|
|
||||||
|
localBindingManager.setBindings(bindingService.getBindings());
|
||||||
|
try {
|
||||||
|
Scheme activeScheme= bindingService.getActiveScheme();
|
||||||
|
if (activeScheme != null)
|
||||||
|
localBindingManager.setActiveScheme(activeScheme);
|
||||||
|
} catch (NotDefinedException e) {
|
||||||
|
CUIPlugin.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_NEXT)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
fIterator.setText(fNavigable.getText());
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
int newCaret= fIterator.following(caretPosition);
|
||||||
|
if (newCaret != BreakIterator.DONE) {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
if (caretPosition == selection.y)
|
||||||
|
fNavigable.setSelection(selection.x, newCaret);
|
||||||
|
else
|
||||||
|
fNavigable.setSelection(selection.y, newCaret);
|
||||||
|
}
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.SELECT_WORD_PREVIOUS)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
fIterator.setText(fNavigable.getText());
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
int newCaret= fIterator.preceding(caretPosition);
|
||||||
|
if (newCaret != BreakIterator.DONE) {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
if (caretPosition == selection.x)
|
||||||
|
fNavigable.setSelection(selection.y, newCaret);
|
||||||
|
else
|
||||||
|
fNavigable.setSelection(selection.x, newCaret);
|
||||||
|
}
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_NEXT)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
fIterator.setText(fNavigable.getText());
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
int newCaret= fIterator.following(caretPosition);
|
||||||
|
if (newCaret != BreakIterator.DONE)
|
||||||
|
fNavigable.setSelection(newCaret, newCaret);
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.WORD_PREVIOUS)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
fIterator.setText(fNavigable.getText());
|
||||||
|
int caretPosition= fNavigable.getCaretPosition();
|
||||||
|
int newCaret= fIterator.preceding(caretPosition);
|
||||||
|
if (newCaret != BreakIterator.DONE)
|
||||||
|
fNavigable.setSelection(newCaret, newCaret);
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_NEXT_WORD)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
String text= fNavigable.getText();
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
if (selection.x != selection.y) {
|
||||||
|
start= selection.x;
|
||||||
|
end= selection.y;
|
||||||
|
} else {
|
||||||
|
fIterator.setText(text);
|
||||||
|
start= fNavigable.getCaretPosition();
|
||||||
|
end= fIterator.following(start);
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
if (end == BreakIterator.DONE)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fNavigable.setText(text.substring(0, start) + text.substring(end));
|
||||||
|
fNavigable.setSelection(start, start);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fSubmissions.add(new Submission(getKeyBindings(localBindingManager, commandService, ITextEditorActionDefinitionIds.DELETE_PREVIOUS_WORD)) {
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
Point selection= fNavigable.getSelection();
|
||||||
|
String text= fNavigable.getText();
|
||||||
|
int start;
|
||||||
|
int end;
|
||||||
|
if (selection.x != selection.y) {
|
||||||
|
start= selection.x;
|
||||||
|
end= selection.y;
|
||||||
|
} else {
|
||||||
|
fIterator.setText(text);
|
||||||
|
end= fNavigable.getCaretPosition();
|
||||||
|
start= fIterator.preceding(end);
|
||||||
|
fIterator.setText(EMPTY_TEXT);
|
||||||
|
if (start == BreakIterator.DONE)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fNavigable.setText(text.substring(0, start) + text.substring(end));
|
||||||
|
fNavigable.setSelection(start, start);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return fSubmissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TriggerSequence[] getKeyBindings(BindingManager localBindingManager, ICommandService commandService, String commandID) {
|
||||||
|
Command command= commandService.getCommand(commandID);
|
||||||
|
ParameterizedCommand pCmd= new ParameterizedCommand(command, null);
|
||||||
|
return localBindingManager.getActiveBindingsDisregardingContextFor(pCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return fKeyListener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract static class Submission {
|
||||||
|
private TriggerSequence[] fTriggerSequences;
|
||||||
|
|
||||||
|
public Submission(TriggerSequence[] triggerSequences) {
|
||||||
|
fTriggerSequences= triggerSequences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TriggerSequence[] getTriggerSequences() {
|
||||||
|
return fTriggerSequences;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - initial API and implementation
|
* QNX Software Systems - initial API and implementation
|
||||||
* Sergey Prigogin, Google
|
* Sergey Prigogin (Google)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -43,19 +43,23 @@ import org.eclipse.swt.graphics.Color;
|
||||||
import org.eclipse.swt.graphics.Point;
|
import org.eclipse.swt.graphics.Point;
|
||||||
import org.eclipse.swt.graphics.RGB;
|
import org.eclipse.swt.graphics.RGB;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
||||||
import org.eclipse.ui.texteditor.AbstractTextEditor;
|
import org.eclipse.ui.texteditor.AbstractTextEditor;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;
|
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;
|
||||||
|
import org.eclipse.cdt.ui.text.ICColorConstants;
|
||||||
|
import org.eclipse.cdt.ui.text.IColorManager;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source viewer for C/C++ et al.
|
* Source viewer for C/C++ et al.
|
||||||
*/
|
*/
|
||||||
public class CSourceViewer extends ProjectionViewer implements IPropertyChangeListener {
|
public class CSourceViewer extends ProjectionViewer implements IPropertyChangeListener {
|
||||||
|
|
||||||
/** Show outline operation id. */
|
/** Show outline operation id. */
|
||||||
public static final int SHOW_OUTLINE= 101;
|
public static final int SHOW_OUTLINE= 101;
|
||||||
/** Show type hierarchy operation id. */
|
/** Show type hierarchy operation id. */
|
||||||
|
@ -620,4 +624,32 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
|
||||||
cmd.event= null;
|
cmd.event= null;
|
||||||
cmd.text= null;
|
cmd.text= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the viewer's background color to the given control's background color.
|
||||||
|
* The background color is <em>only</em> set if it's visibly distinct from the
|
||||||
|
* default Java source text color.
|
||||||
|
*
|
||||||
|
* @param control the control with the default background color
|
||||||
|
*/
|
||||||
|
public void adaptBackgroundColor(Control control) {
|
||||||
|
// Workaround for dark editor background color, see https://bugs.eclipse.org/330680
|
||||||
|
Color defaultColor= control.getBackground();
|
||||||
|
float[] defaultBgHSB= defaultColor.getRGB().getHSB();
|
||||||
|
|
||||||
|
CTextTools textTools= CUIPlugin.getDefault().getTextTools();
|
||||||
|
IColorManager manager= textTools.getColorManager();
|
||||||
|
Color cDefaultColor= manager.getColor(ICColorConstants.C_DEFAULT);
|
||||||
|
RGB cDefaultRGB= cDefaultColor != null ?
|
||||||
|
cDefaultColor.getRGB() : new RGB(255, 255, 255);
|
||||||
|
float[] javaDefaultHSB= cDefaultRGB.getHSB();
|
||||||
|
|
||||||
|
if (Math.abs(defaultBgHSB[2] - javaDefaultHSB[2]) >= 0.5f) {
|
||||||
|
getTextWidget().setBackground(defaultColor);
|
||||||
|
if (fBackgroundColor != null) {
|
||||||
|
fBackgroundColor.dispose();
|
||||||
|
fBackgroundColor= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2011 Google, Inc and others.
|
* Copyright (c) 2011, 2012 Google, Inc 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
|
||||||
|
@ -34,6 +34,8 @@ import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
|
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
|
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
|
||||||
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
|
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
|
||||||
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
||||||
|
@ -51,6 +53,7 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
||||||
private static final String EXAMPLE_CONSTANT_NAME = "MY_CONSTANT"; //$NON-NLS-1$
|
private static final String EXAMPLE_CONSTANT_NAME = "MY_CONSTANT"; //$NON-NLS-1$
|
||||||
private static final String EXAMPLE_VARIABLE_NAME = "myVariable"; //$NON-NLS-1$
|
private static final String EXAMPLE_VARIABLE_NAME = "myVariable"; //$NON-NLS-1$
|
||||||
private static final String EXAMPLE_FIELD_NAME = "myField"; //$NON-NLS-1$
|
private static final String EXAMPLE_FIELD_NAME = "myField"; //$NON-NLS-1$
|
||||||
|
private static final String EXAMPLE_METHOD_NAME = "myMethod"; //$NON-NLS-1$
|
||||||
private static final String EXAMPLE_CLASS_NAME = "MyClass"; //$NON-NLS-1$
|
private static final String EXAMPLE_CLASS_NAME = "MyClass"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final String[] CAPITALIZATION_VALUES = {
|
private final String[] CAPITALIZATION_VALUES = {
|
||||||
|
@ -81,6 +84,10 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
||||||
private static final Key KEY_FIELD_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_WORD_DELIMITER);
|
private static final Key KEY_FIELD_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_WORD_DELIMITER);
|
||||||
private static final Key KEY_FIELD_PREFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_PREFIX);
|
private static final Key KEY_FIELD_PREFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_PREFIX);
|
||||||
private static final Key KEY_FIELD_SUFFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_SUFFIX);
|
private static final Key KEY_FIELD_SUFFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_FIELD_SUFFIX);
|
||||||
|
private static final Key KEY_METHOD_CAPITALIZATION = getCDTUIKey(PreferenceConstants.NAME_STYLE_METHOD_CAPITALIZATION);
|
||||||
|
private static final Key KEY_METHOD_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_METHOD_WORD_DELIMITER);
|
||||||
|
private static final Key KEY_METHOD_PREFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_METHOD_PREFIX);
|
||||||
|
private static final Key KEY_METHOD_SUFFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_METHOD_SUFFIX);
|
||||||
private static final Key KEY_GETTER_CAPITALIZATION = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION);
|
private static final Key KEY_GETTER_CAPITALIZATION = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION);
|
||||||
private static final Key KEY_GETTER_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER);
|
private static final Key KEY_GETTER_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER);
|
||||||
private static final Key KEY_GETTER_PREFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_PREFIX);
|
private static final Key KEY_GETTER_PREFIX = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_PREFIX);
|
||||||
|
@ -120,6 +127,10 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
||||||
KEY_FIELD_WORD_DELIMITER,
|
KEY_FIELD_WORD_DELIMITER,
|
||||||
KEY_FIELD_PREFIX,
|
KEY_FIELD_PREFIX,
|
||||||
KEY_FIELD_SUFFIX,
|
KEY_FIELD_SUFFIX,
|
||||||
|
KEY_METHOD_CAPITALIZATION,
|
||||||
|
KEY_METHOD_WORD_DELIMITER,
|
||||||
|
KEY_METHOD_PREFIX,
|
||||||
|
KEY_METHOD_SUFFIX,
|
||||||
KEY_GETTER_CAPITALIZATION,
|
KEY_GETTER_CAPITALIZATION,
|
||||||
KEY_GETTER_WORD_DELIMITER,
|
KEY_GETTER_WORD_DELIMITER,
|
||||||
KEY_GETTER_PREFIX,
|
KEY_GETTER_PREFIX,
|
||||||
|
@ -182,6 +193,14 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
||||||
.setPrefixKey(KEY_FIELD_PREFIX)
|
.setPrefixKey(KEY_FIELD_PREFIX)
|
||||||
.setSuffixKey(KEY_FIELD_SUFFIX)
|
.setSuffixKey(KEY_FIELD_SUFFIX)
|
||||||
.setNameValidator(IDENTIFIER_VALIDATOR);
|
.setNameValidator(IDENTIFIER_VALIDATOR);
|
||||||
|
new Category(PreferencesMessages.NameStyleBlock_method_node,
|
||||||
|
PreferencesMessages.NameStyleBlock_method_node_description, EXAMPLE_METHOD_NAME,
|
||||||
|
codeCategory)
|
||||||
|
.setCapitalizationKey(KEY_METHOD_CAPITALIZATION)
|
||||||
|
.setWordDelimiterKey(KEY_METHOD_WORD_DELIMITER)
|
||||||
|
.setPrefixKey(KEY_METHOD_PREFIX)
|
||||||
|
.setSuffixKey(KEY_METHOD_SUFFIX)
|
||||||
|
.setNameValidator(IDENTIFIER_VALIDATOR);
|
||||||
new Category(PreferencesMessages.NameStyleBlock_getter_node,
|
new Category(PreferencesMessages.NameStyleBlock_getter_node,
|
||||||
PreferencesMessages.NameStyleBlock_getter_node_description, EXAMPLE_FIELD_NAME,
|
PreferencesMessages.NameStyleBlock_getter_node_description, EXAMPLE_FIELD_NAME,
|
||||||
codeCategory)
|
codeCategory)
|
||||||
|
@ -572,7 +591,7 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
||||||
String name = seedNameGenerator != null ?
|
String name = seedNameGenerator != null ?
|
||||||
seedNameGenerator.composeExampleName(settings) : seedName;
|
seedNameGenerator.composeExampleName(settings) : seedName;
|
||||||
if (trimFieldName) {
|
if (trimFieldName) {
|
||||||
name = NameComposer.trimFieldName(name);
|
name = StubUtility.trimFieldName(name);
|
||||||
}
|
}
|
||||||
return composer.compose(name);
|
return composer.compose(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,6 +367,8 @@ public final class PreferencesMessages extends NLS {
|
||||||
public static String NameStyleBlock_variable_node_description;
|
public static String NameStyleBlock_variable_node_description;
|
||||||
public static String NameStyleBlock_field_node;
|
public static String NameStyleBlock_field_node;
|
||||||
public static String NameStyleBlock_field_node_description;
|
public static String NameStyleBlock_field_node_description;
|
||||||
|
public static String NameStyleBlock_method_node;
|
||||||
|
public static String NameStyleBlock_method_node_description;
|
||||||
public static String NameStyleBlock_getter_node;
|
public static String NameStyleBlock_getter_node;
|
||||||
public static String NameStyleBlock_getter_node_description;
|
public static String NameStyleBlock_getter_node_description;
|
||||||
public static String NameStyleBlock_setter_node;
|
public static String NameStyleBlock_setter_node;
|
||||||
|
|
|
@ -420,8 +420,10 @@ NameStyleBlock_constant_node=Constant
|
||||||
NameStyleBlock_constant_node_description=Constant name
|
NameStyleBlock_constant_node_description=Constant name
|
||||||
NameStyleBlock_variable_node=Variable
|
NameStyleBlock_variable_node=Variable
|
||||||
NameStyleBlock_variable_node_description=Variable name
|
NameStyleBlock_variable_node_description=Variable name
|
||||||
NameStyleBlock_field_node=Class field
|
NameStyleBlock_field_node=Class Field
|
||||||
NameStyleBlock_field_node_description=Class field name
|
NameStyleBlock_field_node_description=Class field name
|
||||||
|
NameStyleBlock_method_node=Class Method
|
||||||
|
NameStyleBlock_method_node_description=Class method name
|
||||||
NameStyleBlock_getter_node=Getter Method
|
NameStyleBlock_getter_node=Getter Method
|
||||||
NameStyleBlock_getter_node_description=Getter name based on the field name
|
NameStyleBlock_getter_node_description=Getter name based on the field name
|
||||||
NameStyleBlock_setter_node=Setter Method
|
NameStyleBlock_setter_node=Setter Method
|
||||||
|
|
|
@ -66,6 +66,7 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
|
|
||||||
protected String name = Messages.Refactoring_name;
|
protected String name = Messages.Refactoring_name;
|
||||||
protected IFile file;
|
protected IFile file;
|
||||||
|
protected final ITranslationUnit tu;
|
||||||
protected Region region;
|
protected Region region;
|
||||||
protected RefactoringStatus initStatus;
|
protected RefactoringStatus initStatus;
|
||||||
protected IASTTranslationUnit ast;
|
protected IASTTranslationUnit ast;
|
||||||
|
@ -76,11 +77,10 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
project = proj;
|
project = proj;
|
||||||
if (element instanceof ISourceReference) {
|
if (element instanceof ISourceReference) {
|
||||||
ISourceReference sourceRef= (ISourceReference) element;
|
ISourceReference sourceRef= (ISourceReference) element;
|
||||||
ITranslationUnit tu = sourceRef.getTranslationUnit();
|
this.tu = sourceRef.getTranslationUnit();
|
||||||
IResource res= tu.getResource();
|
IResource res= tu.getResource();
|
||||||
if (res instanceof IFile)
|
if (res instanceof IFile)
|
||||||
this.file= (IFile) res;
|
this.file= (IFile) res;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final ISourceRange sourceRange = sourceRef.getSourceRange();
|
final ISourceRange sourceRange = sourceRef.getSourceRange();
|
||||||
this.region = new Region(sourceRange.getIdStartPos(), sourceRange.getIdLength());
|
this.region = new Region(sourceRange.getIdStartPos(), sourceRange.getIdLength());
|
||||||
|
@ -89,6 +89,7 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
this.tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file);
|
||||||
this.region = SelectionHelper.getRegion(selection);
|
this.region = SelectionHelper.getRegion(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,10 +236,10 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
|
|
||||||
protected boolean loadTranslationUnit(RefactoringStatus status, IProgressMonitor mon) {
|
protected boolean loadTranslationUnit(RefactoringStatus status, IProgressMonitor mon) {
|
||||||
SubMonitor subMonitor = SubMonitor.convert(mon, 10);
|
SubMonitor subMonitor = SubMonitor.convert(mon, 10);
|
||||||
if (file != null) {
|
if (tu != null) {
|
||||||
try {
|
try {
|
||||||
subMonitor.subTask(Messages.Refactoring_PM_ParseTU);
|
subMonitor.subTask(Messages.Refactoring_PM_ParseTU);
|
||||||
ast = loadTranslationUnit(file);
|
ast = tu.getAST(fIndex, AST_STYLE);
|
||||||
if (ast == null) {
|
if (ast == null) {
|
||||||
subMonitor.done();
|
subMonitor.done();
|
||||||
return false;
|
return false;
|
||||||
|
@ -256,7 +257,7 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
status.addFatalError(Messages.NO_FILE);
|
status.addFatalError(NLS.bind(Messages.CRefactoring_FileNotFound, tu.getPath().toString()));
|
||||||
subMonitor.done();
|
subMonitor.done();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -264,15 +265,6 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IASTTranslationUnit loadTranslationUnit(IFile file) throws CoreException {
|
|
||||||
ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file);
|
|
||||||
if (tu == null) {
|
|
||||||
initStatus.addFatalError(NLS.bind(Messages.CRefactoring_FileNotFound, file.getName()));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return tu.getAST(fIndex, AST_STYLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean translationUnitHasProblem() {
|
protected boolean translationUnitHasProblem() {
|
||||||
ProblemFinder pf = new ProblemFinder(initStatus);
|
ProblemFinder pf = new ProblemFinder(initStatus);
|
||||||
ast.accept(pf);
|
ast.accept(pf);
|
||||||
|
@ -305,6 +297,13 @@ public abstract class CRefactoring extends Refactoring {
|
||||||
return fIndex;
|
return fIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the translation unit where the refactoring started.
|
||||||
|
*/
|
||||||
|
public ITranslationUnit getTranslationUnit() {
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
|
||||||
public IASTTranslationUnit getUnit() {
|
public IASTTranslationUnit getUnit() {
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,6 +239,13 @@ public abstract class CRefactoring2 extends Refactoring {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the translation unit where the refactoring started.
|
||||||
|
*/
|
||||||
|
public ITranslationUnit getTranslationUnit() {
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
|
||||||
protected IASTTranslationUnit getAST(ITranslationUnit tu, IProgressMonitor pm)
|
protected IASTTranslationUnit getAST(ITranslationUnit tu, IProgressMonitor pm)
|
||||||
throws CoreException, OperationCanceledException {
|
throws CoreException, OperationCanceledException {
|
||||||
return astCache.getAST(tu, pm);
|
return astCache.getAST(tu, pm);
|
||||||
|
|
|
@ -0,0 +1,815 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2011 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
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.refactoring;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.jface.contentassist.SubjectControlContentAssistant;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.viewers.CellEditor;
|
||||||
|
import org.eclipse.jface.viewers.ColumnWeightData;
|
||||||
|
import org.eclipse.jface.viewers.ComboBoxCellEditor;
|
||||||
|
import org.eclipse.jface.viewers.ICellModifier;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
|
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||||
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||||
|
import org.eclipse.jface.viewers.ITableFontProvider;
|
||||||
|
import org.eclipse.jface.viewers.ITableLabelProvider;
|
||||||
|
import org.eclipse.jface.viewers.LabelProvider;
|
||||||
|
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||||
|
import org.eclipse.jface.viewers.StructuredSelection;
|
||||||
|
import org.eclipse.jface.viewers.TableViewer;
|
||||||
|
import org.eclipse.jface.viewers.Viewer;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.CCombo;
|
||||||
|
import org.eclipse.swt.events.KeyAdapter;
|
||||||
|
import org.eclipse.swt.events.KeyEvent;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.events.TraverseEvent;
|
||||||
|
import org.eclipse.swt.events.TraverseListener;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Table;
|
||||||
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
import org.eclipse.ui.contentassist.ContentAssistHandler;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.dialogs.TableTextCellEditor;
|
||||||
|
import org.eclipse.cdt.internal.ui.dialogs.TextFieldNavigationHandler;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.SWTUtil;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.TableLayoutComposite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special control to edit and reorder method parameters.
|
||||||
|
*/
|
||||||
|
public class ChangeParametersControl extends Composite {
|
||||||
|
|
||||||
|
public static enum Mode {
|
||||||
|
EXTRACT_METHOD, EXTRACT_METHOD_FIXED_RETURN, CHANGE_METHOD_SIGNATURE, INTRODUCE_PARAMETER;
|
||||||
|
|
||||||
|
public boolean canChangeTypes() {
|
||||||
|
return this == CHANGE_METHOD_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canAddParameters() {
|
||||||
|
return this == Mode.CHANGE_METHOD_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canChangeDefault() {
|
||||||
|
return this == Mode.CHANGE_METHOD_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldShowDirection() {
|
||||||
|
return this == Mode.EXTRACT_METHOD || this == Mode.EXTRACT_METHOD_FIXED_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canChangeReturn() {
|
||||||
|
return this == Mode.EXTRACT_METHOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NameInformationContentProvider implements IStructuredContentProvider {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object[] getElements(Object inputElement) {
|
||||||
|
return removeMarkedAsDeleted((List<NameInformation>) inputElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NameInformation[] removeMarkedAsDeleted(List<NameInformation> params) {
|
||||||
|
List<NameInformation> result= new ArrayList<NameInformation>(params.size());
|
||||||
|
for (Iterator<NameInformation> iter= params.iterator(); iter.hasNext();) {
|
||||||
|
NameInformation info= iter.next();
|
||||||
|
if (!info.isDeleted())
|
||||||
|
result.add(info);
|
||||||
|
}
|
||||||
|
return result.toArray(new NameInformation[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NameInformationLabelProvider extends LabelProvider
|
||||||
|
implements ITableLabelProvider, ITableFontProvider {
|
||||||
|
@Override
|
||||||
|
public Image getColumnImage(Object element, int columnIndex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnText(Object element, int columnIndex) {
|
||||||
|
NameInformation info= (NameInformation) element;
|
||||||
|
if (columnIndex == indexType) {
|
||||||
|
return info.getTypeName();
|
||||||
|
} else if (columnIndex == indexDirection) {
|
||||||
|
return getDirectionLabel(info);
|
||||||
|
} else if (columnIndex == indexName) {
|
||||||
|
return info.getNewName();
|
||||||
|
} else if (columnIndex == indexDefault) {
|
||||||
|
if (info.isAdded()) {
|
||||||
|
return info.getDefaultValue();
|
||||||
|
} else {
|
||||||
|
return "-"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(columnIndex + ": " + element); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Font getFont(Object element, int columnIndex) {
|
||||||
|
NameInformation info= (NameInformation) element;
|
||||||
|
if (info.isAdded()) {
|
||||||
|
return JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ParametersCellModifier implements ICellModifier {
|
||||||
|
@Override
|
||||||
|
public boolean canModify(Object element, String property) {
|
||||||
|
Assert.isTrue(element instanceof NameInformation);
|
||||||
|
if (property.equals(columnProperties[indexType])) {
|
||||||
|
return fMode.canChangeTypes();
|
||||||
|
} else if (property.equals(columnProperties[indexDirection])) {
|
||||||
|
return fMode.canChangeReturn() && ((NameInformation) element).isOutput();
|
||||||
|
} else if (property.equals(columnProperties[indexName])) {
|
||||||
|
return true;
|
||||||
|
} else if (property.equals(columnProperties[indexDefault])) {
|
||||||
|
return ((NameInformation) element).isAdded();
|
||||||
|
}
|
||||||
|
Assert.isTrue(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue(Object element, String property) {
|
||||||
|
Assert.isTrue(element instanceof NameInformation);
|
||||||
|
if (property.equals(columnProperties[indexType])) {
|
||||||
|
return ((NameInformation) element).getTypeName();
|
||||||
|
} else if (property.equals(columnProperties[indexDirection])) {
|
||||||
|
return ((NameInformation) element).isReturnValue() ? INDEX_RETURN : INDEX_OUTPUT;
|
||||||
|
} else if (property.equals(columnProperties[indexName])) {
|
||||||
|
return ((NameInformation) element).getNewName();
|
||||||
|
} else if (property.equals(columnProperties[indexDefault])) {
|
||||||
|
return ((NameInformation) element).getDefaultValue();
|
||||||
|
}
|
||||||
|
Assert.isTrue(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void modify(Object element, String property, Object value) {
|
||||||
|
if (element instanceof TableItem)
|
||||||
|
element= ((TableItem) element).getData();
|
||||||
|
if (!(element instanceof NameInformation))
|
||||||
|
return;
|
||||||
|
String[] columnsToUpdate = new String[] { property };
|
||||||
|
boolean unchanged;
|
||||||
|
NameInformation parameterInfo= (NameInformation) element;
|
||||||
|
if (property.equals(columnProperties[indexType])) {
|
||||||
|
unchanged= parameterInfo.getTypeName().equals(value);
|
||||||
|
parameterInfo.setTypeName((String) value);
|
||||||
|
} else if (property.equals(columnProperties[indexDirection])) {
|
||||||
|
columnsToUpdate = new String[] { property, columnProperties[indexType] };
|
||||||
|
boolean isReturn = value.equals(INDEX_RETURN);
|
||||||
|
unchanged= isReturn == parameterInfo.isReturnValue();
|
||||||
|
if (!unchanged && isReturn) {
|
||||||
|
for (NameInformation param : fParameters) {
|
||||||
|
if (param != parameterInfo && param.isOutput()) {
|
||||||
|
param.setReturnValue(false);
|
||||||
|
ChangeParametersControl.this.fListener.parameterChanged(param);
|
||||||
|
ChangeParametersControl.this.fTableViewer.update(param, columnsToUpdate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameterInfo.setReturnValue(isReturn);
|
||||||
|
} else if (property.equals(columnProperties[indexName])) {
|
||||||
|
unchanged= parameterInfo.getNewName().equals(value);
|
||||||
|
parameterInfo.setNewName((String) value);
|
||||||
|
} else if (property.equals(columnProperties[indexDefault])) {
|
||||||
|
unchanged= parameterInfo.getDefaultValue().equals(value);
|
||||||
|
parameterInfo.setDefaultValue((String) value);
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
if (!unchanged) {
|
||||||
|
ChangeParametersControl.this.fListener.parameterChanged(parameterInfo);
|
||||||
|
ChangeParametersControl.this.fTableViewer.update(parameterInfo, columnsToUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DirectionCellEditor extends ComboBoxCellEditor {
|
||||||
|
DirectionCellEditor(Table table) {
|
||||||
|
super(table,
|
||||||
|
new String[] {
|
||||||
|
/* INDEX_OUTPUT */ Messages.ChangeParametersControl_output,
|
||||||
|
/* INDEX_RETURN */ Messages.ChangeParametersControl_return},
|
||||||
|
SWT.READ_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Control createControl(Composite parent) {
|
||||||
|
final CCombo comboBox = (CCombo) super.createControl(parent);
|
||||||
|
comboBox.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
fireApplyEditorValue();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return comboBox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String[] columnProperties;
|
||||||
|
private final int indexType;
|
||||||
|
private final int indexDirection;
|
||||||
|
private final int indexName;
|
||||||
|
private final int indexDefault;
|
||||||
|
|
||||||
|
private static final int ROW_COUNT= 7;
|
||||||
|
|
||||||
|
static final Integer INDEX_OUTPUT = 0;
|
||||||
|
static final Integer INDEX_RETURN = 1;
|
||||||
|
|
||||||
|
private final Mode fMode;
|
||||||
|
private final IParameterListChangeListener fListener;
|
||||||
|
private List<NameInformation> fParameters;
|
||||||
|
private final StubTypeContext fTypeContext;
|
||||||
|
private final String[] fParamNameProposals;
|
||||||
|
private ContentAssistHandler fNameContentAssistHandler;
|
||||||
|
|
||||||
|
private TableViewer fTableViewer;
|
||||||
|
private Button fUpButton;
|
||||||
|
private Button fDownButton;
|
||||||
|
private Button fEditButton;
|
||||||
|
private Button fAddButton;
|
||||||
|
private Button fRemoveButton;
|
||||||
|
|
||||||
|
public ChangeParametersControl(Composite parent, int style, String label,
|
||||||
|
IParameterListChangeListener listener, Mode mode, StubTypeContext typeContext) {
|
||||||
|
this(parent, style, label, listener, mode, typeContext, new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChangeParametersControl(Composite parent, int style, String label,
|
||||||
|
IParameterListChangeListener listener, Mode mode) {
|
||||||
|
this(parent, style, label, listener, mode, null, new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChangeParametersControl(Composite parent, int style, String label,
|
||||||
|
IParameterListChangeListener listener, Mode mode, String[] paramNameProposals) {
|
||||||
|
this(parent, style, label, listener, mode, null, paramNameProposals);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param label the label before the table or <code>null</code>
|
||||||
|
* @param typeContext the package in which to complete types
|
||||||
|
*/
|
||||||
|
private ChangeParametersControl(Composite parent, int style, String label,
|
||||||
|
IParameterListChangeListener listener, Mode mode, StubTypeContext typeContext,
|
||||||
|
String[] paramNameProposals) {
|
||||||
|
super(parent, style);
|
||||||
|
Assert.isNotNull(listener);
|
||||||
|
fListener= listener;
|
||||||
|
fMode= mode;
|
||||||
|
fTypeContext= typeContext;
|
||||||
|
fParamNameProposals= paramNameProposals;
|
||||||
|
|
||||||
|
ArrayList<String> properties = new ArrayList<String>();
|
||||||
|
indexType = properties.size();
|
||||||
|
properties.add("type"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (fMode.shouldShowDirection()) {
|
||||||
|
indexDirection = properties.size();
|
||||||
|
properties.add("direction"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
indexDirection = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
indexName = properties.size();
|
||||||
|
properties.add("name"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
if (fMode.canChangeDefault()) {
|
||||||
|
indexDefault = properties.size();
|
||||||
|
properties.add("default"); //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
indexDefault = -1;
|
||||||
|
}
|
||||||
|
columnProperties = properties.toArray(new String[properties.size()]);
|
||||||
|
|
||||||
|
GridLayout layout= new GridLayout();
|
||||||
|
layout.numColumns= 2;
|
||||||
|
layout.marginWidth= 0;
|
||||||
|
layout.marginHeight= 0;
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
if (label != null) {
|
||||||
|
Label tableLabel= new Label(this, SWT.NONE);
|
||||||
|
GridData labelGd= new GridData();
|
||||||
|
labelGd.horizontalSpan= 2;
|
||||||
|
tableLabel.setLayoutData(labelGd);
|
||||||
|
tableLabel.setText(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
createParameterList(this);
|
||||||
|
createButtonComposite(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInput(List<NameInformation> parameterInfos) {
|
||||||
|
Assert.isNotNull(parameterInfos);
|
||||||
|
fParameters= parameterInfos;
|
||||||
|
fTableViewer.setInput(fParameters);
|
||||||
|
if (fParameters.size() > 0)
|
||||||
|
fTableViewer.setSelection(new StructuredSelection(fParameters.get(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editParameter(NameInformation info) {
|
||||||
|
fTableViewer.getControl().setFocus();
|
||||||
|
if (!info.isDeleted()) {
|
||||||
|
fTableViewer.setSelection(new StructuredSelection(info), true);
|
||||||
|
updateButtonsEnabledState();
|
||||||
|
editColumnOrNextPossible(indexName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Parameter table -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void createParameterList(Composite parent) {
|
||||||
|
TableLayoutComposite layouter= new TableLayoutComposite(parent, SWT.NONE);
|
||||||
|
addColumnLayoutData(layouter);
|
||||||
|
|
||||||
|
final Table table= new Table(layouter, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION);
|
||||||
|
table.setHeaderVisible(true);
|
||||||
|
table.setLinesVisible(true);
|
||||||
|
TableColumn tc;
|
||||||
|
tc= new TableColumn(table, SWT.NONE, indexType);
|
||||||
|
tc.setResizable(true);
|
||||||
|
tc.setText(Messages.ChangeParametersControl_table_type);
|
||||||
|
|
||||||
|
if (indexDirection >= 0) {
|
||||||
|
tc= new TableColumn(table, SWT.NONE, indexDirection);
|
||||||
|
tc.setResizable(true);
|
||||||
|
tc.setText(Messages.ChangeParametersControl_table_direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc= new TableColumn(table, SWT.NONE, indexName);
|
||||||
|
tc.setResizable(true);
|
||||||
|
tc.setText(Messages.ChangeParametersControl_table_name);
|
||||||
|
|
||||||
|
if (indexDefault >= 0) {
|
||||||
|
tc= new TableColumn(table, SWT.NONE, indexDefault);
|
||||||
|
tc.setResizable(true);
|
||||||
|
tc.setText(Messages.ChangeParametersControl_table_default_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
GridData gd= new GridData(GridData.FILL_BOTH);
|
||||||
|
gd.heightHint= SWTUtil.getTableHeightHint(table, ROW_COUNT);
|
||||||
|
gd.widthHint= 40;
|
||||||
|
layouter.setLayoutData(gd);
|
||||||
|
|
||||||
|
fTableViewer= new TableViewer(table);
|
||||||
|
fTableViewer.setUseHashlookup(true);
|
||||||
|
fTableViewer.setContentProvider(new NameInformationContentProvider());
|
||||||
|
fTableViewer.setLabelProvider(new NameInformationLabelProvider());
|
||||||
|
fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void selectionChanged(SelectionChangedEvent event) {
|
||||||
|
updateButtonsEnabledState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
table.addTraverseListener(new TraverseListener() {
|
||||||
|
@Override
|
||||||
|
public void keyTraversed(TraverseEvent e) {
|
||||||
|
if (e.detail == SWT.TRAVERSE_RETURN && e.stateMask == SWT.NONE) {
|
||||||
|
editColumnOrNextPossible(0);
|
||||||
|
e.detail= SWT.TRAVERSE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
table.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if (e.keyCode == SWT.F2 && e.stateMask == SWT.NONE) {
|
||||||
|
editColumnOrNextPossible(0);
|
||||||
|
e.doit= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addCellEditors();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDirectionLabel(NameInformation parameter) {
|
||||||
|
return parameter.isReturnValue() ?
|
||||||
|
Messages.ChangeParametersControl_return :
|
||||||
|
parameter.isOutput() ?
|
||||||
|
Messages.ChangeParametersControl_output :
|
||||||
|
Messages.ChangeParametersControl_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editColumnOrNextPossible(int column) {
|
||||||
|
NameInformation[] selected= getSelectedElements();
|
||||||
|
if (selected.length != 1)
|
||||||
|
return;
|
||||||
|
int nextColumn= column;
|
||||||
|
do {
|
||||||
|
fTableViewer.editElement(selected[0], nextColumn);
|
||||||
|
if (fTableViewer.isCellEditorActive())
|
||||||
|
return;
|
||||||
|
nextColumn= nextColumn(nextColumn);
|
||||||
|
} while (nextColumn != column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editColumnOrPrevPossible(int column) {
|
||||||
|
NameInformation[] selected= getSelectedElements();
|
||||||
|
if (selected.length != 1)
|
||||||
|
return;
|
||||||
|
int prevColumn= column;
|
||||||
|
do {
|
||||||
|
fTableViewer.editElement(selected[0], prevColumn);
|
||||||
|
if (fTableViewer.isCellEditorActive())
|
||||||
|
return;
|
||||||
|
prevColumn= prevColumn(prevColumn);
|
||||||
|
} while (prevColumn != column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int nextColumn(int column) {
|
||||||
|
return column >= getTable().getColumnCount() - 1 ? 0 : column + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int prevColumn(int column) {
|
||||||
|
return column <= 0 ? getTable().getColumnCount() - 1 : column - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addColumnLayoutData(TableLayoutComposite layouter) {
|
||||||
|
for (int i = 0; i < columnProperties.length; i++) {
|
||||||
|
layouter.addColumnData(new ColumnWeightData(10, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NameInformation[] getSelectedElements() {
|
||||||
|
ISelection selection= fTableViewer.getSelection();
|
||||||
|
if (selection == null)
|
||||||
|
return new NameInformation[0];
|
||||||
|
|
||||||
|
if (!(selection instanceof IStructuredSelection))
|
||||||
|
return new NameInformation[0];
|
||||||
|
|
||||||
|
List<?> selected= ((IStructuredSelection) selection).toList();
|
||||||
|
return selected.toArray(new NameInformation[selected.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Button bar --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void createButtonComposite(Composite parent) {
|
||||||
|
Composite buttonComposite= new Composite(parent, SWT.NONE);
|
||||||
|
buttonComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL));
|
||||||
|
GridLayout gl= new GridLayout();
|
||||||
|
gl.marginHeight= 0;
|
||||||
|
gl.marginWidth= 0;
|
||||||
|
buttonComposite.setLayout(gl);
|
||||||
|
|
||||||
|
if (fMode.canAddParameters())
|
||||||
|
fAddButton= createAddButton(buttonComposite);
|
||||||
|
|
||||||
|
fEditButton= createEditButton(buttonComposite);
|
||||||
|
|
||||||
|
if (fMode.canAddParameters())
|
||||||
|
fRemoveButton= createRemoveButton(buttonComposite);
|
||||||
|
|
||||||
|
if (buttonComposite.getChildren().length != 0)
|
||||||
|
addSpacer(buttonComposite);
|
||||||
|
|
||||||
|
fUpButton= createButton(buttonComposite, Messages.ChangeParametersControl_buttons_move_up, true);
|
||||||
|
fDownButton= createButton(buttonComposite, Messages.ChangeParametersControl_buttons_move_down, false);
|
||||||
|
|
||||||
|
updateButtonsEnabledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSpacer(Composite parent) {
|
||||||
|
Label label= new Label(parent, SWT.NONE);
|
||||||
|
GridData gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.heightHint= 5;
|
||||||
|
label.setLayoutData(gd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateButtonsEnabledState() {
|
||||||
|
fUpButton.setEnabled(canMove(true));
|
||||||
|
fDownButton.setEnabled(canMove(false));
|
||||||
|
if (fEditButton != null)
|
||||||
|
fEditButton.setEnabled(getTableSelectionCount() == 1);
|
||||||
|
if (fAddButton != null)
|
||||||
|
fAddButton.setEnabled(true);
|
||||||
|
if (fRemoveButton != null)
|
||||||
|
fRemoveButton.setEnabled(getTableSelectionCount() != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTableSelectionCount() {
|
||||||
|
return getTable().getSelectionCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTableItemCount() {
|
||||||
|
return getTable().getItemCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Table getTable() {
|
||||||
|
return fTableViewer.getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button createEditButton(Composite buttonComposite) {
|
||||||
|
Button button= new Button(buttonComposite, SWT.PUSH);
|
||||||
|
button.setText(Messages.ChangeParametersControl_buttons_edit);
|
||||||
|
button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
SWTUtil.setButtonDimensionHint(button);
|
||||||
|
button.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
try {
|
||||||
|
NameInformation[] selected= getSelectedElements();
|
||||||
|
Assert.isTrue(selected.length == 1);
|
||||||
|
NameInformation parameterInfo= selected[0];
|
||||||
|
ParameterEditDialog dialog= new ParameterEditDialog(getShell(), parameterInfo,
|
||||||
|
fMode.canChangeTypes(), fMode.canChangeDefault(),
|
||||||
|
fMode.canChangeReturn() && parameterInfo.isOutput());
|
||||||
|
dialog.open();
|
||||||
|
fListener.parameterChanged(parameterInfo);
|
||||||
|
fTableViewer.update(parameterInfo, columnProperties);
|
||||||
|
} finally {
|
||||||
|
fTableViewer.getControl().setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button createAddButton(Composite buttonComposite) {
|
||||||
|
Button button= new Button(buttonComposite, SWT.PUSH);
|
||||||
|
button.setText(Messages.ChangeParametersControl_buttons_add);
|
||||||
|
button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
SWTUtil.setButtonDimensionHint(button);
|
||||||
|
button.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
Set<String> excludedParamNames= new HashSet<String>(fParameters.size());
|
||||||
|
for (int i= 0; i < fParameters.size(); i++) {
|
||||||
|
NameInformation info= fParameters.get(i);
|
||||||
|
excludedParamNames.add(info.getNewName());
|
||||||
|
}
|
||||||
|
String newParamName= StubUtility.suggestParameterName("newParam", excludedParamNames, //$NON-NLS-1$
|
||||||
|
fTypeContext != null ? fTypeContext.getTranslationUnit() : null);
|
||||||
|
NameInformation newInfo= NameInformation.createInfoForAddedParameter("int", newParamName, "0"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
int insertIndex= fParameters.size();
|
||||||
|
fParameters.add(insertIndex, newInfo);
|
||||||
|
fListener.parameterAdded(newInfo);
|
||||||
|
fTableViewer.refresh();
|
||||||
|
fTableViewer.getControl().setFocus();
|
||||||
|
fTableViewer.setSelection(new StructuredSelection(newInfo), true);
|
||||||
|
updateButtonsEnabledState();
|
||||||
|
editColumnOrNextPossible(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button createRemoveButton(Composite buttonComposite) {
|
||||||
|
final Button button= new Button(buttonComposite, SWT.PUSH);
|
||||||
|
button.setText(Messages.ChangeParametersControl_buttons_remove);
|
||||||
|
button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
SWTUtil.setButtonDimensionHint(button);
|
||||||
|
button.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
int index= getTable().getSelectionIndices()[0];
|
||||||
|
NameInformation[] selected= getSelectedElements();
|
||||||
|
for (int i= 0; i < selected.length; i++) {
|
||||||
|
if (selected[i].isAdded()) {
|
||||||
|
fParameters.remove(selected[i]);
|
||||||
|
} else {
|
||||||
|
selected[i].markAsDeleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
restoreSelection(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreSelection(int index) {
|
||||||
|
fTableViewer.refresh();
|
||||||
|
fTableViewer.getControl().setFocus();
|
||||||
|
int itemCount= getTableItemCount();
|
||||||
|
if (itemCount != 0) {
|
||||||
|
if (index >= itemCount)
|
||||||
|
index= itemCount - 1;
|
||||||
|
getTable().setSelection(index);
|
||||||
|
}
|
||||||
|
fListener.parameterListChanged();
|
||||||
|
updateButtonsEnabledState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button createButton(Composite buttonComposite, String text, final boolean up) {
|
||||||
|
Button button= new Button(buttonComposite, SWT.PUSH);
|
||||||
|
button.setText(text);
|
||||||
|
button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
SWTUtil.setButtonDimensionHint(button);
|
||||||
|
button.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
ISelection savedSelection= fTableViewer.getSelection();
|
||||||
|
if (savedSelection == null)
|
||||||
|
return;
|
||||||
|
NameInformation[] selection= getSelectedElements();
|
||||||
|
if (selection.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (up) {
|
||||||
|
moveUp(selection);
|
||||||
|
} else {
|
||||||
|
moveDown(selection);
|
||||||
|
}
|
||||||
|
fTableViewer.refresh();
|
||||||
|
fTableViewer.setSelection(savedSelection);
|
||||||
|
fListener.parameterListChanged();
|
||||||
|
fTableViewer.getControl().setFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- editing -----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void addCellEditors() {
|
||||||
|
fTableViewer.setColumnProperties(columnProperties);
|
||||||
|
|
||||||
|
ArrayList<CellEditor> editors = new ArrayList<CellEditor>();
|
||||||
|
TableTextCellEditor cellEditorType= new TableTextCellEditor(fTableViewer, indexType);
|
||||||
|
editors.add(cellEditorType);
|
||||||
|
if (indexDirection >= 0) {
|
||||||
|
ComboBoxCellEditor cellEditorDirection= new DirectionCellEditor(fTableViewer.getTable());
|
||||||
|
editors.add(cellEditorDirection);
|
||||||
|
}
|
||||||
|
TableTextCellEditor cellEditorName= new TableTextCellEditor(fTableViewer, indexName);
|
||||||
|
editors.add(cellEditorName);
|
||||||
|
if (indexDefault >= 0) {
|
||||||
|
TableTextCellEditor cellEditorDefault= new TableTextCellEditor(fTableViewer, indexDefault);
|
||||||
|
editors.add(cellEditorDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fParamNameProposals.length > 0) {
|
||||||
|
SubjectControlContentAssistant assistant= installParameterNameContentAssist(cellEditorName.getText());
|
||||||
|
cellEditorName.setContentAssistant(assistant);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < editors.size(); i++) {
|
||||||
|
final int editorColumn= i;
|
||||||
|
final CellEditor editor = editors.get(i);
|
||||||
|
// Support tabbing between columns while editing
|
||||||
|
Control control = editor.getControl();
|
||||||
|
control.addTraverseListener(new TraverseListener() {
|
||||||
|
@Override
|
||||||
|
public void keyTraversed(TraverseEvent e) {
|
||||||
|
switch (e.detail) {
|
||||||
|
case SWT.TRAVERSE_TAB_NEXT:
|
||||||
|
editColumnOrNextPossible(nextColumn(editorColumn));
|
||||||
|
e.detail= SWT.TRAVERSE_NONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SWT.TRAVERSE_TAB_PREVIOUS:
|
||||||
|
editColumnOrPrevPossible(prevColumn(editorColumn));
|
||||||
|
e.detail= SWT.TRAVERSE_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (control instanceof Text) {
|
||||||
|
TextFieldNavigationHandler.install((Text) control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cellEditorName.setActivationListener(new TableTextCellEditor.IActivationListener() {
|
||||||
|
@Override
|
||||||
|
public void activate() {
|
||||||
|
NameInformation[] selected= getSelectedElements();
|
||||||
|
if (selected.length == 1 && fNameContentAssistHandler != null) {
|
||||||
|
fNameContentAssistHandler.setEnabled(selected[0].isAdded());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fTableViewer.setCellEditors(editors.toArray(new CellEditor[editors.size()]));
|
||||||
|
fTableViewer.setCellModifier(new ParametersCellModifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- change order ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void moveUp(NameInformation[] selection) {
|
||||||
|
moveUp(fParameters, Arrays.asList(selection));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveDown(NameInformation[] selection) {
|
||||||
|
Collections.reverse(fParameters);
|
||||||
|
moveUp(fParameters, Arrays.asList(selection));
|
||||||
|
Collections.reverse(fParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void moveUp(List<NameInformation> elements, List<NameInformation> move) {
|
||||||
|
List<NameInformation> res= new ArrayList<NameInformation>(elements.size());
|
||||||
|
List<NameInformation> deleted= new ArrayList<NameInformation>();
|
||||||
|
NameInformation floating= null;
|
||||||
|
for (Iterator<NameInformation> iter= elements.iterator(); iter.hasNext();) {
|
||||||
|
NameInformation curr= iter.next();
|
||||||
|
if (move.contains(curr)) {
|
||||||
|
res.add(curr);
|
||||||
|
} else if (curr.isDeleted()) {
|
||||||
|
deleted.add(curr);
|
||||||
|
} else {
|
||||||
|
if (floating != null)
|
||||||
|
res.add(floating);
|
||||||
|
floating= curr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (floating != null) {
|
||||||
|
res.add(floating);
|
||||||
|
}
|
||||||
|
res.addAll(deleted);
|
||||||
|
elements.clear();
|
||||||
|
for (Iterator<NameInformation> iter= res.iterator(); iter.hasNext();) {
|
||||||
|
elements.add(iter.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canMove(boolean up) {
|
||||||
|
int notDeletedInfosCount= getNotDeletedInfosCount();
|
||||||
|
if (notDeletedInfosCount == 0)
|
||||||
|
return false;
|
||||||
|
int[] indc= getTable().getSelectionIndices();
|
||||||
|
if (indc.length == 0)
|
||||||
|
return false;
|
||||||
|
int invalid= up ? 0 : notDeletedInfosCount - 1;
|
||||||
|
for (int i= 0; i < indc.length; i++) {
|
||||||
|
if (indc[i] == invalid)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getNotDeletedInfosCount() {
|
||||||
|
if (fParameters == null) // during initialization
|
||||||
|
return 0;
|
||||||
|
int result= 0;
|
||||||
|
for (Iterator<NameInformation> iter= fParameters.iterator(); iter.hasNext();) {
|
||||||
|
NameInformation info= iter.next();
|
||||||
|
if (!info.isDeleted())
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SubjectControlContentAssistant installParameterNameContentAssist(Text text) {
|
||||||
|
return null;
|
||||||
|
// TODO(sprigogin): Implement to support parameter name content assist.
|
||||||
|
// VariableNamesProcessor processor= new VariableNamesProcessor(fParamNameProposals);
|
||||||
|
// SubjectControlContentAssistant contentAssistant= ControlContentAssistHelper.createCContentAssistant(processor);
|
||||||
|
// fNameContentAssistHandler= ContentAssistHandler.createHandlerForText(text, contentAssistant);
|
||||||
|
// return contentAssistant;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2012 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
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.refactoring;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ChangeParametersControl
|
||||||
|
*/
|
||||||
|
public interface IParameterListChangeListener {
|
||||||
|
/**
|
||||||
|
* Gets fired when the given parameter has changed
|
||||||
|
* @param parameter the parameter that has changed.
|
||||||
|
*/
|
||||||
|
public void parameterChanged(NameInformation parameter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets fired when the given parameter has been added
|
||||||
|
* @param parameter the parameter that has been added.
|
||||||
|
*/
|
||||||
|
public void parameterAdded(NameInformation parameter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets fired if the parameter list got modified by reordering or removing
|
||||||
|
* parameters (note that adding is handled by <code>parameterAdded</code>))
|
||||||
|
*/
|
||||||
|
public void parameterListChanged();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -35,7 +35,6 @@ public final class Messages extends NLS {
|
||||||
public static String Refactoring_CantLoadTU;
|
public static String Refactoring_CantLoadTU;
|
||||||
public static String Refactoring_Ambiguity;
|
public static String Refactoring_Ambiguity;
|
||||||
public static String Refactoring_ParsingError;
|
public static String Refactoring_ParsingError;
|
||||||
public static String NO_FILE;
|
|
||||||
public static String RefactoringSaveHelper_unexpected_exception;
|
public static String RefactoringSaveHelper_unexpected_exception;
|
||||||
public static String RefactoringSaveHelper_saving;
|
public static String RefactoringSaveHelper_saving;
|
||||||
public static String RefactoringSaveHelper_always_save;
|
public static String RefactoringSaveHelper_always_save;
|
||||||
|
@ -49,6 +48,28 @@ public final class Messages extends NLS {
|
||||||
public static String ChangeExceptionHandler_undo_button;
|
public static String ChangeExceptionHandler_undo_button;
|
||||||
public static String ChangeExceptionHandler_undo_dialog_message;
|
public static String ChangeExceptionHandler_undo_dialog_message;
|
||||||
public static String ChangeExceptionHandler_undo_dialog_title;
|
public static String ChangeExceptionHandler_undo_dialog_title;
|
||||||
|
public static String ChangeParametersControl_table_type;
|
||||||
|
public static String ChangeParametersControl_table_direction;
|
||||||
|
public static String ChangeParametersControl_table_name;
|
||||||
|
public static String ChangeParametersControl_table_default_value;
|
||||||
|
public static String ChangeParametersControl_input;
|
||||||
|
public static String ChangeParametersControl_output;
|
||||||
|
public static String ChangeParametersControl_return;
|
||||||
|
public static String ChangeParametersControl_buttons_move_up;
|
||||||
|
public static String ChangeParametersControl_buttons_move_down;
|
||||||
|
public static String ChangeParametersControl_buttons_edit;
|
||||||
|
public static String ChangeParametersControl_buttons_add;
|
||||||
|
public static String ChangeParametersControl_buttons_remove;
|
||||||
|
public static String ParameterEditDialog_title;
|
||||||
|
public static String ParameterEditDialog_message_new;
|
||||||
|
public static String ParameterEditDialog_message;
|
||||||
|
public static String ParameterEditDialog_type;
|
||||||
|
public static String ParameterEditDialog_name;
|
||||||
|
public static String ParameterEditDialog_name_error;
|
||||||
|
public static String ParameterEditDialog_default_value;
|
||||||
|
public static String ParameterEditDialog_default_value_error;
|
||||||
|
public static String ParameterEditDialog_default_value_invalid;
|
||||||
|
public static String ParameterEditDialog_use_as_return;
|
||||||
public static String RefactoringExecutionHelper_cannot_execute;
|
public static String RefactoringExecutionHelper_cannot_execute;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
# Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
# Rapperswil, University of applied sciences and others
|
# Rapperswil, University of applied sciences 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
|
||||||
|
@ -22,7 +22,7 @@ Refactoring_CanceledByUser=Refactoring canceled by user.
|
||||||
Refactoring_CompileErrorInTU=The translation unit contains one or several problems. This can be caused by a syntax error in the code or a parser flaw. The refactoring will possibly fail.
|
Refactoring_CompileErrorInTU=The translation unit contains one or several problems. This can be caused by a syntax error in the code or a parser flaw. The refactoring will possibly fail.
|
||||||
AddDeclarationNodeToClassChange_AddDeclaration=Add Declaration to Class {0}.
|
AddDeclarationNodeToClassChange_AddDeclaration=Add Declaration to Class {0}.
|
||||||
CreateFileChange_CreateFile=Create file: {0}
|
CreateFileChange_CreateFile=Create file: {0}
|
||||||
CreateFileChange_UnknownLoc=Unknown Location: {0}
|
CreateFileChange_UnknownLoc=Unknown location: {0}
|
||||||
CreateFileChange_FileExists=File already exists: {0}
|
CreateFileChange_FileExists=File already exists: {0}
|
||||||
CRefactoring_FileNotFound=The file {0} is not on the build path of a C/C++ project.
|
CRefactoring_FileNotFound=The file {0} is not on the build path of a C/C++ project.
|
||||||
CRefactoring_checking_final_conditions=Checking preconditions...
|
CRefactoring_checking_final_conditions=Checking preconditions...
|
||||||
|
@ -30,7 +30,6 @@ Refactoring_SelectionNotValid=Selection is not valid.
|
||||||
Refactoring_CantLoadTU=Can not load translation unit.
|
Refactoring_CantLoadTU=Can not load translation unit.
|
||||||
Refactoring_Ambiguity=Translation unit is ambiguous.
|
Refactoring_Ambiguity=Translation unit is ambiguous.
|
||||||
Refactoring_ParsingError=Unable to parse {0}.
|
Refactoring_ParsingError=Unable to parse {0}.
|
||||||
NO_FILE=File not found.
|
|
||||||
RefactoringSaveHelper_unexpected_exception=An unexpected exception occurred. See the error log for more details.
|
RefactoringSaveHelper_unexpected_exception=An unexpected exception occurred. See the error log for more details.
|
||||||
RefactoringSaveHelper_saving=Saving Resources
|
RefactoringSaveHelper_saving=Saving Resources
|
||||||
RefactoringSaveHelper_always_save=&Always save all modified resources automatically prior to refactoring
|
RefactoringSaveHelper_always_save=&Always save all modified resources automatically prior to refactoring
|
||||||
|
@ -44,4 +43,26 @@ ChangeExceptionHandler_status_without_detail=Exception does not provide a detail
|
||||||
ChangeExceptionHandler_undo_dialog_title=Undo Refactoring
|
ChangeExceptionHandler_undo_dialog_title=Undo Refactoring
|
||||||
ChangeExceptionHandler_undo_dialog_message=An unexpected exception occurred while undoing the refactoring ''{0}''
|
ChangeExceptionHandler_undo_dialog_message=An unexpected exception occurred while undoing the refactoring ''{0}''
|
||||||
ChangeExceptionHandler_dialog_message=An exception has been caught while processing the refactoring ''{0}''.
|
ChangeExceptionHandler_dialog_message=An exception has been caught while processing the refactoring ''{0}''.
|
||||||
|
ChangeParametersControl_table_type=Type
|
||||||
|
ChangeParametersControl_table_direction=Input/Output
|
||||||
|
ChangeParametersControl_table_name=Name
|
||||||
|
ChangeParametersControl_table_default_value=Default value
|
||||||
|
ChangeParametersControl_input=input
|
||||||
|
ChangeParametersControl_output=output
|
||||||
|
ChangeParametersControl_return=return
|
||||||
|
ChangeParametersControl_buttons_move_up=&Up
|
||||||
|
ChangeParametersControl_buttons_move_down=D&own
|
||||||
|
ChangeParametersControl_buttons_edit=&Edit...
|
||||||
|
ChangeParametersControl_buttons_add=&Add
|
||||||
|
ChangeParametersControl_buttons_remove=Re&move
|
||||||
|
ParameterEditDialog_title=Function Parameter
|
||||||
|
ParameterEditDialog_message_new=Declaration of parameter:
|
||||||
|
ParameterEditDialog_message=Declaration of parameter ''{0}'':
|
||||||
|
ParameterEditDialog_type=&Type:
|
||||||
|
ParameterEditDialog_name=&Name:
|
||||||
|
ParameterEditDialog_name_error= Parameter name must not be empty.
|
||||||
|
ParameterEditDialog_default_value=&Default value:
|
||||||
|
ParameterEditDialog_default_value_error= Default value must not be empty.
|
||||||
|
ParameterEditDialog_default_value_invalid=''{0}'' is not a valid expression.
|
||||||
|
ParameterEditDialog_use_as_return=Use as &return value
|
||||||
RefactoringExecutionHelper_cannot_execute=The operation cannot be performed due to the following problem:\n\n{0}
|
RefactoringExecutionHelper_cannot_execute=The operation cannot be performed due to the following problem:\n\n{0}
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
|
* Rapperswil, University of applied sciences and others
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.refactoring;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional information about an IASTName in code being refactored.
|
||||||
|
*/
|
||||||
|
public class NameInformation {
|
||||||
|
public static final int INDEX_FOR_ADDED = -1;
|
||||||
|
|
||||||
|
private final IASTName name;
|
||||||
|
private IASTName declarationName;
|
||||||
|
private final List<IASTName> references;
|
||||||
|
private List<IASTName> referencesAfterCached;
|
||||||
|
private int lastCachedReferencesHash;
|
||||||
|
private boolean isOutput;
|
||||||
|
private boolean mustBeReturnValue;
|
||||||
|
private boolean isWriteAccess;
|
||||||
|
private boolean passOutputByPointer;
|
||||||
|
private boolean isReturnValue;
|
||||||
|
private String newName;
|
||||||
|
private int newOrder;
|
||||||
|
private boolean isDeleted;
|
||||||
|
private String defaultValue;
|
||||||
|
private String newTypeName;
|
||||||
|
|
||||||
|
public NameInformation(IASTName name) {
|
||||||
|
this.name = name;
|
||||||
|
this.newName = String.valueOf(name.getSimpleID());
|
||||||
|
references = new ArrayList<IASTName>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NameInformation createInfoForAddedParameter(String type, String name,
|
||||||
|
String defaultValue) {
|
||||||
|
NameInformation info= new NameInformation(null);
|
||||||
|
info.setTypeName(type);
|
||||||
|
info.setNewName(name);
|
||||||
|
info.setDefaultValue(defaultValue);
|
||||||
|
info.setNewOrder(INDEX_FOR_ADDED);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For debugging only.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNewOrder() {
|
||||||
|
return newOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewOrder(int newOrder) {
|
||||||
|
this.newOrder = newOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if the value of the variable has to propagate to the outside world.
|
||||||
|
*/
|
||||||
|
public boolean isOutput() {
|
||||||
|
return isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOutput(boolean isOutput) {
|
||||||
|
this.isOutput = isOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOutputParameter() {
|
||||||
|
return isOutput() && !isReturnValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean mustBeReturnValue() {
|
||||||
|
return mustBeReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMustBeReturnValue(boolean mustBeReturnValue) {
|
||||||
|
this.mustBeReturnValue = mustBeReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReturnValue() {
|
||||||
|
return mustBeReturnValue || isReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReturnValue(boolean isReturnValue) {
|
||||||
|
Assert.isTrue(isReturnValue || !mustBeReturnValue);
|
||||||
|
this.isReturnValue = isReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewName() {
|
||||||
|
return newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewName(String newName) {
|
||||||
|
this.newName = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWriteAccess() {
|
||||||
|
return isWriteAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWriteAccess(boolean isWriteAceess) {
|
||||||
|
this.isWriteAccess = isWriteAceess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return isDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markAsDeleted() {
|
||||||
|
Assert.isTrue(!isAdded()); // Added parameters should be simply removed from the list
|
||||||
|
isDeleted= true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAdded() {
|
||||||
|
// TODO(sprigogin): Adding parameters is not supported yet.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultValue(String value) {
|
||||||
|
Assert.isNotNull(value);
|
||||||
|
defaultValue= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTName getDeclarationName() {
|
||||||
|
return declarationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTDeclarator getDeclarator() {
|
||||||
|
return (IASTDeclarator) declarationName.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTDeclSpecifier getDeclSpecifier() {
|
||||||
|
IASTNode parent = getDeclarator().getParent();
|
||||||
|
if (parent instanceof IASTSimpleDeclaration) {
|
||||||
|
return ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||||
|
} else if (parent instanceof IASTParameterDeclaration) {
|
||||||
|
return ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDeclarationName(IASTName declarationName) {
|
||||||
|
Assert.isTrue(declarationName.getParent() instanceof IASTDeclarator);
|
||||||
|
this.declarationName = declarationName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTName getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRenamed() {
|
||||||
|
return name == null ? newName != null : String.valueOf(name.getSimpleID()).equals(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addReference(IASTName name) {
|
||||||
|
references.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTypeName() {
|
||||||
|
if (newTypeName != null)
|
||||||
|
return newTypeName;
|
||||||
|
INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory();
|
||||||
|
IASTParameterDeclaration declaration = getParameterDeclaration(nodeFactory, null);
|
||||||
|
ASTWriterVisitor writer = new ASTWriterVisitor();
|
||||||
|
declaration.accept(writer);
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeName(String type) {
|
||||||
|
Assert.isNotNull(type);
|
||||||
|
newTypeName= type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReturnType() {
|
||||||
|
if (!isReturnValue())
|
||||||
|
return null;
|
||||||
|
INodeFactory nodeFactory = name.getTranslationUnit().getASTNodeFactory();
|
||||||
|
IASTDeclarator sourceDeclarator = getDeclarator();
|
||||||
|
IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier());
|
||||||
|
IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, null);
|
||||||
|
IASTParameterDeclaration declaration = nodeFactory.newParameterDeclaration(declSpec, declarator);
|
||||||
|
ASTWriterVisitor writer = new ASTWriterVisitor();
|
||||||
|
declaration.accept(writer);
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IASTName> getReferencesAfterSelection(int endOffset) {
|
||||||
|
if (referencesAfterCached == null || lastCachedReferencesHash != references.hashCode()) {
|
||||||
|
lastCachedReferencesHash = references.hashCode();
|
||||||
|
referencesAfterCached = new ArrayList<IASTName>();
|
||||||
|
for (IASTName ref : references) {
|
||||||
|
IASTFileLocation loc = ref.getFileLocation();
|
||||||
|
if (loc.getNodeOffset() >= endOffset) {
|
||||||
|
referencesAfterCached.add(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return referencesAfterCached;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReferencedAfterSelection(int endOffset) {
|
||||||
|
return !getReferencesAfterSelection(endOffset).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory) {
|
||||||
|
return getParameterDeclaration(nodeFactory, newName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory, String paramName) {
|
||||||
|
IASTDeclarator sourceDeclarator = getDeclarator();
|
||||||
|
IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier());
|
||||||
|
IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, paramName);
|
||||||
|
|
||||||
|
if (isOutputParameter()) {
|
||||||
|
if (nodeFactory instanceof ICPPNodeFactory && !passOutputByPointer) {
|
||||||
|
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
||||||
|
} else {
|
||||||
|
declarator.addPointerOperator(nodeFactory.newPointer());
|
||||||
|
}
|
||||||
|
} else if (declSpec != null && !isWriteAccess) {
|
||||||
|
IType type = TypeHelper.createType(sourceDeclarator);
|
||||||
|
if (TypeHelper.shouldBePassedByReference(type, declarationName.getTranslationUnit())) {
|
||||||
|
if (nodeFactory instanceof ICPPNodeFactory) {
|
||||||
|
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
||||||
|
} else {
|
||||||
|
declarator.addPointerOperator(nodeFactory.newPointer());
|
||||||
|
}
|
||||||
|
declSpec.setConst(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declarator.setNestedDeclarator(sourceDeclarator.getNestedDeclarator());
|
||||||
|
|
||||||
|
return nodeFactory.newParameterDeclaration(declSpec, declarator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTDeclarator createDeclarator(INodeFactory nodeFactory, IASTDeclarator sourceDeclarator,
|
||||||
|
String name) {
|
||||||
|
IASTName astName = name != null ?
|
||||||
|
nodeFactory.newName(name.toCharArray()) : nodeFactory.newName();
|
||||||
|
IASTDeclarator declarator;
|
||||||
|
if (sourceDeclarator instanceof IASTArrayDeclarator) {
|
||||||
|
IASTArrayDeclarator arrDeclarator = (IASTArrayDeclarator) sourceDeclarator;
|
||||||
|
IASTArrayDeclarator arrayDeclarator = nodeFactory.newArrayDeclarator(astName);
|
||||||
|
IASTArrayModifier[] arrayModifiers = arrDeclarator.getArrayModifiers();
|
||||||
|
for (IASTArrayModifier arrayModifier : arrayModifiers) {
|
||||||
|
arrayDeclarator.addArrayModifier(arrayModifier.copy(CopyStyle.withLocations));
|
||||||
|
}
|
||||||
|
declarator= arrayDeclarator;
|
||||||
|
} else {
|
||||||
|
declarator = nodeFactory.newDeclarator(astName);
|
||||||
|
}
|
||||||
|
for (IASTPointerOperator pointerOp : sourceDeclarator.getPointerOperators()) {
|
||||||
|
declarator.addPointerOperator(pointerOp.copy(CopyStyle.withLocations));
|
||||||
|
}
|
||||||
|
return declarator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T extends IASTNode> T safeCopy(T node) {
|
||||||
|
return node == null ? null : (T) node.copy(CopyStyle.withLocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITranslationUnit getTranslationUnit() {
|
||||||
|
return name != null ? name.getTranslationUnit().getOriginatingTranslationUnit() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPassOutputByPointer() {
|
||||||
|
return passOutputByPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassOutputByPointer(boolean passOutputByPointer) {
|
||||||
|
this.passOutputByPointer = passOutputByPointer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -18,263 +18,39 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.Assert;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.runtime.ILog;
|
import org.eclipse.core.runtime.ILog;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.preferences.IPreferencesService;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||||
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.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
|
||||||
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.INodeFactory;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
|
||||||
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.rewrite.astwriter.ASTWriter;
|
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||||
|
|
||||||
public class NodeContainer {
|
public class NodeContainer {
|
||||||
public final NameInformation NULL_NAME_INFORMATION = new NameInformation(new CPPASTName());
|
|
||||||
|
|
||||||
private final List<IASTNode> nodes;
|
private final List<IASTNode> nodes;
|
||||||
private List<NameInformation> names;
|
private List<NameInformation> names;
|
||||||
private List<NameInformation> interfaceNames;
|
private List<NameInformation> interfaceNames;
|
||||||
|
|
||||||
public class NameInformation {
|
|
||||||
private IASTName name;
|
|
||||||
private IASTName declaration;
|
|
||||||
private final List<IASTName> references;
|
|
||||||
private List<IASTName> referencesAfterCached;
|
|
||||||
private int lastCachedReferencesHash;
|
|
||||||
private boolean mustBeOutput;
|
|
||||||
private boolean mustBeReturnValue;
|
|
||||||
private boolean isConst;
|
|
||||||
private boolean isWriteAccess;
|
|
||||||
|
|
||||||
private boolean isOutput;
|
|
||||||
private boolean isReturnValue;
|
|
||||||
private String userSetName;
|
|
||||||
private int userOrder;
|
|
||||||
|
|
||||||
public int getUserOrder() {
|
|
||||||
return userOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserOrder(int userOrder) {
|
|
||||||
this.userOrder = userOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NameInformation(IASTName name) {
|
|
||||||
super();
|
|
||||||
this.name = name;
|
|
||||||
references = new ArrayList<IASTName>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IASTName getDeclaration() {
|
|
||||||
return declaration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDeclaration(IASTName declaration) {
|
|
||||||
this.declaration = declaration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IASTName getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(IASTName name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addReference(IASTName name) {
|
|
||||||
references.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<IASTName> getReferencesAfterSelection() {
|
|
||||||
if (referencesAfterCached == null || lastCachedReferencesHash != references.hashCode()) {
|
|
||||||
lastCachedReferencesHash = references.hashCode();
|
|
||||||
referencesAfterCached = new ArrayList<IASTName>();
|
|
||||||
for (IASTName ref : references) {
|
|
||||||
IASTFileLocation loc = ref.getFileLocation();
|
|
||||||
if (loc.getNodeOffset() >= getEndOffset()) {
|
|
||||||
referencesAfterCached.add(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return referencesAfterCached;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReferencedAfterSelection() {
|
|
||||||
return !getReferencesAfterSelection().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory) {
|
|
||||||
IASTDeclarator sourceDeclarator = (IASTDeclarator) getDeclaration().getParent();
|
|
||||||
|
|
||||||
IASTDeclSpecifier declSpec= null;
|
|
||||||
IASTDeclarator declarator= null;
|
|
||||||
|
|
||||||
if (sourceDeclarator.getParent() instanceof IASTSimpleDeclaration) {
|
|
||||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) sourceDeclarator.getParent();
|
|
||||||
declSpec = decl.getDeclSpecifier().copy(CopyStyle.withLocations);
|
|
||||||
} else if (sourceDeclarator.getParent() instanceof IASTParameterDeclaration) {
|
|
||||||
IASTParameterDeclaration decl = (IASTParameterDeclaration) sourceDeclarator.getParent();
|
|
||||||
declSpec = decl.getDeclSpecifier().copy(CopyStyle.withLocations);
|
|
||||||
}
|
|
||||||
|
|
||||||
IASTName name= nodeFactory.newName(getDeclaration().toCharArray());
|
|
||||||
if (sourceDeclarator instanceof IASTArrayDeclarator) {
|
|
||||||
IASTArrayDeclarator arrDeclarator = (IASTArrayDeclarator) sourceDeclarator;
|
|
||||||
IASTArrayDeclarator arrayDtor = nodeFactory.newArrayDeclarator(name);
|
|
||||||
IASTArrayModifier[] arrayModifiers = arrDeclarator.getArrayModifiers();
|
|
||||||
for (IASTArrayModifier arrayModifier : arrayModifiers) {
|
|
||||||
arrayDtor.addArrayModifier(arrayModifier.copy(CopyStyle.withLocations));
|
|
||||||
}
|
|
||||||
declarator= arrayDtor;
|
|
||||||
} else {
|
|
||||||
declarator = nodeFactory.newDeclarator(name);
|
|
||||||
}
|
|
||||||
for (IASTPointerOperator pointerOp : sourceDeclarator.getPointerOperators()) {
|
|
||||||
declarator.addPointerOperator(pointerOp.copy(CopyStyle.withLocations));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean output = isOutput() && !isReturnValue();
|
|
||||||
if (output && !hasReferenceOperator(declarator)) {
|
|
||||||
if (nodeFactory instanceof ICPPNodeFactory) {
|
|
||||||
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
|
||||||
} else {
|
|
||||||
declarator.addPointerOperator(nodeFactory.newPointer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declarator.setNestedDeclarator(sourceDeclarator.getNestedDeclarator());
|
|
||||||
|
|
||||||
return nodeFactory.newParameterDeclaration(declSpec, declarator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasReferenceOperator(IASTDeclarator declarator) {
|
|
||||||
for (IASTPointerOperator pOp : declarator.getPointerOperators()) {
|
|
||||||
if (pOp instanceof ICPPASTReferenceOperator) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
IASTDeclSpecifier declSpec = null;
|
|
||||||
|
|
||||||
IASTNode node = getDeclaration().getParent();
|
|
||||||
if (node instanceof ICPPASTSimpleTypeTemplateParameter) {
|
|
||||||
ICPPASTSimpleTypeTemplateParameter parameter = (ICPPASTSimpleTypeTemplateParameter) node;
|
|
||||||
return parameter.getName().toString();
|
|
||||||
}
|
|
||||||
IASTDeclarator sourceDeclarator = (IASTDeclarator) node;
|
|
||||||
if (sourceDeclarator.getParent() instanceof IASTSimpleDeclaration) {
|
|
||||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) sourceDeclarator.getParent();
|
|
||||||
declSpec = decl.getDeclSpecifier();
|
|
||||||
} else if (sourceDeclarator.getParent() instanceof IASTParameterDeclaration) {
|
|
||||||
IASTParameterDeclaration decl = (IASTParameterDeclaration) sourceDeclarator.getParent();
|
|
||||||
declSpec = decl.getDeclSpecifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
ASTWriter writer = new ASTWriter();
|
|
||||||
return writer.write(declSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDeclaredInSelection() {
|
|
||||||
if (declaration != null && declaration.toCharArray().length > 0) {
|
|
||||||
int declOffset = declaration.getFileLocation().getNodeOffset();
|
|
||||||
return declOffset >= getStartOffset() && declOffset <= getEndOffset();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return name.toString() + (isDeclaredInSelection() ? " (declared inside)" : ""); //$NON-NLS-1$//$NON-NLS-2$
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mustBeOutput() {
|
|
||||||
return mustBeOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMustBeOutput(boolean mustBeOutput) {
|
|
||||||
this.mustBeOutput = mustBeOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOutput() {
|
|
||||||
return mustBeOutput || isOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsOutput(boolean isOutput) {
|
|
||||||
Assert.isTrue(isOutput || !mustBeOutput);
|
|
||||||
this.isOutput = isOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mustBeReturnValue() {
|
|
||||||
return mustBeReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMustBeReturnValue(boolean mustBeReturnValue) {
|
|
||||||
this.mustBeReturnValue = mustBeReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isReturnValue() {
|
|
||||||
return mustBeReturnValue || isReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReturnValue(boolean isReturnValue) {
|
|
||||||
Assert.isTrue(isReturnValue || !mustBeReturnValue);
|
|
||||||
this.isReturnValue = isReturnValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUserSetName() {
|
|
||||||
return userSetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserSetName(String userSetName) {
|
|
||||||
this.userSetName = userSetName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isConst() {
|
|
||||||
return isConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConst(boolean isConst) {
|
|
||||||
this.isConst = isConst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWriteAccess() {
|
|
||||||
return isWriteAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setWriteAccess(boolean isWriteAceess) {
|
|
||||||
this.isWriteAccess = isWriteAceess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeContainer() {
|
public NodeContainer() {
|
||||||
super();
|
super();
|
||||||
nodes = new ArrayList<IASTNode>();
|
nodes = new ArrayList<IASTNode>();
|
||||||
|
@ -297,6 +73,12 @@ public class NodeContainer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
names = new ArrayList<NameInformation>();
|
names = new ArrayList<NameInformation>();
|
||||||
|
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
final boolean passOutputByPointer = preferences.getBoolean(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER, false,
|
||||||
|
PreferenceConstants.getPreferenceScopes(getProject()));
|
||||||
|
|
||||||
for (IASTNode node : nodes) {
|
for (IASTNode node : nodes) {
|
||||||
node.accept(new ASTVisitor() {
|
node.accept(new ASTVisitor() {
|
||||||
{
|
{
|
||||||
|
@ -305,18 +87,19 @@ public class NodeContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTName name) {
|
public int visit(IASTName name) {
|
||||||
IBinding bind = name.resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
|
|
||||||
if (bind instanceof ICPPBinding && !(bind instanceof ICPPTemplateTypeParameter)) {
|
if (binding instanceof ICPPBinding && !(binding instanceof ICPPTemplateTypeParameter)) {
|
||||||
ICPPBinding cppBind = (ICPPBinding) bind;
|
ICPPBinding cppBinding = (ICPPBinding) binding;
|
||||||
try {
|
try {
|
||||||
if (!cppBind.isGloballyQualified()) {
|
if (!cppBinding.isGloballyQualified()) {
|
||||||
NameInformation nameInformation = new NameInformation(name);
|
NameInformation nameInfo = new NameInformation(name);
|
||||||
IASTName[] refs = name.getTranslationUnit().getReferences(bind);
|
nameInfo.setPassOutputByPointer(passOutputByPointer);
|
||||||
|
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||||
for (IASTName ref : refs) {
|
for (IASTName ref : refs) {
|
||||||
nameInformation.addReference(ref);
|
nameInfo.addReference(ref);
|
||||||
}
|
}
|
||||||
names.add(nameInformation);
|
names.add(nameInfo);
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
ILog logger = CUIPlugin.getDefault().getLog();
|
ILog logger = CUIPlugin.getDefault().getLog();
|
||||||
|
@ -324,10 +107,10 @@ public class NodeContainer {
|
||||||
CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
|
CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
|
||||||
logger.log(status);
|
logger.log(status);
|
||||||
}
|
}
|
||||||
} else if (bind instanceof IVariable) {
|
} else if (binding instanceof IVariable) {
|
||||||
NameInformation nameInformation = new NameInformation(name);
|
NameInformation nameInformation = new NameInformation(name);
|
||||||
|
|
||||||
IASTName[] refs = name.getTranslationUnit().getReferences(bind);
|
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||||
for (IASTName ref : refs) {
|
for (IASTName ref : refs) {
|
||||||
nameInformation.addReference(ref);
|
nameInformation.addReference(ref);
|
||||||
}
|
}
|
||||||
|
@ -344,11 +127,21 @@ public class NodeContainer {
|
||||||
IASTTranslationUnit unit = name.getTranslationUnit();
|
IASTTranslationUnit unit = name.getTranslationUnit();
|
||||||
IASTName[] nameDeclarations = unit.getDeclarationsInAST(name.resolveBinding());
|
IASTName[] nameDeclarations = unit.getDeclarationsInAST(name.resolveBinding());
|
||||||
if (nameDeclarations.length != 0) {
|
if (nameDeclarations.length != 0) {
|
||||||
nameInfo.setDeclaration(nameDeclarations[nameDeclarations.length - 1]);
|
nameInfo.setDeclarationName(nameDeclarations[nameDeclarations.length - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IProject getProject() {
|
||||||
|
IProject project = null;
|
||||||
|
if (nodes.isEmpty()) {
|
||||||
|
ITranslationUnit tu = nodes.get(0).getTranslationUnit().getOriginatingTranslationUnit();
|
||||||
|
if (tu != null)
|
||||||
|
project = tu.getCProject().getProject();
|
||||||
|
}
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns names that are either parameter or return value candidates.
|
* Returns names that are either parameter or return value candidates.
|
||||||
*/
|
*/
|
||||||
|
@ -359,25 +152,30 @@ public class NodeContainer {
|
||||||
Set<IASTName> declarations = new HashSet<IASTName>();
|
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||||
interfaceNames = new ArrayList<NameInformation>();
|
interfaceNames = new ArrayList<NameInformation>();
|
||||||
|
|
||||||
|
int endOffset = getEndOffset();
|
||||||
for (NameInformation nameInfo : names) {
|
for (NameInformation nameInfo : names) {
|
||||||
if (declarations.add(nameInfo.getDeclaration())) {
|
IASTName declarationName = nameInfo.getDeclarationName();
|
||||||
if (nameInfo.isDeclaredInSelection()) {
|
if (declarations.add(declarationName)) {
|
||||||
if (nameInfo.isReferencedAfterSelection()) {
|
if (isDeclaredInSelection(nameInfo)) {
|
||||||
|
if (nameInfo.isReferencedAfterSelection(endOffset)) {
|
||||||
nameInfo.setMustBeReturnValue(true);
|
nameInfo.setMustBeReturnValue(true);
|
||||||
interfaceNames.add(nameInfo);
|
interfaceNames.add(nameInfo);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (NameInformation n2 : names) {
|
IASTDeclarator declarator = (IASTDeclarator) declarationName.getParent();
|
||||||
if (n2.getDeclaration() == nameInfo.getDeclaration()) {
|
if (!hasReferenceOperator(declarator)) {
|
||||||
int flag = CPPVariableReadWriteFlags.getReadWriteFlags(n2.getName());
|
for (NameInformation n2 : names) {
|
||||||
if ((flag & PDOMName.WRITE_ACCESS) != 0) {
|
if (n2.getDeclarationName() == declarationName) {
|
||||||
nameInfo.setWriteAccess(true);
|
int flag = CPPVariableReadWriteFlags.getReadWriteFlags(n2.getName());
|
||||||
break;
|
if ((flag & PDOMName.WRITE_ACCESS) != 0) {
|
||||||
|
nameInfo.setWriteAccess(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection(endOffset)) {
|
||||||
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection()) {
|
nameInfo.setOutput(true);
|
||||||
nameInfo.setMustBeOutput(true);
|
}
|
||||||
}
|
}
|
||||||
interfaceNames.add(nameInfo);
|
interfaceNames.add(nameInfo);
|
||||||
}
|
}
|
||||||
|
@ -388,6 +186,20 @@ public class NodeContainer {
|
||||||
return interfaceNames;
|
return interfaceNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hasReferenceOperator(IASTDeclarator declarator) {
|
||||||
|
IASTPointerOperator[] operators = declarator.getPointerOperators();
|
||||||
|
return operators.length != 0 && operators[operators.length - 1] instanceof ICPPASTReferenceOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeclaredInSelection(NameInformation nameInfo) {
|
||||||
|
IASTName declaration = nameInfo.getDeclarationName();
|
||||||
|
if (declaration != null && declaration.toCharArray().length > 0) {
|
||||||
|
int declOffset = declaration.getFileLocation().getNodeOffset();
|
||||||
|
return declOffset >= getStartOffset() && declOffset <= getEndOffset();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private List<NameInformation> getInterfaceNames(boolean isReturnValue) {
|
private List<NameInformation> getInterfaceNames(boolean isReturnValue) {
|
||||||
List<NameInformation> selectedNames = null;
|
List<NameInformation> selectedNames = null;
|
||||||
|
|
||||||
|
@ -412,7 +224,6 @@ public class NodeContainer {
|
||||||
return getInterfaceNames(false);
|
return getInterfaceNames(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns names that are candidates for being used as the function return value. Multiple
|
* Returns names that are candidates for being used as the function return value. Multiple
|
||||||
* return value candidates mean that the function cannot be extracted.
|
* return value candidates mean that the function cannot be extracted.
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2012 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
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.refactoring;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.jface.dialogs.StatusDialog;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.ModifyEvent;
|
||||||
|
import org.eclipse.swt.events.ModifyListener;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CConventions;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.dialogs.TextFieldNavigationHandler;
|
||||||
|
import org.eclipse.cdt.internal.ui.viewsupport.BasicElementLabels;
|
||||||
|
|
||||||
|
public class ParameterEditDialog extends StatusDialog {
|
||||||
|
private final NameInformation fParameter;
|
||||||
|
private final boolean fEditType;
|
||||||
|
private final boolean fEditDefault;
|
||||||
|
private final boolean fEditReturn;
|
||||||
|
private Text fType;
|
||||||
|
private Text fName;
|
||||||
|
private Text fDefaultValue;
|
||||||
|
private Button fReturn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param parentShell
|
||||||
|
* @param parameter
|
||||||
|
* @param canEditType
|
||||||
|
* @param canEditDefault
|
||||||
|
* @param canChangeReturn
|
||||||
|
* Can be <code>null</code> if <code>canEditType</code> is <code>false</code>.
|
||||||
|
*/
|
||||||
|
public ParameterEditDialog(Shell parentShell, NameInformation parameter, boolean canEditType,
|
||||||
|
boolean canEditDefault, boolean canChangeReturn) {
|
||||||
|
super(parentShell);
|
||||||
|
fParameter= parameter;
|
||||||
|
fEditType= canEditType;
|
||||||
|
fEditDefault= canEditDefault;
|
||||||
|
fEditReturn = canChangeReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureShell(Shell newShell) {
|
||||||
|
super.configureShell(newShell);
|
||||||
|
newShell.setText(Messages.ParameterEditDialog_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Control createDialogArea(Composite parent) {
|
||||||
|
Composite result= (Composite) super.createDialogArea(parent);
|
||||||
|
GridLayout layout= (GridLayout) result.getLayout();
|
||||||
|
layout.numColumns= 2;
|
||||||
|
Label label;
|
||||||
|
GridData gd;
|
||||||
|
|
||||||
|
label= new Label(result, SWT.NONE);
|
||||||
|
String newName = fParameter.getNewName();
|
||||||
|
if (newName.isEmpty()) {
|
||||||
|
label.setText(Messages.ParameterEditDialog_message_new);
|
||||||
|
} else {
|
||||||
|
label.setText(NLS.bind(Messages.ParameterEditDialog_message,
|
||||||
|
BasicElementLabels.getCElementName(newName)));
|
||||||
|
}
|
||||||
|
gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.horizontalSpan= 2;
|
||||||
|
label.setLayoutData(gd);
|
||||||
|
|
||||||
|
if (fEditType) {
|
||||||
|
label= new Label(result, SWT.NONE);
|
||||||
|
label.setText(Messages.ParameterEditDialog_type);
|
||||||
|
fType= new Text(result, SWT.BORDER);
|
||||||
|
gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
fType.setLayoutData(gd);
|
||||||
|
fType.setText(fParameter.getTypeName());
|
||||||
|
fType.addModifyListener(
|
||||||
|
new ModifyListener() {
|
||||||
|
@Override
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
validate((Text) e.widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TextFieldNavigationHandler.install(fType);
|
||||||
|
}
|
||||||
|
|
||||||
|
label= new Label(result, SWT.NONE);
|
||||||
|
fName= new Text(result, SWT.BORDER);
|
||||||
|
initializeDialogUnits(fName);
|
||||||
|
label.setText(Messages.ParameterEditDialog_name);
|
||||||
|
gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.widthHint= convertWidthInCharsToPixels(45);
|
||||||
|
fName.setLayoutData(gd);
|
||||||
|
fName.setText(newName);
|
||||||
|
fName.addModifyListener(
|
||||||
|
new ModifyListener() {
|
||||||
|
@Override
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
validate((Text) e.widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TextFieldNavigationHandler.install(fName);
|
||||||
|
|
||||||
|
if (fEditDefault && fParameter.isAdded()) {
|
||||||
|
label= new Label(result, SWT.NONE);
|
||||||
|
label.setText(Messages.ParameterEditDialog_default_value);
|
||||||
|
fDefaultValue= new Text(result, SWT.BORDER);
|
||||||
|
gd= new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
fDefaultValue.setLayoutData(gd);
|
||||||
|
fDefaultValue.setText(fParameter.getDefaultValue());
|
||||||
|
fDefaultValue.addModifyListener(
|
||||||
|
new ModifyListener() {
|
||||||
|
@Override
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
validate((Text) e.widget);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TextFieldNavigationHandler.install(fDefaultValue);
|
||||||
|
}
|
||||||
|
if (fEditReturn) {
|
||||||
|
fReturn = new Button(result, SWT.CHECK);
|
||||||
|
fReturn.setText(Messages.ParameterEditDialog_use_as_return);
|
||||||
|
fReturn.setSelection(fParameter.isReturnValue());
|
||||||
|
fReturn.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
}
|
||||||
|
applyDialogFont(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void okPressed() {
|
||||||
|
if (fType != null) {
|
||||||
|
fParameter.setTypeName(fType.getText());
|
||||||
|
}
|
||||||
|
fParameter.setNewName(fName.getText());
|
||||||
|
if (fDefaultValue != null) {
|
||||||
|
fParameter.setDefaultValue(fDefaultValue.getText());
|
||||||
|
}
|
||||||
|
if (fReturn != null) {
|
||||||
|
fParameter.setReturnValue(fReturn.getSelection());
|
||||||
|
}
|
||||||
|
super.okPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validate(Text first) {
|
||||||
|
IStatus[] result= new IStatus[3];
|
||||||
|
if (first == fType) {
|
||||||
|
result[0]= validateType();
|
||||||
|
result[1]= validateName();
|
||||||
|
result[2]= validateDefaultValue();
|
||||||
|
} else if (first == fName) {
|
||||||
|
result[0]= validateName();
|
||||||
|
result[1]= validateType();
|
||||||
|
result[2]= validateDefaultValue();
|
||||||
|
} else {
|
||||||
|
result[0]= validateDefaultValue();
|
||||||
|
result[1]= validateName();
|
||||||
|
result[2]= validateType();
|
||||||
|
}
|
||||||
|
for (int i= 0; i < result.length; i++) {
|
||||||
|
IStatus status= result[i];
|
||||||
|
if (status != null && !status.isOK()) {
|
||||||
|
updateStatus(status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateStatus(Status.OK_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IStatus validateType() {
|
||||||
|
// TODO(sprigogin): Implement type validation.
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IStatus validateName() {
|
||||||
|
if (fName == null)
|
||||||
|
return null;
|
||||||
|
String name= fName.getText();
|
||||||
|
if (name.isEmpty())
|
||||||
|
return createErrorStatus(Messages.ParameterEditDialog_name_error);
|
||||||
|
IStatus status= CConventions.validateFieldName(name);
|
||||||
|
if (status.matches(IStatus.ERROR))
|
||||||
|
return status;
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IStatus validateDefaultValue() {
|
||||||
|
if (fDefaultValue == null)
|
||||||
|
return null;
|
||||||
|
String defaultValue= fDefaultValue.getText();
|
||||||
|
if (defaultValue.isEmpty())
|
||||||
|
return createErrorStatus(Messages.ParameterEditDialog_default_value_error);
|
||||||
|
// TODO(sprigogin): Implement real default value validation.
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Status createErrorStatus(String message) {
|
||||||
|
return new Status(IStatus.ERROR, CUIPlugin.getPluginId(), IStatus.ERROR, message, null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2012 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
|
||||||
|
* Sergey Prigogin (Googel)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.refactoring;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
|
||||||
|
public class StubTypeContext {
|
||||||
|
private final ITranslationUnit tu;
|
||||||
|
|
||||||
|
public StubTypeContext(ITranslationUnit tu) {
|
||||||
|
this.tu = tu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ITranslationUnit getTranslationUnit() {
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,204 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
|
||||||
* Rapperswil, University of applied sciences and others
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Institute for Software - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.custom.TableEditor;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Button;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.swt.widgets.Table;
|
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
|
||||||
|
|
||||||
public class ChooserComposite extends Composite {
|
|
||||||
private static final String COLUMN_RETURN = Messages.ChooserComposite_Return;
|
|
||||||
private static final String COLUMN_REFERENCE = Messages.ChooserComposite_CallByRef;
|
|
||||||
private static final String COLUMN_NAME = Messages.ChooserComposite_Name;
|
|
||||||
private static final String COLUMN_TYPE = Messages.ChooserComposite_Type;
|
|
||||||
|
|
||||||
private Button checkboxVoidReturn;
|
|
||||||
|
|
||||||
public ChooserComposite(Composite parent, final ExtractFunctionInformation info,
|
|
||||||
ExtractFunctionInputPage page) {
|
|
||||||
super(parent, SWT.NONE);
|
|
||||||
|
|
||||||
GridLayout layout = new GridLayout();
|
|
||||||
setLayout(layout);
|
|
||||||
|
|
||||||
final ArrayList<Button> returnButtons = new ArrayList<Button>();
|
|
||||||
final ArrayList<Button> referenceButtons = new ArrayList<Button>();
|
|
||||||
|
|
||||||
final Table table = new Table(parent, SWT.BORDER | SWT.MULTI | SWT.FILL);
|
|
||||||
|
|
||||||
GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
|
|
||||||
table.setLayoutData(tableLayoutData);
|
|
||||||
|
|
||||||
table.setLinesVisible(true);
|
|
||||||
table.setHeaderVisible(true);
|
|
||||||
|
|
||||||
addColumnToTable(table, COLUMN_TYPE);
|
|
||||||
addColumnToTable(table, COLUMN_NAME);
|
|
||||||
addColumnToTable(table, COLUMN_REFERENCE);
|
|
||||||
addColumnToTable(table, Messages.ChooserComposite_const);
|
|
||||||
if (!info.isExtractExpression()) {
|
|
||||||
addColumnToTable(table, COLUMN_RETURN);
|
|
||||||
}
|
|
||||||
addColumnToTable(table, ""); //$NON-NLS-1$
|
|
||||||
|
|
||||||
for (int i = 0; i < info.getParameterCandidates().size(); i++) {
|
|
||||||
if (!info.getParameterCandidates().get(i).isDeclaredInSelection()) {
|
|
||||||
TableItem item = new TableItem(table, SWT.NONE);
|
|
||||||
|
|
||||||
TableEditor editor = new TableEditor(table);
|
|
||||||
int columnIndex = 0;
|
|
||||||
|
|
||||||
final NameInformation name = info.getParameterCandidates().get(i);
|
|
||||||
|
|
||||||
// Text
|
|
||||||
item.setText(columnIndex++, name.getType());
|
|
||||||
item.setText(columnIndex++, name.getName().toString());
|
|
||||||
|
|
||||||
// Button
|
|
||||||
editor = new TableEditor(table);
|
|
||||||
final Button buttonOutput = new Button(table, SWT.CHECK);
|
|
||||||
if (name.hasReferenceOperator((IASTDeclarator) name.getDeclaration().getParent())) {
|
|
||||||
buttonOutput.setSelection(true);
|
|
||||||
buttonOutput.setEnabled(false);
|
|
||||||
} else {
|
|
||||||
buttonOutput.setSelection(name.isOutput() && !name.isReturnValue());
|
|
||||||
buttonOutput.setEnabled(!name.mustBeOutput() && !name.isReturnValue());
|
|
||||||
}
|
|
||||||
buttonOutput.setBackground(table.getBackground());
|
|
||||||
buttonOutput.addSelectionListener(new SelectionListener() {
|
|
||||||
@Override
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
widgetSelected(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
if (buttonOutput.isEnabled()) {
|
|
||||||
name.setIsOutput(buttonOutput.getSelection());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buttonOutput.pack();
|
|
||||||
editor.minimumWidth = buttonOutput.getSize().x;
|
|
||||||
editor.horizontalAlignment = SWT.CENTER;
|
|
||||||
referenceButtons.add(buttonOutput);
|
|
||||||
editor.setEditor(buttonOutput, item, columnIndex++);
|
|
||||||
|
|
||||||
// Const button
|
|
||||||
editor = new TableEditor(table);
|
|
||||||
final Button buttonConst = new Button(table, SWT.CHECK);
|
|
||||||
|
|
||||||
buttonConst.setSelection(name.isConst());
|
|
||||||
buttonConst.setEnabled(!name.isWriteAccess());
|
|
||||||
|
|
||||||
buttonConst.setBackground(table.getBackground());
|
|
||||||
buttonConst.addSelectionListener(new SelectionListener() {
|
|
||||||
@Override
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
widgetSelected(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
name.setConst(buttonConst.getSelection());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buttonConst.pack();
|
|
||||||
editor.minimumWidth = buttonConst.getSize().x;
|
|
||||||
editor.horizontalAlignment = SWT.CENTER;
|
|
||||||
// referenceButtons.add(referenceButton);
|
|
||||||
editor.setEditor(buttonConst, item, columnIndex++);
|
|
||||||
|
|
||||||
if (info.isExtractExpression())
|
|
||||||
continue; // Skip the return radiobutton
|
|
||||||
|
|
||||||
// Button
|
|
||||||
editor = new TableEditor(table);
|
|
||||||
final Button buttonReturn = new Button(table, SWT.RADIO);
|
|
||||||
buttonReturn.setSelection(name.mustBeReturnValue());
|
|
||||||
buttonReturn.setEnabled(info.getMandatoryReturnVariable() == null);
|
|
||||||
buttonReturn.setBackground(table.getBackground());
|
|
||||||
buttonReturn.addSelectionListener(new SelectionListener() {
|
|
||||||
@Override
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
widgetSelected(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
name.setReturnValue(buttonReturn.getSelection());
|
|
||||||
if (buttonReturn.getSelection()) {
|
|
||||||
buttonOutput.setSelection(false);
|
|
||||||
buttonOutput.notifyListeners(SWT.Selection, new Event());
|
|
||||||
} else if (name.mustBeOutput()) {
|
|
||||||
buttonOutput.setSelection(true);
|
|
||||||
buttonOutput.notifyListeners(SWT.Selection, new Event());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
buttonReturn.pack();
|
|
||||||
editor.minimumWidth = buttonReturn.getSize().x;
|
|
||||||
editor.horizontalAlignment = SWT.CENTER;
|
|
||||||
returnButtons.add(buttonReturn);
|
|
||||||
editor.setEditor(buttonReturn, item, columnIndex++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info.isExtractExpression()) {
|
|
||||||
checkboxVoidReturn = new Button(parent, SWT.CHECK | SWT.LEFT);
|
|
||||||
checkboxVoidReturn.setText(Messages.ChooserComposite_NoReturnValue);
|
|
||||||
checkboxVoidReturn.setEnabled(info.getMandatoryReturnVariable() == null);
|
|
||||||
checkboxVoidReturn.addSelectionListener(new SelectionListener() {
|
|
||||||
@Override
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
widgetSelected(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
info.setReturnVariable(null);
|
|
||||||
|
|
||||||
for (Button button : returnButtons) {
|
|
||||||
if (checkboxVoidReturn.getSelection()) {
|
|
||||||
button.setSelection(false);
|
|
||||||
button.notifyListeners(SWT.Selection, new Event());
|
|
||||||
}
|
|
||||||
button.setEnabled(!checkboxVoidReturn.getSelection());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addColumnToTable(final Table table, String string) {
|
|
||||||
TableColumn column = new TableColumn(table, SWT.NONE);
|
|
||||||
column.setText(string);
|
|
||||||
column.setWidth(100);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,7 +50,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the extraction of expression nodes, for example, return type determination.
|
* Handles the extraction of expression nodes, for example, return type determination.
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
|
||||||
* Rapperswil, University of applied sciences and others
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* Institute for Software - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.SelectionAdapter;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Button;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Group;
|
|
||||||
import org.eclipse.swt.widgets.Text;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.dialogs.NameAndVisibilityComposite;
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
|
||||||
|
|
||||||
public class ExtractFunctionComposite extends Composite {
|
|
||||||
private Button replaceSimilar;
|
|
||||||
private ChooserComposite comp;
|
|
||||||
private NameAndVisibilityComposite nameVisiComp;
|
|
||||||
private final ExtractFunctionInformation info;
|
|
||||||
|
|
||||||
public ExtractFunctionComposite(Composite parent, ExtractFunctionInformation info,
|
|
||||||
ExtractFunctionInputPage page) {
|
|
||||||
super(parent, SWT.NONE);
|
|
||||||
this.info = info;
|
|
||||||
setLayout(new GridLayout());
|
|
||||||
|
|
||||||
createNewMethodNameComposite(this);
|
|
||||||
|
|
||||||
Group returnGroup = createReturnGroup(nameVisiComp);
|
|
||||||
createReturnValueChooser(returnGroup, info, page);
|
|
||||||
|
|
||||||
createReplaceCheckBox(nameVisiComp);
|
|
||||||
|
|
||||||
if (info.getMethodContext().getType() == MethodContext.ContextType.METHOD) {
|
|
||||||
visibilityPanelSetVisible(true);
|
|
||||||
} else {
|
|
||||||
visibilityPanelSetVisible(false);
|
|
||||||
}
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Group createReturnGroup(Composite parent) {
|
|
||||||
Group returnGroup = new Group(parent,SWT.NONE);
|
|
||||||
|
|
||||||
returnGroup.setText(Messages.ExtractFunctionComposite_ReturnValue);
|
|
||||||
returnGroup.setLayout(new GridLayout());
|
|
||||||
GridData gridData = new GridData();
|
|
||||||
gridData.horizontalAlignment = GridData.FILL;
|
|
||||||
gridData.grabExcessHorizontalSpace = true;
|
|
||||||
returnGroup.setLayoutData(gridData);
|
|
||||||
return returnGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createReturnValueChooser(Composite parent, ExtractFunctionInformation info,
|
|
||||||
ExtractFunctionInputPage page) {
|
|
||||||
GridData gridData = new GridData();
|
|
||||||
gridData.horizontalAlignment = GridData.FILL;
|
|
||||||
gridData.grabExcessHorizontalSpace = true;
|
|
||||||
comp = new ChooserComposite(parent, info, page);
|
|
||||||
comp.setLayoutData(gridData);
|
|
||||||
comp.redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Text getMethodNameText() {
|
|
||||||
return nameVisiComp.getConstantNameText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Button getReplaceSimilarButton() {
|
|
||||||
return replaceSimilar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void visibilityPanelSetVisible(boolean visible) {
|
|
||||||
nameVisiComp.visibilityPanelsetVisible(visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createNewMethodNameComposite(Composite parent) {
|
|
||||||
String label;
|
|
||||||
if (info.getMethodContext().getType() == MethodContext.ContextType.METHOD) {
|
|
||||||
label = Messages.ExtractFunctionComposite_MethodName;
|
|
||||||
} else {
|
|
||||||
label = Messages.ExtractFunctionComposite_FunctionName;
|
|
||||||
}
|
|
||||||
nameVisiComp = new NameAndVisibilityComposite(parent, label, VisibilityEnum.v_private, ""); //$NON-NLS-1$
|
|
||||||
GridData gridData = new GridData();
|
|
||||||
gridData.horizontalAlignment = GridData.FILL;
|
|
||||||
gridData.grabExcessHorizontalSpace = true;
|
|
||||||
nameVisiComp.setLayoutData(gridData);
|
|
||||||
final Button virtual = new Button(nameVisiComp, SWT.CHECK);
|
|
||||||
virtual.setText(Messages.ExtractFunctionComposite_Virtual);
|
|
||||||
virtual.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
info.setVirtual(virtual.getSelection());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createReplaceCheckBox(Composite parent) {
|
|
||||||
replaceSimilar = new Button(parent, SWT.CHECK | SWT.LEFT);
|
|
||||||
GridData buttonLayoutData = new GridData(SWT.None);
|
|
||||||
buttonLayoutData.verticalIndent = 5;
|
|
||||||
replaceSimilar.setLayoutData(buttonLayoutData);
|
|
||||||
replaceSimilar.setText(Messages.ExtractFunctionComposite_ReplaceDuplicates);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChooserComposite getReturnChooser() {
|
|
||||||
return comp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethodName(){
|
|
||||||
return nameVisiComp.getConstantNameText().getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Composite getVisibiltyGroup() {
|
|
||||||
return nameVisiComp.getVisibiltyGroup();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,24 +8,30 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||||
|
|
||||||
public class ExtractFunctionInformation {
|
public class ExtractFunctionInformation {
|
||||||
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
||||||
private String methodName;
|
private String methodName;
|
||||||
private boolean replaceDuplicates;
|
private boolean replaceDuplicates;
|
||||||
private List<NameInformation> parameterCandidates;
|
private List<NameInformation> parameters;
|
||||||
private NameInformation mandatoryReturnVariable;
|
private NameInformation mandatoryReturnVariable;
|
||||||
private NameInformation returnVariable;
|
|
||||||
private ICPPASTFunctionDeclarator declarator;
|
private ICPPASTFunctionDeclarator declarator;
|
||||||
private MethodContext context;
|
private MethodContext context;
|
||||||
private boolean isExtractExpression;
|
private boolean isExtractExpression;
|
||||||
|
@ -61,14 +67,13 @@ public class ExtractFunctionInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public NameInformation getReturnVariable() {
|
public NameInformation getReturnVariable() {
|
||||||
return returnVariable;
|
if (mandatoryReturnVariable != null)
|
||||||
}
|
return mandatoryReturnVariable;
|
||||||
|
for (NameInformation param : parameters) {
|
||||||
public void setReturnVariable(NameInformation variable) {
|
if (param.isReturnValue())
|
||||||
if (variable != null) {
|
return param;
|
||||||
variable.setReturnValue(true);
|
|
||||||
}
|
}
|
||||||
this.returnVariable = variable;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NameInformation getMandatoryReturnVariable() {
|
public NameInformation getMandatoryReturnVariable() {
|
||||||
|
@ -76,19 +81,15 @@ public class ExtractFunctionInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMandatoryReturnVariable(NameInformation variable) {
|
public void setMandatoryReturnVariable(NameInformation variable) {
|
||||||
if (variable != null) {
|
|
||||||
variable.setMustBeReturnValue(true);
|
|
||||||
}
|
|
||||||
this.mandatoryReturnVariable = variable;
|
this.mandatoryReturnVariable = variable;
|
||||||
this.returnVariable = variable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NameInformation> getParameterCandidates() {
|
public List<NameInformation> getParameters() {
|
||||||
return parameterCandidates;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParameterCandidates(List<NameInformation> names) {
|
public void setParameters(List<NameInformation> parameters) {
|
||||||
this.parameterCandidates = names;
|
this.parameters = new ArrayList<NameInformation>(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VisibilityEnum getVisibility() {
|
public VisibilityEnum getVisibility() {
|
||||||
|
@ -122,4 +123,29 @@ public class ExtractFunctionInformation {
|
||||||
public void setVirtual(boolean isVirtual) {
|
public void setVirtual(boolean isVirtual) {
|
||||||
this.virtual = isVirtual;
|
this.virtual = isVirtual;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sortParameters(final boolean outFirst) {
|
||||||
|
Collections.sort(parameters, new Comparator<NameInformation>() {
|
||||||
|
@Override
|
||||||
|
public int compare(NameInformation p1, NameInformation p2) {
|
||||||
|
boolean out1 = p1.isOutputParameter() || hasNonConstPointerOrReference(p1);
|
||||||
|
boolean out2 = p2.isOutputParameter() || hasNonConstPointerOrReference(p2);
|
||||||
|
return out1 == out2 ? 0 : out1 == outFirst ? -1 : 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// int i = 0;
|
||||||
|
// for (NameInformation param : parameterCandidates) {
|
||||||
|
// param.setNewOrder(i++);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasNonConstPointerOrReference(NameInformation param) {
|
||||||
|
IASTDeclarator declarator = param.getDeclarator();
|
||||||
|
IASTPointerOperator[] operators = declarator.getPointerOperators();
|
||||||
|
if (operators.length != 0) {
|
||||||
|
IASTDeclSpecifier declSpecifier = param.getDeclSpecifier();
|
||||||
|
return declSpecifier == null || !declSpecifier.isConst();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,94 +1,343 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2000, 2012 IBM Corporation and others.
|
||||||
* Rapperswil, University of applied sciences 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
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
*
|
||||||
*
|
* Contributors:
|
||||||
* Contributors:
|
* IBM Corporation - initial API and implementation
|
||||||
* Institute for Software - initial API and implementation
|
* Benjamin Muskalla <bmuskalla@eclipsesource.com>
|
||||||
* IBM Corporation
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
|
import org.eclipse.jface.dialogs.Dialog;
|
||||||
|
import org.eclipse.jface.dialogs.IDialogSettings;
|
||||||
|
import org.eclipse.jface.layout.PixelConverter;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.text.Document;
|
||||||
|
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||||
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
|
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.events.ModifyEvent;
|
import org.eclipse.swt.events.ModifyEvent;
|
||||||
import org.eclipse.swt.events.ModifyListener;
|
import org.eclipse.swt.events.ModifyListener;
|
||||||
import org.eclipse.swt.events.MouseAdapter;
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierHelper;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.IdentifierResult;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
import org.eclipse.cdt.ui.text.CSourceViewerConfiguration;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.CPluginImages;
|
||||||
|
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
||||||
|
import org.eclipse.cdt.internal.ui.dialogs.TextFieldNavigationHandler;
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CSourceViewer;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.ChangeParametersControl;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.ChangeParametersControl.Mode;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.IParameterListChangeListener;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.StubTypeContext;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.RowLayouter;
|
||||||
|
|
||||||
public class ExtractFunctionInputPage extends UserInputWizardPage {
|
public class ExtractFunctionInputPage extends UserInputWizardPage {
|
||||||
private final ExtractFunctionInformation info;
|
public static final String PAGE_NAME = "ExtractFunctionInputPage";//$NON-NLS-1$
|
||||||
private ExtractFunctionComposite comp;
|
static final String DIALOG_SETTING_SECTION = "ExtractFunctionWizard"; //$NON-NLS-1$
|
||||||
protected final String NO_NAME_ERROR_LABEL = Messages.ExtractFunctionInputPage_EnterName;
|
|
||||||
|
|
||||||
public ExtractFunctionInputPage(String name, ExtractFunctionInformation info) {
|
private ExtractFunctionRefactoring refactoring;
|
||||||
super(name);
|
private ExtractFunctionInformation info;
|
||||||
this.info = info;
|
private Text textField;
|
||||||
|
private boolean firstTime;
|
||||||
|
private CSourceViewer signaturePreview;
|
||||||
|
private Document signaturePreviewDocument;
|
||||||
|
private IDialogSettings settings;
|
||||||
|
|
||||||
|
private static final String DESCRIPTION = Messages.ExtractFunctionInputPage_description;
|
||||||
|
private static final String ACCESS_MODIFIER = "AccessModifier"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public ExtractFunctionInputPage() {
|
||||||
|
super(PAGE_NAME);
|
||||||
|
setImageDescriptor(CPluginImages.DESC_WIZBAN_REFACTOR_TU);
|
||||||
|
setDescription(DESCRIPTION);
|
||||||
|
firstTime = true;
|
||||||
|
signaturePreviewDocument = new Document();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createControl(final Composite parent) {
|
public void createControl(Composite parent) {
|
||||||
comp = new ExtractFunctionComposite(parent, info, this);
|
refactoring = (ExtractFunctionRefactoring) getRefactoring();
|
||||||
|
info = ((ExtractFunctionRefactoring) getRefactoring()).getRefactoringInfo();
|
||||||
setPageComplete(false);
|
loadSettings();
|
||||||
|
|
||||||
comp.getMethodNameText().addModifyListener(new ModifyListener() {
|
Composite result = new Composite(parent, SWT.NONE);
|
||||||
@Override
|
setControl(result);
|
||||||
public void modifyText(ModifyEvent e) {
|
GridLayout layout = new GridLayout();
|
||||||
info.setMethodName(comp.getMethodName());
|
layout.numColumns = 2;
|
||||||
checkName();
|
result.setLayout(layout);
|
||||||
}
|
RowLayouter layouter = new RowLayouter(2);
|
||||||
});
|
GridData gd = null;
|
||||||
|
|
||||||
for (Control buttons : comp.getVisibiltyGroup().getChildren()) {
|
initializeDialogUnits(result);
|
||||||
buttons.addMouseListener(new MouseAdapter() {
|
|
||||||
|
Label label = new Label(result, SWT.NONE);
|
||||||
|
label.setText(getLabelText());
|
||||||
|
|
||||||
|
textField = createTextInputField(result, SWT.BORDER);
|
||||||
|
textField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
|
||||||
|
layouter.perform(label, textField, 1);
|
||||||
|
|
||||||
|
label = new Label(result, SWT.NONE);
|
||||||
|
label.setText(Messages.ExtractFunctionInputPage_access_modifier);
|
||||||
|
|
||||||
|
Composite group = new Composite(result, SWT.NONE);
|
||||||
|
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
layout = new GridLayout();
|
||||||
|
layout.numColumns = 4;
|
||||||
|
layout.marginWidth = 0;
|
||||||
|
group.setLayout(layout);
|
||||||
|
|
||||||
|
String[] labels = new String[] {
|
||||||
|
Messages.ExtractFunctionInputPage_public,
|
||||||
|
Messages.ExtractFunctionInputPage_protected,
|
||||||
|
Messages.ExtractFunctionInputPage_private
|
||||||
|
};
|
||||||
|
VisibilityEnum[] visibilityValues = new VisibilityEnum[] {
|
||||||
|
VisibilityEnum.v_public, VisibilityEnum.v_protected, VisibilityEnum.v_private
|
||||||
|
};
|
||||||
|
VisibilityEnum visibility = info.getVisibility();
|
||||||
|
for (int i = 0; i < labels.length; i++) {
|
||||||
|
Button radio = new Button(group, SWT.RADIO);
|
||||||
|
radio.setText(labels[i]);
|
||||||
|
radio.setData(visibilityValues[i]);
|
||||||
|
if (visibilityValues[i].equals(visibility))
|
||||||
|
radio.setSelection(true);
|
||||||
|
radio.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void mouseUp(MouseEvent e) {
|
public void widgetSelected(SelectionEvent event) {
|
||||||
String text = ((Button)e.getSource()).getText();
|
final VisibilityEnum selectedModifier = (VisibilityEnum) event.widget.getData();
|
||||||
visibilityChange(text);
|
settings.put(ACCESS_MODIFIER, selectedModifier.toString());
|
||||||
}
|
setVisibility(selectedModifier);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
layouter.perform(label, group, 1);
|
||||||
comp.getReplaceSimilarButton().addSelectionListener(new SelectionListener() {
|
|
||||||
@Override
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
info.setReplaceDuplicates(comp.getReplaceSimilarButton().isEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!info.getParameters().isEmpty()) {
|
||||||
|
Mode mode = info.getMandatoryReturnVariable() != null ?
|
||||||
|
Mode.EXTRACT_METHOD_FIXED_RETURN : Mode.EXTRACT_METHOD;
|
||||||
|
ChangeParametersControl paramControl = new ChangeParametersControl(result, SWT.NONE,
|
||||||
|
Messages.ExtractFunctionInputPage_parameters,
|
||||||
|
new IParameterListChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void parameterChanged(NameInformation parameter) {
|
||||||
|
parameterModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parameterListChanged() {
|
||||||
|
parameterModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parameterAdded(NameInformation parameter) {
|
||||||
|
updatePreview(getText());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mode,
|
||||||
|
new StubTypeContext(refactoring.getTranslationUnit()));
|
||||||
|
gd = new GridData(GridData.FILL_BOTH);
|
||||||
|
gd.horizontalSpan = 2;
|
||||||
|
paramControl.setLayoutData(gd);
|
||||||
|
paramControl.setInput(info.getParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
int duplicates = refactoring.getNumberOfDuplicates();
|
||||||
|
Button checkBox = new Button(result, SWT.CHECK);
|
||||||
|
if (duplicates == 0) {
|
||||||
|
checkBox.setText(Messages.ExtractFunctionInputPage_duplicates_none);
|
||||||
|
} else if (duplicates == 1) {
|
||||||
|
checkBox.setText(Messages.ExtractFunctionInputPage_duplicates_single);
|
||||||
|
} else {
|
||||||
|
checkBox.setText(NLS.bind(
|
||||||
|
Messages.ExtractFunctionInputPage_duplicates_multi, Integer.valueOf(duplicates)));
|
||||||
|
}
|
||||||
|
checkBox.setSelection(info.isReplaceDuplicates());
|
||||||
|
checkBox.setEnabled(duplicates > 0);
|
||||||
|
checkBox.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
widgetDefaultSelected(e);
|
info.setReplaceDuplicates(((Button) e.widget).getSelection());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
layouter.perform(checkBox);
|
||||||
setControl(comp);
|
|
||||||
|
label = new Label(result, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||||
|
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
layouter.perform(label);
|
||||||
|
|
||||||
|
createSignaturePreview(result, layouter);
|
||||||
|
|
||||||
|
Dialog.applyDialogFont(result);
|
||||||
|
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
|
||||||
|
ICHelpContextIds.EXTRACT_FUNCTION_WIZARD_PAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void visibilityChange(String text) {
|
private Text createTextInputField(Composite parent, int style) {
|
||||||
info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(text));
|
Text result = new Text(parent, style);
|
||||||
|
result.addModifyListener(new ModifyListener() {
|
||||||
|
@Override
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
textModified(getText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TextFieldNavigationHandler.install(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkName() {
|
private String getText() {
|
||||||
String methodName = comp.getMethodName();
|
if (textField == null)
|
||||||
IdentifierResult result = IdentifierHelper.checkIdentifierName(methodName);
|
return null;
|
||||||
if (result.isCorrect()) {
|
return textField.getText();
|
||||||
setErrorMessage(null);
|
}
|
||||||
setPageComplete(true);
|
|
||||||
} else {
|
private String getLabelText(){
|
||||||
setErrorMessage(Messages.ExtractFunctionInputPage_CheckFunctionName + " " + result.getMessage()); //$NON-NLS-1$
|
return Messages.ExtractFunctionInputPage_label_text;
|
||||||
setPageComplete(false);
|
}
|
||||||
|
|
||||||
|
private void setVisibility(VisibilityEnum visibility) {
|
||||||
|
info.setVisibility(visibility);
|
||||||
|
updatePreview(getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createSignaturePreview(Composite composite, RowLayouter layouter) {
|
||||||
|
Label previewLabel = new Label(composite, SWT.NONE);
|
||||||
|
previewLabel.setText(Messages.ExtractFunctionInputPage_signature_preview);
|
||||||
|
layouter.perform(previewLabel);
|
||||||
|
|
||||||
|
IPreferenceStore store = CUIPlugin.getDefault().getCombinedPreferenceStore();
|
||||||
|
signaturePreview = new CSourceViewer(composite, null, null, false, SWT.READ_ONLY | SWT.V_SCROLL | SWT.WRAP /*| SWT.BORDER*/, store);
|
||||||
|
signaturePreview.configure(new CSourceViewerConfiguration(CUIPlugin.getDefault().getTextTools().getColorManager(), store, null, null));
|
||||||
|
signaturePreview.getTextWidget().setFont(JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT));
|
||||||
|
signaturePreview.adaptBackgroundColor(composite);
|
||||||
|
signaturePreview.setDocument(signaturePreviewDocument);
|
||||||
|
signaturePreview.setEditable(false);
|
||||||
|
|
||||||
|
// Layouting problems with wrapped text: see http://bugs.eclipse.org/bugs/show_bug.cgi?id=9866
|
||||||
|
Control signaturePreviewControl = signaturePreview.getControl();
|
||||||
|
PixelConverter pixelConverter = new PixelConverter(signaturePreviewControl);
|
||||||
|
GridData gdata = new GridData(GridData.FILL_BOTH);
|
||||||
|
gdata.widthHint = pixelConverter.convertWidthInCharsToPixels(50);
|
||||||
|
gdata.heightHint = pixelConverter.convertHeightInCharsToPixels(3);
|
||||||
|
signaturePreviewControl.setLayoutData(gdata);
|
||||||
|
layouter.perform(signaturePreviewControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePreview(String methodName) {
|
||||||
|
if (signaturePreview == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (methodName.isEmpty()) {
|
||||||
|
methodName = StubUtility.suggestMethodName("someMethodName", null, //$NON-NLS-1$
|
||||||
|
refactoring.getTranslationUnit());
|
||||||
|
}
|
||||||
|
|
||||||
|
int top = signaturePreview.getTextWidget().getTopPixel();
|
||||||
|
String signature = refactoring.getSignature(methodName);
|
||||||
|
signaturePreviewDocument.set(signature);
|
||||||
|
signaturePreview.getTextWidget().setTopPixel(top);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSettings() {
|
||||||
|
settings = getDialogSettings().getSection(DIALOG_SETTING_SECTION);
|
||||||
|
if (settings == null) {
|
||||||
|
settings = getDialogSettings().addNewSection(DIALOG_SETTING_SECTION);
|
||||||
|
settings.put(ACCESS_MODIFIER, VisibilityEnum.v_private.toString());
|
||||||
|
}
|
||||||
|
final String accessModifier = settings.get(ACCESS_MODIFIER);
|
||||||
|
if (accessModifier != null) {
|
||||||
|
info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(accessModifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- Input validation ------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisible(boolean visible) {
|
||||||
|
if (visible) {
|
||||||
|
if (firstTime) {
|
||||||
|
firstTime = false;
|
||||||
|
setPageComplete(false);
|
||||||
|
updatePreview(getText());
|
||||||
|
textField.setFocus();
|
||||||
|
} else {
|
||||||
|
setPageComplete(validatePage(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void textModified(String methodName) {
|
||||||
|
info.setMethodName(methodName);
|
||||||
|
RefactoringStatus status = validatePage(true);
|
||||||
|
if (!status.hasFatalError()) {
|
||||||
|
updatePreview(methodName);
|
||||||
|
} else {
|
||||||
|
signaturePreviewDocument.set(""); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
setPageComplete(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parameterModified() {
|
||||||
|
updatePreview(getText());
|
||||||
|
setPageComplete(validatePage(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RefactoringStatus validatePage(boolean text) {
|
||||||
|
RefactoringStatus result = new RefactoringStatus();
|
||||||
|
if (text) {
|
||||||
|
result.merge(validateMethodName());
|
||||||
|
result.merge(validateParameters());
|
||||||
|
} else {
|
||||||
|
result.merge(validateParameters());
|
||||||
|
result.merge(validateMethodName());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RefactoringStatus validateMethodName() {
|
||||||
|
RefactoringStatus result = new RefactoringStatus();
|
||||||
|
String methodName = getText();
|
||||||
|
if (methodName.isEmpty()) {
|
||||||
|
result.addFatalError(Messages.ExtractFunctionInputPage_validation_empty_function_name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.merge(refactoring.checkMethodName());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RefactoringStatus validateParameters() {
|
||||||
|
RefactoringStatus result = new RefactoringStatus();
|
||||||
|
for (NameInformation paramInfo : info.getParameters()) {
|
||||||
|
if (paramInfo.getNewName().isEmpty()) {
|
||||||
|
result.addFatalError(Messages.ExtractFunctionInputPage_validation_empty_parameter_name);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.merge(refactoring.checkParameterNames());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2010 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,15 +8,17 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
@ -25,10 +27,13 @@ import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.OperationCanceledException;
|
import org.eclipse.core.runtime.OperationCanceledException;
|
||||||
import org.eclipse.core.runtime.Path;
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.SubMonitor;
|
import org.eclipse.core.runtime.SubMonitor;
|
||||||
|
import org.eclipse.core.runtime.preferences.IPreferencesService;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
|
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
|
||||||
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
@ -56,10 +61,12 @@ import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IField;
|
import org.eclipse.cdt.core.dom.ast.IField;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
|
@ -72,8 +79,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
||||||
|
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
|
import org.eclipse.cdt.internal.core.dom.parser.c.CASTBinaryExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
|
||||||
|
@ -91,6 +102,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNodeFactory;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNodeFactory;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
|
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.CRefactoringDescription;
|
import org.eclipse.cdt.internal.ui.refactoring.CRefactoringDescription;
|
||||||
|
@ -99,12 +112,14 @@ import org.eclipse.cdt.internal.ui.refactoring.Container;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.utils.Checks;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
|
||||||
|
import org.eclipse.cdt.internal.ui.viewsupport.BasicElementLabels;
|
||||||
|
|
||||||
public class ExtractFunctionRefactoring extends CRefactoring {
|
public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
public static final String ID =
|
public static final String ID =
|
||||||
|
@ -113,7 +128,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
static final Integer NULL_INTEGER = Integer.valueOf(0);
|
static final Integer NULL_INTEGER = Integer.valueOf(0);
|
||||||
static final char[] ZERO= "0".toCharArray(); //$NON-NLS-1$
|
static final char[] ZERO= "0".toCharArray(); //$NON-NLS-1$
|
||||||
|
|
||||||
NodeContainer container;
|
private NodeContainer container;
|
||||||
final ExtractFunctionInformation info;
|
final ExtractFunctionInformation info;
|
||||||
|
|
||||||
final Map<String, Integer> names;
|
final Map<String, Integer> names;
|
||||||
|
@ -121,12 +136,11 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
final Container<Integer> trailPos;
|
final Container<Integer> trailPos;
|
||||||
private final Container<Integer> returnNumber;
|
private final Container<Integer> returnNumber;
|
||||||
|
|
||||||
protected boolean hasNameResolvingForSimilarError;
|
|
||||||
|
|
||||||
HashMap<String, Integer> nameTrail;
|
HashMap<String, Integer> nameTrail;
|
||||||
|
|
||||||
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
||||||
private final INodeFactory factory = CPPNodeFactory.getDefault();
|
private final INodeFactory nodeFactory = CPPNodeFactory.getDefault();
|
||||||
|
DefaultCodeFormatterOptions formattingOptions;
|
||||||
|
|
||||||
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
||||||
ExtractFunctionInformation info, ICProject project) {
|
ExtractFunctionInformation info, ICProject project) {
|
||||||
|
@ -137,6 +151,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
namesCounter = new Container<Integer>(NULL_INTEGER);
|
namesCounter = new Container<Integer>(NULL_INTEGER);
|
||||||
trailPos = new Container<Integer>(NULL_INTEGER);
|
trailPos = new Container<Integer>(NULL_INTEGER);
|
||||||
returnNumber = new Container<Integer>(NULL_INTEGER);
|
returnNumber = new Container<Integer>(NULL_INTEGER);
|
||||||
|
formattingOptions = new DefaultCodeFormatterOptions(project.getOptions(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -170,19 +185,33 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
if (isProgressMonitorCanceld(sm, initStatus))
|
if (isProgressMonitorCanceld(sm, initStatus))
|
||||||
return initStatus;
|
return initStatus;
|
||||||
|
|
||||||
info.setParameterCandidates(container.getParameterCandidates());
|
List<NameInformation> returnValueCandidates = container.getReturnValueCandidates();
|
||||||
|
if (returnValueCandidates.size() > 1) {
|
||||||
|
initStatus.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
|
||||||
|
return initStatus;
|
||||||
|
} else if (returnValueCandidates.size() == 1) {
|
||||||
|
info.setMandatoryReturnVariable(returnValueCandidates.get(0));
|
||||||
|
}
|
||||||
sm.worked(1);
|
sm.worked(1);
|
||||||
|
|
||||||
if (isProgressMonitorCanceld(sm, initStatus))
|
if (isProgressMonitorCanceld(sm, initStatus))
|
||||||
return initStatus;
|
return initStatus;
|
||||||
|
|
||||||
List<NameInformation> returnValueCandidates = container.getReturnValueCandidates();
|
info.setParameters(container.getParameterCandidates());
|
||||||
if (returnValueCandidates.size() > 1) {
|
initStatus.merge(checkParameterAndReturnTypes());
|
||||||
initStatus.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
|
if (initStatus.hasFatalError())
|
||||||
} else if (returnValueCandidates.size() == 1) {
|
return initStatus;
|
||||||
info.setMandatoryReturnVariable(returnValueCandidates.get(0));
|
|
||||||
|
if (info.getMandatoryReturnVariable() == null) {
|
||||||
|
chooseReturnVariable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
|
final boolean outFirst = preferences.getBoolean(CUIPlugin.PLUGIN_ID,
|
||||||
|
PreferenceConstants.FUNCTION_OUTPUT_PARAMETERS_BEFORE_INPUT, false,
|
||||||
|
PreferenceConstants.getPreferenceScopes(project.getProject()));
|
||||||
|
info.sortParameters(outFirst);
|
||||||
|
|
||||||
extractedFunctionConstructionHelper =
|
extractedFunctionConstructionHelper =
|
||||||
ExtractedFunctionConstructionHelper.createFor(container.getNodesToWrite());
|
ExtractedFunctionConstructionHelper.createFor(container.getNodesToWrite());
|
||||||
|
|
||||||
|
@ -204,6 +233,28 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return initStatus;
|
return initStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void chooseReturnVariable() {
|
||||||
|
NameInformation candidate = null;
|
||||||
|
for (NameInformation param : info.getParameters()) {
|
||||||
|
if (param.isOutput()) {
|
||||||
|
IASTDeclarator declarator = param.getDeclarator();
|
||||||
|
IType type = TypeHelper.createType(declarator);
|
||||||
|
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
|
||||||
|
if (type instanceof IBasicType) {
|
||||||
|
if (((IBasicType) type).getKind() == IBasicType.Kind.eBoolean) {
|
||||||
|
param.setReturnValue(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidate == null && !TypeHelper.shouldBePassedByReference(type, ast)) {
|
||||||
|
candidate = param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidate != null)
|
||||||
|
candidate.setReturnValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
private void checkForNonExtractableStatements(NodeContainer cont, RefactoringStatus status) {
|
private void checkForNonExtractableStatements(NodeContainer cont, RefactoringStatus status) {
|
||||||
NonExtractableStmtFinder finder = new NonExtractableStmtFinder();
|
NonExtractableStmtFinder finder = new NonExtractableStmtFinder();
|
||||||
for (IASTNode node : cont.getNodesToWrite()) {
|
for (IASTNode node : cont.getNodesToWrite()) {
|
||||||
|
@ -259,15 +310,10 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
|
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
|
||||||
|
|
||||||
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration, getIndex())) {
|
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration, getIndex())) {
|
||||||
finalConditions.addError(Messages.ExtractFunctionRefactoring_NameInUse);
|
finalConditions.addError(Messages.ExtractFunctionRefactoring_name_in_use);
|
||||||
return finalConditions;
|
return finalConditions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (NameInformation name : info.getParameterCandidates()) {
|
|
||||||
if (name.isReturnValue()) {
|
|
||||||
info.setReturnVariable(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
unlockIndex();
|
unlockIndex();
|
||||||
}
|
}
|
||||||
|
@ -278,9 +324,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void collectModifications(IProgressMonitor pm,
|
protected void collectModifications(IProgressMonitor pm, ModificationCollector collector)
|
||||||
ModificationCollector collector) throws CoreException,
|
throws CoreException, OperationCanceledException {
|
||||||
OperationCanceledException {
|
|
||||||
try {
|
try {
|
||||||
lockIndex();
|
lockIndex();
|
||||||
try {
|
try {
|
||||||
|
@ -298,10 +343,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
final IFile implementationFile =
|
final IFile implementationFile =
|
||||||
ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(implPath);
|
ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(implPath);
|
||||||
|
|
||||||
createMethodDefinition(astMethodName, context, firstNode, implementationFile,
|
createMethodDefinition(astMethodName, context, firstNode, collector);
|
||||||
collector);
|
|
||||||
|
|
||||||
createMethodCalls(astMethodName, implementationFile, context, collector);
|
createMethodCalls(astMethodName, context, collector);
|
||||||
} finally {
|
} finally {
|
||||||
unlockIndex();
|
unlockIndex();
|
||||||
}
|
}
|
||||||
|
@ -310,8 +354,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMethodCalls(final IASTName astMethodName,
|
private void createMethodCalls(final IASTName astMethodName, MethodContext context,
|
||||||
final IFile implementationFile, MethodContext context,
|
|
||||||
ModificationCollector collector) throws CoreException {
|
ModificationCollector collector) throws CoreException {
|
||||||
String title;
|
String title;
|
||||||
if (context.getType() == MethodContext.ContextType.METHOD) {
|
if (context.getType() == MethodContext.ContextType.METHOD) {
|
||||||
|
@ -326,15 +369,15 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
ASTRewrite rewriter = collector.rewriterForTranslationUnit(
|
ASTRewrite rewriter = collector.rewriterForTranslationUnit(
|
||||||
firstNodeToWrite.getTranslationUnit());
|
firstNodeToWrite.getTranslationUnit());
|
||||||
TextEditGroup editGroup = new TextEditGroup(title);
|
TextEditGroup editGroup = new TextEditGroup(title);
|
||||||
if (methodCall instanceof IASTDeclaration){
|
if (methodCall instanceof IASTDeclaration) {
|
||||||
CPPASTDeclarationStatement declarationStatement =
|
CPPASTDeclarationStatement declarationStatement =
|
||||||
new CPPASTDeclarationStatement((IASTDeclaration) methodCall);
|
new CPPASTDeclarationStatement((IASTDeclaration) methodCall);
|
||||||
methodCall = declarationStatement;
|
methodCall = declarationStatement;
|
||||||
}
|
}
|
||||||
insertCallintoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
insertCallIntoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
||||||
|
|
||||||
if (info.isReplaceDuplicates()) {
|
if (info.isReplaceDuplicates()) {
|
||||||
replaceSimilar(collector, astMethodName, implementationFile, context.getType());
|
replaceSimilar(collector, astMethodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IASTNode node : container.getNodesToWrite()) {
|
for (IASTNode node : container.getNodesToWrite()) {
|
||||||
|
@ -344,8 +387,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertCallintoTree(IASTNode methodCall, List<IASTNode> list,
|
private void insertCallIntoTree(IASTNode methodCall, List<IASTNode> list, ASTRewrite rewriter,
|
||||||
ASTRewrite rewriter, TextEditGroup editGroup) {
|
TextEditGroup editGroup) {
|
||||||
IASTNode firstNode = list.get(0);
|
IASTNode firstNode = list.get(0);
|
||||||
if (list.size() > 1 && firstNode.getParent() instanceof IASTBinaryExpression &&
|
if (list.size() > 1 && firstNode.getParent() instanceof IASTBinaryExpression &&
|
||||||
firstNode.getParent().getParent() instanceof IASTBinaryExpression) {
|
firstNode.getParent().getParent() instanceof IASTBinaryExpression) {
|
||||||
|
@ -372,9 +415,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return binExp;
|
return binExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMethodDefinition(final IASTName astMethodName,
|
private void createMethodDefinition(final IASTName astMethodName, MethodContext context,
|
||||||
MethodContext context, IASTNode firstNode,
|
IASTNode firstNode, ModificationCollector collector) {
|
||||||
final IFile implementationFile, ModificationCollector collector) {
|
|
||||||
IASTFunctionDefinition node = NodeHelper.findFunctionDefinitionInAncestors(firstNode);
|
IASTFunctionDefinition node = NodeHelper.findFunctionDefinitionInAncestors(firstNode);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
String title;
|
String title;
|
||||||
|
@ -400,32 +442,39 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
methodDeclaration, false, collector);
|
methodDeclaration, false, collector);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceSimilar(ModificationCollector collector, final IASTName astMethodName,
|
private void replaceSimilar(ModificationCollector collector, IASTName astMethodName) {
|
||||||
final IFile implementationFile, final ContextType contextType) {
|
|
||||||
// Find similar code
|
// Find similar code
|
||||||
final List<IASTNode> nodesToRewriteWithoutComments = new LinkedList<IASTNode>();
|
final List<IASTNode> nodesToRewriteWithoutComments = getNodesWithoutComments(container.getNodesToWrite());
|
||||||
|
|
||||||
for (IASTNode node : container.getNodesToWrite()) {
|
|
||||||
if (!(node instanceof IASTComment)) {
|
|
||||||
nodesToRewriteWithoutComments.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
final List<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
||||||
final String title;
|
ast.accept(new SimilarReplacerVisitor(this, container, collector, initTrail, astMethodName,
|
||||||
if (contextType == MethodContext.ContextType.METHOD) {
|
nodesToRewriteWithoutComments));
|
||||||
title = Messages.ExtractFunctionRefactoring_CreateMethodCall;
|
|
||||||
} else {
|
|
||||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasNameResolvingForSimilarError) {
|
|
||||||
ast.accept(new SimilarFinderVisitor(this, collector, initTrail, implementationFile,
|
|
||||||
astMethodName, nodesToRewriteWithoutComments, title));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<IASTNode> getTrail(List<IASTNode> stmts) {
|
public int getNumberOfDuplicates() {
|
||||||
|
final List<IASTNode> nodesToRewriteWithoutComments = getNodesWithoutComments(container.getNodesToWrite());
|
||||||
|
final List<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
||||||
|
final int[] count = new int[1];
|
||||||
|
ast.accept(new SimilarFinderVisitor(this, container, initTrail, nodesToRewriteWithoutComments) {
|
||||||
|
@Override
|
||||||
|
protected void foundSimilar() {
|
||||||
|
++count[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return count[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IASTNode> getNodesWithoutComments(List<IASTNode> nodes) {
|
||||||
|
final List<IASTNode> nodesWithoutComments = new ArrayList<IASTNode>(nodes.size());
|
||||||
|
|
||||||
|
for (IASTNode node : nodes) {
|
||||||
|
if (!(node instanceof IASTComment)) {
|
||||||
|
nodesWithoutComments.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodesWithoutComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IASTNode> getTrail(List<IASTNode> stmts) {
|
||||||
final List<IASTNode> trail = new ArrayList<IASTNode>();
|
final List<IASTNode> trail = new ArrayList<IASTNode>();
|
||||||
nameTrail = new HashMap<String, Integer>();
|
nameTrail = new HashMap<String, Integer>();
|
||||||
final Container<Integer> trailCounter = new Container<Integer>(NULL_INTEGER);
|
final Container<Integer> trailCounter = new Container<Integer>(NULL_INTEGER);
|
||||||
|
@ -590,7 +639,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(qname,
|
extractedFunctionConstructionHelper.createFunctionDeclarator(qname,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
info.getParameters(), ast.getASTNodeFactory());
|
||||||
func.setDeclarator(createdFunctionDeclarator);
|
func.setDeclarator(createdFunctionDeclarator);
|
||||||
|
|
||||||
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
||||||
|
@ -619,18 +668,13 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
NameInformation returnVariable = info.getReturnVariable();
|
NameInformation returnVariable = info.getReturnVariable();
|
||||||
if (returnVariable != null) {
|
if (returnVariable != null) {
|
||||||
IASTReturnStatement returnStmt = new CPPASTReturnStatement();
|
IASTReturnStatement returnStmt = new CPPASTReturnStatement();
|
||||||
if (returnVariable.getDeclaration().getParent() instanceof IASTExpression) {
|
IASTIdExpression expr = new CPPASTIdExpression();
|
||||||
IASTExpression returnValue = (IASTExpression) returnVariable.getDeclaration().getParent();
|
if (returnVariable.getNewName() == null) {
|
||||||
returnStmt.setReturnValue(returnValue);
|
expr.setName(newName(returnVariable.getName()));
|
||||||
} else {
|
} else {
|
||||||
IASTIdExpression expr = new CPPASTIdExpression();
|
expr.setName(new CPPASTName(returnVariable.getNewName().toCharArray()));
|
||||||
if (returnVariable.getUserSetName() == null) {
|
|
||||||
expr.setName(newName(returnVariable.getName()));
|
|
||||||
} else {
|
|
||||||
expr.setName(new CPPASTName(returnVariable.getUserSetName().toCharArray()));
|
|
||||||
}
|
|
||||||
returnStmt.setReturnValue(expr);
|
|
||||||
}
|
}
|
||||||
|
returnStmt.setReturnValue(expr);
|
||||||
subRW.insertBefore(compound, null, returnStmt, group);
|
subRW.insertBefore(compound, null, returnStmt, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,8 +690,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
returnVariable);
|
returnVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IASTNode getMethodCall(IASTName astMethodName,
|
protected IASTNode getMethodCall(IASTName astMethodName, Map<String, Integer> trailNameTable,
|
||||||
Map<String, Integer> trailNameTable,
|
|
||||||
Map<String, Integer> similarNameTable, NodeContainer myContainer,
|
Map<String, Integer> similarNameTable, NodeContainer myContainer,
|
||||||
NodeContainer mySimilarContainer) {
|
NodeContainer mySimilarContainer) {
|
||||||
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
||||||
|
@ -656,12 +699,12 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
idExpression.setName(astMethodName);
|
idExpression.setName(astMethodName);
|
||||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||||
|
|
||||||
List<IASTName> declarations = new ArrayList<IASTName>();
|
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||||
IASTName retName = null;
|
IASTName retName = null;
|
||||||
boolean theRetName = false;
|
boolean theRetName = false;
|
||||||
|
|
||||||
for (NameInformation nameInfo : myContainer.getNames()) {
|
for (NameInformation nameInfo : info.getParameters()) {
|
||||||
Integer trailSeqNumber = trailNameTable.get(nameInfo.getDeclaration().getRawSignature());
|
Integer trailSeqNumber = trailNameTable.get(nameInfo.getDeclarationName().getRawSignature());
|
||||||
String origName = null;
|
String origName = null;
|
||||||
for (Entry<String, Integer> entry : similarNameTable.entrySet()) {
|
for (Entry<String, Integer> entry : similarNameTable.entrySet()) {
|
||||||
if (entry.getValue().equals(trailSeqNumber)) {
|
if (entry.getValue().equals(trailSeqNumber)) {
|
||||||
|
@ -676,14 +719,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
if (origName != null) {
|
if (origName != null) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (NameInformation simNameInfo : mySimilarContainer.getNames()) {
|
for (NameInformation simNameInfo : mySimilarContainer.getNames()) {
|
||||||
if (origName.equals(simNameInfo.getDeclaration().getRawSignature())) {
|
if (origName.equals(simNameInfo.getDeclarationName().getRawSignature())) {
|
||||||
addParameterIfPossible(args, declarations, simNameInfo);
|
addParameterIfPossible(args, declarations, simNameInfo);
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
if (theRetName) {
|
if (theRetName) {
|
||||||
theRetName = false;
|
theRetName = false;
|
||||||
retName = new CPPASTName(
|
retName = new CPPASTName(
|
||||||
simNameInfo.getDeclaration().getRawSignature().toCharArray());
|
simNameInfo.getDeclarationName().getRawSignature().toCharArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -733,7 +776,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
IASTFunctionCallExpression callExpression, IASTName retname) {
|
IASTFunctionCallExpression callExpression, IASTName retname) {
|
||||||
if (info.getReturnVariable().equals(info.getMandatoryReturnVariable())) {
|
if (info.getReturnVariable().equals(info.getMandatoryReturnVariable())) {
|
||||||
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
|
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
|
||||||
.getReturnVariable().getDeclaration());
|
.getReturnVariable().getDeclarationName());
|
||||||
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
||||||
|
|
||||||
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
|
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
|
||||||
|
@ -775,14 +818,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
IASTStandardFunctionDeclarator declarator =
|
IASTStandardFunctionDeclarator declarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
info.getParameters(), ast.getASTNodeFactory());
|
||||||
simpleDecl.addDeclarator(declarator);
|
simpleDecl.addDeclarator(declarator);
|
||||||
return simpleDecl;
|
return simpleDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTSimpleDeclaration getDeclaration(ModificationCollector collector, IASTName name) {
|
private IASTSimpleDeclaration getDeclaration(ModificationCollector collector, IASTName name) {
|
||||||
IASTDeclSpecifier declSpec = getReturnType();
|
IASTDeclSpecifier declSpec = getReturnType();
|
||||||
IASTSimpleDeclaration simpleDecl = factory.newSimpleDeclaration(declSpec);
|
IASTSimpleDeclaration simpleDecl = nodeFactory.newSimpleDeclaration(declSpec);
|
||||||
if (info.isVirtual() && declSpec instanceof ICPPASTDeclSpecifier) {
|
if (info.isVirtual() && declSpec instanceof ICPPASTDeclSpecifier) {
|
||||||
((ICPPASTDeclSpecifier) declSpec).setVirtual(true);
|
((ICPPASTDeclSpecifier) declSpec).setVirtual(true);
|
||||||
}
|
}
|
||||||
|
@ -790,7 +833,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
IASTStandardFunctionDeclarator declarator =
|
IASTStandardFunctionDeclarator declarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
info.getParameters(), ast.getASTNodeFactory());
|
||||||
simpleDecl.addDeclarator(declarator);
|
simpleDecl.addDeclarator(declarator);
|
||||||
return simpleDecl;
|
return simpleDecl;
|
||||||
}
|
}
|
||||||
|
@ -826,19 +869,18 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
|
|
||||||
public List<IASTInitializerClause> getCallParameters() {
|
public List<IASTInitializerClause> getCallParameters() {
|
||||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||||
List<IASTName> declarations = new ArrayList<IASTName>();
|
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||||
for (NameInformation nameInfo : container.getNames()) {
|
for (NameInformation nameInfo : info.getParameters()) {
|
||||||
addParameterIfPossible(args, declarations, nameInfo);
|
addParameterIfPossible(args, declarations, nameInfo);
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addParameterIfPossible(List<IASTInitializerClause> args,
|
private void addParameterIfPossible(List<IASTInitializerClause> args, Set<IASTName> declarations,
|
||||||
List<IASTName> declarations, NameInformation nameInfo) {
|
NameInformation nameInfo) {
|
||||||
if (!nameInfo.isDeclaredInSelection()) {
|
if (!container.isDeclaredInSelection(nameInfo)) {
|
||||||
IASTName declaration = nameInfo.getDeclaration();
|
IASTName declaration = nameInfo.getDeclarationName();
|
||||||
if (!declarations.contains(declaration)) {
|
if (declarations.add(declaration)) {
|
||||||
declarations.add(declaration);
|
|
||||||
IASTIdExpression expression = new CPPASTIdExpression();
|
IASTIdExpression expression = new CPPASTIdExpression();
|
||||||
expression.setName(newName(declaration));
|
expression.setName(newName(declaration));
|
||||||
args.add(expression);
|
args.add(expression);
|
||||||
|
@ -866,4 +908,119 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
Boolean.toString(info.isReplaceDuplicates()));
|
Boolean.toString(info.isReplaceDuplicates()));
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ExtractFunctionInformation getRefactoringInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the new method name is a valid method name. This method doesn't
|
||||||
|
* check if a method with the same name already exists in the hierarchy.
|
||||||
|
* @return validation status
|
||||||
|
*/
|
||||||
|
public RefactoringStatus checkMethodName() {
|
||||||
|
return Checks.checkIdentifier(info.getMethodName(), tu);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the parameter names are valid.
|
||||||
|
* @return validation status
|
||||||
|
*/
|
||||||
|
public RefactoringStatus checkParameterNames() {
|
||||||
|
RefactoringStatus result= new RefactoringStatus();
|
||||||
|
List<NameInformation> parameters = info.getParameters();
|
||||||
|
Set<String> usedNames = new HashSet<String>();
|
||||||
|
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||||
|
for (NameInformation nameInfo : container.getNames()) {
|
||||||
|
IASTName declaration = nameInfo.getDeclarationName();
|
||||||
|
if (declarations.add(declaration) && !parameters.contains(nameInfo)) {
|
||||||
|
usedNames.add(String.valueOf(nameInfo.getName().getSimpleID()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (NameInformation parameter : parameters) {
|
||||||
|
result.merge(Checks.checkIdentifier(parameter.getNewName(), tu));
|
||||||
|
for (NameInformation other : parameters) {
|
||||||
|
if (parameter != other && other.getNewName().equals(parameter.getNewName())) {
|
||||||
|
result.addError(NLS.bind(Messages.ExtractFunctionRefactoring_duplicate_parameter,
|
||||||
|
BasicElementLabels.getCElementName(other.getNewName())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parameter.isRenamed() && usedNames.contains(parameter.getNewName())) {
|
||||||
|
result.addError(NLS.bind(Messages.ExtractFunctionRefactoring_parameter_name_in_use,
|
||||||
|
BasicElementLabels.getCElementName(parameter.getNewName())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the parameter names are valid.
|
||||||
|
* @return validation status
|
||||||
|
*/
|
||||||
|
public RefactoringStatus checkParameterAndReturnTypes() {
|
||||||
|
RefactoringStatus result= new RefactoringStatus();
|
||||||
|
for (NameInformation parameter : info.getParameters()) {
|
||||||
|
String typeName = parameter.getTypeName();
|
||||||
|
if (typeName == null || typeName.isEmpty()) {
|
||||||
|
result.addError(NLS.bind(Messages.ExtractFunctionRefactoring_invalid_type,
|
||||||
|
BasicElementLabels.getCElementName(parameter.getNewName())));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the signature of the new method.
|
||||||
|
*
|
||||||
|
* @param methodName the method name used for the new method
|
||||||
|
* @return the signature of the extracted method
|
||||||
|
*/
|
||||||
|
public String getSignature(String methodName) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
NameInformation returnVariable = info.getReturnVariable();
|
||||||
|
if (returnVariable != null) {
|
||||||
|
String type = returnVariable.getReturnType();
|
||||||
|
if (type != null) {
|
||||||
|
buf.append(type);
|
||||||
|
} else {
|
||||||
|
buf.append("<unknown type>"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.append("void"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
buf.append(' ');
|
||||||
|
buf.append(methodName);
|
||||||
|
if (formattingOptions.insert_space_before_opening_paren_in_method_declaration)
|
||||||
|
buf.append(' ');
|
||||||
|
buf.append('(');
|
||||||
|
List<NameInformation> parameters = info.getParameters();
|
||||||
|
if (!parameters.isEmpty()) {
|
||||||
|
if (formattingOptions.insert_space_after_opening_paren_in_method_declaration)
|
||||||
|
buf.append(' ');
|
||||||
|
boolean first = true;
|
||||||
|
for (NameInformation parameter : parameters) {
|
||||||
|
if (!first) {
|
||||||
|
if (formattingOptions.insert_space_before_comma_in_method_declaration_parameters)
|
||||||
|
buf.append(' ');
|
||||||
|
buf.append(',');
|
||||||
|
if (formattingOptions.insert_space_after_comma_in_method_declaration_parameters)
|
||||||
|
buf.append(' ');
|
||||||
|
}
|
||||||
|
IASTParameterDeclaration declaration = parameter.getParameterDeclaration(nodeFactory);
|
||||||
|
ASTWriterVisitor writer = new ASTWriterVisitor();
|
||||||
|
declaration.accept(writer);
|
||||||
|
buf.append(writer.toString());
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
if (formattingOptions.insert_space_before_closing_paren_in_method_declaration)
|
||||||
|
buf.append(' ');
|
||||||
|
} else if (formattingOptions.insert_space_between_empty_parens_in_method_declaration) {
|
||||||
|
buf.append(' ');
|
||||||
|
}
|
||||||
|
buf.append(')');
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
|
@ -18,7 +19,6 @@ import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.CRefactoring;
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
|
import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,8 +35,8 @@ public class ExtractFunctionRefactoringRunner extends RefactoringRunner {
|
||||||
public void run() {
|
public void run() {
|
||||||
ExtractFunctionInformation info = new ExtractFunctionInformation();
|
ExtractFunctionInformation info = new ExtractFunctionInformation();
|
||||||
|
|
||||||
CRefactoring refactoring = new ExtractFunctionRefactoring(file,selection,info, project);
|
ExtractFunctionRefactoring refactoring = new ExtractFunctionRefactoring(file, selection, info, project);
|
||||||
ExtractFunctionRefactoringWizard wizard = new ExtractFunctionRefactoringWizard(refactoring,info);
|
ExtractFunctionWizard wizard = new ExtractFunctionWizard(refactoring);
|
||||||
RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard);
|
RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,27 +8,24 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
import org.eclipse.ltk.core.refactoring.Refactoring;
|
|
||||||
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
|
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
|
||||||
import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
|
|
||||||
|
|
||||||
public class ExtractFunctionRefactoringWizard extends RefactoringWizard {
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
private final ExtractFunctionInformation info;
|
|
||||||
|
|
||||||
public ExtractFunctionRefactoringWizard(Refactoring refactoring, ExtractFunctionInformation info) {
|
public class ExtractFunctionWizard extends RefactoringWizard {
|
||||||
super(refactoring, WIZARD_BASED_USER_INTERFACE);
|
public ExtractFunctionWizard(ExtractFunctionRefactoring refactoring) {
|
||||||
this.info = info;
|
super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
|
||||||
|
setDefaultPageTitle(Messages.ExtractFunctionWizard_extract_function);
|
||||||
|
setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addUserInputPages() {
|
protected void addUserInputPages() {
|
||||||
UserInputWizardPage page = new ExtractFunctionInputPage(
|
addPage(new ExtractFunctionInputPage());
|
||||||
Messages.ExtractFunctionRefactoringWizard_FunctionName,info);
|
|
||||||
page.setTitle(Messages.ExtractFunctionRefactoringWizard_FunctionName);
|
|
||||||
addPage(page);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ public class ExtractStatement extends ExtractedFunctionConstructionHelper {
|
||||||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
||||||
NameInformation returnVariable) {
|
NameInformation returnVariable) {
|
||||||
if (returnVariable != null) {
|
if (returnVariable != null) {
|
||||||
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclaration());
|
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclarationName());
|
||||||
return ASTHelper.getDeclarationSpecifier(decl).copy(CopyStyle.withLocations);
|
return ASTHelper.getDeclarationSpecifier(decl).copy(CopyStyle.withLocations);
|
||||||
}
|
}
|
||||||
IASTDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
IASTDeclSpecifier declSpec = new CPPASTSimpleDeclSpecifier();
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mirko Stocker
|
* @author Mirko Stocker
|
||||||
|
@ -73,7 +73,7 @@ public abstract class ExtractedFunctionConstructionHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnVariable != null) {
|
if (returnVariable != null) {
|
||||||
IASTDeclarator decl = (IASTDeclarator) returnVariable.getDeclaration().getParent();
|
IASTDeclarator decl = returnVariable.getDeclarator();
|
||||||
IASTPointerOperator[] pointers = decl.getPointerOperators();
|
IASTPointerOperator[] pointers = decl.getPointerOperators();
|
||||||
for (IASTPointerOperator operator : pointers) {
|
for (IASTPointerOperator operator : pointers) {
|
||||||
declarator.addPointerOperator(operator.copy(CopyStyle.withLocations));
|
declarator.addPointerOperator(operator.copy(CopyStyle.withLocations));
|
||||||
|
@ -94,8 +94,8 @@ public abstract class ExtractedFunctionConstructionHelper {
|
||||||
public List<IASTParameterDeclaration> getParameterDeclarations(
|
public List<IASTParameterDeclaration> getParameterDeclarations(
|
||||||
Collection<NameInformation> parameterNames, INodeFactory nodeFactory) {
|
Collection<NameInformation> parameterNames, INodeFactory nodeFactory) {
|
||||||
List<IASTParameterDeclaration> result = new ArrayList<IASTParameterDeclaration>(parameterNames.size());
|
List<IASTParameterDeclaration> result = new ArrayList<IASTParameterDeclaration>(parameterNames.size());
|
||||||
for (NameInformation name : parameterNames) {
|
for (NameInformation param : parameterNames) {
|
||||||
result.add(name.getParameterDeclaration(nodeFactory));
|
result.add(param.getParameterDeclaration(nodeFactory));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,35 +8,40 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
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 ExtractFunctionRefactoringWizard_FunctionName;
|
public static String ExtractFunctionWizard_extract_function;
|
||||||
public static String ExtractFunctionRefactoring_ExtractFunction;
|
public static String ExtractFunctionRefactoring_ExtractFunction;
|
||||||
public static String ExtractFunctionRefactoring_NoStmtSelected;
|
public static String ExtractFunctionRefactoring_NoStmtSelected;
|
||||||
public static String ExtractFunctionRefactoring_TooManySelected;
|
public static String ExtractFunctionRefactoring_TooManySelected;
|
||||||
public static String ExtractFunctionRefactoring_NameInUse;
|
public static String ExtractFunctionRefactoring_name_in_use;
|
||||||
|
public static String ExtractFunctionRefactoring_parameter_name_in_use;
|
||||||
|
public static String ExtractFunctionRefactoring_duplicate_parameter;
|
||||||
|
public static String ExtractFunctionRefactoring_invalid_type;
|
||||||
public static String ExtractFunctionComposite_MethodName;
|
public static String ExtractFunctionComposite_MethodName;
|
||||||
public static String ExtractFunctionComposite_FunctionName;
|
public static String ExtractFunctionComposite_FunctionName;
|
||||||
public static String ExtractFunctionInputPage_EnterName;
|
public static String ExtractFunctionInputPage_description;
|
||||||
public static String ExtractFunctionInputPage_CheckFunctionName;
|
public static String ExtractFunctionInputPage_access_modifier;
|
||||||
public static String ExtractFunctionInputPage_1;
|
public static String ExtractFunctionInputPage_public;
|
||||||
public static String ExtractFunctionComposite_ReturnValue;
|
public static String ExtractFunctionInputPage_protected;
|
||||||
|
public static String ExtractFunctionInputPage_private;
|
||||||
|
public static String ExtractFunctionInputPage_signature_preview;
|
||||||
|
public static String ExtractFunctionInputPage_label_text;
|
||||||
|
public static String ExtractFunctionInputPage_parameters;
|
||||||
|
public static String ExtractFunctionInputPage_validation_empty_function_name;
|
||||||
|
public static String ExtractFunctionInputPage_validation_empty_parameter_name;
|
||||||
|
public static String ExtractFunctionInputPage_duplicates_none;
|
||||||
|
public static String ExtractFunctionInputPage_duplicates_single;
|
||||||
|
public static String ExtractFunctionInputPage_duplicates_multi;
|
||||||
public static String ExtractFunctionRefactoring_CreateMethodDef;
|
public static String ExtractFunctionRefactoring_CreateMethodDef;
|
||||||
public static String ExtractFunctionRefactoring_CreateFunctionDef;
|
public static String ExtractFunctionRefactoring_CreateFunctionDef;
|
||||||
public static String ExtractFunctionComposite_ReplaceDuplicates;
|
|
||||||
public static String ExtractFunctionComposite_Virtual;
|
|
||||||
public static String ExtractFunctionRefactoring_CreateMethodCall;
|
public static String ExtractFunctionRefactoring_CreateMethodCall;
|
||||||
public static String ExtractFunctionRefactoring_CreateFunctionCall;
|
public static String ExtractFunctionRefactoring_CreateFunctionCall;
|
||||||
public static String ChooserComposite_Return;
|
|
||||||
public static String ChooserComposite_CallByRef;
|
|
||||||
public static String ChooserComposite_const;
|
|
||||||
public static String ChooserComposite_Name;
|
|
||||||
public static String ChooserComposite_Type;
|
|
||||||
public static String ChooserComposite_NoReturnValue;
|
|
||||||
public static String ExtractFunctionRefactoring_Error_Return;
|
public static String ExtractFunctionRefactoring_Error_Return;
|
||||||
public static String ExtractFunctionRefactoring_Error_Continue;
|
public static String ExtractFunctionRefactoring_Error_Continue;
|
||||||
public static String ExtractFunctionRefactoring_Error_Break;
|
public static String ExtractFunctionRefactoring_Error_Break;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
# Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
# Rapperswil, University of applied sciences and others
|
# Rapperswil, University of applied sciences 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
|
||||||
|
@ -7,31 +7,36 @@
|
||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# Institute for Software - initial API and implementation
|
# Institute for Software - initial API and implementation
|
||||||
|
# Sergey Prigogin (Google)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
ExtractFunctionRefactoringWizard_FunctionName=Function Name
|
ExtractFunctionWizard_extract_function=Extract Function
|
||||||
ExtractFunctionRefactoring_ExtractFunction=Extract Function
|
ExtractFunctionRefactoring_ExtractFunction=Extract Function
|
||||||
ExtractFunctionRefactoring_NoStmtSelected=No statement selected
|
ExtractFunctionRefactoring_NoStmtSelected=No statement selected
|
||||||
ExtractFunctionRefactoring_TooManySelected=Too many declarations in selection.
|
ExtractFunctionRefactoring_TooManySelected=Too many declarations in selection.
|
||||||
ExtractFunctionRefactoring_NameInUse=Name already in use.
|
ExtractFunctionRefactoring_name_in_use=Name already in use.
|
||||||
|
ExtractFunctionRefactoring_parameter_name_in_use=''{0}'' is already used as a name in the selected code
|
||||||
|
ExtractFunctionRefactoring_duplicate_parameter=A parameter ''{0}'' already exists
|
||||||
|
ExtractFunctionRefactoring_invalid_type=Unable to determine type of ''{0}''
|
||||||
ExtractFunctionComposite_MethodName=Method &name:
|
ExtractFunctionComposite_MethodName=Method &name:
|
||||||
ExtractFunctionComposite_FunctionName=Function &name:
|
ExtractFunctionComposite_FunctionName=Function &name:
|
||||||
ExtractFunctionInputPage_EnterName=Enter a name
|
ExtractFunctionInputPage_description=Enter new method name and specify the method's visibility
|
||||||
ExtractFunctionInputPage_CheckFunctionName=Check Function Name:
|
ExtractFunctionInputPage_access_modifier=&Access modifier:
|
||||||
ExtractFunctionInputPage_1=is used after the extracted block - it needs to be passed by reference or must be the return value.
|
ExtractFunctionInputPage_public=public
|
||||||
ExtractFunctionComposite_ReturnValue=Return value:
|
ExtractFunctionInputPage_protected=protected
|
||||||
|
ExtractFunctionInputPage_private=private
|
||||||
|
ExtractFunctionInputPage_signature_preview=Function signature preview:
|
||||||
|
ExtractFunctionInputPage_label_text=Function &name:
|
||||||
|
ExtractFunctionInputPage_parameters=&Parameters:
|
||||||
|
ExtractFunctionInputPage_validation_empty_function_name=Provide a method name
|
||||||
|
ExtractFunctionInputPage_validation_empty_parameter_name=Parameter names cannot be empty
|
||||||
|
ExtractFunctionInputPage_duplicates_none=&Replace additional occurrences of statements with method
|
||||||
|
ExtractFunctionInputPage_duplicates_single=&Replace 1 additional occurrence of statements with method
|
||||||
|
ExtractFunctionInputPage_duplicates_multi=&Replace {0} additional occurrences of statements with method
|
||||||
ExtractFunctionRefactoring_CreateMethodDef=Create Method Definition
|
ExtractFunctionRefactoring_CreateMethodDef=Create Method Definition
|
||||||
ExtractFunctionRefactoring_CreateFunctionDef=Create Function Definition
|
ExtractFunctionRefactoring_CreateFunctionDef=Create Function Definition
|
||||||
ExtractFunctionComposite_ReplaceDuplicates=Replace all occurrences of statements with method.
|
|
||||||
ExtractFunctionComposite_Virtual=virtual
|
|
||||||
ExtractFunctionRefactoring_CreateMethodCall=Create Method Call
|
ExtractFunctionRefactoring_CreateMethodCall=Create Method Call
|
||||||
ExtractFunctionRefactoring_CreateFunctionCall=Create Function Call
|
ExtractFunctionRefactoring_CreateFunctionCall=Create Function Call
|
||||||
ChooserComposite_Return=Return
|
|
||||||
ChooserComposite_CallByRef=Call by Reference
|
|
||||||
ChooserComposite_const=const
|
|
||||||
ChooserComposite_Name=Name
|
|
||||||
ChooserComposite_Type=Type
|
|
||||||
ChooserComposite_NoReturnValue=No return-value (void)
|
|
||||||
ExtractFunctionRefactoring_Error_Return=Extracting return statements is not supported
|
ExtractFunctionRefactoring_Error_Return=Extracting return statements is not supported
|
||||||
ExtractFunctionRefactoring_Error_Continue=Extracting cotinue statements without the surrounding loop is not possible. Please adjust your selection.
|
ExtractFunctionRefactoring_Error_Continue=Extracting cotinue statements without the surrounding loop is not possible. Please adjust your selection.
|
||||||
ExtractFunctionRefactoring_Error_Break=Extracting break statements without the surrounding loop is not possible. Please adjust your selection.
|
ExtractFunctionRefactoring_Error_Break=Extracting break statements without the surrounding loop is not possible. Please adjust your selection.
|
||||||
|
|
|
@ -16,39 +16,28 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
|
||||||
|
|
||||||
final class SimilarFinderVisitor extends ASTVisitor {
|
|
||||||
private final ExtractFunctionRefactoring refactoring;
|
|
||||||
|
|
||||||
|
abstract class SimilarFinderVisitor extends ASTVisitor {
|
||||||
|
protected final ExtractFunctionRefactoring refactoring;
|
||||||
|
protected final NodeContainer extractedNodes;
|
||||||
|
protected NodeContainer similarContainer;
|
||||||
|
protected final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
||||||
private final List<IASTNode> trail;
|
private final List<IASTNode> trail;
|
||||||
private final IASTName name;
|
|
||||||
private final List<IASTNode> statements;
|
private final List<IASTNode> statements;
|
||||||
private int statementCount;
|
private int statementCount;
|
||||||
private NodeContainer similarContainer;
|
|
||||||
private final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
|
||||||
|
|
||||||
private final ModificationCollector collector;
|
SimilarFinderVisitor(ExtractFunctionRefactoring refactoring, NodeContainer extractedNodes,
|
||||||
|
List<IASTNode> trail, List<IASTNode> statements) {
|
||||||
SimilarFinderVisitor(ExtractFunctionRefactoring refactoring, ModificationCollector collector,
|
|
||||||
List<IASTNode> trail, IFile file, IASTName name, List<IASTNode> statements,
|
|
||||||
String title) {
|
|
||||||
this.refactoring = refactoring;
|
this.refactoring = refactoring;
|
||||||
|
this.extractedNodes = extractedNodes;
|
||||||
this.trail = trail;
|
this.trail = trail;
|
||||||
this.name = name;
|
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
this.collector = collector;
|
|
||||||
this.similarContainer = new NodeContainer();
|
this.similarContainer = new NodeContainer();
|
||||||
shouldVisitStatements = true;
|
shouldVisitStatements = true;
|
||||||
}
|
}
|
||||||
|
@ -65,8 +54,8 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
// Found similar code
|
// Found similar code
|
||||||
boolean similarOnReturnWays = true;
|
boolean similarOnReturnWays = true;
|
||||||
for (NameInformation nameInfo : similarContainer.getParameterCandidates()) {
|
for (NameInformation nameInfo : similarContainer.getParameterCandidates()) {
|
||||||
if (refactoring.names.containsKey(nameInfo.getDeclaration().getRawSignature())) {
|
if (refactoring.names.containsKey(nameInfo.getDeclarationName().getRawSignature())) {
|
||||||
Integer nameOrderNumber = refactoring.names.get(nameInfo.getDeclaration().getRawSignature());
|
Integer nameOrderNumber = refactoring.names.get(nameInfo.getDeclarationName().getRawSignature());
|
||||||
if (refactoring.nameTrail.containsValue(nameOrderNumber)) {
|
if (refactoring.nameTrail.containsValue(nameOrderNumber)) {
|
||||||
String orgName = null;
|
String orgName = null;
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
|
@ -77,9 +66,9 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (orgName != null) {
|
if (orgName != null) {
|
||||||
for (NameInformation orgNameInfo : refactoring.container.getParameterCandidates()) {
|
for (NameInformation orgNameInfo : extractedNodes.getParameterCandidates()) {
|
||||||
if (orgName.equals(orgNameInfo.getDeclaration().getRawSignature()) &&
|
if (orgName.equals(orgNameInfo.getDeclarationName().getRawSignature()) &&
|
||||||
(orgNameInfo.mustBeOutput() || !nameInfo.mustBeOutput())) {
|
(orgNameInfo.isOutput() || !nameInfo.isOutput())) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -94,17 +83,7 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (similarOnReturnWays) {
|
if (similarOnReturnWays) {
|
||||||
IASTNode call = refactoring.getMethodCall(name, refactoring.nameTrail,
|
foundSimilar();
|
||||||
refactoring.names, refactoring.container, similarContainer);
|
|
||||||
ASTRewrite rewrite =
|
|
||||||
collector.rewriterForTranslationUnit(stmtToReplace.get(0).getTranslationUnit());
|
|
||||||
TextEditGroup editGroup = new TextEditGroup(Messages.SimilarFinderVisitor_replaceDuplicateCode);
|
|
||||||
rewrite.replace(stmtToReplace.get(0), call, editGroup);
|
|
||||||
if (stmtToReplace.size() > 1) {
|
|
||||||
for (int i = 1; i < stmtToReplace.size(); ++i) {
|
|
||||||
rewrite.remove(stmtToReplace.get(i), editGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
@ -115,8 +94,10 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void foundSimilar();
|
||||||
|
|
||||||
private boolean isInSelection(IASTStatement stmt) {
|
private boolean isInSelection(IASTStatement stmt) {
|
||||||
List<IASTNode>nodes = refactoring.container.getNodesToWrite();
|
List<IASTNode>nodes = extractedNodes.getNodesToWrite();
|
||||||
for (IASTNode node : nodes) {
|
for (IASTNode node : nodes) {
|
||||||
if (node.equals(stmt)) {
|
if (node.equals(stmt)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 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.extractfunction;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||||
|
|
||||||
|
final class SimilarReplacerVisitor extends SimilarFinderVisitor {
|
||||||
|
private final IASTName name;
|
||||||
|
|
||||||
|
private final ModificationCollector collector;
|
||||||
|
|
||||||
|
SimilarReplacerVisitor(ExtractFunctionRefactoring refactoring, NodeContainer extractedNodes, ModificationCollector collector,
|
||||||
|
List<IASTNode> trail, IASTName name, List<IASTNode> statements) {
|
||||||
|
super(refactoring, extractedNodes, trail, statements);
|
||||||
|
this.name = name;
|
||||||
|
this.collector = collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void foundSimilar() {
|
||||||
|
IASTNode call = refactoring.getMethodCall(name, refactoring.nameTrail,
|
||||||
|
refactoring.names, extractedNodes, similarContainer);
|
||||||
|
ASTRewrite rewrite =
|
||||||
|
collector.rewriterForTranslationUnit(stmtToReplace.get(0).getTranslationUnit());
|
||||||
|
TextEditGroup editGroup = new TextEditGroup(Messages.SimilarFinderVisitor_replaceDuplicateCode);
|
||||||
|
rewrite.replace(stmtToReplace.get(0), call, editGroup);
|
||||||
|
if (stmtToReplace.size() > 1) {
|
||||||
|
for (int i = 1; i < stmtToReplace.size(); ++i) {
|
||||||
|
rewrite.remove(stmtToReplace.get(i), editGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,21 +13,17 @@ package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.Platform;
|
|
||||||
import org.eclipse.core.runtime.preferences.IPreferencesService;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CConventions;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
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.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
|
||||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
|
||||||
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.ui.util.NameComposer;
|
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||||
|
|
||||||
public class GetterSetterNameGenerator {
|
public class GetterSetterNameGenerator {
|
||||||
private static Set<String> generateGetterSettersPreferenceKeys = new HashSet<String>();
|
private static Set<String> generateGetterSettersPreferenceKeys = new HashSet<String>();
|
||||||
|
@ -64,29 +60,16 @@ public class GetterSetterNameGenerator {
|
||||||
* generated.
|
* generated.
|
||||||
*/
|
*/
|
||||||
public static String generateGetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
public static String generateGetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
||||||
IPreferencesService preferences = Platform.getPreferencesService();
|
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||||
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
return StubUtility.suggestGetterName(StubUtility.trimFieldName(fieldName.toString()),
|
||||||
PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION,
|
isBooleanDeclaratorName(fieldName), namesToAvoid, tu);
|
||||||
PreferenceConstants.NAME_STYLE_CAPITALIZATION_CAMEL_CASE, null);
|
|
||||||
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
|
||||||
String prefix = isBooleanDeclaratorName(fieldName) ?
|
|
||||||
preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is", null) : //$NON-NLS-1$
|
|
||||||
preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_GETTER_PREFIX, "get", null); //$NON-NLS-1$
|
|
||||||
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_GETTER_SUFFIX, "", null); //$NON-NLS-1$
|
|
||||||
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
|
||||||
String name = NameComposer.trimFieldName(fieldName.toString());
|
|
||||||
name = composer.compose(name);
|
|
||||||
return adjustName(name, namesToAvoid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isBooleanDeclaratorName(IASTName name) {
|
private static boolean isBooleanDeclaratorName(IASTName name) {
|
||||||
if (IASTDeclarator.DECLARATOR_NAME.equals(name.getPropertyInParent())) {
|
if (IASTDeclarator.DECLARATOR_NAME.equals(name.getPropertyInParent())) {
|
||||||
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
||||||
IType type = CPPVisitor.createType(declarator);
|
IType type = CPPVisitor.createType(declarator);
|
||||||
|
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
|
||||||
if (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eBoolean) {
|
if (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eBoolean) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -103,57 +86,16 @@ public class GetterSetterNameGenerator {
|
||||||
* generated.
|
* generated.
|
||||||
*/
|
*/
|
||||||
public static String generateSetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
public static String generateSetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
||||||
IPreferencesService preferences = Platform.getPreferencesService();
|
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||||
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
return StubUtility.suggestSetterName(StubUtility.trimFieldName(fieldName.toString()), namesToAvoid, tu);
|
||||||
PreferenceConstants.NAME_STYLE_SETTER_CAPITALIZATION,
|
|
||||||
PreferenceConstants.NAME_STYLE_CAPITALIZATION_CAMEL_CASE, null);
|
|
||||||
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_SETTER_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
|
||||||
String prefix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_SETTER_PREFIX, "set", null); //$NON-NLS-1$
|
|
||||||
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_SETTER_SUFFIX, "", null); //$NON-NLS-1$
|
|
||||||
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
|
||||||
String name = NameComposer.trimFieldName(fieldName.toString());
|
|
||||||
name = composer.compose(name);
|
|
||||||
return adjustName(name, namesToAvoid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generateSetterParameterName(IASTName fieldName){
|
public static String generateSetterParameterName(IASTName fieldName) {
|
||||||
IPreferencesService preferences = Platform.getPreferencesService();
|
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||||
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
|
return StubUtility.suggestParameterName(StubUtility.trimFieldName(fieldName.toString()), null, tu);
|
||||||
PreferenceConstants.NAME_STYLE_VARIABLE_CAPITALIZATION,
|
|
||||||
PreferenceConstants.NAME_STYLE_CAPITALIZATION_ORIGINAL, null);
|
|
||||||
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_VARIABLE_WORD_DELIMITER, "", null); //$NON-NLS-1$
|
|
||||||
String prefix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_VARIABLE_PREFIX, "", null); //$NON-NLS-1$
|
|
||||||
String suffix = preferences.getString(CUIPlugin.PLUGIN_ID,
|
|
||||||
PreferenceConstants.NAME_STYLE_VARIABLE_SUFFIX, "", null); //$NON-NLS-1$
|
|
||||||
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
|
|
||||||
String name = NameComposer.trimFieldName(fieldName.toString());
|
|
||||||
name = composer.compose(name);
|
|
||||||
if (!CConventions.validateIdentifier(name, GPPLanguage.getDefault()).isOK())
|
|
||||||
name = '_' + name;
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static ITranslationUnit getTranslationUnit(IASTNode node) {
|
||||||
* Checks is the given name is valid and, if not, tries to adjust it by adding a numeric suffix
|
return node.getTranslationUnit().getOriginatingTranslationUnit();
|
||||||
* to it.
|
|
||||||
*
|
|
||||||
* @param name the name to check and, possibly, adjust
|
|
||||||
* @param namesToAvoid the set of names to avoid
|
|
||||||
* @return the adjusted name, or <code>null</code> if a valid name could not be generated.
|
|
||||||
*/
|
|
||||||
private static String adjustName(String name, Set<String> namesToAvoid) {
|
|
||||||
String originalName = name;
|
|
||||||
for (int i = 1; i < 100; i++) {
|
|
||||||
if (!namesToAvoid.contains(name) && CConventions.validateIdentifier(name, GPPLanguage.getDefault()).isOK()) {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
name = originalName + i;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2011 IBM Corporation and others.
|
* Copyright (c) 2000, 2012 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
|
||||||
|
@ -21,12 +21,17 @@ import org.eclipse.core.runtime.Assert;
|
||||||
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.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||||
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
|
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
|
||||||
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
|
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CConventions;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||||
|
import org.eclipse.cdt.core.dom.parser.AbstractCLikeLanguage;
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
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.internal.corext.util.CModelUtil;
|
import org.eclipse.cdt.internal.corext.util.CModelUtil;
|
||||||
|
@ -65,6 +70,63 @@ public class Checks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given name is a valid Java identifier.
|
||||||
|
*
|
||||||
|
* @param name the java identifier.
|
||||||
|
* @param context an {@link ITranslationUnit} or <code>null</code>
|
||||||
|
* @return a refactoring status containing the error message if the
|
||||||
|
* name is not a valid java identifier.
|
||||||
|
*/
|
||||||
|
public static RefactoringStatus checkIdentifier(String name, ITranslationUnit context) {
|
||||||
|
return checkName(name, validateIdentifier(name, context));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IStatus validateIdentifier(String name, ITranslationUnit context) {
|
||||||
|
ILanguage language = null;
|
||||||
|
try {
|
||||||
|
if (context != null)
|
||||||
|
language = context.getLanguage();
|
||||||
|
} catch (CoreException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
if (language == null) {
|
||||||
|
language = GPPLanguage.getDefault();
|
||||||
|
}
|
||||||
|
if (language instanceof AbstractCLikeLanguage) {
|
||||||
|
return CConventions.validateIdentifier(name, (AbstractCLikeLanguage) language);
|
||||||
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a fatal error in case the name is empty. In all other cases, an
|
||||||
|
* error based on the given status is returned.
|
||||||
|
*
|
||||||
|
* @param name a name
|
||||||
|
* @param status a status
|
||||||
|
* @return RefactoringStatus based on the given status or the name, if empty.
|
||||||
|
*/
|
||||||
|
public static RefactoringStatus checkName(String name, IStatus status) {
|
||||||
|
RefactoringStatus result= new RefactoringStatus();
|
||||||
|
if (name.isEmpty())
|
||||||
|
return RefactoringStatus.createFatalErrorStatus(Messages.Checks_choose_name);
|
||||||
|
|
||||||
|
if (status.isOK())
|
||||||
|
return result;
|
||||||
|
|
||||||
|
switch (status.getSeverity()){
|
||||||
|
case IStatus.ERROR:
|
||||||
|
return RefactoringStatus.createFatalErrorStatus(status.getMessage());
|
||||||
|
case IStatus.WARNING:
|
||||||
|
return RefactoringStatus.createWarningStatus(status.getMessage());
|
||||||
|
case IStatus.INFO:
|
||||||
|
return RefactoringStatus.createInfoStatus(status.getMessage());
|
||||||
|
default: // Nothing
|
||||||
|
return new RefactoringStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean resourceExists(IPath resourcePath){
|
public static boolean resourceExists(IPath resourcePath){
|
||||||
return ResourcesPlugin.getWorkspace().getRoot().findMember(resourcePath) != null;
|
return ResourcesPlugin.getWorkspace().getRoot().findMember(resourcePath) != null;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +148,7 @@ public class Checks {
|
||||||
if (attributes != null && attributes.isReadOnly())
|
if (attributes != null && attributes.isReadOnly())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (! (res instanceof IContainer))
|
if (!(res instanceof IContainer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
IContainer container= (IContainer)res;
|
IContainer container= (IContainer)res;
|
||||||
|
@ -116,7 +178,7 @@ public class Checks {
|
||||||
if (!status.isOK()) {
|
if (!status.isOK()) {
|
||||||
result.merge(RefactoringStatus.create(status));
|
result.merge(RefactoringStatus.create(status));
|
||||||
if (!result.hasFatalError()) {
|
if (!result.hasFatalError()) {
|
||||||
result.addFatalError(Messages.Checks_validateEdit);
|
result.addFatalError(Messages.Checks_validate_edit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -143,7 +205,7 @@ public class Checks {
|
||||||
if (!status.isOK()) {
|
if (!status.isOK()) {
|
||||||
result.merge(RefactoringStatus.create(status));
|
result.merge(RefactoringStatus.create(status));
|
||||||
if (!result.hasFatalError()) {
|
if (!result.hasFatalError()) {
|
||||||
result.addFatalError(Messages.Checks_validateEdit);
|
result.addFatalError(Messages.Checks_validate_edit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -21,10 +21,8 @@ public final class Messages extends NLS {
|
||||||
public static String IdentifierHelper_emptyIdentifier;
|
public static String IdentifierHelper_emptyIdentifier;
|
||||||
public static String IdentifierHelper_illegalCharacter;
|
public static String IdentifierHelper_illegalCharacter;
|
||||||
public static String IdentifierHelper_unidentifiedMistake;
|
public static String IdentifierHelper_unidentifiedMistake;
|
||||||
public static String VisibilityEnum_public;
|
public static String Checks_validate_edit;
|
||||||
public static String VisibilityEnum_protected;
|
public static String Checks_choose_name;
|
||||||
public static String VisibilityEnum_private;
|
|
||||||
public static String Checks_validateEdit;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
NLS.initializeMessages(Messages.class.getName(), Messages.class);
|
NLS.initializeMessages(Messages.class.getName(), Messages.class);
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# Institute for Software - initial API and implementation
|
# Institute for Software - initial API and implementation
|
||||||
# IBM Corporation
|
# IBM Corporation
|
||||||
|
# Sergey Prigogin (Google)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
IdentifierHelper_isKeyword=''{0}'' is a keyword.
|
IdentifierHelper_isKeyword=''{0}'' is a keyword.
|
||||||
IdentifierHelper_isValid=''{0}'' is valid.
|
IdentifierHelper_isValid=''{0}'' is valid.
|
||||||
|
@ -16,7 +17,5 @@ IdentifierHelper_leadingDigit=''{0}'' has a leading digit.
|
||||||
IdentifierHelper_emptyIdentifier=Identifier must not be empty.
|
IdentifierHelper_emptyIdentifier=Identifier must not be empty.
|
||||||
IdentifierHelper_illegalCharacter=Illegal character found in ''{0}''.
|
IdentifierHelper_illegalCharacter=Illegal character found in ''{0}''.
|
||||||
IdentifierHelper_unidentifiedMistake=''{0}'' contains an unidentified mistake.
|
IdentifierHelper_unidentifiedMistake=''{0}'' contains an unidentified mistake.
|
||||||
VisibilityEnum_public=public
|
Checks_validate_edit=Team provider refused file modification.
|
||||||
VisibilityEnum_protected=protected
|
Checks_choose_name=Choose a name.
|
||||||
VisibilityEnum_private=private
|
|
||||||
Checks_validateEdit=Team provider refused file modification.
|
|
||||||
|
|
|
@ -8,11 +8,12 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.utils;
|
package org.eclipse.cdt.internal.ui.refactoring.utils;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum that represents C++ visibilities, with methods to convert to
|
* Enum that represents C++ visibilities, with methods to convert to
|
||||||
|
@ -20,9 +21,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
|
||||||
*/
|
*/
|
||||||
public enum VisibilityEnum {
|
public enum VisibilityEnum {
|
||||||
// The values are ordered by increasing visibility.
|
// The values are ordered by increasing visibility.
|
||||||
v_private(Messages.VisibilityEnum_private, ICPPASTVisibilityLabel.v_private, ICPPASTBaseSpecifier.v_private),
|
v_private("private", ICPPASTVisibilityLabel.v_private, ICPPASTBaseSpecifier.v_private), //$NON-NLS-1$
|
||||||
v_protected(Messages.VisibilityEnum_protected, ICPPASTVisibilityLabel.v_protected, ICPPASTBaseSpecifier.v_protected),
|
v_protected("protected", ICPPASTVisibilityLabel.v_protected, ICPPASTBaseSpecifier.v_protected), //$NON-NLS-1$
|
||||||
v_public(Messages.VisibilityEnum_public, ICPPASTVisibilityLabel.v_public, ICPPASTBaseSpecifier.v_public);
|
v_public("public", ICPPASTVisibilityLabel.v_public, ICPPASTBaseSpecifier.v_public); //$NON-NLS-1$
|
||||||
|
|
||||||
private final String stringRepresentation;
|
private final String stringRepresentation;
|
||||||
private final int visibilityLabelValue;
|
private final int visibilityLabelValue;
|
||||||
|
|
|
@ -146,46 +146,4 @@ public class NameComposer {
|
||||||
Character.toUpperCase(word.charAt(i)) : Character.toLowerCase(word.charAt(i)));
|
Character.toUpperCase(word.charAt(i)) : Character.toLowerCase(word.charAt(i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the trimmed field name. Leading and trailing non-alphanumeric characters are trimmed.
|
|
||||||
* If the first word of the name consists of a single letter and the name contains more than
|
|
||||||
* one word, the first word is removed.
|
|
||||||
*
|
|
||||||
* @param fieldName a field name to trim
|
|
||||||
* @return the trimmed field name
|
|
||||||
*/
|
|
||||||
public static String trimFieldName(String fieldName){
|
|
||||||
CBreakIterator iterator = new CBreakIterator();
|
|
||||||
iterator.setText(fieldName);
|
|
||||||
int firstWordStart = -1;
|
|
||||||
int firstWordEnd = -1;
|
|
||||||
int secondWordStart = -1;
|
|
||||||
int lastWordEnd = -1;
|
|
||||||
int end;
|
|
||||||
for (int start = iterator.first(); (end = iterator.next()) != BreakIterator.DONE; start = end) {
|
|
||||||
if (Character.isLetterOrDigit(fieldName.charAt(start))) {
|
|
||||||
int pos = end;
|
|
||||||
while (--pos >= start && !Character.isLetterOrDigit(fieldName.charAt(pos))) {
|
|
||||||
}
|
|
||||||
lastWordEnd = pos + 1;
|
|
||||||
if (firstWordStart < 0) {
|
|
||||||
firstWordStart = start;
|
|
||||||
firstWordEnd = lastWordEnd;
|
|
||||||
} else if (secondWordStart < 0) {
|
|
||||||
secondWordStart = start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Skip the first word if it consists of a single letter and the name contains more than
|
|
||||||
// one word.
|
|
||||||
if (firstWordStart >= 0 && firstWordStart + 1 == firstWordEnd && secondWordStart >= 0) {
|
|
||||||
firstWordStart = secondWordStart;
|
|
||||||
}
|
|
||||||
if (firstWordStart < 0) {
|
|
||||||
return fieldName;
|
|
||||||
} else {
|
|
||||||
return fieldName.substring(firstWordStart, lastWordEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1661,9 +1661,43 @@ public class PreferenceConstants {
|
||||||
*/
|
*/
|
||||||
public static final String NAME_STYLE_FIELD_WORD_DELIMITER = "nameStyle.field.wordDelimiter"; //$NON-NLS-1$
|
public static final String NAME_STYLE_FIELD_WORD_DELIMITER = "nameStyle.field.wordDelimiter"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named preference that controls how capitalization of a method name.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>Integer</code>.
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public static final String NAME_STYLE_METHOD_CAPITALIZATION = "nameStyle.method.capitalization"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* A named preference that controls prefix of a method name.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>String</code>.
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public static final String NAME_STYLE_METHOD_PREFIX = "nameStyle.method.prefix"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* A named preference that controls suffix of a method name.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>String</code>.
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public static final String NAME_STYLE_METHOD_SUFFIX = "nameStyle.method.suffix"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* A named preference that controls delimiter that is inserted between words
|
||||||
|
* of a method name.
|
||||||
|
* <p>
|
||||||
|
* Value is of type <code>String</code>.
|
||||||
|
*
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public static final String NAME_STYLE_METHOD_WORD_DELIMITER = "nameStyle.method.wordDelimiter"; //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A named preference that controls how capitalization of the getter name
|
* A named preference that controls how capitalization of the getter name
|
||||||
* depends on capitalization of the field name.
|
* depends on capitalization of the method name.
|
||||||
* <p>
|
* <p>
|
||||||
* Value is of type <code>Integer</code>.
|
* Value is of type <code>Integer</code>.
|
||||||
*
|
*
|
||||||
|
@ -2101,6 +2135,10 @@ public class PreferenceConstants {
|
||||||
store.setDefault(NAME_STYLE_FIELD_PREFIX, ""); //$NON-NLS-1$
|
store.setDefault(NAME_STYLE_FIELD_PREFIX, ""); //$NON-NLS-1$
|
||||||
store.setDefault(NAME_STYLE_FIELD_SUFFIX, ""); //$NON-NLS-1$
|
store.setDefault(NAME_STYLE_FIELD_SUFFIX, ""); //$NON-NLS-1$
|
||||||
store.setDefault(NAME_STYLE_FIELD_WORD_DELIMITER, ""); //$NON-NLS-1$
|
store.setDefault(NAME_STYLE_FIELD_WORD_DELIMITER, ""); //$NON-NLS-1$
|
||||||
|
store.setDefault(NAME_STYLE_METHOD_CAPITALIZATION, NAME_STYLE_CAPITALIZATION_LOWER_CAMEL_CASE);
|
||||||
|
store.setDefault(NAME_STYLE_METHOD_PREFIX, ""); //$NON-NLS-1$
|
||||||
|
store.setDefault(NAME_STYLE_METHOD_SUFFIX, ""); //$NON-NLS-1$
|
||||||
|
store.setDefault(NAME_STYLE_METHOD_WORD_DELIMITER, ""); //$NON-NLS-1$
|
||||||
store.setDefault(NAME_STYLE_GETTER_CAPITALIZATION, NAME_STYLE_CAPITALIZATION_CAMEL_CASE);
|
store.setDefault(NAME_STYLE_GETTER_CAPITALIZATION, NAME_STYLE_CAPITALIZATION_CAMEL_CASE);
|
||||||
store.setDefault(NAME_STYLE_GETTER_PREFIX, "get"); //$NON-NLS-1$
|
store.setDefault(NAME_STYLE_GETTER_PREFIX, "get"); //$NON-NLS-1$
|
||||||
store.setDefault(NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is"); //$NON-NLS-1$
|
store.setDefault(NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is"); //$NON-NLS-1$
|
||||||
|
|