Loading SAM adapters for constructors.
This commit is contained in:
+15
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -31,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.java.*;
|
||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
|
||||
import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation;
|
||||
import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider;
|
||||
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -149,6 +151,7 @@ public final class JavaConstructorResolver {
|
||||
ConstructorDescriptor constructor = resolveConstructor(psiClass, isStatic, psiConstructor, containingClass);
|
||||
if (constructor != null) {
|
||||
constructors.add(constructor);
|
||||
ContainerUtil.addIfNotNull(constructors, resolveSamAdapter(constructor));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,4 +221,16 @@ public final class JavaConstructorResolver {
|
||||
trace.record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor);
|
||||
return constructorDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) {
|
||||
if (SingleAbstractMethodUtils.isSamAdapterNecessary(original)) {
|
||||
ConstructorDescriptor adapterFunction = SingleAbstractMethodUtils.createSamAdapterConstructor(original);
|
||||
|
||||
trace.record(BindingContext.SAM_ADAPTER_FUNCTION_TO_ORIGINAL, adapterFunction, original);
|
||||
trace.record(BindingContext.SOURCE_DESCRIPTOR_FOR_SYNTHESIZED, adapterFunction, original);
|
||||
return adapterFunction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+76
-20
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
@@ -174,7 +175,7 @@ public class SingleAbstractMethodUtils {
|
||||
return getFunctionTypeForSamType(type) != null;
|
||||
}
|
||||
|
||||
public static boolean isSamAdapterNecessary(@NotNull SimpleFunctionDescriptor fun) {
|
||||
public static boolean isSamAdapterNecessary(@NotNull FunctionDescriptor fun) {
|
||||
for (ValueParameterDescriptor param : fun.getValueParameters()) {
|
||||
if (isSamType(param.getType())) {
|
||||
return true;
|
||||
@@ -184,20 +185,77 @@ public class SingleAbstractMethodUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleFunctionDescriptor createSamAdapterFunction(@NotNull SimpleFunctionDescriptor original) {
|
||||
SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl(
|
||||
public static SimpleFunctionDescriptor createSamAdapterFunction(@NotNull final SimpleFunctionDescriptor original) {
|
||||
final SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl(
|
||||
original.getContainingDeclaration(),
|
||||
original.getAnnotations(),
|
||||
original.getName(),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
);
|
||||
FunctionInitializer initializer = new FunctionInitializer() {
|
||||
@Override
|
||||
public void initialize(
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@Nullable JetType returnType
|
||||
) {
|
||||
result.initialize(
|
||||
null,
|
||||
original.getExpectedThisObject(),
|
||||
typeParameters,
|
||||
valueParameters,
|
||||
returnType,
|
||||
original.getModality(),
|
||||
original.getVisibility(),
|
||||
false
|
||||
);
|
||||
}
|
||||
};
|
||||
return initSamAdapter(original, result, initializer);
|
||||
}
|
||||
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), result);
|
||||
@NotNull
|
||||
public static ConstructorDescriptor createSamAdapterConstructor(@NotNull final ConstructorDescriptor original) {
|
||||
final ConstructorDescriptorImpl result = new ConstructorDescriptorImpl(
|
||||
original.getContainingDeclaration(),
|
||||
original.getAnnotations(),
|
||||
original.isPrimary(),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
);
|
||||
FunctionInitializer initializer = new FunctionInitializer() {
|
||||
@Override
|
||||
public void initialize(
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@Nullable JetType returnType
|
||||
) {
|
||||
result.initialize(
|
||||
typeParameters,
|
||||
valueParameters,
|
||||
original.getVisibility(),
|
||||
original.getExpectedThisObject() == ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER
|
||||
);
|
||||
}
|
||||
};
|
||||
return initSamAdapter(original, result, initializer);
|
||||
}
|
||||
|
||||
private static <F extends FunctionDescriptor> F initSamAdapter(
|
||||
@NotNull F original,
|
||||
@NotNull F adapter,
|
||||
@NotNull FunctionInitializer initializer
|
||||
) {
|
||||
TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), adapter);
|
||||
|
||||
JetType returnTypeUnsubstituted = original.getReturnType();
|
||||
assert returnTypeUnsubstituted != null : original;
|
||||
JetType returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE);
|
||||
assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor;
|
||||
JetType returnType;
|
||||
if (returnTypeUnsubstituted == null) { // return type may be null for not yet initialized constructors
|
||||
returnType = null;
|
||||
}
|
||||
else {
|
||||
returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE);
|
||||
assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor;
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
|
||||
for (ValueParameterDescriptor originalParam : original.getValueParameters()) {
|
||||
@@ -208,22 +266,12 @@ public class SingleAbstractMethodUtils {
|
||||
assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + typeParameters.substitutor;
|
||||
|
||||
ValueParameterDescriptor newParam = new ValueParameterDescriptorImpl(
|
||||
result, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null);
|
||||
adapter, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null);
|
||||
valueParameters.add(newParam);
|
||||
}
|
||||
|
||||
result.initialize(
|
||||
null,
|
||||
original.getExpectedThisObject(),
|
||||
typeParameters.descriptors,
|
||||
valueParameters,
|
||||
returnType,
|
||||
original.getModality(),
|
||||
original.getVisibility(),
|
||||
false
|
||||
);
|
||||
|
||||
return result;
|
||||
initializer.initialize(typeParameters.descriptors, valueParameters, returnType);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -273,4 +321,12 @@ public class SingleAbstractMethodUtils {
|
||||
this.substitutor = substitutor;
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class FunctionInitializer {
|
||||
public abstract void initialize(
|
||||
@NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull List<ValueParameterDescriptor> valueParameters,
|
||||
@Nullable JetType returnType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user