Supported simplest cases of SAM adapter.
This commit is contained in:
+3
-1
@@ -268,7 +268,9 @@ public class SignaturesPropagationData {
|
||||
FqName fqName = DescriptorUtils.getFQName(klass).toSafe();
|
||||
|
||||
for (FunctionDescriptor fun : klass.getDefaultType().getMemberScope().getFunctions(functionName)) {
|
||||
if (fun.getKind().isReal() && fun.getValueParameters().size() == parameterCount) {
|
||||
CallableMemberDescriptor.Kind kind = fun.getKind();
|
||||
if ((kind == CallableMemberDescriptor.Kind.DECLARATION || kind == CallableMemberDescriptor.Kind.DELEGATION) &&
|
||||
fun.getValueParameters().size() == parameterCount) {
|
||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, fun);
|
||||
if (declaration instanceof PsiMethod) {
|
||||
result.put(fqName, Pair.create(fun, (PsiMethod) declaration));
|
||||
|
||||
+14
@@ -270,6 +270,8 @@ public final class JavaFunctionResolver {
|
||||
SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(psiClass, method, scopeData, owner);
|
||||
if (function != null) {
|
||||
functionsFromCurrent.add(function);
|
||||
|
||||
ContainerUtil.addIfNotNull(functionsFromCurrent, resolveSamAdapter(function));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +370,18 @@ public final class JavaFunctionResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private SimpleFunctionDescriptor resolveSamAdapter(@NotNull SimpleFunctionDescriptor original) {
|
||||
if (SingleAbstractMethodUtils.isSamAdapterNecessary(original)) {
|
||||
SimpleFunctionDescriptor adapterFunction = SingleAbstractMethodUtils.createSamAdapterFunction(original);
|
||||
|
||||
trace.record(BindingContext.SAM_ADAPTER_FUNCTION_TO_ORIGINAL, adapterFunction, original);
|
||||
trace.record(BindingContext.SOURCE_DESCRIPTOR_FOR_SYNTHESIZED, adapterFunction, original);
|
||||
return adapterFunction;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<FunctionDescriptor> resolveFunctionGroup(
|
||||
@NotNull Name methodName,
|
||||
|
||||
+61
-4
@@ -23,10 +23,12 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lang.types.Variance;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
|
||||
@@ -40,7 +42,9 @@ public class SingleAbstractMethodUtils {
|
||||
private static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
||||
List<CallableMemberDescriptor> abstractMembers = Lists.newArrayList();
|
||||
for (DeclarationDescriptor member : type.getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT) {
|
||||
if (member instanceof CallableMemberDescriptor &&
|
||||
((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT &&
|
||||
((CallableMemberDescriptor) member).getKind() != CallableMemberDescriptor.Kind.SYNTHESIZED) {
|
||||
abstractMembers.add((CallableMemberDescriptor) member);
|
||||
}
|
||||
}
|
||||
@@ -48,14 +52,17 @@ public class SingleAbstractMethodUtils {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetType getFunctionTypeForFunction(@NotNull FunctionDescriptor function) {
|
||||
private static JetType getFunctionTypeForSamType(@NotNull JetType samType) {
|
||||
FunctionDescriptor function = getAbstractMethodOfSamType(samType);
|
||||
JetType returnType = function.getReturnType();
|
||||
assert returnType != null : "function is not initialized: " + function;
|
||||
List<JetType> parameterTypes = Lists.newArrayList();
|
||||
for (ValueParameterDescriptor parameter : function.getValueParameters()) {
|
||||
parameterTypes.add(parameter.getType());
|
||||
}
|
||||
return KotlinBuiltIns.getInstance().getFunctionType(Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType);
|
||||
JetType functionType = KotlinBuiltIns.getInstance()
|
||||
.getFunctionType(Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType);
|
||||
return TypeUtils.makeNullableAsSpecified(functionType, samType.isNullable());
|
||||
}
|
||||
|
||||
private static boolean isSamInterface(@NotNull ClassDescriptor klass) {
|
||||
@@ -91,7 +98,7 @@ public class SingleAbstractMethodUtils {
|
||||
SignaturesUtil.recreateTypeParametersAndReturnMapping(samInterface.getTypeConstructor().getParameters(), result);
|
||||
TypeSubstitutor typeParametersSubstitutor = SignaturesUtil.createSubstitutorForTypeParameters(traitToFunTypeParameters);
|
||||
|
||||
JetType parameterTypeUnsubstituted = getFunctionTypeForFunction(getAbstractMethodOfSamType(samInterface.getDefaultType()));
|
||||
JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType());
|
||||
JetType parameterType = typeParametersSubstitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||
assert parameterType != null : "couldn't substitute type: " + parameterType + ", substitutor = " + typeParametersSubstitutor;
|
||||
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
||||
@@ -127,6 +134,56 @@ public class SingleAbstractMethodUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isSamType(@NotNull JetType type) {
|
||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||
return classifier instanceof ClassDescriptorFromJvmBytecode &&
|
||||
((ClassDescriptorFromJvmBytecode) classifier).isSamInterface();
|
||||
}
|
||||
|
||||
public static boolean isSamAdapterNecessary(@NotNull SimpleFunctionDescriptor fun) {
|
||||
for (ValueParameterDescriptor param : fun.getValueParameters()) {
|
||||
if (isSamType(param.getType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleFunctionDescriptor createSamAdapterFunction(@NotNull SimpleFunctionDescriptor original) {
|
||||
SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl(
|
||||
original.getContainingDeclaration(),
|
||||
original.getAnnotations(),
|
||||
original.getName(),
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
);
|
||||
|
||||
JetType returnType = original.getReturnType();
|
||||
|
||||
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
|
||||
for (ValueParameterDescriptor originalParam : original.getValueParameters()) {
|
||||
JetType originalType = originalParam.getType();
|
||||
JetType newType = isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType;
|
||||
|
||||
ValueParameterDescriptor newParam = new ValueParameterDescriptorImpl(
|
||||
result, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null);
|
||||
valueParameters.add(newParam);
|
||||
}
|
||||
|
||||
result.initialize(
|
||||
null,
|
||||
original.getExpectedThisObject(),
|
||||
Collections.<TypeParameterDescriptor>emptyList(), // TODO copy type parameters
|
||||
valueParameters,
|
||||
returnType,
|
||||
original.getModality(),
|
||||
original.getVisibility(),
|
||||
false
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SimpleFunctionDescriptor getAbstractMethodOfSamType(@NotNull JetType type) {
|
||||
return (SimpleFunctionDescriptor) getAbstractMembers(type).get(0);
|
||||
|
||||
Reference in New Issue
Block a user