in trace/src/main/org/jetbrains/lincheck/trace/TraceRecorderTracePoints.kt [877:919]
fun TRObject(context: TraceContext, obj: Any): TRObject {
val defaultTRObject = {
val classId = context.getOrCreateClassId(obj.javaClass.name)
TRObject(classId, System.identityHashCode(obj), context.getClassDescriptor(classId))
}
return when (obj) {
is Byte -> TRObject(TR_OBJECT_P_BYTE, 0, obj)
is Short -> TRObject(TR_OBJECT_P_SHORT, 0, obj)
is Int -> TRObject(TR_OBJECT_P_INT, 0, obj)
is Long -> TRObject(TR_OBJECT_P_LONG, 0, obj)
is Float -> TRObject(TR_OBJECT_P_FLOAT, 0, obj)
is Double -> TRObject(TR_OBJECT_P_DOUBLE, 0, obj)
is Char -> TRObject(TR_OBJECT_P_CHAR, 0, obj)
is String -> TRObject(TR_OBJECT_P_STRING, 0, obj.trimToString())
is StringBuilder -> TRObject(
TR_OBJECT_P_STRING_BUILDER, System.identityHashCode(obj), obj.trimToString()
)
// If user (traced) code contains CharSequence implementation, it is a bad idea to call it
// as there is no guarantee that this implementation doesn't have side effects.
// Guard by Java and Kotlin std lib packages
is CharSequence if (classNameWhitelisted(obj)) -> runCatching { obj.trimToString() }.let {
// Some implementations of CharSequence might throw when `subSequence` is invoked at some unexpected moment,
// like when this sequence is considered "destroyed" at this point
if (it.isSuccess) TRObject(TR_OBJECT_P_STRING, 0, it.getOrThrow())
else defaultTRObject()
}
is Unit -> TRObject(TR_OBJECT_P_UNIT, 0, obj)
is Boolean -> TRObject(TR_OBJECT_P_BOOLEAN, 0, obj)
// Render these types to strings for simplicity
is Enum<*> -> TRObject(TR_OBJECT_P_RAW_STRING, 0, "${obj.javaClass.simpleName}.${obj.name}")
is BigInteger -> TRObject(TR_OBJECT_P_RAW_STRING, 0, obj.toString())
is BigDecimal -> TRObject(TR_OBJECT_P_RAW_STRING, 0, obj.toString())
is Class<*> -> TRObject(TR_OBJECT_P_JAVA_CLASS, 0, "${obj.simpleName}.class")
is KClass<*> -> TRObject(TR_OBJECT_P_KOTLIN_CLASS, 0, "${obj.simpleName}.kclass")
// Generic case
// TODO Make parametrized
else -> defaultTRObject()
}
}