Skip to content

Commit

Permalink
Add ending line and column to Location.kt (#5032)
Browse files Browse the repository at this point in the history
* Add ending line and column to Location.kt

* Revert changes to detekt-api.api

* Add tests for Location.kt

* Add new line to comply with format

Co-authored-by: schalkms <30376729+schalkms@users.noreply.github.com>
  • Loading branch information
VitalyVPinchuk and schalkms committed Jul 7, 2022
1 parent b6448e3 commit 6638b2f
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
2 changes: 2 additions & 0 deletions detekt-api/api/detekt-api.api
Expand Up @@ -353,6 +353,7 @@ public final class io/gitlab/arturbosch/detekt/api/LazyRegex : kotlin/properties

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;Lio/github/detekt/psi/FilePath;)V
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Lio/github/detekt/psi/FilePath;)V
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;)V
public fun <init> (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;)V
Expand All @@ -367,6 +368,7 @@ public final class io/gitlab/arturbosch/detekt/api/Location : io/gitlab/arturbos
public final fun copy (Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;)Lio/gitlab/arturbosch/detekt/api/Location;
public static synthetic fun copy$default (Lio/gitlab/arturbosch/detekt/api/Location;Lio/gitlab/arturbosch/detekt/api/SourceLocation;Lio/gitlab/arturbosch/detekt/api/TextLocation;Ljava/lang/String;Lio/github/detekt/psi/FilePath;ILjava/lang/Object;)Lio/gitlab/arturbosch/detekt/api/Location;
public fun equals (Ljava/lang/Object;)Z
public final fun getEndSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation;
public final fun getFile ()Ljava/lang/String;
public final fun getFilePath ()Lio/github/detekt/psi/FilePath;
public final fun getSource ()Lio/gitlab/arturbosch/detekt/api/SourceLocation;
Expand Down
Expand Up @@ -26,6 +26,8 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]"
val file: String,
val filePath: FilePath = FilePath.fromAbsolute(Paths.get(file))
) : Compactable {
var endSource: SourceLocation = source
private set

@Suppress("DEPRECATION")
constructor(
Expand All @@ -34,6 +36,16 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]"
filePath: FilePath
) : this(source, text, filePath.absolutePath.toString(), filePath)

@Suppress("DEPRECATION")
constructor(
source: SourceLocation,
endSource: SourceLocation,
text: TextLocation,
filePath: FilePath,
) : this(source, text, filePath.absolutePath.toString(), filePath) {
this.endSource = endSource
}

@Suppress("DEPRECATION")
@Deprecated(
"""
Expand Down Expand Up @@ -62,20 +74,33 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]"
fun from(element: PsiElement, offset: Int = 0): Location {
val start = startLineAndColumn(element, offset)
val sourceLocation = SourceLocation(start.line, start.column)
val end = endLineAndColumn(element, offset)
val endSourceLocation = SourceLocation(end.line, end.column)
val textLocation = TextLocation(element.startOffset + offset, element.endOffset + offset)
return Location(sourceLocation, textLocation, element.containingFile.toFilePath())
return Location(sourceLocation, endSourceLocation, textLocation, element.containingFile.toFilePath())
}

/**
* Determines the line and column of a [PsiElement] in the source file.
* Determines the start line and column of a [PsiElement] in the source file.
*/
fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn {
fun startLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn =
lineAndColumn(
element,
TextRange(element.textRange.startOffset + offset, element.textRange.endOffset + offset)
)

/**
* Determines the end line and column of a [PsiElement] in the source file.
*/
private fun endLineAndColumn(element: PsiElement, offset: Int = 0): PsiDiagnosticUtils.LineAndColumn =
lineAndColumn(
element,
TextRange(element.textRange.endOffset + offset, element.textRange.endOffset + offset)
)

private fun lineAndColumn(element: PsiElement, range: TextRange): PsiDiagnosticUtils.LineAndColumn {
return try {
val range = element.textRange
DiagnosticUtils.getLineAndColumnInPsiFile(
element.containingFile,
TextRange(range.startOffset + offset, range.endOffset + offset)
)
DiagnosticUtils.getLineAndColumnInPsiFile(element.containingFile, range)
} catch (@Suppress("SwallowedException", "TooGenericExceptionCaught") e: IndexOutOfBoundsException) {
// #3317 If any rule mutates the PsiElement, searching the original PsiElement may throw exception.
PsiDiagnosticUtils.LineAndColumn(-1, -1, null)
Expand Down
@@ -0,0 +1,35 @@
package io.gitlab.arturbosch.detekt.api

import io.github.detekt.test.utils.compileContentForTest
import org.assertj.core.api.Assertions.assertThat
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.junit.jupiter.api.Test

class LocationSpec {

@Test
fun `start and end positions of block`() {
val code = """
fun data(): Int {
return 0
}
""".trimIndent()
val psiElement = compileContentForTest(code).findChildByClass(KtNamedFunction::class.java)!!
val location = Location.from(psiElement)

assertThat("${location.source} - ${location.endSource}").isEqualTo("1:1 - 3:2")
}

@Test
fun `start and end positions of fun keyword`() {
val code = """
fun data(): Int {
return 0
}
""".trimIndent()
val psiElement = compileContentForTest(code).findChildByClass(KtNamedFunction::class.java)!!
val location = Location.from(psiElement.funKeyword!!)

assertThat("${location.source} - ${location.endSource}").isEqualTo("1:1 - 1:4")
}
}

0 comments on commit 6638b2f

Please sign in to comment.