Skip to content

Commit

Permalink
Merge branch 'fix-maxlinelength' into location-10
Browse files Browse the repository at this point in the history
  • Loading branch information
3flex committed May 8, 2024
2 parents 4ec6ce3 + eef6467 commit 63e545f
Show file tree
Hide file tree
Showing 11 changed files with 49 additions and 82 deletions.
2 changes: 1 addition & 1 deletion detekt-compiler-plugin/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlinCompilerChecksum=93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88
kotlinCompilerChecksum=eb7b68e01029fa67bc8d060ee54c12018f2c60ddc438cf21db14517229aa693b

kotlin.code.style=official
systemProp.sonar.host.url=http://localhost:9000
Expand Down
4 changes: 0 additions & 4 deletions detekt-psi-utils/api/detekt-psi-utils.api
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ public final class io/gitlab/arturbosch/detekt/rules/IsPartOfUtilsKt {

public final class io/gitlab/arturbosch/detekt/rules/JunkKt {
public static final fun companionObject (Lorg/jetbrains/kotlin/psi/KtClass;)Lorg/jetbrains/kotlin/psi/KtObjectDeclaration;
public static final fun getIntValueForPsiElement (Lorg/jetbrains/kotlin/com/intellij/psi/PsiElement;)Ljava/lang/Integer;
public static final fun hasCommentInside (Lorg/jetbrains/kotlin/com/intellij/psi/PsiElement;)Z
public static final fun hasCommentInside (Lorg/jetbrains/kotlin/psi/KtClassOrObject;)Z
public static final fun isUsedForNesting (Lorg/jetbrains/kotlin/psi/KtCallExpression;)Z
public static final fun receiverIsUsed (Lorg/jetbrains/kotlin/psi/KtCallExpression;Lorg/jetbrains/kotlin/resolve/BindingContext;)Z
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,12 @@
package io.gitlab.arturbosch.detekt.rules

import org.jetbrains.kotlin.com.intellij.openapi.util.Key
import org.jetbrains.kotlin.com.intellij.psi.PsiComment
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtConstantExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression

fun KtCallExpression.isUsedForNesting(): Boolean = when (getCallNameExpression()?.text) {
"run", "let", "apply", "with", "use", "forEach" -> true
else -> false
}

fun KtClassOrObject.hasCommentInside() = this.body?.hasCommentInside() ?: false

fun PsiElement.hasCommentInside(): Boolean {
val commentKey = Key<Boolean>("comment")
this.acceptChildren(object : KtTreeVisitorVoid() {
override fun visitComment(comment: PsiComment) {
putUserData(commentKey, true)
}
})
return getUserData(commentKey) == true
}

fun getIntValueForPsiElement(element: PsiElement): Int? {
return (element as? KtConstantExpression)?.text?.toIntOrNull()
}

fun KtClass.companionObject() = this.companionObjects.singleOrNull { it.isCompanion() }

fun KtCallExpression.receiverIsUsed(context: BindingContext): Boolean =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import io.gitlab.arturbosch.detekt.api.DetektVisitor
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.config
import io.gitlab.arturbosch.detekt.rules.isUsedForNesting
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtContainerNodeForControlStructureBody
import org.jetbrains.kotlin.psi.KtIfExpression
Expand All @@ -16,6 +15,7 @@ import org.jetbrains.kotlin.psi.KtLoopExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.psi.psiUtil.getCallNameExpression

/**
* This rule reports excessive nesting depth in functions. Excessively nested code becomes harder to read and increases
Expand Down Expand Up @@ -110,5 +110,8 @@ class NestedBlockDepth(config: Config) : Rule(
}
}
}

private fun KtCallExpression.isUsedForNesting(): Boolean =
getCallNameExpression()?.text in setOf("run", "let", "apply", "with", "use", "forEach")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.gitlab.arturbosch.detekt.api.ActiveByDefault
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.rules.hasCommentInside
import io.gitlab.arturbosch.detekt.rules.empty.internal.hasCommentInside
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.rules.hasCommentInside
import io.gitlab.arturbosch.detekt.rules.empty.internal.hasCommentInside
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.psi.KtBlockExpression
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.gitlab.arturbosch.detekt.rules.empty.internal

import org.jetbrains.kotlin.com.intellij.psi.PsiComment
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType

fun KtClassOrObject.hasCommentInside() = this.body?.hasCommentInside() ?: false

fun PsiElement.hasCommentInside(): Boolean = getChildrenOfType<PsiComment>().isNotEmpty()
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.rules.getIntValueForPsiElement
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtConstantExpression

/**
* Reports ranges which are empty.
Expand Down Expand Up @@ -35,38 +34,21 @@ class InvalidRange(config: Config) : Rule(
"If a for loops condition is false before the first iteration, the loop will never get executed."
) {

private val minimumSize = 3

override fun visitBinaryExpression(expression: KtBinaryExpression) {
val range = expression.children
if (range.size >= minimumSize && hasInvalidLoopRange(range)) {
report(
CodeSmell(
Entity.from(expression),
"This loop will never be executed due to its expression."
)
)
if (expression.isInvalidLoopRange()) {
report(CodeSmell(Entity.from(expression), "This loop will never be executed due to its expression."))
}
super.visitBinaryExpression(expression)
}

private fun hasInvalidLoopRange(range: Array<PsiElement>): Boolean {
val lowerValue = getIntValueForPsiElement(range[0])
val upperValue = getIntValueForPsiElement(range[2])
if (lowerValue == null || upperValue == null) {
return false
}
return when (range[1].text) {
".." -> checkRangeTo(lowerValue, upperValue)
"downTo" -> checkDownTo(lowerValue, upperValue)
"until", "..<" -> checkUntil(lowerValue, upperValue)
private fun KtBinaryExpression.isInvalidLoopRange(): Boolean {
val lower = (left as? KtConstantExpression)?.text?.toIntOrNull() ?: return false
val upper = (right as? KtConstantExpression)?.text?.toIntOrNull() ?: return false
return when (operationReference.text) {
".." -> lower > upper
"downTo" -> lower < upper
"until", "..<" -> lower >= upper
else -> false
}
}

private fun checkRangeTo(lower: Int, upper: Int) = lower > upper

private fun checkDownTo(lower: Int, upper: Int) = lower < upper

private fun checkUntil(lower: Int, upper: Int) = lower >= upper
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
* the given [line] from a given offset in a [KtFile].
*/
internal fun findKtElementInParents(file: KtFile, offset: Int, line: String): Sequence<PsiElement> {
return file.elementsInRange(TextRange.create(offset - line.length, offset))
return file.elementsInRange(TextRange.create(offset, offset + line.length))
.asSequence()
.plus(file.findElementAt(offset))
.mapNotNull { it?.getNonStrictParentOfType() }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.gitlab.arturbosch.detekt.rules.style

import io.github.detekt.psi.absolutePath
import io.gitlab.arturbosch.detekt.api.ActiveByDefault
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
Expand All @@ -13,10 +14,13 @@ import io.gitlab.arturbosch.detekt.api.config
import io.gitlab.arturbosch.detekt.rules.lastArgumentMatchesKotlinReferenceUrlSyntax
import io.gitlab.arturbosch.detekt.rules.lastArgumentMatchesMarkdownUrlSyntax
import io.gitlab.arturbosch.detekt.rules.lastArgumentMatchesUrl
import org.jetbrains.kotlin.KtPsiSourceFileLinesMapping
import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.getLineAndColumnRangeInPsiFile
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType

/**
* This rule reports lines of code which exceed a defined maximum line length.
Expand Down Expand Up @@ -48,26 +52,26 @@ class MaxLineLength(config: Config) : Rule(

override fun visitKtFile(file: KtFile) {
super.visitKtFile(file)
var offset = 0
val lines = file.text.lines()

for (line in lines) {
offset += line.length
if (!isValidLine(file, offset, line)) {
val sourceFileLinesMapping = KtPsiSourceFileLinesMapping(file)

file.text.lines().withIndex()
.filterNot { isValidLine(file, sourceFileLinesMapping.getLineStartOffset(it.index), it.value) }
.forEach {
val offset = sourceFileLinesMapping.getLineStartOffset(it.index)
val line = it.value
val ktElement = findFirstMeaningfulKtElementInParents(file, offset, line) ?: file
val location = Location.from(file, offset - line.length).let { location ->
val textRange = TextRange(offset, offset + line.length)
val lineAndColumnRange = getLineAndColumnRangeInPsiFile(file, textRange)
val location =
Location(
source = location.source,
endSource = SourceLocation(location.source.line, line.length + 1),
text = TextLocation(offset - line.length, offset),
path = location.path,
source = SourceLocation(lineAndColumnRange.start.line, lineAndColumnRange.start.column),
endSource = SourceLocation(lineAndColumnRange.end.line, lineAndColumnRange.end.column),
text = TextLocation(offset, offset + line.length),
path = file.absolutePath(),
)
}
report(CodeSmell(Entity.from(ktElement, location), description))
}

offset += 1 // '\n'
}
}

private fun isValidLine(file: KtFile, offset: Int, line: String): Boolean {
Expand Down Expand Up @@ -123,5 +127,5 @@ class MaxLineLength(config: Config) : Rule(
}

private fun PsiElement.isInsideRawString(): Boolean {
return this is KtStringTemplateExpression || getParentOfType<KtStringTemplateExpression>(false) != null
return this is KtStringTemplateExpression || getNonStrictParentOfType<KtStringTemplateExpression>() != null
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
dokka = "1.9.20"
jacoco = "0.8.12"
kotlin = "1.9.23"
kotlin = "1.9.24"
coroutines = "1.8.0"
ktlint = "1.2.1"
junit = "5.10.2"
Expand Down

0 comments on commit 63e545f

Please sign in to comment.