diff --git a/compiler/tests/org/jetbrains/jet/checkers/LazyOperationsLog.kt b/compiler/tests/org/jetbrains/jet/checkers/LazyOperationsLog.kt index df7f99cc2c5..65302cd0a89 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/LazyOperationsLog.kt +++ b/compiler/tests/org/jetbrains/jet/checkers/LazyOperationsLog.kt @@ -39,6 +39,9 @@ import org.jetbrains.jet.renderer.DescriptorRenderer import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.jet.lang.psi.debugText.getDebugText import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate +import java.lang.reflect.GenericDeclaration +import java.lang.reflect.Method +import java.lang.reflect.Constructor class LazyOperationsLog( val stringSanitizer: (String) -> String @@ -109,7 +112,7 @@ class LazyOperationsLog( val data = record.data val sb = StringBuilder() - sb.append(data.field?.getName() ?: "") + sb.append(data.field?.getName() ?: "in ${data.lambdaCreatedIn.getDeclarationName()}") if (!data.arguments.isEmpty()) { sb.append(data.arguments.map { render(it) }.join(", ", "(", ")")) @@ -209,4 +212,13 @@ private fun Printer.indent(body: Printer.() -> Unit): Printer { body() popIndent() return this -} \ No newline at end of file +} + +private fun GenericDeclaration?.getDeclarationName(): String? { + return when (this) { + is Class<*> -> getName().substringAfterLast(".") + is Method -> getDeclaringClass().getDeclarationName() + "::" + getName() + "()" + is Constructor<*> -> getDeclaringClass().getDeclarationName() + "::" + getName() + "()" + else -> "" + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/LoggingStorageManager.kt b/compiler/tests/org/jetbrains/jet/checkers/LoggingStorageManager.kt index 5261325e546..93b4d0f8cc3 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/LoggingStorageManager.kt +++ b/compiler/tests/org/jetbrains/jet/checkers/LoggingStorageManager.kt @@ -58,12 +58,12 @@ public class LoggingStorageManager( } private fun computeCallerData(lambda: Any, wrapper: Any, arguments: List, result: Any?): CallData { - val jClass = lambda.javaClass + val lambdaClass = lambda.javaClass - val outerClass: Class? = jClass.getEnclosingClass() + val outerClass: Class? = lambdaClass.getEnclosingClass() // fields named "this" or "this$0" - val referenceToOuter = jClass.getAllDeclaredFields().firstOrNull { + val referenceToOuter = lambdaClass.getAllDeclaredFields().firstOrNull { field -> field.getType() == outerClass && field.getName()!!.contains("this") } @@ -71,6 +71,11 @@ public class LoggingStorageManager( val outerInstance = referenceToOuter?.get(lambda) + fun Class<*>.findFunctionField(): Field? { + return this.getAllDeclaredFields().firstOrNull { + it.getType()?.getName()?.startsWith("kotlin.Function") ?: false + } + } val containingField = if (outerInstance == null) null else outerClass?.getAllDeclaredFields()?.firstOrNull { (field): Boolean -> @@ -79,10 +84,7 @@ public class LoggingStorageManager( if (value == null) return@firstOrNull false val valueClass = value.javaClass - - val functionField = valueClass.getAllDeclaredFields().firstOrNull { - it.getType()?.getName()?.startsWith("kotlin.Function") ?: false - } + val functionField = valueClass.findFunctionField() if (functionField == null) return@firstOrNull false functionField.setAccessible(true) @@ -90,11 +92,26 @@ public class LoggingStorageManager( functionValue == wrapper } - val enclosingEntity = jClass.getEnclosingConstructor() - ?: jClass.getEnclosingMethod() - ?: jClass.getEnclosingClass() + if (containingField == null) { + val wrappedLambdaField = lambdaClass.findFunctionField() + if (wrappedLambdaField != null) { + wrappedLambdaField.setAccessible(true) + val wrappedLambda = wrappedLambdaField.get(lambda) + return CallData(outerInstance, null, enclosingEntity(wrappedLambda.javaClass), arguments, result) + } + } - return CallData(outerInstance, containingField, enclosingEntity as GenericDeclaration?, arguments, result) + val enclosingEntity = enclosingEntity(lambdaClass) + + return CallData(outerInstance, containingField, enclosingEntity, arguments, result) + } + + private fun enclosingEntity(_class: Class): GenericDeclaration? { + val result = _class.getEnclosingConstructor() + ?: _class.getEnclosingMethod() + ?: _class.getEnclosingClass() + + return result as GenericDeclaration? } private fun Class<*>.getAllDeclaredFields(): List {