Optimize codegen for generic SAM types
Search abstract members in unsubstituted scope to avoid computation of substituted descriptors for each type (effectively for each SAM call) #KT-20055 In progress
This commit is contained in:
@@ -203,7 +203,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
|||||||
erasedInterfaceFunction = getErasedInvokeFunction(funDescriptor);
|
erasedInterfaceFunction = getErasedInvokeFunction(funDescriptor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
erasedInterfaceFunction = samType.getAbstractMethod().getOriginal();
|
erasedInterfaceFunction = samType.getOriginalAbstractMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
generateBridge(
|
generateBridge(
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ public class SamType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public SimpleFunctionDescriptor getAbstractMethod() {
|
public SimpleFunctionDescriptor getOriginalAbstractMethod() {
|
||||||
return (SimpleFunctionDescriptor) SingleAbstractMethodUtils.getAbstractMembers(type).get(0);
|
return (SimpleFunctionDescriptor) SingleAbstractMethodUtils.getAbstractMembers(getJavaClassDescriptor()).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class SamWrapperCodegen {
|
|||||||
/* isExternal = */ false
|
/* isExternal = */ false
|
||||||
);
|
);
|
||||||
// e.g. compare(T, T)
|
// e.g. compare(T, T)
|
||||||
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getAbstractMethod().getOriginal().copy(
|
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getOriginalAbstractMethod().copy(
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
Visibilities.PUBLIC,
|
||||||
@@ -167,7 +167,7 @@ public class SamWrapperCodegen {
|
|||||||
|
|
||||||
// generate sam bridges
|
// generate sam bridges
|
||||||
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
|
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
|
||||||
SimpleFunctionDescriptor originalInterfaceErased = samType.getAbstractMethod().getOriginal();
|
SimpleFunctionDescriptor originalInterfaceErased = samType.getOriginalAbstractMethod();
|
||||||
SimpleFunctionDescriptorImpl descriptorForBridges = SimpleFunctionDescriptorImpl
|
SimpleFunctionDescriptorImpl descriptorForBridges = SimpleFunctionDescriptorImpl
|
||||||
.create(erasedInterfaceFunction.getContainingDeclaration(), erasedInterfaceFunction.getAnnotations(), originalInterfaceErased.getName(),
|
.create(erasedInterfaceFunction.getContainingDeclaration(), erasedInterfaceFunction.getAnnotations(), originalInterfaceErased.getName(),
|
||||||
CallableMemberDescriptor.Kind.DECLARATION, erasedInterfaceFunction.getSource());
|
CallableMemberDescriptor.Kind.DECLARATION, erasedInterfaceFunction.getSource());
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ public class KotlinTypeMapper {
|
|||||||
if (expression instanceof KtLambdaExpression) {
|
if (expression instanceof KtLambdaExpression) {
|
||||||
SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
|
SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
|
||||||
if (samType != null) {
|
if (samType != null) {
|
||||||
return samType.getAbstractMethod().getName().asString();
|
return samType.getOriginalAbstractMethod().getName().asString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -47,9 +47,9 @@ public class SingleAbstractMethodUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull KotlinType type) {
|
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
|
||||||
List<CallableMemberDescriptor> abstractMembers = new ArrayList<>();
|
List<CallableMemberDescriptor> abstractMembers = new ArrayList<>();
|
||||||
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(type.getMemberScope())) {
|
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getUnsubstitutedMemberScope())) {
|
||||||
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT) {
|
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT) {
|
||||||
abstractMembers.add((CallableMemberDescriptor) member);
|
abstractMembers.add((CallableMemberDescriptor) member);
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ public class SingleAbstractMethodUtils {
|
|||||||
|
|
||||||
if (klass.isDefinitelyNotSamInterface()) return null;
|
if (klass.isDefinitelyNotSamInterface()) return null;
|
||||||
|
|
||||||
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass.getDefaultType());
|
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass);
|
||||||
if (abstractMembers.size() == 1) {
|
if (abstractMembers.size() == 1) {
|
||||||
CallableMemberDescriptor member = abstractMembers.get(0);
|
CallableMemberDescriptor member = abstractMembers.get(0);
|
||||||
if (member instanceof SimpleFunctionDescriptor) {
|
if (member instanceof SimpleFunctionDescriptor) {
|
||||||
|
|||||||
Reference in New Issue
Block a user