diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt index ce443aa7c43..1df129da1c6 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/symbols/descriptorBased/base/Kt1DescUtils.kt @@ -231,7 +231,12 @@ private fun KotlinType.hasReferenceOtherThan(allowedTypeParameterDescriptors: Se declarationDescriptor !in allowedTypeParameterDescriptors || declarationDescriptor.upperBounds.any { it.hasReferenceOtherThan(allowedTypeParameterDescriptors) } } - else -> arguments.any { it.type.hasReferenceOtherThan(allowedTypeParameterDescriptors) } + else -> arguments.any { typeProjection -> + // A star projection type (lazily) built by type parameter will be yet another type with a star projection, + // resulting in stack overflow if we keep checking allowed type parameter descriptors + !typeProjection.isStarProjection && + typeProjection.type.hasReferenceOtherThan(allowedTypeParameterDescriptors) + } } } diff --git a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java index 3246ca1a56e..cad7e1c2c2e 100644 --- a/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-fe10/tests-gen/org/jetbrains/kotlin/analysis/api/fe10/test/cases/generated/cases/components/callResolver/Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -700,6 +700,12 @@ public class Fe10IdeNormalAnalysisSourceModuleResolveCallTestGenerated extends A runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt"); } + @Test + @TestMetadata("recursiveTypeParameter.kt") + public void testRecursiveTypeParameter() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt"); + } + @Test @TestMetadata("resolveCallInSuperConstructorParam.kt") public void testResolveCallInSuperConstructorParam() throws Exception { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java index 3c5fae19fb2..b1013ce62a4 100644 --- a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/callResolver/FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -700,6 +700,12 @@ public class FirIdeNormalAnalysisSourceModuleResolveCallTestGenerated extends Ab runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt"); } + @Test + @TestMetadata("recursiveTypeParameter.kt") + public void testRecursiveTypeParameter() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt"); + } + @Test @TestMetadata("resolveCallInSuperConstructorParam.kt") public void testResolveCallInSuperConstructorParam() throws Exception { diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java index 93ceecb6da3..9623569e264 100644 --- a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/callResolver/FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated.java @@ -700,6 +700,12 @@ public class FirStandaloneNormalAnalysisSourceModuleResolveCallTestGenerated ext runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/qualifiedCalleeExpressionOfImplicitInvoke.kt"); } + @Test + @TestMetadata("recursiveTypeParameter.kt") + public void testRecursiveTypeParameter() throws Exception { + runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt"); + } + @Test @TestMetadata("resolveCallInSuperConstructorParam.kt") public void testResolveCallInSuperConstructorParam() throws Exception { diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.descriptors.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.descriptors.txt new file mode 100644 index 00000000000..5391e0e60c1 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.descriptors.txt @@ -0,0 +1,49 @@ +KtSuccessCallInfo: + call = KtSimpleFunctionCall: + isImplicitInvoke = false + partiallyAppliedSymbol = KtPartiallyAppliedSymbol: + dispatchReceiver = KtImplicitReceiverValue: + symbol = KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: RunnerModule + classKind: CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: RunnerModule + origin: SOURCE + superTypes: [ + AbstractModule + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + type = RunnerModule + extensionReceiver = null + signature = KtFunctionLikeSignature: + receiverType = null + returnType = kotlin.Unit + symbol = /AbstractModule.install(: AbstractModule, builder: AbstractModule.Builder<*>!): kotlin.Unit + valueParameters = [ + KtVariableLikeSignature: + name = builder + receiverType = null + returnType = AbstractModule.Builder<*>! + symbol = builder: AbstractModule.Builder<*>! + callableIdIfNonLocal = null + ] + callableIdIfNonLocal = /AbstractModule.install + typeArgumentsMapping = {} + argumentMapping = { + CoroutineModule.builder() -> (KtVariableLikeSignature: + name = builder + receiverType = null + returnType = AbstractModule.Builder<*>! + symbol = builder: AbstractModule.Builder<*>! + callableIdIfNonLocal = null) + } diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt new file mode 100644 index 00000000000..525cf8e2139 --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.kt @@ -0,0 +1,39 @@ +// FILE: RunnerModule.kt + +class RunnerModule : AbstractModule() { + fun configure() { + install(CoroutineModule.builder()) + } +} + +// FILE: Module.java + +public interface Module { + public interface Builder { + Module build(); + } +} + +// FILE: AbstractModule.java + +public abstract class AbstractModule { + public abstract static class Builder> implements Module.Builder { + protected abstract B self(); + public abstract Module build(); + } + + protected void install(Builder builder) {} +} + +// FILE: CoroutineModule.kt + +class CoroutineModule : AbstractModule() { + class Builder : AbstractModule.Builder() { + protected override fun self(): Builder = this + override fun build(): Module = CoroutineModule() + } + + companion object { + fun builder(): Builder = Builder() + } +} diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.txt new file mode 100644 index 00000000000..8eae8b0f56c --- /dev/null +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/recursiveTypeParameter.txt @@ -0,0 +1,49 @@ +KtSuccessCallInfo: + call = KtSimpleFunctionCall: + isImplicitInvoke = false + partiallyAppliedSymbol = KtPartiallyAppliedSymbol: + dispatchReceiver = KtImplicitReceiverValue: + symbol = KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: RunnerModule + classKind: CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: RunnerModule + origin: SOURCE + superTypes: [ + AbstractModule + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + type = RunnerModule + extensionReceiver = null + signature = KtFunctionLikeSignature: + receiverType = null + returnType = kotlin.Unit + symbol = /AbstractModule.install(: AbstractModule, builder: ft, AbstractModule.Builder<*>?>): kotlin.Unit + valueParameters = [ + KtVariableLikeSignature: + name = builder + receiverType = null + returnType = ft, AbstractModule.Builder<*>?> + symbol = builder: ft, AbstractModule.Builder<*>?> + callableIdIfNonLocal = null + ] + callableIdIfNonLocal = /AbstractModule.install + typeArgumentsMapping = {} + argumentMapping = { + CoroutineModule.builder() -> (KtVariableLikeSignature: + name = builder + receiverType = null + returnType = ft, AbstractModule.Builder<*>?> + symbol = builder: ft, AbstractModule.Builder<*>?> + callableIdIfNonLocal = null) + }