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

Bug 434677 - Fix implement method insert position with namespaces

If the correct namespace existed before the refactoring in the
translation unit, refactoring process just ignored it.

Change-Id: I9d6bd301807bb2d3f83f74ef772395d3470cf8bd
Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
This commit is contained in:
Marco Stornelli 2020-01-25 11:42:36 +01:00
parent edf13963f7
commit c0402d5d06
3 changed files with 75 additions and 1 deletions

View file

@ -897,4 +897,26 @@ public class ImplementMethodRefactoringTest extends RefactoringTestBase {
public void testWithInnerEnum_Bug452809() throws Exception {
assertRefactoringSuccess();
}
//A.h
//
//namespace N {
//struct A {
// /*$*/void waldo();/*$$*/
//};
//}
//A.cpp
//#include "A.h"
//namespace N {}
//====================
//#include "A.h"
//namespace N {
//void A::waldo() {
//}
//
//}
public void testNamespaceAlreadyInDefinition_Bug434677() throws Exception {
assertRefactoringSuccess();
}
}

View file

@ -63,6 +63,8 @@ public class InsertLocation {
} else if (nodeToInsertAfter != null) {
IASTFileLocation fileLocation = nodeToInsertAfter.getFileLocation();
return fileLocation.getNodeOffset() + fileLocation.getNodeLength();
} else if (parentNode != null) {
return parentNode.getFileLocation().getNodeOffset();
}
return 0;
}

View file

@ -22,6 +22,8 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
@ -29,11 +31,18 @@ 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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder;
import org.eclipse.cdt.internal.ui.refactoring.CRefactoringContext;
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
import org.eclipse.cdt.internal.ui.refactoring.utils.NamespaceHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@ -111,7 +120,48 @@ public class MethodDefinitionInsertLocationFinder {
ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit(declarationTu,
refactoringContext);
if (partner != null) {
if (methodDeclarationLocation == null) {
insertLocation.setParentNode(refactoringContext.getAST(partner, null), partner);
return insertLocation;
}
final ICPPASTName[] names = NamespaceHelper.getSurroundingNamespace(declarationTu,
methodDeclarationLocation.getNodeOffset(), refactoringContext);
IASTTranslationUnit ast = refactoringContext.getAST(partner, null);
IASTNode[] target = new IASTNode[1];
if (ast != null) {
ast.accept(new ASTVisitor() {
{
shouldVisitNamespaces = true;
}
@Override
public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
IASTName name = namespaceDefinition.getName();
IBinding binding = name.resolveBinding();
if (!(binding instanceof ICPPNamespace))
return PROCESS_CONTINUE;
try {
char[][] qualNames = ((ICPPNamespace) binding).getQualifiedNameCharArray();
if (qualNames.length != names.length - 1)
return PROCESS_CONTINUE;
for (int i = 0; i < names.length - 1; ++i) {
if (!CharArrayUtils.equals(qualNames[i], names[i].getSimpleID()))
return PROCESS_CONTINUE;
}
} catch (DOMException e) {
e.printStackTrace();
return PROCESS_CONTINUE;
}
target[0] = namespaceDefinition;
return PROCESS_ABORT;
}
});
}
if (target[0] != null) {
insertLocation.setParentNode(target[0], partner);
} else {
insertLocation.setParentNode(ast, partner);
}
}
} else {
insertLocation.setParentNode(parent.getTranslationUnit(), declarationTu);