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
This commit is contained in:
@@ -26,8 +26,7 @@ import com.intellij.util.indexing.IdFilter
|
|||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache
|
import org.jetbrains.kotlin.idea.caches.KotlinShortNamesCache
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.forceEnableSamAdapters
|
import org.jetbrains.kotlin.idea.codeInsight.forceEnableSamAdapters
|
||||||
@@ -264,7 +263,7 @@ class KotlinIndicesHelper(
|
|||||||
fun getKotlinEnumsByName(name: String): Collection<DeclarationDescriptor> {
|
fun getKotlinEnumsByName(name: String): Collection<DeclarationDescriptor> {
|
||||||
return KotlinClassShortNameIndex.getInstance()[name, project, scope]
|
return KotlinClassShortNameIndex.getInstance()[name, project, scope]
|
||||||
.filter { it is KtEnumEntry && it in scope }
|
.filter { it is KtEnumEntry && it in scope }
|
||||||
.mapNotNull { it.unsafeResolveToDescriptor() }
|
.flatMap { it.resolveToDescriptors<DeclarationDescriptor>() }
|
||||||
.filter(descriptorFilter)
|
.filter(descriptorFilter)
|
||||||
.toSet()
|
.toSet()
|
||||||
}
|
}
|
||||||
@@ -367,10 +366,12 @@ class KotlinIndicesHelper(
|
|||||||
for (declaration in functions + properties) {
|
for (declaration in functions + properties) {
|
||||||
ProgressManager.checkCanceled()
|
ProgressManager.checkCanceled()
|
||||||
if (!filter(declaration)) continue
|
if (!filter(declaration)) continue
|
||||||
val descriptor = declaration.descriptor as? CallableDescriptor ?: continue
|
|
||||||
if (!processed.add(descriptor)) continue
|
for (descriptor in declaration.resolveToDescriptors<CallableDescriptor>()) {
|
||||||
if (!descriptorFilter(descriptor)) continue
|
if (!processed.add(descriptor)) continue
|
||||||
processor(descriptor)
|
if (!descriptorFilter(descriptor)) continue
|
||||||
|
processor(descriptor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +490,7 @@ class KotlinIndicesHelper(
|
|||||||
for (field in shortNamesCache.getFieldsByName(name, scopeWithoutKotlin).filterNot { it is KtLightElement<*, *> }) {
|
for (field in shortNamesCache.getFieldsByName(name, scopeWithoutKotlin).filterNot { it is KtLightElement<*, *> }) {
|
||||||
if (!field.hasModifierProperty(PsiModifier.STATIC)) continue
|
if (!field.hasModifierProperty(PsiModifier.STATIC)) continue
|
||||||
if (filterOutPrivate && field.hasModifierProperty(PsiModifier.PRIVATE)) 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)) {
|
if (descriptorKindFilter.accepts(descriptor) && descriptorFilter(descriptor)) {
|
||||||
processor(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.KtDescriptorsBasedReference
|
||||||
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveToDescriptors
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
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.resolve.frontendService
|
||||||
import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
|
import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
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? {
|
override fun getDocumentationElementForLink(psiManager: PsiManager, link: String, context: PsiElement?): PsiElement? {
|
||||||
val navElement = context?.navigationElement as? KtElement ?: return null
|
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 contextDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, navElement] ?: return null
|
||||||
val descriptors = resolveKDocLink(
|
val descriptors = resolveKDocLink(
|
||||||
bindingContext, navElement.getResolutionFacade(),
|
bindingContext, resolutionFacade,
|
||||||
contextDescriptor, null, link.split('.')
|
contextDescriptor, null, link.split('.')
|
||||||
)
|
)
|
||||||
val target = descriptors.firstOrNull() ?: return null
|
val target = descriptors.firstOrNull() ?: return null
|
||||||
@@ -318,7 +320,8 @@ open class KotlinDocumentationProviderCompatBase : AbstractDocumentationProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildKotlinDeclaration(declaration: KtExpression, quickNavigation: Boolean): KDocTemplate {
|
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]
|
val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
|
||||||
|
|
||||||
if (declarationDescriptor == null) {
|
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? {
|
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
|
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(
|
private fun renderKotlin(
|
||||||
context: BindingContext,
|
context: BindingContext,
|
||||||
declarationDescriptor: DeclarationDescriptor,
|
declarationDescriptor: DeclarationDescriptor,
|
||||||
quickNavigation: Boolean,
|
quickNavigation: Boolean,
|
||||||
ktElement: KtElement
|
ktElement: KtElement,
|
||||||
|
resolutionFacade: ResolutionFacade,
|
||||||
) = buildString {
|
) = buildString {
|
||||||
insert(buildKotlin(context, declarationDescriptor, quickNavigation, ktElement)) {}
|
insert(buildKotlin(context, declarationDescriptor, quickNavigation, ktElement, resolutionFacade)) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildKotlin(
|
private fun buildKotlin(
|
||||||
context: BindingContext,
|
context: BindingContext,
|
||||||
declarationDescriptor: DeclarationDescriptor,
|
declarationDescriptor: DeclarationDescriptor,
|
||||||
quickNavigation: Boolean,
|
quickNavigation: Boolean,
|
||||||
ktElement: KtElement
|
ktElement: KtElement,
|
||||||
|
resolutionFacade: ResolutionFacade,
|
||||||
): KDocTemplate {
|
): KDocTemplate {
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
var declarationDescriptor = declarationDescriptor
|
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 {
|
return KDocTemplate().apply {
|
||||||
definition {
|
definition {
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection() {
|
|||||||
return propertyVisitor(fun(property: KtProperty) {
|
return propertyVisitor(fun(property: KtProperty) {
|
||||||
if (property.receiverTypeReference != null) {
|
if (property.receiverTypeReference != null) {
|
||||||
val nameElement = property.nameIdentifier ?: return
|
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 syntheticScopes = resolutionFacade.frontendService<SyntheticScopes>()
|
||||||
val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return
|
val conflictingExtension = conflictingSyntheticExtension(propertyDescriptor, syntheticScopes) ?: return
|
||||||
|
|||||||
+3
-2
@@ -35,9 +35,10 @@ class OverridingDeprecatedMemberInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerProblemIfNeeded(declaration: KtDeclaration, targetForProblem: PsiElement) {
|
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)
|
val message = deprecationProvider.getDeprecations(accessorDescriptor)
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
|
|||||||
Reference in New Issue
Block a user