From 6318da0f0222f9c754e192bbb5d7e47bcd822dd7 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Tue, 20 Jun 2023 17:06:58 +0200 Subject: [PATCH] [FIR] Remove or replace whole expressions in FIR diagnostic messages FIR expressions rendered by FirRenderer don't look very nice in error messages anyway, and additionally, they can become arbitrarily large, so we shouldn't use them in messages. #KT-59449 Fixed --- .../diagnostics/KtFirDataClassConverters.kt | 20 +++++------ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +-- .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 4 +-- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++++ ...sticCompilerFE10TestDataTestGenerated.java | 6 ++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 ++++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 ++++ .../diagnostics/FirDiagnosticsList.kt | 4 +-- .../fir/analysis/diagnostics/FirErrors.kt | 8 ++--- .../FirInlineDeclarationChecker.kt | 1 - .../FirEqualityCompatibilityChecker.kt | 2 +- .../diagnostics/FirDiagnosticRenderers.kt | 21 ++++++++---- .../diagnostics/FirErrorsDefaultMessages.kt | 34 +++++++++---------- .../coneDiagnosticToFirDiagnostic.kt | 2 ++ .../fir/references/FirReferenceUtils.kt | 7 ++++ .../complexExpression.diag.txt | 1 + .../complexExpression.fir.diag.txt | 1 + .../complexExpression.fir.kt | 7 ++++ .../senselessComparison/complexExpression.kt | 7 ++++ ...ienPropertyFromInvisibleClass.fir.diag.txt | 4 +-- .../test/runners/DiagnosticTestGenerated.java | 6 ++++ 21 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/senselessComparison/complexExpression.diag.txt create mode 100644 compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.diag.txt create mode 100644 compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.kt create mode 100644 compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index dbc280ad1c5..7a17a82f1b8 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3586,8 +3586,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert } add(FirErrors.SENSELESS_COMPARISON) { firDiagnostic -> SenselessComparisonImpl( - firDiagnostic.a.source!!.psi as KtExpression, - firDiagnostic.b, + firDiagnostic.a, firDiagnostic as KtPsiDiagnostic, token, ) @@ -3621,18 +3620,20 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert } add(FirErrors.UNSAFE_INFIX_CALL) { firDiagnostic -> UnsafeInfixCallImpl( - firDiagnostic.a.source!!.psi as KtExpression, - firDiagnostic.b, - firDiagnostic.c.source!!.psi as KtExpression, + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firDiagnostic.b.source!!.psi as KtExpression, + firDiagnostic.c, + firDiagnostic.d.source!!.psi as KtExpression, firDiagnostic as KtPsiDiagnostic, token, ) } add(FirErrors.UNSAFE_OPERATOR_CALL) { firDiagnostic -> UnsafeOperatorCallImpl( - firDiagnostic.a.source!!.psi as KtExpression, - firDiagnostic.b, - firDiagnostic.c.source!!.psi as KtExpression, + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firDiagnostic.b.source!!.psi as KtExpression, + firDiagnostic.c, + firDiagnostic.d.source!!.psi as KtExpression, firDiagnostic as KtPsiDiagnostic, token, ) @@ -4315,8 +4316,7 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert } add(FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE) { firDiagnostic -> InvalidDefaultFunctionalParameterForInlineImpl( - firDiagnostic.a.source!!.psi as KtExpression, - firSymbolBuilder.buildSymbol(firDiagnostic.b), + firSymbolBuilder.buildSymbol(firDiagnostic.a), firDiagnostic as KtPsiDiagnostic, token, ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 282bc753b04..50e86a29a4b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2506,7 +2506,6 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface SenselessComparison : KtFirDiagnostic { override val diagnosticClass get() = SenselessComparison::class - val expression: KtExpression val compareResult: Boolean } @@ -2531,6 +2530,7 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface UnsafeInfixCall : KtFirDiagnostic { override val diagnosticClass get() = UnsafeInfixCall::class + val receiverType: KtType val receiverExpression: KtExpression val operator: String val argumentExpression: KtExpression @@ -2538,6 +2538,7 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface UnsafeOperatorCall : KtFirDiagnostic { override val diagnosticClass get() = UnsafeOperatorCall::class + val receiverType: KtType val receiverExpression: KtExpression val operator: String val argumentExpression: KtExpression @@ -3011,7 +3012,6 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { interface InvalidDefaultFunctionalParameterForInline : KtFirDiagnostic { override val diagnosticClass get() = InvalidDefaultFunctionalParameterForInline::class - val defaultValue: KtExpression val parameter: KtSymbol } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 6aa4baafc8f..0117bc9a916 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -3018,7 +3018,6 @@ internal class UnreachableCodeImpl( ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnreachableCode internal class SenselessComparisonImpl( - override val expression: KtExpression, override val compareResult: Boolean, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, @@ -3048,6 +3047,7 @@ internal class UnsafeImplicitInvokeCallImpl( ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnsafeImplicitInvokeCall internal class UnsafeInfixCallImpl( + override val receiverType: KtType, override val receiverExpression: KtExpression, override val operator: String, override val argumentExpression: KtExpression, @@ -3056,6 +3056,7 @@ internal class UnsafeInfixCallImpl( ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnsafeInfixCall internal class UnsafeOperatorCallImpl( + override val receiverType: KtType, override val receiverExpression: KtExpression, override val operator: String, override val argumentExpression: KtExpression, @@ -3629,7 +3630,6 @@ internal class NonInternalPublishedApiImpl( ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.NonInternalPublishedApi internal class InvalidDefaultFunctionalParameterForInlineImpl( - override val defaultValue: KtExpression, override val parameter: KtSymbol, firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 41627f99923..fcfabd05fc0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -29742,6 +29742,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/senselessComparison"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("complexExpression.kt") + public void testComplexExpression() throws Exception { + runTest("compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt"); + } + @Test @TestMetadata("noExplicitType.kt") public void testNoExplicitType() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 44cbf727859..bf9ebd5db53 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -29742,6 +29742,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/senselessComparison"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("complexExpression.kt") + public void testComplexExpression() throws Exception { + runTest("compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt"); + } + @Test @TestMetadata("noExplicitType.kt") public void testNoExplicitType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 7ad47c13a4e..1faa6843283 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -29742,6 +29742,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/senselessComparison"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("complexExpression.kt") + public void testComplexExpression() throws Exception { + runTest("compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt"); + } + @Test @TestMetadata("noExplicitType.kt") public void testNoExplicitType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index fe0c183b532..aba17773bb1 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -29838,6 +29838,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/senselessComparison"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true, "multiplatform"); } + @Test + @TestMetadata("complexExpression.kt") + public void testComplexExpression() throws Exception { + runTest("compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt"); + } + @Test @TestMetadata("noExplicitType.kt") public void testNoExplicitType() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index e930d76eb9d..40995fa0bad 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -1236,7 +1236,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter>("unreachable") } val SENSELESS_COMPARISON by warning { - parameter("expression") parameter("compareResult") } val SENSELESS_NULL_IN_WHEN by warning() @@ -1252,11 +1251,13 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("receiverType") } val UNSAFE_INFIX_CALL by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) { + parameter("receiverType") parameter("receiverExpression") parameter("operator") parameter("argumentExpression") } val UNSAFE_OPERATOR_CALL by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) { + parameter("receiverType") parameter("receiverExpression") parameter("operator") parameter("argumentExpression") @@ -1520,7 +1521,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val NON_INTERNAL_PUBLISHED_API by error() val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error() { - parameter("defaultValue") parameter("parameter") } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index f010f9e0166..b4393562c8e 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -645,15 +645,15 @@ object FirErrors { val VARIABLE_WITH_NO_TYPE_NO_INITIALIZER by error0(SourceElementPositioningStrategies.DECLARATION_NAME) val INITIALIZATION_BEFORE_DECLARATION by error1>() val UNREACHABLE_CODE by warning2, Set>(SourceElementPositioningStrategies.UNREACHABLE_CODE) - val SENSELESS_COMPARISON by warning2() + val SENSELESS_COMPARISON by warning1() val SENSELESS_NULL_IN_WHEN by warning0() val TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM by error0() // Nullability val UNSAFE_CALL by error2(SourceElementPositioningStrategies.DOT_BY_QUALIFIED) val UNSAFE_IMPLICIT_INVOKE_CALL by error1(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) - val UNSAFE_INFIX_CALL by error3(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) - val UNSAFE_OPERATOR_CALL by error3(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) + val UNSAFE_INFIX_CALL by error4(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) + val UNSAFE_OPERATOR_CALL by error4(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val ITERATOR_ON_NULLABLE by error0() val UNNECESSARY_SAFE_CALL by warning1(SourceElementPositioningStrategies.SAFE_ACCESS) val SAFE_CALL_WILL_CHANGE_NULLABILITY by warning0(SourceElementPositioningStrategies.CALL_ELEMENT_WITH_DOT) @@ -770,7 +770,7 @@ object FirErrors { val DECLARATION_CANT_BE_INLINED by error0(SourceElementPositioningStrategies.INLINE_FUN_MODIFIER) val OVERRIDE_BY_INLINE by warning0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val NON_INTERNAL_PUBLISHED_API by error0() - val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error2() + val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error1() val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error0(SourceElementPositioningStrategies.REIFIED_MODIFIER) val INLINE_PROPERTY_WITH_BACKING_FIELD by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val ILLEGAL_INLINE_PARAMETER_MODIFIER by error0(SourceElementPositioningStrategies.INLINE_PARAMETER_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index 48d9cad5b23..699921d5699 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -420,7 +420,6 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { reporter.reportOn( defaultValue.source, FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE, - defaultValue, param.symbol, context ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt index 8dc0661bdcd..659da20572f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirEqualityCompatibilityChecker.kt @@ -273,7 +273,7 @@ object FirEqualityCompatibilityChecker : FirEqualityOperatorCallChecker() { if (expression.source?.elementType != KtNodeTypes.BINARY_EXPRESSION && type === lType && !compareResult) { reporter.reportOn(expression.source, FirErrors.SENSELESS_NULL_IN_WHEN, context) } else { - reporter.reportOn(expression.source, FirErrors.SENSELESS_COMPARISON, expression, compareResult, context) + reporter.reportOn(expression.source, FirErrors.SENSELESS_COMPARISON, compareResult, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index be866619756..1b11b49b2ee 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -11,10 +11,14 @@ import org.jetbrains.kotlin.diagnostics.KtDiagnosticRenderers import org.jetbrains.kotlin.diagnostics.WhenMissingCase import org.jetbrains.kotlin.diagnostics.rendering.ContextIndependentParameterRenderer import org.jetbrains.kotlin.diagnostics.rendering.Renderer -import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.declarations.utils.* -import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.calleeReference +import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression +import org.jetbrains.kotlin.fir.references.FirNamedReference +import org.jetbrains.kotlin.fir.references.FirSuperReference +import org.jetbrains.kotlin.fir.references.FirThisReference import org.jetbrains.kotlin.fir.renderer.* import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals @@ -65,12 +69,17 @@ object FirDiagnosticRenderers { } } - val VARIABLE_NAME = Renderer { symbol: FirVariableSymbol<*> -> - symbol.name.asString() + val CALLEE_NAME = Renderer { element: FirExpression -> + when (val reference = element.unwrapSmartcastExpression().calleeReference) { + is FirNamedReference -> reference.name.asString() + is FirThisReference -> "this" + is FirSuperReference -> "super" + else -> "???" + } } - val FIR = Renderer { element: FirElement -> - element.render() + val VARIABLE_NAME = Renderer { symbol: FirVariableSymbol<*> -> + symbol.name.asString() } val DECLARATION_NAME = Renderer { symbol: FirBasedSymbol<*> -> diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index ee016ce3c3b..ea013c73882 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -20,8 +20,8 @@ import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.STRING import org.jetbrains.kotlin.diagnostics.rendering.CommonRenderers.commaSeparated import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.CALLEE_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTIONAL_TYPE_KINDS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS_ON_NEWLINE_WITH_INDENT @@ -1254,7 +1254,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { SMARTCAST_IMPOSSIBLE, "Smart cast to ''{0}'' is impossible, because ''{1}'' is a {2}", RENDER_TYPE, - FIR, + CALLEE_NAME, TO_STRING, NOT_RENDERED ) @@ -1367,8 +1367,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { ) map.put( INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE, - "Invalid default value for inline parameter: ''{0}''. Only lambdas, anonymous functions, and callable references are supported", - FIR, + "Invalid default value for inline function parameter. Only lambdas, anonymous functions, and callable references are supported", DECLARATION_NAME ) map.put( @@ -1898,36 +1897,37 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(LEAKED_IN_PLACE_LAMBDA, "Leaked in-place lambda: {0}", SYMBOL) map.put(FirErrors.WRONG_IMPLIES_CONDITION, "Wrong implies condition") map.put(UNREACHABLE_CODE, "Unreachable code", NOT_RENDERED, NOT_RENDERED) - map.put(SENSELESS_COMPARISON, "Condition ''{0}'' is always ''{1}''", FIR, TO_STRING) + map.put(SENSELESS_COMPARISON, "Condition is always ''{0}''", TO_STRING) map.put(SENSELESS_NULL_IN_WHEN, "Expression under 'when' is never equal to null") // Nullability map.put(USELESS_CALL_ON_NOT_NULL, "Unsafe call on not null") map.put( UNSAFE_CALL, - "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type {0}", + "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type ''{0}''.", RENDER_TYPE, - NOT_RENDERED, + NOT_RENDERED ) map.put( UNSAFE_IMPLICIT_INVOKE_CALL, - "Reference has a nullable type ''{0}'', use explicit \"?.invoke\" to make a function-like call instead.", + "Reference has a nullable type ''{0}'', use explicit ''?.invoke'' to make a function-like call instead.", RENDER_TYPE ) map.put( UNSAFE_INFIX_CALL, - "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. " + - "Use ''?.''-qualified call instead", - FIR, - TO_STRING, - FIR, + "Infix call is not allowed on a nullable receiver of type ''{0}''. Use ''?.''-qualified call instead.", + RENDER_TYPE, + NOT_RENDERED, + NOT_RENDERED, + NOT_RENDERED, ) map.put( UNSAFE_OPERATOR_CALL, - "Operator call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. ", - FIR, - TO_STRING, - FIR, + "Operator call is not allowed on a nullable receiver of type ''{0}''. Use ''?.''-qualified call instead.", + RENDER_TYPE, + NOT_RENDERED, + NOT_RENDERED, + NOT_RENDERED, ) map.put(UNNECESSARY_NOT_NULL_ASSERTION, "Unnecessary non-null assertion (!!) on a non-null receiver of type {0}", RENDER_TYPE) map.put(NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION, "Non-null assertion (!!) is called on a lambda expression") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 740c1fc4edd..e0ce80ff682 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -200,6 +200,7 @@ private fun mapUnsafeCallError( return if (operationSource?.getChild(KtTokens.IDENTIFIER) != null) { FirErrors.UNSAFE_INFIX_CALL.createOn( source, + rootCause.actualType, receiverExpression, candidateFunctionName!!.asString(), singleArgument, @@ -207,6 +208,7 @@ private fun mapUnsafeCallError( } else { FirErrors.UNSAFE_OPERATOR_CALL.createOn( source, + rootCause.actualType, receiverExpression, candidateFunctionName!!.asString(), singleArgument, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirReferenceUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirReferenceUtils.kt index 85909039621..e4fc5de7638 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirReferenceUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/references/FirReferenceUtils.kt @@ -70,3 +70,10 @@ fun FirReference.isError(): Boolean { else -> false } } + +fun FirReference.toNameString(): String? = when (this) { + is FirNamedReference -> name.asString() + is FirThisReference -> "this" + is FirSuperReference -> "super" + else -> null +} diff --git a/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.diag.txt b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.diag.txt new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.diag.txt @@ -0,0 +1 @@ + diff --git a/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.diag.txt b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.diag.txt new file mode 100644 index 00000000000..b7cbd33d46c --- /dev/null +++ b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.diag.txt @@ -0,0 +1 @@ +/complexExpression.fir.kt:(75,121): warning: Condition is always 'false' diff --git a/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.kt b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.kt new file mode 100644 index 00000000000..c19564df34d --- /dev/null +++ b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.fir.kt @@ -0,0 +1,7 @@ +// RENDER_DIAGNOSTICS_FULL_TEXT + +fun String?.repro(): Boolean { + return this?.let { + return false + } == true +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt new file mode 100644 index 00000000000..3cc0ae92d2b --- /dev/null +++ b/compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt @@ -0,0 +1,7 @@ +// RENDER_DIAGNOSTICS_FULL_TEXT + +fun String?.repro(): Boolean { + return this?.let { + return false + } == true +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/smartCastOnAlienPropertyFromInvisibleClass.fir.diag.txt b/compiler/testData/diagnostics/tests/smartCasts/smartCastOnAlienPropertyFromInvisibleClass.fir.diag.txt index b565c5a09dc..c80547a840a 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/smartCastOnAlienPropertyFromInvisibleClass.fir.diag.txt +++ b/compiler/testData/diagnostics/tests/smartCasts/smartCastOnAlienPropertyFromInvisibleClass.fir.diag.txt @@ -1,3 +1,3 @@ -/B.kt:(133,134): error: Smart cast to 'kotlin/String' is impossible, because 'this@R|/Derived|.R|/Base.x|' is a public API property declared in different module +/B.kt:(133,134): error: Smart cast to 'kotlin/String' is impossible, because 'x' is a public API property declared in different module -/B.kt:(265,268): error: Smart cast to 'kotlin/String' is impossible, because 'R|/i|.R|/Base.x|' is a public API property declared in different module +/B.kt:(265,268): error: Smart cast to 'kotlin/String' is impossible, because 'x' is a public API property declared in different module diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 7fbcfef9576..b9381811bcd 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -30670,6 +30670,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/senselessComparison"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), true); } + @Test + @TestMetadata("complexExpression.kt") + public void testComplexExpression() throws Exception { + runTest("compiler/testData/diagnostics/tests/senselessComparison/complexExpression.kt"); + } + @Test @TestMetadata("noExplicitType.kt") public void testNoExplicitType() throws Exception {