提交 71cbe976 编写于 作者: M Mikhail Zarechenskiy

Introduce `Unit`-conversions for simple arguments

上级 f08a45f2
...@@ -24444,6 +24444,49 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte ...@@ -24444,6 +24444,49 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
} }
} }
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UnitConversion extends AbstractFirOldFrontendDiagnosticsTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInUnitConversion() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("chainedFunSuspendUnitConversion.kt")
public void testChainedFunSuspendUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
}
@TestMetadata("chainedFunUnitConversion.kt")
public void testChainedFunUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
}
@TestMetadata("chainedUnitSuspendConversion.kt")
public void testChainedUnitSuspendConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
}
@TestMetadata("unitConversionCompatibility.kt")
public void testUnitConversionCompatibility() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
}
@TestMetadata("unitConversionForAllKinds.kt")
public void testUnitConversionForAllKinds() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
}
@TestMetadata("unitConversionForSubtypes.kt")
public void testUnitConversionForSubtypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/varargs") @TestMetadata("compiler/testData/diagnostics/tests/varargs")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
/*
* Copyright 2010-2020 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.resolve.calls.components
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.inference.model.LowerPriorityToPreserveCompatibility
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.typeUtil.isUnit
object UnitTypeConversions : ParameterTypeConversion {
override fun conversionDefinitelyNotNeeded(
candidate: KotlinResolutionCandidate,
argument: KotlinCallArgument,
expectedParameterType: UnwrappedType
): Boolean {
// for callable references and lambdas it already works
if (argument !is SimpleKotlinCallArgument) return true
val receiver = argument.receiver
if (receiver.receiverValue.type.hasUnitOrDynamicReturnType()) return true
if (receiver.typesFromSmartCasts.any { it.hasUnitOrDynamicReturnType() }) return true
if (
!expectedParameterType.isBuiltinFunctionalType ||
!expectedParameterType.getReturnTypeFromFunctionType().isUnit()
) return true
return false
}
private fun KotlinType.hasUnitOrDynamicReturnType(): Boolean =
isFunctionOrKFunctionTypeWithAnySuspendability && arguments.last().type.isUnitOrDynamic()
private fun KotlinType.isUnitOrDynamic(): Boolean = isUnit() || isDynamic()
override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean =
argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionType
override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean {
if (argument !is SimpleKotlinCallArgument) return false
var isFunctionTypeOrSubtype = false
val hasReturnTypeInSubtypes = argument.receiver.stableType.isFunctionTypeOrSubtype {
isFunctionTypeOrSubtype = true
it.getReturnTypeFromFunctionType().isUnitOrDynamic()
}
if (!isFunctionTypeOrSubtype) return false
return !hasReturnTypeInSubtypes
}
override fun convertParameterType(
candidate: KotlinResolutionCandidate,
argument: KotlinCallArgument,
parameter: ParameterDescriptor,
expectedParameterType: UnwrappedType
): UnwrappedType? {
val nonUnitReturnedParameterType = createFunctionType(
candidate.callComponents.builtIns,
expectedParameterType.annotations,
expectedParameterType.getReceiverTypeFromFunctionType(),
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
parameterNames = null,
candidate.callComponents.builtIns.nullableAnyType,
suspendFunction = expectedParameterType.isSuspendFunctionType
)
candidate.addDiagnostic(LowerPriorityToPreserveCompatibility)
return nonUnitReturnedParameterType
}
}
\ No newline at end of file
...@@ -40,14 +40,23 @@ object TypeConversions { ...@@ -40,14 +40,23 @@ object TypeConversions {
) )
val suspendConversionData = performConversionBeforeSubtyping( val suspendConversionData = performConversionBeforeSubtyping(
candidate, argument, candidateParameter, samConversionData.convertedType ?: candidateExpectedType, SuspendTypeConversions candidate, argument, candidateParameter,
candidateExpectedType = samConversionData.convertedType ?: candidateExpectedType,
SuspendTypeConversions
)
val unitConversionData = performConversionBeforeSubtyping(
candidate, argument, candidateParameter,
candidateExpectedType = suspendConversionData.convertedType ?: samConversionData.convertedType ?: candidateExpectedType,
UnitTypeConversions
) )
return ConversionData( return ConversionData(
convertedType = suspendConversionData.convertedType ?: samConversionData.convertedType, convertedType = unitConversionData.convertedType ?: suspendConversionData.convertedType ?: samConversionData.convertedType,
wasConversion = samConversionData.wasConversion || suspendConversionData.wasConversion, wasConversion = samConversionData.wasConversion || suspendConversionData.wasConversion || unitConversionData.wasConversion,
conversionDefinitelyNotNeeded = samConversionData.conversionDefinitelyNotNeeded && conversionDefinitelyNotNeeded = samConversionData.conversionDefinitelyNotNeeded &&
suspendConversionData.conversionDefinitelyNotNeeded suspendConversionData.conversionDefinitelyNotNeeded &&
unitConversionData.conversionDefinitelyNotNeeded
) )
} }
...@@ -60,10 +69,13 @@ object TypeConversions { ...@@ -60,10 +69,13 @@ object TypeConversions {
val samConvertedType = performConversionAfterSubtyping( val samConvertedType = performConversionAfterSubtyping(
candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions
) )
if (samConvertedType != null) return samConvertedType if (samConvertedType != null) return samConvertedType
return performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions) val suspendConvertedType =
performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions)
if (suspendConvertedType != null) return suspendConvertedType
return performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, UnitTypeConversions)
} }
private fun performConversionAfterSubtyping( private fun performConversionAfterSubtyping(
......
// !LANGUAGE: +UnitConversion +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun interface SuspendRunnable {
suspend fun run()
}
fun foo(r: SuspendRunnable) {}
fun bar(): String = ""
abstract class SubInt : () -> Int
fun test(f: () -> String, s: SubInt) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(f)
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
<!INAPPLICABLE_CANDIDATE!>foo<!>(::bar)
}
\ No newline at end of file
// !LANGUAGE: +UnitConversion +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun interface SuspendRunnable {
suspend fun run()
}
fun foo(r: SuspendRunnable) {}
fun bar(): String = ""
abstract class SubInt : () -> Int
fun test(f: () -> String, s: SubInt) {
foo(f)
foo(s)
foo(::bar)
}
\ No newline at end of file
package
public fun bar(): kotlin.String
public fun foo(/*0*/ r: SuspendRunnable): kotlin.Unit
public fun test(/*0*/ f: () -> kotlin.String, /*1*/ s: SubInt): kotlin.Unit
public abstract class SubInt : () -> kotlin.Int {
public constructor SubInt()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public fun interface SuspendRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract suspend fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun interface KRunnable {
fun run()
}
fun foo(r: KRunnable) {}
abstract class SubInt : () -> Int
fun test(f: () -> Int, s: SubInt) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(f)
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
}
\ No newline at end of file
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun interface KRunnable {
fun run()
}
fun foo(r: KRunnable) {}
abstract class SubInt : () -> Int
fun test(f: () -> Int, s: SubInt) {
foo(f)
foo(s)
}
\ No newline at end of file
package
public fun foo(/*0*/ r: KRunnable): kotlin.Unit
public fun test(/*0*/ f: () -> kotlin.Int, /*1*/ s: SubInt): kotlin.Unit
public fun interface KRunnable {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract fun run(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class SubInt : () -> kotlin.Int {
public constructor SubInt()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// !LANGUAGE: +UnitConversion +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: suspend () -> Unit) {}
fun bar(): String = ""
abstract class SubInt : () -> Int
fun test(g: () -> Double, s: SubInt) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(::bar)
<!INAPPLICABLE_CANDIDATE!>foo<!>(g)
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
}
\ No newline at end of file
// !LANGUAGE: +UnitConversion +SuspendConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: suspend () -> Unit) {}
fun bar(): String = ""
abstract class SubInt : () -> Int
fun test(g: () -> Double, s: SubInt) {
foo(::bar)
foo(g)
foo(s)
}
\ No newline at end of file
package
public fun bar(): kotlin.String
public fun foo(/*0*/ f: suspend () -> kotlin.Unit): kotlin.Unit
public fun test(/*0*/ g: () -> kotlin.Double, /*1*/ s: SubInt): kotlin.Unit
public abstract class SubInt : () -> kotlin.Int {
public constructor SubInt()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: () -> Unit) {}
fun <T> fooGeneric(f: (T) -> Unit): T = TODO()
fun bar(): String = ""
fun createCall(): () -> Int = TODO()
fun test(g: () -> String, h: (Float) -> String) {
foo(::bar)
foo { "something" }
foo(g)
fooGeneric(h)
}
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: () -> Unit) {}
fun <T> fooGeneric(f: (T) -> Unit): T = TODO()
fun bar(): String = ""
fun createCall(): () -> Int = TODO()
fun test(g: () -> String, h: (Float) -> String) {
foo(::bar)
foo { "something" }
foo(g)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Float")!>fooGeneric(h)<!>
}
\ No newline at end of file
package
public fun bar(): kotlin.String
public fun createCall(): () -> kotlin.Int
public fun foo(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public fun </*0*/ T> fooGeneric(/*0*/ f: (T) -> kotlin.Unit): T
public fun test(/*0*/ g: () -> kotlin.String, /*1*/ h: (kotlin.Float) -> kotlin.String): kotlin.Unit
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: (Int, String) -> Unit) {}
abstract class SubInt : (Int, String) -> Int
abstract class SubIntWrong : (String, String) -> Int
fun test1(s: SubInt, sWrong: SubIntWrong) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(s)
<!INAPPLICABLE_CANDIDATE!>foo<!>(sWrong)
val a = "foo"
<!INAPPLICABLE_CANDIDATE!>foo<!>(a)
a as (Int, String) -> String
<!INAPPLICABLE_CANDIDATE!>foo<!>(a)
}
fun <T> test2(x: T) where T : (Int, String) -> Int, T : (Double) -> Int {
<!INAPPLICABLE_CANDIDATE!>foo<!>(x)
}
\ No newline at end of file
// !LANGUAGE: +UnitConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
fun foo(f: (Int, String) -> Unit) {}
abstract class SubInt : (Int, String) -> Int
abstract class SubIntWrong : (String, String) -> Int
fun test1(s: SubInt, sWrong: SubIntWrong) {
foo(s)
foo(<!TYPE_MISMATCH!>sWrong<!>)
val a = "foo"
foo(<!TYPE_MISMATCH!>a<!>)
a <!CAST_NEVER_SUCCEEDS!>as<!> (Int, String) -> String
foo(a)
}
fun <T> test2(x: T) where T : (Int, String) -> Int, T : (Double) -> Int {
foo(x)
}
\ No newline at end of file
package
public fun foo(/*0*/ f: (kotlin.Int, kotlin.String) -> kotlin.Unit): kotlin.Unit
public fun test1(/*0*/ s: SubInt, /*1*/ sWrong: SubIntWrong): kotlin.Unit
public fun </*0*/ T : (kotlin.Int, kotlin.String) -> kotlin.Int> test2(/*0*/ x: T): kotlin.Unit where T : (kotlin.Double) -> kotlin.Int
public abstract class SubInt : (kotlin.Int, kotlin.String) -> kotlin.Int {
public constructor SubInt()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: kotlin.Int, /*1*/ p2: kotlin.String): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public abstract class SubIntWrong : (kotlin.String, kotlin.String) -> kotlin.Int {
public constructor SubIntWrong()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: kotlin.String, /*1*/ p2: kotlin.String): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
...@@ -24526,6 +24526,49 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali ...@@ -24526,6 +24526,49 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali
} }
} }
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UnitConversion extends AbstractDiagnosticsTestWithFirValidation {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInUnitConversion() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("chainedFunSuspendUnitConversion.kt")
public void testChainedFunSuspendUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
}
@TestMetadata("chainedFunUnitConversion.kt")
public void testChainedFunUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
}
@TestMetadata("chainedUnitSuspendConversion.kt")
public void testChainedUnitSuspendConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
}
@TestMetadata("unitConversionCompatibility.kt")
public void testUnitConversionCompatibility() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
}
@TestMetadata("unitConversionForAllKinds.kt")
public void testUnitConversionForAllKinds() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
}
@TestMetadata("unitConversionForSubtypes.kt")
public void testUnitConversionForSubtypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/varargs") @TestMetadata("compiler/testData/diagnostics/tests/varargs")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
...@@ -24446,6 +24446,49 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing ...@@ -24446,6 +24446,49 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
} }
} }
@TestMetadata("compiler/testData/diagnostics/tests/unitConversion")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UnitConversion extends AbstractDiagnosticsUsingJavacTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInUnitConversion() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/unitConversion"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@TestMetadata("chainedFunSuspendUnitConversion.kt")
public void testChainedFunSuspendUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunSuspendUnitConversion.kt");
}
@TestMetadata("chainedFunUnitConversion.kt")
public void testChainedFunUnitConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedFunUnitConversion.kt");
}
@TestMetadata("chainedUnitSuspendConversion.kt")
public void testChainedUnitSuspendConversion() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/chainedUnitSuspendConversion.kt");
}
@TestMetadata("unitConversionCompatibility.kt")
public void testUnitConversionCompatibility() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionCompatibility.kt");
}
@TestMetadata("unitConversionForAllKinds.kt")
public void testUnitConversionForAllKinds() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForAllKinds.kt");
}
@TestMetadata("unitConversionForSubtypes.kt")
public void testUnitConversionForSubtypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/unitConversion/unitConversionForSubtypes.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/varargs") @TestMetadata("compiler/testData/diagnostics/tests/varargs")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
...@@ -153,6 +153,7 @@ enum class LanguageFeature( ...@@ -153,6 +153,7 @@ enum class LanguageFeature(
FunctionReferenceWithDefaultValueAsOtherType(sinceVersion = KOTLIN_1_4), FunctionReferenceWithDefaultValueAsOtherType(sinceVersion = KOTLIN_1_4),
NonStrictOnlyInputTypesChecks(sinceVersion = KOTLIN_1_4), NonStrictOnlyInputTypesChecks(sinceVersion = KOTLIN_1_4),
SuspendConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED), SuspendConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
UnitConversion(sinceVersion = KOTLIN_1_4, defaultState = State.DISABLED),
OverloadResolutionByLambdaReturnType(sinceVersion = KOTLIN_1_4), OverloadResolutionByLambdaReturnType(sinceVersion = KOTLIN_1_4),
BooleanElvisBoundSmartCasts(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details BooleanElvisBoundSmartCasts(sinceVersion = KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details
......
...@@ -54,6 +54,9 @@ val KotlinType.isSuspendFunctionTypeOrSubtype: Boolean ...@@ -54,6 +54,9 @@ val KotlinType.isSuspendFunctionTypeOrSubtype: Boolean
val KotlinType.isBuiltinFunctionalTypeOrSubtype: Boolean val KotlinType.isBuiltinFunctionalTypeOrSubtype: Boolean
get() = isTypeOrSubtypeOf { it.isBuiltinFunctionalType } get() = isTypeOrSubtypeOf { it.isBuiltinFunctionalType }
fun KotlinType.isFunctionTypeOrSubtype(predicate: (KotlinType) -> Boolean): Boolean =
isTypeOrSubtypeOf { it.isFunctionType && predicate(it) }
val KotlinType.isFunctionType: Boolean val KotlinType.isFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册