diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/actions/PyFindAllOccurrences.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/actions/PyFindAllOccurrences.java index 97f7294f6..b1edb10cd 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/actions/PyFindAllOccurrences.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/actions/PyFindAllOccurrences.java @@ -13,9 +13,9 @@ import org.eclipse.search.ui.NewSearchUI; import org.python.pydev.editor.actions.refactoring.PyRefactorAction; import org.python.pydev.editor.refactoring.AbstractPyRefactoring; +import org.python.pydev.editor.refactoring.IPyRefactoring2; import org.python.pydev.editor.refactoring.RefactoringRequest; -import com.python.pydev.refactoring.IPyRefactoring2; import com.python.pydev.refactoring.search.FindOccurrencesSearchQuery; public class PyFindAllOccurrences extends PyRefactorAction{ diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/Refactorer.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/Refactorer.java index d9f0a0b3e..3957c6f6d 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/Refactorer.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/Refactorer.java @@ -24,21 +24,21 @@ import org.python.pydev.editor.codecompletion.revisited.visitors.AssignDefinition; import org.python.pydev.editor.model.ItemPointer; import org.python.pydev.editor.refactoring.AbstractPyRefactoring; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; +import org.python.pydev.editor.refactoring.IPyRefactoring2; import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.editor.refactoring.TooManyMatchesException; import org.python.pydev.parser.visitors.scope.ASTEntry; -import com.python.pydev.refactoring.IPyRefactoring2; import com.python.pydev.refactoring.wizards.rename.PyRenameEntryPoint; import com.python.pydev.refactoring.wizards.rename.PyRenameRefactoringWizard; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; /** * This is the entry point for any refactoring that we implement. * * @author Fabio */ -public class Refactorer extends AbstractPyRefactoring implements IPyRefactoring2{ +public class Refactorer extends AbstractPyRefactoring implements IPyRefactoring2 { public String getName() { return "PyDev Extensions Refactorer"; @@ -74,6 +74,7 @@ public ItemPointer[] findDefinition(RefactoringRequest request) throws TooManyMa // --------------------------------------------------------- IPyRefactoring2 + @Override public boolean areAllInSameClassHierarchy(List defs) { return new RefactorerFinds(this).areAllInSameClassHierarchy(defs); } diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/RefactorerFinds.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/RefactorerFinds.java index 73ea01008..bc94078f0 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/RefactorerFinds.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/refactorer/RefactorerFinds.java @@ -34,6 +34,7 @@ import org.python.pydev.editor.codecompletion.revisited.visitors.AssignDefinition; import org.python.pydev.editor.codecompletion.revisited.visitors.Definition; import org.python.pydev.editor.model.ItemPointer; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.editor.refactoring.PyRefactoringFindDefinition; import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.parser.jython.ast.ClassDef; @@ -45,7 +46,6 @@ import com.python.pydev.analysis.additionalinfo.AbstractAdditionalDependencyInfo; import com.python.pydev.analysis.additionalinfo.AdditionalProjectInterpreterInfo; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; public class RefactorerFinds { diff --git a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/search/FindOccurrencesSearchQuery.java b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/search/FindOccurrencesSearchQuery.java index cbeb47008..01b71c6c9 100644 --- a/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/search/FindOccurrencesSearchQuery.java +++ b/plugins/com.python.pydev.refactoring/src/com/python/pydev/refactoring/search/FindOccurrencesSearchQuery.java @@ -26,11 +26,11 @@ import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.core.log.Log; +import org.python.pydev.editor.refactoring.IPyRefactoring2; import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.editorinput.PySourceLocatorBase; import org.python.pydev.parser.visitors.scope.ASTEntry; -import com.python.pydev.refactoring.IPyRefactoring2; import com.python.pydev.refactoring.actions.PyFindAllOccurrences; import com.python.pydev.refactoring.refactorer.search.AbstractPythonSearchQuery; import com.python.pydev.refactoring.wizards.rename.AbstractRenameRefactorProcess; diff --git a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/refactorer/ClassHierarchySearchTest.java b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/refactorer/ClassHierarchySearchTest.java index 1c07f8d70..1fa095b8f 100644 --- a/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/refactorer/ClassHierarchySearchTest.java +++ b/plugins/com.python.pydev.refactoring/tests/com/python/pydev/refactoring/refactorer/ClassHierarchySearchTest.java @@ -20,12 +20,12 @@ import org.python.pydev.editor.codecompletion.revisited.ProjectModulesManager; import org.python.pydev.editor.codecompletion.revisited.modules.CompiledModule; import org.python.pydev.editor.codecompletion.revisited.modules.SourceModule; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.plugin.nature.PythonNature; import com.python.pydev.analysis.additionalinfo.AdditionalInfoTestsBase; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; public class ClassHierarchySearchTest extends AdditionalInfoTestsBase { diff --git a/plugins/com.python.pydev/src/com/python/pydev/actions/OutlineEntry.java b/plugins/com.python.pydev/src/com/python/pydev/actions/OutlineEntry.java index 339c25925..7576d621b 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/actions/OutlineEntry.java +++ b/plugins/com.python.pydev/src/com/python/pydev/actions/OutlineEntry.java @@ -6,12 +6,12 @@ */ package com.python.pydev.actions; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.visitors.NodeUtils; import org.python.pydev.parser.visitors.scope.ASTEntry; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; /** * @author fabioz diff --git a/plugins/com.python.pydev/src/com/python/pydev/actions/PyOutlineSelectionDialog.java b/plugins/com.python.pydev/src/com/python/pydev/actions/PyOutlineSelectionDialog.java index e1242ed1f..0b8ddda7c 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/actions/PyOutlineSelectionDialog.java +++ b/plugins/com.python.pydev/src/com/python/pydev/actions/PyOutlineSelectionDialog.java @@ -46,7 +46,9 @@ import org.python.pydev.editor.model.ItemPointer; import org.python.pydev.editor.model.Location; import org.python.pydev.editor.refactoring.AbstractPyRefactoring; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.editor.refactoring.IPyRefactoring; +import org.python.pydev.editor.refactoring.IPyRefactoring2; import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; @@ -55,8 +57,6 @@ import org.python.pydev.parser.visitors.scope.DefinitionsASTIteratorVisitor; import org.python.pydev.ui.dialogs.TreeSelectionDialog; -import com.python.pydev.refactoring.IPyRefactoring2; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; import com.python.pydev.ui.hierarchy.TreeNode; import com.python.pydev.ui.hierarchy.TreeNodeContentProvider; diff --git a/plugins/com.python.pydev/src/com/python/pydev/actions/PyShowHierarchy.java b/plugins/com.python.pydev/src/com/python/pydev/actions/PyShowHierarchy.java index 27b0ed6b8..a8e995a04 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/actions/PyShowHierarchy.java +++ b/plugins/com.python.pydev/src/com/python/pydev/actions/PyShowHierarchy.java @@ -21,11 +21,11 @@ import org.python.pydev.editor.actions.PyAction; import org.python.pydev.editor.actions.refactoring.PyRefactorAction; import org.python.pydev.editor.refactoring.AbstractPyRefactoring; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.editor.refactoring.IPyRefactoring; +import org.python.pydev.editor.refactoring.IPyRefactoring2; import org.python.pydev.editor.refactoring.RefactoringRequest; -import com.python.pydev.refactoring.IPyRefactoring2; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; import com.python.pydev.ui.hierarchy.PyHierarchyView; /** diff --git a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyViewer.java b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyViewer.java index 7516ad939..cfd2db59e 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyViewer.java +++ b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyViewer.java @@ -35,6 +35,7 @@ import org.python.pydev.core.IModule; import org.python.pydev.editor.actions.PyOpenAction; import org.python.pydev.editor.model.ItemPointer; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.jython.ast.FunctionDef; diff --git a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/PyHierarchyView.java b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/PyHierarchyView.java index 36519fe02..45d0e0081 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/PyHierarchyView.java +++ b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/PyHierarchyView.java @@ -13,6 +13,7 @@ import org.eclipse.ui.IActionBars; import org.python.pydev.core.ExtensionHelper; import org.python.pydev.core.callbacks.ICallbackWithListeners; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.ui.IViewCreatedObserver; import org.python.pydev.ui.IViewWithControls; import org.python.pydev.ui.ViewPartWithOrientation; diff --git a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/TreeNodeContentProvider.java b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/TreeNodeContentProvider.java index e5ee1bec4..b59cf7d9e 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/TreeNodeContentProvider.java +++ b/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/TreeNodeContentProvider.java @@ -14,6 +14,7 @@ import org.eclipse.jface.viewers.StyledString.Styler; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.graphics.Image; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; public class TreeNodeContentProvider implements ITreeContentProvider { diff --git a/plugins/com.python.pydev/tests/com/python/pydev/ui/dialogs/PyOutlineSelectionDialogTest.java b/plugins/com.python.pydev/tests/com/python/pydev/ui/dialogs/PyOutlineSelectionDialogTest.java index 04be47017..8c5660431 100644 --- a/plugins/com.python.pydev/tests/com/python/pydev/ui/dialogs/PyOutlineSelectionDialogTest.java +++ b/plugins/com.python.pydev/tests/com/python/pydev/ui/dialogs/PyOutlineSelectionDialogTest.java @@ -17,13 +17,13 @@ import org.python.pydev.core.MisconfigurationException; import org.python.pydev.editor.codecompletion.revisited.modules.AbstractModule; import org.python.pydev.editor.codecompletion.revisited.modules.SourceModule; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.jython.ast.Module; import org.python.pydev.ui.SWTTest; import com.python.pydev.actions.PyOutlineSelectionDialog; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; public class PyOutlineSelectionDialogTest extends SWTTest { diff --git a/plugins/com.python.pydev/tests/com/python/pydev/ui/hierarchy/HierarchyViewerTest.java b/plugins/com.python.pydev/tests/com/python/pydev/ui/hierarchy/HierarchyViewerTest.java index 1026a7e3a..d8c17ad6d 100644 --- a/plugins/com.python.pydev/tests/com/python/pydev/ui/hierarchy/HierarchyViewerTest.java +++ b/plugins/com.python.pydev/tests/com/python/pydev/ui/hierarchy/HierarchyViewerTest.java @@ -15,6 +15,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.python.pydev.core.TestDependent; +import org.python.pydev.editor.refactoring.HierarchyNodeModel; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.ui.BundleInfoStub; diff --git a/plugins/org.python.pydev.core/.classpath b/plugins/org.python.pydev.core/.classpath index 042b02452..4e26b22b3 100644 --- a/plugins/org.python.pydev.core/.classpath +++ b/plugins/org.python.pydev.core/.classpath @@ -1,10 +1,10 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/plugins/org.python.pydev.core/src/org/python/pydev/core/ExtensionHelper.java b/plugins/org.python.pydev.core/src/org/python/pydev/core/ExtensionHelper.java index bb9334d26..69ab0d7bb 100644 --- a/plugins/org.python.pydev.core/src/org/python/pydev/core/ExtensionHelper.java +++ b/plugins/org.python.pydev.core/src/org/python/pydev/core/ExtensionHelper.java @@ -44,6 +44,7 @@ public class ExtensionHelper { public static final String PYDEV_SIMPLE_ASSIST = "org.python.pydev.pydev_simpleassist"; public static final String PYDEV_ORGANIZE_IMPORTS = "org.python.pydev.pydev_organize_imports"; public static final String PYDEV_REFACTORING = "org.python.pydev.pydev_refactoring"; + public static final String PYDEV_USER_REFACTORING = "org.python.pydev.pydev_user_refactoring"; public static final String PYDEV_QUICK_OUTLINE = "org.python.pydev.pydev_quick_outline"; public static final String PYDEV_PYEDIT_LISTENER = "org.python.pydev.pydev_pyedit_listener"; public static final String PYDEV_PREFERENCES_PROVIDER = "org.python.pydev.pydev_preferences_provider"; @@ -81,50 +82,44 @@ public static IExtension[] getExtensions(String type) { return extensions; } - @SuppressWarnings("unchecked") + /** + * @param type the name of the extension + * @return the participant for the given extension type, or null if none + * is registered. + */ public static Object getParticipant(String type) { - //only one participant may be used for this List participants = getParticipants(type); - if(participants.size() == 1){ - return participants.get(0); - } - - if(participants.size() == 0){ + if (participants.isEmpty()){ return null; } - - if(participants.size() > 1){ + if (participants.size() > 1) { + // only one participant may be used for this throw new RuntimeException("More than one participant is registered for type:"+type); } - - throw new RuntimeException("Should never get here!"); - + return participants.get(participants.size() - 1); } /** * @param type the extension we want to get * @return a list of classes created from those extensions */ - @SuppressWarnings("unchecked") public static List getParticipants(String type) { - if(testingParticipants != null){ - List list = testingParticipants.get(type); - if(list == null){ - list = new ArrayList(); + List list = null; + if (testingParticipants != null) { + list = testingParticipants.get(type); + if (list == null) { + list = new ArrayList(); } - return list; + return list; } - - ArrayList list = new ArrayList(); - IExtension[] extensions = getExtensions(type); + + list = new ArrayList(); // For each extension ... - for (int i = 0; i < extensions.length; i++) { - IExtension extension = extensions[i]; - IConfigurationElement[] elements = extension.getConfigurationElements(); + for (IExtension extension : getExtensions(type)) { + IConfigurationElement[] elements = extension + .getConfigurationElements(); // For each member of the extension ... - for (int j = 0; j < elements.length; j++) { - IConfigurationElement element = elements[j]; - + for (IConfigurationElement element : elements) { try { list.add(element.createExecutableExtension("class")); } catch (Exception e) { @@ -134,6 +129,4 @@ public static List getParticipants(String type) { } return list; } - - } diff --git a/plugins/org.python.pydev.core/tests/org/python/pydev/core/TestCaseUtils.java b/plugins/org.python.pydev.core/tests/org/python/pydev/core/TestCaseUtils.java index a058ae7cb..4e981c412 100644 --- a/plugins/org.python.pydev.core/tests/org/python/pydev/core/TestCaseUtils.java +++ b/plugins/org.python.pydev.core/tests/org/python/pydev/core/TestCaseUtils.java @@ -10,7 +10,7 @@ import org.python.pydev.core.docutils.StringUtils; -public class TestCaseUtils extends TestCase{ +public abstract class TestCaseUtils extends TestCase{ public static final boolean DEBUG = false; diff --git a/plugins/org.python.pydev.core/tests/org/python/pydev/core/resource_stubs/AbstractIProjectStub.java b/plugins/org.python.pydev.core/tests/org/python/pydev/core/resource_stubs/AbstractIProjectStub.java index 4d30aad3b..71f6f8ec8 100644 --- a/plugins/org.python.pydev.core/tests/org/python/pydev/core/resource_stubs/AbstractIProjectStub.java +++ b/plugins/org.python.pydev.core/tests/org/python/pydev/core/resource_stubs/AbstractIProjectStub.java @@ -9,6 +9,7 @@ import java.net.URI; import java.util.Map; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -29,6 +30,10 @@ public void build(int kind, String builderName, Map args, IProgressMonitor monit public void build(int kind, IProgressMonitor monitor) throws CoreException { throw new RuntimeException("Not implemented"); } + + public void build(IBuildConfiguration config, int kind, IProgressMonitor monitor) throws CoreException { + throw new RuntimeException("Not implemented"); + } public void close(IProgressMonitor monitor) throws CoreException { throw new RuntimeException("Not implemented"); @@ -49,6 +54,18 @@ public void create(IProjectDescription description, int updateFlags, IProgressMo public void delete(boolean deleteContent, boolean force, IProgressMonitor monitor) throws CoreException { throw new RuntimeException("Not implemented"); } + + public IBuildConfiguration getActiveBuildConfig() throws CoreException { + throw new RuntimeException("Not implemented"); + } + + public IBuildConfiguration getBuildConfig(String configName) throws CoreException { + throw new RuntimeException("Not implemented"); + } + + public IBuildConfiguration[] getBuildConfigs() throws CoreException { + throw new RuntimeException("Not implemented"); + } public IContentTypeMatcher getContentTypeMatcher() throws CoreException { throw new RuntimeException("Not implemented"); @@ -85,6 +102,14 @@ public IProject[] getReferencedProjects() throws CoreException { public IProject[] getReferencingProjects() { throw new RuntimeException("Not implemented"); } + + public IBuildConfiguration[] getReferencedBuildConfigs(String configName, boolean includeMissing) throws CoreException { + throw new RuntimeException("Not implemented"); + } + + public boolean hasBuildConfig(String configName) throws CoreException { + throw new RuntimeException("Not implemented"); + } public boolean hasNature(String natureId) throws CoreException { throw new RuntimeException("Not implemented"); diff --git a/plugins/org.python.pydev/plugin.xml b/plugins/org.python.pydev/plugin.xml index 66ebf51d7..0b1263b9c 100644 --- a/plugins/org.python.pydev/plugin.xml +++ b/plugins/org.python.pydev/plugin.xml @@ -1048,6 +1048,7 @@ + + + + + + + + + This extension point allows the default refactoring behaviors to be extended in cases where the default refactorer fails in a given operation. Extensions added to this point may have a different implementation of the same operation, and should return a clear indication of whether the operation succeeded or failed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/plugins/org.python.pydev/src/org/python/pydev/builder/PyDevBuilder.java b/plugins/org.python.pydev/src/org/python/pydev/builder/PyDevBuilder.java index d4ebf7fa6..b99089eb6 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/builder/PyDevBuilder.java +++ b/plugins/org.python.pydev/src/org/python/pydev/builder/PyDevBuilder.java @@ -55,7 +55,6 @@ public class PyDevBuilder extends IncrementalProjectBuilder { * * @return a list of visitors for building the application. */ - @SuppressWarnings("unchecked") public List getVisitors() { List list = new ArrayList(); list.add(new PyTodoVisitor()); diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/AbstractPyRefactoring.java b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/AbstractPyRefactoring.java index 46119d74f..4f53c136f 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/AbstractPyRefactoring.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/AbstractPyRefactoring.java @@ -16,35 +16,45 @@ /** * @author Fabio Zadrozny */ -public abstract class AbstractPyRefactoring implements IPyRefactoring{ - +public abstract class AbstractPyRefactoring implements IPyRefactoring { /** - * Instead of making all static, let's use a singleton... it may be useful... + * Instead of making all static, let's use a singleton... it may be + * useful... */ - private volatile static IPyRefactoring pyRefactoring; + private volatile static RefactoringChain pyRefactoring; - /** - * - * @return the pyrefactoring instance that is available (can be some plugin contribution). + * @return the pyrefactoring instance that is available (can be some plugin + * contribution). */ - public synchronized static IPyRefactoring getPyRefactoring(){ - if (AbstractPyRefactoring.pyRefactoring == null){ - IPyRefactoring r = (IPyRefactoring) ExtensionHelper.getParticipant(ExtensionHelper.PYDEV_REFACTORING); - if(r != null){ - AbstractPyRefactoring.pyRefactoring = r; - }else{ - throw new RuntimeException("Refactoring engine not in place! com.python.pydev.refactoring plugin not in place?"); + public synchronized static IPyRefactoring getPyRefactoring() { + // The default refactoring implementation is placed at the front of the chain. Other user + // refactoring implementations, if any, are added afterwards. + if (AbstractPyRefactoring.pyRefactoring == null) { + RefactoringChain chain = new RefactoringChain(); + chain.addRefactorer(ExtensionHelper.getParticipant(ExtensionHelper.PYDEV_REFACTORING)); + + if (!chain.hasRefactorers()) { + throw new RuntimeException( + "Refactoring engine not in place! com.python.pydev.refactoring plugin not in place?"); } + + chain.addAllRefactorers(ExtensionHelper + .getParticipants(ExtensionHelper.PYDEV_USER_REFACTORING)); + + AbstractPyRefactoring.pyRefactoring = chain; } + return AbstractPyRefactoring.pyRefactoring; } - + /** + * Use only for testing!!! + * + * @param refactorer + */ public synchronized static void setPyRefactoring(IPyRefactoring refactorer) { - pyRefactoring = refactorer; + pyRefactoring.clear(); + pyRefactoring.addRefactorer(refactorer); } - - - } diff --git a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyNodeModel.java b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/HierarchyNodeModel.java similarity index 98% rename from plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyNodeModel.java rename to plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/HierarchyNodeModel.java index 25fc8ba47..b6b2b219e 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/ui/hierarchy/HierarchyNodeModel.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/HierarchyNodeModel.java @@ -7,7 +7,7 @@ /* * Created on Apr 10, 2006 */ -package com.python.pydev.ui.hierarchy; +package org.python.pydev.editor.refactoring; import java.util.ArrayList; import java.util.List; diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring.java b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring.java index fc1dd2cc1..465a39092 100644 --- a/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring.java @@ -28,7 +28,7 @@ public interface IPyRefactoring { /** - * Rename something (class, method, local...) + * Rename something (class, method, local...). Returns null to indicate no rename was performed. */ public String rename(RefactoringRequest request); diff --git a/plugins/com.python.pydev/src/com/python/pydev/refactoring/IPyRefactoring2.java b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring2.java similarity index 91% rename from plugins/com.python.pydev/src/com/python/pydev/refactoring/IPyRefactoring2.java rename to plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring2.java index 38be52cd0..6a5f70e95 100644 --- a/plugins/com.python.pydev/src/com/python/pydev/refactoring/IPyRefactoring2.java +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/IPyRefactoring2.java @@ -4,7 +4,7 @@ * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ -package com.python.pydev.refactoring; +package org.python.pydev.editor.refactoring; import java.io.File; import java.util.HashSet; @@ -15,11 +15,8 @@ import org.eclipse.core.runtime.OperationCanceledException; import org.python.pydev.core.Tuple; import org.python.pydev.editor.codecompletion.revisited.visitors.AssignDefinition; -import org.python.pydev.editor.refactoring.RefactoringRequest; import org.python.pydev.parser.visitors.scope.ASTEntry; -import com.python.pydev.ui.hierarchy.HierarchyNodeModel; - /** * This is an additional interface for refactoring, so that other actions (and not only the * default ones provided in the org.python.pydev can be implemented). diff --git a/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/RefactoringChain.java b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/RefactoringChain.java new file mode 100644 index 000000000..adf330ef1 --- /dev/null +++ b/plugins/org.python.pydev/src/org/python/pydev/editor/refactoring/RefactoringChain.java @@ -0,0 +1,162 @@ +package org.python.pydev.editor.refactoring; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.OperationCanceledException; +import org.python.pydev.core.Tuple; +import org.python.pydev.editor.codecompletion.revisited.visitors.AssignDefinition; +import org.python.pydev.editor.model.ItemPointer; +import org.python.pydev.parser.visitors.scope.ASTEntry; + + +/** + * An ordered collection of refactorers. Refactoring operations are attempted for each instance + * until one completes successfully. + * + * Currently, only findDefinition() calls are chained; all other calls will be invoked on at most + * one refactorer instance. For calls to be usefully chained, each call must return some indication + * of whether it is considered to have failed or succeeded. Clarification of IPyRefactoring and + * IPyRefactoring2 semantics would allow for chaining to be extended to additional methods. + * + * It is prudent to add refactorers with a high success rate to the front of the chain, to minimize + * extra processing. + * + * @author Haw-Bin Chai + */ +public class RefactoringChain implements IPyRefactoring, IPyRefactoring2 { + // LinkedHashSet's preserve insertion order. Refactorer instances may not appear more than once + // in each collection. + private LinkedHashSet refactorers; + private LinkedHashSet refactorers2; + + public RefactoringChain() { + refactorers = new LinkedHashSet(); + refactorers2 = new LinkedHashSet(); + } + + /** + * Initializes the chain with the given refactorer. + * + * @param defaultRefactorer + */ + public RefactoringChain(Object defaultRefactorer) { + this(); + addRefactorer(defaultRefactorer); + } + + /** + * Calls findClassHierarchy() on the first composed IPyRefactoring2. Returns null if + * there is no such refactoring instance to use. + */ + @Override + public HierarchyNodeModel findClassHierarchy(RefactoringRequest request, + boolean findOnlyParents) { + Iterator it = refactorers2.iterator(); + if (it.hasNext()) { + return it.next().findClassHierarchy(request, findOnlyParents); + } + return null; + } + + /** + * Calls areAllInSameClassHierarchy on the first composed IPyRefactoring2. Returns false if + * there is no such refactoring instance to use. + */ + @Override + public boolean areAllInSameClassHierarchy(List defs) { + Iterator it = refactorers2.iterator(); + if (it.hasNext()) { + return it.next().areAllInSameClassHierarchy(defs); + } + return false; + } + + /** + * Calls findAllOccurrences on the first composed IPyRefactoring2. Returns null if there is no + * such refactoring instance to use. + */ + @Override + public Map, HashSet> findAllOccurrences( + RefactoringRequest req) throws OperationCanceledException, + CoreException { + Iterator it = refactorers2.iterator(); + if (it.hasNext()) { + return it.next().findAllOccurrences(req); + } + return null; + } + + @Override + public String getName() { + return this.getClass().getName(); + } + + /** + * Calls rename() on the first composed IPyRefactoring. Returns null if there is no such + * refactoring instance to use. + */ + @Override + public String rename(RefactoringRequest request) { + Iterator it = refactorers.iterator(); + if (it.hasNext()) { + return it.next().rename(request); + } + return null; + } + + /** + * Calls findDefinition() on EACH composed IPyRefactoring until a non-empty array is returned. + */ + @Override + public ItemPointer[] findDefinition(RefactoringRequest request) + throws TooManyMatchesException { + for (IPyRefactoring refactorer : refactorers) { + ItemPointer[] items = refactorer.findDefinition(request); + if (items.length > 0) { + return items; + } + } + return new ItemPointer[0]; + } + + /** + * Adds refactorer to the internal collections of composed refactorers, if it is an instance of + * IPyRefactoring or IPyRefactoring2. + * + * @param refactorer + */ + public void addRefactorer(Object refactorer) { + if (refactorer instanceof IPyRefactoring) { + refactorers.add((IPyRefactoring) refactorer); + } + if (refactorer instanceof IPyRefactoring2) { + refactorers2.add((IPyRefactoring2) refactorer); + } + } + + public void addAllRefactorers(List refactorers) { + for (Object refactorer : refactorers) { + addRefactorer(refactorer); + } + } + + /** + * @return true if at least one of each of IPyRefactoring and IPyRefactoring2 have been added + * to this chain, and false otherwise. + */ + public boolean hasRefactorers() { + return !refactorers.isEmpty() && !refactorers2.isEmpty(); + } + + public void clear() { + refactorers.clear(); + refactorers2.clear(); + } +} diff --git a/plugins/org.python.pydev/tests_navigator/org/python/pydev/navigator/WorkspaceStub.java b/plugins/org.python.pydev/tests_navigator/org/python/pydev/navigator/WorkspaceStub.java index eeb09975d..2eb6592af 100644 --- a/plugins/org.python.pydev/tests_navigator/org/python/pydev/navigator/WorkspaceStub.java +++ b/plugins/org.python.pydev/tests_navigator/org/python/pydev/navigator/WorkspaceStub.java @@ -10,6 +10,7 @@ import java.net.URI; import java.util.Map; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFilterMatcherDescriptor; import org.eclipse.core.resources.IMarker; @@ -35,305 +36,217 @@ import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.jobs.ISchedulingRule; -public class WorkspaceStub implements IWorkspace{ - - +public class WorkspaceStub implements IWorkspace { public Object getAdapter(Class adapter) { - return null; } - public void addResourceChangeListener(IResourceChangeListener listener) { - - } - - public void addResourceChangeListener(IResourceChangeListener listener, int eventMask) { - - + public void addResourceChangeListener(IResourceChangeListener listener, + int eventMask) { } - - public ISavedState addSaveParticipant(Plugin plugin, ISaveParticipant participant) throws CoreException { - + public ISavedState addSaveParticipant(Plugin plugin, + ISaveParticipant participant) throws CoreException { return null; } - - public ISavedState addSaveParticipant(String pluginId, ISaveParticipant participant) throws CoreException { - + public ISavedState addSaveParticipant(String pluginId, + ISaveParticipant participant) throws CoreException { return null; } - public void build(int kind, IProgressMonitor monitor) throws CoreException { - - } - + public void build(IBuildConfiguration[] buildConfigs, int kind, + boolean buildReferences, IProgressMonitor monitor) + throws CoreException { + } + public void checkpoint(boolean build) { - - } - public IProject[][] computePrerequisiteOrder(IProject[] projects) { - return null; } - public ProjectOrder computeProjectOrder(IProject[] projects) { - return null; } - - public IStatus copy(IResource[] resources, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { - + public IStatus copy(IResource[] resources, IPath destination, + boolean force, IProgressMonitor monitor) throws CoreException { return null; } - - public IStatus copy(IResource[] resources, IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException { - + public IStatus copy(IResource[] resources, IPath destination, + int updateFlags, IProgressMonitor monitor) throws CoreException { return null; } - - public IStatus delete(IResource[] resources, boolean force, IProgressMonitor monitor) throws CoreException { - + public IStatus delete(IResource[] resources, boolean force, + IProgressMonitor monitor) throws CoreException { return null; } - - public IStatus delete(IResource[] resources, int updateFlags, IProgressMonitor monitor) throws CoreException { - + public IStatus delete(IResource[] resources, int updateFlags, + IProgressMonitor monitor) throws CoreException { return null; } - public void deleteMarkers(IMarker[] markers) throws CoreException { - - } - public void forgetSavedTree(String pluginId) { - - } - public IFilterMatcherDescriptor[] getFilterMatcherDescriptors() { - return null; } - - public IFilterMatcherDescriptor getFilterMatcherDescriptor(String filterMatcherId) { - + public IFilterMatcherDescriptor getFilterMatcherDescriptor( + String filterMatcherId) { return null; } - public IProjectNatureDescriptor[] getNatureDescriptors() { - return null; } - public IProjectNatureDescriptor getNatureDescriptor(String natureId) { - return null; } - public Map getDanglingReferences() { - return null; } - public IWorkspaceDescription getDescription() { - return null; } - public IWorkspaceRoot getRoot() { return new WorkspaceRootStub(); } - public IResourceRuleFactory getRuleFactory() { - return null; } - public ISynchronizer getSynchronizer() { - return null; } - public boolean isAutoBuilding() { - return false; } - public boolean isTreeLocked() { - return false; } - - public IProjectDescription loadProjectDescription(IPath projectDescriptionFile) throws CoreException { - + public IProjectDescription loadProjectDescription( + IPath projectDescriptionFile) throws CoreException { return null; } - - public IProjectDescription loadProjectDescription(InputStream projectDescriptionFile) throws CoreException { - + public IProjectDescription loadProjectDescription( + InputStream projectDescriptionFile) throws CoreException { return null; } - - public IStatus move(IResource[] resources, IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { - + public IStatus move(IResource[] resources, IPath destination, + boolean force, IProgressMonitor monitor) throws CoreException { return null; } - - public IStatus move(IResource[] resources, IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException { - + public IStatus move(IResource[] resources, IPath destination, + int updateFlags, IProgressMonitor monitor) throws CoreException { + return null; + } + + public IBuildConfiguration newBuildConfig(String projectName, + String configName) { return null; } - public IProjectDescription newProjectDescription(String projectName) { - return null; } - public void removeResourceChangeListener(IResourceChangeListener listener) { - - } - public void removeSaveParticipant(Plugin plugin) { - - } - public void removeSaveParticipant(String pluginId) { - - } - - public void run(IWorkspaceRunnable action, ISchedulingRule rule, int flags, IProgressMonitor monitor) throws CoreException { - - + public void run(IWorkspaceRunnable action, ISchedulingRule rule, int flags, + IProgressMonitor monitor) throws CoreException { } - - public void run(IWorkspaceRunnable action, IProgressMonitor monitor) throws CoreException { - - + public void run(IWorkspaceRunnable action, IProgressMonitor monitor) + throws CoreException { } - - public IStatus save(boolean full, IProgressMonitor monitor) throws CoreException { - + public IStatus save(boolean full, IProgressMonitor monitor) + throws CoreException { return null; } - - public void setDescription(IWorkspaceDescription description) throws CoreException { - - + public void setDescription(IWorkspaceDescription description) + throws CoreException { } - public void setWorkspaceLock(WorkspaceLock lock) { - - } - public String[] sortNatureSet(String[] natureIds) { - return null; } - public IStatus validateEdit(IFile[] files, Object context) { - return null; } - public IStatus validateFiltered(IResource resource) { - return null; } - public IStatus validateLinkLocation(IResource resource, IPath location) { - return null; } - public IStatus validateLinkLocationURI(IResource resource, URI location) { - return null; } - public IStatus validateName(String segment, int typeMask) { - return null; } - public IStatus validateNatureSet(String[] natureIds) { - return null; } - public IStatus validatePath(String path, int typeMask) { - return null; } - public IStatus validateProjectLocation(IProject project, IPath location) { - return null; } - public IStatus validateProjectLocationURI(IProject project, URI location) { - return null; } - public IPathVariableManager getPathVariableManager() { - return null; } - }