JS: change how signature for mangling is generated, taking into account more information. See KT-15285
This commit is contained in:
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.js.naming
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.getNameForAnnotatedObject
|
||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
@@ -267,7 +266,7 @@ class NameSuggestion {
|
||||
return regularAndUnstable()
|
||||
}
|
||||
|
||||
fun mangledAndStable() = NameAndStability(getStableMangledName(baseName, getArgumentTypesAsString(descriptor)), true)
|
||||
fun mangledAndStable() = NameAndStability(getStableMangledName(baseName, encodeSignature(descriptor)), true)
|
||||
fun mangledPrivate() = NameAndStability(getPrivateMangledName(baseName, descriptor), false)
|
||||
|
||||
val effectiveVisibility = descriptor.ownEffectiveVisibility
|
||||
@@ -315,20 +314,7 @@ class NameSuggestion {
|
||||
|
||||
@JvmStatic fun getPrivateMangledName(baseName: String, descriptor: CallableDescriptor): String {
|
||||
val ownerName = descriptor.containingDeclaration.fqNameUnsafe.asString()
|
||||
return getStableMangledName(baseName, ownerName + ":" + getArgumentTypesAsString(descriptor))
|
||||
}
|
||||
|
||||
private fun getArgumentTypesAsString(descriptor: CallableDescriptor): String {
|
||||
val argTypes = StringBuilder()
|
||||
|
||||
val receiverParameter = descriptor.extensionReceiverParameter
|
||||
if (receiverParameter != null) {
|
||||
argTypes.append(receiverParameter.type.getJetTypeFqName(true)).append(".")
|
||||
}
|
||||
|
||||
argTypes.append(descriptor.valueParameters.joinToString(",") { it.type.getJetTypeFqName(true) })
|
||||
|
||||
return argTypes.toString()
|
||||
return getStableMangledName(baseName, ownerName + ":" + encodeSignature(descriptor))
|
||||
}
|
||||
|
||||
@JvmStatic fun getStableMangledName(suggestedName: String, forCalculateId: String): String {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.js.naming
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeProjection
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.getEffectiveVariance
|
||||
|
||||
fun encodeSignature(descriptor: CallableDescriptor): String {
|
||||
val sig = StringBuilder()
|
||||
|
||||
val typeParameterNames = nameTypeParameters(descriptor)
|
||||
val currentParameters = descriptor.typeParameters.filter { !it.isCapturedFromOuterDeclaration }.toSet()
|
||||
val usedTypeParameters = currentParameters.toMutableSet()
|
||||
val typeParameterNamer = { typeParameter: TypeParameterDescriptor ->
|
||||
usedTypeParameters += typeParameter.original
|
||||
typeParameterNames[typeParameter.original]!!
|
||||
}
|
||||
|
||||
val receiverParameter = descriptor.extensionReceiverParameter
|
||||
if (receiverParameter != null) {
|
||||
sig.encodeForSignature(receiverParameter.type, typeParameterNamer).append('/')
|
||||
}
|
||||
|
||||
for (valueParameter in descriptor.valueParameters) {
|
||||
if (valueParameter.index > 0) {
|
||||
sig.append(",")
|
||||
}
|
||||
if (valueParameter.varargElementType != null) {
|
||||
sig.append("*")
|
||||
}
|
||||
sig.encodeForSignature(valueParameter.type, typeParameterNamer)
|
||||
}
|
||||
|
||||
var first = true
|
||||
for (typeParameter in typeParameterNames.keys.asSequence().filter { it in usedTypeParameters }) {
|
||||
val upperBounds = typeParameter.upperBounds.filter { !KotlinBuiltIns.isNullableAny(it) }
|
||||
if (upperBounds.isEmpty() && typeParameter !in currentParameters) continue
|
||||
|
||||
sig.append(if (first) "|" else ",").append(typeParameterNames[typeParameter])
|
||||
first = false
|
||||
if (upperBounds.isEmpty()) continue
|
||||
|
||||
sig.append("<:")
|
||||
for ((boundIndex, upperBound) in upperBounds.withIndex()) {
|
||||
if (boundIndex > 0) {
|
||||
sig.append("&")
|
||||
}
|
||||
sig.encodeForSignature(upperBound, typeParameterNamer)
|
||||
}
|
||||
}
|
||||
|
||||
return sig.toString()
|
||||
}
|
||||
|
||||
private fun StringBuilder.encodeForSignature(
|
||||
type: KotlinType,
|
||||
typeParameterNamer: (TypeParameterDescriptor) -> String
|
||||
): StringBuilder {
|
||||
val declaration = type.constructor.declarationDescriptor!!
|
||||
if (declaration is TypeParameterDescriptor) {
|
||||
return append(typeParameterNamer(declaration))
|
||||
}
|
||||
|
||||
append(DescriptorUtils.getFqName(declaration).asString())
|
||||
|
||||
if (type.arguments.isNotEmpty()) {
|
||||
val parameters = declaration.typeConstructor.parameters
|
||||
append("<")
|
||||
for ((index, argument) in type.arguments.withIndex()) {
|
||||
if (index > 0) {
|
||||
append(",")
|
||||
}
|
||||
encodeForSignature(argument, parameters[index], typeParameterNamer)
|
||||
}
|
||||
append(">")
|
||||
}
|
||||
|
||||
if (type.isMarkedNullable) {
|
||||
append("?")
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
private fun StringBuilder.encodeForSignature(
|
||||
projection: TypeProjection,
|
||||
parameter: TypeParameterDescriptor,
|
||||
typeParameterNamer: (TypeParameterDescriptor) -> String
|
||||
): StringBuilder {
|
||||
if (projection.isStarProjection) {
|
||||
return append("*")
|
||||
}
|
||||
else {
|
||||
when (getEffectiveVariance(parameter.variance, projection.projectionKind)) {
|
||||
Variance.IN_VARIANCE -> append("-")
|
||||
Variance.OUT_VARIANCE -> append("+")
|
||||
Variance.INVARIANT -> {}
|
||||
}
|
||||
return encodeForSignature(projection.type, typeParameterNamer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun nameTypeParameters(descriptor: DeclarationDescriptor): Map<TypeParameterDescriptor, String> {
|
||||
val result = mutableMapOf<TypeParameterDescriptor, String>()
|
||||
for ((listIndex, list) in collectTypeParameters(descriptor).withIndex()) {
|
||||
for ((indexInList, typeParameter) in list.withIndex()) {
|
||||
result[typeParameter] = "$listIndex:$indexInList"
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun collectTypeParameters(descriptor: DeclarationDescriptor): List<List<TypeParameterDescriptor>> {
|
||||
var currentDescriptor: DeclarationDescriptor? = descriptor
|
||||
val result = mutableListOf<List<TypeParameterDescriptor>>()
|
||||
while (currentDescriptor != null) {
|
||||
getOwnTypeParameters(currentDescriptor)?.let { result += it }
|
||||
currentDescriptor = if (currentDescriptor is ConstructorDescriptor) {
|
||||
currentDescriptor.constructedClass.containingDeclaration
|
||||
}
|
||||
else {
|
||||
currentDescriptor.containingDeclaration
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun getOwnTypeParameters(descriptor: DeclarationDescriptor): List<TypeParameterDescriptor>? =
|
||||
when (descriptor) {
|
||||
is ClassDescriptor -> descriptor.declaredTypeParameters.filter { !it.isCapturedFromOuterDeclaration }
|
||||
is PropertyAccessorDescriptor -> getOwnTypeParameters(descriptor.correspondingProperty)
|
||||
is CallableDescriptor -> descriptor.typeParameters.filter { !it.isCapturedFromOuterDeclaration }
|
||||
else -> null
|
||||
}
|
||||
Reference in New Issue
Block a user