More information when no containing field found
This commit is contained in:
@@ -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() ?: "<name not found>")
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
private fun GenericDeclaration?.getDeclarationName(): String? {
|
||||
return when (this) {
|
||||
is Class<*> -> getName().substringAfterLast(".")
|
||||
is Method -> getDeclaringClass().getDeclarationName() + "::" + getName() + "()"
|
||||
is Constructor<*> -> getDeclaringClass().getDeclarationName() + "::" + getName() + "()"
|
||||
else -> "<no name>"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,12 +58,12 @@ public class LoggingStorageManager(
|
||||
}
|
||||
|
||||
private fun computeCallerData(lambda: Any, wrapper: Any, arguments: List<Any?>, result: Any?): CallData {
|
||||
val jClass = lambda.javaClass
|
||||
val lambdaClass = lambda.javaClass
|
||||
|
||||
val outerClass: Class<out Any?>? = jClass.getEnclosingClass()
|
||||
val outerClass: Class<out Any?>? = 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<Any>): GenericDeclaration? {
|
||||
val result = _class.getEnclosingConstructor()
|
||||
?: _class.getEnclosingMethod()
|
||||
?: _class.getEnclosingClass()
|
||||
|
||||
return result as GenericDeclaration?
|
||||
}
|
||||
|
||||
private fun Class<*>.getAllDeclaredFields(): List<Field> {
|
||||
|
||||
Reference in New Issue
Block a user