diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierIntention.java index be56f59df528..570bcb076cd4 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -16,7 +16,7 @@ package com.siyeh.ipp.modifiers; import com.intellij.codeInsight.intention.LowPriorityAction; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.*; @@ -30,7 +30,6 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringUIUtil; -import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import com.intellij.util.containers.MultiMap; import com.siyeh.IntentionPowerPackBundle; @@ -38,12 +37,24 @@ import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import org.intellij.lang.annotations.MagicConstant; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Bas Leijdekkers */ abstract class ModifierIntention extends Intention implements LowPriorityAction { + @Override + public boolean startInWriteAction() { + return false; + } + + @Nullable + @Override + public PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) { + return currentFile; + } + @NotNull @Override protected final PsiElementPredicate getElementPredicate() { @@ -51,7 +62,7 @@ abstract class ModifierIntention extends Intention implements LowPriorityAction } @Override - protected final void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + protected final void processIntention(@NotNull PsiElement element) { final PsiMember member = (PsiMember)element.getParent(); final PsiModifierList modifierList = member.getModifierList(); if (modifierList == null) { @@ -63,23 +74,31 @@ abstract class ModifierIntention extends Intention implements LowPriorityAction if (conflicts.isEmpty()) { conflictsDialogOK = true; } else { - final ConflictsDialog conflictsDialog = - new ConflictsDialog(project, conflicts, - () -> ApplicationManager.getApplication().runWriteAction(() -> modifierList.setModifierProperty(getModifier(), true))); + final ConflictsDialog conflictsDialog = new ConflictsDialog(project, conflicts, () -> changeModifier(modifierList)); conflictsDialogOK = conflictsDialog.showAndGet(); } if (conflictsDialogOK) { - modifierList.setModifierProperty(getModifier(), true); - final PsiElement whitespace = PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText(" "); - final PsiElement sibling = modifierList.getNextSibling(); - if (sibling instanceof PsiWhiteSpace) { - sibling.replace(whitespace); - CodeStyleManager.getInstance(project).reformatRange(member, modifierList.getTextOffset(), - modifierList.getNextSibling().getTextOffset()); - } + changeModifier(modifierList); } } + private void changeModifier(PsiModifierList modifierList) { + WriteAction.run(() -> { + final String modifier = getModifier(); + modifierList.setModifierProperty(modifier, true); + if (!PsiModifier.PACKAGE_LOCAL.equals(modifier)) { + final Project project = modifierList.getProject(); + final PsiElement whitespace = PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText(" "); + final PsiElement sibling = modifierList.getNextSibling(); + if (sibling instanceof PsiWhiteSpace) { + sibling.replace(whitespace); + CodeStyleManager.getInstance(project).reformatRange(modifierList.getParent(), modifierList.getTextOffset(), + modifierList.getNextSibling().getTextOffset()); + } + } + }); + } + private MultiMap checkForConflicts(@NotNull final PsiMember member) { if (member instanceof PsiClass && getModifier().equals(PsiModifier.PUBLIC)) { final PsiClass aClass = (PsiClass)member; diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierPredicate.java index 507fad4426fa..74e94b818915 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/modifiers/ModifierPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -41,10 +41,15 @@ class ModifierPredicate implements PsiElementPredicate { if (element instanceof PsiDocComment || element instanceof PsiCodeBlock) { return false; } + final PsiNameIdentifierOwner named = (PsiNameIdentifierOwner)parent; + final PsiElement identifier = named.getNameIdentifier(); + if (identifier == null || (identifier.getTextOffset() + identifier.getTextLength()) <= element.getTextOffset()) { + return false; + } if (parent instanceof PsiClass) { final PsiClass aClass = (PsiClass)parent; - final PsiElement brace = aClass.getLBrace(); - if (brace != null && brace.getTextOffset() < element.getTextOffset()) { + if (aClass.getParent() instanceof PsiDeclarationStatement) { + // local classes are not allowed a modifier return false; } if (aClass.getContainingClass() == null && diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/modifiers/make_public/LocalClass.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/modifiers/make_public/LocalClass.java new file mode 100644 index 000000000000..5bff11a42af0 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/modifiers/make_public/LocalClass.java @@ -0,0 +1,8 @@ +class LocalClass { + + void m() { + class Ssh { + + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/modifiers/MakePrivateIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/modifiers/MakePrivateIntentionTest.java index 2aa9e663fec9..7cd28fb09b5b 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/modifiers/MakePrivateIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/modifiers/MakePrivateIntentionTest.java @@ -27,6 +27,7 @@ public class MakePrivateIntentionTest extends IPPTestCase { public void testMyClass() { assertIntentionNotAvailable(); } public void testMyInterface() { assertIntentionNotAvailable(); } public void testEnumConstructor() { assertIntentionNotAvailable(); } + public void testLocalClass() { assertIntentionNotAvailable(IntentionPowerPackBundle.message("make.public.intention.name")); } public void testMethod() { doTest(); } public void testAnnotatedMember() { doTest(); }