Do not evaluate anything eagerly in KotlinBuiltIns constructor

This commit is contained in:
Alexander Udalov
2016-11-07 18:39:50 +03:00
parent 2be4800307
commit 5adb22ed65
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.builtins; package org.jetbrains.kotlin.builtins;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -33,6 +34,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.serialization.deserialization.AdditionalClassPartsProvider; import org.jetbrains.kotlin.serialization.deserialization.AdditionalClassPartsProvider;
import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory; import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory;
import org.jetbrains.kotlin.serialization.deserialization.PlatformDependentDeclarationFilter; import org.jetbrains.kotlin.serialization.deserialization.PlatformDependentDeclarationFilter;
import org.jetbrains.kotlin.storage.NotNullLazyValue;
import org.jetbrains.kotlin.storage.StorageManager; import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
@@ -65,15 +67,10 @@ public abstract class KotlinBuiltIns {
); );
private final ModuleDescriptorImpl builtInsModule; private final ModuleDescriptorImpl builtInsModule;
private final PackageFragmentDescriptor builtInsPackageFragment;
private final PackageFragmentDescriptor collectionsPackageFragment;
private final PackageFragmentDescriptor annotationPackageFragment;
private final Set<PackageFragmentDescriptor> builtInsPackageFragments; private final NotNullLazyValue<Primitives> primitives;
private final NotNullLazyValue<PackageFragments> packageFragments;
private final Map<PrimitiveType, SimpleType> primitiveTypeToArrayKotlinType;
private final Map<KotlinType, SimpleType> primitiveKotlinTypeToKotlinArrayType;
private final Map<SimpleType, SimpleType> kotlinArrayTypeToPrimitiveKotlinType;
private final StorageManager storageManager; private final StorageManager storageManager;
public static final FqNames FQ_NAMES = new FqNames(); public static final FqNames FQ_NAMES = new FqNames();
@@ -100,22 +97,43 @@ public abstract class KotlinBuiltIns {
builtInsModule.initialize(packageFragmentProvider); builtInsModule.initialize(packageFragmentProvider);
builtInsModule.setDependencies(builtInsModule); builtInsModule.setDependencies(builtInsModule);
Map<FqName, PackageFragmentDescriptor> packageNameToPackageFragment = new LinkedHashMap<FqName, PackageFragmentDescriptor>(); this.packageFragments = storageManager.createLazyValue(new Function0<PackageFragments>() {
@Override
public PackageFragments invoke() {
PackageFragmentProvider provider = builtInsModule.getPackageFragmentProvider();
builtInsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, BUILT_INS_PACKAGE_FQ_NAME); Map<FqName, PackageFragmentDescriptor> nameToFragment = new LinkedHashMap<FqName, PackageFragmentDescriptor>();
collectionsPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, COLLECTIONS_PACKAGE_FQ_NAME); PackageFragmentDescriptor kotlin = createPackage(provider, nameToFragment, BUILT_INS_PACKAGE_FQ_NAME);
createPackage(packageFragmentProvider, packageNameToPackageFragment, RANGES_PACKAGE_FQ_NAME); PackageFragmentDescriptor kotlinCollections = createPackage(provider, nameToFragment, COLLECTIONS_PACKAGE_FQ_NAME);
annotationPackageFragment = createPackage(packageFragmentProvider, packageNameToPackageFragment, ANNOTATION_PACKAGE_FQ_NAME); createPackage(provider, nameToFragment, RANGES_PACKAGE_FQ_NAME);
createPackage(packageFragmentProvider, packageNameToPackageFragment, COROUTINES_PACKAGE_FQ_NAME); PackageFragmentDescriptor kotlinAnnotation = createPackage(provider, nameToFragment, ANNOTATION_PACKAGE_FQ_NAME);
createPackage(provider, nameToFragment, COROUTINES_PACKAGE_FQ_NAME);
builtInsPackageFragments = new LinkedHashSet<PackageFragmentDescriptor>(packageNameToPackageFragment.values()); Set<PackageFragmentDescriptor> all = new LinkedHashSet<PackageFragmentDescriptor>(nameToFragment.values());
primitiveTypeToArrayKotlinType = new EnumMap<PrimitiveType, SimpleType>(PrimitiveType.class); return new PackageFragments(kotlin, kotlinCollections, kotlinAnnotation, all);
primitiveKotlinTypeToKotlinArrayType = new HashMap<KotlinType, SimpleType>(); }
kotlinArrayTypeToPrimitiveKotlinType = new HashMap<SimpleType, SimpleType>(); });
for (PrimitiveType primitive : PrimitiveType.values()) {
makePrimitive(primitive); this.primitives = storageManager.createLazyValue(new Function0<Primitives>() {
} @Override
public Primitives invoke() {
Map<PrimitiveType, SimpleType> primitiveTypeToArrayKotlinType = new EnumMap<PrimitiveType, SimpleType>(PrimitiveType.class);
Map<KotlinType, SimpleType> primitiveKotlinTypeToKotlinArrayType = new HashMap<KotlinType, SimpleType>();
Map<SimpleType, SimpleType> kotlinArrayTypeToPrimitiveKotlinType = new HashMap<SimpleType, SimpleType>();
for (PrimitiveType primitive : PrimitiveType.values()) {
SimpleType type = getBuiltInTypeByClassName(primitive.getTypeName().asString());
SimpleType arrayType = getBuiltInTypeByClassName(primitive.getArrayTypeName().asString());
primitiveTypeToArrayKotlinType.put(primitive, arrayType);
primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type);
}
return new Primitives(
primitiveTypeToArrayKotlinType, primitiveKotlinTypeToKotlinArrayType, kotlinArrayTypeToPrimitiveKotlinType
);
}
});
} }
@NotNull @NotNull
@@ -133,16 +151,6 @@ public abstract class KotlinBuiltIns {
return Collections.<ClassDescriptorFactory>singletonList(new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule)); return Collections.<ClassDescriptorFactory>singletonList(new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule));
} }
private void makePrimitive(@NotNull PrimitiveType primitiveType) {
SimpleType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString());
SimpleType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString());
primitiveTypeToArrayKotlinType.put(primitiveType, arrayType);
primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type);
}
@NotNull @NotNull
private static PackageFragmentDescriptor createPackage( private static PackageFragmentDescriptor createPackage(
@NotNull PackageFragmentProvider fragmentProvider, @NotNull PackageFragmentProvider fragmentProvider,
@@ -159,6 +167,41 @@ public abstract class KotlinBuiltIns {
return storageManager; return storageManager;
} }
private static class Primitives {
public final Map<PrimitiveType, SimpleType> primitiveTypeToArrayKotlinType;
public final Map<KotlinType, SimpleType> primitiveKotlinTypeToKotlinArrayType;
public final Map<SimpleType, SimpleType> kotlinArrayTypeToPrimitiveKotlinType;
private Primitives(
@NotNull Map<PrimitiveType, SimpleType> primitiveTypeToArrayKotlinType,
@NotNull Map<KotlinType, SimpleType> primitiveKotlinTypeToKotlinArrayType,
@NotNull Map<SimpleType, SimpleType> kotlinArrayTypeToPrimitiveKotlinType
) {
this.primitiveTypeToArrayKotlinType = primitiveTypeToArrayKotlinType;
this.primitiveKotlinTypeToKotlinArrayType = primitiveKotlinTypeToKotlinArrayType;
this.kotlinArrayTypeToPrimitiveKotlinType = kotlinArrayTypeToPrimitiveKotlinType;
}
}
private static class PackageFragments {
public final PackageFragmentDescriptor builtInsPackageFragment;
public final PackageFragmentDescriptor collectionsPackageFragment;
public final PackageFragmentDescriptor annotationPackageFragment;
public final Set<PackageFragmentDescriptor> builtInsPackageFragments;
private PackageFragments(
@NotNull PackageFragmentDescriptor builtInsPackageFragment,
@NotNull PackageFragmentDescriptor collectionsPackageFragment,
@NotNull PackageFragmentDescriptor annotationPackageFragment,
@NotNull Set<PackageFragmentDescriptor> builtInsPackageFragments
) {
this.builtInsPackageFragment = builtInsPackageFragment;
this.collectionsPackageFragment = collectionsPackageFragment;
this.annotationPackageFragment = annotationPackageFragment;
this.builtInsPackageFragments = builtInsPackageFragments;
}
}
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public static class FqNames { public static class FqNames {
public final FqNameUnsafe any = fqNameUnsafe("Any"); public final FqNameUnsafe any = fqNameUnsafe("Any");
@@ -280,12 +323,12 @@ public abstract class KotlinBuiltIns {
@NotNull @NotNull
public Set<PackageFragmentDescriptor> getBuiltInsPackageFragments() { public Set<PackageFragmentDescriptor> getBuiltInsPackageFragments() {
return builtInsPackageFragments; return packageFragments.invoke().builtInsPackageFragments;
} }
@NotNull @NotNull
public PackageFragmentDescriptor getBuiltInsPackageFragment() { public PackageFragmentDescriptor getBuiltInsPackageFragment() {
return builtInsPackageFragment; return packageFragments.invoke().builtInsPackageFragment;
} }
public static boolean isBuiltIn(@NotNull DeclarationDescriptor descriptor) { public static boolean isBuiltIn(@NotNull DeclarationDescriptor descriptor) {
@@ -294,12 +337,12 @@ public abstract class KotlinBuiltIns {
@NotNull @NotNull
public MemberScope getBuiltInsPackageScope() { public MemberScope getBuiltInsPackageScope() {
return builtInsPackageFragment.getMemberScope(); return packageFragments.invoke().builtInsPackageFragment.getMemberScope();
} }
@NotNull @NotNull
private ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) { private ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) {
return getBuiltInClassByName(simpleName, annotationPackageFragment); return getBuiltInClassByName(simpleName, packageFragments.invoke().annotationPackageFragment);
} }
@NotNull @NotNull
@@ -515,64 +558,69 @@ public abstract class KotlinBuiltIns {
return getBuiltInClassByName("Annotation"); return getBuiltInClassByName("Annotation");
} }
@NotNull
private ClassDescriptor getCollectionClassByName(@NotNull String simpleName) {
return getBuiltInClassByName(simpleName, packageFragments.invoke().collectionsPackageFragment);
}
@NotNull @NotNull
public ClassDescriptor getIterator() { public ClassDescriptor getIterator() {
return getBuiltInClassByName("Iterator", collectionsPackageFragment); return getCollectionClassByName("Iterator");
} }
@NotNull @NotNull
public ClassDescriptor getIterable() { public ClassDescriptor getIterable() {
return getBuiltInClassByName("Iterable", collectionsPackageFragment); return getCollectionClassByName("Iterable");
} }
@NotNull @NotNull
public ClassDescriptor getMutableIterable() { public ClassDescriptor getMutableIterable() {
return getBuiltInClassByName("MutableIterable", collectionsPackageFragment); return getCollectionClassByName("MutableIterable");
} }
@NotNull @NotNull
public ClassDescriptor getMutableIterator() { public ClassDescriptor getMutableIterator() {
return getBuiltInClassByName("MutableIterator", collectionsPackageFragment); return getCollectionClassByName("MutableIterator");
} }
@NotNull @NotNull
public ClassDescriptor getCollection() { public ClassDescriptor getCollection() {
return getBuiltInClassByName("Collection", collectionsPackageFragment); return getCollectionClassByName("Collection");
} }
@NotNull @NotNull
public ClassDescriptor getMutableCollection() { public ClassDescriptor getMutableCollection() {
return getBuiltInClassByName("MutableCollection", collectionsPackageFragment); return getCollectionClassByName("MutableCollection");
} }
@NotNull @NotNull
public ClassDescriptor getList() { public ClassDescriptor getList() {
return getBuiltInClassByName("List", collectionsPackageFragment); return getCollectionClassByName("List");
} }
@NotNull @NotNull
public ClassDescriptor getMutableList() { public ClassDescriptor getMutableList() {
return getBuiltInClassByName("MutableList", collectionsPackageFragment); return getCollectionClassByName("MutableList");
} }
@NotNull @NotNull
public ClassDescriptor getSet() { public ClassDescriptor getSet() {
return getBuiltInClassByName("Set", collectionsPackageFragment); return getCollectionClassByName("Set");
} }
@NotNull @NotNull
public ClassDescriptor getMutableSet() { public ClassDescriptor getMutableSet() {
return getBuiltInClassByName("MutableSet", collectionsPackageFragment); return getCollectionClassByName("MutableSet");
} }
@NotNull @NotNull
public ClassDescriptor getMap() { public ClassDescriptor getMap() {
return getBuiltInClassByName("Map", collectionsPackageFragment); return getCollectionClassByName("Map");
} }
@NotNull @NotNull
public ClassDescriptor getMutableMap() { public ClassDescriptor getMutableMap() {
return getBuiltInClassByName("MutableMap", collectionsPackageFragment); return getCollectionClassByName("MutableMap");
} }
@NotNull @NotNull
@@ -591,12 +639,12 @@ public abstract class KotlinBuiltIns {
@NotNull @NotNull
public ClassDescriptor getListIterator() { public ClassDescriptor getListIterator() {
return getBuiltInClassByName("ListIterator", collectionsPackageFragment); return getCollectionClassByName("ListIterator");
} }
@NotNull @NotNull
public ClassDescriptor getMutableListIterator() { public ClassDescriptor getMutableListIterator() {
return getBuiltInClassByName("MutableListIterator", collectionsPackageFragment); return getCollectionClassByName("MutableListIterator");
} }
@NotNull @NotNull
@@ -698,7 +746,7 @@ public abstract class KotlinBuiltIns {
return arrayType.getArguments().get(0).getType(); return arrayType.getArguments().get(0).getType();
} }
//noinspection SuspiciousMethodCalls //noinspection SuspiciousMethodCalls
KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType)); KotlinType primitiveType = primitives.invoke().kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType));
if (primitiveType == null) { if (primitiveType == null) {
throw new IllegalStateException("not array: " + arrayType); throw new IllegalStateException("not array: " + arrayType);
} }
@@ -707,7 +755,7 @@ public abstract class KotlinBuiltIns {
@NotNull @NotNull
public SimpleType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) { public SimpleType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) {
return primitiveTypeToArrayKotlinType.get(primitiveType); return primitives.invoke().primitiveTypeToArrayKotlinType.get(primitiveType);
} }
/** /**
@@ -715,7 +763,7 @@ public abstract class KotlinBuiltIns {
*/ */
@Nullable @Nullable
public SimpleType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) { public SimpleType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) {
return primitiveKotlinTypeToKotlinArrayType.get(kotlinType); return primitives.invoke().primitiveKotlinTypeToKotlinArrayType.get(kotlinType);
} }
public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) { public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {