[Commonizer] Blacklist conflicting K/N functions from commonization

This commit is contained in:
Dmitriy Dolovov
2019-12-11 18:53:59 +03:00
parent c79fcb8cf3
commit 359e49fa02
3 changed files with 56 additions and 14 deletions
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.getAbbreviation
private val DEPRECATED_ANNOTATION_FQN = FqName(Deprecated::class.java.name)
internal fun SimpleFunctionDescriptor.isKniBridgeFunction() =
name.asString().startsWith("kniBridge")
// the following logic determines Kotlin functions with conflicting overloads in Darwin library:
internal fun SimpleFunctionDescriptor.isBlacklistedDarwinFunction(): Boolean {
if ((containingDeclaration as? PackageFragmentDescriptor)?.fqName?.isUnderDarwinPackage != true)
return false
val name = name.asString()
if (!name.startsWith("simd_") && !name.startsWith("__"))
return false
if (annotations.hasAnnotation(DEPRECATED_ANNOTATION_FQN))
return true
return valueParameters.any { parameter ->
val type = parameter.type
val abbreviationType = type.getAbbreviation()
abbreviationType != null
&& abbreviationType.declarationDescriptor.name.asString().startsWith("simd_")
&& type.declarationDescriptor.name.asString() == "Vector128"
}
}
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer
import org.jetbrains.kotlin.descriptors.commonizer.fqNameWithTypeParameters
import org.jetbrains.kotlin.descriptors.commonizer.isBlacklistedDarwinFunction
import org.jetbrains.kotlin.descriptors.commonizer.isKniBridgeFunction
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -51,7 +53,7 @@ internal inline fun PropertyCollector(
internal inline fun FunctionCollector(
crossinline typedCollector: (SimpleFunctionDescriptor) -> Unit
): (DeclarationDescriptor) -> Boolean = Collector<SimpleFunctionDescriptor> { candidate ->
if (candidate.kind.isReal && !candidate.name.asString().startsWith("kniBridge"))
if (candidate.kind.isReal && !candidate.isKniBridgeFunction() && !candidate.isBlacklistedDarwinFunction())
typedCollector(candidate)
}
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.descriptors.commonizer
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.konan.library.KonanFactories.DefaultDeserializedDescriptorFactory
@@ -98,23 +95,28 @@ private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES = ForwardDeclarationsFqNam
fqName.asString()
}
private const val DARWIN_PACKAGE_PREFIX = "platform.darwin"
internal val FqName.isUnderStandardKotlinPackages: Boolean
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGE_PREFIXES)
internal val FqName.isUnderKotlinNativeSyntheticPackages: Boolean
get() = hasAnyPrefix(KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES)
internal val FqName.isUnderDarwinPackage: Boolean
get() = asString().hasPrefix(DARWIN_PACKAGE_PREFIX)
private fun FqName.hasAnyPrefix(prefixes: List<String>): Boolean =
asString().let { fqName ->
prefixes.any { prefix ->
val lengthDifference = fqName.length - prefix.length
when {
lengthDifference == 0 -> fqName == prefix
lengthDifference > 0 -> fqName[prefix.length] == '.' && fqName.startsWith(prefix)
else -> false
}
}
asString().let { fqName -> prefixes.any(fqName::hasPrefix) }
private fun String.hasPrefix(prefix: String): Boolean {
val lengthDifference = length - prefix.length
return when {
lengthDifference == 0 -> this == prefix
lengthDifference > 0 -> this[prefix.length] == '.' && this.startsWith(prefix)
else -> false
}
}
internal val ModuleDescriptor.packageFragmentProvider
get() = (this as ModuleDescriptorImpl).packageFragmentProviderForModuleContentWithoutDependencies