Skip to content

Commit

Permalink
Remove running 'AutoCorrect' automatically on background and assign i…
Browse files Browse the repository at this point in the history
…t to IDEA action (#55)

* 53 Remove AutoCorrect functionality and allow to users make auto correction manually

Auto correction action can be called:
Right click on the open kotlin source file -> 'Refactor' -> 'AutoCorrect by Detekt Rules'

* 53: Remove 'AutoCorrect' automatical option

* 53: Refactor code
  • Loading branch information
Dmytro Liakhov authored and arturbosch committed Dec 15, 2019
1 parent c683a4b commit df77386
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 123 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ dependencies {

configure<IntelliJPluginExtension> {
pluginName = "Detekt IntelliJ Plugin"
version = "2019.2"
version = "2019.3"
updateSinceUntilBuild = false
setPlugins("IntelliLang", "Kotlin")
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="io.gitlab.arturbosch.detekt.config.DetektConfigurationForm">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="8" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="680" height="400"/>
Expand All @@ -20,7 +20,7 @@
</component>
<component id="557e8" class="javax.swing.JCheckBox" binding="buildUponDefaultConfig">
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Build upon the default configuration"/>
Expand All @@ -29,7 +29,7 @@
</component>
<component id="b76c7" class="javax.swing.JCheckBox" binding="treatAsErrors">
<constraints>
<grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Treat detekt findings as errors"/>
Expand All @@ -38,7 +38,7 @@
</component>
<vspacer id="f22cd">
<constraints>
<grid row="8" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="7" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="4f4cc" class="javax.swing.JCheckBox" binding="enableFormatting">
Expand All @@ -52,26 +52,17 @@
</component>
<component id="85c28" class="javax.swing.JCheckBox" binding="failFast">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Fail fast"/>
<toolTipText value="Enables all existing rules in detekt regardless the configured active properties of rules."/>
</properties>
</component>
<component id="8719" class="javax.swing.JCheckBox" binding="autoCorrect">
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Auto correct"/>
<toolTipText value="Corrects automatically in-place rules that are fixable"/>
</properties>
</component>
<grid id="f400d" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="7" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
Expand All @@ -98,7 +89,7 @@
<grid id="6b450" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class DetektConfigurationForm {
private JPanel myMainPanel;
private JCheckBox treatAsErrors;
private JCheckBox enableFormatting;
private JCheckBox autoCorrect;
private TextFieldWithBrowseButton baselineFilePath;

private DetektConfigStorage detektConfigStorage;
Expand All @@ -44,7 +43,6 @@ public JComponent createPanel(@NotNull DetektConfigStorage detektConfigStorage)
configurationFilePath.setEnabled(enabled);
treatAsErrors.setEnabled(enabled);
enableFormatting.setEnabled(enabled);
autoCorrect.setEnabled(enabled);
});

FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(
Expand Down Expand Up @@ -77,7 +75,6 @@ public JComponent createPanel(@NotNull DetektConfigStorage detektConfigStorage)
public void apply() {
detektConfigStorage.setEnableDetekt(enableDetekt.isSelected());
detektConfigStorage.setEnableFormatting(enableFormatting.isSelected());
detektConfigStorage.setAutoCorrect(autoCorrect.isSelected());
detektConfigStorage.setBuildUponDefaultConfig(buildUponDefaultConfig.isSelected());
detektConfigStorage.setFailFast(failFast.isSelected());
detektConfigStorage.setTreatAsError(treatAsErrors.isSelected());
Expand All @@ -88,7 +85,6 @@ public void apply() {
public void reset() {
enableDetekt.setSelected(detektConfigStorage.getEnableDetekt());
enableFormatting.setSelected(detektConfigStorage.getEnableFormatting());
autoCorrect.setSelected(detektConfigStorage.getAutoCorrect());
buildUponDefaultConfig.setSelected(detektConfigStorage.getBuildUponDefaultConfig());
failFast.setSelected(detektConfigStorage.getFailFast());
treatAsErrors.setSelected(detektConfigStorage.getTreatAsError());
Expand All @@ -99,7 +95,6 @@ public void reset() {
public boolean isModified() {
return !Comparing.equal(detektConfigStorage.getEnableDetekt(), enableDetekt.isSelected())
|| !Comparing.equal(detektConfigStorage.getEnableFormatting(), enableFormatting.isSelected())
|| !Comparing.equal(detektConfigStorage.getAutoCorrect(), autoCorrect.isSelected())
|| !Comparing.equal(detektConfigStorage.getBuildUponDefaultConfig(), buildUponDefaultConfig.isSelected())
|| !Comparing.equal(detektConfigStorage.getFailFast(), failFast.isSelected())
|| !Comparing.equal(detektConfigStorage.getTreatAsError(), treatAsErrors.isSelected())
Expand Down
96 changes: 16 additions & 80 deletions src/main/kotlin/io/gitlab/arturbosch/detekt/DetektAnnotator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,34 @@ package io.gitlab.arturbosch.detekt

import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.ExternalAnnotator
import com.intellij.notification.Notification
import com.intellij.notification.NotificationType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.options.newEditor.SettingsDialog
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import io.gitlab.arturbosch.detekt.api.Finding
import io.gitlab.arturbosch.detekt.api.TextLocation
import io.gitlab.arturbosch.detekt.cli.CliArgs
import io.gitlab.arturbosch.detekt.cli.FilteredDetectionResult
import io.gitlab.arturbosch.detekt.cli.baseline.BaselineFacade
import io.gitlab.arturbosch.detekt.cli.loadConfiguration
import io.gitlab.arturbosch.detekt.config.DetektConfig
import io.gitlab.arturbosch.detekt.config.DetektConfigStorage
import io.gitlab.arturbosch.detekt.config.NoAutoCorrectConfig
import io.gitlab.arturbosch.detekt.core.DetektFacade
import io.gitlab.arturbosch.detekt.core.FileProcessorLocator
import io.gitlab.arturbosch.detekt.core.ProcessingSettings
import io.gitlab.arturbosch.detekt.core.RuleSetLocator
import io.gitlab.arturbosch.detekt.util.DetektPluginService
import io.gitlab.arturbosch.detekt.util.absolutePath
import io.gitlab.arturbosch.detekt.util.ensureFileExists
import java.io.File
import java.nio.file.Paths
import java.util.concurrent.ForkJoinPool

/**
* @author Dmytro Primshyts
* @author Artur Bosch
*/
class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {

private lateinit var detektPluginService: DetektPluginService

override fun collectInformation(file: PsiFile): PsiFile = file

override fun doAnnotate(collectedInfo: PsiFile): List<Finding> {
WriteCommandAction.runWriteCommandAction(collectedInfo.project, Computable<Boolean> {
val documentManager = FileDocumentManager.getInstance()
val document = documentManager.getDocument(collectedInfo.virtualFile)
if (document != null) {
documentManager.saveDocument(document)
return@Computable false
}
true
})

val configuration = DetektConfigStorage.instance(collectedInfo.project)
detektPluginService = DetektPluginService(configuration)
if (configuration.enableDetekt) {
return runDetekt(collectedInfo, configuration)
}
Expand All @@ -66,18 +44,16 @@ class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {
val settings = processingSettings(collectedInfo.project, virtualFile, configuration)

return settings?.let {
val detektion = createFacade(settings, configuration).run()
val detektion = detektPluginService
.createFacade(settings, !configuration.enableFormatting)
.run()

val result = if (configuration.baselinePath.isNotBlank()) {
FilteredDetectionResult(detektion, BaselineFacade(File(absolutePath(collectedInfo.project, configuration.baselinePath)).toPath()))
} else {
detektion
}

if (settings.autoCorrect) {
virtualFile.refresh(false, false)
}

result.findings.flatMap { it.value }
} ?: emptyList()
}
Expand Down Expand Up @@ -114,7 +90,7 @@ class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {
baselinePath,
project,
"Baseline file not found",
"The provided detekt baseline file <b>${baselinePath}</b> does not exist. Skipping detekt run."
"The provided detekt baseline file <b>$baselinePath</b> does not exist. Skipping detekt run."
)
)
return null
Expand All @@ -125,57 +101,17 @@ class DetektAnnotator : ExternalAnnotator<PsiFile, List<Finding>>() {
rulesPath,
project,
"Configuration file not found",
"The provided detekt configuration file <b>${rulesPath}</b> does not exist. Skipping detekt run."
"The provided detekt configuration file <b>$rulesPath</b> does not exist. Skipping detekt run."
)
)
return null
}

return ProcessingSettings(
inputPath = Paths.get(virtualFile.path),
autoCorrect = configStorage.autoCorrect,
config = NoAutoCorrectConfig(CliArgs().apply {
config = rulesPath
failFast = configStorage.failFast
buildUponDefaultConfig = configStorage.buildUponDefaultConfig
}.loadConfiguration(), configStorage.autoCorrect),
executorService = ForkJoinPool.commonPool()
return detektPluginService.getProcessSettings(
virtualFile = virtualFile,
rulesPath = rulesPath,
configStorage = configStorage,
autoCorrect = false
)
}

private fun absolutePath(project: Project, path: String): String {
return if (path.isBlank() || File(path).isAbsolute)
path
else
project.basePath + "/" + path
}

private fun ensureFileExists(path: String, project: Project, title: String, content: String): Boolean {
if (!File(path).exists()) {
val n = Notification(
"Detekt",
title,
content,
NotificationType.WARNING
)
n.addAction(object : AnAction("Open Detekt projects settings") {
override fun actionPerformed(e: AnActionEvent) {
val dialog = SettingsDialog(project, "Detekt project settings", DetektConfig(project), true, true)
ApplicationManager.getApplication().invokeLater(dialog::show);
}
})
n.notify(project)
return false
}
return true
}

private fun createFacade(settings: ProcessingSettings, configuration: DetektConfigStorage): DetektFacade {
var providers = RuleSetLocator(settings).load()
if (!configuration.enableFormatting) {
providers = providers.filterNot { it.ruleSetId == "formatting" }
}
val processors = FileProcessorLocator(settings).load()
return DetektFacade.create(settings, providers, processors)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package io.gitlab.arturbosch.detekt.action

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.openapi.vfs.VirtualFile
import io.gitlab.arturbosch.detekt.config.DetektConfigStorage
import io.gitlab.arturbosch.detekt.core.ProcessingSettings
import io.gitlab.arturbosch.detekt.util.DetektPluginService
import io.gitlab.arturbosch.detekt.util.FileExtensions
import io.gitlab.arturbosch.detekt.util.absolutePath
import java.io.File

class AutoCorrectAction : AnAction() {
private lateinit var detektPluginService: DetektPluginService

override fun update(event: AnActionEvent) {
val file: VirtualFile = event.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
val project = event.getData(CommonDataKeys.PROJECT) ?: return
val configuration = DetektConfigStorage.instance(project)

if (file.extension == FileExtensions.KOTLIN_FILE_EXTENSION) {
// enable auto corrrect option only when plugin is enabled
event.presentation.isEnabledAndVisible = configuration.enableDetekt
} else {
// hide action for non-Kotlin source files
event.presentation.isEnabledAndVisible = false
}
}

override fun actionPerformed(event: AnActionEvent) {
val virtualFile = event.getData(CommonDataKeys.VIRTUAL_FILE)
val project = event.getData(CommonDataKeys.PROJECT)
println("Update file")
forceUpdateFile(project, virtualFile)

if (virtualFile != null && project != null) {
val configuration = DetektConfigStorage.instance(project)
detektPluginService = DetektPluginService(configuration)

val settings = processingSettings(project, virtualFile, configuration)

settings?.let {
detektPluginService
.createFacade(settings)
.run()

virtualFile.refresh(false, false)
println("AutoCorrect should be complete")
}
}
}

private fun forceUpdateFile(project: Project?, virtualFile: VirtualFile?) {
WriteCommandAction.runWriteCommandAction(project, Computable<Boolean> {
val documentManager = FileDocumentManager.getInstance()
val document = documentManager.getDocument(virtualFile!!)
if (document != null) {
documentManager.saveDocument(document)
println("Force update was completed")
return@Computable false
}
true
})
}

private fun processingSettings(
project: Project,
virtualFile: VirtualFile,
configStorage: DetektConfigStorage
): ProcessingSettings? {
val rulesPath = absolutePath(project, configStorage.rulesPath)
if (rulesPath.isNotEmpty()) {
if (!File(rulesPath).exists()) {
return null
}
}

return detektPluginService.getProcessSettings(
virtualFile = virtualFile,
rulesPath = rulesPath,
configStorage = configStorage,
autoCorrect = true
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.intellij.openapi.components.State
import com.intellij.openapi.components.Storage
import com.intellij.openapi.project.Project
import com.intellij.util.xmlb.annotations.Tag
import java.io.File

/**
* @author Dmytro Primshyts
Expand All @@ -23,9 +22,6 @@ class DetektConfigStorage : PersistentStateComponent<DetektConfigStorage> {
@Tag
var enableFormatting: Boolean = false

@Tag
var autoCorrect: Boolean = false

@Tag
var buildUponDefaultConfig: Boolean = false

Expand All @@ -46,7 +42,6 @@ class DetektConfigStorage : PersistentStateComponent<DetektConfigStorage> {
override fun loadState(state: DetektConfigStorage) {
this.enableDetekt = state.enableDetekt
this.enableFormatting = state.enableFormatting
this.autoCorrect = state.autoCorrect
this.buildUponDefaultConfig = state.buildUponDefaultConfig
this.failFast = state.failFast
this.rulesPath = state.rulesPath
Expand Down
Loading

0 comments on commit df77386

Please sign in to comment.