SAM constructors for type aliases.
This commit is contained in:
+34
-8
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.*;
|
||||
@@ -134,28 +135,41 @@ public class SingleAbstractMethodUtils {
|
||||
) {
|
||||
assert getSingleAbstractMethodOrNull(samInterface) != null : samInterface;
|
||||
|
||||
SamConstructorDescriptor result = new SamConstructorDescriptor(owner, samInterface);
|
||||
SamConstructorDescriptorImpl result = new SamConstructorDescriptorImpl(owner, samInterface);
|
||||
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(samInterface.getTypeConstructor().getParameters(), result);
|
||||
List<TypeParameterDescriptor> samTypeParameters = samInterface.getTypeConstructor().getParameters();
|
||||
SimpleType unsubstitutedSamType = samInterface.getDefaultType();
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType);
|
||||
|
||||
KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType());
|
||||
assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + samInterface.getDefaultType();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void initializeSamConstructorDescriptor(
|
||||
@NotNull JavaClassDescriptor samInterface,
|
||||
@NotNull SimpleFunctionDescriptorImpl samConstructor,
|
||||
@NotNull List<TypeParameterDescriptor> samTypeParameters,
|
||||
@NotNull KotlinType unsubstitutedSamType
|
||||
) {
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(samTypeParameters, samConstructor);
|
||||
|
||||
KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(unsubstitutedSamType);
|
||||
assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + unsubstitutedSamType;
|
||||
KotlinType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||
assert parameterType != null : "couldn't substitute type: " + parameterTypeUnsubstituted +
|
||||
", substitutor = " + typeParameters.substitutor;
|
||||
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
||||
result, null, 0, Annotations.Companion.getEMPTY(), Name.identifier("function"), parameterType,
|
||||
samConstructor, null, 0, Annotations.Companion.getEMPTY(), Name.identifier("function"), parameterType,
|
||||
/* declaresDefaultValue = */ false,
|
||||
/* isCrossinline = */ false,
|
||||
/* isNoinline = */ false,
|
||||
/* isCoroutine = */ false,
|
||||
null, SourceElement.NO_SOURCE);
|
||||
|
||||
KotlinType returnType = typeParameters.substitutor.substitute(samInterface.getDefaultType(), Variance.OUT_VARIANCE);
|
||||
assert returnType != null : "couldn't substitute type: " + samInterface.getDefaultType() +
|
||||
KotlinType returnType = typeParameters.substitutor.substitute(unsubstitutedSamType, Variance.OUT_VARIANCE);
|
||||
assert returnType != null : "couldn't substitute type: " + unsubstitutedSamType +
|
||||
", substitutor = " + typeParameters.substitutor;
|
||||
|
||||
result.initialize(
|
||||
samConstructor.initialize(
|
||||
null,
|
||||
null,
|
||||
typeParameters.descriptors,
|
||||
@@ -164,6 +178,18 @@ public class SingleAbstractMethodUtils {
|
||||
Modality.FINAL,
|
||||
samInterface.getVisibility()
|
||||
);
|
||||
}
|
||||
|
||||
public static SamConstructorDescriptor createTypeAliasSamConstructorFunction(
|
||||
@NotNull TypeAliasDescriptor typeAliasDescriptor,
|
||||
@NotNull SamConstructorDescriptor underlyingSamConstructor
|
||||
) {
|
||||
SamTypeAliasConstructorDescriptorImpl result = new SamTypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingSamConstructor);
|
||||
|
||||
JavaClassDescriptor samInterface = underlyingSamConstructor.getBaseDescriptorForSynthetic();
|
||||
List<TypeParameterDescriptor> samTypeParameters = typeAliasDescriptor.getTypeConstructor().getParameters();
|
||||
SimpleType unsubstitutedSamType = typeAliasDescriptor.getExpandedType();
|
||||
initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmOverloadFilter
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmTypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionsTypeChecker
|
||||
import org.jetbrains.kotlin.resolve.jvm.checkers.*
|
||||
import org.jetbrains.kotlin.synthetic.JavaSyntheticConstructorsProvider
|
||||
import org.jetbrains.kotlin.synthetic.JavaSyntheticScopes
|
||||
import org.jetbrains.kotlin.types.DynamicTypesSettings
|
||||
|
||||
@@ -81,6 +82,7 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
|
||||
container.useImpl<ReflectionAPICallChecker>()
|
||||
container.useImpl<JavaSyntheticScopes>()
|
||||
container.useInstance(JavaSyntheticConstructorsProvider)
|
||||
container.useInstance(JvmTypeSpecificityComparator)
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.synthetic
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticConstructorsProvider
|
||||
import java.lang.AssertionError
|
||||
|
||||
object JavaSyntheticConstructorsProvider : SyntheticConstructorsProvider {
|
||||
override fun getSyntheticConstructors(classifier: ClassifierDescriptor, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
if (classifier is TypeAliasDescriptor) {
|
||||
return getSyntheticTypeAliasConstructors(classifier, location)
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private fun getSyntheticTypeAliasConstructors(typeAliasDescriptor: TypeAliasDescriptor, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
val classDescriptor = typeAliasDescriptor.classDescriptor
|
||||
if (classDescriptor !is LazyJavaClassDescriptor || classDescriptor.functionTypeForSamInterface == null) return emptyList()
|
||||
|
||||
val containingDeclaration = classDescriptor.containingDeclaration
|
||||
|
||||
val outerScope = when (containingDeclaration) {
|
||||
is ClassDescriptor ->
|
||||
containingDeclaration.staticScope
|
||||
is PackageFragmentDescriptor ->
|
||||
containingDeclaration.getMemberScope()
|
||||
else ->
|
||||
throw AssertionError("Unexpected containing declaration for $classDescriptor: $containingDeclaration")
|
||||
}
|
||||
|
||||
return outerScope.getContributedFunctions(classDescriptor.name, location)
|
||||
.filterIsInstance<SamConstructorDescriptorImpl>()
|
||||
.filter { it.baseDescriptorForSynthetic == classDescriptor }
|
||||
.map { SingleAbstractMethodUtils.createTypeAliasSamConstructorFunction(typeAliasDescriptor, it) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user