Disallow function types with big arity on JVM if LV < 1.3 or API < 1.3

The implementation is a bit obscure because this worked on JS since
Kotlin 1.0 and we should not break that; however, on JVM, a diagnostic
will be reported with old language/API version

 #KT-25241 Fixed
This commit is contained in:
Alexander Udalov
2018-06-27 19:41:13 +02:00
parent 56f509ba09
commit dcbb8045bd
25 changed files with 164 additions and 1 deletions
@@ -0,0 +1,30 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.types.typeUtil.contains
object BigFunctionTypeAvailabilityChecker : ClassifierUsageChecker {
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.FunctionTypesWithBigArity)) return
if (targetDescriptor.defaultType.contains { argumentType ->
val descriptor = argumentType.constructor.declarationDescriptor
descriptor is FunctionClassDescriptor && descriptor.hasBigArity
}) {
context.trace.report(
Errors.UNSUPPORTED_FEATURE.on(
element, LanguageFeature.FunctionTypesWithBigArity to context.languageVersionSettings
)
)
}
}
}
@@ -7,12 +7,15 @@ package org.jetbrains.kotlin.types.expressions
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
@@ -84,7 +87,8 @@ class DoubleColonExpressionResolver(
val typeResolver: TypeResolver,
val languageVersionSettings: LanguageVersionSettings,
val additionalCheckers: Iterable<ClassLiteralChecker>,
val dataFlowValueFactory: DataFlowValueFactory
val dataFlowValueFactory: DataFlowValueFactory,
val bigAritySupport: FunctionWithBigAritySupport
) {
private lateinit var expressionTypingServices: ExpressionTypingServices
@@ -592,6 +596,15 @@ class DoubleColonExpressionResolver(
)
context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor)
if (functionDescriptor.valueParameters.size >= FunctionInvokeDescriptor.BIG_ARITY &&
bigAritySupport.shouldCheckLanguageVersionSettings &&
!languageVersionSettings.supportsFeature(LanguageFeature.FunctionTypesWithBigArity)
) {
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(
expression, LanguageFeature.FunctionTypesWithBigArity to languageVersionSettings
))
}
}
internal fun bindPropertyReference(
@@ -796,3 +809,15 @@ class DoubleColonExpressionResolver(
}
}
}
// By default, function types with big arity are supported. On platforms where they are not supported by default (e.g. JVM),
// LANGUAGE_VERSION_DEPENDENT should be used which makes the code check if the corresponding language feature is enabled.
@DefaultImplementation(FunctionWithBigAritySupport::class)
class FunctionWithBigAritySupport private constructor(val shouldCheckLanguageVersionSettings: Boolean) {
constructor() : this(false)
companion object {
@JvmField
val LANGUAGE_VERSION_DEPENDENT = FunctionWithBigAritySupport(true)
}
}