FIC: Add synthetic constructors for fun interfaces aka explicit FIC

This commit is contained in:
Mikhail Zarechenskiy
2019-11-15 13:07:18 +03:00
parent 0f242a9931
commit fc32e8b017
9 changed files with 66 additions and 17 deletions
@@ -7824,6 +7824,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt");
} }
@TestMetadata("funInterfaceSyntheticConstructors.kt")
public void testFunInterfaceSyntheticConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/funInterfaceSyntheticConstructors.kt");
}
@TestMetadata("genericSubstitutionForFunInterface.kt") @TestMetadata("genericSubstitutionForFunInterface.kt")
public void testGenericSubstitutionForFunInterface() throws Exception { public void testGenericSubstitutionForFunInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt");
@@ -17,18 +17,18 @@
package org.jetbrains.kotlin.load.java.sam package org.jetbrains.kotlin.load.java.sam
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
interface SamConstructorDescriptor : SimpleFunctionDescriptor, SyntheticMemberDescriptor<JavaClassDescriptor> interface SamConstructorDescriptor : SimpleFunctionDescriptor, SyntheticMemberDescriptor<ClassDescriptor>
class SamConstructorDescriptorImpl( class SamConstructorDescriptorImpl(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
private val samInterface: JavaClassDescriptor private val samInterface: ClassDescriptor
) : SimpleFunctionDescriptorImpl( ) : SimpleFunctionDescriptorImpl(
containingDeclaration, containingDeclaration,
null, null,
@@ -37,7 +37,7 @@ class SamConstructorDescriptorImpl(
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
samInterface.source samInterface.source
), SamConstructorDescriptor { ), SamConstructorDescriptor {
override val baseDescriptorForSynthetic: JavaClassDescriptor override val baseDescriptorForSynthetic: ClassDescriptor
get() = samInterface get() = samInterface
} }
@@ -16,12 +16,8 @@
package org.jetbrains.kotlin.load.java.sam package org.jetbrains.kotlin.load.java.sam
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithNavigationSubstitute
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
interface SamTypeAliasConstructorDescriptor : SamConstructorDescriptor, DeclarationDescriptorWithNavigationSubstitute { interface SamTypeAliasConstructorDescriptor : SamConstructorDescriptor, DeclarationDescriptorWithNavigationSubstitute {
val typeAliasDescriptor: TypeAliasDescriptor val typeAliasDescriptor: TypeAliasDescriptor
@@ -41,6 +37,6 @@ class SamTypeAliasConstructorDescriptorImpl(
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
typeAliasDescriptor.source typeAliasDescriptor.source
), SamTypeAliasConstructorDescriptor { ), SamTypeAliasConstructorDescriptor {
override val baseDescriptorForSynthetic: JavaClassDescriptor override val baseDescriptorForSynthetic: ClassDescriptor
get() = samInterfaceConstructorDescriptor.baseDescriptorForSynthetic get() = samInterfaceConstructorDescriptor.baseDescriptorForSynthetic
} }
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.SamConversionResolver;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames; import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -167,7 +168,7 @@ public class SingleAbstractMethodUtils {
@NotNull @NotNull
public static SamConstructorDescriptor createSamConstructorFunction( public static SamConstructorDescriptor createSamConstructorFunction(
@NotNull DeclarationDescriptor owner, @NotNull DeclarationDescriptor owner,
@NotNull JavaClassDescriptor samInterface, @NotNull ClassDescriptor samInterface,
@NotNull SamConversionResolver samResolver @NotNull SamConversionResolver samResolver
) { ) {
assert getSingleAbstractMethodOrNull(samInterface) != null : samInterface; assert getSingleAbstractMethodOrNull(samInterface) != null : samInterface;
@@ -182,7 +183,7 @@ public class SingleAbstractMethodUtils {
} }
private static void initializeSamConstructorDescriptor( private static void initializeSamConstructorDescriptor(
@NotNull JavaClassDescriptor samInterface, @NotNull ClassDescriptor samInterface,
@NotNull SimpleFunctionDescriptorImpl samConstructor, @NotNull SimpleFunctionDescriptorImpl samConstructor,
@NotNull List<TypeParameterDescriptor> samTypeParameters, @NotNull List<TypeParameterDescriptor> samTypeParameters,
@NotNull KotlinType unsubstitutedSamType, @NotNull KotlinType unsubstitutedSamType,
@@ -224,7 +225,7 @@ public class SingleAbstractMethodUtils {
) { ) {
SamTypeAliasConstructorDescriptorImpl result = new SamTypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingSamConstructor); SamTypeAliasConstructorDescriptorImpl result = new SamTypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingSamConstructor);
JavaClassDescriptor samInterface = underlyingSamConstructor.getBaseDescriptorForSynthetic(); ClassDescriptor samInterface = underlyingSamConstructor.getBaseDescriptorForSynthetic();
List<TypeParameterDescriptor> samTypeParameters = typeAliasDescriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> samTypeParameters = typeAliasDescriptor.getTypeConstructor().getParameters();
SimpleType unsubstitutedSamType = typeAliasDescriptor.getExpandedType(); SimpleType unsubstitutedSamType = typeAliasDescriptor.getExpandedType();
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver); initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver);
@@ -232,6 +233,15 @@ public class SingleAbstractMethodUtils {
return result; return result;
} }
public static boolean isSamClassDescriptor(@NotNull ClassDescriptor descriptor) {
if (descriptor.isFun()) return true;
if (descriptor instanceof LazyJavaClassDescriptor &&
((LazyJavaClassDescriptor) descriptor).getDefaultFunctionTypeForSamInterface() != null
) return true;
return false;
}
public static boolean isSamType(@NotNull KotlinType type) { public static boolean isSamType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).isFun()) return true; if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).isFun()) return true;
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.SamConversionResolver
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
@@ -73,7 +72,7 @@ class SamAdapterFunctionsScope(
} }
private val samConstructorForClassifier = private val samConstructorForClassifier =
storageManager.createMemoizedFunction<JavaClassDescriptor, SamConstructorDescriptor> { classifier -> storageManager.createMemoizedFunction<ClassDescriptor, SamConstructorDescriptor> { classifier ->
SingleAbstractMethodUtils.createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver) SingleAbstractMethodUtils.createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver)
} }
@@ -259,13 +258,15 @@ class SamAdapterFunctionsScope(
return getTypeAliasSamConstructor(classifier) return getTypeAliasSamConstructor(classifier)
} }
if (classifier !is LazyJavaClassDescriptor || classifier.defaultFunctionTypeForSamInterface == null) return null if (classifier !is ClassDescriptor) return null
if (!SingleAbstractMethodUtils.isSamClassDescriptor(classifier)) return null
return samConstructorForClassifier(classifier) return samConstructorForClassifier(classifier)
} }
private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? { private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? {
val classDescriptor = classifier.classDescriptor ?: return null val classDescriptor = classifier.classDescriptor ?: return null
if (classDescriptor !is LazyJavaClassDescriptor || classDescriptor.defaultFunctionTypeForSamInterface == null) return null if (!SingleAbstractMethodUtils.isSamClassDescriptor(classDescriptor)) return null
return SingleAbstractMethodUtils.createTypeAliasSamConstructorFunction( return SingleAbstractMethodUtils.createTypeAliasSamConstructorFunction(
classifier, samConstructorForClassifier(classDescriptor), samResolver) classifier, samConstructorForClassifier(classDescriptor), samResolver)
@@ -0,0 +1,15 @@
// !LANGUAGE: +NewInference +SamConversionForKotlinFunctions +SamConversionPerArgument +FunctionInterfaceConversion
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun interface KRunnable {
fun invoke()
}
typealias KRunnableAlias = KRunnable
fun foo(f: KRunnable) {}
fun test() {
foo(KRunnable {})
foo(KRunnableAlias {})
}
@@ -0,0 +1,12 @@
package
public fun foo(/*0*/ f: KRunnable): kotlin.Unit
public fun test(): kotlin.Unit
public 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 invoke(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public typealias KRunnableAlias = KRunnable
@@ -7906,6 +7906,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt");
} }
@TestMetadata("funInterfaceSyntheticConstructors.kt")
public void testFunInterfaceSyntheticConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/funInterfaceSyntheticConstructors.kt");
}
@TestMetadata("genericSubstitutionForFunInterface.kt") @TestMetadata("genericSubstitutionForFunInterface.kt")
public void testGenericSubstitutionForFunInterface() throws Exception { public void testGenericSubstitutionForFunInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt");
@@ -7901,6 +7901,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/basicFunInterfaceDisabled.kt");
} }
@TestMetadata("funInterfaceSyntheticConstructors.kt")
public void testFunInterfaceSyntheticConstructors() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/funInterfaceSyntheticConstructors.kt");
}
@TestMetadata("genericSubstitutionForFunInterface.kt") @TestMetadata("genericSubstitutionForFunInterface.kt")
public void testGenericSubstitutionForFunInterface() throws Exception { public void testGenericSubstitutionForFunInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt"); runTest("compiler/testData/diagnostics/tests/funInterface/genericSubstitutionForFunInterface.kt");