Make JvmFunctionImplTypes lazy

It shouldn't compute all FunctionImpls at least until first asked
This commit is contained in:
Alexander Udalov
2014-05-07 16:23:56 +04:00
parent 3a0aac4857
commit 985e9a5f31
@@ -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;
}
}