Make JvmFunctionImplTypes lazy
It shouldn't compute all FunctionImpls at least until first asked
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -36,52 +37,107 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JvmFunctionImplTypes {
|
||||
private final List<ClassDescriptor> functions;
|
||||
private final List<ClassDescriptor> extensionFunctions;
|
||||
private final List<ClassDescriptor> kFunctions;
|
||||
private final List<ClassDescriptor> kMemberFunctions;
|
||||
private final List<ClassDescriptor> kExtensionFunctions;
|
||||
private final ReflectionTypes reflectionTypes;
|
||||
private final ModuleDescriptor fakeModule;
|
||||
|
||||
private final ImmutableMap<ClassDescriptor, ClassDescriptor> kFunctionToImpl;
|
||||
private volatile List<Functions> functionsList;
|
||||
private volatile List<KFunctions> kFunctionsList;
|
||||
private volatile Map<ClassDescriptor, ClassDescriptor> kFunctionToImplMap;
|
||||
|
||||
private static class Functions {
|
||||
public final ClassDescriptor functionImpl;
|
||||
public final ClassDescriptor extensionFunctionImpl;
|
||||
|
||||
public Functions(
|
||||
@NotNull ClassDescriptor functionImpl,
|
||||
@NotNull ClassDescriptor extensionFunctionImpl
|
||||
) {
|
||||
this.functionImpl = functionImpl;
|
||||
this.extensionFunctionImpl = extensionFunctionImpl;
|
||||
}
|
||||
}
|
||||
|
||||
private static class KFunctions {
|
||||
public final ClassDescriptor kFunctionImpl;
|
||||
public final ClassDescriptor kMemberFunctionImpl;
|
||||
public final ClassDescriptor kExtensionFunctionImpl;
|
||||
|
||||
public KFunctions(
|
||||
@NotNull ClassDescriptor kFunctionImpl,
|
||||
@NotNull ClassDescriptor kMemberFunctionImpl,
|
||||
@NotNull ClassDescriptor kExtensionFunctionImpl
|
||||
) {
|
||||
this.kFunctionImpl = kFunctionImpl;
|
||||
this.kMemberFunctionImpl = kMemberFunctionImpl;
|
||||
this.kExtensionFunctionImpl = kExtensionFunctionImpl;
|
||||
}
|
||||
}
|
||||
|
||||
public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
|
||||
int n = KotlinBuiltIns.FUNCTION_TRAIT_COUNT;
|
||||
functions = new ArrayList<ClassDescriptor>(n);
|
||||
extensionFunctions = new ArrayList<ClassDescriptor>(n);
|
||||
kFunctions = new ArrayList<ClassDescriptor>(n);
|
||||
kMemberFunctions = new ArrayList<ClassDescriptor>(n);
|
||||
kExtensionFunctions = new ArrayList<ClassDescriptor>(n);
|
||||
this.reflectionTypes = reflectionTypes;
|
||||
this.fakeModule = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"), Collections.<ImportPath>emptyList(),
|
||||
JavaToKotlinClassMap.getInstance());
|
||||
}
|
||||
|
||||
ModuleDescriptor module = new ModuleDescriptorImpl(Name.special("<fake module for functions impl>"),
|
||||
Collections.<ImportPath>emptyList(), JavaToKotlinClassMap.getInstance());
|
||||
MutablePackageFragmentDescriptor kotlin = new MutablePackageFragmentDescriptor(module, new FqName("kotlin"));
|
||||
MutablePackageFragmentDescriptor reflect = new MutablePackageFragmentDescriptor(module, new FqName("kotlin.reflect"));
|
||||
@NotNull
|
||||
private List<Functions> getFunctionsImplList() {
|
||||
if (functionsList == null) {
|
||||
MutablePackageFragmentDescriptor kotlin = new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin"));
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
|
||||
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
|
||||
for (int i = 0; i < n; i++) {
|
||||
createFunctionImpl(functions, kotlin, "FunctionImpl" + i, builtIns.getFunction(i));
|
||||
createFunctionImpl(extensionFunctions, kotlin, "ExtensionFunctionImpl" + i, builtIns.getExtensionFunction(i));
|
||||
createFunctionImpl(kFunctions, reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i));
|
||||
createFunctionImpl(kMemberFunctions, reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i));
|
||||
createFunctionImpl(kExtensionFunctions, reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i));
|
||||
ImmutableList.Builder<Functions> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) {
|
||||
builder.add(new Functions(
|
||||
createFunctionImpl(kotlin, "FunctionImpl" + i, builtIns.getFunction(i)),
|
||||
createFunctionImpl(kotlin, "ExtensionFunctionImpl" + i, builtIns.getExtensionFunction(i))
|
||||
));
|
||||
}
|
||||
functionsList = builder.build();
|
||||
}
|
||||
return functionsList;
|
||||
}
|
||||
|
||||
ImmutableMap.Builder<ClassDescriptor, ClassDescriptor> builder = ImmutableMap.builder();
|
||||
for (int i = 0; i < n; i++) {
|
||||
builder.put(reflectionTypes.getKFunction(i), kFunctions.get(i));
|
||||
builder.put(reflectionTypes.getKMemberFunction(i), kMemberFunctions.get(i));
|
||||
builder.put(reflectionTypes.getKExtensionFunction(i), kExtensionFunctions.get(i));
|
||||
@NotNull
|
||||
private List<KFunctions> getKFunctionsImplList() {
|
||||
if (kFunctionsList == null) {
|
||||
MutablePackageFragmentDescriptor reflect = new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect"));
|
||||
|
||||
ImmutableList.Builder<KFunctions> builder = ImmutableList.builder();
|
||||
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) {
|
||||
builder.add(new KFunctions(
|
||||
createFunctionImpl(reflect, "KFunctionImpl" + i, reflectionTypes.getKFunction(i)),
|
||||
createFunctionImpl(reflect, "KMemberFunctionImpl" + i, reflectionTypes.getKMemberFunction(i)),
|
||||
createFunctionImpl(reflect, "KExtensionFunctionImpl" + i, reflectionTypes.getKExtensionFunction(i))
|
||||
));
|
||||
}
|
||||
kFunctionsList = builder.build();
|
||||
}
|
||||
kFunctionToImpl = builder.build();
|
||||
return kFunctionsList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<ClassDescriptor, ClassDescriptor> getKFunctionToImplMap() {
|
||||
if (kFunctionToImplMap == null) {
|
||||
ImmutableMap.Builder<ClassDescriptor, ClassDescriptor> builder = ImmutableMap.builder();
|
||||
for (int i = 0; i < KotlinBuiltIns.FUNCTION_TRAIT_COUNT; i++) {
|
||||
KFunctions kFunctions = getKFunctionsImplList().get(i);
|
||||
builder.put(reflectionTypes.getKFunction(i), kFunctions.kFunctionImpl);
|
||||
builder.put(reflectionTypes.getKMemberFunction(i), kFunctions.kMemberFunctionImpl);
|
||||
builder.put(reflectionTypes.getKExtensionFunction(i), kFunctions.kExtensionFunctionImpl);
|
||||
}
|
||||
kFunctionToImplMap = builder.build();
|
||||
}
|
||||
return kFunctionToImplMap;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public ClassDescriptor kFunctionTypeToImpl(@NotNull JetType functionType) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return kFunctionToImpl.get(functionType.getConstructor().getDeclarationDescriptor());
|
||||
return getKFunctionToImplMap().get(functionType.getConstructor().getDeclarationDescriptor());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -108,22 +164,24 @@ public class JvmFunctionImplTypes {
|
||||
|
||||
ClassDescriptor classDescriptor;
|
||||
if (kFunction) {
|
||||
KFunctions kFunctions = getKFunctionsImplList().get(arity);
|
||||
if (expectedThisObject != null) {
|
||||
classDescriptor = kMemberFunctions.get(arity);
|
||||
classDescriptor = kFunctions.kMemberFunctionImpl;
|
||||
}
|
||||
else if (receiverParameter != null) {
|
||||
classDescriptor = kExtensionFunctions.get(arity);
|
||||
classDescriptor = kFunctions.kExtensionFunctionImpl;
|
||||
}
|
||||
else {
|
||||
classDescriptor = kFunctions.get(arity);
|
||||
classDescriptor = kFunctions.kFunctionImpl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Functions functions = getFunctionsImplList().get(arity);
|
||||
if (receiverParameter != null) {
|
||||
classDescriptor = extensionFunctions.get(arity);
|
||||
classDescriptor = functions.extensionFunctionImpl;
|
||||
}
|
||||
else {
|
||||
classDescriptor = functions.get(arity);
|
||||
classDescriptor = functions.functionImpl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +194,8 @@ public class JvmFunctionImplTypes {
|
||||
);
|
||||
}
|
||||
|
||||
private static void createFunctionImpl(
|
||||
@NotNull List<ClassDescriptor> result,
|
||||
@NotNull
|
||||
private static ClassDescriptor createFunctionImpl(
|
||||
@NotNull PackageFragmentDescriptor containingDeclaration,
|
||||
@NotNull String name,
|
||||
@NotNull ClassDescriptor functionInterface
|
||||
@@ -154,6 +212,6 @@ public class JvmFunctionImplTypes {
|
||||
functionImpl.setTypeParameterDescriptors(functionInterface.getDefaultType().getConstructor().getParameters());
|
||||
functionImpl.createTypeConstructor();
|
||||
|
||||
result.add(functionImpl);
|
||||
return functionImpl;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user