Clean code after transformation

This commit is contained in:
Mikhael Bogdanov
2017-05-16 10:13:46 +02:00
parent eca359f176
commit 8a083a41d5
6 changed files with 32 additions and 33 deletions
@@ -428,7 +428,7 @@ class AnonymousObjectTransformer(
//lambda with non InlinedLambdaRemapper already have outer
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
val ownerType = Type.getObjectType(parent.lambdaInternalName)
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType)
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false)
val composed = StackValue.LOCAL_0
@@ -24,16 +24,16 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
open class FieldRemapper(
val lambdaInternalName: String?,
val originalLambdaInternalName: String?,
@JvmField val parent: FieldRemapper?,
private val params: Parameters
protected val parameters: Parameters
) {
val isRoot = parent == null
open val isInsideInliningLambda: Boolean = parent?.isInsideInliningLambda ?: false
protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean {
return fieldOwner == lambdaInternalName &&
return fieldOwner == originalLambdaInternalName &&
//don't process general field of anonymous objects
InlineCodegenUtil.isCapturedFieldName(fieldName)
}
@@ -72,7 +72,7 @@ open class FieldRemapper(
}
@JvmOverloads
open fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo> = params.captured): CapturedParamInfo? {
open fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo> = parameters.captured): CapturedParamInfo? {
for (valueDescriptor in captured) {
if (valueDescriptor.originalFieldName == fieldInsnNode.name && valueDescriptor.containingLambdaName == fieldInsnNode.owner) {
return valueDescriptor
@@ -82,7 +82,7 @@ open class FieldRemapper(
}
open val newLambdaInternalName: String
get() = lambdaInternalName!!
get() = originalLambdaInternalName!!
open fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? =
MethodInliner.findCapturedField(node, this).remapValue
@@ -89,7 +89,8 @@ public class InlineCodegenUtil {
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
public static final String DEFAULT_LAMBDA_FAKE_CALL = "$$$DEFAULT_LAMBDA_FAKE_CALL$$$";
public static final String CAPTURED_FIELD_FOLD_PREFIX = "$$$";
@Nullable
public static SMAPAndMethodNode getMethodNode(
byte[] classData,
@@ -28,9 +28,8 @@ class InlinedLambdaRemapper(
public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) =
isFolding && super.canProcess(fieldOwner, fieldName, true)
override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo>): CapturedParamInfo? {
return parent!!.findField(fieldInsnNode, captured)
}
override fun findField(fieldInsnNode: FieldInsnNode, captured: Collection<CapturedParamInfo>) =
parent!!.findField(fieldInsnNode, captured)
override val isInsideInliningLambda: Boolean = true
@@ -709,7 +709,7 @@ class MethodInliner(
assert(node.name.startsWith("$$$")) { "Captured field template should start with $$$ prefix" }
val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc)
val field = fieldRemapper.findField(fin) ?: throw IllegalStateException(
"Couldn't find captured field " + node.owner + "." + node.name + " in " + fieldRemapper.lambdaInternalName
"Couldn't find captured field ${node.owner}.${node.name} in ${fieldRemapper.originalLambdaInternalName}"
)
return field
}
@@ -17,18 +17,20 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.THIS
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
class RegeneratedLambdaFieldRemapper(
val oldOwnerType: String,
originalLambdaInternalName: String,
override val newLambdaInternalName: String,
private val parameters: Parameters,
parameters: Parameters,
private val recapturedLambdas: Map<String, LambdaInfo>,
remapper: FieldRemapper,
private val isConstructor: Boolean
) : FieldRemapper(oldOwnerType, remapper, parameters) {
) : FieldRemapper(originalLambdaInternalName, remapper, parameters) {
public override fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean) =
super.canProcess(fieldOwner, fieldName, isFolding) || isRecapturedLambdaType(fieldOwner, isFolding)
@@ -41,38 +43,35 @@ class RegeneratedLambdaFieldRemapper(
if (searchInParent) {
return parent!!.findField(fieldInsnNode)
}
return findFieldInMyCaptured(fieldInsnNode)
return findFieldInSuper(fieldInsnNode)
}
override fun processNonAload0FieldAccessChains(isInlinedLambda: Boolean): Boolean {
return isInlinedLambda && isConstructor
}
private fun findFieldInMyCaptured(fieldInsnNode: FieldInsnNode): CapturedParamInfo? {
private fun findFieldInSuper(fieldInsnNode: FieldInsnNode): CapturedParamInfo? {
return super.findField(fieldInsnNode, parameters.captured)
}
override fun getFieldForInline(node: FieldInsnNode, prefix: StackValue?): StackValue? {
assert(node.name.startsWith("$$$")) { "Captured field template should start with $$$ prefix" }
if (node.name == "$$$" + InlineCodegenUtil.THIS) {
assert(oldOwnerType == node.owner) { "Can't unfold '$$\$THIS' parameter" }
val fieldName = node.name
assert(fieldName.startsWith(CAPTURED_FIELD_FOLD_PREFIX)) { "Captured field template should start with $CAPTURED_FIELD_FOLD_PREFIX prefix" }
if (fieldName == CAPTURED_FIELD_FOLD_PREFIX + THIS) {
assert(originalLambdaInternalName == node.owner) { "Can't unfold '$CAPTURED_FIELD_FOLD_PREFIX$THIS' parameter" }
return StackValue.LOCAL_0
}
val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc)
var field = findFieldInMyCaptured(fin)
val fin = FieldInsnNode(node.opcode, node.owner, fieldName.substringAfter(CAPTURED_FIELD_FOLD_PREFIX), node.desc)
var fromParent = false
val field = findFieldInSuper(fin) ?:
//search in parent
findFieldInSuper(FieldInsnNode(
Opcodes.GETSTATIC, originalLambdaInternalName, InlineCodegenUtil.`THIS$0`,
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
))?.also { fromParent = true } ?:
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")
var searchInParent = false
if (field == null) {
field = findFieldInMyCaptured(FieldInsnNode(
Opcodes.GETSTATIC, oldOwnerType, InlineCodegenUtil.`THIS$0`,
Type.getObjectType(parent!!.lambdaInternalName!!).descriptor
))
searchInParent = true
if (field == null) {
throw IllegalStateException("Couldn't find captured this " + lambdaInternalName + " for " + node.name)
}
}
val result = StackValue.field(
if (field.isSkipped)
@@ -84,6 +83,6 @@ class RegeneratedLambdaFieldRemapper(
prefix ?: StackValue.LOCAL_0
)
return if (searchInParent) parent!!.getFieldForInline(node, result) else result
return if (fromParent) parent!!.getFieldForInline(node, result) else result
}
}