AddMethodFix should clear read-only status of the file it modifies, not the current one

This commit is contained in:
peter
2019-01-30 11:40:31 +01:00
parent 3af4ce6360
commit 313edf664d
3 changed files with 57 additions and 17 deletions
@@ -37,6 +37,12 @@ public class AddMethodFix extends LocalQuickFixAndIntentionActionOnPsiElement {
ContainerUtil.addAll(myExceptions, exceptions);
}
@Nullable
@Override
public PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) {
return myStartElement.getContainingFile();
}
@NotNull
private static PsiMethod createMethod(final String methodText, final PsiClass implClass) {
return JavaPsiFacade.getElementFactory(implClass.getProject()).createMethodFromText(methodText, implClass);
@@ -0,0 +1,19 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.codeInsight.intention
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
class AddDefaultConstructorFixTest extends LightCodeInsightFixtureTestCase {
void "test adding constructor to super class"() {
def superClass = myFixture.addClass('abstract class Foo { Foo(int a) {} }')
myFixture.configureByText 'a.java', 'class Bar extends Foo { <caret>Bar() { } }'
def madeWritable = CodeInsightTestFixtureImpl.withReadOnlyFile(superClass.containingFile.virtualFile, project) {
myFixture.launchAction(myFixture.findSingleIntention('Add protected no-args constructor'))
}
assert superClass.constructors.size() == 2
assert madeWritable
}
}
@@ -1871,32 +1871,47 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
// if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
Project project = file.getProject();
VirtualFile vFile = Objects.requireNonNull(InjectedLanguageManager.getInstance(project).getTopLevelFile(file)).getVirtualFile();
AtomicBoolean result = new AtomicBoolean();
withReadOnlyFile(vFile, project, () -> {
try {
ApplicationManager.getApplication().invokeLater(() -> {
try {
result.set(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, action, actionText));
}
catch (StubTextInconsistencyException e) {
PsiTestUtil.compareStubTexts(e);
}
});
UIUtil.dispatchAllInvocationEvents();
checkPsiTextConsistency(project, vFile);
}
catch (AssertionError e) {
ExceptionUtil.rethrowUnchecked(ExceptionUtil.getRootCause(e));
throw e;
}
});
return result.get();
}
/**
* Make the given file read-only and execute the given action, afterwards make file writable again
* @return whether the action has made the file writable itself
*/
public static boolean withReadOnlyFile(VirtualFile vFile, Project project, Runnable action) {
boolean writable;
ReadonlyStatusHandlerImpl handler = (ReadonlyStatusHandlerImpl)ReadonlyStatusHandler.getInstance(project);
VirtualFile vFile = Objects.requireNonNull(InjectedLanguageManager.getInstance(file.getProject()).getTopLevelFile(file)).getVirtualFile();
setReadOnly(vFile, true);
handler.setClearReadOnlyInTests(true);
AtomicBoolean result = new AtomicBoolean();
try {
ApplicationManager.getApplication().invokeLater(() -> {
try {
result.set(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, action, actionText));
}
catch (StubTextInconsistencyException e) {
PsiTestUtil.compareStubTexts(e);
}
});
UIUtil.dispatchAllInvocationEvents();
checkPsiTextConsistency(project, vFile);
}
catch (AssertionError e) {
ExceptionUtil.rethrowUnchecked(ExceptionUtil.getRootCause(e));
throw e;
action.run();
}
finally {
writable = vFile.isWritable();
handler.setClearReadOnlyInTests(false);
setReadOnly(vFile, false);
}
return result.get();
return writable;
}
private static void checkPsiTextConsistency(Project project, VirtualFile vFile) {