1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 05:15:43 +02:00

Bug 316083 - Generate getters and setters does not handle nested classes

in cpp definition

Change-Id: Id2926661984c7f436aee3cd98b5b5922c2474097
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/13843
This commit is contained in:
Marc-Andre Laperle 2013-06-15 20:55:30 -04:00
parent a58170e643
commit f4ed32d9b2
4 changed files with 70 additions and 64 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others * Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -9,6 +9,7 @@
* Contributors: * Contributors:
* Institute for Software - initial API and implementation * Institute for Software - initial API and implementation
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Marc-Andre Laperle (Ericsson)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.gettersandsetters; package org.eclipse.cdt.ui.tests.refactoring.gettersandsetters;
@ -1631,4 +1632,40 @@ public class GenerateGettersAndSettersTest extends RefactoringTestBase {
selectedSetters = new String[] { "a", "b" }; selectedSetters = new String[] { "a", "b" };
assertRefactoringSuccess(); assertRefactoringSuccess();
} }
//A.h
//namespace ns {
//class Test {
//class Foo {
// public:
// int /*$*/a/*$$*/;
// };
// };
//}
//====================
//namespace ns {
//class Test {
//class Foo {
// public:
// int a;
//
// int getA() const;
// };
// };
//}
//A.cpp
//#include "A.h"
//
//====================
//#include "A.h"
//
//int ns::Test::Foo::getA() const {
// return a;
//}
public void testNestedClasses_Bug316083() throws Exception {
definitionSeparate = true;
selectedGetters = new String[] {"a"};
assertRefactoringSuccess();
}
} }

View file

@ -1,27 +1,21 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2011, 2012 Google, Inc and others. * Copyright (c) 2011, 2013 Google, Inc and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Sergey Prigogin (Google) - initial API and implementation * Sergey Prigogin (Google) - initial API and implementation
* Marc-Andre Laperle (Ericsson)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters; package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
import com.ibm.icu.text.Collator; 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.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
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 class AccessorDescriptor implements Comparable<AccessorDescriptor> {
public enum AccessorKind { public enum AccessorKind {
@ -99,24 +93,7 @@ public class AccessorDescriptor implements Comparable<AccessorDescriptor> {
return accessorDeclaration; return accessorDeclaration;
} }
public IASTFunctionDefinition getAccessorDefinition(boolean qualifedName) { public IASTFunctionDefinition getAccessorDefinition(IASTName declaratorName) {
ICPPASTQualifiedName qname; return accessorFactory.createDefinition(declaratorName);
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;
return new CPPASTQualifiedName((ICPPASTName) comp.getName().copy(CopyStyle.withLocations));
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others * Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -9,6 +9,7 @@
* Contributors: * Contributors:
* Institute for Software - initial API and implementation * Institute for Software - initial API and implementation
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Marc-Andre Laperle (Ericsson)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters; package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
@ -27,7 +28,6 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.rewrite.TypeHelper; import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.Keywords;
@ -88,9 +88,9 @@ public abstract class AccessorFactory {
/** /**
* Creates an accessor definition. * Creates an accessor definition.
* *
* @param className qualified name of the class containing the accessor * @param declaratorName name to use for the declarator
*/ */
public abstract IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className); public abstract IASTFunctionDefinition createDefinition(IASTName declaratorName);
protected IASTDeclSpecifier getParamOrReturnDeclSpecifier() { protected IASTDeclSpecifier getParamOrReturnDeclSpecifier() {
IASTDeclSpecifier declSpec = declSpecifier.copy(CopyStyle.withLocations); IASTDeclSpecifier declSpec = declSpecifier.copy(CopyStyle.withLocations);
@ -109,16 +109,16 @@ public abstract class AccessorFactory {
public IASTSimpleDeclaration createDeclaration() { public IASTSimpleDeclaration createDeclaration() {
IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration(); IASTSimpleDeclaration getter = new CPPASTSimpleDeclaration();
getter.setDeclSpecifier(getParamOrReturnDeclSpecifier()); getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
getter.addDeclarator(getGetterDeclarator(null)); getter.addDeclarator(getGetterDeclarator(new CPPASTName(accessorName.toCharArray())));
return getter; return getter;
} }
@Override @Override
public IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className) { public IASTFunctionDefinition createDefinition(IASTName declaratorName) {
IASTFunctionDefinition getter = new CPPASTFunctionDefinition(); IASTFunctionDefinition getter = new CPPASTFunctionDefinition();
getter.setDeclSpecifier(getParamOrReturnDeclSpecifier()); getter.setDeclSpecifier(getParamOrReturnDeclSpecifier());
IASTDeclarator getterDeclarator = getGetterDeclarator(className); IASTDeclarator getterDeclarator = getGetterDeclarator(declaratorName);
// IASTFunctionDefinition expects the outermost IASTFunctionDeclarator in declarator hierarchy // IASTFunctionDefinition expects the outermost IASTFunctionDeclarator in declarator hierarchy
while (!(getterDeclarator instanceof IASTFunctionDeclarator)) { while (!(getterDeclarator instanceof IASTFunctionDeclarator)) {
getterDeclarator = getterDeclarator.getNestedDeclarator(); getterDeclarator = getterDeclarator.getNestedDeclarator();
@ -140,10 +140,7 @@ public abstract class AccessorFactory {
return compound; return compound;
} }
private IASTDeclarator getGetterDeclarator(ICPPASTQualifiedName qualifiedName) { private IASTDeclarator getGetterDeclarator(IASTName declaratorName) {
CPPASTName getterName = new CPPASTName();
getterName.setName(accessorName.toCharArray());
// Copy declarator hierarchy // Copy declarator hierarchy
IASTDeclarator topDeclarator = fieldDeclarator.copy(CopyStyle.withLocations); IASTDeclarator topDeclarator = fieldDeclarator.copy(CopyStyle.withLocations);
@ -167,12 +164,8 @@ public abstract class AccessorFactory {
// Create a new innermost function declarator based on the field declarator // Create a new innermost function declarator based on the field declarator
CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator(); CPPASTFunctionDeclarator functionDeclarator = new CPPASTFunctionDeclarator();
functionDeclarator.setConst(true); functionDeclarator.setConst(true);
if (qualifiedName != null) { functionDeclarator.setName(declaratorName);
qualifiedName.addName(getterName);
functionDeclarator.setName(qualifiedName);
} else {
functionDeclarator.setName(getterName);
}
for (IASTPointerOperator pointer : innermost.getPointerOperators()){ for (IASTPointerOperator pointer : innermost.getPointerOperators()){
functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations)); functionDeclarator.addPointerOperator(pointer.copy(CopyStyle.withLocations));
} }
@ -200,16 +193,16 @@ public abstract class AccessorFactory {
@Override @Override
public IASTSimpleDeclaration createDeclaration() { public IASTSimpleDeclaration createDeclaration() {
IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration(); IASTSimpleDeclaration setter = new CPPASTSimpleDeclaration();
setter.setDeclSpecifier(getVoidDeclSpec()); setter.setDeclSpecifier(getVoidDeclSpec());
setter.addDeclarator(getSetterDeclarator(null)); setter.addDeclarator(getSetterDeclarator(new CPPASTName(accessorName.toCharArray())));
return setter; return setter;
} }
@Override @Override
public IASTFunctionDefinition createDefinition(ICPPASTQualifiedName className) { public IASTFunctionDefinition createDefinition(IASTName declaratorName) {
IASTFunctionDefinition setter = new CPPASTFunctionDefinition(); IASTFunctionDefinition setter = new CPPASTFunctionDefinition();
setter.setDeclSpecifier(getVoidDeclSpec()); setter.setDeclSpecifier(getVoidDeclSpec());
setter.setDeclarator(getSetterDeclarator(className)); setter.setDeclarator(getSetterDeclarator(declaratorName));
setter.setBody(getSetterBody()); setter.setBody(getSetterBody());
return setter; return setter;
} }
@ -244,16 +237,9 @@ public abstract class AccessorFactory {
return compound; return compound;
} }
private CPPASTFunctionDeclarator getSetterDeclarator(ICPPASTQualifiedName qualifiedName) { private CPPASTFunctionDeclarator getSetterDeclarator(IASTName declaratorName) {
CPPASTName setterName = new CPPASTName();
setterName.setName(accessorName.toCharArray());
CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator(); CPPASTFunctionDeclarator declarator = new CPPASTFunctionDeclarator();
if (qualifiedName != null) { declarator.setName(declaratorName);
qualifiedName.addName(setterName);
declarator.setName(qualifiedName);
} else {
declarator.setName(setterName);
}
CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration(); CPPASTParameterDeclaration parameterDeclaration = new CPPASTParameterDeclaration();
IASTDeclarator parameterDeclarator = fieldDeclarator.copy(CopyStyle.withLocations); IASTDeclarator parameterDeclarator = fieldDeclarator.copy(CopyStyle.withLocations);
parameterDeclarator.setName(getSetterParameterName()); parameterDeclarator.setName(getSetterParameterName());

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2008, 2013 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others. * Rapperswil, University of applied sciences and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode; import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ContainerNode;
@ -53,6 +54,7 @@ import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
import org.eclipse.cdt.internal.ui.refactoring.implementmethod.InsertLocation; import org.eclipse.cdt.internal.ui.refactoring.implementmethod.InsertLocation;
import org.eclipse.cdt.internal.ui.refactoring.implementmethod.MethodDefinitionInsertLocationFinder; import org.eclipse.cdt.internal.ui.refactoring.implementmethod.MethodDefinitionInsertLocationFinder;
import org.eclipse.cdt.internal.ui.refactoring.utils.Checks; import org.eclipse.cdt.internal.ui.refactoring.utils.Checks;
import org.eclipse.cdt.internal.ui.refactoring.utils.NameHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
@ -224,24 +226,28 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
throws CoreException, OperationCanceledException { throws CoreException, OperationCanceledException {
List<IASTNode> getterAndSetters = new ArrayList<IASTNode>(); List<IASTNode> getterAndSetters = new ArrayList<IASTNode>();
List<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>(); List<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
ICPPASTCompositeTypeSpecifier classDefinition =
CPPVisitor.findAncestorWithType(context.existingFields.get(0), ICPPASTCompositeTypeSpecifier.class);
for (AccessorDescriptor accessor : context.selectedAccessors) { for (AccessorDescriptor accessor : context.selectedAccessors) {
IASTName accessorName = new CPPASTName(accessor.toString().toCharArray());
if (context.isDefinitionSeparate()) { if (context.isDefinitionSeparate()) {
getterAndSetters.add(accessor.getAccessorDeclaration()); getterAndSetters.add(accessor.getAccessorDeclaration());
IASTFunctionDefinition functionDefinition = accessor.getAccessorDefinition(true); IASTName declaratorName = NameHelper.createQualifiedNameFor(
accessorName, classDefinition.getTranslationUnit().getOriginatingTranslationUnit(), classDefinition.getFileLocation().getNodeOffset(),
definitionInsertLocation.getTranslationUnit(), definitionInsertLocation.getInsertPosition(), refactoringContext);
IASTFunctionDefinition functionDefinition = accessor.getAccessorDefinition(declaratorName);
// Standalone definitions in a header file have to be declared inline. // Standalone definitions in a header file have to be declared inline.
if (definitionInsertLocation.getTranslationUnit().isHeaderUnit()) { if (definitionInsertLocation.getTranslationUnit().isHeaderUnit()) {
functionDefinition.getDeclSpecifier().setInline(true); functionDefinition.getDeclSpecifier().setInline(true);
} }
definitions.add(functionDefinition); definitions.add(functionDefinition);
} else { } else {
getterAndSetters.add(accessor.getAccessorDefinition(false)); getterAndSetters.add(accessor.getAccessorDefinition(accessorName));
} }
} }
if (context.isDefinitionSeparate()) { if (context.isDefinitionSeparate()) {
addDefinition(collector, definitions, pm); addDefinition(collector, definitions, pm);
} }
ICPPASTCompositeTypeSpecifier classDefinition =
CPPVisitor.findAncestorWithType(context.existingFields.get(0), ICPPASTCompositeTypeSpecifier.class);
ClassMemberInserter.createChange(classDefinition, VisibilityEnum.v_public, ClassMemberInserter.createChange(classDefinition, VisibilityEnum.v_public,
getterAndSetters, false, collector); getterAndSetters, false, collector);