Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove running 'AutoCorrect' automatically on background and assign it to IDEA action #55

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
arturbosch marked this conversation as resolved.
Show resolved Hide resolved
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