Introduce JvmMemberSignature to represent name and desc of jvm methods and fields

Return member name and desc in a class in order not to parse that information
from concatenated string when required.
This commit is contained in:
Ilya Gorbunov
2018-05-27 18:14:16 +03:00
parent eee9f8ab3f
commit 36c658fd8b
12 changed files with 91 additions and 77 deletions
@@ -50,7 +50,7 @@ private fun inlineFunctionsJvmNames(functions: List<ProtoBuf.Function>, nameReso
val typeTable = TypeTable(protoTypeTable)
val inlineFunctions = functions.filter { Flags.IS_INLINE.get(it.flags) }
val jvmNames = inlineFunctions.mapNotNull {
JvmProtoBufUtil.getJvmMethodSignature(it, nameResolver, typeTable)
JvmProtoBufUtil.getJvmMethodSignature(it, nameResolver, typeTable)?.toString()
}
return jvmNames.toSet()
}
@@ -334,10 +334,10 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
): MemberSignature? {
return when {
proto is ProtoBuf.Constructor -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable) ?: return null)
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmConstructorSignature(proto, nameResolver, typeTable)?.toString() ?: return null)
}
proto is ProtoBuf.Function -> {
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable) ?: return null)
MemberSignature.fromMethodNameAndDesc(JvmProtoBufUtil.getJvmMethodSignature(proto, nameResolver, typeTable)?.toString() ?: return null)
}
proto is ProtoBuf.Property -> {
val signature = proto.getExtensionOrNull(propertySignature) ?: return null
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. 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.metadata.jvm.deserialization
data class JvmMemberSignature(val name: String, val desc: String) {
override fun toString() = name + desc
}
@@ -64,7 +64,7 @@ object JvmProtoBufUtil {
proto: ProtoBuf.Function,
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
): JvmMemberSignature? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.methodSignature)
val name = if (signature != null && signature.hasName()) signature.name else proto.name
val desc = if (signature != null && signature.hasDesc()) {
@@ -78,14 +78,14 @@ object JvmProtoBufUtil {
parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc
}
return nameResolver.getString(name) + desc
return JvmMemberSignature(nameResolver.getString(name), desc)
}
fun getJvmConstructorSignature(
proto: ProtoBuf.Constructor,
nameResolver: NameResolver,
typeTable: TypeTable
): String? {
): JvmMemberSignature? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.constructorSignature)
val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc)
@@ -95,14 +95,14 @@ object JvmProtoBufUtil {
mapTypeDefault(it.type(typeTable), nameResolver) ?: return null
}.joinToString(separator = "", prefix = "(", postfix = ")V")
}
return "<init>" + desc
return JvmMemberSignature("<init>", desc)
}
fun getJvmFieldSignature(
proto: ProtoBuf.Property,
nameResolver: NameResolver,
typeTable: TypeTable
): PropertySignature? {
): JvmMemberSignature? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
val field =
if (signature.hasField()) signature.field else null
@@ -112,10 +112,9 @@ object JvmProtoBufUtil {
if (field != null && field.hasDesc()) nameResolver.getString(field.desc)
else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null
return PropertySignature(nameResolver.getString(name), desc)
return JvmMemberSignature(nameResolver.getString(name), desc)
}
data class PropertySignature(val name: String, val desc: String)
private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(type.className)) else null
@@ -172,12 +172,12 @@ internal object RuntimeTypeMapper {
val proto = function.proto
if (proto is ProtoBuf.Function) {
JvmProtoBufUtil.getJvmMethodSignature(proto, function.nameResolver, function.typeTable)?.let { signature ->
return JvmFunctionSignature.KotlinFunction(signature)
return JvmFunctionSignature.KotlinFunction(signature.toString())
}
}
if (proto is ProtoBuf.Constructor) {
JvmProtoBufUtil.getJvmConstructorSignature(proto, function.nameResolver, function.typeTable)?.let { signature ->
return JvmFunctionSignature.KotlinConstructor(signature)
return JvmFunctionSignature.KotlinConstructor(signature.toString())
}
}
// If it's a deserialized function but has no JVM signature, it must be from built-ins
@@ -156,8 +156,8 @@ private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignatu
}
if (descriptor is DeserializedSimpleFunctionDescriptor) {
JvmProtoBufUtil.getJvmMethodSignature(descriptor.proto, descriptor.nameResolver, descriptor.typeTable)?.let {
val signature = MemberSignature.fromMethodNameAndDesc(it)
JvmProtoBufUtil.getJvmMethodSignature(descriptor.proto, descriptor.nameResolver, descriptor.typeTable)?.let { it ->
val signature = MemberSignature.fromMethodNameAndDesc(it.toString())
save((descriptor.containingDeclaration as? ClassDescriptor)?.relativeClassName().orEmpty(), signature)
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package kotlinx.metadata.jvm
/**
* A signature of JVM method or field
*
* @property name name of method or field
* @property desc JVM descriptor of a method, e.g. `(Ljava/lang/Object;)Z`, or a field type, e.g. `Ljava/lang/String;`
*/
data class JvmMemberSignature(val name: String, val desc: String) {
override fun toString() = name + desc
}
internal fun org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature.wrapAsPublic() = JvmMemberSignature(name, desc)
@@ -30,7 +30,7 @@ internal class JvmMetadataExtensions : MetadataExtensions {
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable) {
val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, strings, types))
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, strings, types)?.wrapAsPublic())
val lambdaClassOriginName = proto.getExtensionOrNull(JvmProtoBuf.lambdaClassOriginName)
if (lambdaClassOriginName != null) {
@@ -47,22 +47,21 @@ internal class JvmMetadataExtensions : MetadataExtensions {
val setterSignature =
if (propertySignature != null && propertySignature.hasSetter()) propertySignature.setter else null
ext.visit(
fieldSignature?.name,
fieldSignature?.desc,
getterSignature?.run { strings.getString(name) + strings.getString(desc) },
setterSignature?.run { strings.getString(name) + strings.getString(desc) }
fieldSignature?.wrapAsPublic(),
getterSignature?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) },
setterSignature?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) }
)
val syntheticMethod =
if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { strings.getString(name) + strings.getString(desc) })
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) })
ext.visitEnd()
}
override fun readConstructorExtensions(v: KmConstructorVisitor, proto: ProtoBuf.Constructor, strings: NameResolver, types: TypeTable) {
val ext = v.visitExtensions(JvmConstructorExtensionVisitor.TYPE) as? JvmConstructorExtensionVisitor ?: return
ext.visit(JvmProtoBufUtil.getJvmConstructorSignature(proto, strings, types))
ext.visit(JvmProtoBufUtil.getJvmConstructorSignature(proto, strings, types)?.wrapAsPublic())
}
override fun readTypeParameterExtensions(v: KmTypeParameterVisitor, proto: ProtoBuf.TypeParameter, strings: NameResolver) {
@@ -98,7 +97,7 @@ internal class JvmMetadataExtensions : MetadataExtensions {
): KmFunctionExtensionVisitor? {
if (type != JvmFunctionExtensionVisitor.TYPE) return null
return object : JvmFunctionExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
if (desc != null) {
proto.setExtension(JvmProtoBuf.methodSignature, desc.toJvmMethodSignature(strings))
}
@@ -117,21 +116,17 @@ internal class JvmMetadataExtensions : MetadataExtensions {
return object : JvmPropertyExtensionVisitor() {
var signature: JvmProtoBuf.JvmPropertySignature.Builder? = null
override fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
if (fieldName == null && fieldTypeDesc == null && getterDesc == null && setterDesc == null) return
override fun visit(fieldDesc: JvmMemberSignature?, getterDesc: JvmMemberSignature?, setterDesc: JvmMemberSignature?) {
if (fieldDesc == null && getterDesc == null && setterDesc == null) return
if (signature == null) {
signature = JvmProtoBuf.JvmPropertySignature.newBuilder()
}
signature!!.apply {
if (fieldName != null || fieldTypeDesc != null) {
if (fieldDesc != null) {
field = JvmProtoBuf.JvmFieldSignature.newBuilder().also { field ->
if (fieldName != null) {
field.name = strings.getStringIndex(fieldName)
}
if (fieldTypeDesc != null) {
field.desc = strings.getStringIndex(fieldTypeDesc)
}
field.name = strings.getStringIndex(fieldDesc.name)
field.desc = strings.getStringIndex(fieldDesc.desc)
}.build()
}
if (getterDesc != null) {
@@ -143,7 +138,7 @@ internal class JvmMetadataExtensions : MetadataExtensions {
}
}
override fun visitSyntheticMethodForAnnotations(desc: String?) {
override fun visitSyntheticMethodForAnnotations(desc: JvmMemberSignature?) {
if (desc == null) return
if (signature == null) {
@@ -166,7 +161,7 @@ internal class JvmMetadataExtensions : MetadataExtensions {
): KmConstructorExtensionVisitor? {
if (type != JvmConstructorExtensionVisitor.TYPE) return null
return object : JvmConstructorExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
if (desc != null) {
proto.setExtension(JvmProtoBuf.constructorSignature, desc.toJvmMethodSignature(strings))
}
@@ -200,9 +195,9 @@ internal class JvmMetadataExtensions : MetadataExtensions {
}
}
private fun String.toJvmMethodSignature(strings: StringTable): JvmProtoBuf.JvmMethodSignature =
private fun JvmMemberSignature.toJvmMethodSignature(strings: StringTable): JvmProtoBuf.JvmMethodSignature =
JvmProtoBuf.JvmMethodSignature.newBuilder().apply {
name = strings.getStringIndex(substringBefore('('))
desc = strings.getStringIndex("(" + substringAfter('('))
name = strings.getStringIndex(this@toJvmMethodSignature.name)
desc = strings.getStringIndex(this@toJvmMethodSignature.desc)
}.build()
}
@@ -45,7 +45,7 @@ open class JvmFunctionExtensionVisitor @JvmOverloads constructor(
*
* @param desc the signature of the function
*/
open fun visit(desc: String?) {
open fun visit(desc: JvmMemberSignature?) {
delegate?.visit(desc)
}
@@ -84,8 +84,8 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
* @param setterDesc the signature of the property setter in the JVM-based format: `"setX(Ljava/lang/Object;)V"`,
* or `null` if this property has no setter or its signature is unknown
*/
open fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
delegate?.visit(fieldName, fieldTypeDesc, getterDesc, setterDesc)
open fun visit(fieldDesc: JvmMemberSignature?, getterDesc: JvmMemberSignature?, setterDesc: JvmMemberSignature?) {
delegate?.visit(fieldDesc, getterDesc, setterDesc)
}
/**
@@ -94,7 +94,7 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
*
* @param desc the signature of the synthetic method
*/
open fun visitSyntheticMethodForAnnotations(desc: String?) {
open fun visitSyntheticMethodForAnnotations(desc: JvmMemberSignature?) {
delegate?.visitSyntheticMethodForAnnotations(desc)
}
@@ -128,7 +128,7 @@ open class JvmConstructorExtensionVisitor @JvmOverloads constructor(
*
* @param desc the signature of the constructor
*/
open fun visit(desc: String?) {
open fun visit(desc: JvmMemberSignature?) {
delegate?.visit(desc)
}
@@ -45,17 +45,14 @@ private val VISIBILITY_FLAGS_MAP = mapOf(
)
private fun Flags.toVisibility() = VISIBILITY_FLAGS_MAP.entries.firstOrNull { (modifier) -> modifier(this) }?.value
private fun String.toMemberSignature() = indexOf("(").let { i ->
if (i < 0) MemberSignature("", this) else MemberSignature(substring(0, i), substring(i))
}
private fun visitFunction(flags: Flags, name: String, addMember: (MemberVisibility) -> Unit) =
object : KmFunctionVisitor() {
var jvmDesc: String? = null
var jvmDesc: JvmMemberSignature? = null
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? {
if (type != JvmFunctionExtensionVisitor.TYPE) return null
return object : JvmFunctionExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
jvmDesc = desc
}
}
@@ -63,25 +60,25 @@ private fun visitFunction(flags: Flags, name: String, addMember: (MemberVisibili
override fun visitEnd() {
jvmDesc?.let { jvmDesc ->
addMember(MemberVisibility(jvmDesc.toMemberSignature(), flags))
addMember(MemberVisibility(jvmDesc, flags))
}
}
}
private fun visitConstructor(flags: Flags, addMember: (MemberVisibility) -> Unit) =
object : KmConstructorVisitor() {
var jvmDesc: String? = null
var jvmDesc: JvmMemberSignature? = null
override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor? {
if (type != JvmConstructorExtensionVisitor.TYPE) return null
return object : JvmConstructorExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
jvmDesc = desc
}
}
}
override fun visitEnd() {
jvmDesc?.toMemberSignature()?.let { signature ->
jvmDesc?.let { signature ->
addMember(MemberVisibility(signature, flags))
}
}
@@ -89,19 +86,17 @@ private fun visitConstructor(flags: Flags, addMember: (MemberVisibility) -> Unit
private fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setterFlags: Flags, addMember: (MemberVisibility) -> Unit) =
object : KmPropertyVisitor() {
var fieldDesc: MemberSignature? = null
var _fieldDesc: MemberSignature? = null
var _getterDesc: MemberSignature? = null
var _setterDesc: MemberSignature? = null
override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor? {
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
override fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
if (fieldName != null && fieldTypeDesc != null)
fieldDesc = MemberSignature(fieldName, fieldTypeDesc)
_getterDesc = getterDesc?.toMemberSignature()
_setterDesc = setterDesc?.toMemberSignature()
override fun visit(fieldDesc: JvmMemberSignature?, getterDesc: JvmMemberSignature?, setterDesc: JvmMemberSignature?) {
_fieldDesc = fieldDesc
_getterDesc = getterDesc
_setterDesc = setterDesc
}
}
}
@@ -109,7 +104,7 @@ private fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setter
override fun visitEnd() {
_getterDesc?.let { addMember(MemberVisibility(it, getterFlags)) }
_setterDesc?.let { addMember(MemberVisibility(it, setterFlags)) }
fieldDesc?.let {
_fieldDesc?.let {
val fieldVisibility = when {
Flag.Property.IS_LATEINIT(flags) -> setterFlags
_getterDesc == null && _setterDesc == null -> flags // JvmField or const case
@@ -26,7 +26,7 @@ fun ClassVisibility.findMember(signature: MemberSignature): MemberVisibility? =
data class MemberVisibility(val member: MemberSignature, val visibility: Flags?)
data class MemberSignature(val name: String, val desc: String)
typealias MemberSignature = kotlinx.metadata.jvm.JvmMemberSignature
private fun isPublic(visibility: Flags?, isPublishedApi: Boolean) =
visibility == null
@@ -19,7 +19,7 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
var receiverParameterType: String? = null
var returnType: String? = null
var versionRequirement: String? = null
var jvmDesc: String? = null
var jvmDesc: JvmMemberSignature? = null
var lambdaClassOriginName: String? = null
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
@@ -42,7 +42,7 @@ private fun visitFunction(settings: KotlinpSettings, sb: StringBuilder, flags: F
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? {
if (type != JvmFunctionExtensionVisitor.TYPE) return null
return object : JvmFunctionExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
jvmDesc = desc
}
@@ -91,11 +91,10 @@ private fun visitProperty(
var returnType: String? = null
var setterParameter: String? = null
var versionRequirement: String? = null
var jvmFieldName: String? = null
var jvmFieldTypeDesc: String? = null
var jvmGetterDesc: String? = null
var jvmSetterDesc: String? = null
var jvmSyntheticMethodForAnnotationsDesc: String? = null
var jvmFieldDesc: JvmMemberSignature? = null
var jvmGetterDesc: JvmMemberSignature? = null
var jvmSetterDesc: JvmMemberSignature? = null
var jvmSyntheticMethodForAnnotationsDesc: JvmMemberSignature? = null
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
printType(flags) { receiverParameterType = it }
@@ -115,14 +114,13 @@ private fun visitProperty(
override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor? {
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
override fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
jvmFieldName = fieldName
jvmFieldTypeDesc = fieldTypeDesc
override fun visit(fieldDesc: JvmMemberSignature?, getterDesc: JvmMemberSignature?, setterDesc: JvmMemberSignature?) {
jvmFieldDesc = fieldDesc
jvmGetterDesc = getterDesc
jvmSetterDesc = setterDesc
}
override fun visitSyntheticMethodForAnnotations(desc: String?) {
override fun visitSyntheticMethodForAnnotations(desc: JvmMemberSignature?) {
jvmSyntheticMethodForAnnotationsDesc = desc
}
}
@@ -133,11 +131,10 @@ private fun visitProperty(
if (versionRequirement != null) {
sb.appendln(" // $versionRequirement")
}
if (jvmFieldName != null || jvmFieldTypeDesc != null) {
sb.append(" // field: ${jvmFieldName ?: "<null>"}")
if (jvmFieldTypeDesc != null) {
sb.append(":$jvmFieldTypeDesc")
}
if (jvmFieldDesc != null) {
// TODO: support that case in jvmFieldDesc.toString()
sb.append(" // field: ${jvmFieldDesc!!.name}")
sb.append(":").append(jvmFieldDesc!!.desc)
sb.appendln()
}
if (jvmGetterDesc != null) {
@@ -188,7 +185,7 @@ private fun visitConstructor(sb: StringBuilder, flags: Flags): KmConstructorVisi
object : KmConstructorVisitor() {
val params = mutableListOf<String>()
var versionRequirement: String? = null
var jvmDesc: String? = null
var jvmDesc: JvmMemberSignature? = null
override fun visitValueParameter(flags: Flags, name: String): KmValueParameterVisitor? =
printValueParameter(flags, name) { params.add(it) }
@@ -199,7 +196,7 @@ private fun visitConstructor(sb: StringBuilder, flags: Flags): KmConstructorVisi
override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor? {
if (type != JvmConstructorExtensionVisitor.TYPE) return null
return object : JvmConstructorExtensionVisitor() {
override fun visit(desc: String?) {
override fun visit(desc: JvmMemberSignature?) {
jvmDesc = desc
}
}