diff --git a/idea/src/org/jetbrains/jet/plugin/references/StandardLibraryReferenceResolver.java b/idea/src/org/jetbrains/jet/plugin/references/StandardLibraryReferenceResolver.java index 924bb0425c4..f92a6ab4d07 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/StandardLibraryReferenceResolver.java +++ b/idea/src/org/jetbrains/jet/plugin/references/StandardLibraryReferenceResolver.java @@ -53,10 +53,8 @@ import java.util.Collections; import java.util.List; public class StandardLibraryReferenceResolver extends AbstractProjectComponent { - @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private BindingContext bindingContext = null; - private final Object lock = new Object(); private final FqName TUPLE0_FQ_NAME = DescriptorUtils.getFQName(KotlinBuiltIns.getInstance().getTuple(0)).toSafe(); public StandardLibraryReferenceResolver( @@ -72,50 +70,46 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent { StartupManager.getInstance(myProject).registerPostStartupActivity(new Runnable() { @Override public void run() { - ensureInitialized(); + initialize(); } }); } - private void ensureInitialized() { - synchronized (lock) { - if (bindingContext != null) { - return; + private void initialize() { + assert bindingContext == null : "Attempt to initialize twice"; + + 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 jetFilesIndependentOfUnit = new Predicate() { + @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(); - FakeJetNamespaceDescriptor jetNamespace = new FakeJetNamespaceDescriptor(); - context.record(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, KotlinBuiltIns.getInstance().getBuiltInsPackageFqName(), jetNamespace); + ClassDescriptor tuple0 = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, TUPLE0_FQ_NAME); + assert tuple0 != null : "Can't find the declaration for Tuple0. Please invoke File -> Invalidate Caches..."; + 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, - "Builtin classes scope"); - scope.changeLockLevel(WritableScope.LockLevel.BOTH); - jetNamespace.setMemberScope(scope); + TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace, + getJetFiles("jet", Predicates.not(jetFilesIndependentOfUnit))); - Predicate jetFilesIndependentOfUnit = new Predicate() { - @Override - public boolean apply(@Nullable JetFile file) { - return "Unit.jet".equals(file.getName()); - } - }; - TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace, - getJetFiles("jet", jetFilesIndependentOfUnit)); + AnalyzingUtils.throwExceptionOnErrors(context.getBindingContext()); - ClassDescriptor tuple0 = context.get(BindingContext.FQNAME_TO_CLASS_DESCRIPTOR, TUPLE0_FQ_NAME); - 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(); - } + bindingContext = context.getBindingContext(); } private List getJetFiles(String dir, final Predicate filter) { @@ -132,7 +126,7 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent { vf.refresh(false, true); PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(vf); - assert psiDirectory != null; + assert psiDirectory != null : "No PsiDirectory for " + vf; return ContainerUtil.mapNotNull(psiDirectory.getFiles(), new Function() { @Override public JetFile fun(PsiFile file) { @@ -200,7 +194,10 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent { @NotNull public Collection resolveStandardLibrarySymbol(@NotNull BindingContext originalContext, @Nullable JetReferenceExpression referenceExpression) { - ensureInitialized(); + if (bindingContext == null) { + return Collections.emptyList(); + } + DeclarationDescriptor declarationDescriptor = originalContext.get(BindingContext.REFERENCE_TARGET, referenceExpression); return declarationDescriptor != null ? resolveStandardLibrarySymbol(declarationDescriptor) : Collections.emptyList(); @@ -208,7 +205,10 @@ public class StandardLibraryReferenceResolver extends AbstractProjectComponent { @NotNull public Collection resolveStandardLibrarySymbol(@NotNull DeclarationDescriptor declarationDescriptor) { - ensureInitialized(); + if (bindingContext == null) { + return Collections.emptyList(); + } + DeclarationDescriptor descriptor = declarationDescriptor; descriptor = descriptor.getOriginal(); diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java index a60351619ee..25ebf878a6c 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java @@ -22,7 +22,9 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.startup.StartupManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import junit.framework.Assert; @@ -34,6 +36,11 @@ import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings; import java.io.File; public class CompletionHandlerTest extends LightCompletionTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); + } public void testClassCompletionImport() { doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n'); diff --git a/idea/tests/org/jetbrains/jet/resolve/ResolveBaseTest.java b/idea/tests/org/jetbrains/jet/resolve/ResolveBaseTest.java index 0081af7b016..e8823e817d3 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ResolveBaseTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/ResolveBaseTest.java @@ -16,7 +16,9 @@ package org.jetbrains.jet.resolve; +import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.startup.StartupManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; import com.intellij.psi.PsiReference; @@ -30,6 +32,12 @@ import org.jetbrains.jet.testing.ReferenceUtils; import java.io.File; public class ResolveBaseTest extends LightCodeInsightTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); + } + public void testMultiResolve() throws Exception { doMultiResolveTest(); }