Extract LazyResolveStorageManager interface

StorageManager will be available at runtime, thus it can't depend on
BindingTrace
This commit is contained in:
Alexander Udalov
2013-09-11 17:51:49 +02:00
committed by Alexander Udalov
parent f35472414b
commit 54ee7456ce
10 changed files with 178 additions and 135 deletions
@@ -35,7 +35,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap; import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedLazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -85,7 +85,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
final PsiClassFinder psiClassFinder = injector.getPsiClassFinder(); final PsiClassFinder psiClassFinder = injector.getPsiClassFinder();
// TODO: Replace with stub declaration provider // TODO: Replace with stub declaration provider
LockBasedStorageManager storageManager = new LockBasedStorageManager(); LockBasedLazyResolveStorageManager storageManager = new LockBasedLazyResolveStorageManager();
FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(storageManager, files, new Predicate<FqName>() { FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(storageManager, files, new Predicate<FqName>() {
@Override @Override
public boolean apply(FqName fqName) { public boolean apply(FqName fqName) {
@@ -38,7 +38,7 @@ import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFacto
import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider; import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider;
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor; import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyPackageDescriptor; import org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyPackageDescriptor;
import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -57,7 +57,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
} }
}; };
private final StorageManager storageManager; private final LazyResolveStorageManager storageManager;
private final ModuleDescriptor module; private final ModuleDescriptor module;
private final LazyPackageDescriptor rootPackage; private final LazyPackageDescriptor rootPackage;
@@ -74,7 +74,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
public ResolveSession( public ResolveSession(
@NotNull Project project, @NotNull Project project,
@NotNull StorageManager storageManager, @NotNull LazyResolveStorageManager storageManager,
@NotNull ModuleDescriptorImpl rootDescriptor, @NotNull ModuleDescriptorImpl rootDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory @NotNull DeclarationProviderFactory declarationProviderFactory
) { ) {
@@ -85,7 +85,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
public ResolveSession( public ResolveSession(
@NotNull Project project, @NotNull Project project,
@NotNull StorageManager storageManager, @NotNull LazyResolveStorageManager storageManager,
@NotNull ModuleDescriptorImpl rootDescriptor, @NotNull ModuleDescriptorImpl rootDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory, @NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace delegationTrace @NotNull BindingTrace delegationTrace
@@ -102,7 +102,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
@Deprecated // Internal use only @Deprecated // Internal use only
public ResolveSession( public ResolveSession(
@NotNull Project project, @NotNull Project project,
@NotNull StorageManager storageManager, @NotNull LazyResolveStorageManager storageManager,
@NotNull ModuleDescriptorImpl rootDescriptor, @NotNull ModuleDescriptorImpl rootDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory, @NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull Function<FqName, Name> classifierAliases, @NotNull Function<FqName, Name> classifierAliases,
@@ -138,7 +138,7 @@ public class ResolveSession implements KotlinCodeAnalyzer {
} }
@NotNull @NotNull
public StorageManager getStorageManager() { public LazyResolveStorageManager getStorageManager() {
return storageManager; return storageManager;
} }
@@ -0,0 +1,25 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.lazy.storage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace;
public interface LazyResolveStorageManager extends StorageManager {
@NotNull
BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace);
}
@@ -0,0 +1,136 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve.lazy.storage;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
public class LockBasedLazyResolveStorageManager extends LockBasedStorageManager implements LazyResolveStorageManager {
@NotNull
@Override
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
// It seems safe to have a separate lock for traces:
// no other locks will be acquired inside the trace operations
return new LockProtectedTrace(lock, originalTrace);
}
private static class LockProtectedContext implements BindingContext {
private final Object lock;
private final BindingContext context;
private LockProtectedContext(Object lock, BindingContext context) {
this.lock = lock;
this.context = context;
}
@NotNull
@Override
public Collection<Diagnostic> getDiagnostics() {
synchronized (lock) {
return context.getDiagnostics();
}
}
@Nullable
@Override
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) {
return context.get(slice, key);
}
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) {
return context.getKeys(slice);
}
}
@NotNull
@Override
@TestOnly
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
synchronized (lock) {
return context.getSliceContents(slice);
}
}
}
private static class LockProtectedTrace implements BindingTrace {
private final Object lock;
private final BindingTrace trace;
private final BindingContext context;
public LockProtectedTrace(@NotNull Object lock, @NotNull BindingTrace trace) {
this.lock = lock;
this.trace = trace;
this.context = new LockProtectedContext(lock, trace.getBindingContext());
}
@Override
public BindingContext getBindingContext() {
return context;
}
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
synchronized (lock) {
trace.record(slice, key, value);
}
}
@Override
public <K> void record(WritableSlice<K, Boolean> slice, K key) {
synchronized (lock) {
trace.record(slice, key);
}
}
@Override
@Nullable
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) {
return trace.get(slice, key);
}
}
@Override
@NotNull
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) {
return trace.getKeys(slice);
}
}
@Override
public void report(@NotNull Diagnostic diagnostic) {
synchronized (lock) {
trace.report(diagnostic);
}
}
}
}
@@ -16,29 +16,21 @@
package org.jetbrains.jet.lang.resolve.lazy.storage; package org.jetbrains.jet.lang.resolve.lazy.storage;
import com.google.common.collect.ImmutableMap;
import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer; import com.intellij.util.Consumer;
import com.intellij.util.Function; import com.intellij.util.Function;
import com.intellij.util.containers.ConcurrentWeakValueHashMap; import com.intellij.util.containers.ConcurrentWeakValueHashMap;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import org.jetbrains.jet.utils.ExceptionUtils; import org.jetbrains.jet.utils.ExceptionUtils;
import org.jetbrains.jet.utils.WrappedValues; import org.jetbrains.jet.utils.WrappedValues;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
public class LockBasedStorageManager implements StorageManager { public class LockBasedStorageManager implements StorageManager {
private final Object lock = new Object() { protected final Object lock = new Object() {
@Override @Override
public String toString() { public String toString() {
return "LockBasedStorageManager centralized lock"; return "LockBasedStorageManager centralized lock";
@@ -103,14 +95,6 @@ public class LockBasedStorageManager implements StorageManager {
}; };
} }
@NotNull
@Override
public BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace) {
// It seems safe to have a separate lock for traces:
// no other locks will be acquired inside the trace operations
return new LockProtectedTrace(lock, originalTrace);
}
@Override @Override
public <T> T compute(@NotNull Computable<T> computable) { public <T> T compute(@NotNull Computable<T> computable) {
synchronized (lock) { synchronized (lock) {
@@ -228,102 +212,4 @@ public class LockBasedStorageManager implements StorageManager {
return result; return result;
} }
} }
private static class LockProtectedContext implements BindingContext {
private final Object lock;
private final BindingContext context;
private LockProtectedContext(Object lock, BindingContext context) {
this.lock = lock;
this.context = context;
}
@NotNull
@Override
public Collection<Diagnostic> getDiagnostics() {
synchronized (lock) {
return context.getDiagnostics();
}
}
@Nullable
@Override
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) {
return context.get(slice, key);
}
}
@NotNull
@Override
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) {
return context.getKeys(slice);
}
}
@NotNull
@Override
@TestOnly
public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
synchronized (lock) {
return context.getSliceContents(slice);
}
}
}
private static class LockProtectedTrace implements BindingTrace {
private final Object lock;
private final BindingTrace trace;
private final BindingContext context;
public LockProtectedTrace(@NotNull Object lock, @NotNull BindingTrace trace) {
this.lock = lock;
this.trace = trace;
this.context = new LockProtectedContext(lock, trace.getBindingContext());
}
@Override
public BindingContext getBindingContext() {
return context;
}
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
synchronized (lock) {
trace.record(slice, key, value);
}
}
@Override
public <K> void record(WritableSlice<K, Boolean> slice, K key) {
synchronized (lock) {
trace.record(slice, key);
}
}
@Override
@Nullable
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
synchronized (lock) {
return trace.get(slice, key);
}
}
@Override
@NotNull
public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
synchronized (lock) {
return trace.getKeys(slice);
}
}
@Override
public void report(@NotNull Diagnostic diagnostic) {
synchronized (lock) {
trace.report(diagnostic);
}
}
}
} }
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.Computable;
import com.intellij.util.Consumer; import com.intellij.util.Consumer;
import com.intellij.util.Function; import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.BindingTrace;
public interface StorageManager { public interface StorageManager {
/** /**
@@ -56,9 +55,6 @@ public interface StorageManager {
@NotNull @NotNull
<T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(@NotNull Computable<T> computable, @NotNull Consumer<T> postCompute); <T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(@NotNull Computable<T> computable, @NotNull Consumer<T> postCompute);
@NotNull
BindingTrace createSafeTrace(@NotNull BindingTrace originalTrace);
<T> T compute(@NotNull Computable<T> computable); <T> T compute(@NotNull Computable<T> computable);
enum ReferenceKind { enum ReferenceKind {
@@ -30,7 +30,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedLazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -56,7 +56,7 @@ public abstract class AbstractLazyResolveDescriptorRendererTest extends KotlinTe
ModuleDescriptorImpl lazyModule = AnalyzerFacadeForJVM.createJavaModule("<lazy module>"); ModuleDescriptorImpl lazyModule = AnalyzerFacadeForJVM.createJavaModule("<lazy module>");
lazyModule.setModuleConfiguration(injectorForTopDownAnalyzer.getModuleDescriptor().getModuleConfiguration()); lazyModule.setModuleConfiguration(injectorForTopDownAnalyzer.getModuleDescriptor().getModuleConfiguration());
LockBasedStorageManager storageManager = new LockBasedStorageManager(); LockBasedLazyResolveStorageManager storageManager = new LockBasedLazyResolveStorageManager();
final ResolveSession resolveSession = new ResolveSession(getProject(), storageManager, lazyModule, final ResolveSession resolveSession = new ResolveSession(getProject(), storageManager, lazyModule,
new FileBasedDeclarationProviderFactory(storageManager, files)); new FileBasedDeclarationProviderFactory(storageManager, files));
@@ -44,7 +44,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.PsiClassFinder; import org.jetbrains.jet.lang.resolve.java.PsiClassFinder;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedLazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -96,7 +96,7 @@ public class LazyResolveTestUtil {
final PsiClassFinder psiClassFinder = injector.getPsiClassFinder(); final PsiClassFinder psiClassFinder = injector.getPsiClassFinder();
final JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); final JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
LockBasedStorageManager storageManager = new LockBasedStorageManager(); LockBasedLazyResolveStorageManager storageManager = new LockBasedLazyResolveStorageManager();
FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(storageManager, files, new Predicate<FqName>() { FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(storageManager, files, new Predicate<FqName>() {
@Override @Override
public boolean apply(FqName fqName) { public boolean apply(FqName fqName) {
@@ -55,7 +55,7 @@ import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer; import org.jetbrains.jet.lang.resolve.lazy.KotlinCodeAnalyzer;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedLazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.TypeUtils;
@@ -214,7 +214,7 @@ public class JetSourceNavigationHelper {
} }
Project project = decompiledDeclaration.getProject(); Project project = decompiledDeclaration.getProject();
LockBasedStorageManager storageManager = new LockBasedStorageManager(); LockBasedLazyResolveStorageManager storageManager = new LockBasedLazyResolveStorageManager();
FileBasedDeclarationProviderFactory providerFactory = new FileBasedDeclarationProviderFactory(storageManager, getContainingFiles(candidates), FileBasedDeclarationProviderFactory providerFactory = new FileBasedDeclarationProviderFactory(storageManager, getContainingFiles(candidates),
new Predicate<FqName>() { new Predicate<FqName>() {
@Override @Override
@@ -32,7 +32,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedLazyResolveStorageManager;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.k2js.config.Config; import org.jetbrains.k2js.config.Config;
@@ -140,7 +140,7 @@ public final class AnalyzerFacadeForJS {
@NotNull @NotNull
public static ResolveSession getLazyResolveSession(Collection<JetFile> files, Config config) { public static ResolveSession getLazyResolveSession(Collection<JetFile> files, Config config) {
LockBasedStorageManager storageManager = new LockBasedStorageManager(); LockBasedLazyResolveStorageManager storageManager = new LockBasedLazyResolveStorageManager();
FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory( FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(
storageManager, Config.withJsLibAdded(files, config), Predicates.<FqName>alwaysFalse()); storageManager, Config.withJsLibAdded(files, config), Predicates.<FqName>alwaysFalse());
ModuleDescriptorImpl lazyModule = createJsModule("<lazy module>"); ModuleDescriptorImpl lazyModule = createJsModule("<lazy module>");