[FIR] Add RedundantCallOfConversionMethod checker
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
interface IC {
|
||||
fun toString(x: String): String = "IC$x"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
FILE: StringTemplate.kt
|
||||
public abstract interface IC : R|kotlin/Any| {
|
||||
public open fun toString(x: R|kotlin/String|): R|kotlin/String| {
|
||||
^toString <strcat>(String(IC), R|<local>/x|.R|kotlin/Any.toString|())
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun Boolean.toInt() = if (this) 1 else 0
|
||||
|
||||
fun test(x: Int, y: Int): Int {
|
||||
return (x > y).toInt()
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
FILE: booleanToInt.kt
|
||||
public final fun R|kotlin/Boolean|.toInt(): R|kotlin/Int| {
|
||||
^toInt when () {
|
||||
this@R|/toInt| -> {
|
||||
Int(1)
|
||||
}
|
||||
else -> {
|
||||
Int(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final fun test(x: R|kotlin/Int|, y: R|kotlin/Int|): R|kotlin/Int| {
|
||||
^test CMP(>, R|<local>/x|.R|kotlin/Int.compareTo|(R|<local>/y|)).R|/toInt|()
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = Byte.MAX_VALUE.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toByte()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: byte.kt
|
||||
public final val foo: R|kotlin/Byte| = Q|kotlin/Byte|.R|kotlin/Byte.Companion.MAX_VALUE|.R|kotlin/Byte.toByte|()
|
||||
public get(): R|kotlin/Byte|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = 'a'.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toChar()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: char.kt
|
||||
public final val foo: R|kotlin/Char| = Char(a).R|kotlin/Char.toChar|()
|
||||
public get(): R|kotlin/Char|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = 1.1.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toDouble()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: double.kt
|
||||
public final val foo: R|kotlin/Double| = Double(1.1).R|kotlin/Double.toDouble|()
|
||||
public get(): R|kotlin/Double|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = 1.1f.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toFloat()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: float.kt
|
||||
public final val foo: R|kotlin/Float| = Float(1.1).R|kotlin/Float.toFloat|()
|
||||
public get(): R|kotlin/Float|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = 1.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toInt()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: int.kt
|
||||
public final val foo: R|kotlin/Int| = Int(1).R|kotlin/Int.toInt|()
|
||||
public get(): R|kotlin/Int|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = Long.MAX_VALUE.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toLong()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: long.kt
|
||||
public final val foo: R|kotlin/Long| = Q|kotlin/Long|.R|kotlin/Long.Companion.MAX_VALUE|.R|kotlin/Long.toLong|()
|
||||
public get(): R|kotlin/Long|
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
// WITH_RUNTIME
|
||||
// IS_APPLICABLE: false
|
||||
fun foo(s: String?) {
|
||||
val t: String = s.toString()
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: nullable.kt
|
||||
public final fun foo(s: R|kotlin/String?|): R|kotlin/Unit| {
|
||||
lval t: R|kotlin/String| = R|<local>/s|.R|kotlin/toString|()
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
data class Foo(val name: String)
|
||||
|
||||
fun nullable2(foo: Foo?) {
|
||||
val s: String = foo?.name.toString()
|
||||
}
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
FILE: nullable2.kt
|
||||
public final data class Foo : R|kotlin/Any| {
|
||||
public constructor(name: R|kotlin/String|): R|Foo| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val name: R|kotlin/String| = R|<local>/name|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final fun component1(): R|kotlin/String|
|
||||
|
||||
public final fun copy(name: R|kotlin/String| = this@R|/Foo|.R|/Foo.name|): R|Foo|
|
||||
|
||||
}
|
||||
public final fun nullable2(foo: R|Foo?|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String| = R|<local>/foo|?.{ $subj$.R|/Foo.name| }.R|kotlin/toString|()
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun test() {
|
||||
val foo: String? = null
|
||||
foo?.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toString()<!>
|
||||
}
|
||||
compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/safeString.txt
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
FILE: safeString.kt
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lval foo: R|kotlin/String?| = Null(null)
|
||||
R|<local>/foo|?.{ $subj$.R|kotlin/Any.toString|() }
|
||||
}
|
||||
compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/safeString2.kt
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
data class Foo(val name: String)
|
||||
|
||||
fun test(foo: Foo?) {
|
||||
val s: String? = foo?.name?.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toString()<!>
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
FILE: safeString2.kt
|
||||
public final data class Foo : R|kotlin/Any| {
|
||||
public constructor(name: R|kotlin/String|): R|Foo| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public final val name: R|kotlin/String| = R|<local>/name|
|
||||
public get(): R|kotlin/String|
|
||||
|
||||
public final fun component1(): R|kotlin/String|
|
||||
|
||||
public final fun copy(name: R|kotlin/String| = this@R|/Foo|.R|/Foo.name|): R|Foo|
|
||||
|
||||
}
|
||||
public final fun test(foo: R|Foo?|): R|kotlin/Unit| {
|
||||
lval s: R|kotlin/String?| = R|<local>/foo|?.{ $subj$.R|/Foo.name| }?.{ $subj$.R|kotlin/Any.toString|() }
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = Short.MAX_VALUE.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toShort()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: short.kt
|
||||
public final val foo: R|kotlin/Short| = Q|kotlin/Short|.R|kotlin/Short.Companion.MAX_VALUE|.R|kotlin/Short.toShort|()
|
||||
public get(): R|kotlin/Short|
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = "".<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toString()<!>
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
FILE: string.kt
|
||||
public final val foo: R|kotlin/String| = String().R|kotlin/Any.toString|()
|
||||
public get(): R|kotlin/String|
|
||||
compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/toOtherType.kt
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
// IS_APPLICABLE: false
|
||||
val foo = 1.toLong()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
FILE: toOtherType.kt
|
||||
public final val foo: R|kotlin/Long| = Int(1).R|kotlin/Int.toLong|()
|
||||
public get(): R|kotlin/Long|
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun test(i: UByte) {
|
||||
val foo = i.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toUByte()<!>
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: uByte.kt
|
||||
public final fun test(i: R|kotlin/UByte|): R|kotlin/Unit| {
|
||||
lval foo: R|kotlin/UByte| = R|<local>/i|.R|kotlin/UByte.toUByte|()
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun test(i: UInt) {
|
||||
val foo = i.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toUInt()<!>
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: uInt.kt
|
||||
public final fun test(i: R|kotlin/UInt|): R|kotlin/Unit| {
|
||||
lval foo: R|kotlin/UInt| = R|<local>/i|.R|kotlin/UInt.toUInt|()
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun test(i: ULong) {
|
||||
val foo = i.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toULong()<!>
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: uLong.kt
|
||||
public final fun test(i: R|kotlin/ULong|): R|kotlin/Unit| {
|
||||
lval foo: R|kotlin/ULong| = R|<local>/i|.R|kotlin/ULong.toULong|()
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
fun test(i: UShort) {
|
||||
val foo = i.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toUShort()<!>
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: uShort.kt
|
||||
public final fun test(i: R|kotlin/UShort|): R|kotlin/Unit| {
|
||||
lval foo: R|kotlin/UShort| = R|<local>/i|.R|kotlin/UShort.toUShort|()
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
val foo = ""
|
||||
val bar = foo.<!REDUNDANT_CALL_OF_CONVERSION_METHOD!>toString()<!>
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
FILE: variable.kt
|
||||
public final val foo: R|kotlin/String| = String()
|
||||
public get(): R|kotlin/String|
|
||||
public final val bar: R|kotlin/String| = R|/foo|.R|kotlin/Any.toString|()
|
||||
public get(): R|kotlin/String|
|
||||
Generated
+113
@@ -166,6 +166,119 @@ public class ExtendedFirDiagnosticsTestGenerated extends AbstractExtendedFirDiag
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class RedundantCallOfConversionMethod extends AbstractExtendedFirDiagnosticsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRedundantCallOfConversionMethod() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("booleanToInt.kt")
|
||||
public void testBooleanToInt() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/booleanToInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("byte.kt")
|
||||
public void testByte() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/byte.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("char.kt")
|
||||
public void testChar() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/char.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("double.kt")
|
||||
public void testDouble() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/double.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("float.kt")
|
||||
public void testFloat() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/float.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("int.kt")
|
||||
public void testInt() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/int.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("long.kt")
|
||||
public void testLong() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/long.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullable.kt")
|
||||
public void testNullable() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/nullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullable2.kt")
|
||||
public void testNullable2() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/nullable2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeString.kt")
|
||||
public void testSafeString() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/safeString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeString2.kt")
|
||||
public void testSafeString2() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/safeString2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("short.kt")
|
||||
public void testShort() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/short.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("string.kt")
|
||||
public void testString() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/string.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("StringTemplate.kt")
|
||||
public void testStringTemplate() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/StringTemplate.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toOtherType.kt")
|
||||
public void testToOtherType() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/toOtherType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("uByte.kt")
|
||||
public void testUByte() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/uByte.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("uInt.kt")
|
||||
public void testUInt() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/uInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("uLong.kt")
|
||||
public void testULong() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/uLong.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("uShort.kt")
|
||||
public void testUShort() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/uShort.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variable.kt")
|
||||
public void testVariable() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/extendedCheckers/RedundantCallOfConversionMethod/variable.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/analysis-tests/testData/extendedCheckers/emptyRangeChecker")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+3
@@ -5,6 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.extended.RedundantCallOfConversionMethod
|
||||
|
||||
object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
override val expressionCheckers: List<FirBasicExpresionChecker> = listOf()
|
||||
override val qualifiedAccessCheckers: List<FirQualifiedAccessChecker> = listOf(
|
||||
@@ -16,6 +18,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirProjectionsOnNonClassTypeArgumentChecker,
|
||||
FirUpperBoundViolatedChecker,
|
||||
FirTypeArgumentsNotAllowedExpressionChecker,
|
||||
RedundantCallOfConversionMethod
|
||||
)
|
||||
override val functionCallCheckers: List<FirFunctionCallChecker> = listOf()
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.isMarkedNullable
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
object RedundantCallOfConversionMethod : FirQualifiedAccessChecker() {
|
||||
override fun check(functionCall: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (functionCall !is FirFunctionCall) return
|
||||
if (functionCall.source?.kind == FirFakeSourceElementKind.GeneratedToStringCallOnTemplateEntry) return
|
||||
val functionName = functionCall.calleeReference.name.asString()
|
||||
val qualifiedType = targetClassMap[functionName] ?: return
|
||||
|
||||
if (functionCall.explicitReceiver?.isRedundant(qualifiedType) == true) {
|
||||
reporter.report(functionCall.source, FirErrors.REDUNDANT_CALL_OF_CONVERSION_METHOD)
|
||||
}
|
||||
}
|
||||
|
||||
private val targetClassMap = mapOf(
|
||||
"toString" to StandardClassIds.String,
|
||||
"toDouble" to StandardClassIds.Double,
|
||||
"toFloat" to StandardClassIds.Float,
|
||||
"toLong" to StandardClassIds.Long,
|
||||
"toInt" to StandardClassIds.Int,
|
||||
"toChar" to StandardClassIds.Char,
|
||||
"toShort" to StandardClassIds.Short,
|
||||
"toByte" to StandardClassIds.Byte,
|
||||
"toULong" to StandardClassIds.ULong,
|
||||
"toUInt" to StandardClassIds.UInt,
|
||||
"toUShort" to StandardClassIds.UShort,
|
||||
"toUByte" to StandardClassIds.UByte
|
||||
)
|
||||
|
||||
private fun FirExpression.isRedundant(qualifiedClassId: ClassId): Boolean {
|
||||
val thisType = if (this is FirConstExpression<*>) {
|
||||
this.typeRef.coneType.classId
|
||||
} else {
|
||||
val binaryExpression = psi as? KtBinaryExpression
|
||||
val operator = binaryExpression?.operationToken
|
||||
if (operator in OperatorConventions.COMPARISON_OPERATIONS) {
|
||||
// Special case here because compareTo returns Int
|
||||
StandardClassIds.Boolean
|
||||
} else {
|
||||
when {
|
||||
typeRef.coneType is ConeFlexibleType -> null
|
||||
psi?.parent !is KtSafeQualifiedExpression
|
||||
&& (psi is KtSafeQualifiedExpression || typeRef.coneType.isMarkedNullable) -> null
|
||||
this.typeRef.coneType.isMarkedNullable -> null
|
||||
else -> this.typeRef.coneType.classId
|
||||
}
|
||||
}
|
||||
}
|
||||
return thisType == qualifiedClassId
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -104,8 +104,7 @@ object FirErrors {
|
||||
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning0<FirSourceElement, PsiElement>()
|
||||
val CAN_BE_VAL by warning0<FirSourceElement, PsiElement>()
|
||||
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning0<FirSourceElement, PsiElement>()
|
||||
val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning0<FirSourceElement, PsiElement>()
|
||||
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning0<FirSourceElement, PsiElement>()
|
||||
val EMPTY_RANGE by warning0<FirSourceElement, PsiElement>()
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user