fun shouldTransform()

in common/src/main/org/jetbrains/lincheck/util/AnalysisSections.kt [287:365]


    fun shouldTransform(className: String, methodName: String): Boolean {
        // We do not need to instrument most standard Java classes.
        // It is fine to inject the Lincheck analysis only into the
        // `java.util.*` ones, ignored the known atomic constructs.
        if (className.startsWith("java.")) {
            // Instrument `Thread` to intercept thread events.
            if (className == "java.lang.Thread") return true
            // Instrument `Throwable` as it has `synchronized` methods,
            // and corresponding monitor events should be intercepted.
            if (className == "java.lang.Throwable") return true
            // Instrument `java.util.concurrent` classes, except atomics.
            if (className.startsWith("java.util.concurrent.") && className.contains("Atomic")) return false
            // Instrument `java.util` classes.
            if (className.startsWith("java.util.")) return true
            if (isInTraceDebuggerMode) {
                if (className.startsWith("java.io.")) return true
                if (className.startsWith("java.nio.")) return true
                if (className.startsWith("java.time.")) return true
            }
            return false
        }
        if (className.startsWith("com.sun.")) return false
        if (className.startsWith("sun.")) {
            // We should never instrument the Lincheck classes.
            if (className.startsWith("sun.nio.ch.lincheck.")) return false
            if (isInTraceDebuggerMode && className.startsWith("sun.nio.")) return true
            return false
        }
        if (className.startsWith("javax.")) return false
        if (className.startsWith("jdk.")) {
            // Transform `ThreadContainer.start` to detect thread forking.
            if (isThreadContainerClass(className)) return true
            return false
        }
        // We do not need to instrument most standard Kotlin classes.
        // However, we need to inject the Lincheck analysis into the classes
        // related to collections, iterators, random and coroutines.
        if (className.startsWith("kotlin.")) {
            if (className.startsWith("kotlin.concurrent.ThreadsKt")) return true
            if (className.startsWith("kotlin.collections.")) return true
            if (className.startsWith("kotlin.jvm.internal.Array") && className.contains("Iterator")) return true
            if (className.startsWith("kotlin.ranges.")) return true
            if (className.startsWith("kotlin.random.")) return true
            if (className.startsWith("kotlin.coroutines.jvm.internal.")) return false
            if (className.startsWith("kotlin.coroutines.")) return true
            if (isInTraceDebuggerMode && className.startsWith("kotlin.io.")) return true
            return false
        }
        // We do not instrument AtomicFU atomics.
        if (className.startsWith("kotlinx.atomicfu.")) {
            if (className.contains("Atomic")) return false
            return true
        }
        // We need to skip the classes related to the debugger support in Kotlin coroutines.
        if (className.startsWith("kotlinx.coroutines.debug.")) return false
        if (className == "kotlinx.coroutines.DebugKt") return false
        // We should never transform IntelliJ runtime classes (debugger and coverage agents).
        if (isIntellijRuntimeAgentClass(className)) return false
        // We should never instrument the JetBrains coverage package classes (for instance, relocated ASM library).
        if (isJetBrainsCoverageClass(className)) return false
        // We can also safely do not instrument some libraries for performance reasons.
        if (className.startsWith("com.esotericsoftware.kryo.")) return false
        if (className.startsWith("net.bytebuddy.")) return false
        if (className.startsWith("net.rubygrapefruit.platform.")) return false
        if (className.startsWith("io.mockk.")) return false
        if (className.startsWith("it.unimi.dsi.fastutil.")) return false
        if (className.startsWith("worker.org.gradle.")) return false
        if (className.startsWith("org.objectweb.asm.")) return false
        if (className.startsWith("org.gradle.")) return false
        if (className.startsWith("org.slf4j.")) return false
        if (className.startsWith("org.apache.commons.lang.")) return false
        if (className.startsWith("org.junit.")) return false
        if (className.startsWith("junit.framework.")) return false
        // Finally, we should never instrument the Lincheck classes.
        if (className.startsWith(LINCHECK_PACKAGE_NAME)) return false
        if (className.startsWith(LINCHECK_KOTLINX_PACKAGE_NAME)) return false
        // All the classes that were not filtered out are eligible for transformation.
        return true
    }