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 da31f6f15e8..cf7f135ea97 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 @@ -16,8 +16,6 @@ package org.jetbrains.jet.lang.resolve.lazy; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,6 +27,7 @@ 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 static org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils.safeNameForLazyResolve; @@ -37,15 +36,14 @@ public abstract class AbstractLazyMemberScope classDescriptors; + private final ConcurrentMap objectDescriptors; - private final Map classDescriptors = Maps.newHashMap(); - private final Map objectDescriptors = Maps.newHashMap(); + private final ConcurrentMap> functionDescriptors; + private final ConcurrentMap> propertyDescriptors; - protected final Map> functionDescriptors = Maps.newHashMap(); - private final Map> propertyDescriptors = Maps.newHashMap(); - - protected final List allDescriptors = Lists.newArrayList(); + private final Collection allDescriptors; + protected volatile boolean allDescriptorsComputed = false; protected AbstractLazyMemberScope( @NotNull ResolveSession resolveSession, @@ -55,10 +53,17 @@ public abstract class AbstractLazyMemberScope cache, @NotNull Name name, boolean object) { + private ClassDescriptor getClassOrObjectDescriptor(@NotNull ConcurrentMap cache, @NotNull Name name, boolean object) { ClassDescriptor known = cache.get(name); if (known != null) return known; @@ -77,9 +82,11 @@ public abstract class AbstractLazyMemberScope oldValue = functionDescriptors.putIfAbsent(name, result); + if (oldValue != null) return oldValue; + + registerDescriptors(result); } return result; } @@ -170,8 +179,10 @@ public abstract class AbstractLazyMemberScope oldValue = propertyDescriptors.putIfAbsent(name, result); + if (oldValue != null) return oldValue; + + registerDescriptors(result); } return result; } @@ -208,6 +219,16 @@ public abstract class AbstractLazyMemberScope descriptors) { + assert !allDescriptorsComputed : "getAllDescriptors() has been called already"; + allDescriptors.addAll(descriptors); + } + @NotNull @Override public Collection getAllDescriptors() { 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 f6e353d225b..a36d65ca9f9 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,9 @@ 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; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,8 +66,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope extract(@NotNull JetType extractFrom, @NotNull Name name); } - private ConstructorDescriptor primaryConstructor; - private boolean primaryConstructorResolved = false; + private final LazyValue> primaryConstructor; public LazyClassMemberScope( @NotNull ResolveSession resolveSession, @@ -73,6 +74,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope>() { + @Override + public Optional compute() { + return Optional.fromNullable(resolvePrimaryConstructor()); + } + }); } @NotNull @@ -331,9 +338,12 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope { - private final Map packageDescriptors = Maps.newHashMap(); + private final ConcurrentMap packageDescriptors; public LazyPackageMemberScope(@NotNull ResolveSession resolveSession, @NotNull PackageMemberDeclarationProvider declarationProvider, @NotNull NamespaceDescriptor thisPackage) { super(resolveSession, declarationProvider, thisPackage); + + this.packageDescriptors = resolveSession.getStorageManager().createConcurrentMap(); } @Override public NamespaceDescriptor getNamespace(@NotNull Name name) { NamespaceDescriptor known = packageDescriptors.get(name); if (known != null) return known; + if (allDescriptorsComputed) return null; if (!declarationProvider.isPackageDeclared(name)) return null; @@ -52,8 +54,10 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope(); } + @Override + public Collection createConcurrentCollection() { + return new ConcurrentLinkedQueue(); + } + @NotNull @Override public LazyValue createLazyValue(@NotNull Computable computable) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/StorageManager.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/StorageManager.java index 6f553db0ecd..65d37686268 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/StorageManager.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/StorageManager.java @@ -20,12 +20,15 @@ import com.intellij.openapi.util.Computable; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.resolve.BindingTrace; +import java.util.Collection; import java.util.concurrent.ConcurrentMap; public interface StorageManager { @NotNull ConcurrentMap createConcurrentMap(); + Collection createConcurrentCollection(); + @NotNull LazyValue createLazyValue(@NotNull Computable computable);