From e402c4d527a8d41a91fe3cf7efb4e0bbf17d578d Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 7 Aug 2013 14:44:05 +0400 Subject: [PATCH] Guard creation of LazyClassDescriptor with lock to avoid getting 'this' in invalid state --- .../jet/lang/resolve/lazy/ResolveSession.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index c8596e57455..bff81905d3f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.lazy; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; @@ -193,7 +194,7 @@ public class ResolveSession implements KotlinCodeAnalyzer { /*package*/ LazyClassDescriptor getClassObjectDescriptor(JetClassObject classObject) { JetClass aClass = PsiTreeUtil.getParentOfType(classObject, JetClass.class); - LazyClassDescriptor parentClassDescriptor; + final LazyClassDescriptor parentClassDescriptor; if (aClass != null) { parentClassDescriptor = (LazyClassDescriptor) getClassDescriptor(aClass); @@ -212,10 +213,16 @@ public class ResolveSession implements KotlinCodeAnalyzer { if (declaration == null) { // It's possible that there are several class objects and another class object is taking part in lazy resolve. We still want to // build descriptors for such class objects. - JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject); + final JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject); if (classObjectInfo != null) { - Name name = DescriptorUtils.getClassObjectName(parentClassDescriptor.getName().asString()); - return new LazyClassDescriptor(this, parentClassDescriptor, name, classObjectInfo); + final Name name = DescriptorUtils.getClassObjectName(parentClassDescriptor.getName().asString()); + return storageManager.compute(new Computable() { + @Override + public LazyClassDescriptor compute() { + // Create under lock to avoid premature access to published 'this' + return new LazyClassDescriptor(ResolveSession.this, parentClassDescriptor, name, classObjectInfo); + } + }); } }