From 429f0e4f683350c32fac59c1a9e650ab97f42061 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Tue, 2 May 2017 15:03:17 +0300 Subject: [PATCH] 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 --- .../synthetic/JavaSyntheticPropertiesScope.kt | 3 ++ .../synthetic/SamAdapterFunctionsScope.kt | 4 +++ .../kotlin/resolve/scopes/SyntheticScopes.kt | 5 ++- .../codeInsight/ReferenceVariantsHelper.kt | 34 +++++++++++++++---- .../completion/StaticMembersCompletion.kt | 10 ++++-- .../kotlin/idea/core/KotlinIndicesHelper.kt | 7 ++-- .../RedundantSamConstructorInspection.kt | 9 ++--- .../KotlinFunctionParameterInfoHandler.kt | 10 +++++- 8 files changed, 66 insertions(+), 16 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt index 4e94246a0da..fe70c96735a 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticPropertiesScope.kt @@ -180,6 +180,9 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection = emptyList() + override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection + = emptyList() + private fun collectSyntheticPropertiesByName(result: SmartList?, type: TypeConstructor, name: Name, processedTypes: MutableSet?, location: LookupLocation): SmartList? { if (processedTypes != null && !processedTypes.add(type)) return result diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index 2bff31e645e..f164145e382 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -122,6 +122,10 @@ class SamAdapterFunctionsScope( return scope.getContributedFunctions(name, location).mapNotNull { samAdapterForStaticFunction(it) } } + override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection { + return scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS).mapNotNull { samAdapterForStaticFunction(it) } + } + private class MyFunctionDescriptor( containingDeclaration: DeclarationDescriptor, original: SimpleFunctionDescriptor?, diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SyntheticScopes.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SyntheticScopes.kt index a5c9dba0b9a..211ca7b9e2f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SyntheticScopes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/SyntheticScopes.kt @@ -26,11 +26,11 @@ import org.jetbrains.kotlin.types.KotlinType interface SyntheticScope { fun getSyntheticExtensionProperties(receiverTypes: Collection, name: Name, location: LookupLocation): Collection fun getSyntheticMemberFunctions(receiverTypes: Collection, name: Name, location: LookupLocation): Collection - fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection fun getSyntheticExtensionProperties(receiverTypes: Collection): Collection fun getSyntheticMemberFunctions(receiverTypes: Collection): Collection + fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection } interface SyntheticScopes { @@ -56,3 +56,6 @@ fun SyntheticScopes.collectSyntheticExtensionProperties(receiverTypes: Collectio fun SyntheticScopes.collectSyntheticMemberFunctions(receiverTypes: Collection) = scopes.flatMap { it.getSyntheticMemberFunctions(receiverTypes) } + +fun SyntheticScopes.collectSyntheticStaticFunctions(scope: ResolutionScope) + = scopes.flatMap { it.getSyntheticStaticFunctions(scope) } diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index 7921eb5db3b..9c58fc866c3 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -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"); * 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.scopes.* 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.memberScopeAsImportingScope import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor @@ -181,10 +182,11 @@ class ReferenceVariantsHelper( val descriptors = LinkedHashSet() + val filterWithoutExtensions = kindFilter exclude DescriptorKindExclude.Extensions if (receiverExpression != null) { val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] 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) { @@ -202,7 +204,10 @@ class ReferenceVariantsHelper( descriptors.processAll(implicitReceiverTypes, implicitReceiverTypes, resolutionScope, callType, kindFilter, nameFilter) // 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 @@ -222,7 +227,7 @@ class ReferenceVariantsHelper( ): Collection { if (receiverExpression != null) { val qualifier = bindingContext[BindingContext.QUALIFIER, receiverExpression] ?: return emptyList() - return qualifier.staticScope.getDescriptorsFiltered(kindFilter, nameFilter) + return qualifier.staticScope.collectStaticMembers(resolutionFacade, kindFilter, nameFilter) } else { val scope = contextElement.getResolutionScope(bindingContext, resolutionFacade) @@ -261,7 +266,7 @@ class ReferenceVariantsHelper( explicitReceiverTypes .map { (it.constructor.declarationDescriptor as? ClassDescriptor)?.staticScope } .filterNotNull() - .flatMapTo(descriptors) { scope -> scope.getDescriptorsFiltered(kindFilter, nameFilter) } + .flatMapTo(descriptors) { it.collectStaticMembers(resolutionFacade, kindFilter, nameFilter) } } } else { @@ -278,7 +283,7 @@ class ReferenceVariantsHelper( ): Collection { if (receiverExpression != null) { 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 @@ -394,3 +399,20 @@ class ReferenceVariantsHelper( } } } + +private fun MemberScope.collectStaticMembers( + resolutionFacade: ResolutionFacade, + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean +): Collection { + return getDescriptorsFiltered(kindFilter, nameFilter) + collectSyntheticStaticMembers(resolutionFacade, kindFilter, nameFilter) +} + +fun ResolutionScope.collectSyntheticStaticMembers( + resolutionFacade: ResolutionFacade, + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean +): List { + val syntheticScopes = resolutionFacade.getFrontendService(SyntheticScopes::class.java) + return syntheticScopes.collectSyntheticStaticFunctions(this).filter { kindFilter.accepts(it) && nameFilter(it.name) } +} \ No newline at end of file diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt index 0218be952d1..b78eb5806d4 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/StaticMembersCompletion.kt @@ -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"); * 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.ClassKind 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.targetDescriptors import org.jetbrains.kotlin.idea.resolve.ResolutionFacade @@ -76,9 +77,14 @@ class StaticMembersCompletion( .toSet() val result = ArrayList() + + val kindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions + val nameFilter = prefixMatcher.asNameFilter() for (container in containers) { 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 } } return result diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt index 44f3ee7609c..5daeadafcd3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/KotlinIndicesHelper.kt @@ -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"); * 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.isHiddenInResolution 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 java.lang.reflect.Field import java.lang.reflect.Modifier @@ -441,7 +443,8 @@ class KotlinIndicesHelper( processor(descriptor) // 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>() .firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original } ?.let { processor(it) } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt index 4d6f25d86b8..218f6a00bef 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt @@ -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"); * 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.scopes.SyntheticScopes import org.jetbrains.kotlin.resolve.scopes.collectSyntheticMemberFunctions +import org.jetbrains.kotlin.resolve.scopes.collectSyntheticStaticFunctions import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.utils.keysToMapExceptNulls @@ -181,9 +182,10 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() { val originalFunctionDescriptor = functionResolvedCall.resultingDescriptor.original as? FunctionDescriptor ?: return emptyList() val containingClass = originalFunctionDescriptor.containingDeclaration as? ClassDescriptor ?: return emptyList() + val syntheticScopes = functionCall.getResolutionFacade().getFrontendService(SyntheticScopes::class.java) + // SAM adapters for static functions - val contributedFunctions = containingClass.staticScope.getContributedFunctions( - functionResolvedCall.resultingDescriptor.name, NoLookupLocation.FROM_IDE) + val contributedFunctions = syntheticScopes.collectSyntheticStaticFunctions(containingClass.staticScope) for (staticFunWithSameName in contributedFunctions) { if (staticFunWithSameName is SamAdapterDescriptor<*>) { if (isSamAdapterSuitableForCall(staticFunWithSameName, originalFunctionDescriptor, samConstructorCallArgumentMap.size)) { @@ -193,7 +195,6 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() { } // SAM adapters for member functions - val syntheticScopes = functionCall.getResolutionFacade().getFrontendService(SyntheticScopes::class.java) val syntheticExtensions = syntheticScopes.collectSyntheticMemberFunctions( listOf(containingClass.defaultType), functionResolvedCall.resultingDescriptor.name, diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinFunctionParameterInfoHandler.kt b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinFunctionParameterInfoHandler.kt index 3183c9e095f..9447f10f161 100644 --- a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinFunctionParameterInfoHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/KotlinFunctionParameterInfoHandler.kt @@ -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"); * 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.resolve.ResolutionFacade import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.parents @@ -390,6 +391,13 @@ abstract class KotlinParameterInfoWithCallHandlerBase + 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 declaration2 = DescriptorToSourceUtils.descriptorToDeclaration(descriptor2) return declaration1 == declaration2