Make getNestedTypeVariables() an utility
This commit is contained in:
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||
|
||||
+3
-1
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeParameters
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.INCOMPLETE_TYPE_INFERENCE
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.OTHER_ERROR
|
||||
@@ -165,7 +167,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
val candidateWithFreshVariables = FunctionDescriptorUtil.alphaConvertTypeParameters(candidateDescriptor)
|
||||
val conversion = candidateDescriptor.typeParameters.zip(candidateWithFreshVariables.typeParameters).toMap()
|
||||
|
||||
val freshVariables = nestedTypeVariables.map { conversion[argumentConstraintSystem.variableToDescriptor(it)] }.filterNotNull()
|
||||
val freshVariables = returnType.getNestedTypeParameters().map { conversion[it] }.filterNotNull()
|
||||
builder.registerTypeVariables(freshVariables, external = true)
|
||||
|
||||
builder.addSubtypeConstraint(candidateWithFreshVariables.returnType, effectiveExpectedType, constraintPosition)
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
@@ -63,8 +61,6 @@ interface ConstraintSystem {
|
||||
*/
|
||||
val currentSubstitutor: TypeSubstitutor
|
||||
|
||||
fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor>
|
||||
|
||||
fun toBuilder(filterConstraintPosition: (ConstraintPosition) -> Boolean = { true }): Builder
|
||||
|
||||
interface Builder {
|
||||
@@ -101,7 +97,3 @@ interface ConstraintSystem {
|
||||
fun build(): ConstraintSystem
|
||||
}
|
||||
}
|
||||
|
||||
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
||||
return toBuilder { !it.derivedFrom(excludePositionKind) }.build()
|
||||
}
|
||||
|
||||
+4
-8
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
||||
import java.util.*
|
||||
|
||||
@@ -99,11 +98,8 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && isMyTypeVariable(it) }
|
||||
}
|
||||
|
||||
internal fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { if (original) it in descriptorToVariable.keys else isMyTypeVariable(it) }
|
||||
}
|
||||
internal fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor> =
|
||||
type.getNestedTypeParameters().filter { isMyTypeVariable(it) }
|
||||
|
||||
override fun addSupertypeConstraint(constrainingType: KotlinType?, subjectType: KotlinType, constraintPosition: ConstraintPosition) {
|
||||
if (constrainingType != null && TypeUtils.noExpectedType(constrainingType)) return
|
||||
@@ -257,7 +253,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
typeBounds.addBound(bound)
|
||||
|
||||
if (!bound.isProper) {
|
||||
for (dependentTypeVariable in getNestedTypeVariables(bound.constrainingType, original = false)) {
|
||||
for (dependentTypeVariable in getNestedTypeVariables(bound.constrainingType)) {
|
||||
val dependentBounds = usedInBounds.getOrPut(dependentTypeVariable) { arrayListOf() }
|
||||
dependentBounds.add(bound)
|
||||
}
|
||||
@@ -359,7 +355,7 @@ class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
if (typeBounds.isFixed) return
|
||||
typeBounds.setFixed()
|
||||
|
||||
val nestedTypeVariables = typeBounds.bounds.flatMap { getNestedTypeVariables(it.constrainingType, original = false) }
|
||||
val nestedTypeVariables = typeBounds.bounds.flatMap { getNestedTypeVariables(it.constrainingType) }
|
||||
nestedTypeVariables.forEach { fixVariable(it) }
|
||||
|
||||
val value = typeBounds.value ?: return
|
||||
|
||||
-8
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isInternalAnnotationForResolv
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import java.util.*
|
||||
|
||||
@@ -110,13 +109,6 @@ internal class ConstraintSystemImpl(
|
||||
return SubstitutionFilteringInternalResolveAnnotations(substitution).buildSubstitutor()
|
||||
}
|
||||
|
||||
override fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
val descriptor = typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
descriptor?.let { descriptorToVariable[it] }
|
||||
}.filterNotNull()
|
||||
}
|
||||
|
||||
override val typeParameterDescriptors: Set<TypeParameterDescriptor>
|
||||
get() = descriptorToVariable.keys
|
||||
|
||||
|
||||
+2
-4
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
||||
import org.jetbrains.kotlin.types.typeUtil.getNestedArguments
|
||||
import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes
|
||||
import java.util.*
|
||||
|
||||
@@ -59,7 +58,7 @@ fun ConstraintSystemBuilderImpl.incorporateBound(newBound: Bound) {
|
||||
return
|
||||
}
|
||||
|
||||
getNestedTypeVariables(constrainingType, original = true).forEach {
|
||||
getNestedTypeVariables(constrainingType).forEach {
|
||||
val boundsForNestedVariable = getTypeBounds(it).bounds
|
||||
for (index in boundsForNestedVariable.indices) {
|
||||
generateNewBound(newBound, boundsForNestedVariable[index])
|
||||
@@ -100,8 +99,7 @@ private fun ConstraintSystemBuilderImpl.generateNewBound(bound: Bound, substitut
|
||||
|
||||
fun addNewBound(newConstrainingType: KotlinType, newBoundKind: BoundKind) {
|
||||
// We don't generate new recursive constraints
|
||||
val nestedTypeVariables = getNestedTypeVariables(newConstrainingType, original = false)
|
||||
if (nestedTypeVariables.contains(bound.typeVariable)) return
|
||||
if (bound.typeVariable in getNestedTypeVariables(newConstrainingType)) return
|
||||
|
||||
// We don't generate constraint if a type variable was substituted twice
|
||||
val derivedFrom = HashSet(bound.derivedFrom + substitution.derivedFrom)
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.derivedFrom
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjection
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import java.util.*
|
||||
|
||||
fun ConstraintSystem.getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor> =
|
||||
type.getNestedTypeParameters().filter { it in typeParameterDescriptors }.map { descriptorToVariable(it) }
|
||||
|
||||
fun ConstraintSystem.filterConstraintsOut(excludePositionKind: ConstraintPositionKind): ConstraintSystem {
|
||||
return toBuilder { !it.derivedFrom(excludePositionKind) }.build()
|
||||
}
|
||||
|
||||
internal fun KotlinType.getNestedArguments(): List<TypeProjection> {
|
||||
val result = ArrayList<TypeProjection>()
|
||||
|
||||
val stack = ArrayDeque<TypeProjection>()
|
||||
stack.push(TypeProjectionImpl(this))
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
val typeProjection = stack.pop()
|
||||
if (typeProjection.isStarProjection) continue
|
||||
|
||||
result.add(typeProjection)
|
||||
|
||||
typeProjection.type.arguments.forEach { stack.add(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
internal fun KotlinType.getNestedTypeParameters(): List<TypeParameterDescriptor> {
|
||||
return getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull()
|
||||
}
|
||||
+1
-1
@@ -46,7 +46,7 @@ import java.util.Collection;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqNameFromTopLevelClass;
|
||||
import static org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemKt.filterConstraintsOut;
|
||||
import static org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemUtilsKt.filterConstraintsOut;
|
||||
import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.EXPECTED_TYPE_POSITION;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
|
||||
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class A<T> {
|
||||
fun <S> foo(s: S): S = s
|
||||
fun <U> bar(<!UNUSED_PARAMETER!>s<!>: U): List<T> = null!!
|
||||
|
||||
fun test() = foo(bar(""))
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public final class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>()
|
||||
public final fun </*0*/ U> bar(/*0*/ s: U): kotlin.List<T>
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun </*0*/ S> foo(/*0*/ s: S): S
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final fun test(): kotlin.List<T>
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -7955,6 +7955,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("externalTypeParameter.kt")
|
||||
public void testExternalTypeParameter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/nestedCalls/externalTypeParameter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inferenceForNestedBinaryCall.kt")
|
||||
public void testInferenceForNestedBinaryCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/nestedCalls/inferenceForNestedBinaryCall.kt");
|
||||
|
||||
@@ -115,23 +115,6 @@ public fun KotlinTypeChecker.equalTypesOrNulls(type1: KotlinType?, type2: Kotlin
|
||||
return equalTypes(type1, type2)
|
||||
}
|
||||
|
||||
fun KotlinType.getNestedArguments(): List<TypeProjection> {
|
||||
val result = ArrayList<TypeProjection>()
|
||||
|
||||
val stack = ArrayDeque<TypeProjection>()
|
||||
stack.push(TypeProjectionImpl(this))
|
||||
|
||||
while (!stack.isEmpty()) {
|
||||
val typeProjection = stack.pop()
|
||||
if (typeProjection.isStarProjection()) continue
|
||||
|
||||
result.add(typeProjection)
|
||||
|
||||
typeProjection.getType().getArguments().forEach { stack.add(it) }
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun KotlinType.containsError() = ErrorUtils.containsErrorType(this)
|
||||
|
||||
public fun List<KotlinType>.defaultProjections(): List<TypeProjection> = map { TypeProjectionImpl(it) }
|
||||
|
||||
Reference in New Issue
Block a user