Unneeded lock & on-demand initialization removed

This commit is contained in:
Andrey Breslav
2012-12-26 15:32:22 +04:00
parent f26412aae4
commit 1a7b7db67f
3 changed files with 55 additions and 40 deletions
@@ -53,10 +53,8 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class StandardLibraryReferenceResolver extends AbstractProjectComponent { public class StandardLibraryReferenceResolver extends AbstractProjectComponent {
@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
private BindingContext bindingContext = null; private BindingContext bindingContext = null;
private final Object lock = new Object();
private final FqName TUPLE0_FQ_NAME = DescriptorUtils.getFQName(KotlinBuiltIns.getInstance().getTuple(0)).toSafe(); private final FqName TUPLE0_FQ_NAME = DescriptorUtils.getFQName(KotlinBuiltIns.getInstance().getTuple(0)).toSafe();
public StandardLibraryReferenceResolver( public StandardLibraryReferenceResolver(
@@ -72,50 +70,46 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent {
StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() {
@Override @Override
public void run() { public void run() {
ensureInitialized(); initialize();
} }
}); });
} }
private void ensureInitialized() { private void initialize() {
synchronized (lock) { assert bindingContext == null : "Attempt to initialize twice";
if (bindingContext != null) {
return; BindingTraceContext context = new BindingTraceContext();
FakeJetNamespaceDescriptor jetNamespace = new FakeJetNamespaceDescriptor();
context.record(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, KotlinBuiltIns.getInstance().getBuiltInsPackageFqName(), jetNamespace);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, jetNamespace, RedeclarationHandler.THROW_EXCEPTION,
"Builtin classes scope");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
jetNamespace.setMemberScope(scope);
Predicate<JetFile> jetFilesIndependentOfUnit = new Predicate<JetFile>() {
@Override
public boolean apply(@Nullable JetFile file) {
return "Unit.jet".equals(file.getName());
} }
};
TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace,
getJetFiles("jet", jetFilesIndependentOfUnit));
BindingTraceContext context = new BindingTraceContext(); ClassDescriptor tuple0 = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, TUPLE0_FQ_NAME);
FakeJetNamespaceDescriptor jetNamespace = new FakeJetNamespaceDescriptor(); assert tuple0 != null : "Can't find the declaration for Tuple0. Please invoke File -> Invalidate Caches...";
context.record(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, KotlinBuiltIns.getInstance().getBuiltInsPackageFqName(), jetNamespace); scope = new WritableScopeImpl(scope, jetNamespace, RedeclarationHandler.THROW_EXCEPTION,
"Builtin classes scope: needed to analyze builtins which depend on Unit type alias");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
scope.addClassifierAlias(KotlinBuiltIns.UNIT_ALIAS, tuple0);
jetNamespace.setMemberScope(scope);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, jetNamespace, RedeclarationHandler.THROW_EXCEPTION, TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace,
"Builtin classes scope"); getJetFiles("jet", Predicates.not(jetFilesIndependentOfUnit)));
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
jetNamespace.setMemberScope(scope);
Predicate<JetFile> jetFilesIndependentOfUnit = new Predicate<JetFile>() { AnalyzingUtils.throwExceptionOnErrors(context.getBindingContext());
@Override
public boolean apply(@Nullable JetFile file) {
return "Unit.jet".equals(file.getName());
}
};
TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace,
getJetFiles("jet", jetFilesIndependentOfUnit));
ClassDescriptor tuple0 = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, TUPLE0_FQ_NAME); bindingContext = context.getBindingContext();
assert tuple0 != null : "Can't find the declaration for Tuple0";
scope = new WritableScopeImpl(scope, jetNamespace, RedeclarationHandler.THROW_EXCEPTION,
"Builtin classes scope: needed to analyze builtins which depend on Unit type alias");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
scope.addClassifierAlias(KotlinBuiltIns.UNIT_ALIAS, tuple0);
jetNamespace.setMemberScope(scope);
TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace,
getJetFiles("jet", Predicates.not(jetFilesIndependentOfUnit)));
AnalyzingUtils.throwExceptionOnErrors(context.getBindingContext());
bindingContext = context.getBindingContext();
}
} }
private List<JetFile> getJetFiles(String dir, final Predicate<JetFile> filter) { private List<JetFile> getJetFiles(String dir, final Predicate<JetFile> filter) {
@@ -132,7 +126,7 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent {
vf.refresh(false, true); vf.refresh(false, true);
PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(vf); PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(vf);
assert psiDirectory != null; assert psiDirectory != null : "No PsiDirectory for " + vf;
return ContainerUtil.mapNotNull(psiDirectory.getFiles(), new Function<PsiFile, JetFile>() { return ContainerUtil.mapNotNull(psiDirectory.getFiles(), new Function<PsiFile, JetFile>() {
@Override @Override
public JetFile fun(PsiFile file) { public JetFile fun(PsiFile file) {
@@ -200,7 +194,10 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent {
@NotNull @NotNull
public Collection<PsiElement> resolveStandardLibrarySymbol(@NotNull BindingContext originalContext, public Collection<PsiElement> resolveStandardLibrarySymbol(@NotNull BindingContext originalContext,
@Nullable JetReferenceExpression referenceExpression) { @Nullable JetReferenceExpression referenceExpression) {
ensureInitialized(); if (bindingContext == null) {
return Collections.emptyList();
}
DeclarationDescriptor declarationDescriptor = originalContext.get(BindingContext.REFERENCE_TARGET, referenceExpression); DeclarationDescriptor declarationDescriptor = originalContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
return declarationDescriptor != null ? resolveStandardLibrarySymbol(declarationDescriptor) : Collections.<PsiElement>emptyList(); return declarationDescriptor != null ? resolveStandardLibrarySymbol(declarationDescriptor) : Collections.<PsiElement>emptyList();
@@ -208,7 +205,10 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent {
@NotNull @NotNull
public Collection<PsiElement> resolveStandardLibrarySymbol(@NotNull DeclarationDescriptor declarationDescriptor) { public Collection<PsiElement> resolveStandardLibrarySymbol(@NotNull DeclarationDescriptor declarationDescriptor) {
ensureInitialized(); if (bindingContext == null) {
return Collections.emptyList();
}
DeclarationDescriptor descriptor = declarationDescriptor; DeclarationDescriptor descriptor = declarationDescriptor;
descriptor = descriptor.getOriginal(); descriptor = descriptor.getOriginal();
@@ -22,7 +22,9 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.lookup.impl.LookupImpl; import com.intellij.codeInsight.lookup.impl.LookupImpl;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import junit.framework.Assert; import junit.framework.Assert;
@@ -34,6 +36,11 @@ import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings;
import java.io.File; import java.io.File;
public class CompletionHandlerTest extends LightCompletionTestCase { public class CompletionHandlerTest extends LightCompletionTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities();
}
public void testClassCompletionImport() { public void testClassCompletionImport() {
doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n'); doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n');
@@ -16,7 +16,9 @@
package org.jetbrains.jet.resolve; package org.jetbrains.jet.resolve;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReference;
@@ -30,6 +32,12 @@ import org.jetbrains.jet.testing.ReferenceUtils;
import java.io.File; import java.io.File;
public class ResolveBaseTest extends LightCodeInsightTestCase { public class ResolveBaseTest extends LightCodeInsightTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities();
}
public void testMultiResolve() throws Exception { public void testMultiResolve() throws Exception {
doMultiResolveTest(); doMultiResolveTest();
} }