1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 07:05:24 +02:00

Bug 352258 - Generate Getters and Setters can generate code containing

reserved keywords.
This commit is contained in:
Sergey Prigogin 2011-12-28 18:52:49 -08:00
parent b37a0fc605
commit 060afa174d
14 changed files with 726 additions and 523 deletions

View file

@ -487,14 +487,14 @@ public:
return name;
}
int getSystemId() const {
return systemId;
}
void setName(char* name) {
this->name = name;
}
int getSystemId() const {
return systemId;
}
void setSystemId(int systemId) {
this->systemId = systemId;
}
@ -563,14 +563,14 @@ public:
return i;
}
bool isOk() const {
return ok;
}
void setI(int i) {
this->i = i;
}
bool isOk() const {
return ok;
}
void setOk(bool ok) {
this->ok = ok;
}
@ -1425,3 +1425,36 @@ void Test::setTestField(int testField) {
//@component_a/implementation/Test.cpp
//=
//!Bug 352258 - Avoiding reserved names
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
//@.config
filename=A.h
getters=mClass
setters=mClass
//@A.h
#ifndef A_H_
#define A_H_
class getClass {
private:
int /*$*/mClass/*$$*/;
};
#endif /* A_H_ */
//=
#ifndef A_H_
#define A_H_
class getClass {
private:
int mClass;
public:
int getClass1() const {
return mClass;
}
void setClass(int _class) {
mClass = _class;
}
};
#endif /* A_H_ */

View file

@ -13,9 +13,7 @@
******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.gettersandsetters;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import org.eclipse.core.resources.IFile;
@ -23,12 +21,12 @@ 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.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTest;
import org.eclipse.cdt.ui.tests.refactoring.TestSourceFile;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GenerateGettersAndSettersRefactoring;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterContext;
@ -38,11 +36,11 @@ import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterCon
public class GenerateGettersAndSettersTest extends RefactoringTest {
protected boolean fatalError;
private int warnings;
private List<String> selectedGetters;
private List<String> selectedSetters;
private int infos;
private String[] selectedGetters;
private String[] selectedSetters;
private GenerateGettersAndSettersRefactoring refactoring;
private boolean definitionSeparate;
private int infos;
/**
* @param name
@ -88,17 +86,11 @@ public class GenerateGettersAndSettersTest extends RefactoringTest {
private void selectFields() {
GetterSetterContext 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));
}
for (String name : selectedGetters) {
context.selectAccessorForField(name, AccessorKind.GETTER);
}
for (String name : selectedSetters) {
context.selectAccessorForField(name, AccessorKind.SETTER);
}
}
@ -111,13 +103,7 @@ public class GenerateGettersAndSettersTest extends RefactoringTest {
String setters = refactoringProperties.getProperty("setters", ""); //$NON-NLS-1$ //$NON-NLS-2$
definitionSeparate = Boolean.valueOf(refactoringProperties.getProperty("definitionSeparate", "false"));
selectedGetters = new ArrayList<String>();
for (String getterName : getters.split(",")) { //$NON-NLS-1$
selectedGetters.add(getterName);
}
selectedSetters = new ArrayList<String>();
for (String setterName : setters.split(",")) { //$NON-NLS-1$
selectedSetters.add(setterName);
}
selectedGetters = getters.split(",");
selectedSetters = setters.split(",");
}
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2011 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import com.ibm.icu.text.Collator;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
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.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
public class AccessorDescriptor implements Comparable<AccessorDescriptor> {
public enum AccessorKind {
GETTER,
SETTER;
}
private static final Collator collator = Collator.getInstance();
private final AccessorKind kind;
private final String accessorName;
private final IASTName fieldName;
private AccessorFactory accessorFactory;
private IASTSimpleDeclaration accessorDeclaration;
private IASTSimpleDeclaration existingAccessorDeclaration;
private IASTFunctionDefinition existingAccessorDefinition;
public AccessorDescriptor(AccessorKind kind, String accessorName, FieldDescriptor fieldDescriptor) {
GetterSetterContext context = fieldDescriptor.getContext();
this.kind = kind;
this.accessorName = accessorName;
this.fieldName = fieldDescriptor.getFieldName();
if (accessorName != null) {
this.accessorFactory = AccessorFactory.createFactory(kind, fieldName,
fieldDescriptor.getFieldDeclaration(), accessorName);
this.accessorDeclaration = accessorFactory.createDeclaration();
for (IASTFunctionDefinition currentDefinition : context.existingFunctionDefinitions) {
if (currentDefinition.getDeclarator().getName().toString().equals(accessorName)) {
existingAccessorDefinition = currentDefinition;
}
}
for (IASTSimpleDeclaration currentDeclaration : context.existingFunctionDeclarations) {
if (GetterSetterContext.getDeclarationName(currentDeclaration).toString().equals(accessorName)) {
existingAccessorDeclaration = currentDeclaration;
}
}
}
}
boolean canBeGenerated() {
return accessorName != null && existingAccessorDeclaration == null && existingAccessorDefinition == null;
}
public AccessorKind getKind() {
return kind;
}
public IASTName getFieldName() {
return fieldName;
}
public int compareTo(AccessorDescriptor other) {
int c = collator.compare(fieldName.toString(), other.fieldName.toString());
if (c != 0)
return c;
return kind.ordinal() - other.kind.ordinal();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof AccessorDescriptor))
return false;
AccessorDescriptor other = (AccessorDescriptor) obj;
return fieldName == other.fieldName && kind == other.kind;
}
@Override
public String toString() {
return accessorName;
}
public IASTSimpleDeclaration getAccessorDeclaration() {
return accessorDeclaration;
}
public IASTFunctionDefinition getAccessorDefinition(boolean qualifedName) {
ICPPASTQualifiedName qname;
if (qualifedName) {
qname = getClassName();
} else {
qname = null;
}
return accessorFactory.createDefinition(qname);
}
private ICPPASTQualifiedName getClassName() {
IASTNode node = fieldName.getParent();
while (!(node instanceof IASTCompositeTypeSpecifier)) {
node = node.getParent();
}
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node;
CPPASTQualifiedName qname = new CPPASTQualifiedName();
qname.addName(comp.getName().copy(CopyStyle.withLocations));
return qname;
}
}

View file

@ -0,0 +1,274 @@
/*******************************************************************************
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
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.core.dom.ast.cpp.ICPPASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTPointer;
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.CPPASTDeclarator;
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.CPPASTPointer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReferenceOperator;
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.core.dom.parser.cpp.CPPASTSimpleDeclaration;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind;
public abstract class AccessorFactory {
protected final IASTName fieldName;
protected final IASTSimpleDeclaration fieldDeclaration;
protected final String accessorName;
protected boolean passByReference;
public static AccessorFactory createFactory(AccessorKind kind, IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration, String accessorName) {
if (kind == AccessorKind.GETTER) {
return new GetterFactory(fieldName, fieldDeclaration, accessorName);
} else {
return new SetterFactory(fieldName, fieldDeclaration, accessorName);
}
}
protected AccessorFactory(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration,
String accessorName) {
this.fieldName = fieldName;
this.fieldDeclaration = fieldDeclaration;
this.accessorName = accessorName;
// IType type = CPPVisitor.createType(fieldDeclaration.getDeclSpecifier());
// passByReference = TypeHelper.shouldBePassedByReference(type, fieldDeclaration.getTranslationUnit());
}
/**
* Creates an accessor declaration.
*/
public abstract IASTSimpleDeclaration createDeclaration();
/**
* Creates an accessor definition.
*
* @param className qualified name of the class containing the accessor
*/
public abstract IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className);
protected IASTDeclSpecifier getParamOrReturnDeclSpecifier() {
IASTDeclSpecifier declSpec = fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations);
if (passByReference || fieldDeclaration.getDeclarators()[0] instanceof IASTArrayDeclarator) {
declSpec.setConst(true);
}
return declSpec;
}
private static class GetterFactory extends AccessorFactory {
GetterFactory(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration, String getterName) {
super(fieldName, fieldDeclaration, getterName);
}
@Override
public IASTSimpleDeclaration createDeclaration() {
IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
getter.addDeclarator(getGetterDeclarator(null));
return getter;
}
@Override
public IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className) {
IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
IASTDeclarator getterDeclarator = getGetterDeclarator(className);
// IASTFunctionDefinition expects the outermost IASTFunctionDeclarator in declarator hierarchy
while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
getterDeclarator = getterDeclarator.getNestedDeclarator();
}
getter.setDeclarator((IASTFunctionDeclarator) getterDeclarator);
getter.setBody(getGetterBody());
return getter;
}
private CPPASTCompoundStatement getGetterBody() {
CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
CPPASTReturnStatement returnStatement = new CPPASTReturnStatement();
CPPASTIdExpression idExpr = new CPPASTIdExpression();
CPPASTName returnVal = new CPPASTName();
returnVal.setName(fieldName.toCharArray());
idExpr.setName(returnVal);
returnStatement.setReturnValue(idExpr);
compound.addStatement(returnStatement);
return compound;
}
private IASTDeclarator getGetterDeclarator(ICPPASTQualifiedName qualifiedName) {
CPPASTName getterName = new CPPASTName();
getterName.setName(accessorName.toCharArray());
// Copy declarator hierarchy
IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
if (topDeclarator instanceof IASTArrayDeclarator) {
boolean isCpp = topDeclarator instanceof ICPPASTArrayDeclarator;
IASTDeclarator decl = isCpp ? new CPPASTDeclarator() : new CASTDeclarator();
decl.setName(topDeclarator.getName());
decl.setNestedDeclarator(topDeclarator.getNestedDeclarator());
decl.addPointerOperator(isCpp ? new CPPASTPointer() : new CASTPointer());
for (IASTPointerOperator pointer : topDeclarator.getPointerOperators()) {
decl.addPointerOperator(pointer);
}
topDeclarator = decl;
}
// Find the innermost declarator in hierarchy
IASTDeclarator innermost = topDeclarator;
while (innermost.getNestedDeclarator() != null) {
innermost = innermost.getNestedDeclarator();
}
// Create a new innermost function declarator based on the field declarator
CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator();
functionDeclarator.setConst(true);
if (qualifiedName != null) {
qualifiedName.addName(getterName);
functionDeclarator.setName(qualifiedName);
} else {
functionDeclarator.setName(getterName);
}
for (IASTPointerOperator pointer : innermost.getPointerOperators()){
functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
}
if (passByReference) {
functionDeclarator.addPointerOperator(new CPPASTReferenceOperator(false));
}
// Replace the innermost with functionDeclarator and return the whole declarator tree
if (innermost == topDeclarator) {
// No tree
return functionDeclarator;
} else {
IASTDeclarator parent = (IASTDeclarator) innermost.getParent();
parent.setNestedDeclarator(functionDeclarator);
return topDeclarator;
}
}
}
private static class SetterFactory extends AccessorFactory {
SetterFactory(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration, String setterName) {
super(fieldName, fieldDeclaration, setterName);
}
@Override
public IASTSimpleDeclaration createDeclaration() {
IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration();
setter.setDeclSpecifier(getVoidDeclSpec());
setter.addDeclarator(getSetterDeclarator(null));
return setter;
}
@Override
public IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className) {
IASTFunctionDefinition setter = new CPPASTFunctionDefinition();
setter.setDeclSpecifier(getVoidDeclSpec());
setter.setDeclarator(getSetterDeclarator(className));
setter.setBody(getSetterBody());
return setter;
}
private CPPASTCompoundStatement getSetterBody() {
CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
CPPASTExpressionStatement exprStmt = new CPPASTExpressionStatement();
CPPASTBinaryExpression binExpr = new CPPASTBinaryExpression();
IASTDeclarator innerDeclarator = fieldDeclaration.getDeclarators()[0];
while (innerDeclarator.getNestedDeclarator() != null) {
innerDeclarator = innerDeclarator.getNestedDeclarator();
}
IASTName fieldName = innerDeclarator.getName();
CPPASTName parameterName = getSetterParameterName();
if (Arrays.equals(fieldName.getSimpleID(), parameterName.getSimpleID())) {
CPPASTFieldReference fieldRef = new CPPASTFieldReference();
CPPASTLiteralExpression litExpr = new CPPASTLiteralExpression();
litExpr.setValue(Keywords.cTHIS);
fieldRef.setFieldOwner(litExpr);
fieldRef.setIsPointerDereference(true);
fieldRef.setFieldName(fieldName.copy(CopyStyle.withLocations));
binExpr.setOperand1(fieldRef);
} else {
CPPASTIdExpression idExpr = new CPPASTIdExpression(fieldName.copy(CopyStyle.withLocations));
binExpr.setOperand1(idExpr);
}
binExpr.setOperator(IASTBinaryExpression.op_assign);
CPPASTIdExpression idExpr = new CPPASTIdExpression(parameterName);
binExpr.setOperand2(idExpr);
exprStmt.setExpression(binExpr);
compound.addStatement(exprStmt);
return compound;
}
private CPPASTFunctionDeclarator getSetterDeclarator(ICPPASTQualifiedName qualifiedName) {
CPPASTName setterName = new CPPASTName();
setterName.setName(accessorName.toCharArray());
CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
if (qualifiedName != null) {
qualifiedName.addName(setterName);
declarator.setName(qualifiedName);
} else {
declarator.setName(setterName);
}
CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
IASTDeclarator parameterDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
parameterDeclarator.setName(getSetterParameterName());
if (passByReference) {
parameterDeclarator.addPointerOperator(new CPPASTReferenceOperator(false));
}
parameterDeclaration.setDeclarator(parameterDeclarator);
parameterDeclaration.setDeclSpecifier(getParamOrReturnDeclSpecifier());
declarator.addParameterDeclaration(parameterDeclaration.copy(CopyStyle.withLocations));
return declarator;
}
private CPPASTName getSetterParameterName() {
String parameterName = GetterSetterNameGenerator.generateSetterParameterName(fieldName);
return new CPPASTName(parameterName.toCharArray());
}
private static CPPASTSimpleDeclSpecifier getVoidDeclSpec() {
CPPASTSimpleDeclSpecifier declSpecifier = new CPPASTSimpleDeclSpecifier();
declSpecifier.setType(IASTSimpleDeclSpecifier.t_void);
return declSpecifier;
}
}
}

View file

@ -0,0 +1,121 @@
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
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.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind;
class FieldDescriptor {
private final IASTName fieldName;
private final IASTSimpleDeclaration fieldDeclaration;
private final AccessorDescriptor getter;
private final AccessorDescriptor setter;
private final AccessorDescriptor[] childNodes;
private final GetterSetterContext context;
FieldDescriptor(IASTSimpleDeclaration fieldDeclaration, GetterSetterContext context) {
this.fieldName = GetterSetterContext.getDeclarationName(fieldDeclaration);
this.fieldDeclaration = fieldDeclaration;
this.context = context;
Set<String> namesToAvoid = getNamesToAvoid();
String name = GetterSetterNameGenerator.generateGetterName(fieldName, namesToAvoid);
this.getter = new AccessorDescriptor(AccessorKind.GETTER, name, this);
name = GetterSetterNameGenerator.generateSetterName(fieldName, namesToAvoid);
if (!isAssignable(fieldDeclaration))
name = null;
this.setter = new AccessorDescriptor(AccessorKind.SETTER, name, this);
List<AccessorDescriptor> children = new ArrayList<AccessorDescriptor>(2);
if (getter.canBeGenerated()) {
children.add(getter);
}
if (setter.canBeGenerated()) {
children.add(setter);
}
childNodes = children.toArray(new AccessorDescriptor[children.size()]);
}
private Set<String> getNamesToAvoid() {
Set<String> namesToAvoid = new HashSet<String>();
// Add field names.
for (IASTSimpleDeclaration fieldDeclaration : context.existingFields) {
namesToAvoid.add(String.valueOf(GetterSetterContext.getDeclarationName(fieldDeclaration).getSimpleID()));
}
// Add constructor name.
if (!context.existingFields.isEmpty()) {
IASTNode node = context.existingFields.get(0).getParent();
while (!(node instanceof IASTCompositeTypeSpecifier)) {
node = node.getParent();
}
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node;
namesToAvoid.add(String.valueOf(comp.getName().getLastName().getSimpleID()));
}
return namesToAvoid;
}
private static boolean isAssignable(IASTSimpleDeclaration declaration) {
IASTName name = GetterSetterContext.getDeclarationName(declaration);
IBinding binding = name.resolveBinding();
if (!(binding instanceof ICPPField))
return false;
ICPPField field = (ICPPField) binding;
IType type = field.getType();
type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF);
if (type instanceof IArrayType || type instanceof ICPPReferenceType)
return false;
if (type instanceof IPointerType && ((IPointerType) type).isConst())
return false;
if (type instanceof IQualifierType && ((IQualifierType) type).isConst())
return false;
return true;
}
@Override
public String toString() {
return fieldName.toString();
}
AccessorDescriptor[] getChildNodes() {
return childNodes;
}
boolean missingGetterOrSetter() {
return getter.canBeGenerated() || setter.canBeGenerated();
}
public GetterSetterContext getContext() {
return context;
}
public IASTName getFieldName() {
return fieldName;
}
public IASTSimpleDeclaration getFieldDeclaration() {
return fieldDeclaration;
}
public AccessorDescriptor getGetter() {
return getter;
}
public AccessorDescriptor getSetter() {
return setter;
}
}

View file

@ -1,196 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
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.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.parser.Keywords;
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.core.dom.parser.cpp.CPPASTSimpleDeclaration;
public class FunctionFactory {
public static IASTFunctionDefinition createGetterDefinition(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations));
IASTDeclarator getterDeclarator = getGetterDeclarator(fieldName, fieldDeclaration, name);
// IASTFunctionDefinition. expects the outermost IASTFunctionDeclarator in declarator hierarchy
while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
getterDeclarator = getterDeclarator.getNestedDeclarator();
}
getter.setDeclarator((IASTFunctionDeclarator) getterDeclarator);
getter.setBody(getGetterBody(fieldName));
return getter;
}
private static CPPASTCompoundStatement getGetterBody(IASTName fieldName) {
CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
CPPASTReturnStatement returnStatement = new CPPASTReturnStatement();
CPPASTIdExpression idExpr = new CPPASTIdExpression();
CPPASTName returnVal = new CPPASTName();
returnVal.setName(fieldName.toCharArray());
idExpr.setName(returnVal);
returnStatement.setReturnValue(idExpr);
compound.addStatement(returnStatement);
return compound;
}
private static IASTDeclarator getGetterDeclarator(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
CPPASTName getterName = new CPPASTName();
getterName.setName(GetterSetterNameGenerator.generateGetterName(fieldName).toCharArray());
// copy declarator hierarchy
IASTDeclarator topDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
// find the innermost declarator in hierarchy
IASTDeclarator innermost = topDeclarator;
while (innermost.getNestedDeclarator() != null) {
innermost = innermost.getNestedDeclarator();
}
// create a new innermost function declarator basing on the field declarator
CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator();
functionDeclarator.setConst(true);
if (name != null) {
name.addName(getterName);
functionDeclarator.setName(name);
} else {
functionDeclarator.setName(getterName);
}
for (IASTPointerOperator pointer : innermost.getPointerOperators()){
functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
}
// replace innermost with functionDeclarator and return the whole declarator tree
if (innermost == topDeclarator) {
// no tree
return functionDeclarator;
} else {
IASTDeclarator parent = (IASTDeclarator) innermost.getParent();
parent.setNestedDeclarator(functionDeclarator);
return topDeclarator;
}
}
public static IASTFunctionDefinition createSetterDefinition(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
IASTFunctionDefinition setter = new CPPASTFunctionDefinition();
setter.setDeclSpecifier(getVoidDeclSpec());
setter.setDeclarator(getSetterDeclarator(fieldName, fieldDeclaration, name));
setter.setBody(getSetterBody(fieldDeclaration));
return setter;
}
private static CPPASTCompoundStatement getSetterBody(IASTSimpleDeclaration fieldDeclaration) {
CPPASTCompoundStatement compound = new CPPASTCompoundStatement();
CPPASTExpressionStatement exprStmt = new CPPASTExpressionStatement();
CPPASTBinaryExpression binExpr = new CPPASTBinaryExpression();
IASTDeclarator innerDeclarator = fieldDeclaration.getDeclarators()[0];
while (innerDeclarator.getNestedDeclarator() != null) {
innerDeclarator = innerDeclarator.getNestedDeclarator();
}
IASTName fieldName = innerDeclarator.getName();
CPPASTName parameterName = getSetterParameterName(fieldName);
if (Arrays.equals(fieldName.getSimpleID(), parameterName.getSimpleID())) {
CPPASTFieldReference fieldRef = new CPPASTFieldReference();
CPPASTLiteralExpression litExpr = new CPPASTLiteralExpression();
litExpr.setValue(Keywords.cTHIS);
fieldRef.setFieldOwner(litExpr);
fieldRef.setIsPointerDereference(true);
fieldRef.setFieldName(fieldName.copy(CopyStyle.withLocations));
binExpr.setOperand1(fieldRef);
} else {
CPPASTIdExpression idExpr = new CPPASTIdExpression(fieldName.copy(CopyStyle.withLocations));
binExpr.setOperand1(idExpr);
}
binExpr.setOperator(IASTBinaryExpression.op_assign);
CPPASTIdExpression idExpr = new CPPASTIdExpression(parameterName);
binExpr.setOperand2(idExpr);
exprStmt.setExpression(binExpr);
compound.addStatement(exprStmt);
return compound;
}
private static CPPASTFunctionDeclarator getSetterDeclarator(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration, ICPPASTQualifiedName name) {
CPPASTName setterName = new CPPASTName();
setterName.setName(GetterSetterNameGenerator.generateSetterName(fieldName).toCharArray());
CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
if (name != null) {
name.addName(setterName);
declarator.setName(name);
} else {
declarator.setName(setterName);
}
CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
IASTDeclarator parameterDeclarator = fieldDeclaration.getDeclarators()[0].copy(CopyStyle.withLocations);
parameterDeclarator.setName(getSetterParameterName(fieldName));
parameterDeclaration.setDeclarator(parameterDeclarator);
parameterDeclaration.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(
CopyStyle.withLocations));
declarator.addParameterDeclaration(parameterDeclaration.copy(CopyStyle.withLocations));
return declarator;
}
private static CPPASTName getSetterParameterName(IASTName fieldName) {
String parameterName = GetterSetterNameGenerator.generateSetterParameterName(fieldName);
return new CPPASTName(parameterName.toCharArray());
}
private static CPPASTSimpleDeclSpecifier getVoidDeclSpec() {
CPPASTSimpleDeclSpecifier declSpecifier = new CPPASTSimpleDeclSpecifier();
declSpecifier.setType(IASTSimpleDeclSpecifier.t_void);
return declSpecifier;
}
public static IASTSimpleDeclaration createGetterDeclaration(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration) {
IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
getter.setDeclSpecifier(fieldDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations));
getter.addDeclarator(getGetterDeclarator(fieldName, fieldDeclaration, null));
return getter;
}
public static IASTSimpleDeclaration createSetterDeclaration(IASTName fieldName,
IASTSimpleDeclaration fieldDeclaration) {
IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration();
setter.setDeclSpecifier(getVoidDeclSpec());
setter.addDeclarator(getSetterDeclarator(fieldName, fieldDeclaration, null));
return setter;
}
}

View file

@ -33,8 +33,7 @@ import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.preferences.NameStylePreferencePage;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterContext.FieldWrapper;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterInsertEditProvider.AccessorKind;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind;
public class GenerateGettersAndSettersInputPage extends UserInputWizardPage implements IPreferenceChangeListener {
private GetterSetterContext context;
@ -42,7 +41,7 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
private GetterSetterLabelProvider labelProvider;
public GenerateGettersAndSettersInputPage(GetterSetterContext context) {
super(Messages.GettersAndSetters_Name);
super(Messages.GenerateGettersAndSettersInputPage_Name);
this.context = context;
IEclipsePreferences node = InstanceScope.INSTANCE.getNode(CUIPlugin.PLUGIN_ID);
// We are listening for changes in the Name Style preferences
@ -50,20 +49,19 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
}
public void createControl(Composite parent) {
setTitle(Messages.GenerateGettersAndSettersInputPage_Name);
setMessage(Messages.GenerateGettersAndSettersInputPage_Header);
Composite comp = new Composite(parent, SWT.NONE);
setTitle(Messages.GettersAndSetters_Name);
setMessage(Messages.GenerateGettersAndSettersInputPage_header);
comp.setLayout(new GridLayout(2, false));
createTree(comp);
GridData gd = new GridData(GridData.FILL_BOTH);
variableSelectionView.getTree().setLayoutData(gd);
Composite btComp = createButtonComposite(comp);
Composite buttonContainer = createButtonComposite(comp);
gd = new GridData();
gd.verticalAlignment = SWT.TOP;
btComp.setLayoutData(gd);
buttonContainer.setLayoutData(gd);
final Button definitionSeparate = new Button(comp, SWT.CHECK);
definitionSeparate.setText(Messages.GenerateGettersAndSettersInputPage_SeparateDefinition);
@ -133,7 +131,7 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
selectGetter.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
selectMethods(AccessorKind.GETTER);
selectAccessors(AccessorKind.GETTER);
}
});
@ -142,23 +140,23 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
selectSetter.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
selectMethods(AccessorKind.SETTER);
selectAccessors(AccessorKind.SETTER);
}
});
return btComp;
}
private void selectMethods(AccessorKind type) {
private void selectAccessors(AccessorKind kind) {
for (Object treeItem : context.getElements(null)) {
if (treeItem instanceof FieldWrapper) {
FieldWrapper field = (FieldWrapper) treeItem;
Object[] accessors = context.getChildren(field);
for (Object accessor : accessors) {
if (accessor instanceof GetterSetterInsertEditProvider) {
GetterSetterInsertEditProvider getSet = (GetterSetterInsertEditProvider) accessor;
if (getSet.getType() == type) {
variableSelectionView.setChecked(getSet, true);
if (treeItem instanceof FieldDescriptor) {
FieldDescriptor field = (FieldDescriptor) treeItem;
Object[] children = context.getChildren(field);
for (Object child : children) {
if (child instanceof AccessorDescriptor) {
AccessorDescriptor accessor = (AccessorDescriptor) child;
if (accessor.getKind() == kind) {
variableSelectionView.setChecked(accessor, true);
}
}
}
@ -174,11 +172,11 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
variableSelectionView.setLabelProvider(labelProvider);
variableSelectionView.setAutoExpandLevel(3);
variableSelectionView.setInput(""); //$NON-NLS-1$
variableSelectionView.setInput(context);
if (context.selectedName != null) {
String rawSignature = context.selectedName.getRawSignature();
for (Object obj : variableSelectionView.getVisibleExpandedElements()) {
if (obj instanceof FieldWrapper) {
if (obj instanceof FieldDescriptor) {
if (obj.toString().contains(rawSignature)) {
variableSelectionView.setSubtreeChecked(obj, true);
}
@ -196,13 +194,13 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
}
private void updateSelectedFunctions() {
context.selectedFunctions.clear();
for (Object currentElement : variableSelectionView.getCheckedElements()) {
if (currentElement instanceof GetterSetterInsertEditProvider) {
context.selectedFunctions.add((GetterSetterInsertEditProvider) currentElement);
context.selectedAccessors.clear();
for (Object element : variableSelectionView.getCheckedElements()) {
if (element instanceof AccessorDescriptor) {
context.selectedAccessors.add((AccessorDescriptor) element);
}
}
setPageComplete(!context.selectedFunctions.isEmpty());
setPageComplete(!context.selectedAccessors.isEmpty());
}
public void preferenceChange(PreferenceChangeEvent event) {
@ -211,15 +209,19 @@ public class GenerateGettersAndSettersInputPage extends UserInputWizardPage impl
}
if (GetterSetterNameGenerator.getGenerateGetterSettersPreferenceKeys().contains(event.getKey())) {
context.refresh();
context.recreateFieldDescriptors();
variableSelectionView.refresh();
variableSelectionView.setInput(context); // Set input to trigger node expansion.
for (Object element : context.selectedAccessors) {
variableSelectionView.setChecked(element, true);
}
}
}
@Override
public void dispose() {
super.dispose();
IEclipsePreferences node = InstanceScope.INSTANCE.getNode(CUIPlugin.PLUGIN_ID);
node.removePreferenceChangeListener(this);
super.dispose();
}
}

View file

@ -159,7 +159,7 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring2 {
if (compositeTypeSpecifier != null) {
findDeclarations(compositeTypeSpecifier);
} else {
initStatus.addFatalError(Messages.GenerateGettersAndSettersRefactoring_NoCassDefFound);
initStatus.addFatalError(Messages.GenerateGettersAndSettersRefactoring_NoClassDefFound);
}
}
@ -230,17 +230,17 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring2 {
throws CoreException, OperationCanceledException {
List<IASTNode> getterAndSetters = new ArrayList<IASTNode>();
List<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
for (GetterSetterInsertEditProvider currentProvider : context.selectedFunctions) {
for (AccessorDescriptor accessor : context.selectedAccessors) {
if (context.isDefinitionSeparate()) {
getterAndSetters.add(currentProvider.getFunctionDeclaration());
IASTFunctionDefinition functionDefinition = currentProvider.getFunctionDefinition(true);
getterAndSetters.add(accessor.getAccessorDeclaration());
IASTFunctionDefinition functionDefinition = accessor.getAccessorDefinition(true);
// Standalone definitions in a header file have to be declared inline.
if (definitionInsertLocation.getTranslationUnit().isHeaderUnit()) {
functionDefinition.getDeclSpecifier().setInline(true);
}
definitions.add(functionDefinition);
} else {
getterAndSetters.add(currentProvider.getFunctionDefinition(false));
getterAndSetters.add(accessor.getAccessorDefinition(false));
}
}
if (context.isDefinitionSeparate()) {

View file

@ -13,6 +13,7 @@
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
@ -24,43 +25,22 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterInsertEditProvider.AccessorKind;
import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind;
public class GetterSetterContext implements ITreeContentProvider {
public ArrayList<IASTSimpleDeclaration> existingFields = new ArrayList<IASTSimpleDeclaration>();
public ArrayList<IASTFunctionDefinition> existingFunctionDefinitions = new ArrayList<IASTFunctionDefinition>();
public ArrayList<IASTSimpleDeclaration> existingFunctionDeclarations = new ArrayList<IASTSimpleDeclaration>();
public SortedSet<GetterSetterInsertEditProvider> selectedFunctions = new TreeSet<GetterSetterInsertEditProvider>();
public IASTName selectedName;
private ArrayList<FieldWrapper> wrappedFields;
final List<IASTSimpleDeclaration> existingFields = new ArrayList<IASTSimpleDeclaration>();
final List<IASTFunctionDefinition> existingFunctionDefinitions = new ArrayList<IASTFunctionDefinition>();
final List<IASTSimpleDeclaration> existingFunctionDeclarations = new ArrayList<IASTSimpleDeclaration>();
final SortedSet<AccessorDescriptor> selectedAccessors = new TreeSet<AccessorDescriptor>();
IASTName selectedName;
private List<FieldDescriptor> fieldDescriptors;
private boolean definitionSeparate;
private static final Object[] NO_CHILDREN = {};
public Object[] getChildren(Object parentElement) {
ArrayList<GetterSetterInsertEditProvider> children = new ArrayList<GetterSetterInsertEditProvider>();
if (parentElement instanceof FieldWrapper) {
FieldWrapper wrapper = (FieldWrapper) parentElement;
if (wrapper.getChildNodes().isEmpty()) {
if (!wrapper.getter.exists()) {
wrapper.childNodes.add(createGetterInserter(wrapper.field));
}
if (!wrapper.setter.exists() && !wrapper.field.getDeclSpecifier().isConst()) {
wrapper.childNodes.add(createSetterInserter(wrapper.field));
}
}
children = wrapper.getChildNodes();
}
return children.toArray();
}
public GetterSetterInsertEditProvider createGetterInserter(IASTSimpleDeclaration simpleDeclaration) {
IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.GETTER);
}
public GetterSetterInsertEditProvider createSetterInserter(IASTSimpleDeclaration simpleDeclaration) {
IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.SETTER);
if (!(parentElement instanceof FieldDescriptor))
return NO_CHILDREN;
return ((FieldDescriptor) parentElement).getChildNodes();
}
public Object getParent(Object element) {
@ -68,36 +48,51 @@ public class GetterSetterContext implements ITreeContentProvider {
}
public boolean hasChildren(Object element) {
if (element instanceof FieldWrapper) {
FieldWrapper wrapper = (FieldWrapper) element;
return wrapper.missingGetterOrSetter();
if (element instanceof FieldDescriptor) {
FieldDescriptor descriptor = (FieldDescriptor) element;
return descriptor.missingGetterOrSetter();
}
return false;
}
public Object[] getElements(Object inputElement) {
return getWrappedFields().toArray();
return getFieldDescriptors().toArray();
}
public void refresh() {
// We only recreate the function declarations instead of recreating
// GetterSetterInsertEditProviders. That way, selectedFunctions is still valid.
// Also, the objects inside the TreeViewer are still the same, which is convenient because
// that way we don't need to save then restore the collapsed/expanded+checked/unchecked
// state of the TreeViewer.
for (FieldWrapper wrapper : wrappedFields) {
for (GetterSetterInsertEditProvider provider : wrapper.childNodes) {
provider.createFunctionDeclaration();
}
}
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
public void recreateFieldDescriptors() {
// Delete field descriptors so that they are recreated by the next getFieldDescriptors call.
fieldDescriptors = null;
SortedSet<AccessorDescriptor> oldSelected = new TreeSet<AccessorDescriptor>(selectedAccessors);
selectedAccessors.clear();
for (FieldDescriptor descriptor : getFieldDescriptors()) {
for (AccessorDescriptor accessor : descriptor.getChildNodes()) {
if (oldSelected.contains(accessor)) {
selectedAccessors.add(accessor);
}
}
}
}
public void selectAccessorForField(String name, AccessorKind kind) {
for (FieldDescriptor descriptor : getFieldDescriptors()) {
if (name.equals(String.valueOf(descriptor.getFieldName().getSimpleID()))) {
for (Object child : descriptor.getChildNodes()) {
AccessorDescriptor accessor = (AccessorDescriptor) child;
if (accessor.getKind() == kind) {
selectedAccessors.add(accessor);
break;
}
}
}
}
}
public boolean isDefinitionSeparate() {
return definitionSeparate;
}
@ -106,88 +101,24 @@ public class GetterSetterContext implements ITreeContentProvider {
this.definitionSeparate = definitionSeparate;
}
private ArrayList<FieldWrapper> getWrappedFields() {
if (wrappedFields == null) {
wrappedFields = new ArrayList<FieldWrapper>();
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);
private List<FieldDescriptor> getFieldDescriptors() {
if (fieldDescriptors == null) {
fieldDescriptors = new ArrayList<FieldDescriptor>();
for (IASTSimpleDeclaration field : existingFields) {
FieldDescriptor descriptor = new FieldDescriptor(field, this);
if (descriptor.missingGetterOrSetter()) {
fieldDescriptors.add(descriptor);
}
}
}
return wrappedFields;
return fieldDescriptors;
}
private FunctionWrapper getGetterForField(IASTSimpleDeclaration currentField) {
FunctionWrapper wrapper = new FunctionWrapper();
String name = GetterSetterNameGenerator.generateGetterName(getFieldDeclarationName(currentField));
setFunctionToWrapper(wrapper, name);
return wrapper;
}
private IASTName getFieldDeclarationName(IASTSimpleDeclaration fieldDeclaration) {
IASTDeclarator declarator = fieldDeclaration.getDeclarators()[0];
static IASTName getDeclarationName(IASTSimpleDeclaration declaration) {
IASTDeclarator declarator = declaration.getDeclarators()[0];
while (declarator.getNestedDeclarator() != null) {
declarator = declarator.getNestedDeclarator();
}
return declarator.getName();
}
private FunctionWrapper getSetterForField(IASTSimpleDeclaration currentField) {
FunctionWrapper wrapper = new FunctionWrapper();
String name = GetterSetterNameGenerator.generateSetterName(getFieldDeclarationName(currentField));
setFunctionToWrapper(wrapper, name);
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 (getFieldDeclarationName(currentDeclaration).toString().endsWith(getterName)) {
wrapper.functionDeclaration = currentDeclaration;
}
}
}
protected class FieldWrapper {
protected IASTSimpleDeclaration field;
protected FunctionWrapper getter;
protected FunctionWrapper setter;
protected ArrayList<GetterSetterInsertEditProvider> childNodes = new ArrayList<GetterSetterInsertEditProvider>(2);
@Override
public String toString() {
IASTDeclarator declarator = field.getDeclarators()[0];
while (declarator.getNestedDeclarator() != null) {
declarator = declarator.getNestedDeclarator();
}
return declarator.getName().toString();
}
public ArrayList<GetterSetterInsertEditProvider> getChildNodes() {
return childNodes;
}
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;
}
}
}

View file

@ -1,109 +0,0 @@
/*******************************************************************************
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Institute for Software - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
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.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
public class GetterSetterInsertEditProvider implements Comparable<GetterSetterInsertEditProvider> {
public enum AccessorKind {
GETTER,
SETTER;
}
private IASTSimpleDeclaration functionDeclaration;
private AccessorKind kind;
private IASTName fieldName;
private IASTSimpleDeclaration fieldDeclaration;
public GetterSetterInsertEditProvider(IASTName fieldName, IASTSimpleDeclaration fieldDeclaration,
AccessorKind kind) {
this.kind = kind;
this.fieldName = fieldName;
this.fieldDeclaration = fieldDeclaration;
createFunctionDeclaration();
}
public void createFunctionDeclaration() {
switch (this.kind) {
case GETTER:
this.functionDeclaration = FunctionFactory.createGetterDeclaration(fieldName, fieldDeclaration);
break;
case SETTER:
this.functionDeclaration = FunctionFactory.createSetterDeclaration(fieldName, fieldDeclaration);
break;
}
}
@Override
public String toString() {
IASTDeclarator declarator = functionDeclaration.getDeclarators()[0];
while (declarator.getNestedDeclarator() != null) {
declarator = declarator.getNestedDeclarator();
}
return declarator.getName().toString();
}
public IASTFunctionDefinition getFunctionDefinition(boolean qualifedName) {
IASTFunctionDefinition definition = null;
ICPPASTQualifiedName qname;
if (qualifedName) {
qname = getClassname();
} else {
qname = null;
}
switch (kind) {
case GETTER:
definition = FunctionFactory.createGetterDefinition(fieldName, fieldDeclaration, qname);
break;
case SETTER:
definition = FunctionFactory.createSetterDefinition(fieldName, fieldDeclaration, qname);
break;
}
return definition;
}
private ICPPASTQualifiedName getClassname() {
IASTNode node = fieldDeclaration.getParent();
while (!(node instanceof IASTCompositeTypeSpecifier)) {
node = node.getParent();
}
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node;
CPPASTQualifiedName qname = new CPPASTQualifiedName();
qname.addName(comp.getName().copy(CopyStyle.withLocations));
return qname;
}
public IASTSimpleDeclaration getFunctionDeclaration() {
return functionDeclaration;
}
public AccessorKind getType() {
return kind;
}
public int compareTo(GetterSetterInsertEditProvider o) {
return toString().compareTo(o.toString());
}
}

View file

@ -22,10 +22,9 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
* @author Emanuel Graf IFS
*/
public class GetterSetterLabelProvider extends LabelProvider {
@Override
public Image getImage(Object element) {
if (element instanceof GetterSetterInsertEditProvider) {
if (element instanceof AccessorDescriptor) {
return CElementImageProvider.getMethodImageDescriptor(ASTAccessVisibility.PUBLIC).createImage();
}
return null;

View file

@ -16,11 +16,12 @@ import java.util.Set;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.cdt.core.CConventions;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
@ -29,11 +30,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.util.NameComposer;
public class GetterSetterNameGenerator {
// Do not instantiate.
private GetterSetterNameGenerator() {
}
private static Set<String> generateGetterSettersPreferenceKeys = new HashSet<String>();
static {
generateGetterSettersPreferenceKeys.add(PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION);
@ -51,18 +47,30 @@ public class GetterSetterNameGenerator {
generateGetterSettersPreferenceKeys.add(PreferenceConstants.NAME_STYLE_VARIABLE_SUFFIX);
}
// Do not instantiate.
private GetterSetterNameGenerator() {
}
public static Set<String> getGenerateGetterSettersPreferenceKeys() {
return generateGetterSettersPreferenceKeys;
}
public static String generateGetterName(IASTName fieldName) {
/**
* Generates getter name for a given field name.
*
* @param fieldName the name of the field
* @param namesToAvoid the set of names to avoid
* @return the generated getter name, or <code>null</code> if a valid name could not be
* generated.
*/
public static String generateGetterName(IASTName fieldName, Set<String> namesToAvoid) {
IPreferencesService preferences = Platform.getPreferencesService();
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.NAME_STYLE_GETTER_CAPITALIZATION,
PreferenceConstants.NAME_STYLE_CAPITALIZATION_CAMEL_CASE, null);
String wordDelimiter = preferences.getString(CUIPlugin.PLUGIN_ID,
PreferenceConstants.NAME_STYLE_GETTER_WORD_DELIMITER, "", null); //$NON-NLS-1$
String prefix = isBooleanDecaratorName(fieldName) ?
String prefix = isBooleanDeclaratorName(fieldName) ?
preferences.getString(CUIPlugin.PLUGIN_ID,
PreferenceConstants.NAME_STYLE_GETTER_PREFIX_FOR_BOOLEAN, "is", null) : //$NON-NLS-1$
preferences.getString(CUIPlugin.PLUGIN_ID,
@ -71,10 +79,11 @@ public class GetterSetterNameGenerator {
PreferenceConstants.NAME_STYLE_GETTER_SUFFIX, "", null); //$NON-NLS-1$
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
String name = NameComposer.trimFieldName(fieldName.toString());
return composer.compose(name);
name = composer.compose(name);
return adjustName(name, namesToAvoid);
}
private static boolean isBooleanDecaratorName(IASTName name) {
private static boolean isBooleanDeclaratorName(IASTName name) {
if (IASTDeclarator.DECLARATOR_NAME.equals(name.getPropertyInParent())) {
IASTDeclarator declarator = (IASTDeclarator) name.getParent();
IType type = CPPVisitor.createType(declarator);
@ -85,7 +94,15 @@ public class GetterSetterNameGenerator {
return false;
}
public static String generateSetterName(IASTName fieldName) {
/**
* Generates setter name for a given field name.
*
* @param fieldName the name of the field
* @param namesToAvoid the set of names to avoid
* @return the generated setter name, or <code>null</code> if a valid name could not be
* generated.
*/
public static String generateSetterName(IASTName fieldName, Set<String> namesToAvoid) {
IPreferencesService preferences = Platform.getPreferencesService();
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.NAME_STYLE_SETTER_CAPITALIZATION,
@ -98,10 +115,11 @@ public class GetterSetterNameGenerator {
PreferenceConstants.NAME_STYLE_SETTER_SUFFIX, "", null); //$NON-NLS-1$
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
String name = NameComposer.trimFieldName(fieldName.toString());
return composer.compose(name);
name = composer.compose(name);
return adjustName(name, namesToAvoid);
}
public static String generateSetterParameterName(IASTName fieldName) {
public static String generateSetterParameterName(IASTName fieldName){
IPreferencesService preferences = Platform.getPreferencesService();
int capitalization = preferences.getInt(CUIPlugin.PLUGIN_ID,
PreferenceConstants.NAME_STYLE_VARIABLE_CAPITALIZATION,
@ -114,6 +132,28 @@ public class GetterSetterNameGenerator {
PreferenceConstants.NAME_STYLE_VARIABLE_SUFFIX, "", null); //$NON-NLS-1$
NameComposer composer = new NameComposer(capitalization, wordDelimiter, prefix, suffix);
String name = NameComposer.trimFieldName(fieldName.toString());
return composer.compose(name);
name = composer.compose(name);
if (!CConventions.validateIdentifier(name, GPPLanguage.getDefault()).isOK())
name = '_' + name;
return name;
}
/**
* Checks is the given name is valid and, if not, tries to adjust it by adding a numeric suffix
* to it.
*
* @param name the name to check and, possibly, adjust
* @param namesToAvoid the set of names to avoid
* @return the adjusted name, or <code>null</code> if a valid name could not be generated.
*/
private static String adjustName(String name, Set<String> namesToAvoid) {
String originalName = name;
for (int i = 1; i < 100; i++) {
if (!namesToAvoid.contains(name) && CConventions.validateIdentifier(name, GPPLanguage.getDefault()).isOK()) {
return name;
}
name = originalName + i;
}
return null;
}
}

View file

@ -15,17 +15,17 @@ import org.eclipse.osgi.util.NLS;
public final class Messages extends NLS {
public static String GenerateGettersAndSettersInputPage_DeselectAll;
public static String GenerateGettersAndSettersInputPage_header;
public static String GenerateGettersAndSettersInputPage_Header;
public static String GenerateGettersAndSettersInputPage_LinkDescription;
public static String GenerateGettersAndSettersInputPage_LinkTooltip;
public static String GenerateGettersAndSettersInputPage_Name;
public static String GenerateGettersAndSettersInputPage_SeparateDefinition;
public static String GenerateGettersAndSettersInputPage_SelectAll;
public static String GenerateGettersAndSettersInputPage_SelectGetters;
public static String GenerateGettersAndSettersInputPage_SelectSetters;
public static String GenerateGettersAndSettersInputPage_LinkDescription;
public static String GenerateGettersAndSettersInputPage_LinkTooltip;
public static String GenerateGettersAndSettersRefactoring_NoCassDefFound;
public static String GenerateGettersAndSettersRefactoring_NoClassDefFound;
public static String GenerateGettersAndSettersRefactoring_NoFields;
public static String GenerateGettersAndSettersRefactoring_NoImplFile;
public static String GettersAndSetters_Name;
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);

View file

@ -9,15 +9,15 @@
# Contributors:
# Institute for Software - initial API and implementation
###############################################################################
GettersAndSetters_Name=Generate getters and setters
GenerateGettersAndSettersInputPage_DeselectAll=Deselect All
GenerateGettersAndSettersInputPage_header=Select getters and setters to create:
GenerateGettersAndSettersInputPage_Header=Select getters and setters to create:
GenerateGettersAndSettersInputPage_LinkDescription=The names of getters and setters may be configured on the <a>Name Style</a> preference page.
GenerateGettersAndSettersInputPage_LinkTooltip=Show the name style preferences.
GenerateGettersAndSettersInputPage_Name=Generate getters and setters
GenerateGettersAndSettersInputPage_SeparateDefinition=Definition separate from declaration
GenerateGettersAndSettersInputPage_SelectAll=Select All
GenerateGettersAndSettersInputPage_SelectGetters=Select Getters
GenerateGettersAndSettersInputPage_SelectSetters=Select Setters
GenerateGettersAndSettersInputPage_LinkDescription=The names of getters and setters may be configured on the <a>Name Style</a> preference page.
GenerateGettersAndSettersInputPage_LinkTooltip=Show the name style preferences.
GenerateGettersAndSettersRefactoring_NoCassDefFound=No class definition found
GenerateGettersAndSettersRefactoring_NoClassDefFound=No class definition found
GenerateGettersAndSettersRefactoring_NoFields=The class does not contain any fields.
GenerateGettersAndSettersRefactoring_NoImplFile=No implementation file found. Inserting definition into the header file.