All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.fir.analysis.checkers.FirInconsistentTypeParameterHelpers.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2021 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
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
fun checkInconsistentTypeParameters(
firTypeRefClasses: List>,
context: CheckerContext,
reporter: DiagnosticReporter,
source: KtSourceElement?,
isValues: Boolean
) {
val result = buildDeepSubstitutionMultimap(firTypeRefClasses, context)
for ((typeParameterSymbol, typeAndProjections) in result) {
val projections = typeAndProjections.projections
if (projections.size > 1) {
if (isValues) {
reporter.reportOn(
source,
FirErrors.INCONSISTENT_TYPE_PARAMETER_VALUES,
typeParameterSymbol,
typeAndProjections.classSymbol,
projections,
context
)
} else {
reporter.reportOn(
source,
FirErrors.INCONSISTENT_TYPE_PARAMETER_BOUNDS,
typeParameterSymbol,
typeAndProjections.classSymbol,
projections,
context
)
}
}
}
}
private fun buildDeepSubstitutionMultimap(
firTypeRefClasses: List>,
context: CheckerContext,
): Map {
val result = mutableMapOf()
val substitution = mutableMapOf()
val visitedSupertypes = mutableSetOf()
val session = context.session
val typeContext = session.typeContext
fun fillInDeepSubstitutor(typeArguments: Array?, classSymbol: FirRegularClassSymbol, context: CheckerContext) {
if (typeArguments != null) {
val typeParameterSymbols = classSymbol.typeParameterSymbols
val count = minOf(typeArguments.size, typeParameterSymbols.size)
for (index in 0 until count) {
val typeArgument = typeArguments[index]
val substitutedArgument = ConeSubstitutorByMap(substitution, session).substituteArgument(
typeArgument,
classSymbol.toLookupTag(),
index
) ?: typeArgument
val substitutedType = substitutedArgument.type ?: continue
val typeParameterSymbol = typeParameterSymbols[index]
substitution[typeParameterSymbol] = substitutedType
var classSymbolAndProjections = result[typeParameterSymbol]
val projections: MutableList
if (classSymbolAndProjections == null) {
projections = mutableListOf()
classSymbolAndProjections = ClassSymbolAndProjections(classSymbol, projections)
result[typeParameterSymbol] = classSymbolAndProjections
} else {
projections = classSymbolAndProjections.projections
}
if (projections.all {
it != substitutedType && !AbstractTypeChecker.equalTypes(typeContext, it, substitutedType)
}) {
projections.add(substitutedType)
}
}
}
for (superTypeRef in classSymbol.resolvedSuperTypeRefs) {
val fullyExpandedType = superTypeRef.coneType.fullyExpandedType(session)
if (!visitedSupertypes.add(fullyExpandedType))
return
val superClassSymbol = fullyExpandedType.toRegularClassSymbol(session)
withSuppressedDiagnostics(superTypeRef, context) {
if (!fullyExpandedType.isEnum && superClassSymbol != null) {
fillInDeepSubstitutor(fullyExpandedType.typeArguments, superClassSymbol, it)
}
}
}
}
for (firTypeRefClass in firTypeRefClasses) {
fillInDeepSubstitutor(firTypeRefClass.first?.coneType?.fullyExpandedType(session)?.typeArguments, firTypeRefClass.second, context)
}
return result
}
private data class ClassSymbolAndProjections(
val classSymbol: FirRegularClassSymbol,
val projections: MutableList
)