blob: fbf3f3cb00c40facac620489aa9018beb329631d [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains.python.refactoring.rename;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.rename.RenamePsiFileProcessor;
import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo;
import com.intellij.usageView.UsageInfo;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyImportElement;
import com.jetbrains.python.psi.PyImportStatementBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author yole
*/
public class RenamePyFileProcessor extends RenamePsiFileProcessor {
@Override
public boolean canProcessElement(@NotNull PsiElement element) {
return element instanceof PyFile;
}
@Override
public PsiElement substituteElementToRename(PsiElement element, @Nullable Editor editor) {
PyFile file = (PyFile) element;
if (file.getName().equals(PyNames.INIT_DOT_PY)) {
return file.getParent();
}
return element;
}
@NotNull
@Override
public Collection<PsiReference> findReferences(PsiElement element) {
final List<PsiReference> results = new ArrayList<PsiReference>();
for (PsiReference reference : super.findReferences(element)) {
if (isNotAliasedInImportElement(reference)) {
results.add(reference);
}
}
return results;
}
@Override
public void findCollisions(PsiElement element,
final String newName,
Map<? extends PsiElement, String> allRenames,
List<UsageInfo> result) {
final String newFileName = FileUtil.getNameWithoutExtension(newName);
if (!PyNames.isIdentifier(newFileName)) {
List<UsageInfo> usages = new ArrayList<UsageInfo>(result);
for (UsageInfo usageInfo : usages) {
final PyImportStatementBase importStatement = PsiTreeUtil.getParentOfType(usageInfo.getElement(), PyImportStatementBase.class);
if (importStatement != null) {
result.add(new UnresolvableCollisionUsageInfo(importStatement, element) {
@Override
public String getDescription() {
return "The name '" + newFileName + "' is not a valid Python identifier. Cannot update import statement in '" +
importStatement.getContainingFile().getName() + "'";
}
});
}
}
}
}
private static boolean isNotAliasedInImportElement(@NotNull PsiReference reference) {
boolean include = true;
if (reference instanceof PsiPolyVariantReference) {
final ResolveResult[] results = ((PsiPolyVariantReference)reference).multiResolve(false);
for (ResolveResult result : results) {
final PsiElement resolved = result.getElement();
if (resolved instanceof PyImportElement) {
if (((PyImportElement)resolved).getAsName() != null) {
include = false;
break;
}
}
}
}
return include;
}
}