From 09bc729b0e727431c5bbf50caa0452e9658efa94 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 13 Oct 2021 16:48:22 +0300 Subject: [PATCH] FirDefaultParametersResolver: process imported from objects properly #KT-49083 Fixed --- ...nosisCompilerFirTestdataTestGenerated.java | 6 +++++ .../intellij/defaultParameterFromBase.fir.txt | 22 ++++++++++++++++ .../intellij/defaultParameterFromBase.kt | 11 ++++++++ .../runners/FirDiagnosticTestGenerated.java | 6 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++++ .../resolve/FirDefaultParametersResolver.kt | 26 +++++++++++++------ .../kotlin/fir/resolve/ResolveUtils.kt | 2 +- .../calls/FirArgumentsToParametersMapper.kt | 15 ++++++----- 8 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index 95d021138e8..78be35e86e4 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -5069,6 +5069,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/DailyAggregatedDoubleFactor.kt"); } + @Test + @TestMetadata("defaultParameterFromBase.kt") + public void testDefaultParameterFromBase() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt"); + } + @Test @TestMetadata("EnumWithToString.kt") public void testEnumWithToString() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.fir.txt new file mode 100644 index 00000000000..3b20077de67 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.fir.txt @@ -0,0 +1,22 @@ +FILE: defaultParameterFromBase.kt + public open class Base : R|kotlin/Any| { + public constructor(): R|Base| { + super() + } + + public open fun foo(arg: R|kotlin/Int|, def: R|kotlin/String| = String()): R|kotlin/Unit| { + } + + } + public final object Derived : R|Base| { + private constructor(): R|Derived| { + super() + } + + public final override fun foo(arg: R|kotlin/Int|, def: R|kotlin/String|): R|kotlin/Unit| { + } + + } + public final fun test(): R|kotlin/Unit| { + Q|Derived|.R|/Derived.foo|(Int(42)) + } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt new file mode 100644 index 00000000000..995daff3d4b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt @@ -0,0 +1,11 @@ +import Derived.foo + +open class Base { + open fun foo(arg: Int, def: String = "") {} +} +object Derived : Base() { + override fun foo(arg: Int, def: String) {} +} +fun test() { + foo(42) // No value passed for parameter 'def' +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index fa88bda5e06..2c6906b29bb 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -5069,6 +5069,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/DailyAggregatedDoubleFactor.kt"); } + @Test + @TestMetadata("defaultParameterFromBase.kt") + public void testDefaultParameterFromBase() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt"); + } + @Test @TestMetadata("EnumWithToString.kt") public void testEnumWithToString() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index e93c3971e67..277e1a505ea 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -5069,6 +5069,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/DailyAggregatedDoubleFactor.kt"); } + @Test + @TestMetadata("defaultParameterFromBase.kt") + public void testDefaultParameterFromBase() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/defaultParameterFromBase.kt"); + } + @Test @TestMetadata("EnumWithToString.kt") public void testEnumWithToString() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt index ae297e86879..249ad50ad86 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirDefaultParametersResolver.kt @@ -8,26 +8,36 @@ package org.jetbrains.kotlin.fir.resolve import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirValueParameter -import org.jetbrains.kotlin.fir.scopes.FirScope -import org.jetbrains.kotlin.fir.scopes.FirTypeScope -import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope class FirDefaultParametersResolver : FirSessionComponent { fun declaresDefaultValue( + session: FirSession, + scopeSession: ScopeSession, valueParameter: FirValueParameter, function: FirFunction, originScope: FirScope?, index: Int, ): Boolean { if (valueParameter.defaultValue != null) return true - if (originScope !is FirTypeScope) return false - val symbol = function.symbol as? FirNamedFunctionSymbol ?: return false + if (function !is FirSimpleFunction) return false + val symbol = function.symbol + val typeScope = when (originScope) { + is FirTypeScope -> originScope + // imported from object case + is FirAbstractImportingScope -> { + val containingClass = function.getContainingClass(session) ?: return false + containingClass.scopeForClass(ConeSubstitutor.Empty, session, scopeSession) + } + else -> return false + } var result = false - originScope.processOverriddenFunctions(symbol) { overridden -> + typeScope.processOverriddenFunctions(symbol) { overridden -> if (overridden.fir.valueParameters[index].defaultValue != null) { result = true return@processOverriddenFunctions ProcessorAction.STOP diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 309810503e5..e2e320471cd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -446,7 +446,7 @@ private fun initialTypeOfCandidate(candidate: Candidate, typeRef: FirResolvedTyp return candidate.substitutor.substituteOrSelf(typeRef.type) } -fun FirCallableDeclaration.getContainingClass(session: FirSession): FirRegularClass? = this.containingClassForStaticMemberAttr?.let { lookupTag -> +fun FirCallableDeclaration.getContainingClass(session: FirSession): FirRegularClass? = this.containingClass()?.let { lookupTag -> session.symbolProvider.getSymbolByLookupTag(lookupTag)?.fir as? FirRegularClass } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt index bc203ac3da9..d3a1056053c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/FirArgumentsToParametersMapper.kt @@ -259,12 +259,15 @@ private class FirCallArgumentsProcessor( for ((index, parameter) in parameters.withIndex()) { if (!result.containsKey(parameter)) { - if (bodyResolveComponents.session.defaultParameterResolver.declaresDefaultValue(parameter, function, originScope, index)) { - result[parameter] = ResolvedCallArgument.DefaultArgument - } else if (parameter.isVararg) { - result[parameter] = ResolvedCallArgument.VarargArgument(emptyList()) - } else { - addDiagnostic(NoValueForParameter(parameter, function)) + when { + bodyResolveComponents.session.defaultParameterResolver.declaresDefaultValue( + useSiteSession, bodyResolveComponents.scopeSession, parameter, function, originScope, index + ) -> + result[parameter] = ResolvedCallArgument.DefaultArgument + parameter.isVararg -> + result[parameter] = ResolvedCallArgument.VarargArgument(emptyList()) + else -> + addDiagnostic(NoValueForParameter(parameter, function)) } } }