From 30ec73f3221e7a2f9e6145869dded982bfa84c98 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 30 Jul 2018 18:08:38 +0300 Subject: [PATCH] Add migration action and marker fix interface (KT-23401) --- idea/src/META-INF/plugin.xml | 5 ++ idea/src/META-INF/plugin.xml.172 | 5 ++ idea/src/META-INF/plugin.xml.173 | 5 ++ idea/src/META-INF/plugin.xml.182 | 5 ++ idea/src/META-INF/plugin.xml.as31 | 5 ++ idea/src/META-INF/plugin.xml.as32 | 5 ++ idea/src/META-INF/plugin.xml.as33 | 5 ++ .../KotlinMigrationProjectComponent.kt | 16 +++- .../idea/migration/CodeInspectionAction.java | 75 +++++++++++++++++++ .../idea/migration/CodeMigrationAction.kt | 16 ++++ .../idea/migration/kotlinMigrationProfile.kt | 53 +++++++++++++ .../idea/quickfix/migration/MigrationFix.kt | 15 ++++ 12 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/migration/CodeInspectionAction.java create mode 100644 idea/src/org/jetbrains/kotlin/idea/migration/CodeMigrationAction.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/migration/kotlinMigrationProfile.kt create mode 100644 idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrationFix.kt diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 6b971be67b5..438251e6ffd 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -115,6 +115,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.172 b/idea/src/META-INF/plugin.xml.172 index 6d6d2dc52b0..27cfa4cc048 100644 --- a/idea/src/META-INF/plugin.xml.172 +++ b/idea/src/META-INF/plugin.xml.172 @@ -115,6 +115,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.173 b/idea/src/META-INF/plugin.xml.173 index b3af22a346e..14fa467c112 100644 --- a/idea/src/META-INF/plugin.xml.173 +++ b/idea/src/META-INF/plugin.xml.173 @@ -115,6 +115,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.182 b/idea/src/META-INF/plugin.xml.182 index 6410db0b84e..76a34ad2796 100644 --- a/idea/src/META-INF/plugin.xml.182 +++ b/idea/src/META-INF/plugin.xml.182 @@ -116,6 +116,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.as31 b/idea/src/META-INF/plugin.xml.as31 index 6e59334ba17..bd508749395 100644 --- a/idea/src/META-INF/plugin.xml.as31 +++ b/idea/src/META-INF/plugin.xml.as31 @@ -115,6 +115,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.as32 b/idea/src/META-INF/plugin.xml.as32 index 36ac4affcf9..fd0c1a1c30a 100644 --- a/idea/src/META-INF/plugin.xml.as32 +++ b/idea/src/META-INF/plugin.xml.as32 @@ -115,6 +115,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/META-INF/plugin.xml.as33 b/idea/src/META-INF/plugin.xml.as33 index ec95911bd7f..d9b3e13d5cb 100644 --- a/idea/src/META-INF/plugin.xml.as33 +++ b/idea/src/META-INF/plugin.xml.as33 @@ -114,6 +114,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinMigrationProjectComponent.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinMigrationProjectComponent.kt index ea5da10f6ae..a7a0a389930 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinMigrationProjectComponent.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/KotlinMigrationProjectComponent.kt @@ -5,6 +5,10 @@ package org.jetbrains.kotlin.idea.configuration +import com.intellij.ide.DataManager +import com.intellij.openapi.actionSystem.ActionManager +import com.intellij.openapi.actionSystem.ActionPlaces +import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataImportListener import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil @@ -21,6 +25,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.idea.configuration.ui.MigrationNotificationDialog import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID import org.jetbrains.kotlin.idea.framework.MAVEN_SYSTEM_ID +import org.jetbrains.kotlin.idea.migration.CodeMigrationAction import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.versions.LibInfo @@ -54,6 +59,15 @@ class KotlinMigrationProjectComponent(val project: Project) { ApplicationManager.getApplication().invokeLater { val migrationNotificationDialog = MigrationNotificationDialog(project, migrationInfo) migrationNotificationDialog.show() + + if (migrationNotificationDialog.isOK) { + val action = ActionManager.getInstance().getAction(CodeMigrationAction.ACTION_ID) + + val dataContext = DataManager.getInstance().dataContextFromFocus.result + val actionEvent = AnActionEvent.createFromAnAction(action, null, ActionPlaces.ACTION_SEARCH, dataContext) + + action.actionPerformed(actionEvent) + } } } @@ -102,7 +116,7 @@ private class MigrationState( } } -internal data class MigrationInfo( +data class MigrationInfo( val oldStdlibVersion: String, val newStdlibVersion: String, val oldApiVersion: ApiVersion, diff --git a/idea/src/org/jetbrains/kotlin/idea/migration/CodeInspectionAction.java b/idea/src/org/jetbrains/kotlin/idea/migration/CodeInspectionAction.java new file mode 100644 index 00000000000..2d5f3ede691 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/migration/CodeInspectionAction.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.migration; + +import com.intellij.analysis.AnalysisScope; +import com.intellij.analysis.BaseAnalysisAction; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; +import com.intellij.codeInspection.ex.InspectionManagerEx; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.featureStatistics.FeatureUsageTracker; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import static org.jetbrains.kotlin.idea.migration.KotlinMigrationProfileKt.createMigrationProfile; + +public class CodeInspectionAction extends BaseAnalysisAction { + private GlobalInspectionContextImpl myGlobalInspectionContext; + private InspectionProfileImpl myExternalProfile; + + public CodeInspectionAction(String title, String analysisNoon) { + super(title, analysisNoon); + } + + @Override + protected void analyze(@NotNull Project project, @NotNull AnalysisScope scope) { + FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassist.inspect.batch"); + try { + runInspections(project, scope); + } + finally { + myGlobalInspectionContext = null; + myExternalProfile = null; + } + } + + private void runInspections(Project project, AnalysisScope scope) { + scope.setSearchInLibraries(false); + + FileDocumentManager.getInstance().saveAllDocuments(); + + GlobalInspectionContextImpl inspectionContext = getGlobalInspectionContext(project); + + InspectionManagerEx managerEx = (InspectionManagerEx) InspectionManager.getInstance(project); + myExternalProfile = createMigrationProfile(managerEx, null); + + inspectionContext.setExternalProfile(myExternalProfile); + inspectionContext.setCurrentScope(scope); + inspectionContext.doInspections(scope); + } + + private GlobalInspectionContextImpl getGlobalInspectionContext(Project project) { + if (myGlobalInspectionContext == null) { + myGlobalInspectionContext = ((InspectionManagerEx) InspectionManager.getInstance(project)).createNewGlobalContext(false); + } + return myGlobalInspectionContext; + } + + @Override + @NonNls + protected String getHelpTopic() { + return "reference.dialogs.inspection.scope"; + } + + @Override + protected void canceled() { + super.canceled(); + myGlobalInspectionContext = null; + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/migration/CodeMigrationAction.kt b/idea/src/org/jetbrains/kotlin/idea/migration/CodeMigrationAction.kt new file mode 100644 index 00000000000..ce86c102c0f --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/migration/CodeMigrationAction.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.migration + +class CodeMigrationAction : CodeInspectionAction("Code Migration", "Code migration") { + override fun getHelpTopic(): String { + return "reference.dialogs.cleanup.scope" + } + + companion object { + const val ACTION_ID = "KotlinCodeMigration" + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/migration/kotlinMigrationProfile.kt b/idea/src/org/jetbrains/kotlin/idea/migration/kotlinMigrationProfile.kt new file mode 100644 index 00000000000..6b1b5445a70 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/migration/kotlinMigrationProfile.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.migration + +import com.intellij.codeInspection.ex.InspectionManagerEx +import com.intellij.codeInspection.ex.InspectionProfileImpl +import com.intellij.codeInspection.ex.InspectionToolWrapper +import com.intellij.codeInspection.ex.createSimple +import com.intellij.openapi.util.InvalidDataException +import com.intellij.openapi.util.WriteExternalException +import com.intellij.profile.codeInspection.InspectionProfileManager +import com.intellij.psi.PsiElement +import org.jdom.Element +import org.jetbrains.kotlin.idea.quickfix.migration.MigrationFix +import java.util.LinkedHashSet + +fun createMigrationProfile(managerEx: InspectionManagerEx, psiElement: PsiElement?): InspectionProfileImpl { + val rootProfile = InspectionProfileManager.getInstance().currentProfile + + val migrationFixWrappers = rootProfile.allTools.asSequence() + .map { it.tool } + .filter { toolWrapper: InspectionToolWrapper<*, *> -> + toolWrapper.tool is MigrationFix + } + .toList() + + val allWrappers = LinkedHashSet>() + for (toolWrapper in migrationFixWrappers) { + allWrappers.add(toolWrapper) + rootProfile.collectDependentInspections(toolWrapper, allWrappers, managerEx.project) + } + + val model = createSimple("Migration", managerEx.project, migrationFixWrappers) + try { + val element = Element("toCopy") + for (wrapper in migrationFixWrappers) { + wrapper.tool.writeSettings(element) + val tw = (if (psiElement == null) + model.getInspectionTool(wrapper.shortName, managerEx.project) + else + model.getInspectionTool(wrapper.shortName, psiElement))!! + + tw.tool.readSettings(element) + } + } catch (ignored: WriteExternalException) { + } catch (ignored: InvalidDataException) { + } + + return model +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrationFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrationFix.kt new file mode 100644 index 00000000000..1f05566c501 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/migration/MigrationFix.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.quickfix.migration + +import org.jetbrains.kotlin.idea.configuration.MigrationInfo + +/** + * Marker interface for inspections that can be used during kotlin migrations + */ +interface MigrationFix { + fun isApplicable(migrationInfo: MigrationInfo): Boolean +}