Move checkTypePosition to VarianceChecker in frontend
This is a partial revert of 279ff0b, which is no longer needed because
of the previous commit
This commit is contained in:
@@ -25,14 +25,18 @@ import org.jetbrains.kotlin.psi.KtTypeReference
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
|
interface TypeBinding<out P : PsiElement> {
|
||||||
interface TypeBinding<out P : PsiElement> : TypeHolder<TypeBinding<P>> {
|
|
||||||
val psiElement: P
|
val psiElement: P
|
||||||
|
val type: KotlinType
|
||||||
val isInAbbreviation: Boolean
|
val isInAbbreviation: Boolean
|
||||||
override val arguments: List<TypeArgumentBinding<P>?>
|
val arguments: List<TypeArgumentBinding<P>?>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TypeArgumentBinding<out P : PsiElement> : TypeHolderArgument<TypeBinding<P>>
|
interface TypeArgumentBinding<out P : PsiElement> {
|
||||||
|
val projection: TypeProjection
|
||||||
|
val typeParameter: TypeParameterDescriptor?
|
||||||
|
val binding: TypeBinding<P>
|
||||||
|
}
|
||||||
|
|
||||||
fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding<KtTypeElement>? {
|
fun KtTypeReference.createTypeBinding(trace: BindingContext): TypeBinding<KtTypeElement>? {
|
||||||
val type = trace[BindingContext.TYPE, this]
|
val type = trace[BindingContext.TYPE, this]
|
||||||
@@ -64,7 +68,7 @@ fun KtCallableDeclaration.createTypeBindingForReturnType(trace: BindingContext):
|
|||||||
private class TypeArgumentBindingImpl<out P : PsiElement>(
|
private class TypeArgumentBindingImpl<out P : PsiElement>(
|
||||||
override val projection: TypeProjection,
|
override val projection: TypeProjection,
|
||||||
override val typeParameter: TypeParameterDescriptor?,
|
override val typeParameter: TypeParameterDescriptor?,
|
||||||
override val holder: TypeBinding<P>
|
override val binding: TypeBinding<P>
|
||||||
) : TypeArgumentBinding<P>
|
) : TypeArgumentBinding<P>
|
||||||
|
|
||||||
private class ExplicitTypeBinding(
|
private class ExplicitTypeBinding(
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve
|
package org.jetbrains.kotlin.resolve
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PropertyAccessorDescriptorImpl
|
||||||
@@ -34,7 +35,7 @@ import org.jetbrains.kotlin.resolve.typeBinding.createTypeBindingForReturnType
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.Variance.*
|
import org.jetbrains.kotlin.types.Variance.*
|
||||||
import org.jetbrains.kotlin.types.checkTypePosition
|
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
||||||
|
|
||||||
class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance)
|
class ManualVariance(val descriptor: TypeParameterDescriptor, val variance: Variance)
|
||||||
|
|
||||||
@@ -142,17 +143,38 @@ class VarianceCheckerCore(
|
|||||||
|
|
||||||
private fun TypeBinding<PsiElement>.checkTypePosition(position: Variance) = checkTypePosition(type, position)
|
private fun TypeBinding<PsiElement>.checkTypePosition(position: Variance) = checkTypePosition(type, position)
|
||||||
|
|
||||||
private fun TypeBinding<PsiElement>.checkTypePosition(containingType: KotlinType, position: Variance): Boolean =
|
private fun TypeBinding<PsiElement>.checkTypePosition(containingType: KotlinType, position: Variance): Boolean {
|
||||||
checkTypePosition(
|
val classifierDescriptor = type.constructor.declarationDescriptor
|
||||||
position,
|
if (classifierDescriptor is TypeParameterDescriptor) {
|
||||||
{ typeParameterDescriptor, typeBinding, errorPosition ->
|
val declarationVariance = classifierDescriptor.varianceWithManual()
|
||||||
val varianceConflictDiagnosticData = VarianceConflictDiagnosticData(containingType, typeParameterDescriptor, errorPosition)
|
if (!declarationVariance.allowsPosition(position)
|
||||||
|
&& !type.annotations.hasAnnotation(KotlinBuiltIns.FQ_NAMES.unsafeVariance)
|
||||||
|
) {
|
||||||
|
val varianceConflictDiagnosticData = VarianceConflictDiagnosticData(containingType, classifierDescriptor, position)
|
||||||
val diagnostic =
|
val diagnostic =
|
||||||
if (typeBinding.isInAbbreviation) Errors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else Errors.TYPE_VARIANCE_CONFLICT
|
if (isInAbbreviation) Errors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else Errors.TYPE_VARIANCE_CONFLICT
|
||||||
diagnosticSink.report(diagnostic.on(typeBinding.psiElement, varianceConflictDiagnosticData))
|
diagnosticSink.report(diagnostic.on(psiElement, varianceConflictDiagnosticData))
|
||||||
},
|
}
|
||||||
customVariance = { it.varianceWithManual() }
|
return declarationVariance.allowsPosition(position)
|
||||||
)
|
}
|
||||||
|
|
||||||
|
var noError = true
|
||||||
|
for (argument in arguments) {
|
||||||
|
if (argument?.typeParameter == null || argument.projection.isStarProjection) continue
|
||||||
|
|
||||||
|
val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(argument.typeParameter!!, argument.projection)!!
|
||||||
|
val newPosition = when (projectionKind) {
|
||||||
|
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> position
|
||||||
|
TypeCheckingProcedure.EnrichedProjectionKind.IN -> position.opposite()
|
||||||
|
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT
|
||||||
|
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
|
||||||
|
}
|
||||||
|
if (newPosition != null) {
|
||||||
|
noError = noError and argument.binding.checkTypePosition(containingType, newPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noError
|
||||||
|
}
|
||||||
|
|
||||||
private fun isIrrelevant(descriptor: CallableDescriptor): Boolean {
|
private fun isIrrelevant(descriptor: CallableDescriptor): Boolean {
|
||||||
val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return true
|
val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return true
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ abstract class AbstractTypeBindingTest : KotlinTestWithEnvironment() {
|
|||||||
if (argument.projection.isStarProjection)
|
if (argument.projection.isStarProjection)
|
||||||
printlnWithNoIndent("*")
|
printlnWithNoIndent("*")
|
||||||
else printlnWithNoIndent("${projection}${argument.projection.type.render()}")
|
else printlnWithNoIndent("${projection}${argument.projection.type.render()}")
|
||||||
print(argument.holder)
|
print(argument.binding)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 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.types
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
|
||||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure.EnrichedProjectionKind
|
|
||||||
import org.jetbrains.kotlin.utils.DO_NOTHING_3
|
|
||||||
|
|
||||||
interface TypeHolder<out D : TypeHolder<D>> {
|
|
||||||
val type: KotlinType
|
|
||||||
val arguments: List<TypeHolderArgument<D>?>
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TypeHolderArgument<out D : TypeHolder<D>> {
|
|
||||||
val projection: TypeProjection
|
|
||||||
val typeParameter: TypeParameterDescriptor?
|
|
||||||
val holder: D
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <D : TypeHolder<D>> D.checkTypePosition(
|
|
||||||
position: Variance,
|
|
||||||
reportError: (TypeParameterDescriptor, D, Variance) -> Unit = DO_NOTHING_3,
|
|
||||||
customVariance: (TypeParameterDescriptor) -> Variance? = { null }
|
|
||||||
): Boolean {
|
|
||||||
val classifierDescriptor = type.constructor.declarationDescriptor
|
|
||||||
if (classifierDescriptor is TypeParameterDescriptor) {
|
|
||||||
val declarationVariance = customVariance(classifierDescriptor) ?: classifierDescriptor.variance
|
|
||||||
if (!declarationVariance.allowsPosition(position)
|
|
||||||
&& !type.annotations.hasAnnotation(org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES.unsafeVariance)
|
|
||||||
) {
|
|
||||||
reportError(classifierDescriptor, this, position)
|
|
||||||
}
|
|
||||||
return declarationVariance.allowsPosition(position)
|
|
||||||
}
|
|
||||||
|
|
||||||
var noError = true
|
|
||||||
for (argument in arguments) {
|
|
||||||
if (argument?.typeParameter == null || argument.projection.isStarProjection) continue
|
|
||||||
|
|
||||||
val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(argument.typeParameter!!, argument.projection)!!
|
|
||||||
val newPosition = when (projectionKind) {
|
|
||||||
EnrichedProjectionKind.OUT -> position
|
|
||||||
EnrichedProjectionKind.IN -> position.opposite()
|
|
||||||
EnrichedProjectionKind.INV -> Variance.INVARIANT
|
|
||||||
EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
|
|
||||||
}
|
|
||||||
if (newPosition != null) {
|
|
||||||
noError = noError and argument.holder.checkTypePosition(newPosition, reportError, customVariance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return noError
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user