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