New UI and other improvements for Extract Function refactoring .
|
@ -10,14 +10,18 @@
|
|||
*******************************************************************************/
|
||||
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.ICompositeType;
|
||||
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.internal.core.dom.parser.ASTTranslationUnit;
|
||||
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.c.CVisitor;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -59,4 +63,12 @@ public class TypeHelper {
|
|||
}
|
||||
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;
|
||||
|
||||
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.Collections;
|
||||
|
@ -1864,6 +1868,8 @@ public class CPPVisitor extends ASTQueries {
|
|||
boolean isPackExpansion= false;
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||
} else if (parent instanceof IASTParameterDeclaration) {
|
||||
declSpec = ((IASTParameterDeclaration) parent).getDeclSpecifier();
|
||||
} else if (parent instanceof IASTFunctionDefinition) {
|
||||
declSpec = ((IASTFunctionDefinition) parent).getDeclSpecifier();
|
||||
} else if (parent instanceof ICPPASTTypeId) {
|
||||
|
@ -2506,4 +2512,21 @@ public class CPPVisitor extends ASTQueries {
|
|||
public static ICPPASTDeclarator findInnermostDeclarator(ICPPASTDeclarator 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;
|
||||
} else if (type instanceof ICPPTemplateInstance) {
|
||||
returnedDeclSpec = getDeclSpecForTemplate((ICPPTemplateInstance) type);
|
||||
|
||||
} else if (type instanceof IBinding) { /* ITypedef, ICompositeType... */
|
||||
// BTW - we need to distinguish (and fail explicitly) on literal composites like:
|
||||
// struct { } aSingleInstance;
|
||||
returnedDeclSpec = getDeclSpecForBinding((IBinding) type);
|
||||
}
|
||||
|
||||
// TODO(sprigogin): Be honest and return null instead of void.
|
||||
// Fallback...
|
||||
if (returnedDeclSpec == null) {
|
||||
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
|
||||
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
|
||||
// (to allow assignment, etc)
|
||||
|
@ -311,8 +311,8 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
|||
ICPPNodeFactory cppFactory = (ICPPNodeFactory) factory;
|
||||
ICPPASTTemplateId tempId = cppFactory.newTemplateId(templateName.copy());
|
||||
for (ICPPTemplateArgument arg : type.getTemplateArguments()) {
|
||||
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ? arg
|
||||
.getTypeValue() : arg.getTypeOfNonTypeValue());
|
||||
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ?
|
||||
arg.getTypeValue() : arg.getTypeOfNonTypeValue());
|
||||
IASTTypeId typeId = cppFactory.newTypeId(argDeclSpec, null);
|
||||
tempId.addTemplateArgument(typeId);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
|||
* @author Emanuel Graf
|
||||
*/
|
||||
public class ASTWriter {
|
||||
private ASTModificationStore modificationStore = new ASTModificationStore();
|
||||
private final ASTModificationStore modificationStore = new ASTModificationStore();
|
||||
|
||||
/**
|
||||
* Creates a <code>ASTWriter</code>.
|
||||
|
@ -63,7 +63,7 @@ public class ASTWriter {
|
|||
* Generates the source code representing this node including comments.
|
||||
*
|
||||
* @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.
|
||||
* @throws ProblemRuntimeException if the node or one of it's children is
|
||||
* an <code>IASTProblemNode</code>.
|
||||
|
@ -79,10 +79,6 @@ public class ASTWriter {
|
|||
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
|
||||
* before it.
|
||||
|
|
|
@ -80,6 +80,13 @@ public class ASTWriterVisitor extends ASTVisitor {
|
|||
shouldVisitTypeIds = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a writer with an empty comment map.
|
||||
*/
|
||||
public ASTWriterVisitor() {
|
||||
this(new NodeCommentMap());
|
||||
}
|
||||
|
||||
public ASTWriterVisitor(NodeCommentMap commentMap) {
|
||||
super();
|
||||
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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.cdt.core.formatter;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
||||
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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -10,15 +10,20 @@
|
|||
* Sergey Prigogin (Google)
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.formatter;
|
||||
package org.eclipse.cdt.core.formatter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
|
||||
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 static final int TAB = 1;
|
||||
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.formatter.CodeFormatter;
|
||||
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.model.CoreModel;
|
||||
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.gnu.c.ICASTKnRFunctionDeclarator;
|
||||
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.internal.formatter.align.Alignment;
|
||||
import org.eclipse.cdt.internal.formatter.align.AlignmentException;
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
|
||||
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.AlignmentException;
|
||||
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
|
||||
|
|
|
@ -1502,8 +1502,8 @@ public:
|
|||
return mClass;
|
||||
}
|
||||
|
||||
void setClass(int _class) {
|
||||
mClass = _class;
|
||||
void setClass(int clazz) {
|
||||
mClass = clazz;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -12,6 +12,8 @@ package org.eclipse.cdt.ui.tests.refactoring.utils;
|
|||
|
||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||
|
||||
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
||||
|
@ -46,42 +48,42 @@ public class NameComposerTest extends TestCase {
|
|||
}
|
||||
|
||||
public void testTrimFieldName() {
|
||||
assertEquals("f", NameComposer.trimFieldName("f_"));
|
||||
assertEquals("F", NameComposer.trimFieldName("F_"));
|
||||
assertEquals("oo", NameComposer.trimFieldName("F_oo"));
|
||||
assertEquals("o", NameComposer.trimFieldName("f_o"));
|
||||
assertEquals("f", StubUtility.trimFieldName("f_"));
|
||||
assertEquals("F", StubUtility.trimFieldName("F_"));
|
||||
assertEquals("oo", StubUtility.trimFieldName("F_oo"));
|
||||
assertEquals("o", StubUtility.trimFieldName("f_o"));
|
||||
|
||||
assertEquals("M", NameComposer.trimFieldName("a_M_"));
|
||||
assertEquals("bs", NameComposer.trimFieldName("a_bs_"));
|
||||
assertEquals("foo_bar", NameComposer.trimFieldName("foo_bar"));
|
||||
assertEquals("foo_bar", NameComposer.trimFieldName("foo_bar_"));
|
||||
assertEquals("M", StubUtility.trimFieldName("a_M_"));
|
||||
assertEquals("bs", StubUtility.trimFieldName("a_bs_"));
|
||||
assertEquals("foo_bar", StubUtility.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", NameComposer.trimFieldName("_foo"));
|
||||
assertEquals("bar", NameComposer.trimFieldName("_f_bar"));
|
||||
assertEquals("foo", StubUtility.trimFieldName("foo"));
|
||||
assertEquals("foo", StubUtility.trimFieldName("_foo"));
|
||||
assertEquals("bar", StubUtility.trimFieldName("_f_bar"));
|
||||
|
||||
assertEquals("f", NameComposer.trimFieldName("f__"));
|
||||
assertEquals("f", NameComposer.trimFieldName("__f"));
|
||||
assertEquals("O__b", NameComposer.trimFieldName("fO__b"));
|
||||
assertEquals("Oo", NameComposer.trimFieldName("fOo"));
|
||||
assertEquals("O", NameComposer.trimFieldName("fO"));
|
||||
assertEquals("MyStatic", NameComposer.trimFieldName("sMyStatic"));
|
||||
assertEquals("MyMember", NameComposer.trimFieldName("mMyMember"));
|
||||
assertEquals("f", StubUtility.trimFieldName("f__"));
|
||||
assertEquals("f", StubUtility.trimFieldName("__f"));
|
||||
assertEquals("O__b", StubUtility.trimFieldName("fO__b"));
|
||||
assertEquals("Oo", StubUtility.trimFieldName("fOo"));
|
||||
assertEquals("O", StubUtility.trimFieldName("fO"));
|
||||
assertEquals("MyStatic", StubUtility.trimFieldName("sMyStatic"));
|
||||
assertEquals("MyMember", StubUtility.trimFieldName("mMyMember"));
|
||||
|
||||
assertEquals("8", NameComposer.trimFieldName("_8"));
|
||||
assertEquals("8", StubUtility.trimFieldName("_8"));
|
||||
|
||||
assertEquals("8bar", NameComposer.trimFieldName("_8bar_"));
|
||||
assertEquals("8bar_8", NameComposer.trimFieldName("_8bar_8"));
|
||||
assertEquals("8bAr", NameComposer.trimFieldName("_8bAr"));
|
||||
assertEquals("b8Ar", NameComposer.trimFieldName("_b8Ar"));
|
||||
assertEquals("8bar", StubUtility.trimFieldName("_8bar_"));
|
||||
assertEquals("8bar_8", StubUtility.trimFieldName("_8bar_8"));
|
||||
assertEquals("8bAr", StubUtility.trimFieldName("_8bAr"));
|
||||
assertEquals("b8Ar", StubUtility.trimFieldName("_b8Ar"));
|
||||
|
||||
assertEquals("Id", NameComposer.trimFieldName("Id"));
|
||||
assertEquals("ID", NameComposer.trimFieldName("ID"));
|
||||
assertEquals("IDS", NameComposer.trimFieldName("IDS"));
|
||||
assertEquals("ID", NameComposer.trimFieldName("bID"));
|
||||
assertEquals("Id", NameComposer.trimFieldName("MId"));
|
||||
assertEquals("IdA", NameComposer.trimFieldName("IdA"));
|
||||
assertEquals("Id", StubUtility.trimFieldName("Id"));
|
||||
assertEquals("ID", StubUtility.trimFieldName("ID"));
|
||||
assertEquals("IDS", StubUtility.trimFieldName("IDS"));
|
||||
assertEquals("ID", StubUtility.trimFieldName("bID"));
|
||||
assertEquals("Id", StubUtility.trimFieldName("MId"));
|
||||
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.formatter.DefaultCodeFormatterConstants;
|
||||
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterOptions;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
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.CTextTools;
|
||||
|
|
|
@ -22,9 +22,9 @@ import org.eclipse.jface.text.source.LineRange;
|
|||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
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.internal.formatter.DefaultCodeFormatterOptions;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
|
||||
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.formatter.CodeFormatter;
|
||||
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.internal.corext.util.CodeFormatterUtil;
|
||||
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
|
||||
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.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
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.Platform;
|
||||
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.InstanceScope;
|
||||
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.MultiTextEdit;
|
||||
|
||||
import com.ibm.icu.text.BreakIterator;
|
||||
|
||||
import org.eclipse.cdt.core.CConventions;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
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.CoreModel;
|
||||
import org.eclipse.cdt.core.model.IBuffer;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
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.ITranslationUnit;
|
||||
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.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;
|
||||
|
||||
public class StubUtility {
|
||||
|
@ -747,4 +757,205 @@ public class StubUtility {
|
|||
}
|
||||
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 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_METHOD= createUnManaged(T_WIZBAN, "methrefact_wiz.gif"); //$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_TU= createUnManaged(T_WIZBAN, "refactor_tu_wiz.png"); //$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_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_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_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 EXTRACT_FUNCTION_WIZARD_PAGE= PREFIX + "extract_function_wizard_page_context"; //$NON-NLS-1$
|
||||
|
||||
// Dialogs
|
||||
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:
|
||||
* QNX Software Systems - initial API and implementation
|
||||
* Sergey Prigogin, Google
|
||||
* Sergey Prigogin (Google)
|
||||
* Anton Leherbauer (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.RGB;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
|
||||
import org.eclipse.ui.texteditor.AbstractTextEditor;
|
||||
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||
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.
|
||||
*/
|
||||
public class CSourceViewer extends ProjectionViewer implements IPropertyChangeListener {
|
||||
|
||||
/** Show outline operation id. */
|
||||
public static final int SHOW_OUTLINE= 101;
|
||||
/** Show type hierarchy operation id. */
|
||||
|
@ -620,4 +624,32 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
|
|||
cmd.event= 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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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.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.StatusInfo;
|
||||
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_VARIABLE_NAME = "myVariable"; //$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 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_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_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_WORD_DELIMITER = getCDTUIKey(PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER);
|
||||
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_PREFIX,
|
||||
KEY_FIELD_SUFFIX,
|
||||
KEY_METHOD_CAPITALIZATION,
|
||||
KEY_METHOD_WORD_DELIMITER,
|
||||
KEY_METHOD_PREFIX,
|
||||
KEY_METHOD_SUFFIX,
|
||||
KEY_GETTER_CAPITALIZATION,
|
||||
KEY_GETTER_WORD_DELIMITER,
|
||||
KEY_GETTER_PREFIX,
|
||||
|
@ -182,6 +193,14 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
|||
.setPrefixKey(KEY_FIELD_PREFIX)
|
||||
.setSuffixKey(KEY_FIELD_SUFFIX)
|
||||
.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,
|
||||
PreferencesMessages.NameStyleBlock_getter_node_description, EXAMPLE_FIELD_NAME,
|
||||
codeCategory)
|
||||
|
@ -572,7 +591,7 @@ public class NameStyleBlock extends OptionsConfigurationBlock {
|
|||
String name = seedNameGenerator != null ?
|
||||
seedNameGenerator.composeExampleName(settings) : seedName;
|
||||
if (trimFieldName) {
|
||||
name = NameComposer.trimFieldName(name);
|
||||
name = StubUtility.trimFieldName(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_field_node;
|
||||
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_description;
|
||||
public static String NameStyleBlock_setter_node;
|
||||
|
|
|
@ -420,8 +420,10 @@ NameStyleBlock_constant_node=Constant
|
|||
NameStyleBlock_constant_node_description=Constant name
|
||||
NameStyleBlock_variable_node=Variable
|
||||
NameStyleBlock_variable_node_description=Variable name
|
||||
NameStyleBlock_field_node=Class field
|
||||
NameStyleBlock_field_node=Class Field
|
||||
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_description=Getter name based on the field name
|
||||
NameStyleBlock_setter_node=Setter Method
|
||||
|
|
|
@ -66,6 +66,7 @@ public abstract class CRefactoring extends Refactoring {
|
|||
|
||||
protected String name = Messages.Refactoring_name;
|
||||
protected IFile file;
|
||||
protected final ITranslationUnit tu;
|
||||
protected Region region;
|
||||
protected RefactoringStatus initStatus;
|
||||
protected IASTTranslationUnit ast;
|
||||
|
@ -76,11 +77,10 @@ public abstract class CRefactoring extends Refactoring {
|
|||
project = proj;
|
||||
if (element instanceof ISourceReference) {
|
||||
ISourceReference sourceRef= (ISourceReference) element;
|
||||
ITranslationUnit tu = sourceRef.getTranslationUnit();
|
||||
this.tu = sourceRef.getTranslationUnit();
|
||||
IResource res= tu.getResource();
|
||||
if (res instanceof IFile)
|
||||
this.file= (IFile) res;
|
||||
|
||||
try {
|
||||
final ISourceRange sourceRange = sourceRef.getSourceRange();
|
||||
this.region = new Region(sourceRange.getIdStartPos(), sourceRange.getIdLength());
|
||||
|
@ -89,6 +89,7 @@ public abstract class CRefactoring extends Refactoring {
|
|||
}
|
||||
} else {
|
||||
this.file = file;
|
||||
this.tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file);
|
||||
this.region = SelectionHelper.getRegion(selection);
|
||||
}
|
||||
|
||||
|
@ -235,10 +236,10 @@ public abstract class CRefactoring extends Refactoring {
|
|||
|
||||
protected boolean loadTranslationUnit(RefactoringStatus status, IProgressMonitor mon) {
|
||||
SubMonitor subMonitor = SubMonitor.convert(mon, 10);
|
||||
if (file != null) {
|
||||
if (tu != null) {
|
||||
try {
|
||||
subMonitor.subTask(Messages.Refactoring_PM_ParseTU);
|
||||
ast = loadTranslationUnit(file);
|
||||
ast = tu.getAST(fIndex, AST_STYLE);
|
||||
if (ast == null) {
|
||||
subMonitor.done();
|
||||
return false;
|
||||
|
@ -256,7 +257,7 @@ public abstract class CRefactoring extends Refactoring {
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
status.addFatalError(Messages.NO_FILE);
|
||||
status.addFatalError(NLS.bind(Messages.CRefactoring_FileNotFound, tu.getPath().toString()));
|
||||
subMonitor.done();
|
||||
return false;
|
||||
}
|
||||
|
@ -264,15 +265,6 @@ public abstract class CRefactoring extends Refactoring {
|
|||
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() {
|
||||
ProblemFinder pf = new ProblemFinder(initStatus);
|
||||
ast.accept(pf);
|
||||
|
@ -305,6 +297,13 @@ public abstract class CRefactoring extends Refactoring {
|
|||
return fIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation unit where the refactoring started.
|
||||
*/
|
||||
public ITranslationUnit getTranslationUnit() {
|
||||
return tu;
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getUnit() {
|
||||
return ast;
|
||||
}
|
||||
|
|
|
@ -239,6 +239,13 @@ public abstract class CRefactoring2 extends Refactoring {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation unit where the refactoring started.
|
||||
*/
|
||||
public ITranslationUnit getTranslationUnit() {
|
||||
return tu;
|
||||
}
|
||||
|
||||
protected IASTTranslationUnit getAST(ITranslationUnit tu, IProgressMonitor pm)
|
||||
throws CoreException, OperationCanceledException {
|
||||
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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* 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_Ambiguity;
|
||||
public static String Refactoring_ParsingError;
|
||||
public static String NO_FILE;
|
||||
public static String RefactoringSaveHelper_unexpected_exception;
|
||||
public static String RefactoringSaveHelper_saving;
|
||||
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_dialog_message;
|
||||
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;
|
||||
|
||||
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
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# 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.
|
||||
AddDeclarationNodeToClassChange_AddDeclaration=Add Declaration to Class {0}.
|
||||
CreateFileChange_CreateFile=Create file: {0}
|
||||
CreateFileChange_UnknownLoc=Unknown Location: {0}
|
||||
CreateFileChange_UnknownLoc=Unknown location: {0}
|
||||
CreateFileChange_FileExists=File already exists: {0}
|
||||
CRefactoring_FileNotFound=The file {0} is not on the build path of a C/C++ project.
|
||||
CRefactoring_checking_final_conditions=Checking preconditions...
|
||||
|
@ -30,7 +30,6 @@ Refactoring_SelectionNotValid=Selection is not valid.
|
|||
Refactoring_CantLoadTU=Can not load translation unit.
|
||||
Refactoring_Ambiguity=Translation unit is ambiguous.
|
||||
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_saving=Saving Resources
|
||||
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_message=An unexpected exception occurred while undoing 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}
|
||||
|
|
|
@ -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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* 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.Set;
|
||||
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.ILog;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
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.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.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||
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.IASTNodeLocation;
|
||||
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.IASTTranslationUnit;
|
||||
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.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.ICPPNodeFactory;
|
||||
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.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.rewrite.astwriter.ASTWriter;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||
|
||||
public class NodeContainer {
|
||||
public final NameInformation NULL_NAME_INFORMATION = new NameInformation(new CPPASTName());
|
||||
|
||||
private final List<IASTNode> nodes;
|
||||
private List<NameInformation> names;
|
||||
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() {
|
||||
super();
|
||||
nodes = new ArrayList<IASTNode>();
|
||||
|
@ -297,6 +73,12 @@ public class NodeContainer {
|
|||
return;
|
||||
}
|
||||
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) {
|
||||
node.accept(new ASTVisitor() {
|
||||
{
|
||||
|
@ -305,18 +87,19 @@ public class NodeContainer {
|
|||
|
||||
@Override
|
||||
public int visit(IASTName name) {
|
||||
IBinding bind = name.resolveBinding();
|
||||
IBinding binding = name.resolveBinding();
|
||||
|
||||
if (bind instanceof ICPPBinding && !(bind instanceof ICPPTemplateTypeParameter)) {
|
||||
ICPPBinding cppBind = (ICPPBinding) bind;
|
||||
if (binding instanceof ICPPBinding && !(binding instanceof ICPPTemplateTypeParameter)) {
|
||||
ICPPBinding cppBinding = (ICPPBinding) binding;
|
||||
try {
|
||||
if (!cppBind.isGloballyQualified()) {
|
||||
NameInformation nameInformation = new NameInformation(name);
|
||||
IASTName[] refs = name.getTranslationUnit().getReferences(bind);
|
||||
if (!cppBinding.isGloballyQualified()) {
|
||||
NameInformation nameInfo = new NameInformation(name);
|
||||
nameInfo.setPassOutputByPointer(passOutputByPointer);
|
||||
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||
for (IASTName ref : refs) {
|
||||
nameInformation.addReference(ref);
|
||||
nameInfo.addReference(ref);
|
||||
}
|
||||
names.add(nameInformation);
|
||||
names.add(nameInfo);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
ILog logger = CUIPlugin.getDefault().getLog();
|
||||
|
@ -324,10 +107,10 @@ public class NodeContainer {
|
|||
CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
|
||||
logger.log(status);
|
||||
}
|
||||
} else if (bind instanceof IVariable) {
|
||||
} else if (binding instanceof IVariable) {
|
||||
NameInformation nameInformation = new NameInformation(name);
|
||||
|
||||
IASTName[] refs = name.getTranslationUnit().getReferences(bind);
|
||||
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||
for (IASTName ref : refs) {
|
||||
nameInformation.addReference(ref);
|
||||
}
|
||||
|
@ -344,11 +127,21 @@ public class NodeContainer {
|
|||
IASTTranslationUnit unit = name.getTranslationUnit();
|
||||
IASTName[] nameDeclarations = unit.getDeclarationsInAST(name.resolveBinding());
|
||||
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.
|
||||
*/
|
||||
|
@ -359,25 +152,30 @@ public class NodeContainer {
|
|||
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||
interfaceNames = new ArrayList<NameInformation>();
|
||||
|
||||
int endOffset = getEndOffset();
|
||||
for (NameInformation nameInfo : names) {
|
||||
if (declarations.add(nameInfo.getDeclaration())) {
|
||||
if (nameInfo.isDeclaredInSelection()) {
|
||||
if (nameInfo.isReferencedAfterSelection()) {
|
||||
IASTName declarationName = nameInfo.getDeclarationName();
|
||||
if (declarations.add(declarationName)) {
|
||||
if (isDeclaredInSelection(nameInfo)) {
|
||||
if (nameInfo.isReferencedAfterSelection(endOffset)) {
|
||||
nameInfo.setMustBeReturnValue(true);
|
||||
interfaceNames.add(nameInfo);
|
||||
}
|
||||
} else {
|
||||
for (NameInformation n2 : names) {
|
||||
if (n2.getDeclaration() == nameInfo.getDeclaration()) {
|
||||
int flag = CPPVariableReadWriteFlags.getReadWriteFlags(n2.getName());
|
||||
if ((flag & PDOMName.WRITE_ACCESS) != 0) {
|
||||
nameInfo.setWriteAccess(true);
|
||||
break;
|
||||
IASTDeclarator declarator = (IASTDeclarator) declarationName.getParent();
|
||||
if (!hasReferenceOperator(declarator)) {
|
||||
for (NameInformation n2 : names) {
|
||||
if (n2.getDeclarationName() == declarationName) {
|
||||
int flag = CPPVariableReadWriteFlags.getReadWriteFlags(n2.getName());
|
||||
if ((flag & PDOMName.WRITE_ACCESS) != 0) {
|
||||
nameInfo.setWriteAccess(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection()) {
|
||||
nameInfo.setMustBeOutput(true);
|
||||
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection(endOffset)) {
|
||||
nameInfo.setOutput(true);
|
||||
}
|
||||
}
|
||||
interfaceNames.add(nameInfo);
|
||||
}
|
||||
|
@ -388,6 +186,20 @@ public class NodeContainer {
|
|||
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) {
|
||||
List<NameInformation> selectedNames = null;
|
||||
|
||||
|
@ -412,7 +224,6 @@ public class NodeContainer {
|
|||
return getInterfaceNames(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns names that are candidates for being used as the function return value. Multiple
|
||||
* 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.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.
|
||||
|
|
|
@ -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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -8,24 +8,30 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
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 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.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;
|
||||
|
||||
public class ExtractFunctionInformation {
|
||||
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
||||
private String methodName;
|
||||
private boolean replaceDuplicates;
|
||||
private List<NameInformation> parameterCandidates;
|
||||
private List<NameInformation> parameters;
|
||||
private NameInformation mandatoryReturnVariable;
|
||||
private NameInformation returnVariable;
|
||||
private ICPPASTFunctionDeclarator declarator;
|
||||
private MethodContext context;
|
||||
private boolean isExtractExpression;
|
||||
|
@ -61,14 +67,13 @@ public class ExtractFunctionInformation {
|
|||
}
|
||||
|
||||
public NameInformation getReturnVariable() {
|
||||
return returnVariable;
|
||||
}
|
||||
|
||||
public void setReturnVariable(NameInformation variable) {
|
||||
if (variable != null) {
|
||||
variable.setReturnValue(true);
|
||||
if (mandatoryReturnVariable != null)
|
||||
return mandatoryReturnVariable;
|
||||
for (NameInformation param : parameters) {
|
||||
if (param.isReturnValue())
|
||||
return param;
|
||||
}
|
||||
this.returnVariable = variable;
|
||||
return null;
|
||||
}
|
||||
|
||||
public NameInformation getMandatoryReturnVariable() {
|
||||
|
@ -76,19 +81,15 @@ public class ExtractFunctionInformation {
|
|||
}
|
||||
|
||||
public void setMandatoryReturnVariable(NameInformation variable) {
|
||||
if (variable != null) {
|
||||
variable.setMustBeReturnValue(true);
|
||||
}
|
||||
this.mandatoryReturnVariable = variable;
|
||||
this.returnVariable = variable;
|
||||
}
|
||||
|
||||
public List<NameInformation> getParameterCandidates() {
|
||||
return parameterCandidates;
|
||||
public List<NameInformation> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameterCandidates(List<NameInformation> names) {
|
||||
this.parameterCandidates = names;
|
||||
public void setParameters(List<NameInformation> parameters) {
|
||||
this.parameters = new ArrayList<NameInformation>(parameters);
|
||||
}
|
||||
|
||||
public VisibilityEnum getVisibility() {
|
||||
|
@ -122,4 +123,29 @@ public class ExtractFunctionInformation {
|
|||
public void setVirtual(boolean 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
|
||||
* 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
|
||||
* IBM Corporation
|
||||
* 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
|
||||
* Benjamin Muskalla <bmuskalla@eclipsesource.com>
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
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.osgi.util.NLS;
|
||||
import org.eclipse.swt.SWT;
|
||||
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.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.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.internal.ui.refactoring.utils.IdentifierResult;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
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.util.RowLayouter;
|
||||
|
||||
public class ExtractFunctionInputPage extends UserInputWizardPage {
|
||||
private final ExtractFunctionInformation info;
|
||||
private ExtractFunctionComposite comp;
|
||||
protected final String NO_NAME_ERROR_LABEL = Messages.ExtractFunctionInputPage_EnterName;
|
||||
public static final String PAGE_NAME = "ExtractFunctionInputPage";//$NON-NLS-1$
|
||||
static final String DIALOG_SETTING_SECTION = "ExtractFunctionWizard"; //$NON-NLS-1$
|
||||
|
||||
public ExtractFunctionInputPage(String name, ExtractFunctionInformation info) {
|
||||
super(name);
|
||||
this.info = info;
|
||||
private ExtractFunctionRefactoring refactoring;
|
||||
private ExtractFunctionInformation 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
|
||||
public void createControl(final Composite parent) {
|
||||
comp = new ExtractFunctionComposite(parent, info, this);
|
||||
|
||||
setPageComplete(false);
|
||||
|
||||
comp.getMethodNameText().addModifyListener(new ModifyListener() {
|
||||
@Override
|
||||
public void modifyText(ModifyEvent e) {
|
||||
info.setMethodName(comp.getMethodName());
|
||||
checkName();
|
||||
}
|
||||
});
|
||||
|
||||
for (Control buttons : comp.getVisibiltyGroup().getChildren()) {
|
||||
buttons.addMouseListener(new MouseAdapter() {
|
||||
public void createControl(Composite parent) {
|
||||
refactoring = (ExtractFunctionRefactoring) getRefactoring();
|
||||
info = ((ExtractFunctionRefactoring) getRefactoring()).getRefactoringInfo();
|
||||
loadSettings();
|
||||
|
||||
Composite result = new Composite(parent, SWT.NONE);
|
||||
setControl(result);
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.numColumns = 2;
|
||||
result.setLayout(layout);
|
||||
RowLayouter layouter = new RowLayouter(2);
|
||||
GridData gd = null;
|
||||
|
||||
initializeDialogUnits(result);
|
||||
|
||||
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
|
||||
public void mouseUp(MouseEvent e) {
|
||||
String text = ((Button)e.getSource()).getText();
|
||||
visibilityChange(text);
|
||||
}
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
final VisibilityEnum selectedModifier = (VisibilityEnum) event.widget.getData();
|
||||
settings.put(ACCESS_MODIFIER, selectedModifier.toString());
|
||||
setVisibility(selectedModifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
comp.getReplaceSimilarButton().addSelectionListener(new SelectionListener() {
|
||||
@Override
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
info.setReplaceDuplicates(comp.getReplaceSimilarButton().isEnabled());
|
||||
}
|
||||
layouter.perform(label, group, 1);
|
||||
|
||||
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
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
widgetDefaultSelected(e);
|
||||
info.setReplaceDuplicates(((Button) e.widget).getSelection());
|
||||
}
|
||||
});
|
||||
|
||||
setControl(comp);
|
||||
layouter.perform(checkBox);
|
||||
|
||||
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) {
|
||||
info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(text));
|
||||
private Text createTextInputField(Composite parent, int style) {
|
||||
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() {
|
||||
String methodName = comp.getMethodName();
|
||||
IdentifierResult result = IdentifierHelper.checkIdentifierName(methodName);
|
||||
if (result.isCorrect()) {
|
||||
setErrorMessage(null);
|
||||
setPageComplete(true);
|
||||
} else {
|
||||
setErrorMessage(Messages.ExtractFunctionInputPage_CheckFunctionName + " " + result.getMessage()); //$NON-NLS-1$
|
||||
setPageComplete(false);
|
||||
private String getText() {
|
||||
if (textField == null)
|
||||
return null;
|
||||
return textField.getText();
|
||||
}
|
||||
|
||||
private String getLabelText(){
|
||||
return Messages.ExtractFunctionInputPage_label_text;
|
||||
}
|
||||
|
||||
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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -8,15 +8,17 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
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.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.SubMonitor;
|
||||
import org.eclipse.core.runtime.preferences.IPreferencesService;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
|
||||
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
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.IASTStandardFunctionDeclarator;
|
||||
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.IField;
|
||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||
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.ICPPASTConversionName;
|
||||
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.ICPPMethod;
|
||||
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.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.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.CPPASTTemplateDeclaration;
|
||||
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.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.ContextType;
|
||||
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.NameInformation;
|
||||
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.Checks;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
|
||||
import org.eclipse.cdt.internal.ui.viewsupport.BasicElementLabels;
|
||||
|
||||
public class ExtractFunctionRefactoring extends CRefactoring {
|
||||
public static final String ID =
|
||||
|
@ -113,7 +128,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
static final Integer NULL_INTEGER = Integer.valueOf(0);
|
||||
static final char[] ZERO= "0".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
NodeContainer container;
|
||||
private NodeContainer container;
|
||||
final ExtractFunctionInformation info;
|
||||
|
||||
final Map<String, Integer> names;
|
||||
|
@ -121,12 +136,11 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
final Container<Integer> trailPos;
|
||||
private final Container<Integer> returnNumber;
|
||||
|
||||
protected boolean hasNameResolvingForSimilarError;
|
||||
|
||||
HashMap<String, Integer> nameTrail;
|
||||
|
||||
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
||||
private final INodeFactory factory = CPPNodeFactory.getDefault();
|
||||
private final INodeFactory nodeFactory = CPPNodeFactory.getDefault();
|
||||
DefaultCodeFormatterOptions formattingOptions;
|
||||
|
||||
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
||||
ExtractFunctionInformation info, ICProject project) {
|
||||
|
@ -137,6 +151,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
namesCounter = new Container<Integer>(NULL_INTEGER);
|
||||
trailPos = new Container<Integer>(NULL_INTEGER);
|
||||
returnNumber = new Container<Integer>(NULL_INTEGER);
|
||||
formattingOptions = new DefaultCodeFormatterOptions(project.getOptions(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -170,19 +185,33 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
if (isProgressMonitorCanceld(sm, 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);
|
||||
|
||||
if (isProgressMonitorCanceld(sm, initStatus))
|
||||
return initStatus;
|
||||
|
||||
List<NameInformation> returnValueCandidates = container.getReturnValueCandidates();
|
||||
if (returnValueCandidates.size() > 1) {
|
||||
initStatus.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
|
||||
} else if (returnValueCandidates.size() == 1) {
|
||||
info.setMandatoryReturnVariable(returnValueCandidates.get(0));
|
||||
info.setParameters(container.getParameterCandidates());
|
||||
initStatus.merge(checkParameterAndReturnTypes());
|
||||
if (initStatus.hasFatalError())
|
||||
return initStatus;
|
||||
|
||||
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.createFor(container.getNodesToWrite());
|
||||
|
||||
|
@ -204,6 +233,28 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
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) {
|
||||
NonExtractableStmtFinder finder = new NonExtractableStmtFinder();
|
||||
for (IASTNode node : cont.getNodesToWrite()) {
|
||||
|
@ -259,15 +310,10 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
|
||||
|
||||
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration, getIndex())) {
|
||||
finalConditions.addError(Messages.ExtractFunctionRefactoring_NameInUse);
|
||||
finalConditions.addError(Messages.ExtractFunctionRefactoring_name_in_use);
|
||||
return finalConditions;
|
||||
}
|
||||
}
|
||||
for (NameInformation name : info.getParameterCandidates()) {
|
||||
if (name.isReturnValue()) {
|
||||
info.setReturnVariable(name);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
unlockIndex();
|
||||
}
|
||||
|
@ -278,9 +324,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void collectModifications(IProgressMonitor pm,
|
||||
ModificationCollector collector) throws CoreException,
|
||||
OperationCanceledException {
|
||||
protected void collectModifications(IProgressMonitor pm, ModificationCollector collector)
|
||||
throws CoreException, OperationCanceledException {
|
||||
try {
|
||||
lockIndex();
|
||||
try {
|
||||
|
@ -298,10 +343,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
final IFile implementationFile =
|
||||
ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(implPath);
|
||||
|
||||
createMethodDefinition(astMethodName, context, firstNode, implementationFile,
|
||||
collector);
|
||||
createMethodDefinition(astMethodName, context, firstNode, collector);
|
||||
|
||||
createMethodCalls(astMethodName, implementationFile, context, collector);
|
||||
createMethodCalls(astMethodName, context, collector);
|
||||
} finally {
|
||||
unlockIndex();
|
||||
}
|
||||
|
@ -310,8 +354,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
}
|
||||
}
|
||||
|
||||
private void createMethodCalls(final IASTName astMethodName,
|
||||
final IFile implementationFile, MethodContext context,
|
||||
private void createMethodCalls(final IASTName astMethodName, MethodContext context,
|
||||
ModificationCollector collector) throws CoreException {
|
||||
String title;
|
||||
if (context.getType() == MethodContext.ContextType.METHOD) {
|
||||
|
@ -326,15 +369,15 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
ASTRewrite rewriter = collector.rewriterForTranslationUnit(
|
||||
firstNodeToWrite.getTranslationUnit());
|
||||
TextEditGroup editGroup = new TextEditGroup(title);
|
||||
if (methodCall instanceof IASTDeclaration){
|
||||
if (methodCall instanceof IASTDeclaration) {
|
||||
CPPASTDeclarationStatement declarationStatement =
|
||||
new CPPASTDeclarationStatement((IASTDeclaration) methodCall);
|
||||
methodCall = declarationStatement;
|
||||
}
|
||||
insertCallintoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
||||
insertCallIntoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
||||
|
||||
if (info.isReplaceDuplicates()) {
|
||||
replaceSimilar(collector, astMethodName, implementationFile, context.getType());
|
||||
replaceSimilar(collector, astMethodName);
|
||||
}
|
||||
|
||||
for (IASTNode node : container.getNodesToWrite()) {
|
||||
|
@ -344,8 +387,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
}
|
||||
}
|
||||
|
||||
private void insertCallintoTree(IASTNode methodCall, List<IASTNode> list,
|
||||
ASTRewrite rewriter, TextEditGroup editGroup) {
|
||||
private void insertCallIntoTree(IASTNode methodCall, List<IASTNode> list, ASTRewrite rewriter,
|
||||
TextEditGroup editGroup) {
|
||||
IASTNode firstNode = list.get(0);
|
||||
if (list.size() > 1 && firstNode.getParent() instanceof IASTBinaryExpression &&
|
||||
firstNode.getParent().getParent() instanceof IASTBinaryExpression) {
|
||||
|
@ -372,9 +415,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
return binExp;
|
||||
}
|
||||
|
||||
private void createMethodDefinition(final IASTName astMethodName,
|
||||
MethodContext context, IASTNode firstNode,
|
||||
final IFile implementationFile, ModificationCollector collector) {
|
||||
private void createMethodDefinition(final IASTName astMethodName, MethodContext context,
|
||||
IASTNode firstNode, ModificationCollector collector) {
|
||||
IASTFunctionDefinition node = NodeHelper.findFunctionDefinitionInAncestors(firstNode);
|
||||
if (node != null) {
|
||||
String title;
|
||||
|
@ -400,32 +442,39 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
methodDeclaration, false, collector);
|
||||
}
|
||||
|
||||
private void replaceSimilar(ModificationCollector collector, final IASTName astMethodName,
|
||||
final IFile implementationFile, final ContextType contextType) {
|
||||
private void replaceSimilar(ModificationCollector collector, IASTName astMethodName) {
|
||||
// Find similar code
|
||||
final List<IASTNode> nodesToRewriteWithoutComments = new LinkedList<IASTNode>();
|
||||
|
||||
for (IASTNode node : container.getNodesToWrite()) {
|
||||
if (!(node instanceof IASTComment)) {
|
||||
nodesToRewriteWithoutComments.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
final List<IASTNode> nodesToRewriteWithoutComments = getNodesWithoutComments(container.getNodesToWrite());
|
||||
final List<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
||||
final String title;
|
||||
if (contextType == MethodContext.ContextType.METHOD) {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateMethodCall;
|
||||
} else {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
}
|
||||
|
||||
if (!hasNameResolvingForSimilarError) {
|
||||
ast.accept(new SimilarFinderVisitor(this, collector, initTrail, implementationFile,
|
||||
astMethodName, nodesToRewriteWithoutComments, title));
|
||||
}
|
||||
ast.accept(new SimilarReplacerVisitor(this, container, collector, initTrail, astMethodName,
|
||||
nodesToRewriteWithoutComments));
|
||||
}
|
||||
|
||||
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>();
|
||||
nameTrail = new HashMap<String, Integer>();
|
||||
final Container<Integer> trailCounter = new Container<Integer>(NULL_INTEGER);
|
||||
|
@ -590,7 +639,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
||||
extractedFunctionConstructionHelper.createFunctionDeclarator(qname,
|
||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
||||
info.getParameters(), ast.getASTNodeFactory());
|
||||
func.setDeclarator(createdFunctionDeclarator);
|
||||
|
||||
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
||||
|
@ -619,18 +668,13 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
NameInformation returnVariable = info.getReturnVariable();
|
||||
if (returnVariable != null) {
|
||||
IASTReturnStatement returnStmt = new CPPASTReturnStatement();
|
||||
if (returnVariable.getDeclaration().getParent() instanceof IASTExpression) {
|
||||
IASTExpression returnValue = (IASTExpression) returnVariable.getDeclaration().getParent();
|
||||
returnStmt.setReturnValue(returnValue);
|
||||
IASTIdExpression expr = new CPPASTIdExpression();
|
||||
if (returnVariable.getNewName() == null) {
|
||||
expr.setName(newName(returnVariable.getName()));
|
||||
} else {
|
||||
IASTIdExpression expr = new CPPASTIdExpression();
|
||||
if (returnVariable.getUserSetName() == null) {
|
||||
expr.setName(newName(returnVariable.getName()));
|
||||
} else {
|
||||
expr.setName(new CPPASTName(returnVariable.getUserSetName().toCharArray()));
|
||||
}
|
||||
returnStmt.setReturnValue(expr);
|
||||
expr.setName(new CPPASTName(returnVariable.getNewName().toCharArray()));
|
||||
}
|
||||
returnStmt.setReturnValue(expr);
|
||||
subRW.insertBefore(compound, null, returnStmt, group);
|
||||
}
|
||||
}
|
||||
|
@ -646,8 +690,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
returnVariable);
|
||||
}
|
||||
|
||||
protected IASTNode getMethodCall(IASTName astMethodName,
|
||||
Map<String, Integer> trailNameTable,
|
||||
protected IASTNode getMethodCall(IASTName astMethodName, Map<String, Integer> trailNameTable,
|
||||
Map<String, Integer> similarNameTable, NodeContainer myContainer,
|
||||
NodeContainer mySimilarContainer) {
|
||||
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
||||
|
@ -656,12 +699,12 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
idExpression.setName(astMethodName);
|
||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||
|
||||
List<IASTName> declarations = new ArrayList<IASTName>();
|
||||
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||
IASTName retName = null;
|
||||
boolean theRetName = false;
|
||||
|
||||
for (NameInformation nameInfo : myContainer.getNames()) {
|
||||
Integer trailSeqNumber = trailNameTable.get(nameInfo.getDeclaration().getRawSignature());
|
||||
for (NameInformation nameInfo : info.getParameters()) {
|
||||
Integer trailSeqNumber = trailNameTable.get(nameInfo.getDeclarationName().getRawSignature());
|
||||
String origName = null;
|
||||
for (Entry<String, Integer> entry : similarNameTable.entrySet()) {
|
||||
if (entry.getValue().equals(trailSeqNumber)) {
|
||||
|
@ -676,14 +719,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
if (origName != null) {
|
||||
boolean found = false;
|
||||
for (NameInformation simNameInfo : mySimilarContainer.getNames()) {
|
||||
if (origName.equals(simNameInfo.getDeclaration().getRawSignature())) {
|
||||
if (origName.equals(simNameInfo.getDeclarationName().getRawSignature())) {
|
||||
addParameterIfPossible(args, declarations, simNameInfo);
|
||||
found = true;
|
||||
|
||||
if (theRetName) {
|
||||
theRetName = false;
|
||||
retName = new CPPASTName(
|
||||
simNameInfo.getDeclaration().getRawSignature().toCharArray());
|
||||
simNameInfo.getDeclarationName().getRawSignature().toCharArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -733,7 +776,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
IASTFunctionCallExpression callExpression, IASTName retname) {
|
||||
if (info.getReturnVariable().equals(info.getMandatoryReturnVariable())) {
|
||||
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
|
||||
.getReturnVariable().getDeclaration());
|
||||
.getReturnVariable().getDeclarationName());
|
||||
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
||||
|
||||
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
|
||||
|
@ -775,14 +818,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
IASTStandardFunctionDeclarator declarator =
|
||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
||||
info.getParameters(), ast.getASTNodeFactory());
|
||||
simpleDecl.addDeclarator(declarator);
|
||||
return simpleDecl;
|
||||
}
|
||||
|
||||
private IASTSimpleDeclaration getDeclaration(ModificationCollector collector, IASTName name) {
|
||||
IASTDeclSpecifier declSpec = getReturnType();
|
||||
IASTSimpleDeclaration simpleDecl = factory.newSimpleDeclaration(declSpec);
|
||||
IASTSimpleDeclaration simpleDecl = nodeFactory.newSimpleDeclaration(declSpec);
|
||||
if (info.isVirtual() && declSpec instanceof ICPPASTDeclSpecifier) {
|
||||
((ICPPASTDeclSpecifier) declSpec).setVirtual(true);
|
||||
}
|
||||
|
@ -790,7 +833,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
IASTStandardFunctionDeclarator declarator =
|
||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||
info.getParameterCandidates(), ast.getASTNodeFactory());
|
||||
info.getParameters(), ast.getASTNodeFactory());
|
||||
simpleDecl.addDeclarator(declarator);
|
||||
return simpleDecl;
|
||||
}
|
||||
|
@ -826,19 +869,18 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
|
||||
public List<IASTInitializerClause> getCallParameters() {
|
||||
List<IASTInitializerClause> args = new ArrayList<IASTInitializerClause>();
|
||||
List<IASTName> declarations = new ArrayList<IASTName>();
|
||||
for (NameInformation nameInfo : container.getNames()) {
|
||||
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||
for (NameInformation nameInfo : info.getParameters()) {
|
||||
addParameterIfPossible(args, declarations, nameInfo);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
private void addParameterIfPossible(List<IASTInitializerClause> args,
|
||||
List<IASTName> declarations, NameInformation nameInfo) {
|
||||
if (!nameInfo.isDeclaredInSelection()) {
|
||||
IASTName declaration = nameInfo.getDeclaration();
|
||||
if (!declarations.contains(declaration)) {
|
||||
declarations.add(declaration);
|
||||
private void addParameterIfPossible(List<IASTInitializerClause> args, Set<IASTName> declarations,
|
||||
NameInformation nameInfo) {
|
||||
if (!container.isDeclaredInSelection(nameInfo)) {
|
||||
IASTName declaration = nameInfo.getDeclarationName();
|
||||
if (declarations.add(declaration)) {
|
||||
IASTIdExpression expression = new CPPASTIdExpression();
|
||||
expression.setName(newName(declaration));
|
||||
args.add(expression);
|
||||
|
@ -866,4 +908,119 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
Boolean.toString(info.isReplaceDuplicates()));
|
||||
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:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
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.internal.ui.refactoring.CRefactoring;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner;
|
||||
|
||||
/**
|
||||
|
@ -35,8 +35,8 @@ public class ExtractFunctionRefactoringRunner extends RefactoringRunner {
|
|||
public void run() {
|
||||
ExtractFunctionInformation info = new ExtractFunctionInformation();
|
||||
|
||||
CRefactoring refactoring = new ExtractFunctionRefactoring(file,selection,info, project);
|
||||
ExtractFunctionRefactoringWizard wizard = new ExtractFunctionRefactoringWizard(refactoring,info);
|
||||
ExtractFunctionRefactoring refactoring = new ExtractFunctionRefactoring(file, selection, info, project);
|
||||
ExtractFunctionWizard wizard = new ExtractFunctionWizard(refactoring);
|
||||
RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard);
|
||||
|
||||
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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -8,27 +8,24 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
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.UserInputWizardPage;
|
||||
|
||||
public class ExtractFunctionRefactoringWizard extends RefactoringWizard {
|
||||
private final ExtractFunctionInformation info;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
public ExtractFunctionRefactoringWizard(Refactoring refactoring, ExtractFunctionInformation info) {
|
||||
super(refactoring, WIZARD_BASED_USER_INTERFACE);
|
||||
this.info = info;
|
||||
public class ExtractFunctionWizard extends RefactoringWizard {
|
||||
public ExtractFunctionWizard(ExtractFunctionRefactoring refactoring) {
|
||||
super(refactoring, DIALOG_BASED_USER_INTERFACE | PREVIEW_EXPAND_FIRST_NODE);
|
||||
setDefaultPageTitle(Messages.ExtractFunctionWizard_extract_function);
|
||||
setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addUserInputPages() {
|
||||
UserInputWizardPage page = new ExtractFunctionInputPage(
|
||||
Messages.ExtractFunctionRefactoringWizard_FunctionName,info);
|
||||
page.setTitle(Messages.ExtractFunctionRefactoringWizard_FunctionName);
|
||||
addPage(page);
|
||||
addPage(new ExtractFunctionInputPage());
|
||||
}
|
||||
}
|
||||
|
|
@ -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.ui.refactoring.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ public class ExtractStatement extends ExtractedFunctionConstructionHelper {
|
|||
public IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
||||
NameInformation returnVariable) {
|
||||
if (returnVariable != null) {
|
||||
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclaration());
|
||||
IASTNode decl = ASTHelper.getDeclarationForNode(returnVariable.getDeclarationName());
|
||||
return ASTHelper.getDeclarationSpecifier(decl).copy(CopyStyle.withLocations);
|
||||
}
|
||||
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.rewrite.ASTRewrite;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||
|
||||
/**
|
||||
* @author Mirko Stocker
|
||||
|
@ -73,7 +73,7 @@ public abstract class ExtractedFunctionConstructionHelper {
|
|||
}
|
||||
|
||||
if (returnVariable != null) {
|
||||
IASTDeclarator decl = (IASTDeclarator) returnVariable.getDeclaration().getParent();
|
||||
IASTDeclarator decl = returnVariable.getDeclarator();
|
||||
IASTPointerOperator[] pointers = decl.getPointerOperators();
|
||||
for (IASTPointerOperator operator : pointers) {
|
||||
declarator.addPointerOperator(operator.copy(CopyStyle.withLocations));
|
||||
|
@ -94,8 +94,8 @@ public abstract class ExtractedFunctionConstructionHelper {
|
|||
public List<IASTParameterDeclaration> getParameterDeclarations(
|
||||
Collection<NameInformation> parameterNames, INodeFactory nodeFactory) {
|
||||
List<IASTParameterDeclaration> result = new ArrayList<IASTParameterDeclaration>(parameterNames.size());
|
||||
for (NameInformation name : parameterNames) {
|
||||
result.add(name.getParameterDeclaration(nodeFactory));
|
||||
for (NameInformation param : parameterNames) {
|
||||
result.add(param.getParameterDeclaration(nodeFactory));
|
||||
}
|
||||
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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -8,35 +8,40 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||
|
||||
import org.eclipse.osgi.util.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_NoStmtSelected;
|
||||
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_FunctionName;
|
||||
public static String ExtractFunctionInputPage_EnterName;
|
||||
public static String ExtractFunctionInputPage_CheckFunctionName;
|
||||
public static String ExtractFunctionInputPage_1;
|
||||
public static String ExtractFunctionComposite_ReturnValue;
|
||||
public static String ExtractFunctionInputPage_description;
|
||||
public static String ExtractFunctionInputPage_access_modifier;
|
||||
public static String ExtractFunctionInputPage_public;
|
||||
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_CreateFunctionDef;
|
||||
public static String ExtractFunctionComposite_ReplaceDuplicates;
|
||||
public static String ExtractFunctionComposite_Virtual;
|
||||
public static String ExtractFunctionRefactoring_CreateMethodCall;
|
||||
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_Continue;
|
||||
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
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# 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
|
||||
#
|
||||
# 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_NoStmtSelected=No statement selected
|
||||
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_FunctionName=Function &name:
|
||||
ExtractFunctionInputPage_EnterName=Enter a name
|
||||
ExtractFunctionInputPage_CheckFunctionName=Check Function Name:
|
||||
ExtractFunctionInputPage_1=is used after the extracted block - it needs to be passed by reference or must be the return value.
|
||||
ExtractFunctionComposite_ReturnValue=Return value:
|
||||
ExtractFunctionInputPage_description=Enter new method name and specify the method's visibility
|
||||
ExtractFunctionInputPage_access_modifier=&Access modifier:
|
||||
ExtractFunctionInputPage_public=public
|
||||
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_CreateFunctionDef=Create Function Definition
|
||||
ExtractFunctionComposite_ReplaceDuplicates=Replace all occurrences of statements with method.
|
||||
ExtractFunctionComposite_Virtual=virtual
|
||||
ExtractFunctionRefactoring_CreateMethodCall=Create Method 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_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.
|
||||
|
|
|
@ -16,39 +16,28 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
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.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
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.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 IASTName name;
|
||||
private final List<IASTNode> statements;
|
||||
private int statementCount;
|
||||
private NodeContainer similarContainer;
|
||||
private final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
||||
|
||||
private final ModificationCollector collector;
|
||||
|
||||
SimilarFinderVisitor(ExtractFunctionRefactoring refactoring, ModificationCollector collector,
|
||||
List<IASTNode> trail, IFile file, IASTName name, List<IASTNode> statements,
|
||||
String title) {
|
||||
SimilarFinderVisitor(ExtractFunctionRefactoring refactoring, NodeContainer extractedNodes,
|
||||
List<IASTNode> trail, List<IASTNode> statements) {
|
||||
this.refactoring = refactoring;
|
||||
this.extractedNodes = extractedNodes;
|
||||
this.trail = trail;
|
||||
this.name = name;
|
||||
this.statements = statements;
|
||||
this.collector = collector;
|
||||
this.similarContainer = new NodeContainer();
|
||||
shouldVisitStatements = true;
|
||||
}
|
||||
|
@ -65,8 +54,8 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
|||
// Found similar code
|
||||
boolean similarOnReturnWays = true;
|
||||
for (NameInformation nameInfo : similarContainer.getParameterCandidates()) {
|
||||
if (refactoring.names.containsKey(nameInfo.getDeclaration().getRawSignature())) {
|
||||
Integer nameOrderNumber = refactoring.names.get(nameInfo.getDeclaration().getRawSignature());
|
||||
if (refactoring.names.containsKey(nameInfo.getDeclarationName().getRawSignature())) {
|
||||
Integer nameOrderNumber = refactoring.names.get(nameInfo.getDeclarationName().getRawSignature());
|
||||
if (refactoring.nameTrail.containsValue(nameOrderNumber)) {
|
||||
String orgName = null;
|
||||
boolean found = false;
|
||||
|
@ -77,9 +66,9 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
|||
}
|
||||
}
|
||||
if (orgName != null) {
|
||||
for (NameInformation orgNameInfo : refactoring.container.getParameterCandidates()) {
|
||||
if (orgName.equals(orgNameInfo.getDeclaration().getRawSignature()) &&
|
||||
(orgNameInfo.mustBeOutput() || !nameInfo.mustBeOutput())) {
|
||||
for (NameInformation orgNameInfo : extractedNodes.getParameterCandidates()) {
|
||||
if (orgName.equals(orgNameInfo.getDeclarationName().getRawSignature()) &&
|
||||
(orgNameInfo.isOutput() || !nameInfo.isOutput())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -94,17 +83,7 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
|||
}
|
||||
|
||||
if (similarOnReturnWays) {
|
||||
IASTNode call = refactoring.getMethodCall(name, refactoring.nameTrail,
|
||||
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);
|
||||
}
|
||||
}
|
||||
foundSimilar();
|
||||
}
|
||||
clear();
|
||||
}
|
||||
|
@ -115,8 +94,10 @@ final class SimilarFinderVisitor extends ASTVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract void foundSimilar();
|
||||
|
||||
private boolean isInSelection(IASTStatement stmt) {
|
||||
List<IASTNode>nodes = refactoring.container.getNodesToWrite();
|
||||
List<IASTNode>nodes = extractedNodes.getNodesToWrite();
|
||||
for (IASTNode node : nodes) {
|
||||
if (node.equals(stmt)) {
|
||||
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.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.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.NameComposer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.corext.codemanipulation.StubUtility;
|
||||
|
||||
public class GetterSetterNameGenerator {
|
||||
private static Set<String> generateGetterSettersPreferenceKeys = new HashSet<String>();
|
||||
|
@ -64,29 +60,16 @@ public class GetterSetterNameGenerator {
|
|||
* generated.
|
||||
*/
|
||||
public static String generateGetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
||||
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 = 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);
|
||||
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||
return StubUtility.suggestGetterName(StubUtility.trimFieldName(fieldName.toString()),
|
||||
isBooleanDeclaratorName(fieldName), namesToAvoid, tu);
|
||||
}
|
||||
|
||||
private static boolean isBooleanDeclaratorName(IASTName name) {
|
||||
if (IASTDeclarator.DECLARATOR_NAME.equals(name.getPropertyInParent())) {
|
||||
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
|
||||
IType type = CPPVisitor.createType(declarator);
|
||||
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
|
||||
if (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eBoolean) {
|
||||
return true;
|
||||
}
|
||||
|
@ -103,57 +86,16 @@ public class GetterSetterNameGenerator {
|
|||
* generated.
|
||||
*/
|
||||
public static String generateSetterName(IASTName fieldName, Set<String> namesToAvoid) {
|
||||
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);
|
||||
String name = NameComposer.trimFieldName(fieldName.toString());
|
||||
name = composer.compose(name);
|
||||
return adjustName(name, namesToAvoid);
|
||||
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||
return StubUtility.suggestSetterName(StubUtility.trimFieldName(fieldName.toString()), namesToAvoid, tu);
|
||||
}
|
||||
|
||||
public static String generateSetterParameterName(IASTName fieldName){
|
||||
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);
|
||||
String name = NameComposer.trimFieldName(fieldName.toString());
|
||||
name = composer.compose(name);
|
||||
if (!CConventions.validateIdentifier(name, GPPLanguage.getDefault()).isOK())
|
||||
name = '_' + name;
|
||||
return name;
|
||||
public static String generateSetterParameterName(IASTName fieldName) {
|
||||
ITranslationUnit tu = getTranslationUnit(fieldName);
|
||||
return StubUtility.suggestParameterName(StubUtility.trimFieldName(fieldName.toString()), null, tu);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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;
|
||||
private static ITranslationUnit getTranslationUnit(IASTNode node) {
|
||||
return node.getTranslationUnit().getOriginatingTranslationUnit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* 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.IPath;
|
||||
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.participants.CheckConditionsContext;
|
||||
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.ICElement;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
|
||||
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){
|
||||
return ResourcesPlugin.getWorkspace().getRoot().findMember(resourcePath) != null;
|
||||
}
|
||||
|
@ -86,7 +148,7 @@ public class Checks {
|
|||
if (attributes != null && attributes.isReadOnly())
|
||||
return true;
|
||||
|
||||
if (! (res instanceof IContainer))
|
||||
if (!(res instanceof IContainer))
|
||||
return false;
|
||||
|
||||
IContainer container= (IContainer)res;
|
||||
|
@ -116,7 +178,7 @@ public class Checks {
|
|||
if (!status.isOK()) {
|
||||
result.merge(RefactoringStatus.create(status));
|
||||
if (!result.hasFatalError()) {
|
||||
result.addFatalError(Messages.Checks_validateEdit);
|
||||
result.addFatalError(Messages.Checks_validate_edit);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -143,7 +205,7 @@ public class Checks {
|
|||
if (!status.isOK()) {
|
||||
result.merge(RefactoringStatus.create(status));
|
||||
if (!result.hasFatalError()) {
|
||||
result.addFatalError(Messages.Checks_validateEdit);
|
||||
result.addFatalError(Messages.Checks_validate_edit);
|
||||
}
|
||||
}
|
||||
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
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* 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_illegalCharacter;
|
||||
public static String IdentifierHelper_unidentifiedMistake;
|
||||
public static String VisibilityEnum_public;
|
||||
public static String VisibilityEnum_protected;
|
||||
public static String VisibilityEnum_private;
|
||||
public static String Checks_validateEdit;
|
||||
public static String Checks_validate_edit;
|
||||
public static String Checks_choose_name;
|
||||
|
||||
static {
|
||||
NLS.initializeMessages(Messages.class.getName(), Messages.class);
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Institute for Software - initial API and implementation
|
||||
# IBM Corporation
|
||||
# Institute for Software - initial API and implementation
|
||||
# IBM Corporation
|
||||
# Sergey Prigogin (Google)
|
||||
###############################################################################
|
||||
IdentifierHelper_isKeyword=''{0}'' is a keyword.
|
||||
IdentifierHelper_isValid=''{0}'' is valid.
|
||||
|
@ -16,7 +17,5 @@ IdentifierHelper_leadingDigit=''{0}'' has a leading digit.
|
|||
IdentifierHelper_emptyIdentifier=Identifier must not be empty.
|
||||
IdentifierHelper_illegalCharacter=Illegal character found in ''{0}''.
|
||||
IdentifierHelper_unidentifiedMistake=''{0}'' contains an unidentified mistake.
|
||||
VisibilityEnum_public=public
|
||||
VisibilityEnum_protected=protected
|
||||
VisibilityEnum_private=private
|
||||
Checks_validateEdit=Team provider refused file modification.
|
||||
Checks_validate_edit=Team provider refused file modification.
|
||||
Checks_choose_name=Choose a name.
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
*******************************************************************************/
|
||||
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.ICPPASTVisibilityLabel;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
// The values are ordered by increasing visibility.
|
||||
v_private(Messages.VisibilityEnum_private, ICPPASTVisibilityLabel.v_private, ICPPASTBaseSpecifier.v_private),
|
||||
v_protected(Messages.VisibilityEnum_protected, ICPPASTVisibilityLabel.v_protected, ICPPASTBaseSpecifier.v_protected),
|
||||
v_public(Messages.VisibilityEnum_public, ICPPASTVisibilityLabel.v_public, ICPPASTBaseSpecifier.v_public);
|
||||
v_private("private", ICPPASTVisibilityLabel.v_private, ICPPASTBaseSpecifier.v_private), //$NON-NLS-1$
|
||||
v_protected("protected", ICPPASTVisibilityLabel.v_protected, ICPPASTBaseSpecifier.v_protected), //$NON-NLS-1$
|
||||
v_public("public", ICPPASTVisibilityLabel.v_public, ICPPASTBaseSpecifier.v_public); //$NON-NLS-1$
|
||||
|
||||
private final String stringRepresentation;
|
||||
private final int visibilityLabelValue;
|
||||
|
|
|
@ -146,46 +146,4 @@ public class NameComposer {
|
|||
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$
|
||||
|
||||
/**
|
||||
* 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
|
||||
* depends on capitalization of the field name.
|
||||
* depends on capitalization of the method name.
|
||||
* <p>
|
||||
* 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_SUFFIX, ""); //$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_PREFIX, "get"); //$NON-NLS-1$
|
||||
store.setDefault(NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is"); //$NON-NLS-1$
|
||||
|
|