1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Renamed InsertLocation2 to InsertLocation and MethodDefinitionInsertLocationFinder2 to MethodDefinitionInsertLocationFinder2.

This commit is contained in:
Sergey Prigogin 2011-04-18 17:43:23 +00:00
parent 6c11ab94ca
commit 9bcc2f85f4
6 changed files with 173 additions and 413 deletions

View file

@ -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)) {

View file

@ -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<IASTSimpleDeclaration, InsertLocation2> insertLocations;
private MethodDefinitionInsertLocationFinder methodDefinitionInsertLocationFinder;
private Map<IASTSimpleDeclaration, InsertLocation> 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<IASTSimpleDeclaration, InsertLocation2>();
methodDefinitionInsertLocationFinder = new MethodDefinitionInsertLocationFinder();
insertLocations = new HashMap<IASTSimpleDeclaration, InsertLocation>();
}
@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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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<IASTSimpleDeclaration, IASTName> cachedDeclarationToDefinition =
new HashMap<IASTSimpleDeclaration, IASTName>();
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<IASTSimpleDeclaration> allPreviousSimpleDeclarationsFromClassInReverseOrder =
getAllPreviousSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation, pm);
Collection<IASTSimpleDeclaration> 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<IASTSimpleDeclaration> getAllPreviousSimpleDeclarationsFromClassInReverseOrder(
IASTDeclaration[] declarations, IASTFileLocation methodPosition) {
ArrayList<IASTSimpleDeclaration> allIASTSimpleDeclarations = new ArrayList<IASTSimpleDeclaration>();
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<IASTSimpleDeclaration> outputDeclarations = new ArrayList<IASTSimpleDeclaration>();
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<IASTSimpleDeclaration> getAllFollowingSimpleDeclarationsFromClass(
IASTDeclaration[] declarations, IASTFileLocation methodPosition) {
ArrayList<IASTSimpleDeclaration> allIASTSimpleDeclarations = new ArrayList<IASTSimpleDeclaration>();
IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) {
ArrayList<IASTSimpleDeclaration> outputDeclarations = new ArrayList<IASTSimpleDeclaration>();
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) {

View file

@ -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<IASTSimpleDeclaration, IASTName> cachedDeclarationToDefinition =
new HashMap<IASTSimpleDeclaration, IASTName>();
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<IASTSimpleDeclaration> allPreviousSimpleDeclarationsFromClassInReverseOrder =
getAllPreviousSimpleDeclarationsFromClassInReverseOrder(declarations, methodDeclarationLocation, pm);
Collection<IASTSimpleDeclaration> 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<IASTSimpleDeclaration> getAllPreviousSimpleDeclarationsFromClassInReverseOrder(
IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) {
ArrayList<IASTSimpleDeclaration> outputDeclarations = new ArrayList<IASTSimpleDeclaration>();
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<IASTSimpleDeclaration> getAllFollowingSimpleDeclarationsFromClass(
IASTDeclaration[] declarations, IASTFileLocation methodPosition, IProgressMonitor pm) {
ArrayList<IASTSimpleDeclaration> outputDeclarations = new ArrayList<IASTSimpleDeclaration>();
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;
}
}