[PSI, FE] Support functional types
This commit is contained in:
committed by
TeamCityServer
parent
e53cee77a3
commit
e3f987459c
+28
@@ -10588,6 +10588,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/functionalType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericOuterClass.kt")
|
@TestMetadata("genericOuterClass.kt")
|
||||||
public void testGenericOuterClass() throws Exception {
|
public void testGenericOuterClass() throws Exception {
|
||||||
@@ -10719,6 +10725,28 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
public void testWithExplicitReceiverError() throws Exception {
|
public void testWithExplicitReceiverError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class FromKEEP {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInFromKEEP() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clickHandler.kt")
|
||||||
|
public void testClickHandler() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/clickHandler.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/functionalType.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ class JvmRuntimeTypes(
|
|||||||
descriptor.builtIns,
|
descriptor.builtIns,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
actualFunctionDescriptor.extensionReceiverParameter?.type,
|
actualFunctionDescriptor.extensionReceiverParameter?.type,
|
||||||
|
actualFunctionDescriptor.contextReceiverParameters.map { it.type },
|
||||||
actualFunctionDescriptor.valueParameters.map { it.type },
|
actualFunctionDescriptor.valueParameters.map { it.type },
|
||||||
null,
|
null,
|
||||||
actualFunctionDescriptor.returnType!!
|
actualFunctionDescriptor.returnType!!
|
||||||
@@ -146,6 +147,7 @@ class JvmRuntimeTypes(
|
|||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
if (isBound) null else referencedFunction.extensionReceiverParameter?.type
|
if (isBound) null else referencedFunction.extensionReceiverParameter?.type
|
||||||
?: referencedFunction.dispatchReceiverParameter?.type,
|
?: referencedFunction.dispatchReceiverParameter?.type,
|
||||||
|
referencedFunction.contextReceiverParameters.map { it.type },
|
||||||
anonymousFunctionDescriptor.valueParameters.drop(receivers).map { it.type },
|
anonymousFunctionDescriptor.valueParameters.drop(receivers).map { it.type },
|
||||||
null,
|
null,
|
||||||
anonymousFunctionDescriptor.returnType!!,
|
anonymousFunctionDescriptor.returnType!!,
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ fun InstructionAdapter.generateClosureFieldsInitializationFromParameters(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun computeExpectedNumberOfReceivers(referencedFunction: FunctionDescriptor, isBound: Boolean): Int {
|
fun computeExpectedNumberOfReceivers(referencedFunction: FunctionDescriptor, isBound: Boolean): Int {
|
||||||
val receivers = (if (referencedFunction.dispatchReceiverParameter != null) 1 else 0) +
|
val receivers = referencedFunction.contextReceiverParameters.size +
|
||||||
|
(if (referencedFunction.dispatchReceiverParameter != null) 1 else 0) +
|
||||||
(if (referencedFunction.extensionReceiverParameter != null) 1 else 0) -
|
(if (referencedFunction.extensionReceiverParameter != null) 1 else 0) -
|
||||||
(if (isBound) 1 else 0)
|
(if (isBound) 1 else 0)
|
||||||
|
|
||||||
|
|||||||
@@ -339,6 +339,14 @@ public abstract interface Comparable<in T> : R|kotlin/Any| {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@R|kotlin/annotation/Target|(allowedTargets = <implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.TYPE|())) @R|kotlin/annotation/MustBeDocumented|() public final annotation class ContextFunctionTypeParams : R|kotlin/Annotation| {
|
||||||
|
public final val count: R|kotlin/Int|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
public constructor(count: R|kotlin/Int|): R|kotlin/ContextFunctionTypeParams|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@R|kotlin/annotation/Target|(allowedTargets = <implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/MustBeDocumented|() public final annotation class Deprecated : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(allowedTargets = <implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY|(), R|kotlin/annotation/AnnotationTarget.ANNOTATION_CLASS|(), R|kotlin/annotation/AnnotationTarget.CONSTRUCTOR|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.TYPEALIAS|())) @R|kotlin/annotation/MustBeDocumented|() public final annotation class Deprecated : R|kotlin/Annotation| {
|
||||||
public final val level: R|kotlin/DeprecationLevel|
|
public final val level: R|kotlin/DeprecationLevel|
|
||||||
public get(): R|kotlin/DeprecationLevel|
|
public get(): R|kotlin/DeprecationLevel|
|
||||||
|
|||||||
+28
@@ -10588,6 +10588,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/functionalType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericOuterClass.kt")
|
@TestMetadata("genericOuterClass.kt")
|
||||||
public void testGenericOuterClass() throws Exception {
|
public void testGenericOuterClass() throws Exception {
|
||||||
@@ -10719,6 +10725,28 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
public void testWithExplicitReceiverError() throws Exception {
|
public void testWithExplicitReceiverError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class FromKEEP {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInFromKEEP() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clickHandler.kt")
|
||||||
|
public void testClickHandler() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/clickHandler.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/functionalType.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
@@ -10588,6 +10588,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/functionalType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericOuterClass.kt")
|
@TestMetadata("genericOuterClass.kt")
|
||||||
public void testGenericOuterClass() throws Exception {
|
public void testGenericOuterClass() throws Exception {
|
||||||
@@ -10719,6 +10725,28 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
public void testWithExplicitReceiverError() throws Exception {
|
public void testWithExplicitReceiverError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class FromKEEP {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInFromKEEP() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clickHandler.kt")
|
||||||
|
public void testClickHandler() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/clickHandler.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/functionalType.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -346,7 +346,12 @@ class TypeResolver(
|
|||||||
|
|
||||||
override fun visitFunctionType(type: KtFunctionType) {
|
override fun visitFunctionType(type: KtFunctionType) {
|
||||||
val receiverTypeRef = type.receiverTypeReference
|
val receiverTypeRef = type.receiverTypeReference
|
||||||
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
val receiverType = if (receiverTypeRef?.typeElement == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||||
|
|
||||||
|
val contextReceiversTypeRefs = type.contextReceiversTypeReferences
|
||||||
|
val contextReceiversTypes = contextReceiversTypeRefs?.mapNotNull {
|
||||||
|
resolveType(c.noBareTypes(), it)
|
||||||
|
} ?: emptyList()
|
||||||
|
|
||||||
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
|
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
|
||||||
checkParametersOfFunctionType(parameterDescriptors)
|
checkParametersOfFunctionType(parameterDescriptors)
|
||||||
@@ -362,7 +367,7 @@ class TypeResolver(
|
|||||||
|
|
||||||
result = type(
|
result = type(
|
||||||
createFunctionType(
|
createFunctionType(
|
||||||
moduleDescriptor.builtIns, annotations, receiverType,
|
moduleDescriptor.builtIns, annotations, receiverType, contextReceiversTypes,
|
||||||
parameterDescriptors.map { it.type },
|
parameterDescriptors.map { it.type },
|
||||||
parameterDescriptors.map { it.name },
|
parameterDescriptors.map { it.name },
|
||||||
returnType,
|
returnType,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import javax.inject.Inject;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.psi.KtPsiUtil.getLastElementDeparenthesized;
|
import static org.jetbrains.kotlin.psi.KtPsiUtil.getLastElementDeparenthesized;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getRecordedTypeInfo;
|
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getRecordedTypeInfo;
|
||||||
@@ -334,7 +335,7 @@ public class ArgumentTypeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return FunctionTypesKt.createFunctionType(
|
return FunctionTypesKt.createFunctionType(
|
||||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), null, TypeUtils.DONT_CARE
|
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), Collections.emptyList(), null, TypeUtils.DONT_CARE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +373,7 @@ public class ArgumentTypeResolver {
|
|||||||
return expectedTypeIsUnknown
|
return expectedTypeIsUnknown
|
||||||
? functionPlaceholders.createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false)
|
? functionPlaceholders.createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false)
|
||||||
: FunctionTypesKt.createFunctionType(
|
: FunctionTypesKt.createFunctionType(
|
||||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), null, DONT_CARE
|
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), Collections.emptyList(), null, DONT_CARE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
List<KtParameter> valueParameters = function.getValueParameters();
|
List<KtParameter> valueParameters = function.getValueParameters();
|
||||||
@@ -391,11 +392,14 @@ public class ArgumentTypeResolver {
|
|||||||
KotlinType returnType = resolveTypeRefWithDefault(function.getTypeReference(), scope, temporaryTrace, DONT_CARE);
|
KotlinType returnType = resolveTypeRefWithDefault(function.getTypeReference(), scope, temporaryTrace, DONT_CARE);
|
||||||
assert returnType != null;
|
assert returnType != null;
|
||||||
KotlinType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null);
|
KotlinType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null);
|
||||||
|
List<KotlinType> contextReceiversTypes = function.getContextReceivers().stream().map(contextReceiver ->
|
||||||
|
resolveTypeRefWithDefault(contextReceiver.typeReference(), scope, temporaryTrace, null)
|
||||||
|
).collect(Collectors.toList());
|
||||||
|
|
||||||
return expectedTypeIsUnknown && isFunctionLiteral
|
return expectedTypeIsUnknown && isFunctionLiteral
|
||||||
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
|
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
|
||||||
: FunctionTypesKt.createFunctionType(
|
: FunctionTypesKt.createFunctionType(
|
||||||
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, parameterNames, returnType, suspendFunctionTypeExpected
|
builtIns, Annotations.Companion.getEMPTY(), receiverType, contextReceiversTypes, parameterTypes, parameterNames, returnType, suspendFunctionTypeExpected
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ public class CallResolver {
|
|||||||
parameterTypes.add(NO_EXPECTED_TYPE);
|
parameterTypes.add(NO_EXPECTED_TYPE);
|
||||||
}
|
}
|
||||||
expectedType = FunctionTypesKt.createFunctionType(
|
expectedType = FunctionTypesKt.createFunctionType(
|
||||||
builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, null, context.expectedType
|
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), parameterTypes, null, context.expectedType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
KotlinType calleeType = expressionTypingServices.safeGetType(
|
KotlinType calleeType = expressionTypingServices.safeGetType(
|
||||||
|
|||||||
+1
-1
@@ -177,7 +177,7 @@ class BuilderInferenceSupport(
|
|||||||
approximationSubstitutor.buildSubstitutor().substitute(lambdaExpectedType, Variance.IN_VARIANCE) ?: return
|
approximationSubstitutor.buildSubstitutor().substitute(lambdaExpectedType, Variance.IN_VARIANCE) ?: return
|
||||||
|
|
||||||
val newExpectedType = createFunctionType(
|
val newExpectedType = createFunctionType(
|
||||||
newReceiverType.builtIns, approximatedLambdaType.annotations, newReceiverType,
|
newReceiverType.builtIns, approximatedLambdaType.annotations, newReceiverType, emptyList(), // TODO: Context receivers?
|
||||||
approximatedLambdaType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType),
|
approximatedLambdaType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType),
|
||||||
parameterNames = null, // TODO: parameterNames
|
parameterNames = null, // TODO: parameterNames
|
||||||
returnType = approximatedLambdaType.getReturnTypeFromFunctionType(),
|
returnType = approximatedLambdaType.getReturnTypeFromFunctionType(),
|
||||||
|
|||||||
+3
-4
@@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference
|
package org.jetbrains.kotlin.resolve.calls.inference
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
import org.jetbrains.kotlin.builtins.*
|
||||||
import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType
|
|
||||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
|
||||||
@@ -471,8 +469,9 @@ internal fun createTypeForFunctionPlaceholder(
|
|||||||
functionPlaceholderTypeConstructor.argumentTypes
|
functionPlaceholderTypeConstructor.argumentTypes
|
||||||
}
|
}
|
||||||
val receiverType = if (isExtension) DONT_CARE else null
|
val receiverType = if (isExtension) DONT_CARE else null
|
||||||
|
val contextReceiverTypes = (0 until expectedType.contextFunctionTypeParamsCount()).map { DONT_CARE }
|
||||||
return createFunctionType(
|
return createFunctionType(
|
||||||
functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, newArgumentTypes, null, DONT_CARE,
|
functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, contextReceiverTypes, newArgumentTypes, null, DONT_CARE,
|
||||||
suspendFunction = expectedType.isSuspendFunctionType
|
suspendFunction = expectedType.isSuspendFunctionType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,9 +186,11 @@ class DynamicCallableDescriptors(private val storageManager: StorageManager, bui
|
|||||||
val funLiteral = funLiteralExpr.functionLiteral
|
val funLiteral = funLiteralExpr.functionLiteral
|
||||||
|
|
||||||
val receiverType = funLiteral.receiverTypeReference?.let { dynamicType }
|
val receiverType = funLiteral.receiverTypeReference?.let { dynamicType }
|
||||||
|
val contextReceiversTypes = funLiteral.contextReceivers.map { dynamicType }
|
||||||
|
|
||||||
val parameterTypes = funLiteral.valueParameters.map { dynamicType }
|
val parameterTypes = funLiteral.valueParameters.map { dynamicType }
|
||||||
|
|
||||||
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, parameterTypes, null, dynamicType)
|
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, contextReceiversTypes, parameterTypes, null, dynamicType)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (arg in call.valueArguments) {
|
for (arg in call.valueArguments) {
|
||||||
|
|||||||
+2
-1
@@ -171,8 +171,9 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
@OptIn(TypeRefinement::class) callComponents.kotlinTypeChecker.kotlinTypeRefiner.refineType(it)
|
@OptIn(TypeRefinement::class) callComponents.kotlinTypeChecker.kotlinTypeRefiner.refineType(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Context receivers?
|
||||||
val expectedType = createFunctionType(
|
val expectedType = createFunctionType(
|
||||||
builtIns, annotations, refinedReceiverType, parameters, null,
|
builtIns, annotations, refinedReceiverType, emptyList(), parameters, null,
|
||||||
lambdaInfo.expectedType, isSuspend
|
lambdaInfo.expectedType, isSuspend
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1
@@ -334,6 +334,7 @@ class ResolvedAtomCompleter(
|
|||||||
builtIns,
|
builtIns,
|
||||||
existingLambdaType.annotations,
|
existingLambdaType.annotations,
|
||||||
substitutedLambdaTypes.receiverType?.substitutedType,
|
substitutedLambdaTypes.receiverType?.substitutedType,
|
||||||
|
emptyList(),
|
||||||
substitutedLambdaTypes.parameterTypes.map { it.substitutedType },
|
substitutedLambdaTypes.parameterTypes.map { it.substitutedType },
|
||||||
null, // parameter names transforms to special annotations, so they are already taken from parameter types
|
null, // parameter names transforms to special annotations, so they are already taken from parameter types
|
||||||
substitutedLambdaTypes.returnType.substitutedType,
|
substitutedLambdaTypes.returnType.substitutedType,
|
||||||
|
|||||||
+5
-1
@@ -830,6 +830,9 @@ class DoubleColonExpressionResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private fun contextReceiverTypesFor(descriptor: CallableDescriptor): List<KotlinType> =
|
||||||
|
descriptor.contextReceiverParameters.map { it.type }
|
||||||
|
|
||||||
private fun receiverTypeFor(descriptor: CallableDescriptor, lhs: DoubleColonLHS?): KotlinType? =
|
private fun receiverTypeFor(descriptor: CallableDescriptor, lhs: DoubleColonLHS?): KotlinType? =
|
||||||
(descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter)?.let { (lhs as? DoubleColonLHS.Type)?.type }
|
(descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter)?.let { (lhs as? DoubleColonLHS.Type)?.type }
|
||||||
|
|
||||||
@@ -849,6 +852,7 @@ class DoubleColonExpressionResolver(
|
|||||||
reflectionTypes: ReflectionTypes,
|
reflectionTypes: ReflectionTypes,
|
||||||
scopeOwnerDescriptor: DeclarationDescriptor
|
scopeOwnerDescriptor: DeclarationDescriptor
|
||||||
): KotlinType? {
|
): KotlinType? {
|
||||||
|
val contextReceiverTypes = contextReceiverTypesFor(descriptor)
|
||||||
val receiverType = receiverTypeFor(descriptor, lhs)
|
val receiverType = receiverTypeFor(descriptor, lhs)
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is FunctionDescriptor -> {
|
is FunctionDescriptor -> {
|
||||||
@@ -857,7 +861,7 @@ class DoubleColonExpressionResolver(
|
|||||||
val parametersNames = descriptor.valueParameters.map { it.name }
|
val parametersNames = descriptor.valueParameters.map { it.name }
|
||||||
return reflectionTypes.getKFunctionType(
|
return reflectionTypes.getKFunctionType(
|
||||||
Annotations.EMPTY, receiverType,
|
Annotations.EMPTY, receiverType,
|
||||||
parametersTypes, parametersNames, returnType, descriptor.builtIns, descriptor.isSuspend
|
contextReceiverTypes, parametersTypes, parametersNames, returnType, descriptor.builtIns, descriptor.isSuspend
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
|
|||||||
@@ -397,6 +397,7 @@ fun SimpleFunctionDescriptor.createFunctionType(
|
|||||||
builtIns,
|
builtIns,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
extensionReceiverParameter?.type,
|
extensionReceiverParameter?.type,
|
||||||
|
contextReceiverParameters.map { it.type },
|
||||||
if (shouldUseVarargType) valueParameters.map { it.varargElementType ?: it.type } else valueParameters.map { it.type },
|
if (shouldUseVarargType) valueParameters.map { it.varargElementType ?: it.type } else valueParameters.map { it.type },
|
||||||
null,
|
null,
|
||||||
returnType ?: return null,
|
returnType ?: return null,
|
||||||
|
|||||||
+1
@@ -540,6 +540,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
|
|||||||
(statementGenerator.context.irBuiltIns as IrBuiltInsOverDescriptors).builtIns,
|
(statementGenerator.context.irBuiltIns as IrBuiltInsOverDescriptors).builtIns,
|
||||||
annotations,
|
annotations,
|
||||||
null,
|
null,
|
||||||
|
emptyList(),
|
||||||
arguments.dropLast(1).map { it.type },
|
arguments.dropLast(1).map { it.type },
|
||||||
null,
|
null,
|
||||||
arguments.last().type,
|
arguments.last().type,
|
||||||
|
|||||||
@@ -2172,6 +2172,12 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
IElementType lookahead = lookahead(1);
|
IElementType lookahead = lookahead(1);
|
||||||
IElementType lookahead2 = lookahead(2);
|
IElementType lookahead2 = lookahead(2);
|
||||||
boolean typeBeforeDot = true;
|
boolean typeBeforeDot = true;
|
||||||
|
boolean withContextReceiver = at(CONTEXT_KEYWORD) && lookahead == LPAR;
|
||||||
|
|
||||||
|
if (withContextReceiver) {
|
||||||
|
parseContextReceiverList();
|
||||||
|
}
|
||||||
|
|
||||||
if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
|
if (at(IDENTIFIER) && !(lookahead == DOT && lookahead2 == IDENTIFIER) && lookahead != LT && at(DYNAMIC_KEYWORD)) {
|
||||||
PsiBuilder.Marker dynamicType = mark();
|
PsiBuilder.Marker dynamicType = mark();
|
||||||
advance(); // DYNAMIC_KEYWORD
|
advance(); // DYNAMIC_KEYWORD
|
||||||
@@ -2180,7 +2186,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
|
else if (at(IDENTIFIER) || at(PACKAGE_KEYWORD) || atParenthesizedMutableForPlatformTypes(0)) {
|
||||||
parseUserType(allowSimpleIntersectionTypes);
|
parseUserType(allowSimpleIntersectionTypes);
|
||||||
}
|
}
|
||||||
else if (at(LPAR)) {
|
else if (at(LPAR) && !withContextReceiver) {
|
||||||
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
||||||
|
|
||||||
// This may be a function parameter list or just a parenthesized type
|
// This may be a function parameter list or just a parenthesized type
|
||||||
@@ -2211,7 +2217,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else if (!withContextReceiver) {
|
||||||
errorWithRecovery("Type expected",
|
errorWithRecovery("Type expected",
|
||||||
TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST,
|
TokenSet.orSet(TOP_LEVEL_DECLARATION_FIRST,
|
||||||
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON),
|
TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON),
|
||||||
@@ -2240,8 +2246,10 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
intersectionType.done(INTERSECTION_TYPE);
|
intersectionType.done(INTERSECTION_TYPE);
|
||||||
wasIntersection = true;
|
wasIntersection = true;
|
||||||
}
|
}
|
||||||
|
boolean withExtensionReceiver = typeBeforeDot && at(DOT);
|
||||||
|
|
||||||
if (typeBeforeDot && !wasIntersection && at(DOT)) {
|
|
||||||
|
if (withExtensionReceiver && !wasIntersection || withContextReceiver) {
|
||||||
// This is a receiver for a function type
|
// This is a receiver for a function type
|
||||||
// A.(B) -> C
|
// A.(B) -> C
|
||||||
// ^
|
// ^
|
||||||
@@ -2253,7 +2261,9 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
|||||||
receiverTypeRef.done(TYPE_REFERENCE);
|
receiverTypeRef.done(TYPE_REFERENCE);
|
||||||
receiverType.done(FUNCTION_TYPE_RECEIVER);
|
receiverType.done(FUNCTION_TYPE_RECEIVER);
|
||||||
|
|
||||||
advance(); // DOT
|
if (withExtensionReceiver) {
|
||||||
|
advance(); // DOT
|
||||||
|
}
|
||||||
|
|
||||||
if (at(LPAR)) {
|
if (at(LPAR)) {
|
||||||
parseFunctionTypeContents().drop();
|
parseFunctionTypeContents().drop();
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ public class KtFunctionType extends KtElementImplStub<KotlinPlaceHolderStub<KtFu
|
|||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getTypeArgumentsAsTypes() {
|
public List<KtTypeReference> getTypeArgumentsAsTypes() {
|
||||||
ArrayList<KtTypeReference> result = Lists.newArrayList();
|
ArrayList<KtTypeReference> result = Lists.newArrayList();
|
||||||
|
List<KtTypeReference> contextReceiversTypeRefs = getContextReceiversTypeReferences();
|
||||||
|
if (contextReceiversTypeRefs != null) {
|
||||||
|
result.addAll(contextReceiversTypeRefs);
|
||||||
|
}
|
||||||
KtTypeReference receiverTypeRef = getReceiverTypeReference();
|
KtTypeReference receiverTypeRef = getReceiverTypeReference();
|
||||||
if (receiverTypeRef != null) {
|
if (receiverTypeRef != null) {
|
||||||
result.add(receiverTypeRef);
|
result.add(receiverTypeRef);
|
||||||
@@ -89,6 +93,20 @@ public class KtFunctionType extends KtElementImplStub<KotlinPlaceHolderStub<KtFu
|
|||||||
return receiverDeclaration.getTypeReference();
|
return receiverDeclaration.getTypeReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<KtTypeReference> getContextReceiversTypeReferences() {
|
||||||
|
KtFunctionTypeReceiver receiverDeclaration = getReceiver();
|
||||||
|
if (receiverDeclaration == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
KtTypeReference receiverTypeRef = receiverDeclaration.getTypeReference();
|
||||||
|
KtContextReceiverList contextReceiverList = receiverTypeRef.getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
|
||||||
|
if (contextReceiverList != null) {
|
||||||
|
return contextReceiverList.typeReferences();
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public KtTypeReference getReturnTypeReference() {
|
public KtTypeReference getReturnTypeReference() {
|
||||||
return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
|
return getStubOrPsiChild(KtStubElementTypes.TYPE_REFERENCE);
|
||||||
|
|||||||
+1
-1
@@ -86,7 +86,7 @@ private fun preprocessLambdaArgument(
|
|||||||
|
|
||||||
if (expectedType != null) {
|
if (expectedType != null) {
|
||||||
val lambdaType = createFunctionType(
|
val lambdaType = createFunctionType(
|
||||||
csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver,
|
csBuilder.builtIns, Annotations.EMPTY, resolvedArgument.receiver, emptyList(), // TODO: Context receivers?
|
||||||
resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend
|
resolvedArgument.parameters, null, resolvedArgument.returnType, resolvedArgument.isSuspend
|
||||||
)
|
)
|
||||||
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPositionImpl(argument))
|
csBuilder.addSubtypeConstraint(lambdaType, expectedType, ArgumentConstraintPositionImpl(argument))
|
||||||
|
|||||||
+1
@@ -43,6 +43,7 @@ object SuspendTypeConversions : ParameterTypeConversion {
|
|||||||
candidate.callComponents.builtIns,
|
candidate.callComponents.builtIns,
|
||||||
expectedParameterType.annotations,
|
expectedParameterType.annotations,
|
||||||
expectedParameterType.getReceiverTypeFromFunctionType(),
|
expectedParameterType.getReceiverTypeFromFunctionType(),
|
||||||
|
expectedParameterType.getContextReceiverTypesFromFunctionType(),
|
||||||
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
|
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
|
||||||
parameterNames = null,
|
parameterNames = null,
|
||||||
expectedParameterType.getReturnTypeFromFunctionType(),
|
expectedParameterType.getReturnTypeFromFunctionType(),
|
||||||
|
|||||||
+1
@@ -78,6 +78,7 @@ object UnitTypeConversions : ParameterTypeConversion {
|
|||||||
candidate.callComponents.builtIns,
|
candidate.callComponents.builtIns,
|
||||||
expectedParameterType.annotations,
|
expectedParameterType.annotations,
|
||||||
expectedParameterType.getReceiverTypeFromFunctionType(),
|
expectedParameterType.getReceiverTypeFromFunctionType(),
|
||||||
|
expectedParameterType.getContextReceiverTypesFromFunctionType(),
|
||||||
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
|
expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type },
|
||||||
parameterNames = null,
|
parameterNames = null,
|
||||||
candidate.callComponents.builtIns.nullableAnyType,
|
candidate.callComponents.builtIns.nullableAnyType,
|
||||||
|
|||||||
@@ -195,6 +195,12 @@ public interface Comparable</*0*/ in T> {
|
|||||||
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.MustBeDocumented public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
/*primary*/ public constructor ContextFunctionTypeParams(/*0*/ count: kotlin.Int)
|
||||||
|
public final val count: kotlin.Int
|
||||||
|
public final fun <get-count>(): kotlin.Int
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
||||||
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
||||||
public final val level: kotlin.DeprecationLevel
|
public final val level: kotlin.DeprecationLevel
|
||||||
|
|||||||
@@ -203,6 +203,12 @@ public interface Comparable</*0*/ in T> {
|
|||||||
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.MustBeDocumented public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
/*primary*/ public constructor ContextFunctionTypeParams(/*0*/ count: kotlin.Int)
|
||||||
|
public final val count: kotlin.Int
|
||||||
|
public final fun <get-count>(): kotlin.Int
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
||||||
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
||||||
public final val level: kotlin.DeprecationLevel
|
public final val level: kotlin.DeprecationLevel
|
||||||
|
|||||||
@@ -205,6 +205,12 @@ public interface Comparable</*0*/ in T> {
|
|||||||
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.MustBeDocumented public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
/*primary*/ public constructor ContextFunctionTypeParams(/*0*/ count: kotlin.Int)
|
||||||
|
public final val count: kotlin.Int
|
||||||
|
public final fun <get-count>(): kotlin.Int
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
||||||
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
||||||
public final val level: kotlin.DeprecationLevel
|
public final val level: kotlin.DeprecationLevel
|
||||||
|
|||||||
@@ -203,6 +203,12 @@ public interface Comparable</*0*/ in T> {
|
|||||||
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
public abstract operator fun compareTo(/*0*/ other: T): kotlin.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) @kotlin.annotation.MustBeDocumented public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
/*primary*/ public constructor ContextFunctionTypeParams(/*0*/ count: kotlin.Int)
|
||||||
|
public final val count: kotlin.Int
|
||||||
|
public final fun <get-count>(): kotlin.Int
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.MustBeDocumented public final annotation class Deprecated : kotlin.Annotation {
|
||||||
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
/*primary*/ public constructor Deprecated(/*0*/ message: kotlin.String, /*1*/ replaceWith: kotlin.ReplaceWith = ..., /*2*/ level: kotlin.DeprecationLevel = ...)
|
||||||
public final val level: kotlin.DeprecationLevel
|
public final val level: kotlin.DeprecationLevel
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
|
||||||
|
class Button
|
||||||
|
class ClickEvent
|
||||||
|
|
||||||
|
typealias ClickHandler = context(Button) (ClickEvent) -> Unit
|
||||||
|
|
||||||
|
fun handleClick(clickHandler: ClickHandler) {
|
||||||
|
clickHandler(Button(), ClickEvent())
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun handleClick(/*0*/ clickHandler: ClickHandler /* = @kotlin.ContextFunctionTypeParams(count = 1) (ClickEvent) -> kotlin.Unit */): kotlin.Unit
|
||||||
|
|
||||||
|
public final class Button {
|
||||||
|
public constructor Button()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class ClickEvent {
|
||||||
|
public constructor ClickEvent()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
public typealias ClickHandler = @kotlin.ContextFunctionTypeParams(count = 1) (ClickEvent) -> kotlin.Unit
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE
|
||||||
|
|
||||||
|
class Context
|
||||||
|
class Receiver
|
||||||
|
class Param
|
||||||
|
|
||||||
|
fun foo(context: Context, receiver: Receiver, p: Param) {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
fun bar(receiver: Receiver, p: Param) {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
fun Receiver.baz(p: Param) {}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
var g: context(Context) Receiver.(Param) -> Unit
|
||||||
|
g = ::<!UNRESOLVED_REFERENCE!>foo<!> // OK
|
||||||
|
g = ::bar // OK
|
||||||
|
g = Receiver::baz // OK
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// !DIAGNOSTICS: -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE
|
||||||
|
|
||||||
|
class Context
|
||||||
|
class Receiver
|
||||||
|
class Param
|
||||||
|
|
||||||
|
fun foo(context: Context, receiver: Receiver, p: Param) {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
fun bar(receiver: Receiver, p: Param) {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
fun Receiver.baz(p: Param) {}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
var g: context(Context) Receiver.(Param) -> Unit
|
||||||
|
g = ::foo // OK
|
||||||
|
g = ::bar // OK
|
||||||
|
g = Receiver::baz // OK
|
||||||
|
}
|
||||||
Vendored
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun bar(/*0*/ receiver: Receiver, /*1*/ p: Param): kotlin.Unit
|
||||||
|
public fun foo(/*0*/ context: Context, /*1*/ receiver: Receiver, /*2*/ p: Param): kotlin.Unit
|
||||||
|
public fun main(): kotlin.Unit
|
||||||
|
public fun Receiver.baz(/*0*/ p: Param): kotlin.Unit
|
||||||
|
|
||||||
|
public final class Context {
|
||||||
|
public constructor Context()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Param {
|
||||||
|
public constructor Param()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Receiver {
|
||||||
|
public constructor Receiver()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
class Param
|
||||||
|
class C
|
||||||
|
class R
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun R.f1(g: context(C) R.(Param) -> Unit) {
|
||||||
|
g(this@C, this@R, Param())
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun f2(g: context(C) (Param) -> Unit) {
|
||||||
|
g(this@C, Param())
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun R.f3(g: context(C) R.() -> Unit) {
|
||||||
|
g(this@C, this@R)
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun f4(g: context(C) () -> Unit) {
|
||||||
|
g(this@C)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val lf1: context(C) R.(Param) -> Unit = { _ -> }
|
||||||
|
val lf2: context(C) (Param) -> Unit = { _ -> }
|
||||||
|
val lf3: context(C) R.() -> Unit = { }
|
||||||
|
val lf4: context(C) () -> Unit = { }
|
||||||
|
|
||||||
|
with(C()) {
|
||||||
|
with(R()) {
|
||||||
|
f1(lf1)
|
||||||
|
f2(lf2)
|
||||||
|
f3(lf3)
|
||||||
|
f4(lf4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
class Param
|
||||||
|
class C
|
||||||
|
class R
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun R.f1(g: context(C) R.(Param) -> Unit) {
|
||||||
|
g(this@C, this@R, Param())
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun f2(g: context(C) (Param) -> Unit) {
|
||||||
|
g(this@C, Param())
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun R.f3(g: context(C) R.() -> Unit) {
|
||||||
|
g(this@C, this@R)
|
||||||
|
}
|
||||||
|
|
||||||
|
context(C)
|
||||||
|
fun f4(g: context(C) () -> Unit) {
|
||||||
|
g(this@C)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val lf1: context(C) R.(Param) -> Unit = { _ -> }
|
||||||
|
val lf2: context(C) (Param) -> Unit = { _ -> }
|
||||||
|
val lf3: context(C) R.() -> Unit = { }
|
||||||
|
val lf4: context(C) () -> Unit = { }
|
||||||
|
|
||||||
|
with(C()) {
|
||||||
|
with(R()) {
|
||||||
|
f1(lf1)
|
||||||
|
f2(lf2)
|
||||||
|
f3(lf3)
|
||||||
|
f4(lf4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f2(/*0*/ g: @kotlin.ContextFunctionTypeParams(count = 1) (Param) -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun f4(/*0*/ g: @kotlin.ContextFunctionTypeParams(count = 1) () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
public fun R.f1(/*0*/ g: @kotlin.ContextFunctionTypeParams(count = 1) (R.(Param) -> kotlin.Unit)): kotlin.Unit
|
||||||
|
public fun R.f3(/*0*/ g: @kotlin.ContextFunctionTypeParams(count = 1) (R.() -> kotlin.Unit)): kotlin.Unit
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
public constructor C()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Param {
|
||||||
|
public constructor Param()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class R {
|
||||||
|
public constructor R()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Generated
+28
@@ -10594,6 +10594,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/functionalType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("genericOuterClass.kt")
|
@TestMetadata("genericOuterClass.kt")
|
||||||
public void testGenericOuterClass() throws Exception {
|
public void testGenericOuterClass() throws Exception {
|
||||||
@@ -10725,6 +10731,28 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
public void testWithExplicitReceiverError() throws Exception {
|
public void testWithExplicitReceiverError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class FromKEEP {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInFromKEEP() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("clickHandler.kt")
|
||||||
|
public void testClickHandler() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/clickHandler.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("functionalType.kt")
|
||||||
|
public void testFunctionalType() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/fromKEEP/functionalType.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ public enum class DeprecationLevel {
|
|||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
public annotation class ExtensionFunctionType
|
public annotation class ExtensionFunctionType
|
||||||
|
|
||||||
|
// TODO: How to make it require opt-in? @RequiresOptIn doesn't support TYPE target
|
||||||
|
@Target(TYPE)
|
||||||
|
@MustBeDocumented
|
||||||
|
public annotation class ContextFunctionTypeParams(val count: Int)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotates type arguments of functional type and holds corresponding parameter name specified by the user in type declaration (if any).
|
* Annotates type arguments of functional type and holds corresponding parameter name specified by the user in type declaration (if any).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ object StandardNames {
|
|||||||
@JvmField val deprecationLevel: FqName = fqName("DeprecationLevel")
|
@JvmField val deprecationLevel: FqName = fqName("DeprecationLevel")
|
||||||
@JvmField val replaceWith: FqName = fqName("ReplaceWith")
|
@JvmField val replaceWith: FqName = fqName("ReplaceWith")
|
||||||
@JvmField val extensionFunctionType: FqName = fqName("ExtensionFunctionType")
|
@JvmField val extensionFunctionType: FqName = fqName("ExtensionFunctionType")
|
||||||
|
@JvmField val contextFunctionTypeParams: FqName = fqName("ContextFunctionTypeParams")
|
||||||
@JvmField val parameterName: FqName = fqName("ParameterName")
|
@JvmField val parameterName: FqName = fqName("ParameterName")
|
||||||
@JvmField val parameterNameClassId: ClassId = ClassId.topLevel(parameterName)
|
@JvmField val parameterNameClassId: ClassId = ClassId.topLevel(parameterName)
|
||||||
@JvmField val annotation: FqName = fqName("Annotation")
|
@JvmField val annotation: FqName = fqName("Annotation")
|
||||||
|
|||||||
@@ -58,13 +58,15 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
|
|||||||
fun getKFunctionType(
|
fun getKFunctionType(
|
||||||
annotations: Annotations,
|
annotations: Annotations,
|
||||||
receiverType: KotlinType?,
|
receiverType: KotlinType?,
|
||||||
|
contextReceiverTypes: List<KotlinType>,
|
||||||
parameterTypes: List<KotlinType>,
|
parameterTypes: List<KotlinType>,
|
||||||
parameterNames: List<Name>?,
|
parameterNames: List<Name>?,
|
||||||
returnType: KotlinType,
|
returnType: KotlinType,
|
||||||
builtIns: KotlinBuiltIns,
|
builtIns: KotlinBuiltIns,
|
||||||
isSuspend: Boolean
|
isSuspend: Boolean
|
||||||
): SimpleType {
|
): SimpleType {
|
||||||
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, parameterNames, returnType, builtIns)
|
val arguments =
|
||||||
|
getFunctionTypeArgumentProjections(receiverType, contextReceiverTypes, parameterTypes, parameterNames, returnType, builtIns)
|
||||||
val classDescriptor =
|
val classDescriptor =
|
||||||
if (isSuspend) getKSuspendFunction(arguments.size - 1 /* return type */) else getKFunction(arguments.size - 1 /* return type */)
|
if (isSuspend) getKSuspendFunction(arguments.size - 1 /* return type */) else getKFunction(arguments.size - 1 /* return type */)
|
||||||
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
|
return KotlinTypeFactory.simpleNotNullType(annotations, classDescriptor, arguments)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.builtins
|
package org.jetbrains.kotlin.builtins
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_NAME
|
import org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_NAME
|
||||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
@@ -16,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations
|
|||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
@@ -128,10 +128,29 @@ private fun FqNameUnsafe.getFunctionalClassKind(): FunctionClassKind? {
|
|||||||
return FunctionClassKind.getFunctionalClassKind(shortName().asString(), toSafe().parent())
|
return FunctionClassKind.getFunctionalClassKind(shortName().asString(), toSafe().parent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KotlinType.contextFunctionTypeParamsCount(): Int {
|
||||||
|
val annotationDescriptor = annotations.findAnnotation(StandardNames.FqNames.contextFunctionTypeParams) ?: return 0
|
||||||
|
val constantValue = annotationDescriptor.allValueArguments.getValue(Name.identifier("count"))
|
||||||
|
return (constantValue as IntValue).value
|
||||||
|
}
|
||||||
|
|
||||||
fun KotlinType.getReceiverTypeFromFunctionType(): KotlinType? {
|
fun KotlinType.getReceiverTypeFromFunctionType(): KotlinType? {
|
||||||
assert(isBuiltinFunctionalType) { "Not a function type: $this" }
|
assert(isBuiltinFunctionalType) { "Not a function type: $this" }
|
||||||
return if (isTypeAnnotatedWithExtensionFunctionType) arguments.first().type else null
|
if (!isTypeAnnotatedWithExtensionFunctionType) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val index = contextFunctionTypeParamsCount()
|
||||||
|
return arguments[index].type
|
||||||
|
}
|
||||||
|
|
||||||
|
fun KotlinType.getContextReceiverTypesFromFunctionType(): List<KotlinType> {
|
||||||
|
assert(isBuiltinFunctionalType) { "Not a function type: $this" }
|
||||||
|
val contextReceiversCount = contextFunctionTypeParamsCount()
|
||||||
|
return if (contextReceiversCount == 0) {
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
arguments.subList(0, contextReceiversCount).map { it.type }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KotlinType.getReturnTypeFromFunctionType(): KotlinType {
|
fun KotlinType.getReturnTypeFromFunctionType(): KotlinType {
|
||||||
@@ -148,7 +167,7 @@ fun KotlinType.replaceReturnType(newReturnType: KotlinType): KotlinType {
|
|||||||
fun KotlinType.getValueParameterTypesFromFunctionType(): List<TypeProjection> {
|
fun KotlinType.getValueParameterTypesFromFunctionType(): List<TypeProjection> {
|
||||||
assert(isBuiltinFunctionalType) { "Not a function type: $this" }
|
assert(isBuiltinFunctionalType) { "Not a function type: $this" }
|
||||||
val arguments = arguments
|
val arguments = arguments
|
||||||
val first = if (isBuiltinExtensionFunctionalType) 1 else 0
|
val first = contextFunctionTypeParamsCount() + if (isBuiltinExtensionFunctionalType) 1 else 0
|
||||||
val last = arguments.size - 1
|
val last = arguments.size - 1
|
||||||
assert(first <= last) { "Not an exact function type: $this" }
|
assert(first <= last) { "Not an exact function type: $this" }
|
||||||
return arguments.subList(first, last)
|
return arguments.subList(first, last)
|
||||||
@@ -183,14 +202,16 @@ fun KotlinType.extractParameterNameFromFunctionTypeArgument(): Name? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getFunctionTypeArgumentProjections(
|
fun getFunctionTypeArgumentProjections(
|
||||||
receiverType: KotlinType?,
|
receiverType: KotlinType?,
|
||||||
parameterTypes: List<KotlinType>,
|
contextReceiverTypes: List<KotlinType>,
|
||||||
parameterNames: List<Name>?,
|
parameterTypes: List<KotlinType>,
|
||||||
returnType: KotlinType,
|
parameterNames: List<Name>?,
|
||||||
builtIns: KotlinBuiltIns
|
returnType: KotlinType,
|
||||||
|
builtIns: KotlinBuiltIns
|
||||||
): List<TypeProjection> {
|
): List<TypeProjection> {
|
||||||
val arguments = ArrayList<TypeProjection>(parameterTypes.size + (if (receiverType != null) 1 else 0) + 1)
|
val arguments = ArrayList<TypeProjection>(parameterTypes.size + contextReceiverTypes.size + (if (receiverType != null) 1 else 0) + 1)
|
||||||
|
|
||||||
|
arguments.addAll(contextReceiverTypes.map { it.asTypeProjection() })
|
||||||
arguments.addIfNotNull(receiverType?.asTypeProjection())
|
arguments.addIfNotNull(receiverType?.asTypeProjection())
|
||||||
|
|
||||||
parameterTypes.mapIndexedTo(arguments) { index, type ->
|
parameterTypes.mapIndexedTo(arguments) { index, type ->
|
||||||
@@ -219,17 +240,22 @@ fun createFunctionType(
|
|||||||
builtIns: KotlinBuiltIns,
|
builtIns: KotlinBuiltIns,
|
||||||
annotations: Annotations,
|
annotations: Annotations,
|
||||||
receiverType: KotlinType?,
|
receiverType: KotlinType?,
|
||||||
|
contextReceiverTypes: List<KotlinType>,
|
||||||
parameterTypes: List<KotlinType>,
|
parameterTypes: List<KotlinType>,
|
||||||
parameterNames: List<Name>?,
|
parameterNames: List<Name>?,
|
||||||
returnType: KotlinType,
|
returnType: KotlinType,
|
||||||
suspendFunction: Boolean = false
|
suspendFunction: Boolean = false
|
||||||
): SimpleType {
|
): SimpleType {
|
||||||
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, parameterNames, returnType, builtIns)
|
val arguments =
|
||||||
val parameterCount = if (receiverType == null) parameterTypes.size else parameterTypes.size + 1
|
getFunctionTypeArgumentProjections(receiverType, contextReceiverTypes, parameterTypes, parameterNames, returnType, builtIns)
|
||||||
|
val parameterCount = parameterTypes.size + contextReceiverTypes.size + if (receiverType == null) 0 else 1
|
||||||
val classDescriptor = getFunctionDescriptor(builtIns, parameterCount, suspendFunction)
|
val classDescriptor = getFunctionDescriptor(builtIns, parameterCount, suspendFunction)
|
||||||
|
|
||||||
// TODO: preserve laziness of given annotations
|
// TODO: preserve laziness of given annotations
|
||||||
val typeAnnotations = if (receiverType != null) annotations.withExtensionFunctionAnnotation(builtIns) else annotations
|
var typeAnnotations = annotations
|
||||||
|
if (receiverType != null) typeAnnotations = typeAnnotations.withExtensionFunctionAnnotation(builtIns)
|
||||||
|
if (contextReceiverTypes.isNotEmpty()) typeAnnotations =
|
||||||
|
typeAnnotations.withContextReceiversFunctionAnnotation(builtIns, contextReceiverTypes.size)
|
||||||
|
|
||||||
return KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
|
return KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
|
||||||
}
|
}
|
||||||
@@ -246,6 +272,19 @@ fun Annotations.withExtensionFunctionAnnotation(builtIns: KotlinBuiltIns) =
|
|||||||
Annotations.create(this + BuiltInAnnotationDescriptor(builtIns, StandardNames.FqNames.extensionFunctionType, emptyMap()))
|
Annotations.create(this + BuiltInAnnotationDescriptor(builtIns, StandardNames.FqNames.extensionFunctionType, emptyMap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Annotations.withContextReceiversFunctionAnnotation(builtIns: KotlinBuiltIns, contextReceiversCount: Int) =
|
||||||
|
if (hasAnnotation(StandardNames.FqNames.contextFunctionTypeParams)) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
Annotations.create(
|
||||||
|
this + BuiltInAnnotationDescriptor(
|
||||||
|
builtIns, StandardNames.FqNames.contextFunctionTypeParams, mapOf(
|
||||||
|
Name.identifier("count") to IntValue(contextReceiversCount)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun getFunctionDescriptor(builtIns: KotlinBuiltIns, parameterCount: Int, isSuspendFunction: Boolean) =
|
fun getFunctionDescriptor(builtIns: KotlinBuiltIns, parameterCount: Int, isSuspendFunction: Boolean) =
|
||||||
if (isSuspendFunction) builtIns.getSuspendFunction(parameterCount) else builtIns.getFunction(parameterCount)
|
if (isSuspendFunction) builtIns.getSuspendFunction(parameterCount) else builtIns.getFunction(parameterCount)
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,11 @@ fun transformSuspendFunctionToRuntimeFunctionType(suspendFunType: KotlinType): S
|
|||||||
}
|
}
|
||||||
|
|
||||||
return createFunctionType(
|
return createFunctionType(
|
||||||
suspendFunType.builtIns,
|
suspendFunType.builtIns,
|
||||||
suspendFunType.annotations,
|
suspendFunType.annotations,
|
||||||
suspendFunType.getReceiverTypeFromFunctionType(),
|
suspendFunType.getReceiverTypeFromFunctionType(),
|
||||||
suspendFunType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType) +
|
suspendFunType.getContextReceiverTypesFromFunctionType(),
|
||||||
|
suspendFunType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType) +
|
||||||
KotlinTypeFactory.simpleType(
|
KotlinTypeFactory.simpleType(
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
// Continuation interface is not a part of built-ins anymore, it has been moved to stdlib.
|
// Continuation interface is not a part of built-ins anymore, it has been moved to stdlib.
|
||||||
|
|||||||
@@ -76,14 +76,15 @@ fun getFunctionTypeForAbstractMethod(
|
|||||||
val parameterTypes = ArrayList<KotlinType>(valueParameters.size)
|
val parameterTypes = ArrayList<KotlinType>(valueParameters.size)
|
||||||
val parameterNames = ArrayList<Name>(valueParameters.size)
|
val parameterNames = ArrayList<Name>(valueParameters.size)
|
||||||
|
|
||||||
var startIndex = 0
|
val contextReceiversTypes = function.contextReceiverParameters.map { it.type }
|
||||||
|
var startIndex = contextReceiversTypes.size
|
||||||
var receiverType: KotlinType? = null
|
var receiverType: KotlinType? = null
|
||||||
val extensionReceiver = function.extensionReceiverParameter
|
val extensionReceiver = function.extensionReceiverParameter
|
||||||
if (extensionReceiver != null) {
|
if (extensionReceiver != null) {
|
||||||
receiverType = extensionReceiver.type
|
receiverType = extensionReceiver.type
|
||||||
} else if (shouldConvertFirstParameterToDescriptor && function.valueParameters.isNotEmpty()) {
|
} else if (shouldConvertFirstParameterToDescriptor && function.valueParameters.isNotEmpty()) {
|
||||||
receiverType = valueParameters[0].type
|
receiverType = valueParameters[0].type
|
||||||
startIndex = 1
|
startIndex += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in startIndex until valueParameters.size) {
|
for (i in startIndex until valueParameters.size) {
|
||||||
@@ -93,7 +94,7 @@ fun getFunctionTypeForAbstractMethod(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return createFunctionType(
|
return createFunctionType(
|
||||||
function.builtIns, EMPTY, receiverType, parameterTypes,
|
function.builtIns, EMPTY, receiverType, contextReceiversTypes, parameterTypes,
|
||||||
parameterNames, returnType, function.isSuspend
|
parameterNames, returnType, function.isSuspend
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -226,6 +226,7 @@ class TypeDeserializer(
|
|||||||
funType.builtIns,
|
funType.builtIns,
|
||||||
funType.annotations,
|
funType.annotations,
|
||||||
funType.getReceiverTypeFromFunctionType(),
|
funType.getReceiverTypeFromFunctionType(),
|
||||||
|
funType.getContextReceiverTypesFromFunctionType(),
|
||||||
funType.getValueParameterTypesFromFunctionType().dropLast(1).map(TypeProjection::getType),
|
funType.getValueParameterTypesFromFunctionType().dropLast(1).map(TypeProjection::getType),
|
||||||
// TODO: names
|
// TODO: names
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -1187,6 +1187,14 @@ public open class ConcurrentModificationException : kotlin.RuntimeException {
|
|||||||
public constructor ConcurrentModificationException(cause: kotlin.Throwable?)
|
public constructor ConcurrentModificationException(cause: kotlin.Throwable?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE})
|
||||||
|
@kotlin.annotation.MustBeDocumented
|
||||||
|
public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
public constructor ContextFunctionTypeParams(count: kotlin.Int)
|
||||||
|
|
||||||
|
public final val count: kotlin.Int { get; }
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.SinceKotlin(version = "1.4")
|
@kotlin.SinceKotlin(version = "1.4")
|
||||||
@kotlin.ExperimentalStdlibApi
|
@kotlin.ExperimentalStdlibApi
|
||||||
public final class DeepRecursiveFunction<T, R> {
|
public final class DeepRecursiveFunction<T, R> {
|
||||||
|
|||||||
@@ -1158,6 +1158,14 @@ public open class ConcurrentModificationException : kotlin.RuntimeException {
|
|||||||
public constructor ConcurrentModificationException(cause: kotlin.Throwable?)
|
public constructor ConcurrentModificationException(cause: kotlin.Throwable?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE})
|
||||||
|
@kotlin.annotation.MustBeDocumented
|
||||||
|
public final annotation class ContextFunctionTypeParams : kotlin.Annotation {
|
||||||
|
public constructor ContextFunctionTypeParams(count: kotlin.Int)
|
||||||
|
|
||||||
|
public final val count: kotlin.Int { get; }
|
||||||
|
}
|
||||||
|
|
||||||
@kotlin.SinceKotlin(version = "1.4")
|
@kotlin.SinceKotlin(version = "1.4")
|
||||||
@kotlin.ExperimentalStdlibApi
|
@kotlin.ExperimentalStdlibApi
|
||||||
public final class DeepRecursiveFunction<T, R> {
|
public final class DeepRecursiveFunction<T, R> {
|
||||||
|
|||||||
+4
@@ -1,6 +1,10 @@
|
|||||||
public abstract interface annotation class kotlin/BuilderInference : java/lang/annotation/Annotation {
|
public abstract interface annotation class kotlin/BuilderInference : java/lang/annotation/Annotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract interface annotation class kotlin/ContextFunctionTypeParams : java/lang/annotation/Annotation {
|
||||||
|
public abstract fun count ()I
|
||||||
|
}
|
||||||
|
|
||||||
public final class kotlin/DeepRecursiveFunction {
|
public final class kotlin/DeepRecursiveFunction {
|
||||||
public fun <init> (Lkotlin/jvm/functions/Function3;)V
|
public fun <init> (Lkotlin/jvm/functions/Function3;)V
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user