[FIR] Add redundant single string expression template checker
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
|||||||
|
val x = "Hello"
|
||||||
|
|
||||||
|
val y = "$<!REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE!>x<!>"
|
||||||
|
|
||||||
|
val z = "${y.hashCode()}"
|
||||||
|
|
||||||
|
fun toString(x: String) = "IC$x"
|
||||||
|
|
||||||
|
data class ProductGroup(val short_name: String, val parent: ProductGroup?) {
|
||||||
|
val name: String = if (parent == null) short_name else "${parent.name} $short_name"
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
FILE: RedundantSingleExpressionStringTemplateChecker.kt
|
||||||
|
public final val x: R|kotlin/String| = String(Hello)
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
public final val y: R|kotlin/String| = R|/x|.R|kotlin/Any.toString|()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
public final val z: R|kotlin/String| = R|/y|.R|kotlin/Any.hashCode|().R|kotlin/Any.toString|()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
public final fun toString(x: R|kotlin/String|): R|kotlin/String| {
|
||||||
|
^toString <strcat>(String(IC), R|<local>/x|.R|kotlin/Any.toString|())
|
||||||
|
}
|
||||||
|
public final data class ProductGroup : R|kotlin/Any| {
|
||||||
|
public constructor(short_name: R|kotlin/String|, parent: R|ProductGroup?|): R|ProductGroup| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val short_name: R|kotlin/String| = R|<local>/short_name|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
public final val parent: R|ProductGroup?| = R|<local>/parent|
|
||||||
|
public get(): R|ProductGroup?|
|
||||||
|
|
||||||
|
public final val name: R|kotlin/String| = when () {
|
||||||
|
==(R|<local>/parent|, Null(null)) -> {
|
||||||
|
R|<local>/short_name|
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
<strcat>(R|<local>/parent|.R|/ProductGroup.name|.R|kotlin/Any.toString|(), String( ), R|<local>/short_name|.R|kotlin/Any.toString|())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
public final fun component1(): R|kotlin/String|
|
||||||
|
|
||||||
|
public final fun component2(): R|ProductGroup?|
|
||||||
|
|
||||||
|
public final fun copy(short_name: R|kotlin/String| = this@R|/ProductGroup|.R|/ProductGroup.short_name|, parent: R|ProductGroup?| = this@R|/ProductGroup|.R|/ProductGroup.parent|): R|ProductGroup|
|
||||||
|
|
||||||
|
}
|
||||||
Generated
+5
@@ -48,6 +48,11 @@ public class ExtendedFirDiagnosticsTestGenerated extends AbstractExtendedFirDiag
|
|||||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantReturnUnitTypeChecker.kt");
|
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantReturnUnitTypeChecker.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("RedundantSingleExpressionStringTemplateChecker.kt")
|
||||||
|
public void testRedundantSingleExpressionStringTemplateChecker() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantSingleExpressionStringTemplateChecker.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("RedundantVisibilityModifierChecker.kt")
|
@TestMetadata("RedundantVisibilityModifierChecker.kt")
|
||||||
public void testRedundantVisibilityModifierChecker() throws Exception {
|
public void testRedundantVisibilityModifierChecker() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantVisibilityModifierChecker.kt");
|
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantVisibilityModifierChecker.kt");
|
||||||
|
|||||||
+3
-1
@@ -7,10 +7,12 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.extended.ArrayEqualityCanBeReplacedWithEquals
|
import org.jetbrains.kotlin.fir.analysis.checkers.extended.ArrayEqualityCanBeReplacedWithEquals
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.extended.CanBeReplacedWithOperatorAssignmentChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.extended.CanBeReplacedWithOperatorAssignmentChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.extended.RedundantSingleExpressionStringTemplateChecker
|
||||||
|
|
||||||
object ExtendedExpressionCheckers : ExpressionCheckers() {
|
object ExtendedExpressionCheckers : ExpressionCheckers() {
|
||||||
override val expressionCheckers: List<FirBasicExpresionChecker> = listOf(
|
override val expressionCheckers: List<FirBasicExpresionChecker> = listOf(
|
||||||
ArrayEqualityCanBeReplacedWithEquals
|
ArrayEqualityCanBeReplacedWithEquals,
|
||||||
|
RedundantSingleExpressionStringTemplateChecker
|
||||||
)
|
)
|
||||||
override val variableAssignmentCheckers: List<FirVariableAssignmentChecker> = listOf(
|
override val variableAssignmentCheckers: List<FirVariableAssignmentChecker> = listOf(
|
||||||
CanBeReplacedWithOperatorAssignmentChecker
|
CanBeReplacedWithOperatorAssignmentChecker
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.analysis.checkers.extended
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirBasicExpresionChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
|
import org.jetbrains.kotlin.fir.psi
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
|
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||||
|
|
||||||
|
object RedundantSingleExpressionStringTemplateChecker : FirBasicExpresionChecker() {
|
||||||
|
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (expression.source?.kind != FirFakeSourceElementKind.GeneratedToStringCallOnTemplateEntry) return
|
||||||
|
if (expression !is FirFunctionCall) return
|
||||||
|
if (
|
||||||
|
expression.explicitReceiver?.typeRef?.coneType?.classId == StandardClassIds.String
|
||||||
|
&& expression.psi?.findStringParent()?.children?.size == 1 // there is no more children in original string template
|
||||||
|
) {
|
||||||
|
reporter.report(expression.source, REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.findStringParent(): KtStringTemplateExpression? {
|
||||||
|
if (this is KtStringTemplateExpression) return this
|
||||||
|
return if (this.parent != null) this.parent.findStringParent()
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,7 +89,10 @@ object FirErrors {
|
|||||||
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, PsiElement>()
|
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, PsiElement>()
|
||||||
val REDUNDANT_RETURN_UNIT_TYPE by warning0<FirSourceElement, PsiTypeElement>()
|
val REDUNDANT_RETURN_UNIT_TYPE by warning0<FirSourceElement, PsiTypeElement>()
|
||||||
val REDUNDANT_EXPLICIT_TYPE by warning0<FirSourceElement, PsiElement>()
|
val REDUNDANT_EXPLICIT_TYPE by warning0<FirSourceElement, PsiElement>()
|
||||||
|
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0<FirSourceElement, PsiElement>()
|
||||||
val CAN_BE_VAL by warning0<FirSourceElement, PsiElement>()
|
val CAN_BE_VAL by warning0<FirSourceElement, PsiElement>()
|
||||||
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning0<FirSourceElement, PsiElement>()
|
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning0<FirSourceElement, PsiElement>()
|
||||||
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, PsiElement>()
|
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, PsiElement>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user