[FIR] Various checkers performance fixes

This commit is contained in:
Nick
2020-08-25 17:34:06 +03:00
parent 5c88eb722d
commit bb18203ae6
16 changed files with 300 additions and 165 deletions
@@ -0,0 +1,10 @@
open class A
open class B : A()
open class First<T> {
open fun test(item: T) {}
}
open class Second : First<A>() {
override fun test(item: A) {}
}
@@ -0,0 +1,31 @@
FILE: someOverridesTest.kt
public open class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
}
public open class B : R|A| {
public constructor(): R|B| {
super<R|A|>()
}
}
public open class First<T> : R|kotlin/Any| {
public constructor<T>(): R|First<T>| {
super<R|kotlin/Any|>()
}
public open fun test(item: R|T|): R|kotlin/Unit| {
}
}
public open class Second : R|First<A>| {
public constructor(): R|Second| {
super<R|First<A>|>()
}
public open override fun test(item: R|A|): R|kotlin/Unit| {
}
}
@@ -1056,6 +1056,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt");
}
@TestMetadata("someOverridesTest.kt")
public void testSomeOverridesTest() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/someOverridesTest.kt");
}
@TestMetadata("superIsNotAnExpression.kt")
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
@@ -1056,6 +1056,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt");
}
@TestMetadata("someOverridesTest.kt")
public void testSomeOverridesTest() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/someOverridesTest.kt");
}
@TestMetadata("superIsNotAnExpression.kt")
public void testSuperIsNotAnExpression() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/superIsNotAnExpression.kt");
@@ -9,9 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -19,78 +17,172 @@ import org.jetbrains.kotlin.name.Name
* Provides representations for FirElement's.
*/
interface FirDeclarationPresenter {
open class RepresentationBuilder {
var receiver = ""
var name = ""
open fun build() = "[$receiver] $name"
fun StringBuilder.appendRepresentation(it: FirElement) {
append("NO_REPRESENTATION")
}
fun buildRepresentation(init: RepresentationBuilder.() -> Unit): String {
return RepresentationBuilder().apply(init).build()
fun StringBuilder.appendRepresentation(it: ClassId) {
append(it.packageFqName.asString())
append('/')
append(it.relativeClassName.asString())
}
class FunctionRepresentationBuilder : RepresentationBuilder() {
var representsOperator = false
var typeArguments = ""
var parameters = ""
override fun build() = "<$typeArguments> [$receiver] ${if (representsOperator) "operator " else ""}$name ($parameters)"
}
fun buildFunctionRepresentation(init: FunctionRepresentationBuilder.() -> Unit): String {
return FunctionRepresentationBuilder().apply(init).build()
}
fun represent(it: FirElement) = "NO_REPRESENTATION"
fun represent(it: ClassId) = it.packageFqName.asString() + '/' + it.relativeClassName.asString()
fun represent(it: CallableId) = if (it.className != null) {
it.packageName.asString() + '/' + it.className + '.' + it.callableName
} else {
it.packageName.asString() + '/' + it.callableName
}
fun represent(it: FirTypeRef) = when (it) {
is FirResolvedTypeRef -> it.type.toString()
is FirErrorTypeRef -> "ERROR"
else -> "?"
}
fun represent(it: FirTypeParameter) = it.name.asString() + " : " + it.bounds
.map { represent(it) }
.sorted()
.joinToString()
fun represent(it: FirValueParameter): String {
val prefix = if (it.isVararg) "vararg " else ""
return prefix + " " + represent(it.returnTypeRef)
}
fun represent(it: FirProperty) = buildRepresentation {
it.receiverTypeRef?.let {
receiver = represent(it)
fun StringBuilder.appendRepresentation(it: CallableId) {
if (it.className != null) {
append(it.packageName.asString())
append('/')
append(it.className)
append('.')
append(it.callableName)
} else {
append(it.packageName.asString())
append('/')
append(it.callableName)
}
name = represent(it.symbol.callableId)
}
fun represent(it: FirSimpleFunction) = buildFunctionRepresentation {
typeArguments = it.typeParameters.joinToString { represent(it) }
it.receiverTypeRef?.let {
receiver = represent(it)
fun StringBuilder.appendRepresentation(it: ConeTypeProjection) {
when (it) {
ConeStarProjection -> {
append('*')
}
is ConeKotlinTypeProjectionIn -> {
append("in ")
appendRepresentation(it.type)
}
is ConeKotlinTypeProjectionOut -> {
append("out ")
appendRepresentation(it.type)
}
is ConeKotlinType -> {
appendRepresentation(it)
}
}
representsOperator = it.isOperator
name = represent(it.symbol.callableId)
parameters = it.valueParameters.joinToString { represent(it) }
}
fun represent(it: FirTypeAlias) = buildRepresentation {
name = represent(it.symbol.classId)
fun StringBuilder.appendRepresentation(it: ConeKotlinType) {
when (it) {
is ConeDefinitelyNotNullType -> {
appendRepresentation(it.original)
append(it.nullability.suffix)
}
is ConeClassErrorType -> {
append("ERROR(")
append(it.diagnostic.reason)
append(')')
}
is ConeCapturedType -> {
append(it.constructor.projection)
append(it.nullability.suffix)
}
is ConeClassLikeType -> {
appendRepresentation(it.lookupTag.classId)
if (it.typeArguments.isNotEmpty()) {
append('<')
it.typeArguments.forEach { that ->
appendRepresentation(that)
append(',')
}
append('>')
}
append(it.nullability.suffix)
}
is ConeLookupTagBasedType -> {
append(it.lookupTag.name)
append(it.nullability.suffix)
}
is ConeIntegerLiteralType -> {
append(it.value)
append(it.nullability.suffix)
}
is ConeFlexibleType,
is ConeIntersectionType,
is ConeStubType -> {
append("ERROR")
}
}
}
fun represent(it: FirRegularClass) = buildRepresentation {
name = represent(it.symbol.classId)
fun StringBuilder.appendRepresentation(it: FirTypeRef) {
when (it) {
is FirResolvedTypeRef -> appendRepresentation(it.type)
is FirErrorTypeRef -> append("ERROR")
else -> append("?")
}
}
fun StringBuilder.appendRepresentation(it: FirTypeParameter) {
append(it.name.asString())
append(':')
when (it.bounds.size) {
0 -> {
}
1 -> {
appendRepresentation(it.bounds[0])
}
else -> {
val set = sortedSetOf<String>()
it.bounds.forEach { that ->
set.add(buildString { appendRepresentation(that) })
}
set.forEach { that ->
append(that)
append(',')
}
}
}
}
fun StringBuilder.appendRepresentation(it: FirValueParameter) {
if (it.isVararg) {
append("vararg ")
}
appendRepresentation(it.returnTypeRef)
}
fun represent(it: FirProperty) = buildString {
append('[')
it.receiverTypeRef?.let {
appendRepresentation(it)
}
append(']')
appendRepresentation(it.symbol.callableId)
}
fun represent(it: FirSimpleFunction) = buildString {
append('<')
it.typeParameters.forEach {
appendRepresentation(it)
append(',')
}
append('>')
append('[')
it.receiverTypeRef?.let {
appendRepresentation(it)
}
append(']')
if (it.isOperator) {
append("operator ")
}
appendRepresentation(it.symbol.callableId)
append('(')
it.valueParameters.forEach {
appendRepresentation(it)
append(',')
}
append(')')
}
fun represent(it: FirTypeAlias) = buildString {
append('[')
append(']')
appendRepresentation(it.symbol.classId)
}
fun represent(it: FirRegularClass) = buildString {
append('[')
append(']')
appendRepresentation(it.symbol.classId)
}
}
@@ -28,7 +28,7 @@ abstract class CheckerContext {
* T instance or null if no such item could be found.
*/
inline fun <reified T : FirDeclaration> findClosest(): T? {
for (it in containingDeclarations.reversed()) {
for (it in containingDeclarations.asReversed()) {
return it as? T ?: continue
}
@@ -27,7 +27,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirConflictingProjectionChecker,
)
override val memberDeclarationCheckers: List<FirMemberDeclarationChecker> = listOf(
override val memberDeclarationCheckers: List<FirMemberDeclarationChecker> =listOf(
FirInfixFunctionDeclarationChecker,
FirExposedVisibilityDeclarationChecker,
FirCommonConstructorDelegationIssuesChecker,
@@ -41,11 +41,10 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirEnumClassSimpleChecker,
FirSealedSupertypeChecker,
FirInapplicableLateinitChecker,
FirTypeMismatchOnOverrideChecker,
)
override val regularClassCheckers: List<FirRegularClassChecker> = listOf(
FirTypeMismatchOnOverrideChecker,
)
override val constructorCheckers: List<FirConstructorChecker> = listOf(
@@ -13,25 +13,20 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.min
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
// we can't just check for FirTypedDeclaration
// because it leads to duplicate reports for
// some cases. Maybe we should fix this via not
// visiting the same firs twice instead.
if (declaration is FirPropertyAccessor) {
return
}
if (declaration is FirTypedDeclaration) {
checkTypeRef(declaration.returnTypeRef, context, reporter)
}
when (declaration) {
is FirPropertyAccessor -> {}
is FirProperty -> {
checkTypeRef(declaration.returnTypeRef, context, reporter)
}
is FirFunction<*> -> {
for (it in declaration.valueParameters) {
checkTypeRef(it.returnTypeRef, context, reporter)
}
checkTypeRef(declaration.returnTypeRef, context, reporter)
}
is FirClass<*> -> {
for (it in declaration.superTypeRefs) {
checkTypeRef(it, context, reporter)
@@ -56,14 +51,19 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() {
?.fir.safeAs<FirRegularClass>()
?: return
declaration.typeParameters.zip(typeRef.coneType.typeArguments).forEach { (proto, actual) ->
val size = min(declaration.typeParameters.size, typeRef.coneType.typeArguments.size)
for (it in 0 until size) {
val proto = declaration.typeParameters[it]
val actual = typeRef.coneType.typeArguments[it]
val protoVariance = proto.safeAs<FirTypeParameterRef>()
?.symbol?.fir
?.variance
?: return@forEach
?: continue
if (protoVariance == Variance.INVARIANT) {
return@forEach
continue
}
if (
@@ -47,10 +47,13 @@ object FirDelegationInInterfaceChecker : FirMemberDeclarationChecker() {
return -1
}
private fun PsiElement.findSuperTypeDelegation() = if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtDelegatedSuperTypeEntry }
} else {
-1
private fun PsiElement.findSuperTypeDelegation(): Int {
val children = this.children // this is a method call and it collects children
return if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtDelegatedSuperTypeEntry }
} else {
-1
}
}
private fun LighterASTNode.findSuperTypeDelegation(tree: FlyweightCapableTreeStructure<LighterASTNode>): Int {
@@ -34,13 +34,26 @@ object FirMethodOfAnyImplementedInInterfaceChecker : FirMemberDeclarationChecker
inspector = this
}
override fun represent(it: FirSimpleFunction) = buildFunctionRepresentation {
typeArguments = it.typeParameters.joinToString { represent(it) }
it.receiverTypeRef?.let {
receiver = represent(it)
@Suppress("DuplicatedCode")
override fun represent(it: FirSimpleFunction) = buildString {
append('<')
it.typeParameters.forEach {
appendRepresentation(it)
append(',')
}
name = it.name.asString()
parameters = it.valueParameters.joinToString { represent(it) }
append('>')
append('[')
it.receiverTypeRef?.let {
appendRepresentation(it)
}
append(']')
append(it.name.asString())
append('(')
it.valueParameters.forEach {
appendRepresentation(it)
append(',')
}
append(')')
}
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -47,10 +47,13 @@ object FirSupertypeInitializedInInterfaceChecker : FirMemberDeclarationChecker()
return -1
}
private fun PsiElement.findSuperTypeCall() = if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtSuperTypeCallEntry }
} else {
-1
private fun PsiElement.findSuperTypeCall(): Int {
val children = this.children // this is a method call and it collects children
return if (children.isNotEmpty() && children[0] !is PsiErrorElement) {
children[0].children.indexOfFirst { it is KtSuperTypeCallEntry }
} else {
-1
}
}
private fun LighterASTNode.findSuperTypeCall(tree: FlyweightCapableTreeStructure<LighterASTNode>): Int {
@@ -52,6 +52,7 @@ object FirSupertypeInitializedWithoutPrimaryConstructor : FirMemberDeclarationCh
}
private fun PsiElement.anySupertypeHasConstructorParentheses(): Boolean {
val children = this.children // this is a method call and it collects children
return children.isNotEmpty() && children[0] !is PsiErrorElement && children[0].children.any { it is KtSuperTypeCallEntry }
}
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
@@ -23,14 +21,11 @@ import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.AbstractTypeCheckerContext
import org.jetbrains.kotlin.utils.addToStdlib.min
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirRegularClass) {
return
}
object FirTypeMismatchOnOverrideChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false
@@ -43,8 +38,8 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
for (it in declaration.declarations) {
when (it) {
is FirSimpleFunction -> checkFunction(declaration, it, context, reporter, typeCheckerContext, firTypeScope)
is FirProperty -> checkProperty(declaration, it, context, reporter, typeCheckerContext, firTypeScope)
is FirSimpleFunction -> checkFunction(it, reporter, typeCheckerContext, firTypeScope)
is FirProperty -> checkProperty(it, reporter, typeCheckerContext, firTypeScope)
}
}
}
@@ -73,38 +68,6 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
return overriddenProperties.toList()
}
private fun FirRegularClass.substituteAllSupertypeParameters(context: CheckerContext): ConeSubstitutor {
val allSupertypesMapping = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
val remapper = mutableMapOf<ConeKotlinType, ConeKotlinType>()
fun FirRegularClass.collectSupertypes() {
for (it in superTypeRefs) {
val fir = it.coneType.safeAs<ConeClassLikeType>()?.lookupTag?.toSymbol(context.session)
?.fir.safeAs<FirRegularClass>()
?: continue
if (it.coneType.typeArguments.size != fir.typeParameters.size) {
continue
}
for (that in fir.typeParameters.indices) {
val proto = fir.typeParameters[that].symbol
val actual = it.coneType.typeArguments[that].safeAs<ConeKotlinType>()
?.lowerBoundIfFlexible()
?: continue
val value = remapper.getOrDefault(actual, actual)
remapper[proto.fir.toConeType()] = value
allSupertypesMapping[proto] = value
}
fir.collectSupertypes()
}
}
collectSupertypes()
return substitutorByMap(allSupertypesMapping)
}
private fun ConeKotlinType.substituteAllTypeParameters(
overrideDeclaration: FirCallableMemberDeclaration<*>,
baseDeclarationSymbol: FirCallableSymbol<*>,
@@ -117,32 +80,30 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
?: return this
val map = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
val size = min(overrideDeclaration.typeParameters.size, parametersOwner.typeParameters.size)
for (it in 0 until size) {
val to = overrideDeclaration.typeParameters[it]
val from = parametersOwner.typeParameters[it]
overrideDeclaration.typeParameters.zip(parametersOwner.typeParameters).forEach { (to, from) ->
map[from.symbol] = to.toConeType()
}
return substitutorByMap(map).substituteOrSelf(this)
}
private fun ConeKotlinType.substituteOrSelf(substitutor: ConeSubstitutor) = substitutor.substituteOrSelf(this)
private fun FirCallableMemberDeclaration<*>.checkReturnType(
regularClass: FirRegularClass,
overriddenSymbols: List<FirCallableSymbol<*>>,
context: CheckerContext,
typeCheckerContext: AbstractTypeCheckerContext,
): FirMemberDeclaration? {
val returnType = returnTypeRef.safeAs<FirResolvedTypeRef>()?.type
?: return null
val bounds = overriddenSymbols.map { it.fir.returnTypeRef.coneType.upperBoundIfFlexible() }
val supertypesParameterSubstitutor = regularClass.substituteAllSupertypeParameters(context)
for (it in bounds.indices) {
val restriction = bounds[it]
.substituteAllTypeParameters(this, overriddenSymbols[it])
.substituteOrSelf(supertypesParameterSubstitutor)
if (!AbstractTypeChecker.isSubtypeOf(typeCheckerContext, returnType, restriction)) {
return overriddenSymbols[it].fir.safeAs()
@@ -153,9 +114,7 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
}
private fun checkFunction(
regularClass: FirRegularClass,
function: FirSimpleFunction,
context: CheckerContext,
reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext,
firTypeScope: FirTypeScope
@@ -171,9 +130,7 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
}
val restriction = function.checkReturnType(
regularClass = regularClass,
overriddenSymbols = overriddenFunctionSymbols,
context = context,
typeCheckerContext = typeCheckerContext
)
@@ -187,9 +144,7 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
}
private fun checkProperty(
regularClass: FirRegularClass,
property: FirProperty,
context: CheckerContext,
reporter: DiagnosticReporter,
typeCheckerContext: AbstractTypeCheckerContext,
firTypeScope: FirTypeScope
@@ -205,9 +160,7 @@ object FirTypeMismatchOnOverrideChecker : FirMemberDeclarationChecker() {
}
val restriction = property.checkReturnType(
regularClass = regularClass,
overriddenSymbols = overriddenPropertySymbols,
context = context,
typeCheckerContext = typeCheckerContext
)
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isSuperclassOf
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
@@ -22,6 +22,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecker() {
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
expression.explicitReceiver.safeAs<FirQualifiedAccessExpression>()
?.calleeReference.safeAs<FirSuperReference>()
?: return
val closestClass = context.findClosest<FirRegularClass>() ?: return
if (closestClass.classKind == ClassKind.INTERFACE) {
@@ -30,7 +34,7 @@ object FirSuperclassNotAccessibleFromInterfaceChecker : FirQualifiedAccessChecke
?.fir
?: return
if (origin.source != null && origin.isSuperclassOf(closestClass)) {
if (origin.source != null && origin.classKind == ClassKind.CLASS) {
reporter.report(expression.explicitReceiver?.source)
}
}
@@ -50,7 +50,8 @@ object FirTypeArgumentsNotAllowedExpressionChecker : FirQualifiedAccessChecker()
}
private fun PsiElement.hasAnyArguments(): Boolean {
return this.children.size > 1 && this.children[1] is KtTypeArgumentList
val children = this.children // this is a method call and it collects children
return children.size > 1 && children[1] is KtTypeArgumentList
}
private fun LighterASTNode.hasAnyArguments(tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
@@ -35,13 +35,13 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
?.fir.safeAs<FirTypeParameterRefsOwner>()
?: return
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false
)
val count = min(calleeFir.typeParameters.size, expression.typeArguments.size)
if (count == 0) {
return
}
val parameterPairs = mutableMapOf<FirTypeParameterSymbol, FirResolvedTypeRef>()
val count = min(calleeFir.typeParameters.size, expression.typeArguments.size)
for (it in 0 until count) {
expression.typeArguments[it].safeAs<FirTypeProjectionWithVariance>()
@@ -61,6 +61,11 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
parameterPairs.mapValues { it.value.type }
)
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false
)
parameterPairs.forEach { (proto, actual) ->
if (actual.source == null) {
// inferred types don't report INAPPLICABLE_CANDIDATE for type aliases!
@@ -122,9 +127,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
?.type.safeAs<ConeClassLikeType>()
?: return
val constructorsParameterPairs = mutableMapOf<FirTypeParameterSymbol, ConeSimpleKotlinType>()
val count = min(protoConstructor.typeParameters.size, actualConstructor.typeArguments.size)
if (count == 0) {
return
}
val constructorsParameterPairs = mutableMapOf<FirTypeParameterSymbol, ConeSimpleKotlinType>()
for (it in 0 until count) {
actualConstructor.typeArguments[it].safeAs<ConeSimpleKotlinType>()
?.let { that ->
@@ -182,9 +192,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() {
?.fir.safeAs<FirRegularClass>()
?: return false
val parameterPairs = mutableMapOf<FirTypeParameterSymbol, ConeClassLikeType>()
val count = min(prototypeClass.typeParameters.size, type.typeArguments.size)
if (count == 0) {
return false
}
val parameterPairs = mutableMapOf<FirTypeParameterSymbol, ConeClassLikeType>()
for (it in 0 until count) {
type.typeArguments[it].safeAs<ConeClassLikeType>()
?.let { that ->