[FE][PSI2IR] Generalized SamType
Operations regarding <fun interface> are common for all backends
This commit is contained in:
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.SimpleType;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
|
||||
@@ -92,6 +92,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker;
|
||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker;
|
||||
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.backend.common.SamTypeFactory
|
||||
|
||||
object JvmSamTypeFactory : SamTypeFactory() {
|
||||
override fun isSamType(type: KotlinType) = JavaSingleAbstractMethodUtils.isSamType(type)
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils;
|
||||
import org.jetbrains.kotlin.resolve.sam.SamConversionResolverImplKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.KotlinTypeKt;
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||
|
||||
public class SamType {
|
||||
@Nullable
|
||||
public static SamType createByValueParameter(@NotNull ValueParameterDescriptor valueParameter) {
|
||||
KotlinType singleArgumentType;
|
||||
KotlinType originalSingleArgumentType;
|
||||
KotlinType varargElementType = valueParameter.getVarargElementType();
|
||||
if (varargElementType != null) {
|
||||
singleArgumentType = varargElementType;
|
||||
originalSingleArgumentType = valueParameter.getOriginal().getVarargElementType();
|
||||
assert originalSingleArgumentType != null :
|
||||
"Value parameter and original value parameter have inconsistent varargs: " +
|
||||
valueParameter + "; " + valueParameter.getOriginal();
|
||||
} else {
|
||||
singleArgumentType = valueParameter.getType();
|
||||
originalSingleArgumentType = valueParameter.getOriginal().getType();
|
||||
}
|
||||
|
||||
if (KotlinTypeKt.isError(singleArgumentType) || KotlinTypeKt.isError(originalSingleArgumentType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
KotlinType originalTypeToUse =
|
||||
// This can be true in case when the value parameter is in the method of a generic type with out-projection.
|
||||
// We approximate Inv<Captured#1> to Nothing, while Inv itself can be a SAM interface safe to call here
|
||||
// (see testData genericSamProjectedOut.kt for details)
|
||||
KotlinBuiltIns.isNothing(singleArgumentType)
|
||||
// In such a case we can't have a proper supertype since wildcards are not allowed there,
|
||||
// so we use Nothing arguments instead that leads to a raw type used for a SAM wrapper.
|
||||
// See org.jetbrains.kotlin.codegen.state.KotlinTypeMapper#writeGenericType to understand how
|
||||
// raw types and Nothing arguments relate.
|
||||
? TypeUtilsKt.replaceArgumentsWithNothing(originalSingleArgumentType)
|
||||
: singleArgumentType;
|
||||
|
||||
return create(TypeMapperUtilsKt.removeExternalProjections(originalTypeToUse));
|
||||
}
|
||||
public static SamType create(@NotNull KotlinType originalType) {
|
||||
if (!JavaSingleAbstractMethodUtils.isSamType(originalType)) return null;
|
||||
return new SamType(originalType);
|
||||
}
|
||||
|
||||
private final KotlinType type;
|
||||
|
||||
private SamType(@NotNull KotlinType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassDescriptor getClassDescriptor() {
|
||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||
assert classifier instanceof ClassDescriptor : "Sam/Fun interface not a class descriptor: " + classifier;
|
||||
return (ClassDescriptor) classifier;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinType getKotlinFunctionType() {
|
||||
ClassDescriptor descriptor = getClassDescriptor();
|
||||
//noinspection ConstantConditions
|
||||
return descriptor.getDefaultFunctionTypeForSamInterface();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SimpleFunctionDescriptor getOriginalAbstractMethod() {
|
||||
return (SimpleFunctionDescriptor) SamConversionResolverImplKt.getAbstractMembers(getClassDescriptor()).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof SamType && type.equals(((SamType) o).type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return type.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SamType(" + type + ")";
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.kotlin.backend.common.SamType
|
||||
|
||||
class SamWrapperClasses(private val state: GenerationState) {
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
|
||||
+6
-5
@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -861,7 +862,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
if (valueArguments == null) return;
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : valueParametersWithSAMConversion) {
|
||||
SamType samType = SamType.createByValueParameter(valueParameter);
|
||||
SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter);
|
||||
if (samType == null) continue;
|
||||
|
||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
|
||||
@@ -873,7 +874,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
}
|
||||
|
||||
private void recordSamTypeOnArgumentExpression(ValueParameterDescriptor valueParameter, ValueArgument valueArgument) {
|
||||
SamType samType = SamType.createByValueParameter(valueParameter);
|
||||
SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter);
|
||||
if (samType == null) return;
|
||||
|
||||
recordSamTypeOnArgumentExpression(samType, valueArgument);
|
||||
@@ -955,7 +956,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
bindingTrace.record(SAM_CONSTRUCTOR_TO_ARGUMENT, expression, argumentExpression);
|
||||
|
||||
//noinspection ConstantConditions
|
||||
SamType samType = SamType.create(callableDescriptor.getReturnType());
|
||||
SamType samType = JvmSamTypeFactory.INSTANCE.create(callableDescriptor.getReturnType());
|
||||
bindingTrace.record(SAM_VALUE, argumentExpression, samType);
|
||||
}
|
||||
|
||||
@@ -972,7 +973,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) operationDescriptor);
|
||||
if (original == null) return;
|
||||
|
||||
SamType samType = SamType.createByValueParameter(original.getValueParameters().get(0));
|
||||
SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(original.getValueParameters().get(0));
|
||||
if (samType == null) return;
|
||||
|
||||
IElementType token = expression.getOperationToken();
|
||||
@@ -1001,7 +1002,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
|
||||
List<KtExpression> indexExpressions = expression.getIndexExpressions();
|
||||
List<ValueParameterDescriptor> parameters = original.getValueParameters();
|
||||
for (ValueParameterDescriptor valueParameter : parameters) {
|
||||
SamType samType = SamType.createByValueParameter(valueParameter);
|
||||
SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter);
|
||||
if (samType == null) continue;
|
||||
|
||||
if (isSetter && valueParameter.getIndex() == parameters.size() - 1) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.SamType;
|
||||
import org.jetbrains.kotlin.backend.common.SamType;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.backend.common.SamType
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
@@ -75,6 +75,7 @@ import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
|
||||
import org.jetbrains.kotlin.types.checker.convertVariance
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.backend.common.SamType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
Reference in New Issue
Block a user