diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java index 60ff69c54dd4..aa0eae3a4e7b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddMethodFix.java @@ -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); diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddDefaultConstructorFixTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddDefaultConstructorFixTest.groovy new file mode 100644 index 000000000000..531ca302f707 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/AddDefaultConstructorFixTest.groovy @@ -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 { 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 + } +} diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index db7d6816f77a..d3db2ac3800c 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -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) {