diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt new file mode 100644 index 00000000000..54425d3f0c9 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.jvm + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil +import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider +import org.jetbrains.kotlin.fileClasses.getFileClassFqName +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils +import org.jetbrains.kotlin.resolve.OverloadFilter +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor +import java.util.* + + +object JvmOverloadFilter : OverloadFilter { + override fun filterPackageMemberOverloads(overloads: Collection): Collection { + val result = ArrayList() + + val sourceClassesFQNs = HashSet() + for (overload in overloads) { + val file = DescriptorToSourceUtils.getContainingFile(overload) ?: continue + result.add(overload) + sourceClassesFQNs.add(NoResolveFileClassesProvider.getFileClassFqName(file)) + } + + for (overload in overloads) { + if (overload !is DeserializedCallableMemberDescriptor) continue + + val containingDeclaration = overload.containingDeclaration + if (containingDeclaration !is PackageFragmentDescriptor) { + throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration") + } + val implClassName = JvmFileClassUtil.getImplClassName(overload) ?: + throw AssertionError("No implClassName: $overload") + val implClassFQN = containingDeclaration.fqName.child(implClassName) + if (!sourceClassesFQNs.contains(implClassFQN)) { + result.add(overload) + } + } + + return result + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt index fca7bc02ccf..b08a38a88e3 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JvmPlatformConfigurator.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.jvm.RuntimeAssertionsTypeChecker import org.jetbrains.kotlin.load.kotlin.JavaAnnotationCallChecker import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeFunChecker import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.jvm.JvmOverloadFilter import org.jetbrains.kotlin.resolve.jvm.checkers.* import org.jetbrains.kotlin.types.DynamicTypesSettings @@ -61,7 +62,9 @@ public object JvmPlatformConfigurator : PlatformConfigurator( FileClassAnnotationsChecker ), - identifierChecker = JvmSimpleNameBacktickChecker + identifierChecker = JvmSimpleNameBacktickChecker, + + overloadFilter = JvmOverloadFilter ) { override fun configure(container: StorageComponentContainer) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadFilter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadFilter.kt new file mode 100644 index 00000000000..a64d770cc6a --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadFilter.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve + +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor + + +interface OverloadFilter { + fun filterPackageMemberOverloads(overloads: Collection): Collection + + object DEFAULT : OverloadFilter { + override fun filterPackageMemberOverloads(overloads: Collection): Collection = + overloads + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java index 1a8a002f109..08cf687121c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.java @@ -35,10 +35,16 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; public class OverloadResolver { @NotNull private final BindingTrace trace; + @NotNull private final OverloadFilter overloadFilter; @NotNull private final MainFunctionDetector mainFunctionDetector; - public OverloadResolver(@NotNull BindingTrace trace) { + public OverloadResolver( + @NotNull BindingTrace trace, + @NotNull OverloadFilter overloadFilter + ) { this.trace = trace; + this.overloadFilter = overloadFilter; + mainFunctionDetector = new MainFunctionDetector(trace.getBindingContext()); } @@ -88,7 +94,8 @@ public class OverloadResolver { @NotNull BodiesResolveContext c, @NotNull MultiMap inPackages ) { - MultiMap membersByName = OverloadUtil.groupModulePackageMembersByFqName(c, inPackages); + MultiMap membersByName = + OverloadUtil.groupModulePackageMembersByFqName(c, inPackages, overloadFilter); for (Map.Entry> e : membersByName.entrySet()) { FqNameUnsafe fqName = e.getKey().parent(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadUtil.kt index 9a49773f512..846b60446ca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadUtil.kt @@ -82,16 +82,17 @@ object OverloadUtil { public @JvmStatic fun groupModulePackageMembersByFqName( c: BodiesResolveContext, - constructorsInPackages: MultiMap + constructorsInPackages: MultiMap, + overloadFilter: OverloadFilter ): MultiMap { val packageMembersByName = MultiMap() - collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values) { + collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values, overloadFilter) { scope, name -> scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS) } - collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values) { + collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) { scope, name -> scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS).filterIsInstance() } @@ -105,6 +106,7 @@ object OverloadUtil { private inline fun collectModulePackageMembersWithSameName( packageMembersByName: MultiMap, interestingDescriptors: Collection, + overloadFilter: OverloadFilter, getMembersByName: (MemberScope, Name) -> Collection ) { val observedFQNs = hashSetOf() @@ -115,13 +117,14 @@ object OverloadUtil { if (observedFQNs.contains(descriptorFQN)) continue observedFQNs.add(descriptorFQN) - val packageMembersWithSameName = getModulePackageMembersWithSameName(descriptor, getMembersByName) + val packageMembersWithSameName = getModulePackageMembersWithSameName(descriptor, overloadFilter, getMembersByName) packageMembersByName.putValues(descriptorFQN, packageMembersWithSameName) } } private inline fun getModulePackageMembersWithSameName( packageMember: CallableMemberDescriptor, + overloadFilter: OverloadFilter, getMembersByName: (MemberScope, Name) -> Collection ): Collection { val containingPackage = packageMember.containingDeclaration @@ -132,10 +135,13 @@ object OverloadUtil { val containingModule = DescriptorUtils.getContainingModuleOrNull(packageMember) ?: return listOf(packageMember) val containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope - val possibleOverloads = getMembersByName(containingPackageScope, packageMember.name) + val possibleOverloads = + getMembersByName(containingPackageScope, packageMember.name).filter { + // NB memberScope for PackageViewDescriptor includes module dependencies + DescriptorUtils.getContainingModule(it) == containingModule + } - // NB memberScope for PackageViewDescriptor includes module dependencies - return possibleOverloads.filter { DescriptorUtils.getContainingModule(it) == containingModule } + return overloadFilter.filterPackageMemberOverloads(possibleOverloads) } private fun MemberDescriptor.isPrivate() = Visibilities.isPrivate(this.visibility) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt index ee57cf7b963..57fb5757a3c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TargetPlatform.kt @@ -44,7 +44,8 @@ abstract class TargetPlatform( override val builtIns: KotlinBuiltIns get() = DefaultBuiltIns.Instance override val defaultModuleParameters = ModuleParameters.Empty - override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf(), IdentifierChecker.DEFAULT) + override val platformConfigurator = PlatformConfigurator(DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf(), + IdentifierChecker.DEFAULT, OverloadFilter.DEFAULT) } } @@ -69,7 +70,8 @@ open class PlatformConfigurator( additionalTypeCheckers: List, additionalSymbolUsageValidators: List, private val additionalAnnotationCheckers: List, - private val identifierChecker: IdentifierChecker + private val identifierChecker: IdentifierChecker, + private val overloadFilter: OverloadFilter ) { private val declarationCheckers: List = DEFAULT_DECLARATION_CHECKERS + additionalDeclarationCheckers @@ -86,6 +88,7 @@ open class PlatformConfigurator( useInstance(symbolUsageValidator) additionalAnnotationCheckers.forEach { useInstance(it) } useInstance(identifierChecker) + useInstance(overloadFilter) } } } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt index 86f0d0b6771..9a2335879d8 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/JsPlatformConfigurator.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.js.resolve.diagnostics.JsCallChecker import org.jetbrains.kotlin.resolve.IdentifierChecker +import org.jetbrains.kotlin.resolve.OverloadFilter import org.jetbrains.kotlin.resolve.PlatformConfigurator import org.jetbrains.kotlin.types.DynamicTypesAllowed @@ -30,7 +31,8 @@ public object JsPlatformConfigurator : PlatformConfigurator( additionalTypeCheckers = listOf(), additionalSymbolUsageValidators = listOf(), additionalAnnotationCheckers = listOf(), - identifierChecker = IdentifierChecker.DEFAULT + identifierChecker = IdentifierChecker.DEFAULT, + overloadFilter = OverloadFilter.DEFAULT ) { override fun configure(container: StorageComponentContainer) { super.configure(container)