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