From 165b2dc6d641440c5751dc28055f8f9ec923e333 Mon Sep 17 00:00:00 2001 From: Brais Date: Sat, 9 Jul 2022 17:43:38 +0200 Subject: [PATCH] Forbit usage of DiagnosticUtils.getLineAndColumnInPsiFile --- config/detekt/detekt.yml | 1 + .../io/gitlab/arturbosch/detekt/api/Location.kt | 10 +++------- .../kotlin/io/github/detekt/metrics/LinesOfCode.kt | 13 ++----------- detekt-psi-utils/api/detekt-psi-utils.api | 1 + .../src/main/kotlin/io/github/detekt/psi/KtFiles.kt | 11 +++++++++++ .../detekt/rules/style/NewLineAtEndOfFile.kt | 6 +++--- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 399eee6b89d..5b36faedc51 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -191,6 +191,7 @@ style: - 'java.net.URL.openStream' - 'java.lang.Class.getResourceAsStream' - 'java.lang.ClassLoader.getResourceAsStream' + - 'org.jetbrains.kotlin.diagnostics.DiagnosticUtils.getLineAndColumnInPsiFile' ForbiddenVoid: active: true LibraryCodeMustSpecifyReturnType: diff --git a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt index a95648addb8..41da22bda63 100644 --- a/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt +++ b/detekt-api/src/main/kotlin/io/gitlab/arturbosch/detekt/api/Location.kt @@ -1,10 +1,10 @@ package io.gitlab.arturbosch.detekt.api import io.github.detekt.psi.FilePath +import io.github.detekt.psi.getLineAndColumnInPsiFile import io.github.detekt.psi.toFilePath import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.com.intellij.psi.PsiElement -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -99,12 +99,8 @@ data class Location @Deprecated("Consider relative path by passing a [FilePath]" ) private fun lineAndColumn(element: PsiElement, range: TextRange): PsiDiagnosticUtils.LineAndColumn { - return try { - 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) - } + return getLineAndColumnInPsiFile(element.containingFile, range) + ?: PsiDiagnosticUtils.LineAndColumn(-1, -1, null) } } } diff --git a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt index d93f7b51e3a..398a4206694 100644 --- a/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt +++ b/detekt-metrics/src/main/kotlin/io/github/detekt/metrics/LinesOfCode.kt @@ -2,6 +2,7 @@ package io.github.detekt.metrics +import io.github.detekt.psi.getLineAndColumnInPsiFile import org.jetbrains.kotlin.com.intellij.lang.ASTNode import org.jetbrains.kotlin.com.intellij.psi.PsiComment import org.jetbrains.kotlin.com.intellij.psi.PsiElement @@ -10,7 +11,6 @@ import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafElement import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiCommentImpl import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiCoreCommentImpl import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.kdoc.psi.api.KDoc import org.jetbrains.kotlin.kdoc.psi.api.KDocElement import org.jetbrains.kotlin.kdoc.psi.impl.KDocElementImpl @@ -44,16 +44,7 @@ fun KtElement.linesOfCode(inFile: KtFile = this.containingKtFile): Int = .distinct() .count() -fun ASTNode.line(inFile: KtFile): Int = try { - DiagnosticUtils.getLineAndColumnInPsiFile(inFile, this.textRange).line -} catch (@Suppress("SwallowedException", "TooGenericExceptionCaught") e: IndexOutOfBoundsException) { - // When auto-correctable rules performs actual mutation, KtFile.text is updated but - // KtFile.viewProvider.document is not updated. This will cause crash in subsequent rules - // if they are using any function relying on the KtFile.viewProvider.document. - // The exception is silenced to return -1 while we should seek long-term solution for execution - // order of rules (#3445) - -1 -} +fun ASTNode.line(inFile: KtFile): Int = getLineAndColumnInPsiFile(inFile, this.textRange)?.line ?: -1 private val comments: Set> = setOf( PsiWhiteSpace::class.java, diff --git a/detekt-psi-utils/api/detekt-psi-utils.api b/detekt-psi-utils/api/detekt-psi-utils.api index cdb632ca8a2..059942650fe 100644 --- a/detekt-psi-utils/api/detekt-psi-utils.api +++ b/detekt-psi-utils/api/detekt-psi-utils.api @@ -33,6 +33,7 @@ public final class io/github/detekt/psi/KtFilesKt { public static final fun basePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/nio/file/Path; public static final fun fileNameWithoutSuffix (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/lang/String; public static final fun getFileName (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/lang/String; + public static final fun getLineAndColumnInPsiFile (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;Lorg/jetbrains/kotlin/com/intellij/openapi/util/TextRange;)Lorg/jetbrains/kotlin/diagnostics/PsiDiagnosticUtils$LineAndColumn; public static final fun relativePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Ljava/nio/file/Path; public static final fun toFilePath (Lorg/jetbrains/kotlin/com/intellij/psi/PsiFile;)Lio/github/detekt/psi/FilePath; public static final fun toUnifiedString (Ljava/nio/file/Path;)Ljava/lang/String; diff --git a/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt b/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt index 8b4b2be69c1..86809fa3a8d 100644 --- a/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt +++ b/detekt-psi-utils/src/main/kotlin/io/github/detekt/psi/KtFiles.kt @@ -1,6 +1,9 @@ package io.github.detekt.psi +import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.com.intellij.psi.PsiFile +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils +import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils import java.io.File import java.nio.file.Path import java.nio.file.Paths @@ -68,6 +71,14 @@ fun PsiFile.toFilePath(): FilePath { } } +// #3317 If any rule mutates the PsiElement, searching the original PsiElement may throw exception. +fun getLineAndColumnInPsiFile(file: PsiFile, range: TextRange): PsiDiagnosticUtils.LineAndColumn? { + return runCatching { + @Suppress("ForbiddenMethodCall") + DiagnosticUtils.getLineAndColumnInPsiFile(file, range) + }.getOrNull() +} + /** * Returns a system-independent string with UNIX system file separator. */ diff --git a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt index a04bbcd17bb..903b1bc6e3c 100644 --- a/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt +++ b/detekt-rules-style/src/main/kotlin/io/gitlab/arturbosch/detekt/rules/style/NewLineAtEndOfFile.kt @@ -1,5 +1,6 @@ package io.gitlab.arturbosch.detekt.rules.style +import io.github.detekt.psi.getLineAndColumnInPsiFile import io.github.detekt.psi.toFilePath import io.gitlab.arturbosch.detekt.api.CodeSmell import io.gitlab.arturbosch.detekt.api.Config @@ -13,7 +14,6 @@ import io.gitlab.arturbosch.detekt.api.SourceLocation import io.gitlab.arturbosch.detekt.api.TextLocation import io.gitlab.arturbosch.detekt.api.internal.ActiveByDefault import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -33,11 +33,11 @@ class NewLineAtEndOfFile(config: Config = Config.empty) : Rule(config) { override fun visitKtFile(file: KtFile) { val text = file.text if (text.isNotEmpty() && !text.endsWith('\n')) { - val coords = DiagnosticUtils.getLineAndColumnInPsiFile( + val coords = getLineAndColumnInPsiFile( file, TextRange(file.endOffset, file.endOffset) ) - val sourceLocation = SourceLocation(coords.line, coords.column) + val sourceLocation = SourceLocation(coords?.line ?: 0, coords?.column ?: 0) val textLocation = TextLocation(file.endOffset, file.endOffset) val location = Location(sourceLocation, textLocation, file.containingFile.toFilePath()) report(