From ce0d81f6707f3fcb9ea6ac91455513b549e1e02f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 7 Oct 2016 19:09:55 +0200 Subject: [PATCH] to avoid running resolve under ClsTypeElement lock, return empty modifier list if we're currently calculating the return type (the modifier list is requested to apply type annotations, and we don't care about them anyway) #KT-12966 Fixed --- .../resolve/jvm/KotlinJavaPsiFacade.java | 9 ++++++++ .../kotlin/asJava/elements/KtLightMethod.kt | 21 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java index b999fb4e21f..23316e900cf 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java @@ -28,6 +28,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.PsiElementFinderImpl; import com.intellij.psi.impl.file.PsiPackageImpl; import com.intellij.psi.impl.file.impl.JavaFileManager; +import com.intellij.psi.impl.light.LightModifierList; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.reference.SoftReference; @@ -41,6 +42,7 @@ import kotlin.collections.CollectionsKt; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.name.ClassId; @@ -62,6 +64,7 @@ public class KotlinJavaPsiFacade { private volatile SoftReference packageCache; private final Project project; + private final LightModifierList emptyModifierList; public static KotlinJavaPsiFacade getInstance(Project project) { return ServiceManager.getService(project, KotlinJavaPsiFacade.class); @@ -70,6 +73,8 @@ public class KotlinJavaPsiFacade { public KotlinJavaPsiFacade(@NotNull Project project) { this.project = project; + emptyModifierList = new LightModifierList(PsiManager.getInstance(project), KotlinLanguage.INSTANCE); + final PsiModificationTracker modificationTracker = PsiManager.getInstance(project).getModificationTracker(); MessageBus bus = project.getMessageBus(); @@ -88,6 +93,10 @@ public class KotlinJavaPsiFacade { }); } + public LightModifierList getEmptyModifierList() { + return emptyModifierList; + } + public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethod.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethod.kt index d66c740f93b..189df4a0335 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethod.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightMethod.kt @@ -21,6 +21,7 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.* import com.intellij.psi.impl.compiled.ClsTypeElementImpl import com.intellij.psi.impl.light.LightMethod +import com.intellij.psi.impl.light.LightModifierList import com.intellij.psi.scope.PsiScopeProcessor import com.intellij.psi.util.* import com.intellij.util.IncorrectOperationException @@ -33,6 +34,7 @@ import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind interface KtLightMethod : PsiMethod, KtLightDeclaration { @@ -53,6 +55,8 @@ sealed class KtLightMethodImpl( delegateTypeElement?.let { ClsTypeElementImpl(this, it.canonicalText, /*ClsTypeElementImpl.VARIANCE_NONE */ 0.toChar()) } } + private val calculatingReturnType = ThreadLocal() + override fun getContainingClass(): KtLightClass = super.getContainingClass() as KtLightClass private val paramsList: CachedValue by lazy(LazyThreadSafetyMode.PUBLICATION) { @@ -141,7 +145,12 @@ sealed class KtLightMethodImpl( else clsDelegate.modifierList } - override fun getModifierList() = _modifierList + override fun getModifierList(): PsiModifierList { + if (calculatingReturnType.get() == true) { + return KotlinJavaPsiFacade.getInstance(project).emptyModifierList + } + return _modifierList + } override fun getNameIdentifier() = lightIdentifier @@ -206,7 +215,15 @@ sealed class KtLightMethodImpl( // which is relied upon by java type inference override fun getReturnTypeElement(): PsiTypeElement? = returnTypeElem - override fun getReturnType() = returnTypeElement?.type + override fun getReturnType(): PsiType? { + calculatingReturnType.set(true) + try { + return returnTypeElement?.type + } + finally { + calculatingReturnType.set(false) + } + } companion object Factory { fun create(