diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java index cf7f135ea97..ad6b25648f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyMemberScope.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.lazy; import com.google.common.collect.Sets; +import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -26,21 +27,24 @@ import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import java.util.*; -import java.util.concurrent.ConcurrentMap; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; import static org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve; +import static org.jetbrains.jet.lang.resolve.lazy.StorageManager.MemoizationMode.STRONG; public abstract class AbstractLazyMemberScope implements JetScope { protected final ResolveSession resolveSession; protected final DP declarationProvider; protected final D thisDescriptor; - private final ConcurrentMap classDescriptors; - private final ConcurrentMap objectDescriptors; + private final Function classDescriptors; + private final Function objectDescriptors; - private final ConcurrentMap> functionDescriptors; - private final ConcurrentMap> propertyDescriptors; + private final Function> functionDescriptors; + private final Function> propertyDescriptors; private final Collection allDescriptors; protected volatile boolean allDescriptorsComputed = false; @@ -55,25 +59,40 @@ public abstract class AbstractLazyMemberScope() { + @Override + public ClassDescriptor fun(Name name) { + return resolveClassOrObjectDescriptor(name, false); + } + }, STRONG); + this.objectDescriptors = storageManager.createMemoizedFunctionWithNullableValues(new Function() { + @Override + public ClassDescriptor fun(Name name) { + return resolveClassOrObjectDescriptor(name, true); + } + }, STRONG); + + this.functionDescriptors = storageManager.createMemoizedFunction(new Function>() { + @Override + public Set fun(Name name) { + return doGetFunctions(name); + } + }, STRONG); + this.propertyDescriptors = storageManager.createMemoizedFunction(new Function>() { + @Override + public Set fun(Name name) { + return doGetProperties(name); + } + }, STRONG); + this.allDescriptors = storageManager.createConcurrentCollection(); } @Nullable - private ClassDescriptor getClassOrObjectDescriptor(@NotNull ConcurrentMap cache, @NotNull Name name, boolean object) { - ClassDescriptor known = cache.get(name); - if (known != null) return known; - - if (allDescriptorsComputed) return null; - + private ClassDescriptor resolveClassOrObjectDescriptor(@NotNull Name name, boolean object) { Collection classOrObjectDeclarations = declarationProvider.getClassOrObjectDeclarations(name); if (classOrObjectDeclarations.isEmpty()) return null; - ClassDescriptor result = null; - for (JetClassOrObject classOrObjectDeclaration : classOrObjectDeclarations) { // TODO: when enum entries with constructors are dropped, replace with declaresObjectOrEnumConstant() @@ -82,16 +101,13 @@ public abstract class AbstractLazyMemberScope getFunctions(@NotNull Name name) { - Set known = functionDescriptors.get(name); - if (known != null) return known; - - // If all descriptors are already computed, we are - if (allDescriptorsComputed) return Collections.emptySet(); + return functionDescriptors.fun(name); + } + @NotNull + private Set doGetFunctions(@NotNull Name name) { Set result = Sets.newLinkedHashSet(); Collection declarations = declarationProvider.getFunctionDeclarations(name); @@ -130,9 +145,6 @@ public abstract class AbstractLazyMemberScope oldValue = functionDescriptors.putIfAbsent(name, result); - if (oldValue != null) return oldValue; - registerDescriptors(result); } return result; @@ -146,12 +158,11 @@ public abstract class AbstractLazyMemberScope getProperties(@NotNull Name name) { - Set known = propertyDescriptors.get(name); - if (known != null) return known; - - // If all descriptors are already computed, we are - if (allDescriptorsComputed) return Collections.emptySet(); + return propertyDescriptors.fun(name); + } + @NotNull + public Set doGetProperties(@NotNull Name name) { Set result = Sets.newLinkedHashSet(); Collection declarations = declarationProvider.getPropertyDeclarations(name); @@ -178,12 +189,8 @@ public abstract class AbstractLazyMemberScope oldValue = propertyDescriptors.putIfAbsent(name, result); - if (oldValue != null) return oldValue; + registerDescriptors(result); - registerDescriptors(result); - } return result; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/FileBasedDeclarationProviderFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/FileBasedDeclarationProviderFactory.java index 50e88467886..42dcb8325fc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/FileBasedDeclarationProviderFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/FileBasedDeclarationProviderFactory.java @@ -23,7 +23,9 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.intellij.openapi.util.Computable; +import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespaceHeader; import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo; @@ -31,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import java.util.Collection; import java.util.Set; -import java.util.concurrent.ConcurrentMap; public class FileBasedDeclarationProviderFactory implements DeclarationProviderFactory { @@ -45,7 +46,7 @@ public class FileBasedDeclarationProviderFactory implements DeclarationProviderF private final StorageManager storageManager; private final LazyValue index; - private final ConcurrentMap packageDeclarationProviders; + private final Function packageDeclarationProviders; public FileBasedDeclarationProviderFactory(@NotNull StorageManager storageManager, @NotNull Collection files) { this(storageManager, files, Predicates.alwaysFalse()); @@ -64,7 +65,12 @@ public class FileBasedDeclarationProviderFactory implements DeclarationProviderF return computeFilesByPackage(files); } }); - this.packageDeclarationProviders = storageManager.createConcurrentMap(); + this.packageDeclarationProviders = storageManager.createMemoizedFunctionWithNullableValues(new Function() { + @Override + public PackageMemberDeclarationProvider fun(FqName fqName) { + return createPackageMemberDeclarationProvider(fqName); + } + }, StorageManager.MemoizationMode.STRONG); } @NotNull @@ -109,11 +115,11 @@ public class FileBasedDeclarationProviderFactory implements DeclarationProviderF @Override public PackageMemberDeclarationProvider getPackageMemberDeclarationProvider(@NotNull FqName packageFqName) { - PackageMemberDeclarationProvider cached = packageDeclarationProviders.get(packageFqName); - if (cached != null) { - return cached; - } + return packageDeclarationProviders.fun(packageFqName); + } + @Nullable + public PackageMemberDeclarationProvider createPackageMemberDeclarationProvider(@NotNull FqName packageFqName) { if (!isPackageDeclaredExplicitly(packageFqName)) { if (isPackageDeclaredExternally.apply(packageFqName)) { return EmptyPackageMemberDeclarationProvider.INSTANCE; @@ -121,15 +127,7 @@ public class FileBasedDeclarationProviderFactory implements DeclarationProviderF return null; } - FileBasedPackageMemberDeclarationProvider provider = - new FileBasedPackageMemberDeclarationProvider(storageManager, packageFqName, this, index.get().filesByPackage.get(packageFqName)); - - PackageMemberDeclarationProvider oldValue = packageDeclarationProviders.putIfAbsent(packageFqName, provider); - if (oldValue != null) { - return oldValue; - } - - return provider; + return new FileBasedPackageMemberDeclarationProvider(storageManager, packageFqName, this, index.get().filesByPackage.get(packageFqName)); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 698386e16b6..1067bf0d781 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve.lazy; -import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; @@ -71,7 +70,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc private final LazyValue thisAsReceiverParameter; private final LazyValue> annotations; - private final LazyValue> classObjectDescriptor; + private final LazyValue classObjectDescriptor; private final LazyClassMemberScope unsubstitutedMemberScope; private final JetScope unsubstitutedInnerClassesScope; @@ -129,10 +128,10 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc return resolveAnnotations(); } }); - this.classObjectDescriptor = storageManager.createLazyValue(new Computable>() { + this.classObjectDescriptor = storageManager.createNullableLazyValue(new Computable() { @Override - public Optional compute() { - return Optional.fromNullable(computeClassObjectDescriptor()); + public ClassDescriptor compute() { + return computeClassObjectDescriptor(); } }); this.scopeForClassHeaderResolution = storageManager.createLazyValue(new Computable() { @@ -273,7 +272,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc @Override public ClassDescriptor getClassObjectDescriptor() { - return classObjectDescriptor.get().orNull(); + return classObjectDescriptor.get(); } @Nullable diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java index a36d65ca9f9..2c2768d9525 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassMemberScope.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve.lazy; -import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiElement; @@ -66,7 +65,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope extract(@NotNull JetType extractFrom, @NotNull Name name); } - private final LazyValue> primaryConstructor; + private final LazyValue primaryConstructor; public LazyClassMemberScope( @NotNull ResolveSession resolveSession, @@ -74,10 +73,10 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope>() { + this.primaryConstructor = resolveSession.getStorageManager().createNullableLazyValue(new Computable() { @Override - public Optional compute() { - return Optional.fromNullable(resolvePrimaryConstructor()); + public ConstructorDescriptor compute() { + return resolvePrimaryConstructor(); } }); } @@ -338,7 +337,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope { - private final ConcurrentMap packageDescriptors; + private final Function packageDescriptors; public LazyPackageMemberScope(@NotNull ResolveSession resolveSession, @NotNull PackageMemberDeclarationProvider declarationProvider, @NotNull NamespaceDescriptor thisPackage) { super(resolveSession, declarationProvider, thisPackage); - this.packageDescriptors = resolveSession.getStorageManager().createConcurrentMap(); + this.packageDescriptors = resolveSession.getStorageManager().createMemoizedFunctionWithNullableValues(new Function() { + @Override + public NamespaceDescriptor fun(Name name) { + return createPackageDescriptor(name); + } + }, StorageManager.MemoizationMode.STRONG); } @Override public NamespaceDescriptor getNamespace(@NotNull Name name) { - NamespaceDescriptor known = packageDescriptors.get(name); - if (known != null) return known; - - if (allDescriptorsComputed) return null; + return packageDescriptors.fun(name); + } + @Nullable + public NamespaceDescriptor createPackageDescriptor(@NotNull Name name) { if (!declarationProvider.isPackageDeclared(name)) return null; PackageMemberDeclarationProvider packageMemberDeclarationProvider = resolveSession.getDeclarationProviderFactory().getPackageMemberDeclarationProvider( @@ -54,9 +60,6 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope