Adapt changes in IDE after moving SAM adapters to synthetic scope

The main change is that now to get static sam adapters one should do it using synthetic scopes and static scope of container
This commit is contained in:
Mikhail Zarechenskiy
2017-05-02 15:03:17 +03:00
parent 8e233162ed
commit 429f0e4f68
8 changed files with 66 additions and 16 deletions
@@ -180,6 +180,9 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
= emptyList() = emptyList()
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor>
= emptyList()
private fun collectSyntheticPropertiesByName(result: SmartList<PropertyDescriptor>?, type: TypeConstructor, name: Name, processedTypes: MutableSet<TypeConstructor>?, location: LookupLocation): SmartList<PropertyDescriptor>? { private fun collectSyntheticPropertiesByName(result: SmartList<PropertyDescriptor>?, type: TypeConstructor, name: Name, processedTypes: MutableSet<TypeConstructor>?, location: LookupLocation): SmartList<PropertyDescriptor>? {
if (processedTypes != null && !processedTypes.add(type)) return result if (processedTypes != null && !processedTypes.add(type)) return result
@@ -122,6 +122,10 @@ class SamAdapterFunctionsScope(
return scope.getContributedFunctions(name, location).mapNotNull { samAdapterForStaticFunction(it) } return scope.getContributedFunctions(name, location).mapNotNull { samAdapterForStaticFunction(it) }
} }
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
return scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS).mapNotNull { samAdapterForStaticFunction(it) }
}
private class MyFunctionDescriptor( private class MyFunctionDescriptor(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
original: SimpleFunctionDescriptor?, original: SimpleFunctionDescriptor?,
@@ -26,11 +26,11 @@ import org.jetbrains.kotlin.types.KotlinType
interface SyntheticScope { interface SyntheticScope {
fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor> fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<PropertyDescriptor>
fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor>
fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor>
fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor>
fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor>
} }
interface SyntheticScopes { interface SyntheticScopes {
@@ -56,3 +56,6 @@ fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collectio
fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>) fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>)
= scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes) } = scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes) }
fun SyntheticScopes.collectSyntheticStaticFunctions(scope: ResolutionScope)
= scopes.flatMap { it.getSyntheticStaticFunctions(scope) }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2017 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.
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.utils.collectAllFromMeAndParent
import org.jetbrains.kotlin.resolve.scopes.utils.collectDescriptorsFiltered import org.jetbrains.kotlin.resolve.scopes.utils.collectDescriptorsFiltered
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
@@ -181,10 +182,11 @@ class ReferenceVariantsHelper(
val descriptors = LinkedHashSet<DeclarationDescriptor>() val descriptors = LinkedHashSet<DeclarationDescriptor>()
val filterWithoutExtensions = kindFilter exclude DescriptorKindExclude.Extensions
if (receiverExpression != null) { if (receiverExpression != null) {
val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression]
if (qualifier != null) { if (qualifier != null) {
descriptors.addAll(qualifier.staticScope.getDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.Extensions, nameFilter)) descriptors.addAll(qualifier.staticScope.collectStaticMembers(resolutionFacade, filterWithoutExtensions, nameFilter))
} }
val explicitReceiverTypes = if (useReceiverType != null) { val explicitReceiverTypes = if (useReceiverType != null) {
@@ -202,7 +204,10 @@ class ReferenceVariantsHelper(
descriptors.processAll(implicitReceiverTypes, implicitReceiverTypes, resolutionScope, callType, kindFilter, nameFilter) descriptors.processAll(implicitReceiverTypes, implicitReceiverTypes, resolutionScope, callType, kindFilter, nameFilter)
// add non-instance members // add non-instance members
descriptors.addAll(resolutionScope.collectDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.Extensions, nameFilter)) descriptors.addAll(resolutionScope.collectDescriptorsFiltered(filterWithoutExtensions, nameFilter))
descriptors.addAll(resolutionScope.collectAllFromMeAndParent { scope ->
scope.collectSyntheticStaticMembers(resolutionFacade, kindFilter, nameFilter)
})
} }
if (callType == CallType.SUPER_MEMBERS) { // we need to unwrap fake overrides in case of "super." because ShadowedDeclarationsFilter does not work correctly if (callType == CallType.SUPER_MEMBERS) { // we need to unwrap fake overrides in case of "super." because ShadowedDeclarationsFilter does not work correctly
@@ -222,7 +227,7 @@ class ReferenceVariantsHelper(
): Collection<DeclarationDescriptor> { ): Collection<DeclarationDescriptor> {
if (receiverExpression != null) { if (receiverExpression != null) {
val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] ?: return emptyList() val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] ?: return emptyList()
return qualifier.staticScope.getDescriptorsFiltered(kindFilter, nameFilter) return qualifier.staticScope.collectStaticMembers(resolutionFacade, kindFilter, nameFilter)
} }
else { else {
val scope = contextElement.getResolutionScope(bindingContext, resolutionFacade) val scope = contextElement.getResolutionScope(bindingContext, resolutionFacade)
@@ -261,7 +266,7 @@ class ReferenceVariantsHelper(
explicitReceiverTypes explicitReceiverTypes
.map { (it.constructor.declarationDescriptor as? ClassDescriptor)?.staticScope } .map { (it.constructor.declarationDescriptor as? ClassDescriptor)?.staticScope }
.filterNotNull() .filterNotNull()
.flatMapTo(descriptors) { scope -> scope.getDescriptorsFiltered(kindFilter, nameFilter) } .flatMapTo(descriptors) { it.collectStaticMembers(resolutionFacade, kindFilter, nameFilter) }
} }
} }
else { else {
@@ -278,7 +283,7 @@ class ReferenceVariantsHelper(
): Collection<DeclarationDescriptor> { ): Collection<DeclarationDescriptor> {
if (receiverExpression != null) { if (receiverExpression != null) {
val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] ?: return emptyList() val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] ?: return emptyList()
val staticDescriptors = qualifier.staticScope.getDescriptorsFiltered(kindFilter, nameFilter) val staticDescriptors = qualifier.staticScope.collectStaticMembers(resolutionFacade, kindFilter, nameFilter)
val objectDescriptor = (qualifier as? ClassQualifier)?.descriptor?.takeIf { it.kind == ClassKind.OBJECT } ?: return staticDescriptors val objectDescriptor = (qualifier as? ClassQualifier)?.descriptor?.takeIf { it.kind == ClassKind.OBJECT } ?: return staticDescriptors
@@ -394,3 +399,20 @@ class ReferenceVariantsHelper(
} }
} }
} }
private fun MemberScope.collectStaticMembers(
resolutionFacade: ResolutionFacade,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
return getDescriptorsFiltered(kindFilter, nameFilter) + collectSyntheticStaticMembers(resolutionFacade, kindFilter, nameFilter)
}
fun ResolutionScope.collectSyntheticStaticMembers(
resolutionFacade: ResolutionFacade,
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): List<FunctionDescriptor> {
val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
return syntheticScopes.collectSyntheticStaticFunctions(this).filter { kindFilter.accepts(it) && nameFilter(it.name) }
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2017 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.
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.codeInsight.collectSyntheticStaticMembers
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
import org.jetbrains.kotlin.idea.core.targetDescriptors import org.jetbrains.kotlin.idea.core.targetDescriptors
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
@@ -76,9 +77,14 @@ class StaticMembersCompletion(
.toSet() .toSet()
val result = ArrayList<DeclarationDescriptor>() val result = ArrayList<DeclarationDescriptor>()
val kindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions
val nameFilter = prefixMatcher.asNameFilter()
for (container in containers) { for (container in containers) {
val memberScope = if (container.kind == ClassKind.OBJECT) container.unsubstitutedMemberScope else container.staticScope val memberScope = if (container.kind == ClassKind.OBJECT) container.unsubstitutedMemberScope else container.staticScope
val members = memberScope.getDescriptorsFiltered(DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions, prefixMatcher.asNameFilter()) val members =
memberScope.getDescriptorsFiltered(kindFilter, nameFilter) +
memberScope.collectSyntheticStaticMembers(resolutionFacade, kindFilter, nameFilter)
members.filterTo(result) { it is CallableDescriptor && it !in alreadyAdded } members.filterTo(result) { it is CallableDescriptor && it !in alreadyAdded }
} }
return result return result
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * Copyright 2010-2017 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.
@@ -46,6 +46,8 @@ import org.jetbrains.kotlin.psi.psiUtil.contains
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.isHiddenInResolution import org.jetbrains.kotlin.resolve.isHiddenInResolution
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
@@ -441,7 +443,8 @@ class KotlinIndicesHelper(
processor(descriptor) processor(descriptor)
// SAM-adapter // SAM-adapter
container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE) val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java)
syntheticScopes.collectSyntheticStaticFunctions(container.staticScope, descriptor.name, NoLookupLocation.FROM_IDE)
.filterIsInstance<SamAdapterDescriptor<*>>() .filterIsInstance<SamAdapterDescriptor<*>>()
.firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original } .firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original }
?.let { processor(it) } ?.let { processor(it) }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2017 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.
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.util.DelegatingCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticMemberFunctions import org.jetbrains.kotlin.resolve.scopes.collectSyntheticMemberFunctions
import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.keysToMapExceptNulls import org.jetbrains.kotlin.utils.keysToMapExceptNulls
@@ -181,9 +182,10 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() {
val originalFunctionDescriptor = functionResolvedCall.resultingDescriptor.original as? FunctionDescriptor ?: return emptyList() val originalFunctionDescriptor = functionResolvedCall.resultingDescriptor.original as? FunctionDescriptor ?: return emptyList()
val containingClass = originalFunctionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList() val containingClass = originalFunctionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList()
val syntheticScopes = functionCall.getResolutionFacade().getFrontendService(SyntheticScopes::class.java)
// SAM adapters for static functions // SAM adapters for static functions
val contributedFunctions = containingClass.staticScope.getContributedFunctions( val contributedFunctions = syntheticScopes.collectSyntheticStaticFunctions(containingClass.staticScope)
functionResolvedCall.resultingDescriptor.name, NoLookupLocation.FROM_IDE)
for (staticFunWithSameName in contributedFunctions) { for (staticFunWithSameName in contributedFunctions) {
if (staticFunWithSameName is SamAdapterDescriptor<*>) { if (staticFunWithSameName is SamAdapterDescriptor<*>) {
if (isSamAdapterSuitableForCall(staticFunWithSameName, originalFunctionDescriptor, samConstructorCallArgumentMap.size)) { if (isSamAdapterSuitableForCall(staticFunWithSameName, originalFunctionDescriptor, samConstructorCallArgumentMap.size)) {
@@ -193,7 +195,6 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() {
} }
// SAM adapters for member functions // SAM adapters for member functions
val syntheticScopes = functionCall.getResolutionFacade().getFrontendService(SyntheticScopes::class.java)
val syntheticExtensions = syntheticScopes.collectSyntheticMemberFunctions( val syntheticExtensions = syntheticScopes.collectSyntheticMemberFunctions(
listOf(containingClass.defaultType), listOf(containingClass.defaultType),
functionResolvedCall.resultingDescriptor.name, functionResolvedCall.resultingDescriptor.name,
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2017 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.
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
import org.jetbrains.kotlin.idea.core.resolveCandidates import org.jetbrains.kotlin.idea.core.resolveCandidates
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.psi.psiUtil.parents import org.jetbrains.kotlin.psi.psiUtil.parents
@@ -390,6 +391,13 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
// we should not compare descriptors directly because partial resolve is involved // we should not compare descriptors directly because partial resolve is involved
private fun descriptorsEqual(descriptor1: FunctionDescriptor, descriptor2: FunctionDescriptor): Boolean { private fun descriptorsEqual(descriptor1: FunctionDescriptor, descriptor2: FunctionDescriptor): Boolean {
if (descriptor1.original == descriptor2.original) return true if (descriptor1.original == descriptor2.original) return true
val isSamDescriptor1 = descriptor1 is SamAdapterDescriptor<*>
val isSamDescriptor2 = descriptor2 is SamAdapterDescriptor<*>
// Previously it worked because of different order
// If descriptor1 is SamAdapter and descriptor2 isn't, this function shouldn't return `true` because of equal declaration
if (isSamDescriptor1 xor isSamDescriptor2) return false
val declaration1 = DescriptorToSourceUtils.descriptorToDeclaration(descriptor1) ?: return false val declaration1 = DescriptorToSourceUtils.descriptorToDeclaration(descriptor1) ?: return false
val declaration2 = DescriptorToSourceUtils.descriptorToDeclaration(descriptor2) val declaration2 = DescriptorToSourceUtils.descriptorToDeclaration(descriptor2)
return declaration1 == declaration2 return declaration1 == declaration2