From 16ab4bec34589cd8cc865c8284991708270f0bbe Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Wed, 20 Jan 2016 17:21:08 +0300 Subject: [PATCH] Try to diagnose NoDescriptorForDeclarationException in completion --- .../jetbrains/kotlin/frontend/di/injection.kt | 7 ++----- .../kotlin/resolve/CompilerEnvironment.kt | 2 ++ ...xception.kt => AbsentDescriptorHandler.kt} | 16 +++++++++++--- .../resolve/lazy/LazyDeclarationResolver.java | 7 +++++-- .../expressions/LocalClassifierAnalyzer.kt | 5 +++-- .../kotlin/idea/project/IdeaEnvironment.kt | 1 + .../project/IdeaLocalDescriptorResolver.kt | 21 ++++++++++++++++--- .../PluginDeclarationProviderFactory.kt | 20 ++++++++++++++++++ 8 files changed, 64 insertions(+), 15 deletions(-) rename compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/{NoDescriptorForDeclarationException.kt => AbsentDescriptorHandler.kt} (55%) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index d7119848b0c..dc646fbd71a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -22,12 +22,8 @@ import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.resolve.* -import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider -import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer -import org.jetbrains.kotlin.resolve.lazy.NoTopLevelDescriptorProvider -import org.jetbrains.kotlin.resolve.lazy.ResolveSession +import org.jetbrains.kotlin.resolve.lazy.* import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory -import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.types.expressions.DeclarationScopeProviderForLocalClassifierAnalyzer import org.jetbrains.kotlin.types.expressions.LocalClassDescriptorHolder import org.jetbrains.kotlin.types.expressions.LocalLazyDeclarationResolver @@ -90,6 +86,7 @@ fun createContainerForLazyBodyResolve( useInstance(kotlinCodeAnalyzer.getFileScopeProvider()) useInstance(bodyResolveCache) useImpl() + useImpl() } fun createContainerForLazyLocalClassifierAnalyzer( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt index 9be9236adb7..7e7d4ddf0fa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerEnvironment.kt @@ -20,10 +20,12 @@ import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.container.useInstance import org.jetbrains.kotlin.resolve.lazy.CompilerLocalDescriptorResolver +import org.jetbrains.kotlin.resolve.lazy.BasicAbsentDescriptorHandler object CompilerEnvironment : TargetEnvironment("Compiler") { override fun configure(container: StorageComponentContainer) { container.useInstance(BodyResolveCache.ThrowException) container.useImpl() + container.useImpl() } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/NoDescriptorForDeclarationException.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/AbsentDescriptorHandler.kt similarity index 55% rename from compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/NoDescriptorForDeclarationException.kt rename to compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/AbsentDescriptorHandler.kt index fa5993c92b6..61495d6adc5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/NoDescriptorForDeclarationException.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/AbsentDescriptorHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -16,8 +16,18 @@ package org.jetbrains.kotlin.resolve.lazy +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext -class NoDescriptorForDeclarationException(declaration: KtDeclaration) : - IllegalStateException("Descriptor wasn't found for declaration $declaration\n${declaration.getElementTextWithContext()}") +interface AbsentDescriptorHandler { + fun diagnoseDescriptorNotFound(declaration: KtDeclaration): DeclarationDescriptor +} + +class BasicAbsentDescriptorHandler : AbsentDescriptorHandler { + override fun diagnoseDescriptorNotFound(declaration: KtDeclaration) = throw NoDescriptorForDeclarationException(declaration) +} + +class NoDescriptorForDeclarationException @JvmOverloads constructor(declaration: KtDeclaration, additionalDetails: String? = null) : + IllegalStateException("Descriptor wasn't found for declaration $declaration\n${declaration.getElementTextWithContext()}" + + (additionalDetails?.let { "\n---------------------------------------------------\n$it" } ?: "")) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java index ed98c371326..11e5f94d797 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyDeclarationResolver.java @@ -41,6 +41,7 @@ import java.util.List; public class LazyDeclarationResolver { @NotNull private final TopLevelDescriptorProvider topLevelDescriptorProvider; + @NotNull private final AbsentDescriptorHandler absentDescriptorHandler; @NotNull private final BindingTrace trace; protected DeclarationScopeProvider scopeProvider; @@ -55,9 +56,11 @@ public class LazyDeclarationResolver { public LazyDeclarationResolver( @NotNull GlobalContext globalContext, @NotNull BindingTrace delegationTrace, - @NotNull TopLevelDescriptorProvider topLevelDescriptorProvider + @NotNull TopLevelDescriptorProvider topLevelDescriptorProvider, + @NotNull AbsentDescriptorHandler absentDescriptorHandler ) { this.topLevelDescriptorProvider = topLevelDescriptorProvider; + this.absentDescriptorHandler = absentDescriptorHandler; LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = new LockBasedLazyResolveStorageManager(globalContext.getStorageManager()); @@ -233,7 +236,7 @@ public class LazyDeclarationResolver { } }, null); if (result == null) { - throw new NoDescriptorForDeclarationException(declaration); + return absentDescriptorHandler.diagnoseDescriptorNotFound(declaration); } return result; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt index f7319e53912..31168763deb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/LocalClassifierAnalyzer.kt @@ -166,8 +166,9 @@ class LocalLazyDeclarationResolver( globalContext: GlobalContext, trace: BindingTrace, private val localClassDescriptorManager: LocalClassDescriptorHolder, - topLevelDescriptorProvider : TopLevelDescriptorProvider -) : LazyDeclarationResolver(globalContext, trace, topLevelDescriptorProvider) { + topLevelDescriptorProvider : TopLevelDescriptorProvider, + absentDescriptorHandler: AbsentDescriptorHandler +) : LazyDeclarationResolver(globalContext, trace, topLevelDescriptorProvider, absentDescriptorHandler) { override fun getClassDescriptor(classOrObject: KtClassOrObject, location: LookupLocation): ClassDescriptor { if (localClassDescriptorManager.isMyClass(classOrObject)) { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt index f2d9583cdec..792dbda4115 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaEnvironment.kt @@ -24,5 +24,6 @@ object IdeaEnvironment : TargetEnvironment("Idea") { override fun configure(container: StorageComponentContainer) { container.useImpl() container.useImpl() + container.useImpl() } } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaLocalDescriptorResolver.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaLocalDescriptorResolver.kt index e2017fb5660..903e627a8db 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaLocalDescriptorResolver.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/IdeaLocalDescriptorResolver.kt @@ -17,18 +17,33 @@ package org.jetbrains.kotlin.idea.project import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.stubindex.resolve.PluginDeclarationProviderFactory import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolver +import org.jetbrains.kotlin.resolve.lazy.AbsentDescriptorHandler import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException +import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory class IdeaLocalDescriptorResolver( - private val resolveElementCache: ResolveElementCache -): LocalDescriptorResolver { + private val resolveElementCache: ResolveElementCache, + private val absentDescriptorHandler: AbsentDescriptorHandler +) : LocalDescriptorResolver { override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor { val context = resolveElementCache.resolveToElement(declaration, BodyResolveMode.FULL) return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) - ?: throw NoDescriptorForDeclarationException(declaration) + ?: absentDescriptorHandler.diagnoseDescriptorNotFound(declaration) + } +} + +class IdeaAbsentDescriptorHandler( + private val declarationProviderFactory: DeclarationProviderFactory +) : AbsentDescriptorHandler { + override fun diagnoseDescriptorNotFound(declaration: KtDeclaration): DeclarationDescriptor { + throw NoDescriptorForDeclarationException( + declaration, + (declarationProviderFactory as? PluginDeclarationProviderFactory)?.debugToString() + ) } } \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/resolve/PluginDeclarationProviderFactory.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/resolve/PluginDeclarationProviderFactory.kt index d3526fde730..fbad90526ff 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/resolve/PluginDeclarationProviderFactory.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/resolve/PluginDeclarationProviderFactory.kt @@ -58,4 +58,24 @@ class PluginDeclarationProviderFactory( throw IllegalStateException("Cannot find package fragment for file ${file.name} with package ${file.packageFqName}, " + "vFile ${file.virtualFile}, nonIndexed ${file in nonIndexedFiles}") } + + // trying to diagnose org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException in completion + private val onCreationDebugInfo = debugInfo() + + fun debugToString(): String { + return "PluginDeclarationProviderFactory\nOn failure:\n${debugInfo()}On creation:\n$onCreationDebugInfo" + } + + private fun debugInfo(): String { + if (nonIndexedFiles.isEmpty()) return "-no synthetic files-\n" + + return buildString { + nonIndexedFiles.forEach { + append(it.name) + append(" isPhysical=${it.isPhysical}") + append(" modStamp=${it.modificationStamp}") + appendln() + } + } + } }