diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java index 128871034d7..f4dac3c3ebf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/gettersandsetters/GenerateGettersAndSettersRefactoring.java @@ -51,8 +51,8 @@ import org.eclipse.cdt.internal.ui.refactoring.AddDeclarationNodeToClassChange; import org.eclipse.cdt.internal.ui.refactoring.Container; import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector; import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache; -import org.eclipse.cdt.internal.ui.refactoring.implementmethod.InsertLocation2; -import org.eclipse.cdt.internal.ui.refactoring.implementmethod.MethodDefinitionInsertLocationFinder2; +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.utils.Checks; import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum; @@ -90,7 +90,7 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring2 { private static final String MEMBER_DECLARATION = "MEMBER_DECLARATION"; //$NON-NLS-1$ private final GetterAndSetterContext context; - private InsertLocation2 definitionInsertLocation; + private InsertLocation definitionInsertLocation; public GenerateGettersAndSettersRefactoring(ICElement element, ISelection selection, ICProject project, RefactoringASTCache astCache) { @@ -271,8 +271,8 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring2 { } IASTSimpleDeclaration decl = context.existingFields.get(0); - MethodDefinitionInsertLocationFinder2 methodDefinitionInsertLocationFinder = new MethodDefinitionInsertLocationFinder2(); - InsertLocation2 location = methodDefinitionInsertLocationFinder.find( + MethodDefinitionInsertLocationFinder methodDefinitionInsertLocationFinder = new MethodDefinitionInsertLocationFinder(); + InsertLocation location = methodDefinitionInsertLocationFinder.find( tu, decl.getFileLocation(), decl.getParent(), astCache, pm); if (location.getFile() == null || NodeHelper.isContainedInTemplateDeclaration(decl)) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java index 630a15d7fb6..e7284d1ee7c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/ImplementMethodRefactoring.java @@ -74,15 +74,15 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper; public class ImplementMethodRefactoring extends CRefactoring2 { private ICPPASTFunctionDeclarator createdMethodDeclarator; private ImplementMethodData data; - private MethodDefinitionInsertLocationFinder2 methodDefinitionInsertLocationFinder; - private Map insertLocations; + private MethodDefinitionInsertLocationFinder methodDefinitionInsertLocationFinder; + private Map insertLocations; private static ICPPNodeFactory nodeFactory = ASTNodeFactoryFactory.getDefaultCPPNodeFactory(); public ImplementMethodRefactoring(ICElement element, ISelection selection, ICProject project, RefactoringASTCache astCache) { super(element, selection, project, astCache); data = new ImplementMethodData(); - methodDefinitionInsertLocationFinder = new MethodDefinitionInsertLocationFinder2(); - insertLocations = new HashMap(); + methodDefinitionInsertLocationFinder = new MethodDefinitionInsertLocationFinder(); + insertLocations = new HashMap(); } @Override @@ -140,7 +140,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { if (binding instanceof ICPPMethod) { ICPPMethod methodBinding = (ICPPMethod) binding; if (methodBinding.isPureVirtual()) { - return false; //Êpure virtual not handled for now, see bug 303870 + return false; //�pure virtual not handled for now, see bug 303870 } } @@ -174,7 +174,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { throw new OperationCanceledException(); } IASTSimpleDeclaration decl = config.getDeclaration(); - InsertLocation2 insertLocation = findInsertLocation(decl, subMonitor); + InsertLocation insertLocation = findInsertLocation(decl, subMonitor); if (subMonitor.isCanceled()) { throw new OperationCanceledException(); } @@ -218,11 +218,11 @@ public class ImplementMethodRefactoring extends CRefactoring2 { } } - private InsertLocation2 findInsertLocation(IASTSimpleDeclaration methodDeclaration, IProgressMonitor subMonitor) throws CoreException { + private InsertLocation findInsertLocation(IASTSimpleDeclaration methodDeclaration, IProgressMonitor subMonitor) throws CoreException { if (insertLocations.containsKey(methodDeclaration)) { return insertLocations.get(methodDeclaration); } - InsertLocation2 insertLocation = methodDefinitionInsertLocationFinder.find(tu, methodDeclaration.getFileLocation(), methodDeclaration.getParent(), astCache, subMonitor); + InsertLocation insertLocation = methodDefinitionInsertLocationFinder.find(tu, methodDeclaration.getFileLocation(), methodDeclaration.getParent(), astCache, subMonitor); if (insertLocation.getTranslationUnit() == null || NodeHelper.isContainedInTemplateDeclaration(methodDeclaration)) { insertLocation.setNodeToInsertAfter(NodeHelper.findTopLevelParent(methodDeclaration), tu); @@ -231,7 +231,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { return insertLocation; } - private IASTDeclaration createFunctionDefinition(IASTTranslationUnit unit, IASTSimpleDeclaration methodDeclaration, InsertLocation2 insertLocation) throws CoreException { + private IASTDeclaration createFunctionDefinition(IASTTranslationUnit unit, IASTSimpleDeclaration methodDeclaration, InsertLocation insertLocation) throws CoreException { IASTDeclSpecifier declSpecifier = methodDeclaration.getDeclSpecifier().copy(CopyStyle.withLocations); ICPPASTFunctionDeclarator functionDeclarator = (ICPPASTFunctionDeclarator) methodDeclaration.getDeclarators()[0]; IASTNode declarationParent = methodDeclaration.getParent(); @@ -274,7 +274,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { } private ICPPASTQualifiedName createQualifiedNameFor(IASTFunctionDeclarator functionDeclarator, - IASTNode declarationParent, InsertLocation2 insertLocation) throws CoreException { + IASTNode declarationParent, InsertLocation insertLocation) throws CoreException { int insertOffset = insertLocation.getInsertPosition(); return NameHelper.createQualifiedNameFor( functionDeclarator.getName(), tu, functionDeclarator.getFileLocation().getNodeOffset(), @@ -298,7 +298,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { files.add(file); } - for (InsertLocation2 insertLocation : insertLocations.values()) { + for (InsertLocation insertLocation : insertLocations.values()) { if (insertLocation != null) { file = insertLocation.getFile(); if (file != null) { @@ -331,7 +331,7 @@ public class ImplementMethodRefactoring extends CRefactoring2 { return true; } - for (InsertLocation2 insertLocation : insertLocations.values()) { + for (InsertLocation insertLocation : insertLocations.values()) { if (insertLocation != null && tu.equals(insertLocation.getTranslationUnit())) { return true; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation.java index ceda3a5b11f..42b763a1f20 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Institute for Software, HSR Hochschule fuer Technik + * 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 @@ -7,91 +7,77 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Institute for Software - initial API and implementation + * Institute for Software - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; - -import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper; +import org.eclipse.cdt.core.model.ITranslationUnit; /** - * Is returned when using the find-method of the MethodDefinitionInsertLocationFinder. - * Contains all the infos needet to insert at the correct position. + * Is returned when using the find method of the MethodDefinitionInsertLocationFinder. + * Contains all the information needed to insert at the correct position. + * This class is intended as a replacement for InsertLocation. * * @author Lukas Felber */ public class InsertLocation { - private IFile insertFile; private IASTNode nodeToInsertAfter; private IASTNode nodeToInsertBefore; - private IASTTranslationUnit targetTranslationUnit; + private IASTNode parentNode; + private ITranslationUnit tu; + + public InsertLocation() { + } public boolean hasAnyNode() { return nodeToInsertAfter != null || nodeToInsertBefore != null; } - + public IASTNode getNodeToInsertBefore() { return nodeToInsertBefore; } - - public IASTNode getPartenOfNodeToInsertBefore() throws CoreException { - IASTNode affectedNode = getAffectedNode(); - return (affectedNode != null) ? affectedNode.getParent() : getTargetTranslationUnit(); + + public IASTNode getParentOfNodeToInsertBefore() throws CoreException { + IASTNode node = nodeToInsertBefore != null ? nodeToInsertBefore : nodeToInsertAfter; + return node != null ? node.getParent() : parentNode; } - private IASTNode getAffectedNode() { - IASTNode concernedNode = (nodeToInsertBefore != null) ? nodeToInsertBefore : nodeToInsertAfter; - return concernedNode; + public ITranslationUnit getTranslationUnit() { + return tu; } - public IFile getInsertFile() { - return insertFile; - } - - public void setInsertFile(IFile insertFile) { - this.insertFile = insertFile; - } - - public void setNodeToInsertAfter(IASTNode nodeToInsertAfter) { - this.nodeToInsertAfter = nodeToInsertAfter; - } - - public void setNodeToInsertBefore(IASTNode nodeToInsertBefore) { - this.nodeToInsertBefore = nodeToInsertBefore; - } - - public boolean hasFile() { - return insertFile != null; - } - - public IASTTranslationUnit getTargetTranslationUnit() throws CoreException{ - if (targetTranslationUnit == null) { - loadTargetTranslationUnit(); - } - return targetTranslationUnit; - } - - private void loadTargetTranslationUnit() throws CoreException{ - IASTNode affectedNode = getAffectedNode(); - if (affectedNode != null) { - targetTranslationUnit = affectedNode.getTranslationUnit(); - } else if (hasFile()) { - targetTranslationUnit = TranslationUnitHelper.loadTranslationUnit(insertFile, true); - } + public IFile getFile() { + return tu != null ? (IFile) tu.getResource() : null; } public int getInsertPosition() { if (nodeToInsertBefore != null) { return nodeToInsertBefore.getFileLocation().getNodeOffset(); } else if (nodeToInsertAfter != null) { - return nodeToInsertAfter.getFileLocation().getNodeOffset() + nodeToInsertAfter.getFileLocation().getNodeLength(); - } else { - return 0; + IASTFileLocation fileLocation = nodeToInsertAfter.getFileLocation(); + return fileLocation.getNodeOffset() + fileLocation.getNodeLength(); } + return 0; + } + + public void setNodeToInsertAfter(IASTNode nodeToInsertAfter, ITranslationUnit tu) { + this.nodeToInsertAfter = nodeToInsertAfter; + this.tu = tu; + } + + public void setNodeToInsertBefore(IASTNode nodeToInsertBefore, ITranslationUnit tu) { + this.nodeToInsertBefore = nodeToInsertBefore; + this.tu = tu; + } + + public void setParentNode(IASTNode parentNode, ITranslationUnit tu) { + this.parentNode = parentNode; + this.tu = tu; } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation2.java deleted file mode 100644 index 2835a22d333..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/InsertLocation2.java +++ /dev/null @@ -1,83 +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.implementmethod; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; - -import org.eclipse.cdt.core.dom.ast.IASTFileLocation; -import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.model.ITranslationUnit; - -/** - * Is returned when using the find method of the MethodDefinitionInsertLocationFinder. - * Contains all the information needed to insert at the correct position. - * This class is intended as a replacement for InsertLocation. - * - * @author Lukas Felber - */ -public class InsertLocation2 { - private IASTNode nodeToInsertAfter; - private IASTNode nodeToInsertBefore; - private IASTNode parentNode; - private ITranslationUnit tu; - - public InsertLocation2() { - } - - public boolean hasAnyNode() { - return nodeToInsertAfter != null || nodeToInsertBefore != null; - } - - public IASTNode getNodeToInsertBefore() { - return nodeToInsertBefore; - } - - public IASTNode getParentOfNodeToInsertBefore() throws CoreException { - IASTNode node = nodeToInsertBefore != null ? nodeToInsertBefore : nodeToInsertAfter; - return node != null ? node.getParent() : parentNode; - } - - public ITranslationUnit getTranslationUnit() { - return tu; - } - - public IFile getFile() { - return tu != null ? (IFile) tu.getResource() : null; - } - - public int getInsertPosition() { - if (nodeToInsertBefore != null) { - return nodeToInsertBefore.getFileLocation().getNodeOffset(); - } else if (nodeToInsertAfter != null) { - IASTFileLocation fileLocation = nodeToInsertAfter.getFileLocation(); - return fileLocation.getNodeOffset() + fileLocation.getNodeLength(); - } - return 0; - } - - public void setNodeToInsertAfter(IASTNode nodeToInsertAfter, ITranslationUnit tu) { - this.nodeToInsertAfter = nodeToInsertAfter; - this.tu = tu; - } - - public void setNodeToInsertBefore(IASTNode nodeToInsertBefore, ITranslationUnit tu) { - this.nodeToInsertBefore = nodeToInsertBefore; - this.tu = tu; - } - - public void setParentNode(IASTNode parentNode, ITranslationUnit tu) { - this.parentNode = parentNode; - this.tu = tu; - } -} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder.java index a1841644739..adbb6d4fed5 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik + * 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 @@ -7,17 +7,22 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Institute for Software - initial API and implementation + * Institute for Software - initial API and implementation + * Sergey Prigogin (Google) + * Marc-Andre Laperle *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.implementmethod; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; -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.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; @@ -28,21 +33,89 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.model.ITranslationUnit; -import org.eclipse.cdt.internal.core.resources.ResourceLookup; - import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder; -import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder; -import org.eclipse.cdt.internal.ui.refactoring.utils.FileHelper; +import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache; +import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder2; import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; /** - * Finds the information that are needed to tell where a MethodDefinition of a certain + * Finds the information that are needed to tell where a method definition of a certain * method declaration should be inserted. + * This class is intended as a replacement for MethodDefinitionInsertLocationFinder. * * @author Mirko Stocker, Lukas Felber */ public class MethodDefinitionInsertLocationFinder { - + // We cache DefinitionFinder2.getDefinition results because refactorings like Implement Method + // might want to find multiple insert locations in the same translation unit. This prevents + // many redundant calls to DefinitionFinder2.getDefinition and speeds up the process quite + //a bit. Unfortunately, this has the minor side-effect or having to instantiate this class. + Map cachedDeclarationToDefinition = + new HashMap(); + + public InsertLocation find(ITranslationUnit declarationTu, IASTFileLocation methodDeclarationLocation, + IASTNode parent, RefactoringASTCache astCache, IProgressMonitor pm) throws CoreException { + IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent); + InsertLocation insertLocation = new InsertLocation(); + + Collection allPreviousSimpleDeclarationsFromClassInReverseOrder = + getAllPreviousSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation, pm); + Collection allFollowingSimpleDeclarationsFromClass = + getAllFollowingSimpleDeclarationsFromClass(declarations, methodDeclarationLocation, pm); + + for (IASTSimpleDeclaration simpleDeclaration : allPreviousSimpleDeclarationsFromClassInReverseOrder) { + if (pm != null && pm.isCanceled()) { + throw new OperationCanceledException(); + } + + IASTName definition = null; + if (cachedDeclarationToDefinition.containsKey(simpleDeclaration)) { + definition = cachedDeclarationToDefinition.get(simpleDeclaration); + } else { + definition = DefinitionFinder2.getDefinition(simpleDeclaration, astCache, pm); + if (definition != null) { + cachedDeclarationToDefinition.put(simpleDeclaration, definition); + } + } + + if (definition != null) { + insertLocation.setNodeToInsertAfter(findFirstSurroundingParentFunctionNode( + definition), definition.getTranslationUnit().getOriginatingTranslationUnit()); + } + } + + for (IASTSimpleDeclaration simpleDeclaration : allFollowingSimpleDeclarationsFromClass) { + if (pm != null && pm.isCanceled()) { + throw new OperationCanceledException(); + } + + IASTName definition = null; + if (cachedDeclarationToDefinition.containsKey(simpleDeclaration)) { + definition = cachedDeclarationToDefinition.get(simpleDeclaration); + } else { + definition = DefinitionFinder2.getDefinition(simpleDeclaration, astCache, pm); + if (definition != null) { + cachedDeclarationToDefinition.put(simpleDeclaration, definition); + } + } + + if (definition != null) { + insertLocation.setNodeToInsertBefore(findFirstSurroundingParentFunctionNode(definition), + definition.getTranslationUnit().getOriginatingTranslationUnit()); + } + } + + if (insertLocation.getTranslationUnit() == null) { + ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit( + declarationTu, astCache); + if (partner != null) { + insertLocation.setParentNode(astCache.getAST(partner, null), partner); + } + } + + return insertLocation; + } + private static IASTNode findFunctionDefinitionInParents(IASTNode node) { if (node == null) { return null; @@ -54,85 +127,63 @@ public class MethodDefinitionInsertLocationFinder { } return findFunctionDefinitionInParents(node.getParent()); } - + private static IASTNode findFirstSurroundingParentFunctionNode(IASTNode definition) { IASTNode functionDefinitionInParents = findFunctionDefinitionInParents(definition); - if (functionDefinitionInParents == null || - functionDefinitionInParents.getNodeLocations().length == 0) { + if (functionDefinitionInParents == null) { + return null; + } + if (functionDefinitionInParents.getNodeLocations().length == 0) { return null; } return functionDefinitionInParents; } - public static InsertLocation find(IASTFileLocation methodDeclarationLocation, IASTNode parent, - IFile file) throws CoreException { - IASTName definition = null; - IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent); - InsertLocation result = new InsertLocation(); - - for (IASTSimpleDeclaration simpleDeclaration : getAllPreviousSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation)) { - definition = DefinitionFinder.getDefinition(simpleDeclaration, file); - - if (definition != null) { - result.setNodeToInsertAfter(findFirstSurroundingParentFunctionNode(definition)); - result.setInsertFile(FileHelper.getIFilefromIASTNode(definition)); - } - } - - for (IASTSimpleDeclaration simpleDeclaration : getAllFollowingSimpleDeclarationsFromClass(declarations, methodDeclarationLocation)) { - definition = DefinitionFinder.getDefinition(simpleDeclaration, file); - - if (definition != null) { - result.setNodeToInsertBefore(findFirstSurroundingParentFunctionNode(definition)); - result.setInsertFile(FileHelper.getIFilefromIASTNode(definition)); - } - } - - ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file); - ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit(tu); - if (partner != null) { - IFile fileForLocation = ResourceLookup.selectFileForLocation(partner.getLocation(), file.getProject()); - if (fileForLocation != null && fileForLocation.exists()) { - result.setInsertFile(fileForLocation); - } - } - - return result; - } - /** * Searches the given class for all IASTSimpleDeclarations occurring before 'method' * and returns them in reverse order. * * @param declarations to be searched * @param methodPosition on which the search aborts + * @param pm * @return all declarations, sorted in reverse order */ private static Collection getAllPreviousSimpleDeclarationsFromClassInReverseOrder( - IASTDeclaration[] declarations, IASTFileLocation methodPosition) { - ArrayList allIASTSimpleDeclarations = new ArrayList(); - for (IASTDeclaration decl : declarations) { - if (decl.getFileLocation().getStartingLineNumber() >= methodPosition.getStartingLineNumber()) { - return allIASTSimpleDeclarations; - } - if (isMemberFunctionDeclaration(decl)) { - allIASTSimpleDeclarations.add(0, (IASTSimpleDeclaration) decl); + IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) { + ArrayList outputDeclarations = new ArrayList(); + if (declarations.length >= 0) { + for (IASTDeclaration decl : declarations) { + if (pm != null && pm.isCanceled()) { + return outputDeclarations; + } + if (decl.getFileLocation().getStartingLineNumber() >= methodPosition.getStartingLineNumber()) { + break; + } + if (isMemberFunctionDeclaration(decl)) { + outputDeclarations.add((IASTSimpleDeclaration) decl); + } } } - return allIASTSimpleDeclarations; + Collections.reverse(outputDeclarations); + return outputDeclarations; } private static Collection getAllFollowingSimpleDeclarationsFromClass( - IASTDeclaration[] declarations, IASTFileLocation methodPosition) { - ArrayList allIASTSimpleDeclarations = new ArrayList(); + IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) { + ArrayList outputDeclarations = new ArrayList(); - for (IASTDeclaration decl : declarations) { - if (isMemberFunctionDeclaration(decl) && - decl.getFileLocation().getStartingLineNumber() > methodPosition.getStartingLineNumber() ) { - allIASTSimpleDeclarations.add((IASTSimpleDeclaration) decl); + if (declarations.length >= 0) { + for (IASTDeclaration decl : declarations) { + if (pm != null && pm.isCanceled()) { + return outputDeclarations; + } + if (isMemberFunctionDeclaration(decl) && + decl.getFileLocation().getStartingLineNumber() > methodPosition.getStartingLineNumber() ) { + outputDeclarations.add((IASTSimpleDeclaration) decl); + } } } - return allIASTSimpleDeclarations; + return outputDeclarations; } private static boolean isMemberFunctionDeclaration(IASTDeclaration decl) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder2.java deleted file mode 100644 index 2b42ef3765e..00000000000 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/implementmethod/MethodDefinitionInsertLocationFinder2.java +++ /dev/null @@ -1,194 +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) - * Marc-Andre Laperle - *******************************************************************************/ -package org.eclipse.cdt.internal.ui.refactoring.implementmethod; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; - -import org.eclipse.cdt.core.dom.ast.IASTDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTFileLocation; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; -import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; -import org.eclipse.cdt.core.model.ITranslationUnit; - -import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder; -import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache; -import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder2; -import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper; - -/** - * Finds the information that are needed to tell where a method definition of a certain - * method declaration should be inserted. - * This class is intended as a replacement for MethodDefinitionInsertLocationFinder. - * - * @author Mirko Stocker, Lukas Felber - */ -public class MethodDefinitionInsertLocationFinder2 { - // We cache DefinitionFinder2.getDefinition results because refactorings like Implement Method - // might want to find multiple insert locations in the same translation unit. This prevents - // many redundant calls to DefinitionFinder2.getDefinition and speeds up the process quite - //a bit. Unfortunately, this has the minor side-effect or having to instantiate this class. - Map cachedDeclarationToDefinition = - new HashMap(); - - public InsertLocation2 find(ITranslationUnit declarationTu, IASTFileLocation methodDeclarationLocation, - IASTNode parent, RefactoringASTCache astCache, IProgressMonitor pm) throws CoreException { - IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent); - InsertLocation2 insertLocation = new InsertLocation2(); - - Collection allPreviousSimpleDeclarationsFromClassInReverseOrder = - getAllPreviousSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation, pm); - Collection allFollowingSimpleDeclarationsFromClass = - getAllFollowingSimpleDeclarationsFromClass(declarations, methodDeclarationLocation, pm); - - for (IASTSimpleDeclaration simpleDeclaration : allPreviousSimpleDeclarationsFromClassInReverseOrder) { - if (pm != null && pm.isCanceled()) { - throw new OperationCanceledException(); - } - - IASTName definition = null; - if (cachedDeclarationToDefinition.containsKey(simpleDeclaration)) { - definition = cachedDeclarationToDefinition.get(simpleDeclaration); - } else { - definition = DefinitionFinder2.getDefinition(simpleDeclaration, astCache, pm); - if (definition != null) { - cachedDeclarationToDefinition.put(simpleDeclaration, definition); - } - } - - if (definition != null) { - insertLocation.setNodeToInsertAfter(findFirstSurroundingParentFunctionNode( - definition), definition.getTranslationUnit().getOriginatingTranslationUnit()); - } - } - - for (IASTSimpleDeclaration simpleDeclaration : allFollowingSimpleDeclarationsFromClass) { - if (pm != null && pm.isCanceled()) { - throw new OperationCanceledException(); - } - - IASTName definition = null; - if (cachedDeclarationToDefinition.containsKey(simpleDeclaration)) { - definition = cachedDeclarationToDefinition.get(simpleDeclaration); - } else { - definition = DefinitionFinder2.getDefinition(simpleDeclaration, astCache, pm); - if (definition != null) { - cachedDeclarationToDefinition.put(simpleDeclaration, definition); - } - } - - if (definition != null) { - insertLocation.setNodeToInsertBefore(findFirstSurroundingParentFunctionNode(definition), - definition.getTranslationUnit().getOriginatingTranslationUnit()); - } - } - - if (insertLocation.getTranslationUnit() == null) { - ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit( - declarationTu, astCache); - if (partner != null) { - insertLocation.setParentNode(astCache.getAST(partner, null), partner); - } - } - - return insertLocation; - } - - private static IASTNode findFunctionDefinitionInParents(IASTNode node) { - if (node == null) { - return null; - } else if (node instanceof IASTFunctionDefinition) { - if (node.getParent() instanceof ICPPASTTemplateDeclaration) { - node = node.getParent(); - } - return node; - } - return findFunctionDefinitionInParents(node.getParent()); - } - - private static IASTNode findFirstSurroundingParentFunctionNode(IASTNode definition) { - IASTNode functionDefinitionInParents = findFunctionDefinitionInParents(definition); - if (functionDefinitionInParents == null) { - return null; - } - if (functionDefinitionInParents.getNodeLocations().length == 0) { - return null; - } - return functionDefinitionInParents; - } - - /** - * Searches the given class for all IASTSimpleDeclarations occurring before 'method' - * and returns them in reverse order. - * - * @param declarations to be searched - * @param methodPosition on which the search aborts - * @param pm - * @return all declarations, sorted in reverse order - */ - private static Collection getAllPreviousSimpleDeclarationsFromClassInReverseOrder( - IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) { - ArrayList outputDeclarations = new ArrayList(); - if (declarations.length >= 0) { - for (IASTDeclaration decl : declarations) { - if (pm != null && pm.isCanceled()) { - return outputDeclarations; - } - if (decl.getFileLocation().getStartingLineNumber() >= methodPosition.getStartingLineNumber()) { - break; - } - if (isMemberFunctionDeclaration(decl)) { - outputDeclarations.add((IASTSimpleDeclaration) decl); - } - } - } - Collections.reverse(outputDeclarations); - return outputDeclarations; - } - - private static Collection getAllFollowingSimpleDeclarationsFromClass( - IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) { - ArrayList outputDeclarations = new ArrayList(); - - if (declarations.length >= 0) { - for (IASTDeclaration decl : declarations) { - if (pm != null && pm.isCanceled()) { - return outputDeclarations; - } - if (isMemberFunctionDeclaration(decl) && - decl.getFileLocation().getStartingLineNumber() > methodPosition.getStartingLineNumber() ) { - outputDeclarations.add((IASTSimpleDeclaration) decl); - } - } - } - return outputDeclarations; - } - - private static boolean isMemberFunctionDeclaration(IASTDeclaration decl) { - return decl instanceof IASTSimpleDeclaration && - ((IASTSimpleDeclaration) decl).getDeclarators().length > 0 && - ((IASTSimpleDeclaration) decl).getDeclarators()[0] instanceof IASTFunctionDeclarator; - } -}