From c2d59fc5daf64300241ace9b09902ad09abecd27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20H=C3=B6fler?= <29115214+marius-h@users.noreply.github.com> Date: Sun, 22 Aug 2021 23:10:51 +0200 Subject: [PATCH] Add "Make private" and "Make public" action (#145) * Add "Make private" and "Make public" actions * Add "Make private" and "Make public" intentions --- CHANGELOG.md | 1 + .../intentions/MakePrivateIntention.kt | 19 ++++ .../intentions/MakePublicIntention.kt | 19 ++++ .../intentions/ModifyVisibilityInspection.kt | 92 +++++++++++++++++++ src/main/resources/META-INF/plugin.xml | 9 ++ .../MakePrivateIntention/after.dart.template | 1 + .../MakePrivateIntention/before.dart.template | 1 + .../MakePrivateIntention/description.html | 5 + .../MakePublicIntention/after.dart.template | 1 + .../MakePublicIntention/before.dart.template | 1 + .../MakePublicIntention/description.html | 5 + 11 files changed, 154 insertions(+) create mode 100644 src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePrivateIntention.kt create mode 100644 src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePublicIntention.kt create mode 100644 src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/ModifyVisibilityInspection.kt create mode 100644 src/main/resources/intentionDescriptions/MakePrivateIntention/after.dart.template create mode 100644 src/main/resources/intentionDescriptions/MakePrivateIntention/before.dart.template create mode 100644 src/main/resources/intentionDescriptions/MakePrivateIntention/description.html create mode 100644 src/main/resources/intentionDescriptions/MakePublicIntention/after.dart.template create mode 100644 src/main/resources/intentionDescriptions/MakePublicIntention/before.dart.template create mode 100644 src/main/resources/intentionDescriptions/MakePublicIntention/description.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 229f70e..de15b1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Added - Open a package's pub.dev page directly from your pubspec.yaml (#121) +- Make a variable, function or class private or public via alt+enter (#107) - Custom file templates for "New Flutter widget" menu - Run `flutter pub get` from menu by right-clicking a file or a directory (#52) ### Changed diff --git a/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePrivateIntention.kt b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePrivateIntention.kt new file mode 100644 index 0000000..40235c5 --- /dev/null +++ b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePrivateIntention.kt @@ -0,0 +1,19 @@ +package de.mariushoefler.flutterenhancementsuite.intentions + +import com.intellij.psi.PsiElement + +/** + * Makes selected class, function or variable private + * + * @author Marius Höfler + * @since v1.6.0 + */ +class MakePrivateIntention : AbstractModifyVisibilityIntentionAction() { + override fun getText(): String = "Make private" + + override fun getModifiedName(element: PsiElement): String = PRIVATE_MODIFIER + element.text + + override fun isAvailable(element: PsiElement): Boolean { + return !element.text.startsWith(PRIVATE_MODIFIER) + } +} diff --git a/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePublicIntention.kt b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePublicIntention.kt new file mode 100644 index 0000000..d20f290 --- /dev/null +++ b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/MakePublicIntention.kt @@ -0,0 +1,19 @@ +package de.mariushoefler.flutterenhancementsuite.intentions + +import com.intellij.psi.PsiElement + +/** + * Makes selected class, function or variable public + * + * @author Marius Höfler + * @since v1.6.0 + */ +class MakePublicIntention : AbstractModifyVisibilityIntentionAction() { + override fun getText(): String = "Make public" + + override fun getModifiedName(element: PsiElement): String = element.text.removePrefix(PRIVATE_MODIFIER) + + override fun isAvailable(element: PsiElement): Boolean { + return element.text.startsWith(PRIVATE_MODIFIER) + } +} diff --git a/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/ModifyVisibilityInspection.kt b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/ModifyVisibilityInspection.kt new file mode 100644 index 0000000..5bc0727 --- /dev/null +++ b/src/main/kotlin/de/mariushoefler/flutterenhancementsuite/intentions/ModifyVisibilityInspection.kt @@ -0,0 +1,92 @@ +package de.mariushoefler.flutterenhancementsuite.intentions + +import com.intellij.CommonBundle +import com.intellij.codeInsight.FileModificationService +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction +import com.intellij.openapi.application.WriteAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.psi.PsiElement +import com.intellij.refactoring.util.CommonRefactoringUtil +import com.jetbrains.lang.dart.assists.AssistUtils +import com.jetbrains.lang.dart.assists.DartSourceEditException +import com.jetbrains.lang.dart.ide.refactoring.ServerRenameRefactoring +import com.jetbrains.lang.dart.ide.refactoring.status.RefactoringStatus +import com.jetbrains.lang.dart.psi.DartComponentName +import com.jetbrains.lang.dart.psi.DartReferenceExpression +import com.jetbrains.lang.dart.psi.DartSimpleType +import com.jetbrains.lang.dart.psi.DartType + +const val PRIVATE_MODIFIER = "_" + +/** + * Provides quick fixes for modifying the visibility of classes, functions and variables + * + * @author Marius Höfler + * @since v1.6.0 + */ +abstract class AbstractModifyVisibilityIntentionAction : PsiElementBaseIntentionAction(), IntentionAction { + override fun getFamilyName(): String = text + + override fun isAvailable(project: Project, editor: Editor?, element: PsiElement): Boolean { + val parent = element.parent?.parent + val isReference = + parent is DartReferenceExpression && parent.parent !is DartType && parent.parent !is DartSimpleType + return isAvailable(element) && (parent is DartComponentName || isReference) + } + + override fun startInWriteAction() = true + + override fun invoke(project: Project, editor: Editor?, element: PsiElement) { + val virtualFile = element.containingFile?.virtualFile + if (virtualFile == null || !FileModificationService.getInstance() + .preparePsiElementForWrite(element) + ) return + + // Create the refactoring. + val refactoring = ServerRenameRefactoring(project, virtualFile, element.textOffset, 0) + // Validate initial status. + val initialStatus: RefactoringStatus = refactoring.checkInitialConditions() ?: return + if (initialStatus.hasError()) { + initialStatus.message?.let { + CommonRefactoringUtil.showErrorHint(project, editor, it, CommonBundle.getErrorTitle(), null) + } + return + } + refactoring.setNewName(getModifiedName(element)) + doRenameRefactoring(project, refactoring, refactoring.potentialEdits)?.let { error -> + Messages.showErrorDialog(project, error, CommonBundle.getErrorTitle()) + } + } + + protected abstract fun getModifiedName(element: PsiElement): String + + protected abstract fun isAvailable(element: PsiElement): Boolean + + private fun doRenameRefactoring( + project: Project, + refactoring: ServerRenameRefactoring, + excludedIds: Set + ): String? { + refactoring.checkFinalConditions()?.let { finalStatus -> + if (finalStatus.hasError()) { + return finalStatus.message + } + + refactoring.change?.let { change -> + return WriteAction.compute { + try { + AssistUtils.applySourceChange(project, change, false, excludedIds) + } catch (e: DartSourceEditException) { + return@compute e.message + } + null + } + } + } + return null + } +} + diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 7dd0112..0917039 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -55,6 +55,15 @@ id="PubChangelogProvider" order="first, before YamlJsonSchemaDocumentationProvider"/> + + de.mariushoefler.flutterenhancementsuite.intentions.MakePrivateIntention + Dart + + + de.mariushoefler.flutterenhancementsuite.intentions.MakePublicIntention + Dart + + diff --git a/src/main/resources/intentionDescriptions/MakePrivateIntention/after.dart.template b/src/main/resources/intentionDescriptions/MakePrivateIntention/after.dart.template new file mode 100644 index 0000000..831452c --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePrivateIntention/after.dart.template @@ -0,0 +1 @@ +String _foo = 'bar'; diff --git a/src/main/resources/intentionDescriptions/MakePrivateIntention/before.dart.template b/src/main/resources/intentionDescriptions/MakePrivateIntention/before.dart.template new file mode 100644 index 0000000..be710b5 --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePrivateIntention/before.dart.template @@ -0,0 +1 @@ +String foo = 'bar'; diff --git a/src/main/resources/intentionDescriptions/MakePrivateIntention/description.html b/src/main/resources/intentionDescriptions/MakePrivateIntention/description.html new file mode 100644 index 0000000..2243530 --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePrivateIntention/description.html @@ -0,0 +1,5 @@ + + +

Makes selected class, function or variable private

+ + diff --git a/src/main/resources/intentionDescriptions/MakePublicIntention/after.dart.template b/src/main/resources/intentionDescriptions/MakePublicIntention/after.dart.template new file mode 100644 index 0000000..be710b5 --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePublicIntention/after.dart.template @@ -0,0 +1 @@ +String foo = 'bar'; diff --git a/src/main/resources/intentionDescriptions/MakePublicIntention/before.dart.template b/src/main/resources/intentionDescriptions/MakePublicIntention/before.dart.template new file mode 100644 index 0000000..831452c --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePublicIntention/before.dart.template @@ -0,0 +1 @@ +String _foo = 'bar'; diff --git a/src/main/resources/intentionDescriptions/MakePublicIntention/description.html b/src/main/resources/intentionDescriptions/MakePublicIntention/description.html new file mode 100644 index 0000000..a668022 --- /dev/null +++ b/src/main/resources/intentionDescriptions/MakePublicIntention/description.html @@ -0,0 +1,5 @@ + + +

Makes selected class, function or variable public

+ +