Search in sources :

Example 1 with IRefactorRenameProcess

use of com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess in project Pydev by fabioz.

the class PyRenameEntryPoint method checkFinalConditions.

@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException {
    // Clear (will be filled now).
    allChanges.clear();
    fRequest.pushMonitor(pm);
    RefactoringStatus status = new RefactoringStatus();
    try {
        if (this.fRequest.isModuleRenameRefactoringRequest() && this.fRequest.getSimpleResourceRename() && this.fRequest.getIFileResource() != null) {
            // Ok, simple resource change
            return status;
        }
        final Map<IPath, Tuple<TextChange, MultiTextEdit>> fileToChangeInfo = new HashMap<IPath, Tuple<TextChange, MultiTextEdit>>();
        final Set<IResource> affectedResources = new HashSet<>();
        for (RefactoringRequest request : this.fRequest.getRequests()) {
            if (request.isModuleRenameRefactoringRequest()) {
                boolean searchInit = true;
                IModule module = request.getTargetNature().getAstManager().getModule(request.inputName, request.getTargetNature(), !searchInit, // i.e.: the parameter is dontSearchInit (so, pass in negative form to search)
                new BaseModuleRequest(request.acceptTypeshed));
                if (module != null) {
                    String partName = module.getName().endsWith(".__init__") ? "package" : "module";
                    status.addFatalError("Unable to perform module rename because a " + partName + " named: " + request.inputName + " already exists.");
                    return status;
                }
            }
            List<IRefactorRenameProcess> processes = pyReferenceSearcher.getProcesses(request);
            if (processes == null || processes.size() == 0) {
                status.addFatalError("Refactoring Process not defined: the refactoring cycle did not complete correctly.");
                return status;
            }
            request.getMonitor().beginTask("Finding references", processes.size());
            try {
                pyReferenceSearcher.search(request);
            } catch (PyReferenceSearcher.SearchException e) {
                status.addFatalError(e.getMessage());
                return status;
            }
            TextEditCreation textEditCreation = new TextEditCreation(request.qualifier, request.inputName, request.getModule().getName(), request.getDoc(), processes, status, request.getIFile()) {

                @Override
                protected Tuple<TextChange, MultiTextEdit> getTextFileChange(IFile workspaceFile, IDocument doc) {
                    if (workspaceFile == null) {
                        // used for tests
                        TextChange docChange = PyDocumentChange.create("Current module: " + moduleName, doc);
                        MultiTextEdit rootEdit = new MultiTextEdit();
                        docChange.setEdit(rootEdit);
                        docChange.setKeepPreviewEdits(true);
                        allChanges.add(docChange);
                        return new Tuple<TextChange, MultiTextEdit>(docChange, rootEdit);
                    }
                    IPath fullPath = workspaceFile.getFullPath();
                    Tuple<TextChange, MultiTextEdit> tuple = fileToChangeInfo.get(fullPath);
                    if (tuple == null) {
                        TextFileChange docChange = new SynchronizedTextFileChange("RenameChange: " + inputName, workspaceFile);
                        docChange.setTextType("py");
                        MultiTextEdit rootEdit = new MultiTextEdit();
                        docChange.setEdit(rootEdit);
                        docChange.setKeepPreviewEdits(true);
                        allChanges.add(docChange);
                        affectedResources.add(workspaceFile);
                        tuple = new Tuple<TextChange, MultiTextEdit>(docChange, rootEdit);
                        fileToChangeInfo.put(fullPath, tuple);
                    }
                    return tuple;
                }

                @Override
                protected PyRenameResourceChange createResourceChange(IResource resourceToRename, String newName, RefactoringRequest request) {
                    IContainer target = null;
                    if (request instanceof ModuleRenameRefactoringRequest) {
                        target = ((ModuleRenameRefactoringRequest) request).getTarget();
                    }
                    PyRenameResourceChange change = new PyRenameResourceChange(resourceToRename, initialName, newName, StringUtils.format("Changing %s to %s", initialName, inputName), target);
                    allChanges.add(change);
                    affectedResources.add(resourceToRename);
                    return change;
                }
            };
            textEditCreation.fillRefactoringChangeObject(request, context);
            if (status.hasFatalError() || request.getMonitor().isCanceled()) {
                return status;
            }
        }
        checkResourcesToBeChanged(affectedResources, context, status);
    } catch (OperationCanceledException e) {
    // OK
    } finally {
        fRequest.popMonitor().done();
    }
    return status;
}
Also used : IModule(org.python.pydev.core.IModule) IFile(org.eclipse.core.resources.IFile) PyRenameResourceChange(com.python.pydev.analysis.refactoring.changes.PyRenameResourceChange) HashMap(java.util.HashMap) RefactoringRequest(org.python.pydev.ast.refactoring.RefactoringRequest) ModuleRenameRefactoringRequest(org.python.pydev.ast.refactoring.ModuleRenameRefactoringRequest) PyRefactoringRequest(org.python.pydev.ast.refactoring.PyRefactoringRequest) IPyRefactoringRequest(org.python.pydev.ast.refactoring.IPyRefactoringRequest) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) RefactoringStatus(org.eclipse.ltk.core.refactoring.RefactoringStatus) ModuleRenameRefactoringRequest(org.python.pydev.ast.refactoring.ModuleRenameRefactoringRequest) IRefactorRenameProcess(com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess) IContainer(org.eclipse.core.resources.IContainer) HashSet(java.util.HashSet) IPath(org.eclipse.core.runtime.IPath) BaseModuleRequest(org.python.pydev.core.BaseModuleRequest) TextChange(org.eclipse.ltk.core.refactoring.TextChange) TextFileChange(org.eclipse.ltk.core.refactoring.TextFileChange) SynchronizedTextFileChange(org.python.pydev.refactoring.core.base.SynchronizedTextFileChange) SynchronizedTextFileChange(org.python.pydev.refactoring.core.base.SynchronizedTextFileChange) Tuple(org.python.pydev.shared_core.structure.Tuple) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) IResource(org.eclipse.core.resources.IResource) IDocument(org.eclipse.jface.text.IDocument)

Example 2 with IRefactorRenameProcess

use of com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess in project Pydev by fabioz.

the class PyReferenceSearcher method prepareSearch.

/**
 * Prepares for an upcoming use of {@link #search(RefactoringRequest)}.  This must be called
 * before a search is performed.
 *
 * @param request the search request.
 * @throws SearchException if the AST can not be found or the definition for the
 *     identifier isn't valid or can't otherwise be searched.
 * @throws BadLocationException
 * @throws TooManyMatchesException
 */
public void prepareSearch(RefactoringRequest request) throws SearchException, TooManyMatchesException, BadLocationException {
    List<IRefactorRenameProcess> processes = requestToProcesses.get(request);
    // Clear the existing processes for the request
    processes.clear();
    ItemPointer[] pointers;
    if (request.isModuleRenameRefactoringRequest()) {
        IModule module = request.getModule();
        pointers = new ItemPointer[] { new ItemPointer(request.file, new Location(0, 0), new Location(0, 0), new Definition(1, 1, "", null, null, module, false), null) };
    } else {
        SimpleNode ast = request.getAST();
        if (ast == null) {
            throw new SearchException("AST not generated (syntax error).");
        }
        IPyRefactoring pyRefactoring = AbstractPyRefactoring.getPyRefactoring();
        request.communicateWork("Finding definition");
        pointers = pyRefactoring.findDefinition(request);
    }
    if (pointers.length == 0) {
        // no definition found
        IRefactorRenameProcess p = RefactorProcessFactory.getRenameAnyProcess();
        processes.add(p);
    } else {
        for (ItemPointer pointer : pointers) {
            if (pointer.definition == null) {
                throw new SearchException(INVALID_DEFINITION + pointer);
            }
            IRefactorRenameProcess p = RefactorProcessFactory.getProcess(pointer.definition, request);
            if (p == null) {
                throw new SearchException(INVALID_DEFINITION + pointer.definition);
            }
            processes.add(p);
        }
    }
    if (processes.isEmpty()) {
        throw new SearchException("The pre-conditions were not satisfied.");
    }
}
Also used : IModule(org.python.pydev.core.IModule) Definition(org.python.pydev.ast.codecompletion.revisited.visitors.Definition) IPyRefactoring(org.python.pydev.ast.refactoring.IPyRefactoring) IRefactorRenameProcess(com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess) ItemPointer(org.python.pydev.ast.item_pointer.ItemPointer) Location(org.python.pydev.shared_core.structure.Location) SimpleNode(org.python.pydev.parser.jython.SimpleNode)

Example 3 with IRefactorRenameProcess

use of com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess in project Pydev by fabioz.

the class PyReferenceSearcher method search.

/**
 * Searches for references to the identifier in the request.
 *
 * <p>{@link #prepareSearch(RefactoringRequest)} must be called before
 * {@link #search(RefactoringRequest)} or else results are undefined.
 *
 * @param request the search request
 * @throws SearchException if an exception occurs in the process of finding references.
 * @throws OperationCanceledException if the request is canceled.
 */
public void search(RefactoringRequest request) throws SearchException, OperationCanceledException {
    for (IRefactorRenameProcess p : requestToProcesses.get(request)) {
        request.checkCancelled();
        // Clear references found from a previous invocation
        p.clear();
        RefactoringStatus status = new RefactoringStatus();
        request.pushMonitor(new SubProgressMonitor(request.getMonitor(), 1));
        try {
            p.findReferencesToRename(request, status);
        } finally {
            request.popMonitor().done();
        }
        if (status.hasFatalError()) {
            throw new SearchException(status.getEntryWithHighestSeverity().getMessage());
        }
    }
}
Also used : RefactoringStatus(org.eclipse.ltk.core.refactoring.RefactoringStatus) IRefactorRenameProcess(com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess) SubProgressMonitor(org.eclipse.core.runtime.SubProgressMonitor)

Example 4 with IRefactorRenameProcess

use of com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess in project Pydev by fabioz.

the class TextEditCreation method fillRefactoringChangeObject.

/**
 * In this method, changes from the occurrences found in the current document and
 * other files are transformed to the objects required by the Eclipse Language Toolkit
 */
public void fillRefactoringChangeObject(RefactoringRequest request, CheckConditionsContext context) {
    for (IRefactorRenameProcess p : processes) {
        if (status.hasFatalError() || request.getMonitor().isCanceled()) {
            break;
        }
        HashSet<ASTEntry> occurrences = p.getOccurrences();
        if (docOccurrences == null) {
            docOccurrences = occurrences;
        } else {
            docOccurrences.addAll(occurrences);
        }
        Map<Tuple<String, File>, HashSet<ASTEntry>> occurrencesInOtherFiles = p.getOccurrencesInOtherFiles();
        if (fileOccurrences == null) {
            fileOccurrences = occurrencesInOtherFiles;
        } else {
            // iterate in a copy
            for (Map.Entry<Tuple<String, File>, HashSet<ASTEntry>> entry : new HashMap<Tuple<String, File>, HashSet<ASTEntry>>(occurrencesInOtherFiles).entrySet()) {
                HashSet<ASTEntry> set = occurrencesInOtherFiles.get(entry.getKey());
                if (set == null) {
                    occurrencesInOtherFiles.put(entry.getKey(), entry.getValue());
                } else {
                    set.addAll(entry.getValue());
                }
            }
        }
    }
    createCurrModuleChange(request);
    createOtherFileChanges(request);
}
Also used : ASTEntry(org.python.pydev.parser.visitors.scope.ASTEntry) IRefactorRenameProcess(com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess) HashMap(java.util.HashMap) Map(java.util.Map) Tuple(org.python.pydev.shared_core.structure.Tuple) HashSet(java.util.HashSet)

Example 5 with IRefactorRenameProcess

use of com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess in project Pydev by fabioz.

the class PyReferenceSearcher method getWorkspaceReferences.

/**
 * Returns the set of references found in the workspace.
 *
 * <p>{@link #prepareSearch(RefactoringRequest)} and {@link #search(RefactoringRequest)} must be
 * called before {@link #getProcesses(RefactoringRequest)}, or else results are undefined.
 *
 * @param request the search request
 * @return a map that points the references found in other files, but excludes those found locally.
 */
public Map<Tuple<String, File>, HashSet<ASTEntry>> getWorkspaceReferences(RefactoringRequest request) {
    HashMap<Tuple<String, File>, HashSet<ASTEntry>> allReferences = new HashMap<>();
    for (IRefactorRenameProcess p : requestToProcesses.get(request)) {
        Map<Tuple<String, File>, HashSet<ASTEntry>> references = p.getOccurrencesInOtherFiles();
        if (references != null) {
            for (Map.Entry<Tuple<String, File>, HashSet<ASTEntry>> reference : references.entrySet()) {
                Tuple<String, File> key = reference.getKey();
                HashSet<ASTEntry> existingReferences = allReferences.get(key);
                if (existingReferences == null) {
                    existingReferences = new HashSet<>();
                    allReferences.put(key, existingReferences);
                }
                existingReferences.addAll(reference.getValue());
            }
        }
    }
    return allReferences;
}
Also used : HashMap(java.util.HashMap) ASTEntry(org.python.pydev.parser.visitors.scope.ASTEntry) IRefactorRenameProcess(com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess) HashMap(java.util.HashMap) Map(java.util.Map) File(java.io.File) Tuple(org.python.pydev.shared_core.structure.Tuple) HashSet(java.util.HashSet)

Aggregations

IRefactorRenameProcess (com.python.pydev.analysis.refactoring.wizards.IRefactorRenameProcess)6 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 Tuple (org.python.pydev.shared_core.structure.Tuple)3 Map (java.util.Map)2 RefactoringStatus (org.eclipse.ltk.core.refactoring.RefactoringStatus)2 IModule (org.python.pydev.core.IModule)2 ASTEntry (org.python.pydev.parser.visitors.scope.ASTEntry)2 PyRenameResourceChange (com.python.pydev.analysis.refactoring.changes.PyRenameResourceChange)1 File (java.io.File)1 IContainer (org.eclipse.core.resources.IContainer)1 IFile (org.eclipse.core.resources.IFile)1 IResource (org.eclipse.core.resources.IResource)1 IPath (org.eclipse.core.runtime.IPath)1 OperationCanceledException (org.eclipse.core.runtime.OperationCanceledException)1 SubProgressMonitor (org.eclipse.core.runtime.SubProgressMonitor)1 IDocument (org.eclipse.jface.text.IDocument)1 TextChange (org.eclipse.ltk.core.refactoring.TextChange)1 TextFileChange (org.eclipse.ltk.core.refactoring.TextFileChange)1 MultiTextEdit (org.eclipse.text.edits.MultiTextEdit)1