From cd48414961ff3e7ec5cc4f1ed8bd5aa575b771b7 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 16 Apr 2008 13:59:50 +0000 Subject: [PATCH] Generate getters and setters by Emanuel Graf, bug 226658. --- .../refactoring/GenerateGettersAndSetters.rts | 652 ++++++++++++++++++ .../refactoring/RefactoringTestSuite.java | 3 +- .../GenerateGettersAndSettersTest.java | 125 ++++ core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF | 1 + core/org.eclipse.cdt.ui/plugin.properties | 3 + core/org.eclipse.cdt.ui/plugin.xml | 27 +- .../editor/ICEditorActionDefinitionIds.java | 6 + .../internal/ui/refactoring/CRefactoring.java | 2 +- .../gettersandsetters/FunctionFactory.java | 108 +++ .../GenerateGettersAndSettersInputPage.java | 72 ++ .../GenerateGettersAndSettersRefactoring.java | 123 ++++ ...ateGettersAndSettersRefactoringRunner.java | 49 ++ ...ateGettersAndSettersRefactoringWizard.java | 37 + .../GetterAndSetterContext.java | 167 +++++ .../GetterSetterInsertEditProvider.java | 33 + .../gettersandsetters/Messages.java | 30 + .../gettersandsetters/messages.properties | 2 + .../ui/refactoring/utils/NameHelper.java | 67 ++ .../cdt/ui/actions/CdtActionConstants.java | 6 + .../actions/CRefactoringActionGroup.java | 10 +- .../actions/GettersAndSettersAction.java | 57 ++ .../cdt/ui/refactoring/actions/Messages.java | 1 + .../refactoring/actions/messages.properties | 1 + 23 files changed, 1568 insertions(+), 14 deletions(-) create mode 100644 core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts create mode 100644 core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/gettersandsetters/GenerateGettersAndSettersTest.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersInputPage.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringRunner.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringWizard.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterAndSetterContext.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/GettersAndSettersAction.java diff --git a/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts new file mode 100644 index 00000000000..5eca1f4fa5d --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/resources/refactoring/GenerateGettersAndSetters.rts @@ -0,0 +1,652 @@ +//!Generate Getters and Setters One Getter Selection +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +getters=name +//@C.cpp +#include "C.h" + +int Person::SocSecNo(){ + return socSecNo; +} + +int main(int argc, char **argv) { + +} + +//= +//@C.h +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int //$SocSecNo$//(); + + int GetUniqueId(); + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + +int gooo = 1; + +#endif /*C_H_*/ +//= +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int SocSecNo(); + + int GetUniqueId(); + char *getName() const + { + return name; + } + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + +int gooo = 1; + +#endif /*C_H_*/ +//!Generate Getters and Setters One Getter Selection with Namespace +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +getters=name +//@C.cpp +#include "C.h" + +int Person::SocSecNo(){ + return socSecNo; +} + +int main(int argc, char **argv) { + +} + +//= +//@C.h +#ifndef C_H_ +#define C_H_ + +namespace Personal { + class Person { + + private: + + int systemId; + + protected: + + char *name; + + public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int //$SocSecNo$//(); + + int GetUniqueId(); + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } + }; +} + +int gooo = 1; + +#endif /*C_H_*/ + +//= +#ifndef C_H_ +#define C_H_ + +namespace Personal { + class Person { + + private: + + int systemId; + + protected: + + char *name; + + public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int SocSecNo(); + + int GetUniqueId(); + char *getName() const + { + return name; + } + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } + }; +} + +int gooo = 1; + +#endif /*C_H_*/ + +//!Generate Getters and Setters One Setter Selection +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +setters=name +//@C.cpp +#include "C.h" + +int Person::SocSecNo(){ + return socSecNo; +} + +int main(int argc, char **argv) { + +} + +//= +//@C.h +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int //$SocSecNo$//(); + + int GetUniqueId(); + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + + +int gooo = 1; + +#endif /*C_H_*/ +//= +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int SocSecNo(); + + int GetUniqueId(); + void setName(char *name) + { + this.name = name; + } + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + + +int gooo = 1; + +#endif /*C_H_*/ +//!Generate Getters and Setters Getter and Setter Selection +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +setters=name +getters=name +//@C.cpp +#include "C.h" + +int Person::SocSecNo(){ + return socSecNo; +} + +int main(int argc, char **argv) { + +} + +//= +//@C.h +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int //$SocSecNo$//(); + + int GetUniqueId(); + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + + +int gooo = 1; + +#endif /*C_H_*/ +//= +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int SocSecNo(); + + int GetUniqueId(); + char *getName() const + { + return name; + } + + void setName(char *name) + { + this.name = name; + } + + int getSystemId(){ + return systemId; + } + + void setSystemId(int systemId){ + this.systemId = systemId; + } +}; + + +int gooo = 1; + +#endif /*C_H_*/ +//!Generate Getters and Setters Multiple Selection +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=C.h +getters=name,systemId +setters=name,systemId +//@C.cpp +#include "C.h" + +int Person::SocSecNo(){ + return socSecNo; +} + +int main(int argc, char **argv) { + +} + +//= +//@C.h +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int //$SocSecNo$//(); + + int GetUniqueId(); + +}; + +int gooo = 1; + +#endif /*C_H_*/ + +//= +#ifndef C_H_ +#define C_H_ + +class Person { + +private: + + int systemId; + +protected: + + char *name; + +public: + + const int socSecNo; + + Person myFriend; + int getSystemId() const + { + return systemId; + } + + void setSystemId(int systemId) + { + this.systemId = systemId; + } + + char *getName() const + { + return name; + } + + void setName(char *name) + { + this.name = name; + } + + Person(int socSecNo); // contructor + + ~Person(); // destructor + + + char* Name(); + + void Print(); + + int SocSecNo(); + + int GetUniqueId(); + +}; + +int gooo = 1; + +#endif /*C_H_*/ + +//!Generate Getters and Setters Visibility order 1 +//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest +//@.config +filename=GaS.h +getters=i,isOk +setters=i,isOk +//@GaS.cpp +#include "Getters.h" + +GaS::Getters() { +} + +GaS::~Getters() { +} + +//@GaS.h +#ifndef GAS_H_ +#define GAS_H_ + +class GaS { +public: + GaS(); + virtual ~GaS(); + bool //$isOk$//; + void methode2(); + +private: + int i; +}; + +#endif + +//= +#ifndef GAS_H_ +#define GAS_H_ + +class GaS { +public: + GaS(); + virtual ~GaS(); + bool isOk; + void methode2(); + bool getIsOk() const + { + return isOk; + } + + void setIsOk(bool isOk) + { + this.isOk = isOk; + } + + int getI() const + { + return i; + } + + void setI(int i) + { + this.i = i; + } + +private: + int i; +}; + +#endif + diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java index 48c6c63b6b7..2c575bc0d71 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestSuite.java @@ -26,11 +26,12 @@ public class RefactoringTestSuite extends TestSuite { public static Test suite() throws Exception { TestSuite suite = new RefactoringTestSuite(); + suite.addTest(UtilTestSuite.suite()); suite.addTest(RenameRegressionTests.suite()); suite.addTest(ExtractFunctionTestSuite.suite()); suite.addTest(RefactoringTester.suite("ExtractConstantRefactoringTests", "resources/refactoring/ExtractConstant.rts")); suite.addTest(RefactoringTester.suite("HideMethodRefactoringTests", "resources/refactoring/HideMethod.rts")); - suite.addTest(UtilTestSuite.suite()); + suite.addTest(RefactoringTester.suite("GettersAndSettersTests", "resources/refactoring/GenerateGettersAndSetters.rts")); suite.addTest(RefactoringTester.suite("ImplementMethodRefactoringTests", "resources/refactoring/ImplementMethod.rts")); return suite; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/gettersandsetters/GenerateGettersAndSettersTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/gettersandsetters/GenerateGettersAndSettersTest.java new file mode 100644 index 00000000000..7bb838c0647 --- /dev/null +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/gettersandsetters/GenerateGettersAndSettersTest.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * Rapperswil, University of applied sciences + * 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: + * Emanuel Graf & Leo Buettiker - initial API and implementation + * Thomas Corbat - implementation + ******************************************************************************/ +package org.eclipse.cdt.ui.tests.refactoring.gettersandsetters; + +import java.util.ArrayList; +import java.util.Properties; +import java.util.Vector; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.ui.tests.refactoring.RefactoringTest; +import org.eclipse.cdt.ui.tests.refactoring.TestSourceFile; + +import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GenerateGettersAndSettersRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterAndSetterContext; + +/** + * @author Thomas Corbat + * + */ +public class GenerateGettersAndSettersTest extends RefactoringTest { + + protected boolean fatalError; + private int warnings; + private ArrayList selectedGetters; + private ArrayList selectedSetters; + private GenerateGettersAndSettersRefactoring refactoring; + + + /** + * @param name + * @param files + */ + public GenerateGettersAndSettersTest(String name, Vector files) { + super(name, files); + } + + @Override + protected void runTest() throws Throwable { + IFile refFile = project.getFile(fileName); + refactoring = new GenerateGettersAndSettersRefactoring(refFile, selection, null); + RefactoringStatus initialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR); + + + if(fatalError){ + assertConditionsFatalError(initialConditions); + return; + } + else{ + assertConditionsOk(initialConditions); + executeRefactoring(); + } + + + } + + private void executeRefactoring() throws CoreException, Exception { + + RefactoringStatus initialConditions = refactoring.checkInitialConditions(NULL_PROGRESS_MONITOR); + assertConditionsOk(initialConditions); + selectFields(); + Change createChange = refactoring.createChange(NULL_PROGRESS_MONITOR); + RefactoringStatus finalConditions = refactoring.checkFinalConditions(NULL_PROGRESS_MONITOR); + if(warnings > 0){ + assertConditionsWarning(finalConditions, warnings); + } + else{ + assertConditionsOk(finalConditions); + } + + createChange.perform(NULL_PROGRESS_MONITOR); + + compareFiles(fileMap); + } + + private void selectFields() { + GetterAndSetterContext context = refactoring.getContext(); + + for(IASTSimpleDeclaration currentDecl : context.existingFields){ + String name = currentDecl.getDeclarators()[0].getName().getRawSignature(); + if(selectedGetters.contains(name) ){ + selectedGetters.remove(name); + context.selectedFunctions.add(context.createGetterInserter(currentDecl)); + } + + if(selectedSetters.contains(name) ){ + selectedSetters.remove(name); + context.selectedFunctions.add(context.createSetterInserter(currentDecl)); + } + } + } + + + @Override + protected void configureRefactoring(Properties refactoringProperties) { + fatalError = Boolean.valueOf(refactoringProperties.getProperty("fatalerror", "false")).booleanValue(); //$NON-NLS-1$//$NON-NLS-2$ + warnings = new Integer(refactoringProperties.getProperty("warnings", "0")).intValue(); //$NON-NLS-1$//$NON-NLS-2$ + String getters = refactoringProperties.getProperty("getters", ""); //$NON-NLS-1$ //$NON-NLS-2$ + String setters = refactoringProperties.getProperty("setters", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + selectedGetters = new ArrayList(); + for(String getterName : getters.split(",")){ //$NON-NLS-1$ + selectedGetters.add(getterName); + } + selectedSetters = new ArrayList(); + for(String setterName : setters.split(",")){ //$NON-NLS-1$ + selectedSetters.add(setterName); + } + } + +} diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF index 1a2706068cc..310952d8945 100644 --- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF @@ -32,6 +32,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true, org.eclipse.cdt.internal.ui.refactoring.dialogs;x-internal:=true, org.eclipse.cdt.internal.ui.refactoring.extractconstant;x-friends:="org.eclipse.cdt.ui.tests", org.eclipse.cdt.internal.ui.refactoring.extractfunction;x-friends:="org.eclipse.cdt.ui.tests", + org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;x-friends:="org.eclipse.cdt.ui.tests", org.eclipse.cdt.internal.ui.refactoring.hidemethod;x-friends:="org.eclipse.cdt.ui.tests", org.eclipse.cdt.internal.ui.refactoring.implementmethod;x-friends:="org.eclipse.cdt.ui.tests", org.eclipse.cdt.internal.ui.refactoring.rename;x-friends:="org.eclipse.cdt.ui.tests", diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 351dd8acb5c..17b686626ed 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -148,6 +148,8 @@ ActionDefinition.extractFunction.name= Extract Function - Refactoring ActionDefinition.extractFunction.description= Extract a function for the selected list of expressions or statements ActionDefinition.implementMethod.name= Implement Method - Source Generation ActionDefinition.implementMethod.description= Implements a method for a selected method declaration +ActionDefinition.gettersAndSetters.name = Generate Getters and Setters... +ActionDefinition.gettersAndSetters.description = Generates getters and setters for a selected field # Action Set CodingActionSet.label= C/C++ Coding @@ -159,6 +161,7 @@ Refactoring.extractConstant.label=Extr&act Constant... Refactoring.extractFunction.label=Extract &Function... (work in progress) Refactoring.hideMethod.label=Hide Member Function... (work in progress) Refactoring.implementMethod.label=Impl&ement Method... (work in progress) +Refactoring.gettersAndSetters.label=Generate Getters and Setters... CEditor.name=C/C++ Editor diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 3fbe2853638..85e08d57f55 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -1171,10 +1171,17 @@ id="org.eclipse.cdt.ui.actions.ExtractConstant" retarget="true"> + + @@ -1989,27 +1996,27 @@ name="%ActionDefinition.renameElement.name" description="%ActionDefinition.renameElement.description" categoryId="org.eclipse.cdt.ui.category.refactoring" - id="org.eclipse.cdt.ui.edit.text.rename.element"> - + id="org.eclipse.cdt.ui.edit.text.rename.element"/> - + id="org.eclipse.cdt.ui.refactor.extract.constant"/> - + id="org.eclipse.cdt.ui.refactor.extract.function"/> - - + id="org.eclipse.cdt.ui.refactor.implement.method"/> + generate getters and setters + * (value "org.eclipse.cdt.ui.refactor.getters.and.setters"). + */ + public static final String GETTERS_AND_SETTERS= "org.eclipse.cdt.ui.refactor.getters.and.setters"; //$NON-NLS-1$ + /** * Action definition ID of the refactor -> undo action * (value "org.eclipse.cdt.ui.edit.text.undo.action"). diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java index a11985198b8..f4b003b2ac9 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/CRefactoring.java @@ -278,7 +278,7 @@ public abstract class CRefactoring extends Refactoring { return null; } - private boolean loadTranslationUnit(RefactoringStatus status, + protected boolean loadTranslationUnit(RefactoringStatus status, IProgressMonitor mon) { SubMonitor subMonitor = SubMonitor.convert(mon, 10); if (file != null) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java new file mode 100644 index 00000000000..0fa8ac1a282 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/FunctionFactory.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; + +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTExpressionStatement; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier; + +import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; + +public class FunctionFactory { + + public static IASTFunctionDefinition createGetter(String varName, IASTSimpleDeclaration fieldDeclaration) { + + IASTFunctionDefinition getter = new CPPASTFunctionDefinition(); + + getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier()); + + CPPASTName getterName = new CPPASTName(); + String varPartOfGetterName = NameHelper.makeFirstCharUpper(NameHelper.trimFieldName(varName)); + getterName.setName("get".concat(varPartOfGetterName).toCharArray()); //$NON-NLS-1$ + CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator(); + declarator.setConst(true); + declarator.setName(getterName); + for(IASTPointerOperator pointer : fieldDeclaration.getDeclarators()[0].getPointerOperators()){ + declarator.addPointerOperator(pointer); + } + getter.setDeclarator(declarator); + + CPPASTCompoundStatement compound = new CPPASTCompoundStatement(); + CPPASTReturnStatement returnStatement = new CPPASTReturnStatement(); + CPPASTIdExpression idExpr = new CPPASTIdExpression(); + CPPASTName returnVal = new CPPASTName(); + returnVal.setName(varName.toCharArray()); + idExpr.setName(returnVal); + returnStatement.setReturnValue(idExpr); + compound.addStatement(returnStatement); + + getter.setBody(compound); + + return getter; + } + + public static IASTFunctionDefinition createSetter(String varName, IASTSimpleDeclaration fieldDeclaration) { + + IASTFunctionDefinition setter = new CPPASTFunctionDefinition(); + + CPPASTSimpleDeclSpecifier declSpecifier = new CPPASTSimpleDeclSpecifier(); + declSpecifier.setType(IASTSimpleDeclSpecifier.t_void); + setter.setDeclSpecifier(declSpecifier); + + CPPASTName setterName = new CPPASTName(); + String varPartOfSetterName = NameHelper.makeFirstCharUpper(NameHelper.trimFieldName(varName)); + setterName.setName("set".concat(varPartOfSetterName).toCharArray()); //$NON-NLS-1$ + CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator(); + declarator.setName(setterName); + setter.setDeclarator(declarator); + CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration(); + parameterDeclaration.setDeclarator(fieldDeclaration.getDeclarators()[0]); + parameterDeclaration.setDeclSpecifier(fieldDeclaration.getDeclSpecifier()); + declarator.addParameterDeclaration(parameterDeclaration); + + CPPASTCompoundStatement compound = new CPPASTCompoundStatement(); + CPPASTExpressionStatement exprStmt = new CPPASTExpressionStatement(); + CPPASTBinaryExpression binExpr = new CPPASTBinaryExpression(); + CPPASTFieldReference fieldRef = new CPPASTFieldReference(); + CPPASTLiteralExpression litExpr = new CPPASTLiteralExpression(); + litExpr.setValue("this"); //$NON-NLS-1$ + fieldRef.setFieldOwner(litExpr); + fieldRef.setFieldName(fieldDeclaration.getDeclarators()[0].getName()); + binExpr.setOperand1(fieldRef); + binExpr.setOperator(IASTBinaryExpression.op_assign); + CPPASTIdExpression idExpr = new CPPASTIdExpression(); + idExpr.setName(fieldDeclaration.getDeclarators()[0].getName()); + binExpr.setOperand2(idExpr); + exprStmt.setExpression(binExpr); + compound.addStatement(exprStmt); + + setter.setBody(compound); + + return setter; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersInputPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersInputPage.java new file mode 100644 index 00000000000..6c8f57dcdbb --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersInputPage.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.gettersandsetters; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer; + +public class GenerateGettersAndSettersInputPage extends UserInputWizardPage { + + private GetterAndSetterContext context; + + public GenerateGettersAndSettersInputPage(GetterAndSetterContext context) { + super(Messages.GettersAndSetters_Name); + this.context = context; + } + + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE ); + comp.setLayout(new FillLayout()); + createTree(comp); + + setControl(comp); + } + + private void createTree(Composite comp) { + final ContainerCheckedTreeViewer variableSelectionView = new ContainerCheckedTreeViewer(comp, SWT.BORDER); + for(IASTSimpleDeclaration currentField : context.existingFields){ + if(currentField.getDeclarators().length == 0){ + continue; + } + + variableSelectionView.setContentProvider(context); + variableSelectionView.setAutoExpandLevel(3); + variableSelectionView.setInput(""); //$NON-NLS-1$ + + variableSelectionView.addCheckStateListener(new ICheckStateListener(){ + + public void checkStateChanged(CheckStateChangedEvent event) { + ArrayList checkedFunctions = new ArrayList(); + for(Object currentElement : variableSelectionView.getCheckedElements()){ + if (currentElement instanceof GetterSetterInsertEditProvider) { + GetterSetterInsertEditProvider editProvider = (GetterSetterInsertEditProvider) currentElement; + checkedFunctions.add(editProvider); + } + } + context.selectedFunctions = checkedFunctions; + + } + + }); + } + + } + +} 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 new file mode 100644 index 00000000000..ae206abb082 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.model.ICElement; + +import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange; +import org.eclipse.cdt.internal.ui.refactoring.CRefactoring; +import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; +import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; + +/** + * @author Thomas Corbat + * + */ +public class GenerateGettersAndSettersRefactoring extends CRefactoring { + + private static final String MEMBER_DECLARATION = "MEMBER_DECLARATION"; //$NON-NLS-1$ + private final GetterAndSetterContext context = new GetterAndSetterContext(); + + public GenerateGettersAndSettersRefactoring(IFile file, ISelection selection, ICElement element) { + super(file, selection, element); + } + + @Override + public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { + SubMonitor sm = SubMonitor.convert(pm, 10); + + super.checkInitialConditions(sm.newChild(6)); + + initRefactoring(pm); + + return initStatus; + } + + private void initRefactoring(IProgressMonitor pm) { + loadTranslationUnit(initStatus, pm); + context.setUnit(unit); + findDeclarations(); + + } + + protected void findDeclarations() { + + unit.accept(new CPPASTVisitor() { + + { + shouldVisitDeclarations = true; + } + + @Override + public int visit(IASTDeclaration declaration) { + if (declaration instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration fieldDeclaration = (IASTSimpleDeclaration) declaration; + ASTNodeProperty props = fieldDeclaration.getPropertyInParent(); + if (props.getName().contains(MEMBER_DECLARATION)) { + final IASTDeclarator[] declarators = fieldDeclaration.getDeclarators(); + if (declarators.length > 0) { + if ((declarators[0] instanceof IASTFunctionDeclarator)) { + context.existingFunctionDeclarations.add(fieldDeclaration); + } else { + if(isInSameFile(fieldDeclaration)){ + context.existingFields.add(fieldDeclaration); + } + } + } + } + } + if (declaration instanceof IASTFunctionDefinition) { + IASTFunctionDefinition functionDefinition = (IASTFunctionDefinition) declaration; + ASTNodeProperty props = functionDefinition.getPropertyInParent(); + if (props.getName().contains(MEMBER_DECLARATION)) { + context.existingFunctionDefinitions.add(functionDefinition); + } + } + return super.visit(declaration); + } + }); + } + + @Override + protected void collectModifications(IProgressMonitor pm,ModificationCollector collector) throws CoreException, OperationCanceledException { +// egtodo +// ASTRewrite rewriter = collector.rewriterForTranslationUnit(unit); + + for(GetterSetterInsertEditProvider currentProvider : context.selectedFunctions){ +// egtodo +// TextEditGroup editGroup = new TextEditGroup(Messages.GenerateGettersAndSettersRefactoring_Insert + currentProvider.toString()); + ICPPASTCompositeTypeSpecifier classDefinition = (ICPPASTCompositeTypeSpecifier) context.existingFunctionDeclarations.get(context.existingFunctionDeclarations.size()-1).getParent(); + AddDeclarationNodeToClassChange.createChange(classDefinition, VisibilityEnum.v_public, currentProvider.getFunction(), false, collector); + } + } + + public GetterAndSetterContext getContext() { + return context; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringRunner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringRunner.java new file mode 100644 index 00000000000..0d8d8ca1744 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringRunner.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.texteditor.ITextEditor; + +import org.eclipse.cdt.core.model.ICElement; + +import org.eclipse.cdt.internal.ui.refactoring.RefactoringRunner; + +/** + * @author Thomas Corbat + * + */ +public class GenerateGettersAndSettersRefactoringRunner extends RefactoringRunner { + + public GenerateGettersAndSettersRefactoringRunner(IFile file, ISelection selection, ICElement elem, IShellProvider shellProvider) { + super(file, selection, elem, shellProvider); + } + + @Override + public void run() { + if (PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor() instanceof ITextEditor) { + GenerateGettersAndSettersRefactoring refactoring = new GenerateGettersAndSettersRefactoring(file, selection, celement); + GenerateGettersAndSettersRefactoringWizard wizard = new GenerateGettersAndSettersRefactoringWizard(refactoring); + RefactoringWizardOpenOperation operator = new RefactoringWizardOpenOperation(wizard); + + try { + operator.run(shellProvider.getShell(), refactoring.getName()); + } catch (InterruptedException e) { + //initial condition checking got canceled by the user. + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringWizard.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringWizard.java new file mode 100644 index 00000000000..5dea88b9b2f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoringWizard.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.ltk.ui.refactoring.RefactoringWizard; +import org.eclipse.ltk.ui.refactoring.UserInputWizardPage; + +/** + * @author Thomas Corbat + * + */ +public class GenerateGettersAndSettersRefactoringWizard extends + RefactoringWizard { + + private final GenerateGettersAndSettersRefactoring refactoring; + + public GenerateGettersAndSettersRefactoringWizard( + GenerateGettersAndSettersRefactoring refactoring) { + super(refactoring, WIZARD_BASED_USER_INTERFACE); + this.refactoring = refactoring; + } + + @Override + protected void addUserInputPages() { + UserInputWizardPage page = new GenerateGettersAndSettersInputPage(refactoring.getContext()); + addPage(page); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterAndSetterContext.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterAndSetterContext.java new file mode 100644 index 00000000000..49f1d854d11 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterAndSetterContext.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import java.util.ArrayList; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; + +import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper; + +public class GetterAndSetterContext implements ITreeContentProvider{ + + public ArrayList existingFields = new ArrayList(); + public ArrayList existingFunctionDefinitions = new ArrayList(); + public ArrayList existingFunctionDeclarations = new ArrayList(); + public ArrayList selectedFunctions = new ArrayList(); + private IASTTranslationUnit unit; + + public Object[] getChildren(Object parentElement) { + + ArrayList children = new ArrayList(); + if (parentElement instanceof FieldWrapper) { + FieldWrapper wrapper = (FieldWrapper) parentElement; + + if(!wrapper.getter.exists()){ + children.add(createGetterInserter(wrapper.field)); + } + if(!wrapper.setter.exists() && !wrapper.field.getDeclSpecifier().isConst()){ + + children.add(createSetterInserter(wrapper.field)); + } + } + return children.toArray(); + } + + public GetterSetterInsertEditProvider createGetterInserter(IASTSimpleDeclaration simpleDeclaration) { + String varName = simpleDeclaration.getDeclarators()[0].getName().toString(); + IASTFunctionDefinition getter = FunctionFactory.createGetter(varName, simpleDeclaration); + getter.setParent(unit); + return new GetterSetterInsertEditProvider(getter); + } + + public GetterSetterInsertEditProvider createSetterInserter(IASTSimpleDeclaration simpleDeclaration) { + String varName = simpleDeclaration.getDeclarators()[0].getName().toString(); + IASTFunctionDefinition setter = FunctionFactory.createSetter(varName, simpleDeclaration); + setter.setParent(unit); + return new GetterSetterInsertEditProvider(setter); + } + + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + public boolean hasChildren(Object element) { + if (element instanceof FieldWrapper) { + FieldWrapper wrapper = (FieldWrapper) element; + + return wrapper.missingGetterOrSetter(); + } + return false; + } + + public Object[] getElements(Object inputElement) { + + return getWrappedFields().toArray(); + } + + public void dispose() { + // TODO Auto-generated method stub + } + + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // TODO Auto-generated method stub + } + + public void setUnit(IASTTranslationUnit unit) { + this.unit = unit; + } + + private ArrayList getWrappedFields() { + ArrayList wrappedFields = new ArrayList(); + for(IASTSimpleDeclaration currentField : existingFields){ + FieldWrapper wrapper = new FieldWrapper(); + wrapper.field = currentField; + wrapper.getter = getGetterForField(currentField); + wrapper.setter = getSetterForField(currentField); + if(wrapper.missingGetterOrSetter()){ + wrappedFields.add(wrapper); + } + } + return wrappedFields; + } + + private FunctionWrapper getGetterForField(IASTSimpleDeclaration currentField) { + FunctionWrapper wrapper = new FunctionWrapper(); + String trimmedName = NameHelper.trimFieldName(currentField.getDeclarators()[0].getName().toString()); + String getterName = "get" + NameHelper.makeFirstCharUpper(trimmedName); //$NON-NLS-1$ + + setFunctionToWrapper(wrapper, getterName); + + return wrapper; + } + + private FunctionWrapper getSetterForField(IASTSimpleDeclaration currentField) { + FunctionWrapper wrapper = new FunctionWrapper(); + String trimmedName = NameHelper.trimFieldName(currentField.getDeclarators()[0].getName().toString()); + String setterName = "set" + NameHelper.makeFirstCharUpper(trimmedName); //$NON-NLS-1$ + + setFunctionToWrapper(wrapper, setterName); + + return wrapper; + } + private void setFunctionToWrapper(FunctionWrapper wrapper, String getterName) { + for(IASTFunctionDefinition currentDefinition : existingFunctionDefinitions){ + if(currentDefinition.getDeclarator().getName().toString().endsWith(getterName)){ + wrapper.functionDefinition = currentDefinition; + } + } + + for(IASTSimpleDeclaration currentDeclaration : existingFunctionDeclarations){ + if(currentDeclaration.getDeclarators()[0].getName().toString().endsWith(getterName)){ + wrapper.functionDeclaration = currentDeclaration; + } + } + } + + + protected class FieldWrapper{ + protected IASTSimpleDeclaration field; + protected FunctionWrapper getter; + protected FunctionWrapper setter; + + @Override + public String toString(){ + return field.getDeclarators()[0].getName().toString(); + } + + public boolean missingGetterOrSetter() { + return !getter.exists() || !setter.exists(); + } + } + + protected class FunctionWrapper{ + protected IASTSimpleDeclaration functionDeclaration; + protected IASTFunctionDefinition functionDefinition; + + public boolean exists() { + + return functionDeclaration != null || functionDefinition != null; + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java new file mode 100644 index 00000000000..444f2f17c4b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GetterSetterInsertEditProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; + + +public class GetterSetterInsertEditProvider { + + private IASTFunctionDefinition function; + + public GetterSetterInsertEditProvider(IASTFunctionDefinition function){ + this.function = function; + } + + @Override + public String toString(){ + return function.getDeclarator().getName().toString(); + } + + public IASTFunctionDefinition getFunction() { + return function; + } +} 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 new file mode 100644 index 00000000000..b1bf3da98fc --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/Messages.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * 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.gettersandsetters; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.cdt.hsrrefactoring.generategettersandsetters.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String GenerateGettersAndSettersRefactoring_Insert; + public static String GettersAndSetters_Name; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} 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 new file mode 100644 index 00000000000..abb369946b0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/messages.properties @@ -0,0 +1,2 @@ +GettersAndSetters_Name=Generate Getters and Setters +GenerateGettersAndSettersRefactoring_Insert=Insert diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java index b6708d16a1a..73173b249f1 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/utils/NameHelper.java @@ -15,7 +15,11 @@ import java.util.regex.Pattern; import org.eclipse.core.resources.IFile; +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.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; @@ -64,4 +68,67 @@ public class NameHelper { qname.addName(declaratorName); return qname; } + + + public static IASTFunctionDefinition getAncestorFunctionDefinition(IASTName startNode) { + return (IASTFunctionDefinition) getAncestorDefinition(startNode, IASTFunctionDefinition.class); + } + + public static IASTSimpleDeclaration getAncestorFunctionDeclaration(IASTName startNode) { + return (IASTSimpleDeclaration) getAncestorDefinition(startNode, IASTSimpleDeclaration.class); + } + + public static ICPPASTCompositeTypeSpecifier getAncestorClassDefinition(IASTName startNode) { + return (ICPPASTCompositeTypeSpecifier) getAncestorDefinition(startNode, ICPPASTCompositeTypeSpecifier.class); + } + + + public static IASTNode getAncestorDefinition(IASTName startNode, Class type) { + + IASTNode node = startNode; + + while(node != null ){ + if(type.isInstance(node)) { + return node; + } + node = node.getParent(); + } + + return null; + } + + public static String trimFieldName(String fieldName){ + char[] letters = fieldName.toCharArray(); + int start = 0; + int end = letters.length - 1; + try{ + while(!Character.isLetter(letters[start]) && start < end) { + ++start; + } + + if(Character.isLowerCase(letters[start])){ + if(!Character.isLetter(letters[start + 1])){ + start+= 2; + } + else if (Character.isUpperCase(letters[start + 1])){ + start += 1; + } + } + + while((!Character.isLetter(letters[end]) && !Character.isDigit(letters[end])) && start < end) { + --end; + } + }catch(IndexOutOfBoundsException e){} + + return new String(letters, start, end - start + 1); + + } + + public static String makeFirstCharUpper(String name) { + if(Character.isLowerCase(name.charAt(0))){ + name = Character.toUpperCase(name.charAt(0)) + name.substring(1); + } + return name; + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java index 8fdad457994..4c5e7f1f188 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/CdtActionConstants.java @@ -260,6 +260,12 @@ public class CdtActionConstants { */ public static final String IMPLEMENT_METHOD= "org.eclipse.cdt.ui.actions.ImplementMethod"; //$NON-NLS-1$ + /** + * Refactor menu: name of standard Generate Getters and Setters global action + * (value "org.eclipse.cdt.ui.actions.GettersAndSetters"). + */ + public static final String GETTERS_AND_SETTERS= "org.eclipse.cdt.ui.actions.GettersAndSetters"; //$NON-NLS-1$ + /** * Refactor menu: name of standard Introduce Parameter global action * (value "org.eclipse.cdt.ui.actions.IntroduceParameter"). diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java index 807fff139f4..c13458f37f2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/CRefactoringActionGroup.java @@ -116,6 +116,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh private RefactoringAction fExtractFunctionAction; private RefactoringAction fHideMethodAction; private RefactoringAction fImplementMethodAction; + private RefactoringAction fGettersAndSettersAction; private IWorkbenchSite fSite; private List fAllActions= new ArrayList(); @@ -164,6 +165,10 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh fImplementMethodAction = new ImplementMethodAction(); fImplementMethodAction.setActionDefinitionId(ICEditorActionDefinitionIds.IMPLEMENT_METHOD); fAllActions.add(fImplementMethodAction); + + fGettersAndSettersAction = new GettersAndSettersAction(); + fGettersAndSettersAction.setActionDefinitionId(ICEditorActionDefinitionIds.GETTERS_AND_SETTERS); + fAllActions.add(fGettersAndSettersAction); } public void setWorkbenchSite(IWorkbenchSite site) { @@ -202,6 +207,7 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh setActionHandler(actionBar, CdtActionConstants.EXTRACT_METHOD, fExtractFunctionAction); setActionHandler(actionBar, CdtActionConstants.HIDE_METHOD, fHideMethodAction); setActionHandler(actionBar, CdtActionConstants.IMPLEMENT_METHOD, fImplementMethodAction); + setActionHandler(actionBar, CdtActionConstants.GETTERS_AND_SETTERS, fGettersAndSettersAction); } private void setActionHandler(IActionBars actionBar, String id, RefactoringAction action) { @@ -232,12 +238,12 @@ public class CRefactoringActionGroup extends ActionGroup implements ISelectionCh addAction(refactorSubmenu, fExtractConstantAction); addAction(refactorSubmenu, fExtractFunctionAction); addAction(refactorSubmenu, fHideMethodAction); - addAction(refactorSubmenu, fImplementMethodAction); - refactorSubmenu.add(new Separator(GROUP_REORG2)); refactorSubmenu.add(new Separator(GROUP_TYPE)); refactorSubmenu.add(new Separator(GROUP_TYPE2)); refactorSubmenu.add(new Separator(GROUP_CODING2)); + addAction(refactorSubmenu, fImplementMethodAction); + addAction(refactorSubmenu, fGettersAndSettersAction); refactorSubmenu.add(new Separator(GROUP_TYPE3)); menu.appendToGroup(fGroupName, refactorSubmenu); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/GettersAndSettersAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/GettersAndSettersAction.java new file mode 100644 index 00000000000..9db220e93b2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/GettersAndSettersAction.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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.ui.refactoring.actions; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.window.IShellProvider; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IField; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.IWorkingCopy; + +import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GenerateGettersAndSettersRefactoringRunner; + +/** + * Launches a getter and setter source code generation. + */ +public class GettersAndSettersAction extends RefactoringAction { + + public GettersAndSettersAction() { + super(Messages.GettersAndSetters_label); + } + + @Override + public void run(IShellProvider shellProvider, ICElement elem) { + new GenerateGettersAndSettersRefactoringRunner(null, null, elem, shellProvider).run(); + } + + @Override + public void run(IShellProvider shellProvider, IWorkingCopy wc, ITextSelection s) { + IResource res= wc.getResource(); + if (res instanceof IFile) { + new GenerateGettersAndSettersRefactoringRunner((IFile) res, s, null, shellProvider).run(); + } + } + + @Override + public void updateSelection(ICElement elem) { + super.updateSelection(elem); + if (elem instanceof IField == false + || elem instanceof ISourceReference == false + || ((ISourceReference) elem).getTranslationUnit().getResource() instanceof IFile == false) { + setEnabled(false); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java index c90df502eaf..ffc21b54597 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/Messages.java @@ -20,6 +20,7 @@ public class Messages extends NLS { public static String ExtractFunctionAction_label; public static String HideMethodAction_label; public static String ImplementMethodAction_label; + public static String GettersAndSetters_label; static { // initialize resource bundle diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties index a122e389716..52d03bcbb77 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/refactoring/actions/messages.properties @@ -11,6 +11,7 @@ CRefactoringActionGroup_menu=Refactor CRenameAction_label=Rename... ExtractConstantAction_label=Extract Constant... +GettersAndSetters_label=Generate Getters and Setters... ImplementMethodAction_label=Implement Method... (work in progress) HideMethodAction_label=Hide Member Function... (work in progress) ExtractFunctionAction_label=Extract Function... (work in progress)