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

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

/*******************************************************************************
* 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.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.search.IDLTKSearchConstants;
import org.eclipse.dltk.core.search.MethodReferenceMatch;
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.internal.corext.refactoring.RefactoringAvailabilityTester;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
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.nodes.PHPCallExpression;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.ReplaceEdit;
import org.pdtextensions.core.PHPType;
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 RenameMethodProcessor extends PHPRenameProcessor {
  private List<IMethod> overridingMethods;

  public RenameMethodProcessor(IMethod modelElement) {
    super(modelElement);
  }

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

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

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

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

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

  @Override
  protected RefactoringStatus renameDeclaration(IProgressMonitor pm) throws CoreException {
    RefactoringStatus result = super.renameDeclaration(pm);
    if (result.hasFatalError()) return result;

    for (IMethod overridingMethods: getOverridingMethods(pm)) {
      result = renameDeclaration(pm, overridingMethods, overridingMethods.getSourceModule());
      if (result.hasFatalError()) return result;
    }

    return result;
  }

  @Override
  protected RefactoringStatus updateReferences(IProgressMonitor pm) throws CoreException {
    RefactoringStatus result = updateReferences(pm, (IMethod) modelElement);
    if (result.hasFatalError()) return result;

    for (IMethod overridingMethods: getOverridingMethods(pm)) {
      result = updateReferences(pm, overridingMethods);
      if (result.hasFatalError()) return result;
    }

    return result;
  }

  private RefactoringStatus updateReferences(IProgressMonitor pm, final IMethod method) throws CoreException {
    new SearchEngine().search(
      SearchPattern.createPattern(
        method,
        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 MethodReferenceMatch && ((MethodReferenceMatch) match).getNode() instanceof PHPCallExpression && match.getElement() instanceof IModelElement) {
              final ISourceModule module = (ISourceModule) ((IModelElement) match.getElement()).getAncestor(IModelElement.SOURCE_MODULE);
              if (module != null && RefactoringAvailabilityTester.isRenameAvailable(module)) {
                PHPCallExpression expression = (PHPCallExpression) ((MethodReferenceMatch) match).getNode();
                if (expression.getReceiver() == null) {
                  if (expression.getCallName() instanceof FullyQualifiedReference) {
                    int offset;
                    if (((FullyQualifiedReference) expression.getCallName()).getNamespace() == null) {
                      offset = expression.getCallName().sourceStart();
                    } else {
                      if ("\\".equals(((FullyQualifiedReference) expression.getCallName()).getNamespace().getName())) {
                        offset = ((FullyQualifiedReference) expression.getCallName()).getNamespace().sourceEnd();
                      } else {
                        offset = ((FullyQualifiedReference) expression.getCallName()).getNamespace().sourceEnd() + 1;
                      }
                    }

                    try {
                      addTextEdit(
                        changeManager.get(module),
                        getProcessorName(),
                        new ReplaceEdit(offset, method.getElementName().length(), getNewElementName())
                      );
                    } catch (MalformedTreeException e) {
                      // conflicting update -> omit text match
                    }
                  }
                } else {
                  IModelElement sourceElement = PDTModelUtils.getSourceElement(module, expression.getCallName().sourceStart(), expression.getCallName().matchLength());
                  if (sourceElement != null && sourceElement.getElementType() == IModelElement.METHOD) {
                    IType declaringType = ((IMethod) sourceElement).getDeclaringType();
                    if (declaringType != null && new PHPType(declaringType).isInstanceOf(method.getDeclaringType())) {
                      try {
                        addTextEdit(
                          changeManager.get(module),
                          getProcessorName(),
                          new ReplaceEdit(expression.getCallName().sourceStart(), method.getElementName().length(), getNewElementName())
                        );
                      } catch (MalformedTreeException e) {
                        // conflicting update -> omit text match
                      }
                    }
                  }
                }
              }
            }
          }
      },
      new SubProgressMonitor(pm, 1000)
    );

    return new RefactoringStatus();
  }

  private List<IMethod> getOverridingMethods(IProgressMonitor pm) throws ModelException {
    if (overridingMethods == null) {
      overridingMethods = new ArrayList<IMethod>();
      IType declaringType = ((IMethod) modelElement).getDeclaringType();
      if (declaringType != null) {
        for (IType subType: declaringType.newTypeHierarchy(pm).getAllSubtypes(declaringType)) {
          for (IMethod methodBySubType: subType.getMethods()) {
            if (methodBySubType.getElementName().equals(getCurrentElementName())) {
              overridingMethods.add(methodBySubType);
              break;
            }
          }
        }
      }
    }

    return overridingMethods;
  }
}
TOP

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

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.