Try to diagnose NoDescriptorForDeclarationException in completion
This commit is contained in:
@@ -22,12 +22,8 @@ import org.jetbrains.kotlin.context.ModuleContext
|
|||||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.lazy.FileScopeProvider
|
import org.jetbrains.kotlin.resolve.lazy.*
|
||||||
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.declarations.DeclarationProviderFactory
|
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.DeclarationScopeProviderForLocalClassifierAnalyzer
|
||||||
import org.jetbrains.kotlin.types.expressions.LocalClassDescriptorHolder
|
import org.jetbrains.kotlin.types.expressions.LocalClassDescriptorHolder
|
||||||
import org.jetbrains.kotlin.types.expressions.LocalLazyDeclarationResolver
|
import org.jetbrains.kotlin.types.expressions.LocalLazyDeclarationResolver
|
||||||
@@ -90,6 +86,7 @@ fun createContainerForLazyBodyResolve(
|
|||||||
useInstance(kotlinCodeAnalyzer.getFileScopeProvider())
|
useInstance(kotlinCodeAnalyzer.getFileScopeProvider())
|
||||||
useInstance(bodyResolveCache)
|
useInstance(bodyResolveCache)
|
||||||
useImpl<LazyTopDownAnalyzerForTopLevel>()
|
useImpl<LazyTopDownAnalyzerForTopLevel>()
|
||||||
|
useImpl<BasicAbsentDescriptorHandler>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createContainerForLazyLocalClassifierAnalyzer(
|
fun createContainerForLazyLocalClassifierAnalyzer(
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ import org.jetbrains.kotlin.container.StorageComponentContainer
|
|||||||
import org.jetbrains.kotlin.container.useImpl
|
import org.jetbrains.kotlin.container.useImpl
|
||||||
import org.jetbrains.kotlin.container.useInstance
|
import org.jetbrains.kotlin.container.useInstance
|
||||||
import org.jetbrains.kotlin.resolve.lazy.CompilerLocalDescriptorResolver
|
import org.jetbrains.kotlin.resolve.lazy.CompilerLocalDescriptorResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BasicAbsentDescriptorHandler
|
||||||
|
|
||||||
object CompilerEnvironment : TargetEnvironment("Compiler") {
|
object CompilerEnvironment : TargetEnvironment("Compiler") {
|
||||||
override fun configure(container: StorageComponentContainer) {
|
override fun configure(container: StorageComponentContainer) {
|
||||||
container.useInstance(BodyResolveCache.ThrowException)
|
container.useInstance(BodyResolveCache.ThrowException)
|
||||||
container.useImpl<CompilerLocalDescriptorResolver>()
|
container.useImpl<CompilerLocalDescriptorResolver>()
|
||||||
|
container.useImpl<BasicAbsentDescriptorHandler>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+13
-3
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,8 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.lazy
|
package org.jetbrains.kotlin.resolve.lazy
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
|
|
||||||
class NoDescriptorForDeclarationException(declaration: KtDeclaration) :
|
interface AbsentDescriptorHandler {
|
||||||
IllegalStateException("Descriptor wasn't found for declaration $declaration\n${declaration.getElementTextWithContext()}")
|
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" } ?: ""))
|
||||||
+5
-2
@@ -41,6 +41,7 @@ import java.util.List;
|
|||||||
public class LazyDeclarationResolver {
|
public class LazyDeclarationResolver {
|
||||||
|
|
||||||
@NotNull private final TopLevelDescriptorProvider topLevelDescriptorProvider;
|
@NotNull private final TopLevelDescriptorProvider topLevelDescriptorProvider;
|
||||||
|
@NotNull private final AbsentDescriptorHandler absentDescriptorHandler;
|
||||||
@NotNull private final BindingTrace trace;
|
@NotNull private final BindingTrace trace;
|
||||||
|
|
||||||
protected DeclarationScopeProvider scopeProvider;
|
protected DeclarationScopeProvider scopeProvider;
|
||||||
@@ -55,9 +56,11 @@ public class LazyDeclarationResolver {
|
|||||||
public LazyDeclarationResolver(
|
public LazyDeclarationResolver(
|
||||||
@NotNull GlobalContext globalContext,
|
@NotNull GlobalContext globalContext,
|
||||||
@NotNull BindingTrace delegationTrace,
|
@NotNull BindingTrace delegationTrace,
|
||||||
@NotNull TopLevelDescriptorProvider topLevelDescriptorProvider
|
@NotNull TopLevelDescriptorProvider topLevelDescriptorProvider,
|
||||||
|
@NotNull AbsentDescriptorHandler absentDescriptorHandler
|
||||||
) {
|
) {
|
||||||
this.topLevelDescriptorProvider = topLevelDescriptorProvider;
|
this.topLevelDescriptorProvider = topLevelDescriptorProvider;
|
||||||
|
this.absentDescriptorHandler = absentDescriptorHandler;
|
||||||
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
|
LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager =
|
||||||
new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
|
new LockBasedLazyResolveStorageManager(globalContext.getStorageManager());
|
||||||
|
|
||||||
@@ -233,7 +236,7 @@ public class LazyDeclarationResolver {
|
|||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
throw new NoDescriptorForDeclarationException(declaration);
|
return absentDescriptorHandler.diagnoseDescriptorNotFound(declaration);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -166,8 +166,9 @@ class LocalLazyDeclarationResolver(
|
|||||||
globalContext: GlobalContext,
|
globalContext: GlobalContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
private val localClassDescriptorManager: LocalClassDescriptorHolder,
|
private val localClassDescriptorManager: LocalClassDescriptorHolder,
|
||||||
topLevelDescriptorProvider : TopLevelDescriptorProvider
|
topLevelDescriptorProvider : TopLevelDescriptorProvider,
|
||||||
) : LazyDeclarationResolver(globalContext, trace, topLevelDescriptorProvider) {
|
absentDescriptorHandler: AbsentDescriptorHandler
|
||||||
|
) : LazyDeclarationResolver(globalContext, trace, topLevelDescriptorProvider, absentDescriptorHandler) {
|
||||||
|
|
||||||
override fun getClassDescriptor(classOrObject: KtClassOrObject, location: LookupLocation): ClassDescriptor {
|
override fun getClassDescriptor(classOrObject: KtClassOrObject, location: LookupLocation): ClassDescriptor {
|
||||||
if (localClassDescriptorManager.isMyClass(classOrObject)) {
|
if (localClassDescriptorManager.isMyClass(classOrObject)) {
|
||||||
|
|||||||
@@ -24,5 +24,6 @@ object IdeaEnvironment : TargetEnvironment("Idea") {
|
|||||||
override fun configure(container: StorageComponentContainer) {
|
override fun configure(container: StorageComponentContainer) {
|
||||||
container.useImpl<ResolveElementCache>()
|
container.useImpl<ResolveElementCache>()
|
||||||
container.useImpl<IdeaLocalDescriptorResolver>()
|
container.useImpl<IdeaLocalDescriptorResolver>()
|
||||||
|
container.useImpl<IdeaAbsentDescriptorHandler>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+18
-3
@@ -17,18 +17,33 @@
|
|||||||
package org.jetbrains.kotlin.idea.project
|
package org.jetbrains.kotlin.idea.project
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.stubindex.resolve.PluginDeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.lazy.LocalDescriptorResolver
|
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.NoDescriptorForDeclarationException
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||||
|
|
||||||
class IdeaLocalDescriptorResolver(
|
class IdeaLocalDescriptorResolver(
|
||||||
private val resolveElementCache: ResolveElementCache
|
private val resolveElementCache: ResolveElementCache,
|
||||||
): LocalDescriptorResolver {
|
private val absentDescriptorHandler: AbsentDescriptorHandler
|
||||||
|
) : LocalDescriptorResolver {
|
||||||
override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor {
|
override fun resolveLocalDeclaration(declaration: KtDeclaration): DeclarationDescriptor {
|
||||||
val context = resolveElementCache.resolveToElement(declaration, BodyResolveMode.FULL)
|
val context = resolveElementCache.resolveToElement(declaration, BodyResolveMode.FULL)
|
||||||
return context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
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()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+20
@@ -58,4 +58,24 @@ class PluginDeclarationProviderFactory(
|
|||||||
throw IllegalStateException("Cannot find package fragment for file ${file.name} with package ${file.packageFqName}, " +
|
throw IllegalStateException("Cannot find package fragment for file ${file.name} with package ${file.packageFqName}, " +
|
||||||
"vFile ${file.virtualFile}, nonIndexed ${file in nonIndexedFiles}")
|
"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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user