/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Created on Dec 9, 2006
* @author Fabio
*/
package com.python.pydev.refactoring.refactorer;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.OperationCanceledException;
import org.python.pydev.core.ICodeCompletionASTManager;
import org.python.pydev.core.IDefinition;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.core.structure.CompletionRecursionException;
import org.python.pydev.editor.codecompletion.revisited.CompletionCache;
import org.python.pydev.editor.codecompletion.revisited.visitors.Definition;
import org.python.pydev.editor.model.ItemPointer;
import org.python.pydev.editor.refactoring.PyRefactoringFindDefinition;
import org.python.pydev.editor.refactoring.RefactoringRequest;
import org.python.pydev.editor.refactoring.TooManyMatchesException;
import com.python.pydev.analysis.AnalysisPlugin;
import com.python.pydev.analysis.additionalinfo.AbstractAdditionalTokensInfo;
import com.python.pydev.analysis.additionalinfo.AdditionalProjectInterpreterInfo;
import com.python.pydev.analysis.additionalinfo.IInfo;
/**
* Class used to find the definition for some refactoring request.
*
* @author Fabio
*/
public class RefactorerFindDefinition {
/**
* This function is used to find the definition for some token.
* It may return a list of ItemPointer because the actual definition may not be
* easy to find (so, multiple places that could be the definitions for
* the given token may be returned... and it may be up to the user to actually
* choose the best match).
*
* @see org.python.pydev.editor.refactoring.IPyRefactoring#findDefinition(org.python.pydev.editor.refactoring.RefactoringRequest)
*/
public ItemPointer[] findDefinition(RefactoringRequest request) {
try {
request.getMonitor().beginTask("Find definition", 100);
List<ItemPointer> pointers = new ArrayList<ItemPointer>();
CompletionCache completionCache = new CompletionCache();
ArrayList<IDefinition> selected = new ArrayList<IDefinition>();
String[] tokenAndQual;
try {
tokenAndQual = PyRefactoringFindDefinition.findActualDefinition(request, completionCache, selected);
} catch (CompletionRecursionException e1) {
Log.log(e1);
return new ItemPointer[0];
}
if (tokenAndQual == null) {
return new ItemPointer[0];
}
PyRefactoringFindDefinition.getAsPointers(pointers, selected.toArray(new Definition[0]));
if (pointers.size() == 0
&& ((Boolean) request.getAdditionalInfo(
AstEntryRefactorerRequestConstants.FIND_DEFINITION_IN_ADDITIONAL_INFO, true))) {
String lookForInterface = tokenAndQual[1];
List<IInfo> tokensEqualTo;
try {
tokensEqualTo = AdditionalProjectInterpreterInfo.getTokensEqualTo(lookForInterface, request.nature,
AbstractAdditionalTokensInfo.TOP_LEVEL | AbstractAdditionalTokensInfo.INNER);
ICodeCompletionASTManager manager = request.nature.getAstManager();
if (manager == null) {
return new ItemPointer[0];
}
if (tokensEqualTo.size() > 50) {
//too many matches for that...
throw new TooManyMatchesException("Too Many matches (" + tokensEqualTo.size()
+ ") were found for the requested token:" + lookForInterface, tokensEqualTo.size());
}
request.communicateWork(com.aptana.shared_core.string.StringUtils.format("Found: %s possible matches.", tokensEqualTo.size()));
IPythonNature nature = request.nature;
for (IInfo info : tokensEqualTo) {
AnalysisPlugin.getDefinitionFromIInfo(pointers, manager, nature, info, completionCache);
request.checkCancelled();
}
} catch (MisconfigurationException e) {
Log.log(e);
return new ItemPointer[0];
}
}
request.communicateWork(com.aptana.shared_core.string.StringUtils.format("Found: %s matches.", pointers.size()));
return pointers.toArray(new ItemPointer[0]);
} catch (OperationCanceledException e) {
//that's ok... it was cancelled
throw e;
} finally {
request.getMonitor().done();
}
}
}