From e49bb1fe37950a540e312bb6be020e46af8dcc38 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Thu, 1 Dec 2022 15:08:34 +0100 Subject: [PATCH] [FIR] Support of REDECLARATION for local val/var, ^KT-54405 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ .../diagnostics/upperBoundViolated.fir.txt | 8 ++-- .../resolve/diagnostics/upperBoundViolated.kt | 8 ++-- .../negative/missingBooleanBranch.fir.txt | 2 +- .../negative/missingBooleanBranch.kt | 2 +- .../positive/exhaustiveness_enum.fir.txt | 4 +- .../positive/exhaustiveness_enum.kt | 4 +- .../positive/exhaustiveness_enumJava.fir.txt | 4 +- .../positive/exhaustiveness_enumJava.kt | 4 +- .../RedundantExplicitTypeChecker.fir.txt | 2 +- .../RedundantExplicitTypeChecker.kt | 2 +- ...eeOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 +++ .../checkers/CommonDeclarationCheckers.kt | 2 +- .../checkers/CommonExpressionCheckers.kt | 3 +- ...ionInspector.kt => FirConflictsHelpers.kt} | 45 +++++++++++++++++++ ...r.kt => FirConflictsDeclarationChecker.kt} | 45 +------------------ .../FirConflictsExpressionChecker.kt | 17 +++++++ .../diagnostics/tests/Underscore.fir.kt | 4 +- .../RedeclarationsInMultiDecl.fir.kt | 8 ++-- .../RedeclarationInForLoop.fir.kt | 2 +- .../underscore.fir.kt | 4 +- .../redeclaration.fir.kt | 4 +- .../destructuringInLambdas/underscore.fir.kt | 2 +- .../RedeclaredValsAndVars.fir.kt | 28 ++++++++++++ .../redeclarations/RedeclaredValsAndVars.kt | 28 ++++++++++++ .../redeclarations/RedeclaredValsAndVars.txt | 14 ++++++ .../tryCatch/catchRedeclaration.fir.kt | 4 +- .../test/runners/DiagnosticTestGenerated.java | 6 +++ .../type-parameters/neg/1.fir.kt | 12 ++--- 30 files changed, 201 insertions(+), 85 deletions(-) rename compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/{FirDeclarationInspector.kt => FirConflictsHelpers.kt} (84%) rename compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/{FirConflictsChecker.kt => FirConflictsDeclarationChecker.kt} (90%) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConflictsExpressionChecker.kt create mode 100644 compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.fir.kt create mode 100644 compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt create mode 100644 compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 8e619512253..163879e1f61 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -25770,6 +25770,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt"); } + @Test + @TestMetadata("RedeclaredValsAndVars.kt") + public void testRedeclaredValsAndVars() throws Exception { + runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt"); + } + @Test @TestMetadata("RedeclaredValueParameters.kt") public void testRedeclaredValueParameters() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.fir.txt index 21f0323d394..75779a1d912 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.fir.txt @@ -59,10 +59,10 @@ FILE: upperBoundViolated.kt lval o3: R|S| = R|/S.S|() lval o4: R|S, T>| = R|/S.S||, R|T|>() lval o5: R|S, T>| = R|/S.S#||, R|T|>() - lval o5: R|S, T>| = R|/S.S#||, R|T|>() - lval o6: R|S, kotlin/String>>| = R|/S.S|, kotlin/String>|>() - lval o7: R|S, kotlin/Nothing>>| = R|/S.S|, kotlin/Nothing>|>() - lval o8: R|P>| = R|/P.P#||>() + lval o6: R|S, T>| = R|/S.S#||, R|T|>() + lval o7: R|S, kotlin/String>>| = R|/S.S|, kotlin/String>|>() + lval o8: R|S, kotlin/Nothing>>| = R|/S.S|, kotlin/Nothing>|>() + lval o9: R|P>| = R|/P.P#||>() } public final class NumColl|> : R|kotlin/Any| { public constructor|>(): R|NumColl| { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt index 035a6e1d562..d6617284535 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/upperBoundViolated.kt @@ -35,11 +35,11 @@ fun rest() { val o4 = S, T>() val o5 = S, T>() - val o5 = S, T>() + val o6 = S, T>() - val o6 = S, String>>() - val o7 = S, Nothing>>() - val o8 = P<String, P1<String, String>>() + val o7 = S, String>>() + val o8 = S, Nothing>>() + val o9 = P<String, P1<String, String>>() } class NumColl> diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt index 8e060626a81..f37e990514e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt @@ -32,7 +32,7 @@ FILE: missingBooleanBranch.kt } } - lval x: R|kotlin/Int| = when (R|/cond|) { + lval y: R|kotlin/Int| = when (R|/cond|) { ==($subj$, Boolean(true)) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt index 5b51bd9b806..05ae691120b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt @@ -19,7 +19,7 @@ fun test_2(cond: Boolean?) { false -> 2 } - val x = when (cond) { + val y = when (cond) { true -> 1 false -> 2 null -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt index ecc389bf0e5..f58fb4915bf 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt @@ -74,7 +74,7 @@ FILE: exhaustiveness_enum.kt } } - lval a: R|kotlin/Int| = when (R|/e|) { + lval b: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|Enum|.R|/Enum.A|) -> { Int(1) } @@ -89,7 +89,7 @@ FILE: exhaustiveness_enum.kt } } - lval a: R|kotlin/Int| = when (R|/e|) { + lval c: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|Enum|.R|/Enum.A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt index ac2e4c7bbb1..4b322c5a1d9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt @@ -33,14 +33,14 @@ fun test_2(e: Enum?) { Enum.C -> 3 } - val a = when (e) { + val b = when (e) { Enum.A -> 1 Enum.B -> 2 Enum.C -> 3 null -> 4 } - val a = when (e) { + val c = when (e) { Enum.A -> 1 Enum.B -> 2 Enum.C -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt index f3b8d19e300..09164d980b2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt @@ -56,7 +56,7 @@ FILE: main.kt } } .#(Int(0)) - lval a: R|kotlin/Int| = when (R|/e|) { + lval b: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) } @@ -71,7 +71,7 @@ FILE: main.kt } } .R|kotlin/Int.plus|(Int(0)) - lval a: R|kotlin/Int| = when (R|/e|) { + lval c: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt index 07ab6b5a49d..b5044dc32c2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt @@ -37,14 +37,14 @@ fun test_2(e: JavaEnum?) { JavaEnum.C -> 3 }.plus(0) - val a = when (e) { + val b = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 JavaEnum.C -> 3 null -> 4 }.plus(0) - val a = when (e) { + val c = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 JavaEnum.C -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.fir.txt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.fir.txt index 7f042559dd0..6459da556df 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.fir.txt @@ -64,7 +64,7 @@ FILE: RedundantExplicitTypeChecker.kt lval a: R|kotlin/Boolean| = Boolean(true) lval i: R|kotlin/Int| = Int(2).R|kotlin/Int.times|(Int(2)) lval l: R|kotlin/Long| = Long(1234567890123) - lval s: R|kotlin/String?| = Null(null) + lval s1: R|kotlin/String?| = Null(null) lval sh: R|kotlin/Short| = Short(42) lval integer: R|kotlin/Int| = Int(42) lval piFloat: R|kotlin/Float| = Float(3.14) diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.kt index d43dacf66c8..837bd2e5803 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantExplicitTypeChecker.kt @@ -45,7 +45,7 @@ fun foo() { val a: Boolean = true val i: Int = 2 * 2 val l: Long = 1234567890123L - val s: String? = null + val s1: String? = null val sh: Short = 42 val integer: Int = 42 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 2210a777d96..b5786b06afc 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 @@ -25770,6 +25770,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt"); } + @Test + @TestMetadata("RedeclaredValsAndVars.kt") + public void testRedeclaredValsAndVars() throws Exception { + runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt"); + } + @Test @TestMetadata("RedeclaredValueParameters.kt") public void testRedeclaredValueParameters() 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 233b45c39eb..bd329993e9a 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 @@ -25776,6 +25776,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt"); } + @Test + @TestMetadata("RedeclaredValsAndVars.kt") + public void testRedeclaredValsAndVars() throws Exception { + runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt"); + } + @Test @TestMetadata("RedeclaredValueParameters.kt") public void testRedeclaredValueParameters() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 73b746c6242..84a1fefe1ab 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -18,7 +18,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { override val basicDeclarationCheckers: Set get() = setOf( FirModifierChecker, - FirConflictsChecker, + FirConflictsDeclarationChecker, FirProjectionRelationChecker, FirTypeConstraintsChecker, FirReservedUnderscoreDeclarationChecker, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt index 612b96aaaf2..fca51aa1362 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonExpressionCheckers.kt @@ -115,7 +115,8 @@ object CommonExpressionCheckers : ExpressionCheckers() { override val blockCheckers: Set get() = setOf( - FirForLoopChecker + FirForLoopChecker, + FirConflictsExpressionChecker ) override val checkNotNullCallCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirDeclarationInspector.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt similarity index 84% rename from compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirDeclarationInspector.kt rename to compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt index bc55f6bb9ff..5b510cf05d5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirDeclarationInspector.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConflictsHelpers.kt @@ -6,10 +6,17 @@ package org.jetbrains.kotlin.fir.analysis.checkers import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.declarations.utils.isOperator +import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.util.ListMultimap import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -279,3 +286,41 @@ open class FirDeclarationInspector( else -> false } } + +fun checkConflictingElements(elements: List, context: CheckerContext, reporter: DiagnosticReporter) { + if (elements.size <= 1) return + + val multimap = ListMultimap>() + for (element in elements) { + val name: Name? + val symbol: FirBasedSymbol<*>? + when (element) { + is FirVariable -> { + symbol = element.symbol + name = element.name + } + is FirOuterClassTypeParameterRef -> { + continue + } + is FirTypeParameterRef -> { + symbol = element.symbol + name = symbol.name + } + else -> { + symbol = null + name = null + } + } + if (name?.isSpecial == false) { + multimap.put(name, symbol!!) + } + } + for (key in multimap.keys) { + val conflictingElements = multimap[key] + if (conflictingElements.size > 1) { + for (conflictingElement in conflictingElements) { + reporter.reportOn(conflictingElement.source, FirErrors.REDECLARATION, conflictingElements, context) + } + } + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt similarity index 90% rename from compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt rename to compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt index 2434493dd3b..6ea81bbbaa5 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsDeclarationChecker.kt @@ -12,10 +12,10 @@ import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter +import org.jetbrains.kotlin.fir.analysis.checkers.checkConflictingElements import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef import org.jetbrains.kotlin.fir.resolve.getContainingDeclaration import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope @@ -25,13 +25,12 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase -import org.jetbrains.kotlin.fir.util.ListMultimap import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.SmartSet -object FirConflictsChecker : FirBasicDeclarationChecker() { +object FirConflictsDeclarationChecker : FirBasicDeclarationChecker() { private class DeclarationInspector : FirDeclarationInspector() { @@ -272,46 +271,6 @@ object FirConflictsChecker : FirBasicDeclarationChecker() { } } - private fun checkConflictingParameters(parameters: List, context: CheckerContext, reporter: DiagnosticReporter) { - if (parameters.size <= 1) return - - val multimap = ListMultimap>() - for (parameter in parameters) { - val name: Name - val symbol: FirBasedSymbol<*> - when (parameter) { - is FirValueParameter -> { - symbol = parameter.symbol - name = parameter.name - } - is FirOuterClassTypeParameterRef -> { - continue - } - is FirTypeParameterRef -> { - symbol = parameter.symbol - name = symbol.name - } - else -> throw AssertionError("Invalid parameter type") - } - if (!name.isSpecial) { - multimap.put(name, symbol) - } - } - for (key in multimap.keys) { - val conflictingParameters = multimap[key] - if (conflictingParameters.size > 1) { - for (parameter in conflictingParameters) { - reporter.reportOn( - parameter.source, - FirErrors.REDECLARATION, - conflictingParameters, - context - ) - } - } - } - } - private fun checkFile(file: FirFile, inspector: DeclarationInspector, context: CheckerContext) { val packageMemberScope: FirPackageMemberScope = context.sessionHolder.scopeSession.getOrBuild(file.packageFqName, PACKAGE_MEMBER) { FirPackageMemberScope(file.packageFqName, context.sessionHolder.session) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConflictsExpressionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConflictsExpressionChecker.kt new file mode 100644 index 00000000000..29731bc08da --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirConflictsExpressionChecker.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2010-2022 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.expression + +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.checkers.checkConflictingElements +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.expressions.FirBlock + +object FirConflictsExpressionChecker : FirBlockChecker() { + override fun check(expression: FirBlock, context: CheckerContext, reporter: DiagnosticReporter) { + checkConflictingElements(expression.statements, context, reporter) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/Underscore.fir.kt b/compiler/testData/diagnostics/tests/Underscore.fir.kt index 1e961ffffc7..0bb33044ab6 100644 --- a/compiler/testData/diagnostics/tests/Underscore.fir.kt +++ b/compiler/testData/diagnostics/tests/Underscore.fir.kt @@ -12,12 +12,12 @@ fun __(___: Int, y: __________) = Pair(___ - 1, 42) val ____ = x // in backquotes: allowed - val `_` = __________ + val `_` = __________ val q = fun(_: Int, __: Int) {} q(1, 2) - val _ = 56 + val _ = 56 fun localFun(_: String) = 1 diff --git a/compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.fir.kt index 0c7b4aad47f..e7216a1256b 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.fir.kt @@ -4,11 +4,11 @@ class A { } fun a() { - val (a, a) = A() - val (x, y) = A(); - val b = 1 + val (a, a) = A() + val (x, y) = A(); + val b = 1 use(b) - val (b, y) = A(); + val (b, y) = A(); } diff --git a/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/RedeclarationInForLoop.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/RedeclarationInForLoop.fir.kt index 36f980565b4..eae50990799 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/RedeclarationInForLoop.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/RedeclarationInForLoop.fir.kt @@ -8,7 +8,7 @@ class C { } fun test() { - for ((x, x) in C()) { + for ((x, x) in C()) { } } diff --git a/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/underscore.fir.kt b/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/underscore.fir.kt index aa74bdbeacb..6b5913dce8e 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/underscore.fir.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/destructuringDeclarations/underscore.fir.kt @@ -36,11 +36,11 @@ fun test() { foo(x, _) foo(_, y) - val (`_`, z) = A() + val (`_`, z) = A() foo(_, z) - val (_, `_`) = A() + val (_, `_`) = A() foo(_, y) diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt index b4fb40537f5..1bfee1c3e1e 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/redeclaration.fir.kt @@ -6,7 +6,7 @@ data class B(val u: Double, val w: Short) fun foo(block: (A, B) -> Unit) { } fun bar() { - foo { (a, a), b -> + foo { (a, a), b -> a checkType { _() } b checkType { _() } } @@ -21,7 +21,7 @@ fun bar() { b checkType { _() } } - foo { (a, b), (c, b) -> + foo { (a, b), (c, b) -> a checkType { _() } b checkType { _() } c checkType { _() } diff --git a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/underscore.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/underscore.fir.kt index 9f9803681ff..2bdabaf1117 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/underscore.fir.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/destructuringInLambdas/underscore.fir.kt @@ -46,7 +46,7 @@ fun bar() { _ checkType { _() } } - foo { (`_`, `_`) -> + foo { (`_`, `_`) -> _ checkType { _() } } diff --git a/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.fir.kt b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.fir.kt new file mode 100644 index 00000000000..f540ac86c44 --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.fir.kt @@ -0,0 +1,28 @@ +// ISSUE: KT-54405 + +class A { + operator fun component1() = 1 + operator fun component2() = "" +} + +fun test(b: Boolean) { + val y = 1 + val y = 2 + val `_` = 3 + val `_` = 4 + { + var a = 10 + var a = 11 + } + if (b) { + val z = 3 + val x = 5 + val x = 6 + } else { + val z = 4 + } +} + +fun test2() { + val (`_`, _) = A() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt new file mode 100644 index 00000000000..8e378e51dec --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt @@ -0,0 +1,28 @@ +// ISSUE: KT-54405 + +class A { + operator fun component1() = 1 + operator fun component2() = "" +} + +fun test(b: Boolean) { + val y = 1 + val y = 2 + val `_` = 3 + val `_` = 4 + { + var a = 10 + var a = 11 + } + if (b) { + val z = 3 + val x = 5 + val x = 6 + } else { + val z = 4 + } +} + +fun test2() { + val (`_`, _) = A() +} diff --git a/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.txt b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.txt new file mode 100644 index 00000000000..fa0ba0e8247 --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.txt @@ -0,0 +1,14 @@ +package + +public fun test(/*0*/ b: kotlin.Boolean): kotlin.Unit +public fun test2(): kotlin.Unit + +public final class A { + public constructor A() + public final operator fun component1(): kotlin.Int + public final operator fun component2(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + diff --git a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/catchRedeclaration.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/catchRedeclaration.fir.kt index 71268d77c13..3d08da759b4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/tryCatch/catchRedeclaration.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/tryCatch/catchRedeclaration.fir.kt @@ -35,8 +35,8 @@ fun test3() { fun test4() { try {} catch (e: Exception) { - val a = 42 - val a = "foo" + val a = 42 + val a = "foo" } } 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 6e3602b8ec8..83c82df4507 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 @@ -25776,6 +25776,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt"); } + @Test + @TestMetadata("RedeclaredValsAndVars.kt") + public void testRedeclaredValsAndVars() throws Exception { + runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValsAndVars.kt"); + } + @Test @TestMetadata("RedeclaredValueParameters.kt") public void testRedeclaredValueParameters() throws Exception { diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/local-variables/type-parameters/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/local-variables/type-parameters/neg/1.fir.kt index 774cbe9c43f..0ad2929d951 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/local-variables/type-parameters/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/local-variables/type-parameters/neg/1.fir.kt @@ -71,20 +71,20 @@ fun case_10(x: Boolean?) = when (val < // TESTCASE NUMBER: 11 fun case_11() { - val x by lazy { 1 } - var x by lazy { 1 } + val x by lazy { 1 } + var x by lazy { 1 } } // TESTCASE NUMBER: 12 fun case_12() { - val __UNRESOLVED__> x: Int - var __UNRESOLVED__> x: Int + val __UNRESOLVED__> x: Int + var __UNRESOLVED__> x: Int } // TESTCASE NUMBER: 13 fun case_13() { - val __UNRESOLVED__> x: Int where __UNRESOLVED__: __UNRESOLVED__ - var __UNRESOLVED__> x: Int where __UNRESOLVED__: __UNRESOLVED__ + val __UNRESOLVED__> x: Int where __UNRESOLVED__: __UNRESOLVED__ + var __UNRESOLVED__> x: Int where __UNRESOLVED__: __UNRESOLVED__ } // TESTCASE NUMBER: 14