From 7e1f9c87fc2ae7886156613a95802eb902665efc Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 30 May 2008 11:13:33 +0000 Subject: Fixes for refactoring by Guido Zgraggen and Lukas Felber, bug 234783, 234786 and 234791. --- .../rewrite/CommentHandlingTestSource.rts | 45 ++++++++++ .../core/dom/rewrite/astwriter/ASTWriter.java | 5 +- .../dom/rewrite/astwriter/ASTWriterVisitor.java | 17 +++- .../changegenerator/ASTModificationHelper.java | 3 + .../ChangeGeneratorWriterVisitor.java | 30 +++++++ .../changegenerator/ModificationScopeStack.java | 5 +- .../dom/rewrite/commenthandler/NodeCommenter.java | 9 +- .../refactoring/GenerateGettersAndSetters.rts | 40 +++++++++ .../resources/refactoring/ImplementMethod.rts | 98 ++++++++++++++++++++++ .../ImplementMethodRefactoringTest.java | 17 ++-- .../refactoring/utils/PseudoNameGeneratorTest.java | 2 +- .../GenerateGettersAndSettersRefactoring.java | 4 + .../ui/refactoring/gettersandsetters/Messages.java | 3 +- .../gettersandsetters/messages.properties | 12 +++ .../ImplementMethodRefactoring.java | 86 +++++++++++-------- .../ui/refactoring/implementmethod/Messages.java | 4 + .../ui/refactoring/implementmethod/Parameter.java | 27 ------ .../implementmethod/ParameterHandler.java | 74 ++++++++++++---- .../refactoring/implementmethod/ParameterInfo.java | 72 ++++++++++++++++ .../implementmethod/ParameterNamesInputPage.java | 52 +++++++++--- .../implementmethod/messages.properties | 4 + .../ui/refactoring/utils/DelayedJobRunner.java | 68 +++++++++++++++ .../internal/ui/refactoring/utils/NodeFactory.java | 18 ---- .../internal/ui/refactoring/utils/NodeHelper.java | 19 ++++- .../ui/refactoring/utils/PseudoNameGenerator.java | 11 ++- .../ui/refactoring/utils/SelectionHelper.java | 2 +- 26 files changed, 600 insertions(+), 127 deletions(-) delete mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Parameter.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterInfo.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/DelayedJobRunner.java delete mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeFactory.java diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts b/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts index 98fc157d935..782bb902cb1 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/CommentHandlingTestSource.rts @@ -3098,3 +3098,48 @@ int HideMethod::methode2(){ return i; = //comment =>trailing =>freestanding + +//!CommentRecognition Bug 234786 +//#org.eclipse.cdt.core.parser.tests.rewrite.comenthandler.CommentHandlingTest +//@test.h +#ifndef HIDEMETHOD_H_ +#define HIDEMETHOD_H_ + +class HideMethod { +public: + HideMethod(); + virtual ~HideMethod(); + int methode2(); +private: + int i; +}; + +#endif /* HIDEMETHOD_H_ */ + +//= +=>leading +=>trailing +=>freestanding + +//@test.cpp +#include "test.h" + +HideMethod::HideMethod() +{ +} + +HideMethod::~HideMethod() +{ +} + +int HideMethod::methode2(){ + i++; //comment + return i; +} + +//= +=>leading +=>trailing +i++; = //comment +=>freestanding + diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java index 598e025c900..22b013232f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriter.java @@ -45,7 +45,7 @@ public class ASTWriter { /** * Creates a ASTWriter that indents the code. * - * @param givenIndentation The indention added to each line + * @param givenIndentation The indentation added to each line */ public ASTWriter(String givenIndentation) { super(); @@ -66,7 +66,7 @@ public class ASTWriter { /** * - * Genereates the source code representing this node including comments. + * Generates the source code representing this node including comments. * * @param rootNode Node to write. * @param fileScope @@ -84,7 +84,6 @@ public class ASTWriter { return str; } - public void setModificationStore(ASTModificationStore modificationStore) { this.modificationStore = modificationStore; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java index a733f3bb8f0..edb2af11c73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java @@ -218,14 +218,27 @@ public class ASTWriterVisitor extends CPPASTVisitor { writeLeadingComments((ASTNode) parameterDeclaration); if(!macroHandler.checkisMacroExpansionNode(parameterDeclaration)) { parameterDeclaration.getDeclSpecifier().accept(this); - IASTDeclarator declarator = parameterDeclaration.getDeclarator(); - if(declarator.getName().toString().length() != 0){ + IASTDeclarator declarator = getParameterDeclarator(parameterDeclaration); + + if(getParameterName(declarator).toString().length() != 0){ scribe.printSpaces(1); } declarator.accept(this); } return ASTVisitor.PROCESS_SKIP; } + + + + protected IASTName getParameterName(IASTDeclarator declarator) { + return declarator.getName(); + } + + + protected IASTDeclarator getParameterDeclarator( + IASTParameterDeclaration parameterDeclaration) { + return parameterDeclaration.getDeclarator(); + } @Override public int visit(ICPPASTNamespaceDefinition namespace) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java index df3366f683b..e681824313f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ASTModificationHelper.java @@ -129,9 +129,12 @@ public class ASTModificationHelper { case REPLACE: if(childModification.getNewNode() instanceof IASTInitializer){ return (IASTInitializer)childModification.getNewNode(); + } else if (childModification.getNewNode() == null) { + return null; } throw new UnhandledASTModificationException(childModification); + case INSERT_BEFORE: throw new UnhandledASTModificationException(childModification); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java index 2a1a1662590..69b3ce6edd7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ChangeGeneratorWriterVisitor.java @@ -96,6 +96,34 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } + @Override + protected IASTDeclarator getParameterDeclarator( + IASTParameterDeclaration parameterDeclaration) { + + IASTDeclarator newDecl = parameterDeclaration.getDeclarator(); + if(stack.getModifiedNodes().contains(newDecl)){ + for(ASTModification currentModification : stack.getModificationsForNode(newDecl)){ + if(currentModification.getKind() == ASTModification.ModificationKind.REPLACE && currentModification.getTargetNode() == parameterDeclaration){ + newDecl = (IASTDeclarator) currentModification.getNewNode(); + } + } + } + return newDecl; + } + + @Override + protected IASTName getParameterName(IASTDeclarator declarator) { + IASTName newName = declarator.getName(); + if(stack.getModifiedNodes().contains(newName)){ + for(ASTModification currentModification : stack.getModificationsForNode(newName)){ + if(currentModification.getKind() == ASTModification.ModificationKind.REPLACE && currentModification.getTargetNode() == newName){ + newName = (IASTName) currentModification.getNewNode(); + } + } + } + return newName; + } + @Override public int leave(ICPPASTBaseSpecifier specifier) { super.leave(specifier); @@ -320,6 +348,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } } + //Check all insert before and append modifications for the current node. If necessary put it onto the stack. for (IASTNode currentModifiedNode : stack.getModifiedNodes()) { for (ASTModification currentMod : stack.getModificationsForNode(currentModifiedNode)) { if(currentMod.getNewNode() == node){ @@ -330,6 +359,7 @@ public class ChangeGeneratorWriterVisitor extends ASTWriterVisitor { } } } + //Check all replace modifications for the current node. Visit the replacing node if found. for (IASTNode currentModifiedNode : stack.getModifiedNodes()) { for (ASTModification currentMod : stack.getModificationsForNode(currentModifiedNode)) { if(currentMod.getTargetNode() == node && currentMod.getKind() == ModificationKind.REPLACE){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java index 1b3c8e20c92..8dacf66f139 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/changegenerator/ModificationScopeStack.java @@ -102,7 +102,10 @@ public class ModificationScopeStack { } List modForNodeList = new ArrayList(); for (ASTModification modification : aktModList) { - modForNodeList.addAll(modStore.getNestedModifications(modification).getModificationsForNode(node)); + ASTModificationMap nestedModifications = modStore.getNestedModifications(modification); + if(nestedModifications != null) { + modForNodeList.addAll(nestedModifications.getModificationsForNode(node)); + } } return Collections.unmodifiableList(modForNodeList); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommenter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommenter.java index 7e76048eeab..3cae3e20ea0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommenter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/commenthandler/NodeCommenter.java @@ -159,8 +159,13 @@ public class NodeCommenter { int length = OffsetHelper.getNodeOffset(com)-OffsetHelper.getNodeEndPoint(node); byte[] b = new byte[length]; - is.skip(OffsetHelper.getNodeEndPoint(node)); - is.read(b, 0, length); + long count = is.skip(OffsetHelper.getEndOffsetWithoutComments(node)); + if(count < OffsetHelper.getEndOffsetWithoutComments(node)) { + return false; + } + if(is.read(b, 0, length) == -1) { + return false; + } for(byte bb : b) { if(!Character.isWhitespace(bb)) { diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts index 85f19404e1a..f9ea1ba0218 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts @@ -742,3 +742,43 @@ public: #endif /* TEST_H_ */ +//!Generate Getters and Setters no Fields +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +fatalerror=true +//@C.h +/* + * test.h + */ + +#ifndef TEST_H_ +#define TEST_H_ + +//comment1 +class test +{ + void //$test$//(); + //comment3 +}; + +#endif /* TEST_H_ */ + +//= +/* + * test.h + */ + +#ifndef TEST_H_ +#define TEST_H_ + +//comment1 +class test +{ + void test(); + //comment3 +}; + +#endif /* TEST_H_ */ + + diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts index 59577185e1f..e3f3d765002 100644 --- a/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/ImplementMethod.rts @@ -1,3 +1,101 @@ +//!Param const and reference and pointer +//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest +//@.config +filename=A.h +//@A.h +class X { +public: + bool //$a(int = 100)$// const; +}; + +//= +class X { +public: + bool a(int = 100) const; +}; + +inline bool X::a(int int1) const +{ +} + + + +//!Param const and reference and pointer two params +//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest +//@.config +filename=A.h +//@A.h +class X { +public: + bool //$xy(int, int i)$// const; +}; + +//= +class X { +public: + bool xy(int, int i) const; +}; + +inline bool X::xy(int int1, int i) const +{ +} + + + +//!Test if TemplateMethod stays in header +//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest +//@.config +filename=A.h +//@A.h +template class A +{ +public: + //$void test();$// +}; + +//= +template class A +{ +public: + void test(); +}; + +template inline void A::test() +{ +} + + + +//@A.cpp +#include "A.h" + +//= +#include "A.h" + +//!Test Warning when Method definition in Class selected +//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest +//@.config +filename=A.h +initialWarnings=1 +//@A.h + +struct Test +{ + void //$bla$//() {} +}; + +//!Test Warning when ClassName selected +//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest +//@.config +filename=A.h +initialWarnings=1 +//@A.h + +struct //$Test$// +{ + void bla2(); +}; + //!class template member functions //#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest //@.config diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java index a3c7efc9995..589a163e43e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/implementmethod/ImplementMethodRefactoringTest.java @@ -30,7 +30,8 @@ import org.eclipse.cdt.internal.ui.refactoring.implementmethod.ImplementMethodRe */ public class ImplementMethodRefactoringTest extends RefactoringTest { - protected int warnings; + protected int finalWarnings; + private int initialWarnings; public ImplementMethodRefactoringTest(String name,Vector files) { super(name, files); @@ -46,16 +47,21 @@ public class ImplementMethodRefactoringTest extends RefactoringTest { try { RefactoringStatus checkInitialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR); - assertConditionsOk(checkInitialConditions); + if(initialWarnings == 0) { + assertConditionsOk(checkInitialConditions); + } else { + assertConditionsFatalError(checkInitialConditions, initialWarnings); + return; + } refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR); RefactoringStatus finalConditions = refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR); - if (warnings == 0) { + if (finalWarnings == 0) { Change createChange = refactoring.createChange(NULL_PROGRESS_MONITOR); assertConditionsOk(finalConditions); createChange.perform(NULL_PROGRESS_MONITOR); } else { - assertConditionsWarning(finalConditions, warnings); + assertConditionsWarning(finalConditions, finalWarnings); } compareFiles(fileMap); } @@ -66,6 +72,7 @@ public class ImplementMethodRefactoringTest extends RefactoringTest { @Override protected void configureRefactoring(Properties refactoringProperties) { - warnings = new Integer(refactoringProperties.getProperty("warnings", "0")).intValue(); //$NON-NLS-1$//$NON-NLS-2$ + finalWarnings = new Integer(refactoringProperties.getProperty("finalWarnings", "0")).intValue(); //$NON-NLS-1$//$NON-NLS-2$ + initialWarnings = Integer.parseInt(refactoringProperties.getProperty("initialWarnings", "0")); //$NON-NLS-1$//$NON-NLS-2$ } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/PseudoNameGeneratorTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/PseudoNameGeneratorTest.java index 46346522c4f..6e6a649076a 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/PseudoNameGeneratorTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/utils/PseudoNameGeneratorTest.java @@ -58,6 +58,6 @@ public class PseudoNameGeneratorTest extends TestCase { } public void testWithNamespace() { - assertEquals("string1", pseudoNameGenerator.generateNewName("std::string")); //$NON-NLS-1$//$NON-NLS-2$ + assertEquals("string", pseudoNameGenerator.generateNewName("std::string")); //$NON-NLS-1$//$NON-NLS-2$ } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java index fe622fd0e3e..eaccaa89caf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java @@ -61,6 +61,10 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring { initRefactoring(pm); + if(context.existingFields.size() == 0) { + initStatus.addFatalError(Messages.GenerateGettersAndSettersRefactoring_NoFields); + } + return initStatus; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java index a0f17674abb..4dec2ab88d1 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java @@ -15,12 +15,13 @@ import org.eclipse.osgi.util.NLS; public final class Messages extends NLS { - private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.generategettersandsetters.messages";//$NON-NLS-1$ + private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.messages";//$NON-NLS-1$ private Messages() { // Do not instantiate } + public static String GenerateGettersAndSettersRefactoring_NoFields; public static String GettersAndSetters_Name; static { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties index a3f392a75a3..c1bde5de902 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties @@ -1 +1,13 @@ +############################################################################### +# Copyright (c) 2008 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 +############################################################################### GettersAndSetters_Name=Generate Getters and Setters +GenerateGettersAndSettersRefactoring_NoFields=The class does not contain any fields. diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java index bed9e8fa686..266ccad3062 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java @@ -21,10 +21,11 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; @@ -44,7 +45,6 @@ import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder; import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; -import org.eclipse.cdt.internal.ui.refactoring.utils.NodeFactory; import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper; @@ -60,6 +60,8 @@ public class ImplementMethodRefactoring extends CRefactoring { private IASTSimpleDeclaration methodDeclaration; private InsertLocation insertLocation; private ParameterHandler parameterHandler; + private IASTDeclaration createdMethodDefinition; + private CPPASTFunctionDeclarator createdMethodDeclarator; public ImplementMethodRefactoring(IFile file, ISelection selection, ICElement element) { super(file, selection, element); @@ -73,8 +75,8 @@ public class ImplementMethodRefactoring extends CRefactoring { methodDeclaration = SelectionHelper.findFirstSelectedDeclaration(region, unit); - if (methodDeclaration == null) { - initStatus.addFatalError("No method selected"); //$NON-NLS-1$ + if (!NodeHelper.isMethodDeclaration(methodDeclaration)) { + initStatus.addFatalError(Messages.ImplementMethodRefactoring_NoMethodSelected); return initStatus; } @@ -82,13 +84,13 @@ public class ImplementMethodRefactoring extends CRefactoring { sm.worked(1); if (DefinitionFinder.getDefinition(methodDeclaration, file) != null) { - initStatus.addFatalError("This method already has an implementation."); //$NON-NLS-1$ + initStatus.addFatalError(Messages.ImplementMethodRefactoring_MethodHasImpl); return initStatus; } if(isProgressMonitorCanceld(sm, initStatus))return initStatus; sm.worked(1); sm.done(); - parameterHandler.initAditionalArgumentNames(); + parameterHandler.initArgumentNames(); sm.worked(1); sm.done(); findInsertLocation(); @@ -102,34 +104,59 @@ public class ImplementMethodRefactoring extends CRefactoring { protected void collectModifications(IProgressMonitor pm, ModificationCollector collector) throws CoreException, OperationCanceledException { IASTTranslationUnit targetUnit = insertLocation.getTargetTranslationUnit(); IASTNode parent = insertLocation.getPartenOfNodeToInsertBefore(); - IASTNode insertNode = createFunctionDefinition(targetUnit); + createFunctionDefinition(targetUnit); IASTNode nodeToInsertBefore = insertLocation.getNodeToInsertBefore(); - ASTRewrite rewrite = collector.rewriterForTranslationUnit(targetUnit); - rewrite.insertBefore(parent, nodeToInsertBefore, insertNode, null); + ASTRewrite translationUnitRewrite = collector.rewriterForTranslationUnit(targetUnit); + ASTRewrite methodRewrite = translationUnitRewrite.insertBefore(parent, nodeToInsertBefore, createdMethodDefinition, null); + + createParameterModifications(methodRewrite); + } + + private void createParameterModifications(ASTRewrite methodRewrite) { + for(ParameterInfo actParameterInfo : parameterHandler.getParameterInfos()) { + ASTRewrite parameterRewrite = methodRewrite.insertBefore(createdMethodDeclarator, null, actParameterInfo.getParameter(), null); + createNewNameInsertModification(actParameterInfo, parameterRewrite); + createRemoveDefaultValueModification(actParameterInfo, parameterRewrite); + } + + } + + private void createRemoveDefaultValueModification(ParameterInfo parameterInfo, ASTRewrite parameterRewrite) { + if(parameterInfo.hasDefaultValue()) { + parameterRewrite.remove(parameterInfo.getDefaultValueNode(), null); + } + } + + private void createNewNameInsertModification(ParameterInfo parameterInfo, ASTRewrite parameterRewrite) { + if(parameterInfo.hasNewName()) { + IASTNode insertNode = parameterInfo.getNewNameNode(); + IASTName replaceNode = parameterInfo.getNameNode(); + parameterRewrite.replace(replaceNode, insertNode, null); + } } private void findInsertLocation() throws CoreException { insertLocation = MethodDefinitionInsertLocationFinder.find(methodDeclaration.getFileLocation(), methodDeclaration.getParent(), file); - if (!insertLocation.hasFile()) { + if (!insertLocation.hasFile() || NodeHelper.isContainedInTemplateDeclaration(methodDeclaration)) { insertLocation.setInsertFile(file); - insertLocation.setNodeToInsertAfter(NodeHelper - .findTopLevelParent(methodDeclaration)); + insertLocation.setNodeToInsertAfter(NodeHelper.findTopLevelParent(methodDeclaration)); } } - private IASTNode createFunctionDefinition(IASTTranslationUnit unit) { - return createFunctionDefinition( + private void createFunctionDefinition(IASTTranslationUnit unit) { + createFunctionDefinition( methodDeclaration.getDeclSpecifier(), (ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0], methodDeclaration.getParent(), unit); } - public IASTNode createFunctionDefinition() { - return createFunctionDefinition(unit); + public IASTDeclaration createFunctionDefinition() { + createFunctionDefinition(unit); + return createdMethodDefinition; } - private IASTNode createFunctionDefinition(IASTDeclSpecifier declSpecifier, ICPPASTFunctionDeclarator functionDeclarator, IASTNode declarationParent, IASTTranslationUnit unit) { + private void createFunctionDefinition(IASTDeclSpecifier declSpecifier, ICPPASTFunctionDeclarator functionDeclarator, IASTNode declarationParent, IASTTranslationUnit unit) { IASTFunctionDefinition func = new CPPASTFunctionDefinition(); func.setParent(unit); @@ -151,20 +178,14 @@ public class ImplementMethodRefactoring extends CRefactoring { ICPPASTQualifiedName qname = createQualifiedNameFor(functionDeclarator, declarationParent); - CPPASTFunctionDeclarator newFunctionDeclarator = new CPPASTFunctionDeclarator(); - newFunctionDeclarator.setName(qname); - newFunctionDeclarator.setConst(functionDeclarator.isConst()); + createdMethodDeclarator = new CPPASTFunctionDeclarator(); + createdMethodDeclarator.setName(qname); + createdMethodDeclarator.setConst(functionDeclarator.isConst()); - - for(Parameter actParameter : parameterHandler.getParameters()) { - IASTParameterDeclaration createdParam = NodeFactory.createParameterDeclaration(actParameter.typeName, actParameter.parameterName); - newFunctionDeclarator.addParameterDeclaration(createdParam); - } - - func.setDeclarator(newFunctionDeclarator); + func.setDeclarator(createdMethodDeclarator); func.setBody(new CPPASTCompoundStatement()); - if(classHasTemplates(declarationParent)) { + if(NodeHelper.isContainedInTemplateDeclaration(declarationParent)) { CPPASTTemplateDeclaration templateDeclaration = new CPPASTTemplateDeclaration(); templateDeclaration.setParent(unit); @@ -173,9 +194,10 @@ public class ImplementMethodRefactoring extends CRefactoring { } templateDeclaration.setDeclaration(func); - return templateDeclaration; + createdMethodDefinition = templateDeclaration; + return; } - return func; + createdMethodDefinition = func; } private ICPPASTQualifiedName createQualifiedNameFor(IASTFunctionDeclarator functionDeclarator, IASTNode declarationParent) { @@ -183,10 +205,6 @@ public class ImplementMethodRefactoring extends CRefactoring { return NameHelper.createQualifiedNameFor(functionDeclarator.getName(), file, region.getOffset(), insertLocation.getInsertFile(), insertOffset); } - private boolean classHasTemplates(IASTNode declarationParent) { - return declarationParent.getParent() != null && declarationParent.getParent().getParent() instanceof ICPPASTTemplateDeclaration; - } - public IASTSimpleDeclaration getMethodDeclaration() { return methodDeclaration; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java index 344446d8f88..0912df01e09 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Messages.java @@ -24,6 +24,10 @@ public final class Messages extends NLS { public static String ParameterNamesInputPage_Title; public static String ParameterNamesInputPage_CompleteMissingMails; + public static String PreviewGenerationNotPossible; + public static String ImplementMethodRefactoringPage_GeneratingPreview; + public static String ImplementMethodRefactoring_NoMethodSelected; + public static String ImplementMethodRefactoring_MethodHasImpl; static { NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Parameter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Parameter.java deleted file mode 100644 index 426b5029387..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/Parameter.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008 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.implementmethod; - -/** - * @author Lukas Felber - * - */ -public class Parameter { - public Parameter(String typeName, String parameterName, boolean isChangable) { - this.typeName = typeName; - this.parameterName = parameterName; - this.isChangable = isChangable; - } - public String typeName; - public String parameterName; - public boolean isChangable; -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java index 50d8bc24dfc..d4b4d297883 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterHandler.java @@ -1,21 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2008 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.implementmethod; import java.util.ArrayList; import java.util.Collection; -import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.text.edits.InsertEdit; +import org.eclipse.text.edits.MultiTextEdit; + import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; - -import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriter; +import org.eclipse.cdt.ui.refactoring.CTextFileChange; import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.PseudoNameGenerator; +/** + * Manages and creates Method Parameter Infos. + * + * @author Lukas Felber + * + */ public class ParameterHandler { private boolean needsAditionalArgumentNames; private PseudoNameGenerator pseudoNameGenerator; - private ArrayList parameters; + private ArrayList parameterInfos; private ImplementMethodRefactoring refactoring; public ParameterHandler(ImplementMethodRefactoring refactoring) { @@ -26,22 +49,21 @@ public class ParameterHandler { return needsAditionalArgumentNames; } - public void initAditionalArgumentNames() { - if(parameters != null) { + public void initArgumentNames() { + if(parameterInfos != null) { return; } needsAditionalArgumentNames = false; - parameters = new ArrayList(); + parameterInfos = new ArrayList(); for(IASTParameterDeclaration actParam : getParametersFromMethodNode()) { String actName = actParam.getDeclarator().getName().toString(); boolean isChangable = false; - String typeName = NameHelper.getTypeName(actParam); if(actName.length() == 0) { needsAditionalArgumentNames = true; isChangable = true; - actName = findNameForParameter(typeName); + actName = findNameForParameter(NameHelper.getTypeName(actParam)); } - parameters.add(new Parameter(typeName, actName, isChangable)); + parameterInfos.add(new ParameterInfo(actParam, actName, isChangable)); } } @@ -66,12 +88,34 @@ public class ParameterHandler { } public String createFunctionDefinitionSignature() { - ASTWriter writer = new ASTWriter(); - IASTNode def = refactoring.createFunctionDefinition(); - return writer.write(def); + try { + CompositeChange compositeChange = (CompositeChange) refactoring.createChange(new NullProgressMonitor()); + InsertEdit insertEdit = getInsertEdit(compositeChange); + return insertEdit.getText().trim(); + } catch (OperationCanceledException e) { + return Messages.PreviewGenerationNotPossible; + } catch (CoreException e) { + return Messages.PreviewGenerationNotPossible; + } + } + + private InsertEdit getInsertEdit(CompositeChange compositeChange) { + for(Change actChange : compositeChange.getChildren()) { + if(actChange instanceof CompositeChange) { + return getInsertEdit((CompositeChange) actChange); + } else if (actChange instanceof CTextFileChange) { + CTextFileChange textFileChange = (CTextFileChange) actChange; + MultiTextEdit multiEdit = (MultiTextEdit) textFileChange.getEdit(); + if(multiEdit.getChildrenSize() == 0) { + continue; + } + return (InsertEdit) multiEdit.getChildren()[0]; + } + } + return null; } - public Collection getParameters() { - return parameters; + public Collection getParameterInfos() { + return parameterInfos; } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterInfo.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterInfo.java new file mode 100644 index 00000000000..55adcb1bfba --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterInfo.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2008 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.implementmethod; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; + +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; + +import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; + +/** + * @author Lukas Felber + * + */ +public class ParameterInfo { + private IASTParameterDeclaration parameter; + private boolean hasNewName; + private String parameterName; + + public ParameterInfo(IASTParameterDeclaration parameter, String parameterName, boolean HasNewName) { + this.parameter = parameter; + this.hasNewName = HasNewName; + this.parameterName = parameterName; + } + + public boolean hasNewName() { + return hasNewName; + } + + public boolean hasDefaultValue() { + return getDefaultValueNode() != null; + } + + public String getTypeName() { + return NameHelper.getTypeName(parameter); + } + + public String getParameterName() { + return parameterName; + } + + public void setParameterName(String newName) { + this.parameterName = newName; + } + + public IASTParameterDeclaration getParameter() { + return parameter; + } + + public IASTName getNameNode() { + return parameter.getDeclarator().getName(); + } + + public IASTName getNewNameNode() { + return new CPPASTName(parameterName.toCharArray()); + } + + public IASTNode getDefaultValueNode() { + return parameter.getDeclarator().getInitializer(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java index c0b106542c3..b242039b80d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ParameterNamesInputPage.java @@ -9,13 +9,14 @@ * Contributors: * Institute for Software - initial API and implementation *******************************************************************************/ - package org.eclipse.cdt.internal.ui.refactoring.implementmethod; import java.util.HashMap; import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; @@ -23,6 +24,7 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.cdt.internal.ui.preferences.formatter.TranslationUnitPreview; import org.eclipse.cdt.internal.ui.refactoring.dialogs.ValidatingLabeledTextField; +import org.eclipse.cdt.internal.ui.refactoring.utils.DelayedJobRunner; /** * InputPage used by the ImplementMethod refactoring if its necessary to enter additional parameter names. @@ -33,8 +35,9 @@ import org.eclipse.cdt.internal.ui.refactoring.dialogs.ValidatingLabeledTextFiel public class ParameterNamesInputPage extends UserInputWizardPage { private final ParameterHandler parameterHandler; - private TranslationUnitPreview translationUnitPreview; - + private TranslationUnitPreview translationUnitPreview; + private DelayedJobRunner delayedPreviewUpdater; + public ParameterNamesInputPage(ParameterHandler parameterHandler) { super(Messages.ParameterNamesInputPage_Title); this.parameterHandler = parameterHandler; @@ -53,11 +56,11 @@ public class ParameterNamesInputPage extends UserInputWizardPage { ValidatingLabeledTextField validatingLabeledTextField = new ValidatingLabeledTextField(superComposite); validatingLabeledTextField.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); - for (final Parameter actParameter : parameterHandler.getParameters()) { + for (final ParameterInfo actParameterInfo : parameterHandler.getParameterInfos()) { - String type = actParameter.typeName; - String content = actParameter.parameterName; - boolean readOnly = !actParameter.isChangable; + String type = actParameterInfo.getTypeName(); + String content = actParameterInfo.getParameterName(); + boolean readOnly = !actParameterInfo.hasNewName(); validatingLabeledTextField.addElement(type, content, readOnly, new ValidatingLabeledTextField.Validator(){ @@ -73,22 +76,45 @@ public class ParameterNamesInputPage extends UserInputWizardPage { @Override public boolean isValidInput(String newName) { - actParameter.parameterName = newName; + actParameterInfo.setParameterName(newName); updatePreview(); return true; }}); } - translationUnitPreview = new TranslationUnitPreview(new HashMap(), superComposite); - translationUnitPreview.getControl().setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); - updatePreview(); + createPreview(superComposite); setControl(superComposite); } + + private void createPreview(Composite superComposite) { + translationUnitPreview = new TranslationUnitPreview(new HashMap(), superComposite); + translationUnitPreview.getControl().setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL)); + Runnable runnable = new Runnable() { + public void run() { + setPreviewText(Messages.ImplementMethodRefactoringPage_GeneratingPreview); + setPreviewText(parameterHandler.createFunctionDefinitionSignature()); + } + private void setPreviewText(final String text) { + getShell().getDisplay().asyncExec(new Runnable() { + public void run() { + translationUnitPreview.setPreviewText(text); + }}); + } + }; + delayedPreviewUpdater = new DelayedJobRunner(runnable, 500); + delayedPreviewUpdater.start(); + superComposite.addDisposeListener(new DisposeListener() { + + public void widgetDisposed(DisposeEvent e) { + delayedPreviewUpdater.stop(); + }}); + } private void updatePreview() { - if (translationUnitPreview != null) { - translationUnitPreview.setPreviewText(parameterHandler.createFunctionDefinitionSignature()); + if (translationUnitPreview == null) { + return; } + delayedPreviewUpdater.runJob(); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties index 63cb2a2cd48..c67e42581d8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/messages.properties @@ -12,3 +12,7 @@ ############################################################################### ParameterNamesInputPage_Title=Implement Method ParameterNamesInputPage_CompleteMissingMails=Please complete the missing variable names: +ImplementMethodRefactoring_MethodDefinition=Method Definition +ImplementMethodRefactoringPage_GeneratingPreview=Generating preview... +ImplementMethodRefactoring_NoMethodSelected=No method declaration selected +ImplementMethodRefactoring_MethodHasImpl=This method already has an implementation. \ No newline at end of file diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/DelayedJobRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/DelayedJobRunner.java new file mode 100644 index 00000000000..e4242a64e2f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/DelayedJobRunner.java @@ -0,0 +1,68 @@ +package org.eclipse.cdt.internal.ui.refactoring.utils; + + +/** + * Runs a job delayed by a given time when runJob gets called.
+ * Only the time of the last runJob call is considered. So if runJob + * gets called before the time expires the first call will be ignored and the job will be run + * after the time of the second call + the delay time.
+ * DelayedJobRunner isn't thread save (not neede till now).
+ * Oh and one more thing. Do call the stop method when the runner isn't needed any more. ;-) + * + * @author Lukas Felber + * + */ +public class DelayedJobRunner { + private Runnable job; + private long lastUpdateEventTime; + private long delayTimeInMillis; + private boolean shouldStop; + private boolean shouldUpdate; + private static final long sleepTimeInMillis = 50; + + public DelayedJobRunner(Runnable job, long delayTimeInMillis) { + this.job = job; + this.delayTimeInMillis = delayTimeInMillis; + shouldUpdate = true; + } + + public void start() { + shouldStop = false; + new Thread( + new Runnable() { + public void run() { + startUpdateLoop(); + } + } + ).start(); + } + + public void runJob() { + shouldUpdate = true; + lastUpdateEventTime = System.currentTimeMillis(); + } + + private void startUpdateLoop() { + try { + while (!shouldStop) { + if (shouldUpdate && isDelayTimeOver()) { + lastUpdateEventTime = System.currentTimeMillis(); + shouldUpdate = false; + job.run(); + } + Thread.sleep(sleepTimeInMillis); + } + } catch (Exception e) { + //do nothing expect die. + } + } + + private boolean isDelayTimeOver() { + long currentTime = System.currentTimeMillis(); + return lastUpdateEventTime + delayTimeInMillis < currentTime; + } + + public void stop() { + this.shouldStop = true; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeFactory.java deleted file mode 100644 index ebac1996d66..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeFactory.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.eclipse.cdt.internal.ui.refactoring.utils; - -import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; - -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration; - -public class NodeFactory { - - public static IASTParameterDeclaration createParameterDeclaration(String paramType, String paramName) { - CPPASTNamedTypeSpecifier type = new CPPASTNamedTypeSpecifier(new CPPASTName(paramType.toCharArray()), false); - CPPASTDeclarator declarator = new CPPASTDeclarator(new CPPASTName(paramName.toCharArray())); - return new CPPASTParameterDeclaration(type,declarator); - } - -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeHelper.java index dcf8454590e..1bd5aade32e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeHelper.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NodeHelper.java @@ -24,7 +24,9 @@ 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.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamespaceDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; @@ -157,5 +159,20 @@ public class NodeHelper { } return null; } - + + public static boolean isMethodDeclaration(IASTSimpleDeclaration simpleDeclaration) { + if(simpleDeclaration == null) { + return false; + } + return simpleDeclaration.getDeclarators().length == 1 && simpleDeclaration.getDeclarators()[0] instanceof ICPPASTFunctionDeclarator; + } + + public static boolean isContainedInTemplateDeclaration(IASTNode node) { + if(node == null) { + return false; + } else if (node instanceof ICPPASTTemplateDeclaration) { + return true; + } + return isContainedInTemplateDeclaration(node.getParent()); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java index de0ec5888bd..6364253c4d7 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/PseudoNameGenerator.java @@ -32,14 +32,19 @@ public class PseudoNameGenerator { String[] nameParts = typeName.split("::"); //$NON-NLS-1$ typeName = nameParts[nameParts.length - 1]; + if(typeName.length() != 0) { + typeName = typeName.substring(0, 1).toLowerCase() + typeName.substring(1); + } - String newNameCandidate = null; + String numberString = ""; //$NON-NLS-1$ + String newNameCandidate; int index = 0; do { + newNameCandidate = typeName + numberString; index++; - newNameCandidate = String.format("%s%d", typeName, Integer.valueOf(index)); //$NON-NLS-1$ - } while(names.contains(newNameCandidate)); + numberString = Integer.toString(index); + } while(names.contains(newNameCandidate) || !NameHelper.isValidLocalVariableName(newNameCandidate) || NameHelper.isKeyword(newNameCandidate)); names.add(newNameCandidate); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/SelectionHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/SelectionHelper.java index 10909da2d19..dbf85ac0e5b 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/SelectionHelper.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/SelectionHelper.java @@ -70,7 +70,7 @@ public class SelectionHelper { Region exprPos = createExpressionPosition(expression); int selStart = textSelection.getOffset(); int selEnd = textSelection.getLength() + selStart; - return exprPos.getOffset()+exprPos.getLength() > selStart && exprPos.getOffset() < selEnd; + return exprPos.getOffset()+exprPos.getLength() >= selStart && exprPos.getOffset() <= selEnd; } public static boolean isExpressionWhollyInSelection(Region textSelection, IASTNode expression) { -- cgit v1.2.3