Package org.pdtextensions.internal.corext.refactoring.rename

Source Code of org.pdtextensions.internal.corext.refactoring.rename.RenameTypeProcessor

/*******************************************************************************
* Copyright (c) 2013-2014 The PDT Extension Group (https://github.com/pdt-eg)
* 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
******************************************************************************/
package org.pdtextensions.internal.corext.refactoring.rename;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.core.DLTKContentTypeManager;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.SourceParserUtil;
import org.eclipse.dltk.core.search.IDLTKSearchConstants;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.core.search.SearchMatch;
import org.eclipse.dltk.core.search.SearchParticipant;
import org.eclipse.dltk.core.search.SearchPattern;
import org.eclipse.dltk.core.search.SearchRequestor;
import org.eclipse.dltk.core.search.TypeReferenceMatch;
import org.eclipse.dltk.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.dltk.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.resource.RenameResourceChange;
import org.eclipse.php.internal.core.PHPLanguageToolkit;
import org.eclipse.php.internal.core.compiler.ast.nodes.FullyQualifiedReference;
import org.eclipse.php.internal.core.compiler.ast.visitor.PHPASTVisitor;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.ReplaceEdit;
import org.pdtextensions.core.PHPType;
import org.pdtextensions.core.ui.PEXUIPlugin;
import org.pdtextensions.core.ui.refactoring.IPHPRefactorings;
import org.pdtextensions.core.ui.refactoring.IRefactoringProcessorIds;
import org.pdtextensions.core.util.PDTModelUtils;
import org.pdtextensions.internal.corext.refactoring.Checks;
import org.pdtextensions.internal.corext.refactoring.RefactoringCoreMessages;

/**
* @since 0.17.0
*/
@SuppressWarnings("restriction")
public class RenameTypeProcessor extends PHPRenameProcessor {
  public RenameTypeProcessor(IType modelElement) {
    super(modelElement);
  }

  @Override
  public RefactoringStatus checkNewElementName(String newName) throws CoreException {
    return Checks.checkTypeName(newName);
  }

  @Override
  public String getIdentifier() {
    return IRefactoringProcessorIds.RENAME_TYPE_PROCESSOR;
  }

  @Override
  public String getProcessorName() {
    return RefactoringCoreMessages.RenameTypeRefactoring_name;
  }

  @Override
  public boolean needsSavedEditors() {
    return true;
  }

  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
    pm.beginTask(RefactoringCoreMessages.RenameRefactoring_checking, 1);

    try {
      DynamicValidationRefactoringChange result = new DynamicValidationRefactoringChange(createRefactoringDescriptor(), getProcessorName(), changeManager.getAllChanges());
      IResource resource = modelElement.getResource();
      if (resource instanceof IFile && willRenameCU((IFile) resource)) {
        result.add(
          new RenameResourceChange(
            resource.getFullPath(),
            resource.getFileExtension().isEmpty() ? getNewElementName() : getNewElementName() + "." + resource.getFileExtension() //$NON-NLS-1$
          )
        );
      }
      pm.worked(1);

      return result;
    } finally {
      changeManager.clear();
      pm.done();
    }
  }

  @Override
  protected IFile[] getChangedFiles() throws CoreException {
    List<IFile> result = new ArrayList<IFile>();
    result.addAll(Arrays.asList(super.getChangedFiles()));

    IResource resource = modelElement.getResource();
    if (resource instanceof IFile && willRenameCU((IFile) resource)) {
      result.add((IFile) resource);
    }

    return result.toArray(new IFile[result.size()]);
  }

  @Override
  protected String getRefactoringId() {
    return IPHPRefactorings.RENAME_TYPE;
  }

  @Override
  protected RefactoringStatus updateReferences(IProgressMonitor pm) throws CoreException {
    new SearchEngine().search(
      SearchPattern.createPattern(
        modelElement,
        IDLTKSearchConstants.REFERENCES,
        SearchPattern.R_FULL_MATCH | SearchPattern.R_ERASURE_MATCH,
        PHPLanguageToolkit.getDefault()
      ),
      new SearchParticipant[]{ SearchEngine.getDefaultSearchParticipant() },
      SearchEngine.createSearchScope(modelElement.getScriptProject()),
      new SearchRequestor() {
        @Override
        public void acceptSearchMatch(final SearchMatch match) throws CoreException {
          if (match instanceof TypeReferenceMatch && match.getElement() instanceof IModelElement) {
            final ISourceModule module = (ISourceModule) ((IModelElement) match.getElement()).getAncestor(IModelElement.SOURCE_MODULE);
            if (module != null && RefactoringAvailabilityTester.isRenameAvailable(module)) {
              ModuleDeclaration moduleDeclaration = SourceParserUtil.getModuleDeclaration(module);
              if (moduleDeclaration != null) {
                try {
                  moduleDeclaration.traverse(new PHPASTVisitor() {
                    @Override
                    public boolean visit(FullyQualifiedReference s) throws Exception {
                      if (s.sourceStart() == match.getOffset() && s.sourceEnd() == match.getOffset() + match.getLength()) {
                        IModelElement sourceElement = PDTModelUtils.getSourceElement(module, s.sourceStart(), s.matchLength());
                        if (sourceElement != null) {
                          IType sourceType = (IType) sourceElement.getAncestor(IModelElement.TYPE);
                          if (sourceType != null && new PHPType(sourceType).isInstanceOf((IType) modelElement)) {
                            int offset;
                            if (s.getNamespace() == null) {
                              offset = s.sourceStart();
                            } else {
                              if ("\\".equals(s.getNamespace().getName())) { //$NON-NLS-1$
                                offset = s.getNamespace().sourceEnd();
                              } else {
                                offset = s.getNamespace().sourceEnd() + 1;
                              }
                            }

                            try {
                              addTextEdit(
                                changeManager.get(module),
                                getProcessorName(),
                                new ReplaceEdit(offset, getCurrentElementName().length(), getNewElementName())
                              );
                            } catch (MalformedTreeException e) {
                              // conflicting update -> omit text match
                            }
                          }
                        }

                        return false;
                      }

                      return true;
                    }
                  });
                } catch (Exception e) {
                  throw new CoreException(new Status(IStatus.ERROR, PEXUIPlugin.PLUGIN_ID, e.getMessage(), e));
                }
              }
            }
          }
        }
      },
      new SubProgressMonitor(pm, 1000)
    );

    return new RefactoringStatus();
  }

  private boolean willRenameCU(IFile file) throws CoreException {
    if (file.isLinked()) return false;
    if (!PDTModelUtils.inResourceWithSameName(file, modelElement.getElementName())) return false;
    if (!DLTKContentTypeManager.isValidFileNameForContentType(PHPLanguageToolkit.getDefault(), getNewElementName() + "." + file.getFileExtension())) return false; //$NON-NLS-1$

    return true;
  }
}
TOP

Related Classes of org.pdtextensions.internal.corext.refactoring.rename.RenameTypeProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.