From cd30e7de2140b075b451518623e9f25273e207e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kvapil?= Date: Thu, 19 Jun 2025 20:05:04 +0200 Subject: [PATCH 1/2] Track end line numbers and column information --- api/api.base | 13 +++++++++++-- .../com/google/devtools/ksp/symbol/Location.kt | 8 +++++++- .../google/devtools/ksp/impl/symbol/kotlin/util.kt | 12 +++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/api/api.base b/api/api.base index 06f85c6b4a..d50ed22d92 100644 --- a/api/api.base +++ b/api/api.base @@ -256,12 +256,21 @@ package com.google.devtools.ksp.symbol { } public final class FileLocation extends com.google.devtools.ksp.symbol.Location { - ctor public FileLocation(@NonNull String filePath, int lineNumber); + ctor public FileLocation(@NonNull String filePath, int lineNumber, int column, int endLineNumber, int endColumn); method @NonNull public String component1(); method public int component2(); - method @NonNull public com.google.devtools.ksp.symbol.FileLocation copy(@NonNull String filePath, int lineNumber); + method public int component3(); + method public int component4(); + method public int component5(); + method @NonNull public com.google.devtools.ksp.symbol.FileLocation copy(@NonNull String filePath, int lineNumber, int column, int endLineNumber, int endColumn); + method public int getColumn(); + method public int getEndColumn(); + method public int getEndLineNumber(); method @NonNull public String getFilePath(); method public int getLineNumber(); + property public final int column; + property public final int endColumn; + property public final int endLineNumber; property @NonNull public final String filePath; property public final int lineNumber; } diff --git a/api/src/main/kotlin/com/google/devtools/ksp/symbol/Location.kt b/api/src/main/kotlin/com/google/devtools/ksp/symbol/Location.kt index 7167dc8866..08fa326659 100644 --- a/api/src/main/kotlin/com/google/devtools/ksp/symbol/Location.kt +++ b/api/src/main/kotlin/com/google/devtools/ksp/symbol/Location.kt @@ -18,6 +18,12 @@ package com.google.devtools.ksp.symbol sealed class Location -data class FileLocation(val filePath: String, val lineNumber: Int) : Location() +data class FileLocation( + val filePath: String, + val lineNumber: Int, + val column: Int, + val endLineNumber: Int, + val endColumn: Int, +) : Location() object NonExistLocation : Location() diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt index 99e17811ce..56f156d9a7 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt @@ -73,6 +73,7 @@ import org.jetbrains.kotlin.name.JvmStandardClassIds.JVM_WILDCARD_ANNOTATION_FQ_ import org.jetbrains.kotlin.psi.KtAnnotated import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.getEffectiveVariance import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments @@ -223,7 +224,16 @@ internal fun PsiElement?.toLocation(): Location { } val file = this.containingFile val document = KSPCoreEnvironment.instance.psiDocumentManager.getDocument(file) ?: return NonExistLocation - return FileLocation(file.virtualFile.path, document.getLineNumber(this.textOffset) + 1) + val lineNumber = document.getLineNumber(textOffset) + val endLineNumber = document.getLineNumber(endOffset) + + return FileLocation( + filePath = file.virtualFile.path, + lineNumber = lineNumber + 1, + column = textOffset - document.getLineStartOffset(lineNumber), + endLineNumber = endLineNumber + 1, + endColumn = document.getLineEndOffset(endLineNumber) - document.getLineStartOffset(endLineNumber), + ) } internal fun KaSymbol.toContainingFile(): KSFile? { From 9f80315e3e07003eb65a364798dbe1bbfc3eb424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kvapil?= Date: Thu, 19 Jun 2025 20:20:57 +0200 Subject: [PATCH 2/2] Extend location tests --- kotlin-analysis-api/testData/locations.kt | 38 +++++++++---------- .../ksp/processor/LocationsProcessor.kt | 8 +++- test-utils/testData/api/locations.kt | 36 +++++++++--------- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/kotlin-analysis-api/testData/locations.kt b/kotlin-analysis-api/testData/locations.kt index 76bf6608fa..601699e0c4 100644 --- a/kotlin-analysis-api/testData/locations.kt +++ b/kotlin-analysis-api/testData/locations.kt @@ -17,25 +17,25 @@ // TEST PROCESSOR: LocationsProcessor // EXPECTED: -// A:K.kt:51 -// File: K.kt:K.kt:1 -// K:J.java:73 -// K:K.kt:54 -// T:J.java:73 -// T:J.java:73 -// T:K.kt:54 -// f1:J.java:77 -// f1:K.kt:61 -// p1:K.kt:56 -// p2:J.java:77 -// p2:K.kt:61 -// v1:K.kt:55 -// v1:K.kt:55 -// v2:J.java:74 -// v2:K.kt:58 -// v3.getter():K.kt:66 -// v3.setter():K.kt:67 -// v3:J.java:82 +// A:K.kt:51,10-51,15 +// File: K.kt:K.kt:1,0-70,0 +// K:J.java:73,6-83,1 +// K:K.kt:54,6-68,1 +// T:J.java:73,8-73,22 +// T:J.java:73,8-73,22 +// T:K.kt:54,18-54,21 +// f1:J.java:77,9-79,5 +// f1:K.kt:61,8-61,36 +// p1:K.kt:56,14-56,25 +// p2:J.java:77,26-77,31 +// p2:K.kt:61,21-61,36 +// v1:K.kt:55,18-55,26 +// v1:K.kt:55,18-55,26 +// v2:J.java:74,18-74,25 +// v2:K.kt:58,18-58,25 +// v3.getter():K.kt:66,8-66,22 +// v3.setter():K.kt:67,8-67,35 +// v3:J.java:82,17-82,36 // END diff --git a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/LocationsProcessor.kt b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/LocationsProcessor.kt index 087a09f222..7109b0ef23 100644 --- a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/LocationsProcessor.kt +++ b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/LocationsProcessor.kt @@ -22,9 +22,13 @@ class LocationsProcessor : AbstractTestProcessor() { is FileLocation -> { val filename = File(location.filePath).name val line = location.lineNumber - result.add("$it:$filename:$line") + val endLine = location.endLineNumber + val column = location.column + val endColumn = location.endColumn + + result += "$it:$filename:$line,$column-$endLine,$endColumn" } - is NonExistLocation -> result.add("$it:NonExistLocation") + is NonExistLocation -> result += "$it:NonExistLocation" } } } diff --git a/test-utils/testData/api/locations.kt b/test-utils/testData/api/locations.kt index 44562be950..cfb728680f 100644 --- a/test-utils/testData/api/locations.kt +++ b/test-utils/testData/api/locations.kt @@ -17,24 +17,24 @@ // TEST PROCESSOR: LocationsProcessor // EXPECTED: -// A:K.kt:49 -// File: K.kt:K.kt:1 -// K:J.java:71 -// K:K.kt:52 -// T:J.java:71 -// T:K.kt:52 -// f1:J.java:75 -// f1:K.kt:59 -// p1:K.kt:54 -// p2:J.java:75 -// p2:K.kt:59 -// v1:K.kt:53 -// v1:K.kt:53 -// v2:J.java:72 -// v2:K.kt:56 -// v3.getter():K.kt:64 -// v3.setter():K.kt:65 -// v3:J.java:80 +// A:K.kt:49,10-49,15 +// File: K.kt:K.kt:1,0-68,0 +// K:J.java:71,6-81,1 +// K:K.kt:52,6-66,1 +// T:J.java:71,8-71,22 +// T:K.kt:52,18-52,21 +// f1:J.java:75,9-77,5 +// f1:K.kt:59,8-59,36 +// p1:K.kt:54,14-54,25 +// p2:J.java:75,26-75,31 +// p2:K.kt:59,21-59,36 +// v1:K.kt:53,18-53,26 +// v1:K.kt:53,18-53,26 +// v2:J.java:72,18-72,25 +// v2:K.kt:56,18-56,25 +// v3.getter():K.kt:64,8-64,22 +// v3.setter():K.kt:65,8-65,35 +// v3:J.java:80,17-80,36 // END // FILE: Location.kt