Skip to content

Commit

Permalink
Capture KtFile in Location instead of physical Path
Browse files Browse the repository at this point in the history
  • Loading branch information
3flex committed May 1, 2024
1 parent d78458a commit 9d5483a
Show file tree
Hide file tree
Showing 23 changed files with 53 additions and 54 deletions.
4 changes: 3 additions & 1 deletion detekt-api/api/detekt-api.api
Expand Up @@ -196,10 +196,12 @@ public abstract interface class io/gitlab/arturbosch/detekt/api/Issue$RuleInfo {

public final class io/gitlab/arturbosch/detekt/api/Location : io/gitlab/arturbosch/detekt/api/Compactable {
public static final field Companion Lio/gitlab/arturbosch/detekt/api/Location$Companion;
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/nio/file/Path;)V
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)V
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Lorg/jetbrains/kotlin/psi/KtFile;)V
public fun compact ()Ljava/lang/String;
public fun compactWithSignature ()Ljava/lang/String;
public final fun getEndSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation;
public final fun getKtFile ()Lorg/jetbrains/kotlin/psi/KtFile;
public final fun getPath ()Ljava/nio/file/Path;
public final fun getSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation;
public final fun getText ()Lio/gitlab/arturbosch/detekt/api/TextLocation;
Expand Down
2 changes: 2 additions & 0 deletions detekt-api/build.gradle.kts
Expand Up @@ -12,6 +12,8 @@ dependencies {

testImplementation(projects.detektTest)
testImplementation(libs.assertj)

testFixturesImplementation(projects.detektParser)
}

detekt {
Expand Down
Expand Up @@ -5,12 +5,11 @@ import io.github.detekt.psi.absolutePath
import io.github.detekt.psi.getLineAndColumnInPsiFile
import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.com.intellij.psi.PsiFile
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import java.nio.file.Path
import kotlin.io.path.absolutePathString

/**
* Specifies a position within a source code fragment.
Expand All @@ -19,13 +18,22 @@ class Location(
val source: SourceLocation,
val endSource: SourceLocation,
val text: TextLocation,
val path: Path,
val ktFile: KtFile,
) : Compactable {

override fun compact(): String = "${path.absolutePathString()}:$source"
constructor(
source: SourceLocation,
endSource: SourceLocation,
text: TextLocation,
psiFile: PsiFile
) : this(source, endSource, text, psiFile as KtFile)

val path = ktFile.absolutePath()

Check failure

Code scanning / detekt

Class contents should be in this order: Property declarations/initializer blocks; secondary constructors; method declarations then companion objects. Error

property path should be declared before secondary constructors.

Check failure

Code scanning / detekt

Class contents should be in this order: Property declarations/initializer blocks; secondary constructors; method declarations then companion objects. Error

property path should be declared before secondary constructors.

Check failure

Code scanning / detekt

Class contents should be in this order: Property declarations/initializer blocks; secondary constructors; method declarations then companion objects. Error

property path should be declared before secondary constructors.

override fun compact(): String = "$path:$source"

override fun toString(): String =
"Location(source=$source, endSource=$endSource, text=$text, path=${path.absolutePathString()})"
"Location(source=$source, endSource=$endSource, text=$text, path=$path)"

companion object {
/**
Expand All @@ -38,7 +46,7 @@ class Location(
val end = endLineAndColumn(element, offset)
val endSourceLocation = SourceLocation(end.line, end.column)
val textLocation = TextLocation(element.startOffset + offset, element.endOffset + offset)
return Location(sourceLocation, endSourceLocation, textLocation, element.containingFile.absolutePath())
return Location(sourceLocation, endSourceLocation, textLocation, element.containingFile)
}

/**
Expand Down
@@ -1,5 +1,6 @@
package io.gitlab.arturbosch.detekt.api

import io.github.detekt.parser.KtCompiler
import io.gitlab.arturbosch.detekt.test.location
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
Expand All @@ -19,7 +20,7 @@ class CodeSmellSpec {
source = SourceLocation(1, 1),
endSource = SourceLocation(1, 1),
text = TextLocation(0, 0),
path = Path("/").absolute().resolve("Users/tester/detekt/TestFile.kt"),
KtCompiler().createKtFile("", Path("/"), Path("Users/tester/detekt/TestFile.kt")),
),
ktElement = null
),
Expand All @@ -29,7 +30,7 @@ class CodeSmellSpec {
assertThat(codeSmell.toString()).isEqualTo(
"CodeSmell(entity=Entity(name=TestEntity, signature=TestEntitySignature, " +
"location=Location(source=1:1, endSource=1:1, text=0:0, " +
"path=${codeSmell.location.path.absolutePathString()}), ktElement=null), message=TestMessage, " +
"path=${codeSmell.location.path}), ktElement=null), message=TestMessage, " +
"references=[])"
)
}
Expand Down
Expand Up @@ -4,7 +4,6 @@ import io.gitlab.arturbosch.detekt.test.createEntity
import io.gitlab.arturbosch.detekt.test.location
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import kotlin.io.path.absolutePathString

class CorrectableCodeSmellSpec {

Expand All @@ -20,7 +19,7 @@ class CorrectableCodeSmellSpec {
"CorrectableCodeSmell(autoCorrectEnabled=true, " +
"entity=Entity(name=TestEntity, signature=TestEntitySignature, " +
"location=Location(source=1:1, endSource=1:1, text=0:0, " +
"path=${codeSmell.location.path.absolutePathString()}), ktElement=null), " +
"path=${codeSmell.location.path}), ktElement=null), " +
"message=TestMessage, references=[])"
)
}
Expand Down
@@ -1,5 +1,6 @@
package io.gitlab.arturbosch.detekt.test

import io.github.detekt.parser.KtCompiler
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Location
Expand All @@ -10,7 +11,6 @@ import io.gitlab.arturbosch.detekt.api.SourceLocation
import io.gitlab.arturbosch.detekt.api.TextLocation
import org.jetbrains.kotlin.psi.KtElement
import kotlin.io.path.Path
import kotlin.io.path.absolute

fun createIssue(
ruleName: String = "TestSmell",
Expand Down Expand Up @@ -78,7 +78,7 @@ fun createIssueForRelativePath(
source = SourceLocation(1, 1),
endSource = SourceLocation(1, 1),
text = TextLocation(0, 0),
path = Path("/").absolute().resolve(basePath).resolve(relativePath)
KtCompiler().createKtFile("", Path(basePath), Path(basePath).resolve(relativePath))
),
ktElement = null
),
Expand All @@ -99,7 +99,7 @@ fun createEntity(

fun createLocation(
path: String = "TestFile.kt",
basePath: String? = null,
basePath: String = System.getProperty("user.dir"),
position: Pair<Int, Int> = 1 to 1,
endPosition: Pair<Int, Int> = 1 to 1,
text: IntRange = 0..0,
Expand All @@ -109,7 +109,7 @@ fun createLocation(
source = SourceLocation(position.first, position.second),
endSource = SourceLocation(endPosition.first, endPosition.second),
text = TextLocation(text.first, text.last),
path = basePath?.let { Path(it).absolute().resolve(path) } ?: Path(path).absolute(),
KtCompiler().createKtFile("", Path(basePath), Path(basePath).resolve(path))
)
}

Expand Down
Expand Up @@ -2,7 +2,6 @@ package io.gitlab.arturbosch.detekt.core.reporting.console

import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.core.reporting.printIssues
import kotlin.io.path.absolutePathString

/**
* Contains all rule violations grouped by file location.
Expand All @@ -13,7 +12,7 @@ class FileBasedIssuesReport : AbstractIssuesReport() {
override val id: String = "FileBasedIssuesReport"

override fun render(issues: List<Issue>): String {
val issuesPerFile = issues.groupBy { it.entity.location.path.absolutePathString() }
val issuesPerFile = issues.groupBy { it.entity.location.path.toString() }
return printIssues(issuesPerFile)
}
}
Expand Up @@ -29,10 +29,10 @@ class FileBasedIssuesReportSpec {

assertThat(output).isEqualTo(
"""
${location1.path.absolutePathString()}
${location1.path}
TestSmell - [TestMessage] at ${location1.compact()}
TestSmell - [TestMessage] at ${location1.compact()}
${location2.path.absolutePathString()}
${location2.path}
TestSmell - [TestMessage] at ${location2.compact()}
""".trimIndent()
Expand Down
Expand Up @@ -4,7 +4,6 @@ import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CODE_STYLE_PROPERT
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfig
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfigProperty
import com.pinterest.ktlint.rule.engine.core.api.editorconfig.INDENT_STYLE_PROPERTY
import io.github.detekt.psi.absolutePath
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.CorrectableCodeSmell
Expand All @@ -20,7 +19,6 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyElement
import org.jetbrains.kotlin.com.intellij.psi.impl.source.JavaDummyHolder
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import java.nio.file.Path

/**
* Rule to detect formatting violations.
Expand All @@ -38,13 +36,13 @@ abstract class FormattingRule(config: Config, description: String) : Rule(config

private lateinit var positionByOffset: (offset: Int) -> Pair<Int, Int>
private lateinit var root: KtFile
private lateinit var originalFilePath: Path
private lateinit var originalFile: KtFile

override fun visit(root: KtFile) {
val fileCopy = KtPsiFactory(root.project).createPhysicalFile(root.name, root.modifiedText ?: root.text)

this.root = fileCopy
originalFilePath = root.absolutePath()
originalFile = root
positionByOffset = KtLintLineColCalculator.calculateLineColByOffset(fileCopy.text)

wrapping.beforeFirstNode(computeEditorConfigProperties())
Expand Down Expand Up @@ -95,7 +93,7 @@ abstract class FormattingRule(config: Config, description: String) : Rule(config
endSource = SourceLocation(line, column),
// Use offset + 1 since ktlint always reports a single location.
text = TextLocation(offset, offset + 1),
path = originalFilePath
ktFile = originalFile
)
val entity = Entity.from(node.psi, location)

Expand Down
Expand Up @@ -76,7 +76,7 @@ class FormattingRuleSpec {
val rule = ChainWrapping(Config.empty)
val findings = rule.visitFile(compileForTest(expectedPath))
assertThat(findings).anySatisfy { finding ->
assertThat(finding.location.path.absolutePathString()).isEqualTo(expectedPath.toString())
assertThat(finding.location.path).isEqualTo(expectedPath)
}
}
}
Expand Up @@ -157,8 +157,7 @@ class HtmlOutputReport : BuiltInOutputReport, OutputReport() {
}

private fun FlowContent.renderIssue(issue: Issue) {
val filePath = basePath?.let { issue.location.path.absolute().relativeTo(it) }
?: issue.location.path.absolute()
val filePath = basePath?.let { issue.location.path.relativeTo(it) } ?: issue.location.path
val pathString = filePath.invariantSeparatorsPathString
span("location") {
text(
Expand Down
Expand Up @@ -145,8 +145,7 @@ private fun MarkdownContent.renderIssues(issues: List<Issue>, basePath: Path?) {
}

private fun MarkdownContent.renderIssue(issue: Issue, basePath: Path?): String {
val filePath = basePath?.let { issue.location.path.absolute().relativeTo(it) }
?: issue.location.path.absolute()
val filePath = basePath?.let { issue.location.path.relativeTo(it) } ?: issue.location.path
val location =
"${filePath.invariantSeparatorsPathString}:${issue.location.source.line}:${issue.location.source.column}"

Expand Down
Expand Up @@ -10,7 +10,6 @@ import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Location
import io.gitlab.arturbosch.detekt.api.Severity
import kotlin.io.path.Path
import kotlin.io.path.absolute
import kotlin.io.path.invariantSeparatorsPathString
import kotlin.io.path.relativeTo

Expand Down Expand Up @@ -47,7 +46,7 @@ private fun Location.toLocation(basePath: String?): io.github.detekt.sarif4k.Loc
uriBaseID = SRCROOT
)
} else {
ArtifactLocation(uri = path.absolute().toUri().toString())
ArtifactLocation(uri = path.toUri().toString())
}
)
)
Expand Down
Expand Up @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.psi.KtClassOrObject
import org.junit.jupiter.api.Test
import java.net.URI
import kotlin.io.path.Path
import kotlin.io.path.absolute

class SarifOutputReportSpec {

Expand Down Expand Up @@ -96,7 +95,7 @@ class SarifOutputReportSpec {
createIssueForRelativePath(createRuleInfo("TestSmellC", "RuleSet2")),
)

val basePath = Path("/").absolute().resolve("Users/tester/detekt/")
val basePath = Path("${System.getProperty("user.dir")}/Users/tester/detekt/")
val report = SarifOutputReport()
.apply {
init(
Expand Down
Expand Up @@ -36,10 +36,7 @@ class XmlOutputReport : BuiltInOutputReport, OutputReport() {
lines += "<checkstyle version=\"4.3\">"

detektion.issues
.groupBy {
basePath?.let { path -> it.location.path.absolute().relativeTo(path) }
?: it.location.path.absolute()
}
.groupBy { basePath?.let { path -> it.location.path.relativeTo(path) } ?: it.location.path }
.forEach { (filePath, issues) ->
lines += "<file name=\"${filePath.invariantSeparatorsPathString.toXmlString()}\">"
issues.forEach {
Expand Down
Expand Up @@ -62,7 +62,7 @@ class XmlOutputFormatSpec {
"""
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="4.3">
<file name="${entity1.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity1.location.path.invariantSeparatorsPathString}">
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_a" />
</file>
</checkstyle>
Expand All @@ -81,7 +81,7 @@ class XmlOutputFormatSpec {
"""
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="4.3">
<file name="${entity1.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity1.location.path.invariantSeparatorsPathString}">
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_a" />
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_b" />
</file>
Expand All @@ -101,10 +101,10 @@ class XmlOutputFormatSpec {
"""
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="4.3">
<file name="${entity1.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity1.location.path.invariantSeparatorsPathString}">
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_a" />
</file>
<file name="${entity2.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity2.location.path.invariantSeparatorsPathString}">
$TAB<error line="22" column="2" severity="error" message="TestMessage" source="detekt.id_a" />
</file>
</checkstyle>
Expand Down Expand Up @@ -165,11 +165,11 @@ class XmlOutputFormatSpec {
"""
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="4.3">
<file name="${entity1.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity1.location.path.invariantSeparatorsPathString}">
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_a" />
$TAB<error line="11" column="1" severity="error" message="TestMessage" source="detekt.id_b" />
</file>
<file name="${entity2.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity2.location.path.invariantSeparatorsPathString}">
$TAB<error line="22" column="2" severity="error" message="TestMessage" source="detekt.id_a" />
$TAB<error line="22" column="2" severity="error" message="TestMessage" source="detekt.id_b" />
</file>
Expand All @@ -195,7 +195,7 @@ class XmlOutputFormatSpec {
val expected = """
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="4.3">
<file name="${entity1.location.path.absolute().invariantSeparatorsPathString}">
<file name="${entity1.location.path.invariantSeparatorsPathString}">
$TAB<error line="${issue.location.source.line}" column="${issue.location.source.column}" severity="$xmlSeverity" message="${issue.message}" source="detekt.${issue.ruleInfo.id}" />
</file>
</checkstyle>
Expand Down
@@ -1,6 +1,5 @@
package io.gitlab.arturbosch.detekt.rules.style

import io.github.detekt.psi.absolutePath
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Configuration
Expand Down Expand Up @@ -115,7 +114,7 @@ class CascadingCallWrapping(config: Config) : Rule(
val textLocation = TextLocation(operationReference.startOffset, rhs.endOffset)
Entity.from(
this,
Location(operationSourceLocation, rhsSourceLocation, textLocation, containingFile.absolutePath())
Location(operationSourceLocation, rhsSourceLocation, textLocation, containingFile)
)
}
else -> Entity.from(this)
Expand Down
Expand Up @@ -90,7 +90,7 @@ class ForbiddenAnnotation(config: Config) : Rule(
location.source,
location.endSource,
TextLocation(location.text.start, element.children.firstOrNull()?.endOffset ?: location.text.end),
location.path
location.ktFile
)
}
report(CodeSmell(Entity.from(element, location), message))
Expand Down
Expand Up @@ -60,7 +60,7 @@ class MaxLineLength(config: Config) : Rule(
source = location.source,
endSource = SourceLocation(location.source.line, line.length + 1),
text = TextLocation(offset - line.length, offset),
path = location.path,
ktFile = location.ktFile,
)
}
report(CodeSmell(Entity.from(ktElement, location), description))
Expand Down

0 comments on commit 9d5483a

Please sign in to comment.