Check that target functions can be modified in JetChangeSignature

This commit is contained in:
Pavel V. Talanov
2013-11-11 17:27:46 +04:00
parent f4c8655fa2
commit 3e97203f85
4 changed files with 78 additions and 4 deletions
@@ -33,6 +33,9 @@ import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*
import org.jetbrains.jet.lang.resolve.BindingContextUtils.* import org.jetbrains.jet.lang.resolve.BindingContextUtils.*
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
import org.jetbrains.jet.plugin.quickfix.QuickFixUtil
import com.intellij.CommonBundle
import com.intellij.refactoring.RefactoringBundle
public trait JetChangeSignatureConfiguration { public trait JetChangeSignatureConfiguration {
fun configure(changeSignatureData: JetChangeSignatureData, bindingContext: BindingContext) fun configure(changeSignatureData: JetChangeSignatureData, bindingContext: BindingContext)
@@ -125,8 +128,14 @@ public class JetChangeSignature(val project: Project,
return return
} }
if (configuration.performSilently(dialog.getMethodDescriptor().getAffectedFunctions()) val affectedFunctions = dialog.getMethodDescriptor().getAffectedFunctions()
|| ApplicationManager.getApplication()!!.isUnitTestMode()) {
if (affectedFunctions.any { !checkModifiable(it) }) {
return
}
if (configuration.performSilently(affectedFunctions)
|| ApplicationManager.getApplication()!!.isUnitTestMode()) {
performRefactoringSilently(dialog) performRefactoringSilently(dialog)
} }
else { else {
@@ -142,11 +151,33 @@ public class JetChangeSignature(val project: Project,
return null return null
} }
if (!checkModifiable(functionDeclaration)) {
return null
}
val changeSignatureData = JetChangeSignatureData(baseDescriptor, functionDeclaration, bindingContext, descriptorsForSignatureChange) val changeSignatureData = JetChangeSignatureData(baseDescriptor, functionDeclaration, bindingContext, descriptorsForSignatureChange)
configuration.configure(changeSignatureData, bindingContext) configuration.configure(changeSignatureData, bindingContext)
return JetChangeSignatureDialog(project, changeSignatureData, defaultValueContext, commandName) return JetChangeSignatureDialog(project, changeSignatureData, defaultValueContext, commandName)
} }
private fun checkModifiable(function: PsiElement): Boolean {
if (QuickFixUtil.canModifyElement(function)) {
return true
}
val unmodifiableFile = function.getContainingFile()?.getVirtualFile()?.getPresentableUrl()
if (unmodifiableFile != null) {
val message = RefactoringBundle.message("refactoring.cannot.be.performed") + "\n" +
IdeBundle.message("error.message.cannot.modify.file.0", unmodifiableFile)
Messages.showErrorDialog(project, message, CommonBundle.getErrorTitle()!!)
}
else {
LOG.error("Could not find file for Psi element: " + function.getText())
}
return false
}
private fun performRefactoringSilently(dialog: JetChangeSignatureDialog) { private fun performRefactoringSilently(dialog: JetChangeSignatureDialog) {
ApplicationManager.getApplication()!!.runWriteAction { ApplicationManager.getApplication()!!.runWriteAction {
dialog.createRefactoringProcessor().run() dialog.createRefactoringProcessor().run()
@@ -0,0 +1,3 @@
fun f(a: Number) {
a.<caret>toFloat()
}
@@ -0,0 +1,3 @@
fun f(a: Any) {
a.<caret>equals("a")
}
@@ -16,6 +16,7 @@
package org.jetbrains.jet.plugin.refactoring.changeSignature; package org.jetbrains.jet.plugin.refactoring.changeSignature;
import com.intellij.codeInsight.CodeInsightTestCase;
import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Disposer;
@@ -24,7 +25,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibilities; import org.jetbrains.jet.lang.descriptors.Visibilities;
@@ -38,12 +38,13 @@ import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.getChangeSignatureDialog; import static org.jetbrains.jet.plugin.refactoring.changeSignature.ChangeSignaturePackage.getChangeSignatureDialog;
public class JetChangeSignatureTest extends LightCodeInsightTestCase { public class JetChangeSignatureTest extends CodeInsightTestCase {
public void testBadSelection() throws Exception { public void testBadSelection() throws Exception {
configureByFile(getTestName(false) + "Before.kt"); configureByFile(getTestName(false) + "Before.kt");
Editor editor = getEditor(); Editor editor = getEditor();
@@ -185,6 +186,42 @@ public class JetChangeSignatureTest extends LightCodeInsightTestCase {
fail("Exception expected"); fail("Exception expected");
} }
public void testUnmodifiableFromLibrary() throws Exception {
doTestUnmodifiableCheck();
}
public void testUnmodifiableFromBuiltins() throws Exception {
doTestUnmodifiableCheck();
}
private void doTestUnmodifiableCheck() throws Exception {
try {
JetChangeInfo changeInfo = getChangeInfo();
PsiFile containingFile = changeInfo.getMethod().getContainingFile();
JetChangeSignatureConfiguration empty = new JetChangeSignatureConfiguration() {
@Override
public void configure(
JetChangeSignatureData data, BindingContext bindingContext
) {
}
@Override
public boolean performSilently(Collection<? extends PsiElement> elements) {
return true;
}
};
BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) containingFile).getBindingContext();
ChangeSignaturePackage
.runChangeSignature(getProject(), changeInfo.getOldDescriptor(), empty, context, changeInfo.getMethod(), "test");
}
catch (RuntimeException e) {
assertTrue(e.getMessage().startsWith("Refactoring cannot be"));
return;
}
fail("Exception expected");
}
public void testInnerFunctionsConflict() throws Exception { public void testInnerFunctionsConflict() throws Exception {
JetChangeInfo changeInfo = getChangeInfo(); JetChangeInfo changeInfo = getChangeInfo();
changeInfo.setNewName("inner2"); changeInfo.setNewName("inner2");