提交 470fef94 编写于 作者: P Pavel Kirpichenkov

Use bound resolution facade in DeprecationResolver usages

Resolution facade should be used consistently with direct usages of frontend components.
Otherwise they can start processing descriptors from foreign resolvers which leads to memory leaks.

Plain resolution API with provided facade is not suitable as-is for compiled declarations in KotlinIndicesHelper though.
Resolution facade for module sources contained in helper can't handle decompiled
sources from PSI indices (leads to "ModuleInfo not contained in resolver" errors).
That's why "hacked" resolve via import references should be used there.

#KT-39642 Fixed
上级 82ef6bf9
......@@ -26,8 +26,7 @@ import com.intellij.util.indexing.IdFilter
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.*
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor
import org.jetbrains.kotlin.idea.codeInsight.forceEnableSamAdapters
......@@ -264,7 +263,7 @@ class KotlinIndicesHelper(
fun getKotlinEnumsByName(name: String): Collection<DeclarationDescriptor> {
return KotlinClassShortNameIndex.getInstance()[name, project, scope]
.filter { it is KtEnumEntry && it in scope }
.mapNotNull { it.unsafeResolveToDescriptor() }
.flatMap { it.resolveToDescriptors<DeclarationDescriptor>() }
.filter(descriptorFilter)
.toSet()
}
......@@ -367,10 +366,12 @@ class KotlinIndicesHelper(
for (declaration in functions + properties) {
ProgressManager.checkCanceled()
if (!filter(declaration)) continue
val descriptor = declaration.descriptor as? CallableDescriptor ?: continue
if (!processed.add(descriptor)) continue
if (!descriptorFilter(descriptor)) continue
processor(descriptor)
for (descriptor in declaration.resolveToDescriptors<CallableDescriptor>()) {
if (!processed.add(descriptor)) continue
if (!descriptorFilter(descriptor)) continue
processor(descriptor)
}
}
}
......@@ -489,7 +490,7 @@ class KotlinIndicesHelper(
for (field in shortNamesCache.getFieldsByName(name, scopeWithoutKotlin).filterNot { it is KtLightElement<*, *> }) {
if (!field.hasModifierProperty(PsiModifier.STATIC)) continue
if (filterOutPrivate && field.hasModifierProperty(PsiModifier.PRIVATE)) continue
val descriptor = field.getJavaMemberDescriptor() ?: continue
val descriptor = field.getJavaMemberDescriptor(resolutionFacade) ?: continue
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
processor(descriptor)
}
......
......@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.idea.kdoc.KDocTemplate.DescriptionBodyTemplate
import org.jetbrains.kotlin.idea.references.KtDescriptorsBasedReference
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.resolve.frontendService
import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
......@@ -142,10 +143,11 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
override fun getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement?): PsiElement? {
val navElement = context?.navigationElement as? KtElement ?: return null
val bindingContext = navElement.analyze(BodyResolveMode.PARTIAL)
val resolutionFacade = navElement.getResolutionFacade()
val bindingContext = navElement.analyze(resolutionFacade, BodyResolveMode.PARTIAL)
val contextDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, navElement] ?: return null
val descriptors = resolveKDocLink(
bindingContext, navElement.getResolutionFacade(),
bindingContext, resolutionFacade,
contextDescriptor, null, link.split('.')
)
val target = descriptors.firstOrNull() ?: return null
......@@ -318,7 +320,8 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
}
private fun buildKotlinDeclaration(declaration: KtExpression, quickNavigation: Boolean): KDocTemplate {
val context = declaration.analyze(BodyResolveMode.PARTIAL)
val resolutionFacade = declaration.getResolutionFacade()
val context = declaration.analyze(resolutionFacade, BodyResolveMode.PARTIAL)
val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
if (declarationDescriptor == null) {
......@@ -330,29 +333,32 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
}
}
return buildKotlin(context, declarationDescriptor, quickNavigation, declaration)
return buildKotlin(context, declarationDescriptor, quickNavigation, declaration, resolutionFacade)
}
private fun renderKotlinImplicitLambdaParameter(element: KtReferenceExpression, quickNavigation: Boolean): String? {
val context = element.analyze(BodyResolveMode.PARTIAL)
val resolutionFacade = element.getResolutionFacade()
val context = element.analyze(resolutionFacade, BodyResolveMode.PARTIAL)
val target = element.mainReference.resolveToDescriptors(context).singleOrNull() as? ValueParameterDescriptor? ?: return null
return renderKotlin(context, target, quickNavigation, element)
return renderKotlin(context, target, quickNavigation, element, resolutionFacade)
}
private fun renderKotlin(
context: BindingContext,
declarationDescriptor: DeclarationDescriptor,
quickNavigation: Boolean,
ktElement: KtElement
ktElement: KtElement,
resolutionFacade: ResolutionFacade,
) = buildString {
insert(buildKotlin(context, declarationDescriptor, quickNavigation, ktElement)) {}
insert(buildKotlin(context, declarationDescriptor, quickNavigation, ktElement, resolutionFacade)) {}
}
private fun buildKotlin(
context: BindingContext,
declarationDescriptor: DeclarationDescriptor,
quickNavigation: Boolean,
ktElement: KtElement
ktElement: KtElement,
resolutionFacade: ResolutionFacade,
): KDocTemplate {
@Suppress("NAME_SHADOWING")
var declarationDescriptor = declarationDescriptor
......@@ -363,7 +369,7 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
}
}
val deprecationProvider = ktElement.getResolutionFacade().frontendService<DeprecationResolver>()
val deprecationProvider = resolutionFacade.frontendService<DeprecationResolver>()
return KDocTemplate().apply {
definition {
......
......@@ -58,7 +58,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection() {
return propertyVisitor(fun(property: KtProperty) {
if (property.receiverTypeReference != null) {
val nameElement = property.nameIdentifier ?: return
val propertyDescriptor = property.resolveToDescriptorIfAny() as? PropertyDescriptor ?: return
val propertyDescriptor = property.resolveToDescriptorIfAny(resolutionFacade) as? PropertyDescriptor ?: return
val syntheticScopes = resolutionFacade.frontendService<SyntheticScopes>()
val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return
......
......@@ -35,9 +35,10 @@ class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() {
}
private fun registerProblemIfNeeded(declaration: KtDeclaration, targetForProblem: PsiElement) {
val accessorDescriptor = declaration.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return
val resolutionFacade = declaration.getResolutionFacade()
val accessorDescriptor = declaration.resolveToDescriptorIfAny(resolutionFacade) as? CallableMemberDescriptor ?: return
val deprecationProvider = declaration.getResolutionFacade().frontendService<DeprecationResolver>()
val deprecationProvider = resolutionFacade.frontendService<DeprecationResolver>()
val message = deprecationProvider.getDeprecations(accessorDescriptor)
.firstOrNull()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册