Refactor: make JvmMemberSignature a sealed class

Use JvmMemberSignature.asString instead of toString
This commit is contained in:
Ilya Gorbunov
2018-05-29 06:50:26 +03:00
parent 2f58539200
commit 1a290d0c73
10 changed files with 65 additions and 59 deletions
@@ -50,7 +50,7 @@ private fun inlineFunctionsJvmNames(functions: List<ProtoBuf.Function>, nameReso
val typeTable = TypeTable(protoTypeTable) val typeTable = TypeTable(protoTypeTable)
val inlineFunctions = functions.filter { Flags.IS_INLINE.get(it.flags) } val inlineFunctions = functions.filter { Flags.IS_INLINE.get(it.flags) }
val jvmNames = inlineFunctions.mapNotNull { val jvmNames = inlineFunctions.mapNotNull {
JvmProtoBufUtil.getJvmMethodSignature(it, nameResolver, typeTable)?.toString() JvmProtoBufUtil.getJvmMethodSignature(it, nameResolver, typeTable)?.asString()
} }
return jvmNames.toSet() return jvmNames.toSet()
} }
@@ -40,9 +40,9 @@ data class MemberSignature private constructor(internal val signature: String) {
} }
@JvmStatic @JvmStatic
fun fromJvmMemberSignature(signature: JvmMemberSignature): MemberSignature = when { fun fromJvmMemberSignature(signature: JvmMemberSignature): MemberSignature = when (signature) {
signature.isField -> fromFieldNameAndDesc(signature.name, signature.desc) is JvmMemberSignature.Method -> fromMethodNameAndDesc(signature.name, signature.desc)
else -> fromMethodNameAndDesc(signature.name, signature.desc) is JvmMemberSignature.Field -> fromFieldNameAndDesc(signature.name, signature.desc)
} }
@JvmStatic @JvmStatic
@@ -5,17 +5,25 @@
package org.jetbrains.kotlin.metadata.jvm.deserialization package org.jetbrains.kotlin.metadata.jvm.deserialization
data class JvmMemberSignature(val name: String, val desc: String) { /**
* 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;`
*/
sealed class JvmMemberSignature {
/** abstract val name: String
* Returns `true` when this signature represents a field. abstract val desc: String
*/
val isField: Boolean = desc.indexOf(")") < 0
/** data class Method(override val name: String, override val desc: String) : JvmMemberSignature() {
* Returns `true` when this signature represents a method. override fun asString() = name + desc
*/ }
val isMethod: Boolean get() = !isField
override fun toString() = if (isField) name + ":" + desc else name + desc data class Field(override val name: String, override val desc: String) : JvmMemberSignature() {
override fun asString() = name + ":" + desc
}
final override fun toString() = asString()
abstract fun asString(): String
} }
@@ -64,7 +64,7 @@ object JvmProtoBufUtil {
proto: ProtoBuf.Function, proto: ProtoBuf.Function,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable typeTable: TypeTable
): JvmMemberSignature? { ): JvmMemberSignature.Method? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.methodSignature) val signature = proto.getExtensionOrNull(JvmProtoBuf.methodSignature)
val name = if (signature != null && signature.hasName()) signature.name else proto.name val name = if (signature != null && signature.hasName()) signature.name else proto.name
val desc = if (signature != null && signature.hasDesc()) { val desc = if (signature != null && signature.hasDesc()) {
@@ -78,14 +78,14 @@ object JvmProtoBufUtil {
parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc parametersDesc.joinToString(separator = "", prefix = "(", postfix = ")") + returnTypeDesc
} }
return JvmMemberSignature(nameResolver.getString(name), desc) return JvmMemberSignature.Method(nameResolver.getString(name), desc)
} }
fun getJvmConstructorSignature( fun getJvmConstructorSignature(
proto: ProtoBuf.Constructor, proto: ProtoBuf.Constructor,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable typeTable: TypeTable
): JvmMemberSignature? { ): JvmMemberSignature.Method? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.constructorSignature) val signature = proto.getExtensionOrNull(JvmProtoBuf.constructorSignature)
val desc = if (signature != null && signature.hasDesc()) { val desc = if (signature != null && signature.hasDesc()) {
nameResolver.getString(signature.desc) nameResolver.getString(signature.desc)
@@ -95,14 +95,14 @@ object JvmProtoBufUtil {
mapTypeDefault(it.type(typeTable), nameResolver) ?: return null mapTypeDefault(it.type(typeTable), nameResolver) ?: return null
}.joinToString(separator = "", prefix = "(", postfix = ")V") }.joinToString(separator = "", prefix = "(", postfix = ")V")
} }
return JvmMemberSignature("<init>", desc) return JvmMemberSignature.Method("<init>", desc)
} }
fun getJvmFieldSignature( fun getJvmFieldSignature(
proto: ProtoBuf.Property, proto: ProtoBuf.Property,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable typeTable: TypeTable
): JvmMemberSignature? { ): JvmMemberSignature.Field? {
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null
val field = val field =
if (signature.hasField()) signature.field else null if (signature.hasField()) signature.field else null
@@ -112,7 +112,7 @@ object JvmProtoBufUtil {
if (field != null && field.hasDesc()) nameResolver.getString(field.desc) if (field != null && field.hasDesc()) nameResolver.getString(field.desc)
else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null
return JvmMemberSignature(nameResolver.getString(name), desc) return JvmMemberSignature.Field(nameResolver.getString(name), desc)
} }
@@ -53,13 +53,8 @@ import kotlin.reflect.jvm.internal.structure.*
internal sealed class JvmFunctionSignature { internal sealed class JvmFunctionSignature {
abstract fun asString(): String abstract fun asString(): String
class KotlinFunction(val signature: JvmMemberSignature) : JvmFunctionSignature() { class KotlinFunction(val signature: JvmMemberSignature.Method) : JvmFunctionSignature() {
private val _signature = signature.toString() private val _signature = signature.asString()
init {
require(signature.isMethod)
}
val methodName: String get() = signature.name val methodName: String get() = signature.name
val methodDesc: String get() = signature.desc val methodDesc: String get() = signature.desc
@@ -67,12 +62,8 @@ internal sealed class JvmFunctionSignature {
override fun asString(): String = _signature override fun asString(): String = _signature
} }
class KotlinConstructor(val signature: JvmMemberSignature) : JvmFunctionSignature() { class KotlinConstructor(val signature: JvmMemberSignature.Method) : JvmFunctionSignature() {
private val _signature = signature.toString() private val _signature = signature.asString()
init {
require(signature.isMethod)
}
val constructorDesc: String get() = signature.desc val constructorDesc: String get() = signature.desc
@@ -168,7 +168,7 @@ private object ByJvmSignatureIndexer : DecompiledTextIndexer<ClassNameAndSignatu
if (signature != null) { if (signature != null) {
val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, descriptor.nameResolver, descriptor.typeTable) val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, descriptor.nameResolver, descriptor.typeTable)
if (fieldSignature != null) { if (fieldSignature != null) {
save(className, MemberSignature.fromFieldNameAndDesc(fieldSignature.name, fieldSignature.desc)) save(className, MemberSignature.fromJvmMemberSignature(fieldSignature))
} }
if (signature.hasGetter()) { if (signature.hasGetter()) {
save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.getter)) save(className, MemberSignature.fromMethod(descriptor.nameResolver, signature.getter))
@@ -4,6 +4,7 @@
*/ */
package kotlinx.metadata.jvm package kotlinx.metadata.jvm
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature as JvmMemberSignatureImpl
/** /**
* A signature of JVM method or field * A signature of JVM method or field
@@ -11,19 +12,24 @@ package kotlinx.metadata.jvm
* @property name name of 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;` * @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) { sealed class JvmMemberSignature {
/** abstract val name: String
* Returns `true` when this signature represents a field. abstract val desc: String
*/
val isField: Boolean get() = desc.indexOf("(") < 0
/** data class Method(override val name: String, override val desc: String) : JvmMemberSignature() {
* Returns `true` when this signature represents a method. override fun asString() = name + desc
*/ }
val isMethod: Boolean get() = desc.indexOf("(") >= 0
override fun toString() = if (isField) name + ":" + desc else name + desc data class Field(override val name: String, override val desc: String) : JvmMemberSignature() {
override fun asString() = name + ":" + desc
}
final override fun toString() = asString()
abstract fun asString(): String
} }
internal fun org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature.wrapAsPublic() = JvmMemberSignature(name, desc) internal fun JvmMemberSignatureImpl.wrapAsPublic() = when (this) {
is JvmMemberSignatureImpl.Method -> JvmMemberSignature.Method(name, desc)
is JvmMemberSignatureImpl.Field -> JvmMemberSignature.Field(name, desc)
}
@@ -48,13 +48,13 @@ internal class JvmMetadataExtensions : MetadataExtensions {
if (propertySignature != null && propertySignature.hasSetter()) propertySignature.setter else null if (propertySignature != null && propertySignature.hasSetter()) propertySignature.setter else null
ext.visit( ext.visit(
fieldSignature?.wrapAsPublic(), fieldSignature?.wrapAsPublic(),
getterSignature?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) }, getterSignature?.run { JvmMemberSignature.Method(strings.getString(name), strings.getString(desc)) },
setterSignature?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) } setterSignature?.run { JvmMemberSignature.Method(strings.getString(name), strings.getString(desc)) }
) )
val syntheticMethod = val syntheticMethod =
if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { JvmMemberSignature(strings.getString(name), strings.getString(desc)) }) ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { JvmMemberSignature.Method(strings.getString(name), strings.getString(desc)) })
ext.visitEnd() ext.visitEnd()
} }
@@ -9,6 +9,7 @@ import org.objectweb.asm.*
import org.objectweb.asm.tree.* import org.objectweb.asm.tree.*
import java.io.InputStream import java.io.InputStream
import java.util.jar.JarFile import java.util.jar.JarFile
import kotlinx.metadata.jvm.JvmMemberSignature as MemberSignature
fun main(args: Array<String>) { fun main(args: Array<String>) {
val src = args[0] val src = args[0]
@@ -43,8 +44,8 @@ fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityFilter: (String)
val supertypes = listOf(superName) - "java/lang/Object" + interfaces.sorted() val supertypes = listOf(superName) - "java/lang/Object" + interfaces.sorted()
val memberSignatures = ( val memberSignatures = (
fields.map { with(it) { FieldBinarySignature(name, desc, isPublishedApi(), AccessFlags(access)) } } + fields.map { with(it) { FieldBinarySignature(MemberSignature.Field(name, desc), isPublishedApi(), AccessFlags(access)) } } +
methods.map { with(it) { MethodBinarySignature(name, desc, isPublishedApi(), AccessFlags(access)) } } methods.map { with(it) { MethodBinarySignature(MemberSignature.Method(name, desc), isPublishedApi(), AccessFlags(access)) } }
).filter { ).filter {
it.isEffectivelyPublic(classAccess, mVisibility) it.isEffectivelyPublic(classAccess, mVisibility)
} }
@@ -9,6 +9,7 @@ import kotlinx.metadata.jvm.KotlinClassMetadata
import org.objectweb.asm.Opcodes import org.objectweb.asm.Opcodes
import org.objectweb.asm.tree.* import org.objectweb.asm.tree.*
import kotlin.comparisons.* import kotlin.comparisons.*
import kotlinx.metadata.jvm.JvmMemberSignature as MemberSignature
val ACCESS_NAMES = mapOf( val ACCESS_NAMES = mapOf(
Opcodes.ACC_PUBLIC to "public", Opcodes.ACC_PUBLIC to "public",
@@ -38,8 +39,9 @@ data class ClassBinarySignature(
interface MemberBinarySignature { interface MemberBinarySignature {
val name: String val jvmMember: MemberSignature
val desc: String val name: String get() = jvmMember.name
val desc: String get() = jvmMember.desc
val access: AccessFlags val access: AccessFlags
val isPublishedApi: Boolean val isPublishedApi: Boolean
@@ -48,15 +50,14 @@ interface MemberBinarySignature {
&& (findMemberVisibility(classVisibility)?.isPublic(isPublishedApi) ?: true) && (findMemberVisibility(classVisibility)?.isPublic(isPublishedApi) ?: true)
fun findMemberVisibility(classVisibility: ClassVisibility?): MemberVisibility? { fun findMemberVisibility(classVisibility: ClassVisibility?): MemberVisibility? {
return classVisibility?.findMember(MemberSignature(name, desc)) return classVisibility?.findMember(jvmMember)
} }
val signature: String val signature: String
} }
data class MethodBinarySignature( data class MethodBinarySignature(
override val name: String, override val jvmMember: MemberSignature,
override val desc: String,
override val isPublishedApi: Boolean, override val isPublishedApi: Boolean,
override val access: AccessFlags override val access: AccessFlags
) : MemberBinarySignature { ) : MemberBinarySignature {
@@ -87,17 +88,16 @@ data class MethodBinarySignature(
return when { return when {
!access.isSynthetic -> null !access.isSynthetic -> null
name == "<init>" && "ILkotlin/jvm/internal/DefaultConstructorMarker;" in desc -> name == "<init>" && "ILkotlin/jvm/internal/DefaultConstructorMarker;" in desc ->
MemberSignature(name, desc.replace("ILkotlin/jvm/internal/DefaultConstructorMarker;", "")) MemberSignature.Method(name, desc.replace("ILkotlin/jvm/internal/DefaultConstructorMarker;", ""))
name.endsWith("\$default") && "ILjava/lang/Object;)" in desc -> name.endsWith("\$default") && "ILjava/lang/Object;)" in desc ->
MemberSignature(name.removeSuffix("\$default"), desc.replace("ILjava/lang/Object;)", ")").replace("(L$className;", "(")) MemberSignature.Method(name.removeSuffix("\$default"), desc.replace("ILjava/lang/Object;)", ")").replace("(L$className;", "("))
else -> null else -> null
} }
} }
} }
data class FieldBinarySignature( data class FieldBinarySignature(
override val name: String, override val jvmMember: MemberSignature,
override val desc: String,
override val isPublishedApi: Boolean, override val isPublishedApi: Boolean,
override val access: AccessFlags override val access: AccessFlags
) : MemberBinarySignature { ) : MemberBinarySignature {