├── _latest-gradle-test
├── gradle.properties
├── gradle-plugin-android-test
│ ├── src
│ │ ├── androidTest
│ │ │ ├── kotlin
│ │ │ │ └── gradle-plugin-android-tests-proxy.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── kotlin
│ │ │ │ └── tests-gradle-plugin-android.kt
│ │ └── test
│ │ │ └── kotlin
│ │ │ └── tests-gradle-plugin-android-unit-jvm.kt
│ ├── proguard-rules.pro
│ └── build.gradle.kts
├── settings.gradle.kts
└── build.gradle.kts
├── jvm-agent
├── gradle.properties
├── tests-ja
│ ├── src
│ │ └── test
│ │ │ ├── java
│ │ │ └── module-info.java
│ │ │ └── kotlin
│ │ │ └── tests-jvm-agent.kt
│ └── build.gradle.kts
├── src
│ └── main
│ │ └── kotlin
│ │ └── jvmAgent.kt
└── jdk8-tests-ja
│ ├── src
│ └── test
│ │ └── kotlin
│ │ └── tests-jdk8-jvm-agent.kt
│ └── build.gradle.kts
├── mh-invoker
├── gradle.properties
└── src
│ └── main
│ ├── resources
│ └── META-INF
│ │ └── services
│ │ ├── dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker
│ │ └── dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
│ ├── java
│ └── module-info.java
│ └── kotlin
│ └── internal
│ ├── unknown.kt
│ └── mh-invoker.kt
├── provider
├── gradle.properties
└── src
│ └── main
│ ├── java
│ └── module-info.java
│ └── kotlin
│ └── internal
│ ├── utils-provider.kt
│ ├── provider-api-internal.kt
│ └── provider.kt
├── .github
└── FUNDING.yml
├── _plugins
├── bytecode-processor
│ ├── gradle.properties
│ ├── intrinsics
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── java
│ │ │ │ └── module-info.java
│ │ │ │ └── kotlin
│ │ │ │ ├── deleteClass-intrinsics.kt
│ │ │ │ ├── getCurrentFileName-intrinsincs.kt
│ │ │ │ ├── utils-intrinsics.kt
│ │ │ │ ├── makeStatic-intrinsics.kt
│ │ │ │ ├── changeInvocationsOwner-intrinsics.kt
│ │ │ │ ├── skipInvocations-intrinsics.kt
│ │ │ │ ├── changeClassName-intrinsics.kt
│ │ │ │ ├── getOwnerClass-intrinsics.kt
│ │ │ │ └── loadConstant-intrinsics.kt
│ │ └── build.gradle.kts
│ ├── build.gradle.kts
│ ├── api
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── main
│ │ │ └── kotlin
│ │ │ └── asm-plugin-api.kt
│ ├── settings.gradle.kts
│ ├── plugins
│ │ ├── build.gradle.kts
│ │ └── src
│ │ │ └── main
│ │ │ └── kotlin
│ │ │ ├── deleteClass-plugins.kt
│ │ │ └── internal
│ │ │ └── utils-plugins.kt
│ └── gradle-plugin
│ │ ├── src
│ │ └── main
│ │ │ └── kotlin
│ │ │ └── api-gradle-plugin-bytecode-processor.kt
│ │ └── build.gradle.kts
├── force-variant-java-version
│ ├── settings.gradle.kts
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── forceVariantJavaVersion.kt
└── gradle-plugin-test
│ ├── settings.gradle.kts
│ ├── runtime-settings
│ └── build.gradle.kts
│ ├── embedded-debug-probes-stdlib
│ └── build.gradle.kts
│ ├── intrinsics
│ └── build.gradle.kts
│ ├── provider
│ └── build.gradle.kts
│ ├── base-continuation-accessor
│ └── build.gradle.kts
│ └── embedded-debug-probes-xcoroutines
│ └── build.gradle.kts
├── _tests
├── latest-kotlin-kmp-gradle-plugin-test
│ ├── gradle.properties
│ ├── src
│ │ ├── androidMain
│ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ └── strings.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ └── drawable-v24
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── kotlin
│ │ │ │ └── org
│ │ │ │ │ └── example
│ │ │ │ │ └── project
│ │ │ │ │ ├── Platform.android.kt
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── wasmJsMain
│ │ │ ├── resources
│ │ │ │ ├── styles.css
│ │ │ │ └── index.html
│ │ │ └── kotlin
│ │ │ │ └── org
│ │ │ │ └── example
│ │ │ │ └── project
│ │ │ │ ├── Platform.wasmJs.kt
│ │ │ │ └── main.kt
│ │ ├── commonMain
│ │ │ └── kotlin
│ │ │ │ └── org
│ │ │ │ └── example
│ │ │ │ └── project
│ │ │ │ ├── Platform.kt
│ │ │ │ ├── Greeting.kt
│ │ │ │ └── App.kt
│ │ ├── desktopMain
│ │ │ └── kotlin
│ │ │ │ └── org
│ │ │ │ └── example
│ │ │ │ └── project
│ │ │ │ ├── Platform.jvm.kt
│ │ │ │ └── main.kt
│ │ ├── androidInstrumentedTest
│ │ │ └── kotlin
│ │ │ │ └── tests-last-kotlin-kmp-gradle-plugin-android.kt
│ │ └── androidUnitTest
│ │ │ └── kotlin
│ │ │ └── tests-last-kotlin-kmp-gradle-plugin-android-unit-test.kt
│ └── settings.gradle.kts
└── latest-kotlin-gradle-plugin-test
│ ├── gradle.properties
│ ├── settings.gradle.kts
│ ├── custom-loader
│ └── build.gradle.kts
│ ├── src
│ └── test
│ │ └── kotlin
│ │ └── last-kotlin-gradle-plugin-test.kt
│ ├── build.gradle.kts
│ └── test-utils
│ └── build.gradle.kts
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── common
└── src
│ └── main
│ ├── resources
│ └── META-INF
│ │ └── services
│ │ └── dev.reformator.stacktracedecoroutinator.provider.internal.DecoroutinatorProvider
│ ├── kotlin
│ ├── internal
│ │ ├── utils-mh-api-common.kt
│ │ └── interfaces-common.kt
│ └── intrinsics
│ │ └── intrinsics-common.kt
│ └── java
│ └── module-info.java
├── test-utils
├── retrace-repack
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ ├── dev
│ │ │ └── reformator
│ │ │ │ └── retracerepack
│ │ │ │ ├── retrace
│ │ │ │ └── _dummy.java
│ │ │ │ └── obfuscate
│ │ │ │ └── _dummy.java
│ │ │ └── module-info.java
│ └── build.gradle.kts
├── base-continuation-accessor-stub
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
│ │ │ ├── java
│ │ │ └── module-info.java
│ │ │ └── kotlin
│ │ │ └── base-continuation-accessor-stub.kt
│ └── build.gradle.kts
├── base-continuation-accessor-reflect-stub
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
│ │ │ └── kotlin
│ │ │ └── base-continuation-accessor-reflect-stub.kt
│ └── build.gradle.kts
├── src
│ └── main
│ │ ├── java
│ │ └── module-info.java
│ │ └── kotlin
│ │ └── test-utils.kt
├── custom-loader
│ ├── src
│ │ └── main
│ │ │ └── kotlin
│ │ │ ├── test-utils-custom-loader.kt
│ │ │ └── stub-test-utils-custom-loader.kt
│ └── build.gradle.kts
└── build.gradle.kts
├── gradle-plugin
├── src
│ └── main
│ │ ├── resources
│ │ └── META-INF
│ │ │ └── services
│ │ │ └── dev.reformator.stacktracedecoroutinator.gradleplugin.GroovyDslInitializer
│ │ ├── kotlin
│ │ ├── gradle-plugin-utils.kt
│ │ ├── attribute-gradle-plugin.kt
│ │ ├── gradle-noop-transformer.kt
│ │ └── api-gradle-plugin-decoroutinator.kt
│ │ └── groovy
│ │ └── GroovyDslInitializerImpl.groovy
├── embedded-debug-probes-xcoroutines
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ └── kotlin.coroutines.jvm.internal.DecoroutinatorDebugProbesProvider
│ │ │ └── kotlin
│ │ │ └── embedded-debug-probes-provider.kt
│ └── build.gradle.kts
├── base-continuation-accessor
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
│ │ │ └── kotlin
│ │ │ └── base-continuation-accessor.kt
│ └── build.gradle.kts
├── duplicate-entity-jar-builder
│ ├── src
│ │ └── main
│ │ │ ├── java
│ │ │ └── module-info.java
│ │ │ └── kotlin
│ │ │ └── proxyCaller.kt
│ └── build.gradle.kts
├── android-tests
│ ├── src
│ │ ├── main
│ │ │ └── AndroidManifest.xml
│ │ ├── androidTest
│ │ │ ├── AndroidManifest.xml
│ │ │ └── kotlin
│ │ │ │ └── gradle-plugin-android-tests-proxy.kt
│ │ └── test
│ │ │ └── kotlin
│ │ │ └── tests-gradle-plugin-android-unit-jvm.kt
│ └── proguard-rules.pro
├── android-legacy-tests
│ ├── src
│ │ ├── main
│ │ │ └── AndroidManifest.xml
│ │ └── androidTest
│ │ │ ├── AndroidManifest.xml
│ │ │ └── kotlin
│ │ │ └── gradle-plugin-android-legacy-tests-proxy.kt
│ └── proguard-rules.pro
├── empty-module-tests
│ └── build.gradle.kts
├── tests-gp
│ ├── src
│ │ └── test
│ │ │ ├── java
│ │ │ ├── dev
│ │ │ │ └── reformator
│ │ │ │ │ └── stacktracedecoroutinator
│ │ │ │ │ └── gradleplugintests
│ │ │ │ │ └── DebugProbesAccessor.java
│ │ │ └── module-info.java
│ │ │ └── kotlin
│ │ │ └── tests-gradle-plugin.kt
│ └── build.gradle.kts
├── embedded-debug-probes-stdlib
│ ├── build.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── embedded-debug-probes-stdlib.kt
├── gradle-groovy-dsl-tests
│ └── build.gradle
├── aar-builder
│ ├── src
│ │ └── main
│ │ │ └── kotlin
│ │ │ └── aar-builder.kt
│ └── build.gradle.kts
└── jdk8-tests-gp
│ ├── build.gradle.kts
│ └── src
│ └── test
│ └── kotlin
│ └── tests-jdk8-gradle-plugin.kt
├── mh-invoker-android
└── src
│ └── main
│ ├── resources
│ └── META-INF
│ │ └── services
│ │ ├── dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker
│ │ └── dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
│ └── kotlin
│ └── mh-invoker-android.kt
├── mh-invoker-jvm
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ ├── dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
│ │ ├── kotlin
│ │ │ └── internal
│ │ │ │ └── unknown-mh-invoker-jvm.kt
│ │ └── java
│ │ │ └── module-info.java
│ └── test
│ │ ├── kotlin
│ │ └── tests-mh-invoker-jvm.kt
│ │ └── java
│ │ └── module-info.java
└── jdk8-tests-mij
│ ├── src
│ └── test
│ │ └── kotlin
│ │ └── tests-mh-invoker-jvm.kt
│ └── build.gradle.kts
├── generator-android
└── src
│ ├── main
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── dev.reformator.stacktracedecoroutinator.common.internal.SpecMethodsFactory
│ └── test
│ └── kotlin
│ └── jvm-tests-generator-android.kt
├── generator-jvm
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ ├── dev.reformator.stacktracedecoroutinator.common.internal.SpecMethodsFactory
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.common.internal.AnnotationMetadataResolver
│ │ ├── java
│ │ │ └── module-info.java
│ │ └── kotlin
│ │ │ └── internal
│ │ │ ├── specMethodsFactory-generator.kt
│ │ │ └── classLoader-generator.kt
│ └── test
│ │ ├── kotlin
│ │ ├── tests-generator.kt
│ │ ├── printSpecMethod.kt
│ │ └── showResumeWithAppendix.kt
│ │ └── java
│ │ └── module-info.java
├── jdk8-tests-g
│ ├── src
│ │ └── test
│ │ │ └── kotlin
│ │ │ └── tests-jdk8-generator.kt
│ └── build.gradle.kts
└── android-wrong-generator-tests
│ ├── src
│ └── androidTest
│ │ └── kotlin
│ │ └── android-tests-generator-jvm.kt
│ └── build.gradle.kts
├── intrinsics
├── src
│ └── main
│ │ ├── java
│ │ └── module-info.java
│ │ └── kotlin
│ │ └── intrinsics.kt
└── build.gradle.kts
├── jvm-agent-common
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── services
│ │ │ │ └── dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
│ │ ├── kotlin
│ │ │ └── internal
│ │ │ │ ├── utils-jvm-agent-common.kt
│ │ │ │ ├── di-jvm-agent-common.kt
│ │ │ │ └── base-continuation-accessor-agent-common.kt
│ │ └── java
│ │ │ └── module-info.java
│ └── test
│ │ └── kotlin
│ │ └── showBaseContinuation.kt
└── suspend-class-stub
│ ├── src
│ └── main
│ │ └── kotlin
│ │ └── jvm-agent-common-stub.kt
│ └── build.gradle.kts
├── class-transformer
└── src
│ └── main
│ ├── kotlin
│ └── internal
│ │ └── interfaces-class-transformer.kt
│ └── java
│ └── module-info.java
├── jvm
├── src
│ ├── main
│ │ ├── kotlin
│ │ │ ├── internal
│ │ │ │ └── utils-jvm.kt
│ │ │ └── api-jvm.kt
│ │ └── java
│ │ │ └── module-info.java
│ └── test
│ │ ├── java
│ │ └── module-info.java
│ │ └── kotlin
│ │ ├── example.kt
│ │ └── tests-jvm.kt
└── jdk8-tests-j
│ ├── build.gradle.kts
│ └── src
│ └── test
│ └── kotlin
│ └── tests-jdk8-jvm.kt
├── test-utils-jvm
├── src
│ └── main
│ │ ├── java
│ │ └── module-info.java
│ │ └── kotlin
│ │ ├── test-utils.kt
│ │ └── jvm-test.kt
└── build.gradle.kts
├── spec-method-builder
└── src
│ └── main
│ ├── java
│ └── module-info.java
│ └── kotlin
│ └── internal
│ └── utils-spec-method-builder.kt
├── runtime-settings
├── src
│ └── main
│ │ ├── java
│ │ └── module-info.java
│ │ └── kotlin
│ │ ├── runtime-settings.kt
│ │ └── internal
│ │ └── runtime-settings-internal.kt
└── build.gradle.kts
├── settings.gradle.kts
└── gradlew.bat
/_latest-gradle-test/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 |
--------------------------------------------------------------------------------
/jvm-agent/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.stdlib.default.dependency=false
2 |
--------------------------------------------------------------------------------
/mh-invoker/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.stdlib.default.dependency=false
2 |
--------------------------------------------------------------------------------
/provider/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.stdlib.default.dependency=false
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: Anamorphosee
2 | buy_me_a_coffee: reformator
3 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.jvm.target.validation.mode=ignore
2 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/gradle.properties:
--------------------------------------------------------------------------------
1 | android.useAndroidX=true
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | .idea
3 | .kotlin
4 | build
5 | local.properties
6 | *.hprof
7 | yarn.lock
8 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.jvm.target.validation.mode=ignore
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | kotlin.code.style=official
2 | android.useAndroidX=true
3 | kotlin.jvm.target.validation.mode=ignore
4 | kotlin.incremental=false
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | GarbKmp
3 |
--------------------------------------------------------------------------------
/common/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.provider.internal.DecoroutinatorProvider:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.common.internal.Provider
2 |
--------------------------------------------------------------------------------
/test-utils/retrace-repack/src/main/java/dev/reformator/retracerepack/retrace/_dummy.java:
--------------------------------------------------------------------------------
1 | package dev.reformator.retracerepack.retrace;
2 |
3 | @SuppressWarnings("unused")
4 | public class _dummy { }
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/wasmJsMain/resources/styles.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | width: 100%;
3 | height: 100%;
4 | margin: 0;
5 | padding: 0;
6 | overflow: hidden;
7 | }
--------------------------------------------------------------------------------
/mh-invoker/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularVarHandleInvoker
2 |
--------------------------------------------------------------------------------
/test-utils/retrace-repack/src/main/java/dev/reformator/retracerepack/obfuscate/_dummy.java:
--------------------------------------------------------------------------------
1 | package dev.reformator.retracerepack.obfuscate;
2 |
3 | @SuppressWarnings("unused")
4 | public class _dummy { }
5 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.gradleplugin.GroovyDslInitializer:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.gradleplugin.groovy.GroovyDslInitializerImpl
2 |
--------------------------------------------------------------------------------
/mh-invoker-android/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvokerandroid.AndroidVarHandleInvoker
2 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvokerjvm.internal.JvmVarHandleInvoker
2 |
--------------------------------------------------------------------------------
/mh-invoker/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularMethodHandleInvoker
2 |
--------------------------------------------------------------------------------
/generator-android/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.SpecMethodsFactory:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.generatorandroid.AndroidSpecMethodsFactory
2 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvokerjvm.internal.JvmMethodHandleInvoker
2 |
--------------------------------------------------------------------------------
/test-utils/retrace-repack/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.retracerepack {
2 | exports dev.reformator.retracerepack.retrace;
3 | exports dev.reformator.retracerepack.obfuscate;
4 | }
5 |
--------------------------------------------------------------------------------
/generator-jvm/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.SpecMethodsFactory:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.generatorjvm.internal.GeneratorJvmSpecMethodsFactory
2 |
--------------------------------------------------------------------------------
/mh-invoker-android/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.mhinvokerandroid.AndroidMethodHandleInvoker
2 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.bytecodeprocessor.intrinsics {
2 | requires static kotlin.stdlib;
3 | exports dev.reformator.bytecodeprocessor.intrinsics;
4 | }
--------------------------------------------------------------------------------
/gradle-plugin/embedded-debug-probes-xcoroutines/src/main/resources/META-INF/services/kotlin.coroutines.jvm.internal.DecoroutinatorDebugProbesProvider:
--------------------------------------------------------------------------------
1 | kotlinx.coroutines.debug.internal.DecoroutinatorDebugProbesProviderImpl
2 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/commonMain/kotlin/org/example/project/Platform.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | interface Platform {
4 | val name: String
5 | }
6 |
7 | expect fun getPlatform(): Platform
--------------------------------------------------------------------------------
/generator-jvm/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.common.internal.AnnotationMetadataResolver:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.generatorjvm.internal.AnnotationMetadataResolverImpl
2 |
--------------------------------------------------------------------------------
/gradle-plugin/base-continuation-accessor/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider:
--------------------------------------------------------------------------------
1 | kotlin.coroutines.jvm.internal.DecoroutinatorBaseContinuationAccessorImpl
2 |
--------------------------------------------------------------------------------
/intrinsics/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module intrinsics {
2 | requires static dev.reformator.bytecodeprocessor.intrinsics;
3 | requires kotlin.stdlib;
4 | exports dev.reformator.stacktracedecoroutinator.intrinsics;
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal.AgentBaseContinuationAccessorProvider
2 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/src/androidTest/kotlin/gradle-plugin-android-tests-proxy.kt:
--------------------------------------------------------------------------------
1 | import androidx.annotation.Keep
2 |
3 | @Keep
4 | class TestLocalFile: dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.TestLocalFile()
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/_latest-gradle-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include("gradle-plugin-android-test")
2 |
3 | dependencyResolutionManagement {
4 | versionCatalogs {
5 | create("libs") {
6 | from(files("../gradle/libs.versions.toml"))
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Anamorphosee/stacktrace-decoroutinator/HEAD/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/commonMain/kotlin/org/example/project/Greeting.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | class Greeting {
4 | private val platform = getPlatform()
5 |
6 | fun greet(): String {
7 | return "Hello, ${platform.name}!"
8 | }
9 | }
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-stub/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub.TestBaseContinuationAccessorProviderAccessor
2 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/wasmJsMain/kotlin/org/example/project/Platform.wasmJs.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | class WasmPlatform: Platform {
4 | override val name: String = "Web with Kotlin/Wasm"
5 | }
6 |
7 | actual fun getPlatform(): Platform = WasmPlatform()
--------------------------------------------------------------------------------
/_plugins/force-variant-java-version/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "force-variant-java-version"
2 |
3 | dependencyResolutionManagement {
4 | versionCatalogs {
5 | create("libs") {
6 | from(files("../../gradle/libs.versions.toml"))
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-reflect-stub/src/main/resources/META-INF/services/dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider:
--------------------------------------------------------------------------------
1 | dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub.TestReflectBaseContinuationAccessorProviderAccessor
2 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/desktopMain/kotlin/org/example/project/Platform.jvm.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | class JVMPlatform: Platform {
4 | override val name: String = "Java ${System.getProperty("java.version")}"
5 | }
6 |
7 | actual fun getPlatform(): Platform = JVMPlatform()
--------------------------------------------------------------------------------
/gradle-plugin/duplicate-entity-jar-builder/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.duplicatejar {
2 | requires static dev.reformator.bytecodeprocessor.intrinsics;
3 | requires kotlin.stdlib;
4 | exports dev.reformator.stacktracedecoroutinator.duplicatejar;
5 | }
6 |
--------------------------------------------------------------------------------
/gradle-plugin/android-tests/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/deleteClass-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | @Retention(AnnotationRetention.BINARY)
6 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
7 | annotation class DeleteClass
8 |
--------------------------------------------------------------------------------
/generator-jvm/jdk8-tests-g/src/test/kotlin/tests-jdk8-generator.kt:
--------------------------------------------------------------------------------
1 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
2 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
3 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
4 |
--------------------------------------------------------------------------------
/gradle-plugin/android-legacy-tests/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle-plugin/android-tests/src/androidTest/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/getCurrentFileName-intrinsincs.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | val currentFileName: String
6 | get() { fail() }
7 |
8 | val currentLineNumber: Int
9 | get() { fail() }
10 |
--------------------------------------------------------------------------------
/gradle-plugin/android-legacy-tests/src/androidTest/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/gradle-plugin/android-tests/src/test/kotlin/tests-gradle-plugin-android-unit-jvm.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.TestLocalFile
2 | import org.junit.Test
3 |
4 | class AccessTest {
5 | @Test
6 | fun accessFileInMainModule() {
7 | TestLocalFile::class.java.name
8 | }
9 | }
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/utils-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | fun fail(): Nothing { error("intrinsic failed") }
6 |
7 | @Suppress("ClassName") internal class noClass
8 | internal const val NO_NAME = "\$no name\$"
9 |
--------------------------------------------------------------------------------
/jvm-agent/tests-ja/src/test/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.jvmagent.tests {
2 | requires dev.reformator.stacktracedecoroutinator.testutils;
3 | requires dev.reformator.stacktracedecoroutinator.testutilsjvm;
4 | requires kotlinx.coroutines.core;
5 | requires kotlin.test.junit5;
6 | }
7 |
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/src/androidTest/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/src/test/kotlin/tests-gradle-plugin-android-unit-jvm.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.TestLocalFile
2 | import org.junit.Test
3 |
4 | class AccessTest {
5 | @Test
6 | fun accessFileInMainModule() {
7 | TestLocalFile::class.java.name
8 | }
9 | }
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/kotlin/org/example/project/Platform.android.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | import android.os.Build
4 |
5 | class AndroidPlatform : Platform {
6 | override val name: String = "Android ${Build.VERSION.SDK_INT}"
7 | }
8 |
9 | actual fun getPlatform(): Platform = AndroidPlatform()
--------------------------------------------------------------------------------
/class-transformer/src/main/kotlin/internal/interfaces-class-transformer.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.classtransformer.internal
2 |
3 | class DebugMetadataInfo internal constructor(
4 | internal val specClassInternalClassName: String,
5 | internal val methodName: String,
6 | internal val lineNumbers: Set
7 | )
8 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/makeStatic-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | @Retention(AnnotationRetention.BINARY)
6 | @Target(AnnotationTarget.FUNCTION)
7 | annotation class MakeStatic(
8 | val addToStaticInitializer: Boolean = false
9 | )
10 |
--------------------------------------------------------------------------------
/jvm/src/main/kotlin/internal/utils-jvm.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.jvm.internal
4 |
5 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorTransformed
6 |
7 | val Class<*>.isTransformed: Boolean
8 | get() = getDeclaredAnnotation(DecoroutinatorTransformed::class.java) != null
9 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/build.gradle.kts:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 | dependencies {
8 | classpath(libs.kotlin.gradle.plugin)
9 | }
10 | }
11 |
12 | subprojects {
13 | group = "dev.reformator.bytecodeprocessor"
14 | version = "0.0.1-SNAPSHOT"
15 | }
16 |
--------------------------------------------------------------------------------
/generator-jvm/src/test/kotlin/tests-generator.kt:
--------------------------------------------------------------------------------
1 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
2 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
3 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
4 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
5 |
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/src/main/kotlin/tests-gradle-plugin-android.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch", "JUnitMixedFramework")
2 |
3 | package dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests
4 |
5 | import org.junit.Test
6 |
7 | open class TestLocalFile {
8 | @Test
9 | fun localTest() {
10 | println("OK")
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/test/kotlin/tests-mh-invoker-jvm.kt:
--------------------------------------------------------------------------------
1 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
2 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
3 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
4 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/desktopMain/kotlin/org/example/project/main.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | import androidx.compose.ui.window.Window
4 | import androidx.compose.ui.window.application
5 |
6 | fun main() = application {
7 | Window(
8 | onCloseRequest = ::exitApplication,
9 | title = "GarbKmp",
10 | ) {
11 | App()
12 | }
13 | }
--------------------------------------------------------------------------------
/mh-invoker-jvm/jdk8-tests-mij/src/test/kotlin/tests-mh-invoker-jvm.kt:
--------------------------------------------------------------------------------
1 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
2 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
3 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
4 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
5 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/wasmJsMain/kotlin/org/example/project/main.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | import androidx.compose.ui.ExperimentalComposeUiApi
4 | import androidx.compose.ui.window.ComposeViewport
5 | import kotlinx.browser.document
6 |
7 | @OptIn(ExperimentalComposeUiApi::class)
8 | fun main() {
9 | ComposeViewport(document.body!!) {
10 | App()
11 | }
12 | }
--------------------------------------------------------------------------------
/gradle-plugin/empty-module-tests/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | java {
12 | sourceCompatibility = JavaVersion.VERSION_1_9
13 | targetCompatibility = JavaVersion.VERSION_1_9
14 | }
15 |
16 | kotlin {
17 | compilerOptions {
18 | jvmTarget = JvmTarget.JVM_1_8
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/main/kotlin/internal/unknown-mh-invoker-jvm.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dcunknownjvm
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.ownerClass
6 | import java.lang.invoke.MethodHandles
7 |
8 | internal fun getUnknownPackageLookup(): MethodHandles.Lookup =
9 | MethodHandles.lookup()
10 |
11 | internal fun getUnknownPackageName(): String =
12 | ownerClass.packageName
13 |
--------------------------------------------------------------------------------
/test-utils-jvm/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.testutilsjvm {
2 | requires kotlinx.coroutines.core;
3 | requires org.junit.jupiter.api;
4 | requires io.github.oshai.kotlinlogging;
5 | requires static dev.reformator.bytecodeprocessor.intrinsics;
6 |
7 | exports dev.reformator.stacktracedecoroutinator.testjvm;
8 | opens dev.reformator.stacktracedecoroutinator.testjvm;
9 | }
10 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/wasmJsMain/resources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GarbKmp
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/test/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.mhinvokerjvm.tests {
2 | requires kotlin.stdlib;
3 | requires dev.reformator.stacktracedecoroutinator.common;
4 | requires dev.reformator.stacktracedecoroutinator.testutils;
5 | requires dev.reformator.stacktracedecoroutinator.provider;
6 | requires org.junit.jupiter.api;
7 | requires dev.reformator.stacktracedecoroutinator.testutilsjvm;
8 | }
9 |
--------------------------------------------------------------------------------
/jvm-agent/src/main/kotlin/jvmAgent.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("DecoroutinatorAgentKt")
3 |
4 | package dev.reformator.stacktracedecoroutinator.jvmagent
5 |
6 | import dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal.addDecoroutinatorTransformer
7 | import java.lang.instrument.Instrumentation
8 |
9 | fun premain(@Suppress("UNUSED_PARAMETER") args: String?, inst: Instrumentation) {
10 | addDecoroutinatorTransformer(inst)
11 | }
12 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/changeInvocationsOwner-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | import kotlin.reflect.KClass
6 |
7 | @Retention(AnnotationRetention.BINARY)
8 | @Target(AnnotationTarget.FUNCTION)
9 | annotation class ChangeInvocationsOwner(
10 | val to: KClass<*> = noClass::class,
11 | val toName: String = NO_NAME,
12 | val deleteAfterChanging: Boolean = true
13 | )
14 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/skipInvocations-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | @Retention(AnnotationRetention.BINARY)
6 | @Target(
7 | AnnotationTarget.FUNCTION,
8 | AnnotationTarget.PROPERTY,
9 | AnnotationTarget.PROPERTY_GETTER,
10 | AnnotationTarget.PROPERTY_SETTER
11 | )
12 | annotation class SkipInvocations(
13 | val deleteAfterChanging: Boolean = true
14 | )
15 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/changeClassName-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | import kotlin.reflect.KClass
6 |
7 | @Retention(AnnotationRetention.BINARY)
8 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
9 | annotation class ChangeClassName(
10 | val to: KClass<*> = noClass::class,
11 | val toName: String = NO_NAME,
12 | val deleteAfterChanging: Boolean = false
13 | )
14 |
--------------------------------------------------------------------------------
/gradle-plugin/tests-gp/src/test/java/dev/reformator/stacktracedecoroutinator/gradleplugintests/DebugProbesAccessor.java:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.gradleplugintests;
2 |
3 | import kotlinx.coroutines.debug.internal.DebugProbesImpl;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.util.List;
7 |
8 | public class DebugProbesAccessor {
9 | public static @NotNull List> dumpCoroutinesInfo() {
10 | return DebugProbesImpl.INSTANCE.dumpCoroutinesInfo();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/jvm-agent-common/suspend-class-stub/src/main/kotlin/jvm-agent-common-stub.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.ClassNameConstant
6 | import kotlin.coroutines.suspendCoroutine
7 |
8 | @Suppress("unused")
9 | @ClassNameConstant("jvmAgentCommonSuspendClassName")
10 | private class PreloadStub {
11 | suspend fun suspendFun() {
12 | suspendCoroutine { }
13 | suspendCoroutine { }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/jvm/src/test/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.jvm.tests {
2 | requires dev.reformator.stacktracedecoroutinator.jvm;
3 | requires kotlin.test.junit5;
4 | requires dev.reformator.stacktracedecoroutinator.common;
5 | requires dev.reformator.stacktracedecoroutinator.provider;
6 | requires dev.reformator.stacktracedecoroutinator.testutils;
7 | requires dev.reformator.stacktracedecoroutinator.testutilsjvm;
8 | requires kotlinx.coroutines.core;
9 |
10 | exports dev.reformator.stacktracedecoroutinator.jvmtests;
11 | }
12 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/getOwnerClass-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | @Retention(AnnotationRetention.BINARY)
6 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER)
7 | annotation class GetOwnerClass(
8 | val deleteAfterModification: Boolean = true
9 | )
10 |
11 | val ownerClass: Class<*>
12 | get() { fail() }
13 |
14 | val ownerClassName: String
15 | get() { fail() }
16 |
17 | val ownerMethodName: String
18 | get() { fail() }
19 |
--------------------------------------------------------------------------------
/generator-jvm/src/test/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.generator.tests {
2 | requires kotlin.stdlib;
3 | requires org.objectweb.asm.util;
4 | requires dev.reformator.stacktracedecoroutinator.generatorjvm;
5 | requires dev.reformator.stacktracedecoroutinator.common;
6 | requires jdk.unsupported;
7 | requires dev.reformator.stacktracedecoroutinator.testutils;
8 | requires dev.reformator.stacktracedecoroutinator.provider;
9 | requires org.junit.jupiter.api;
10 | requires dev.reformator.stacktracedecoroutinator.testutilsjvm;
11 | }
12 |
--------------------------------------------------------------------------------
/common/src/main/kotlin/internal/utils-mh-api-common.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("NewApi", "PackageDirectoryMismatch")
2 | @file:AndroidLegacyKeep
3 |
4 | package dev.reformator.stacktracedecoroutinator.common.internal
5 |
6 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorSpec
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.AndroidLegacyKeep
8 | import java.lang.invoke.MethodType
9 | import kotlin.jvm.java
10 |
11 | val specMethodType: MethodType = MethodType.methodType(
12 | Object::class.java,
13 | DecoroutinatorSpec::class.java,
14 | Object::class.java
15 | )
16 |
--------------------------------------------------------------------------------
/jvm/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.jvm {
2 | requires dev.reformator.stacktracedecoroutinator.jvmagentcommon;
3 | requires dev.reformator.stacktracedecoroutinator.common;
4 | requires dev.reformator.stacktracedecoroutinator.provider;
5 | requires net.bytebuddy.agent;
6 | requires java.instrument;
7 | requires kotlin.stdlib;
8 |
9 | exports dev.reformator.stacktracedecoroutinator.jvm;
10 |
11 | exports dev.reformator.stacktracedecoroutinator.jvm.internal to
12 | dev.reformator.stacktracedecoroutinator.jvm.tests;
13 | }
14 |
--------------------------------------------------------------------------------
/spec-method-builder/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.specmethodbuilder {
2 | requires static intrinsics;
3 |
4 | requires kotlin.stdlib;
5 | requires org.objectweb.asm.tree;
6 | requires dev.reformator.stacktracedecoroutinator.provider;
7 |
8 | exports dev.reformator.stacktracedecoroutinator.specmethodbuilder.internal to
9 | dev.reformator.stacktracedecoroutinator.generatorjvm,
10 | dev.reformator.stacktracedecoroutinator.generator.tests,
11 | dev.reformator.stacktracedecoroutinator.classtransformer;
12 | }
13 |
--------------------------------------------------------------------------------
/class-transformer/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.classtransformer {
2 | requires static dev.reformator.bytecodeprocessor.intrinsics;
3 |
4 | requires kotlin.stdlib;
5 | requires dev.reformator.stacktracedecoroutinator.provider;
6 | requires dev.reformator.stacktracedecoroutinator.specmethodbuilder;
7 | requires org.objectweb.asm.tree;
8 | requires dev.reformator.kotlinmetadatajvmrepack;
9 |
10 | exports dev.reformator.stacktracedecoroutinator.classtransformer.internal to
11 | dev.reformator.stacktracedecoroutinator.jvmagentcommon;
12 | }
13 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "gradle-plugin-test"
2 |
3 | include("embedded-debug-probes-stdlib")
4 | include("embedded-debug-probes-xcoroutines")
5 | include("base-continuation-accessor")
6 | include("runtime-settings")
7 | include("intrinsics")
8 | include("provider")
9 |
10 | includeBuild("../bytecode-processor")
11 |
12 | pluginManagement {
13 | includeBuild("../bytecode-processor")
14 | }
15 |
16 | dependencyResolutionManagement {
17 | versionCatalogs {
18 | create("libs") {
19 | from(files("../../gradle/libs.versions.toml"))
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "latest-kotlin-gradle-plugin-test"
2 |
3 | includeBuild("../../_plugins/gradle-plugin-test")
4 | includeBuild("../../_plugins/bytecode-processor")
5 |
6 | pluginManagement {
7 | includeBuild("../../_plugins/gradle-plugin-test")
8 | includeBuild("../../_plugins/bytecode-processor")
9 | }
10 |
11 | dependencyResolutionManagement {
12 | versionCatalogs {
13 | create("libs") {
14 | from(files("../../gradle/libs.versions.toml"))
15 | }
16 | }
17 | }
18 |
19 | include("custom-loader")
20 | include("test-utils")
21 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-stub/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub.TestBaseContinuationAccessorProviderAccessor;
2 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider;
3 |
4 | module dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub {
5 | requires kotlin.stdlib;
6 | requires static intrinsics;
7 | requires dev.reformator.stacktracedecoroutinator.provider;
8 |
9 | provides BaseContinuationAccessorProvider with TestBaseContinuationAccessorProviderAccessor;
10 | }
--------------------------------------------------------------------------------
/gradle-plugin/android-legacy-tests/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -dontwarn javax.**
2 | -dontwarn reactor.**
3 | -dontwarn android.test.AndroidTestCase
4 | -dontwarn android.test.InstrumentationTestCase
5 | -dontwarn com.google.errorprone.annotations.**
6 |
7 | -keepclasseswithmembers class * {
8 | @org.junit.Test ;
9 | ();
10 | }
11 | -keepclasseswithmembers class * {
12 | @org.junit.Before ;
13 | ();
14 | }
15 | -keep class androidx.test.runner.AndroidJUnitRunner { *; }
16 | -keep class dev.reformator.stacktracedecoroutinator.test.Test_utilsKt {
17 | setRetraceMappingFiles(java.lang.String[]);
18 | }
19 |
--------------------------------------------------------------------------------
/gradle-plugin/tests-gp/src/test/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.gradleplugintests {
2 | requires static dev.reformator.bytecodeprocessor.intrinsics;
3 |
4 | requires dev.reformator.stacktracedecoroutinator.testutils;
5 | //noinspection JavaModuleDefinition
6 | requires kotlinx.coroutines.core;
7 | requires kotlin.test.junit5;
8 | requires dev.reformator.stacktracedecoroutinator.testutilsjvm;
9 | requires dev.reformator.stacktracedecoroutinator.duplicatejar;
10 | requires org.jetbrains.annotations;
11 |
12 | exports dev.reformator.stacktracedecoroutinator.gradleplugintests;
13 | }
14 |
--------------------------------------------------------------------------------
/runtime-settings/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.runtimesettings.DecoroutinatorRuntimeSettingsProvider;
2 |
3 | module dev.reformator.stacktracedecoroutinator.runtimesettings {
4 | requires kotlin.stdlib;
5 |
6 | exports dev.reformator.stacktracedecoroutinator.runtimesettings;
7 | exports dev.reformator.stacktracedecoroutinator.runtimesettings.internal to
8 | dev.reformator.stacktracedecoroutinator.common,
9 | dev.reformator.stacktracedecoroutinator.jvmagentcommon,
10 | kotlinx.coroutines.core;
11 |
12 | uses DecoroutinatorRuntimeSettingsProvider;
13 | }
14 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | module dev.reformator.stacktracedecoroutinator.testutils {
2 | requires kotlinx.coroutines.core;
3 | requires org.junit.jupiter.api;
4 | requires junit;
5 | requires io.github.oshai.kotlinlogging;
6 | //noinspection JavaModuleDefinition
7 | requires dev.reformator.retracerepack;
8 |
9 | requires static dev.reformator.stacktracedecoroutinator.common;
10 | requires static dev.reformator.bytecodeprocessor.intrinsics;
11 |
12 | exports dev.reformator.stacktracedecoroutinator.test;
13 |
14 | //noinspection JavaModuleDefinition
15 | opens dev.reformator.stacktracedecoroutinator.test;
16 | }
17 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/kotlin/org/example/project/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.tooling.preview.Preview
8 |
9 | class MainActivity : ComponentActivity() {
10 | override fun onCreate(savedInstanceState: Bundle?) {
11 | super.onCreate(savedInstanceState)
12 |
13 | setContent {
14 | App()
15 | }
16 | }
17 | }
18 |
19 | @Preview
20 | @Composable
21 | fun AppAndroidPreview() {
22 | App()
23 | }
--------------------------------------------------------------------------------
/gradle-plugin/android-tests/src/androidTest/kotlin/gradle-plugin-android-tests-proxy.kt:
--------------------------------------------------------------------------------
1 | import androidx.annotation.Keep
2 |
3 | @Keep
4 | class TestLocalFile: dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.TestLocalFile()
5 |
6 | @Keep
7 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.TailCallDeoptimizeTest()
8 |
9 | @Keep
10 | class DebugProbesTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.DebugProbesTest()
11 |
12 | @Keep
13 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests.RuntimeTest()
14 |
15 | @Keep
16 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
17 |
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -dontwarn edu.umd.cs.findbugs.annotations.**
2 | -dontwarn java.**
3 | -dontwarn javax.**
4 | -dontwarn reactor.**
5 | -dontwarn com.google.errorprone.annotations.**
6 |
7 | -keepclasseswithmembers class * {
8 | @org.junit.Test ;
9 | ();
10 | }
11 | -keepclasseswithmembers class * {
12 | @org.junit.Before ;
13 | ();
14 | }
15 | -keepclasseswithmembers class * {
16 | @org.junit.Rule ;
17 | ();
18 | }
19 | -keep class androidx.test.runner.AndroidJUnitRunner { *; }
20 | -keep class dev.reformator.stacktracedecoroutinator.test.Test_utilsKt {
21 | setRetraceMappingFiles(java.lang.String[]);
22 | }
23 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/api/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | api(libs.asm.utils)
13 |
14 | testImplementation(kotlin("test"))
15 | }
16 |
17 | tasks.test {
18 | useJUnitPlatform()
19 | }
20 |
21 | java {
22 | sourceCompatibility = JavaVersion.VERSION_1_8
23 | targetCompatibility = JavaVersion.VERSION_1_8
24 | }
25 |
26 | tasks.withType {
27 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
28 | }
29 |
30 | kotlin {
31 | compilerOptions {
32 | jvmTarget = JvmTarget.JVM_1_8
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/src/main/kotlin/loadConstant-intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.intrinsics
4 |
5 | @Retention(AnnotationRetention.BINARY)
6 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER)
7 | annotation class LoadConstant(
8 | val key: String,
9 | val deleteAfterModification: Boolean = true
10 | )
11 |
12 | @Retention(AnnotationRetention.BINARY)
13 | @Target(AnnotationTarget.CLASS)
14 | annotation class ClassNameConstant(val key: String)
15 |
16 | @Retention(AnnotationRetention.BINARY)
17 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
18 | annotation class MethodNameConstant(val key: String)
19 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "bytecode-processor"
2 | include(
3 | "api",
4 | "plugins",
5 | "intrinsics",
6 | "gradle-plugin"
7 | )
8 | project(":api").name = "bytecode-processor-api"
9 | project(":plugins").name = "bytecode-processor-plugins"
10 | project(":intrinsics").name = "bytecode-processor-intrinsics"
11 | project(":gradle-plugin").name = "bytecode-processor-gradle-plugin"
12 |
13 | includeBuild("../force-variant-java-version")
14 |
15 | pluginManagement {
16 | includeBuild("../force-variant-java-version")
17 | }
18 |
19 | dependencyResolutionManagement {
20 | versionCatalogs {
21 | create("libs") {
22 | from(files("../../gradle/libs.versions.toml"))
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/jvm-agent-common/suspend-class-stub/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.LoadConstantProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | //noinspection UseTomlInstead
15 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
16 | }
17 |
18 | bytecodeProcessor {
19 | processors = listOf(LoadConstantProcessor)
20 | }
21 |
22 | tasks.withType {
23 | options.compilerArgs.addAll(listOf("-parameters"))
24 | }
25 |
26 | kotlin {
27 | compilerOptions {
28 | jvmTarget = JvmTarget.JVM_1_8
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/gradle-plugin/android-legacy-tests/src/androidTest/kotlin/gradle-plugin-android-legacy-tests-proxy.kt:
--------------------------------------------------------------------------------
1 | import androidx.annotation.Keep
2 |
3 | @Keep
4 | class TestLocalFile: dev.reformator.stacktracedecoroutinator.gradlepluginandroidlegacytests.TestLocalFile()
5 |
6 | @Keep
7 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidlegacytests.TailCallDeoptimizeTest()
8 |
9 | @Keep
10 | class DebugProbesTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidlegacytests.DebugProbesTest()
11 |
12 | @Keep
13 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidlegacytests.RuntimeTest()
14 |
15 | @Keep
16 | class OldAndroidTest: dev.reformator.stacktracedecoroutinator.gradlepluginandroidlegacytests.OldAndroidTest()
17 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/test/kotlin/showBaseContinuation.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package showbasecontinuation
4 |
5 | import dev.reformator.stacktracedecoroutinator.intrinsics.BASE_CONTINUATION_CLASS_NAME
6 | import dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal.getResourceAsStream
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.internalName
8 | import org.objectweb.asm.ClassReader
9 | import org.objectweb.asm.util.TraceClassVisitor
10 | import java.io.PrintWriter
11 |
12 | fun main() {
13 | val classReader = ClassReader(getResourceAsStream(BASE_CONTINUATION_CLASS_NAME.internalName + ".class"))
14 | PrintWriter(System.out.writer()).use {
15 | classReader.accept(TraceClassVisitor(it), 0)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/runtime-settings/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | java {
12 | sourceCompatibility = JavaVersion.VERSION_1_8
13 | targetCompatibility = JavaVersion.VERSION_1_8
14 | }
15 |
16 | kotlin {
17 | compilerOptions {
18 | jvmTarget = JvmTarget.JVM_1_8
19 | }
20 | }
21 |
22 | sourceSets {
23 | main {
24 | kotlin.destinationDirectory = java.destinationDirectory
25 | }
26 | test {
27 | kotlin.destinationDirectory = java.destinationDirectory
28 | }
29 | }
30 |
31 | val kotlinSources = sourceSets.main.get().kotlin
32 | kotlinSources.srcDirs("../../../runtime-settings/src/main/kotlin")
33 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/kotlin/gradle-plugin-utils.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.gradleplugin
4 |
5 | import java.util.Base64
6 | import java.util.zip.ZipInputStream
7 |
8 | internal fun ArtifactBuilder.addJarClassesAndResources(jarBase64: String) {
9 | ZipInputStream(Base64.getDecoder().decode(jarBase64).inputStream()).use { input ->
10 | while (true) {
11 | val entry = input.nextEntry ?: break
12 | if (!entry.isDirectory && entry.name != "META-INF/MANIFEST.MF") {
13 | val path = entry.name.split("/")
14 | val body = input.readBytes()
15 | ensureDirAndAndAddFile(path, body.inputStream())
16 | }
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/gradle-plugin/android-tests/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | -dontwarn edu.umd.cs.findbugs.annotations.**
2 | -dontwarn java.**
3 | -dontwarn javax.**
4 | -dontwarn reactor.**
5 | -dontwarn com.google.errorprone.annotations.**
6 | -dontwarn android.test.AndroidTestCase
7 | -dontwarn android.test.InstrumentationTestCase
8 |
9 | -keepclasseswithmembers class * {
10 | @org.junit.Test ;
11 | ();
12 | }
13 | -keepclasseswithmembers class * {
14 | @org.junit.Before ;
15 | ();
16 | }
17 | -keepclasseswithmembers class * {
18 | @org.junit.Rule ;
19 | ();
20 | }
21 | -keep class androidx.test.runner.AndroidJUnitRunner { *; }
22 | -keep class dev.reformator.stacktracedecoroutinator.test.Test_utilsKt {
23 | setRetraceMappingFiles(java.lang.String[]);
24 | }
25 |
--------------------------------------------------------------------------------
/mh-invoker/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker;
2 | import dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker;
3 | import dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularMethodHandleInvoker;
4 | import dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularVarHandleInvoker;
5 |
6 | module dev.reformator.stacktracedecoroutinator.mhinvoker {
7 | requires static dev.reformator.bytecodeprocessor.intrinsics;
8 |
9 | requires dev.reformator.stacktracedecoroutinator.provider;
10 | requires dev.reformator.stacktracedecoroutinator.common;
11 |
12 | provides MethodHandleInvoker with RegularMethodHandleInvoker;
13 | provides VarHandleInvoker with RegularVarHandleInvoker;
14 | }
15 |
--------------------------------------------------------------------------------
/jvm/src/test/kotlin/example.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.jvmtests
2 |
3 | import dev.reformator.stacktracedecoroutinator.jvm.DecoroutinatorJvmApi
4 | import kotlinx.coroutines.runBlocking
5 | import kotlinx.coroutines.yield
6 |
7 | object Test {
8 | suspend fun rec(depth: Int) {
9 | if (depth == 0) {
10 | yield()
11 | throw Exception("exception at ${System.currentTimeMillis()}")
12 | }
13 | rec(depth - 1)
14 | }
15 | }
16 |
17 | fun main() {
18 | DecoroutinatorJvmApi.install() // enable stacktrace-decoroutinator runtime
19 | try {
20 | runBlocking {
21 | Test.rec(10)
22 | }
23 | } catch (e: Exception) {
24 | e.printStackTrace() // print full stack trace with 10 recursive calls
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/plugins/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | implementation(project(":bytecode-processor-api"))
13 | implementation(project(":bytecode-processor-intrinsics"))
14 |
15 | testImplementation(kotlin("test"))
16 | }
17 |
18 | tasks.test {
19 | useJUnitPlatform()
20 | }
21 |
22 | java {
23 | sourceCompatibility = JavaVersion.VERSION_1_8
24 | targetCompatibility = JavaVersion.VERSION_1_8
25 | }
26 |
27 | tasks.withType {
28 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
29 | }
30 |
31 | kotlin {
32 | compilerOptions {
33 | jvmTarget = JvmTarget.JVM_1_8
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/gradle-plugin/duplicate-entity-jar-builder/src/main/kotlin/proxyCaller.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.duplicatejar
2 |
3 | import dev.reformator.bytecodeprocessor.intrinsics.GetOwnerClass
4 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
5 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
6 | import dev.reformator.bytecodeprocessor.intrinsics.fail
7 |
8 | suspend fun call(callIt: suspend () -> Any?): Any? {
9 | duplicateJarCallLineNumber = currentLineNumber + 1
10 | return callIt()
11 | }
12 |
13 | private val currentFileClass: Class<*>
14 | @GetOwnerClass get() { fail() }
15 |
16 | val duplicateJarCallClassName = currentFileClass.name
17 | val duplicateJarCallMethodName = ::call.name
18 | var duplicateJarCallLineNumber = 0
19 | val duplicateJarFileName = currentFileName
20 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/main/kotlin/internal/utils-jvm-agent-common.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal
2 |
3 | import dev.reformator.bytecodeprocessor.intrinsics.ownerClass
4 | import java.io.InputStream
5 |
6 | internal fun getResourceAsStream(name: String): InputStream? =
7 | try {
8 | Thread.currentThread().contextClassLoader.getResourceAsStream(name)
9 | } catch (_: Throwable) {
10 | null
11 | } ?: try {
12 | ownerClass.classLoader.getResourceAsStream(name)
13 | } catch (_: Throwable) {
14 | null
15 | } ?: try {
16 | ClassLoader.getSystemClassLoader().getResourceAsStream(name)
17 | } catch (_: Throwable) {
18 | null
19 | } ?: try {
20 | ClassLoader.getSystemResourceAsStream(name)
21 | } catch (_: Throwable) {
22 | null
23 | }
24 |
--------------------------------------------------------------------------------
/test-utils/custom-loader/src/main/kotlin/test-utils-custom-loader.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.test
4 |
5 | import org.junit.jupiter.api.Assertions.assertTrue
6 |
7 | fun checkStacktrace(vararg elements: StackTraceElement) {
8 | if (elements.isEmpty()) {
9 | return
10 | }
11 | Exception().stackTrace.also { stacktrace ->
12 | val startIndex = stacktrace.indexOfFirst { it eq elements[0] }
13 | elements.forEachIndexed { index, element ->
14 | assertTrue(element eq stacktrace[startIndex + index])
15 | }
16 | }
17 | }
18 |
19 | private infix fun StackTraceElement.eq(element: StackTraceElement) =
20 | this.className == element.className && this.methodName == element.methodName &&
21 | this.lineNumber == element.lineNumber
22 |
23 |
--------------------------------------------------------------------------------
/generator-jvm/jdk8-tests-g/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | kotlin("jvm")
3 | id("decoroutinatorTransformBaseContinuation")
4 | }
5 |
6 | repositories {
7 | mavenCentral()
8 | }
9 |
10 | dependencies {
11 | testRuntimeOnly(project(":stacktrace-decoroutinator-generator-jvm"))
12 | testRuntimeOnly(project(":stacktrace-decoroutinator-mh-invoker"))
13 |
14 | testImplementation(kotlin("test"))
15 | testImplementation(project(":test-utils"))
16 | testImplementation(project(":test-utils-jvm"))
17 | testRuntimeOnly(project(":test-utils:base-continuation-accessor-stub"))
18 | }
19 |
20 | afterEvaluate {
21 | configurations.testRuntimeClasspath.get().attributes.attribute(decoroutinatorTransformedBaseContinuationAttribute, true)
22 | }
23 |
24 | tasks.test {
25 | useJUnitPlatform()
26 | }
27 |
28 | kotlin {
29 | jvmToolchain(8)
30 | }
31 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/jdk8-tests-mij/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | kotlin("jvm")
3 | id("decoroutinatorTransformBaseContinuation")
4 | }
5 |
6 | repositories {
7 | mavenCentral()
8 | }
9 |
10 | dependencies {
11 | testRuntimeOnly(project(":stacktrace-decoroutinator-generator-jvm"))
12 | testRuntimeOnly(project(":stacktrace-decoroutinator-mh-invoker-jvm"))
13 |
14 | testImplementation(kotlin("test"))
15 | testImplementation(project(":test-utils"))
16 | testImplementation(project(":test-utils-jvm"))
17 | testRuntimeOnly(project(":test-utils:base-continuation-accessor-stub"))
18 | }
19 |
20 | afterEvaluate {
21 | configurations.testRuntimeClasspath.get().attributes.attribute(decoroutinatorTransformedBaseContinuationAttribute, true)
22 | }
23 |
24 | tasks.test {
25 | useJUnitPlatform()
26 | }
27 |
28 | kotlin {
29 | jvmToolchain(8)
30 | }
31 |
--------------------------------------------------------------------------------
/mh-invoker-jvm/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker;
2 | import dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker;
3 | import dev.reformator.stacktracedecoroutinator.mhinvokerjvm.internal.JvmMethodHandleInvoker;
4 | import dev.reformator.stacktracedecoroutinator.mhinvokerjvm.internal.JvmVarHandleInvoker;
5 |
6 | module dev.reformator.stacktracedecoroutinator.mhinvokerjvm {
7 | requires static dev.reformator.bytecodeprocessor.intrinsics;
8 | requires static intrinsics;
9 |
10 | requires dev.reformator.stacktracedecoroutinator.provider;
11 | requires dev.reformator.stacktracedecoroutinator.common;
12 | requires kotlin.stdlib;
13 |
14 | provides MethodHandleInvoker with JvmMethodHandleInvoker;
15 | provides VarHandleInvoker with JvmVarHandleInvoker;
16 | }
17 |
--------------------------------------------------------------------------------
/generator-android/src/test/kotlin/jvm-tests-generator-android.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.methodHandleInvoker
2 | import kotlinx.coroutines.runBlocking
3 | import kotlinx.coroutines.yield
4 | import org.junit.Test
5 | import kotlin.test.assertEquals
6 | import kotlin.test.assertTrue
7 |
8 | class JvmTestsGeneratorAndroid {
9 | @Test
10 | fun runJvmWithGeneratorAndroid() {
11 | val message = "OK"
12 |
13 | suspend fun f() {
14 | yield()
15 | error(message)
16 | }
17 |
18 | try {
19 | runBlocking {
20 | f()
21 | }
22 | } catch (e: IllegalStateException) {
23 | assertEquals(message, e.message)
24 | assertTrue(e.stackTrace.any { it.className == methodHandleInvoker.unknownSpecMethodClass.name })
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/plugins/src/main/kotlin/deleteClass-plugins.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.plugins
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.DeleteClass
6 | import dev.reformator.bytecodeprocessor.api.BytecodeProcessorContext
7 | import dev.reformator.bytecodeprocessor.api.ProcessingDirectory
8 | import dev.reformator.bytecodeprocessor.api.Processor
9 | import dev.reformator.bytecodeprocessor.plugins.internal.find
10 |
11 | object DeleteClassProcessor: Processor {
12 | override fun process(directory: ProcessingDirectory, context: BytecodeProcessorContext) {
13 | directory.classes.forEach { processingClass ->
14 | processingClass.node.invisibleAnnotations.find(DeleteClass::class.java) ?: return@forEach
15 |
16 | processingClass.delete()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/gradle-plugin/src/main/kotlin/api-gradle-plugin-bytecode-processor.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package org.gradle.kotlin.dsl
4 |
5 | import dev.reformator.bytecodeprocessor.gradleplugin.BytecodeProcessorPluginExtension
6 | import dev.reformator.bytecodeprocessor.gradleplugin.EXTENSION_NAME
7 | import dev.reformator.bytecodeprocessor.gradleplugin.INIT_TASK_NAME
8 | import org.gradle.api.Project
9 | import org.gradle.api.Task
10 |
11 | fun Project.bytecodeProcessor(configure: BytecodeProcessorPluginExtension.() -> Unit) {
12 | extensions.configure(EXTENSION_NAME, configure)
13 | }
14 |
15 | val Project.bytecodeProcessor: BytecodeProcessorPluginExtension
16 | get() = extensions.getByName(EXTENSION_NAME) as BytecodeProcessorPluginExtension
17 |
18 | val Project.bytecodeProcessorInitTask: Task
19 | get() = tasks.findByName(INIT_TASK_NAME)!!
20 |
--------------------------------------------------------------------------------
/test-utils-jvm/src/main/kotlin/test-utils.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.testjvm
4 |
5 | import org.junit.jupiter.api.Assertions.assertTrue
6 |
7 | fun checkStacktrace(vararg elements: StackTraceElement) {
8 | if (elements.isEmpty()) {
9 | return
10 | }
11 | Exception().stackTrace.also { stacktrace ->
12 | val startIndex = stacktrace.indexOfFirst { elements[0] eq it }
13 | elements.forEachIndexed { index, element ->
14 | assertTrue(element eq stacktrace[startIndex + index])
15 | }
16 | }
17 | }
18 |
19 | private infix fun StackTraceElement.eq(element: StackTraceElement) =
20 | this.className == element.className && (this.methodName == element.methodName || this.methodName == ANY) &&
21 | this.lineNumber == element.lineNumber
22 |
23 | const val ANY = ""
24 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/intrinsics/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | id("dev.reformator.forcevariantjavaversion")
6 | }
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 | implementation(libs.asm.utils)
14 | testImplementation(kotlin("test"))
15 | }
16 |
17 | tasks.test {
18 | useJUnitPlatform()
19 | }
20 |
21 | java {
22 | sourceCompatibility = JavaVersion.VERSION_1_9
23 | targetCompatibility = JavaVersion.VERSION_1_9
24 | }
25 |
26 | tasks.withType {
27 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
28 | }
29 |
30 | kotlin {
31 | compilerOptions {
32 | jvmTarget = JvmTarget.JVM_1_8
33 | }
34 | }
35 |
36 | sourceSets {
37 | main {
38 | kotlin.destinationDirectory = java.destinationDirectory
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/_latest-gradle-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 |
8 | dependencies {
9 | classpath(libs.kotlin.gradle.plugin.latest)
10 | classpath(libs.android.gradle.plugin)
11 | classpath(fileTree("../gradle-plugin/build/libs") { include("*.jar") })
12 | classpath(libs.kotlin.logging.jvm)
13 | classpath(fileTree("../provider/build/libs") { include("*.jar") })
14 | classpath(fileTree("../class-transformer/build/libs") { include("*.jar") })
15 | classpath(fileTree("../spec-method-builder/build/libs") { include("*.jar") })
16 | classpath(libs.kotlin.metadata.jvm)
17 | classpath(libs.asm.utils)
18 | }
19 | }
20 |
21 | subprojects {
22 | group = "dev.reformator.stacktracedecoroutinator-latest-gradle"
23 | version = "1.0.0-SNAPSHOT"
24 | }
25 |
--------------------------------------------------------------------------------
/test-utils/retrace-repack/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("java")
3 | alias(libs.plugins.shadow)
4 | id("dev.reformator.forcevariantjavaversion")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | implementation(libs.retrace)
13 | }
14 |
15 | java {
16 | sourceCompatibility = JavaVersion.VERSION_1_9
17 | targetCompatibility = JavaVersion.VERSION_1_9
18 | }
19 |
20 | tasks.shadowJar {
21 | duplicatesStrategy = DuplicatesStrategy.EXCLUDE
22 | failOnDuplicateEntries = true
23 | archiveClassifier = ""
24 | relocate("proguard", "dev.reformator.retracerepack")
25 | excludes.remove("module-info.class")
26 | exclude("**/_dummy.class")
27 | exclude("com/**")
28 | exclude("kotlin/**")
29 | exclude("org/**")
30 | exclude("META-INF/versions/**")
31 | exclude("META-INF/*.kotlin_module")
32 | exclude("META-INF/services/*")
33 | }
34 |
--------------------------------------------------------------------------------
/generator-jvm/android-wrong-generator-tests/src/androidTest/kotlin/android-tests-generator-jvm.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.methodHandleInvoker
2 | import kotlinx.coroutines.runBlocking
3 | import kotlinx.coroutines.yield
4 | import org.junit.Assert.assertEquals
5 | import org.junit.Assert.assertTrue
6 | import org.junit.Test
7 |
8 | class AndroidTestsGeneratorJvm {
9 | @Test
10 | fun runAndroidWithGeneratorJvm() {
11 | val message = "OK"
12 |
13 | suspend fun f() {
14 | yield()
15 | error(message)
16 | }
17 |
18 | try {
19 | runBlocking {
20 | f()
21 | }
22 | } catch (e: IllegalStateException) {
23 | assertEquals(message, e.message)
24 | assertTrue(e.stackTrace.any { it.className == methodHandleInvoker.unknownSpecMethodClass.name })
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/gradle-plugin/embedded-debug-probes-stdlib/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | //noinspection UseTomlInstead
13 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
14 |
15 | implementation(project(":stacktrace-decoroutinator-runtime-settings"))
16 | }
17 |
18 | java {
19 | sourceCompatibility = JavaVersion.VERSION_1_9
20 | targetCompatibility = JavaVersion.VERSION_1_9
21 | }
22 |
23 | kotlin {
24 | compilerOptions {
25 | jvmTarget = JvmTarget.JVM_1_8
26 | freeCompilerArgs.add("-Xallow-kotlin-package")
27 | }
28 | }
29 |
30 | sourceSets {
31 | main {
32 | kotlin.destinationDirectory = java.destinationDirectory
33 | }
34 | test {
35 | kotlin.destinationDirectory = java.destinationDirectory
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal.AgentBaseContinuationAccessorProvider;
2 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider;
3 |
4 | module dev.reformator.stacktracedecoroutinator.jvmagentcommon {
5 | requires static intrinsics;
6 | requires static dev.reformator.bytecodeprocessor.intrinsics;
7 |
8 | requires kotlin.stdlib;
9 | requires dev.reformator.stacktracedecoroutinator.runtimesettings;
10 | requires dev.reformator.stacktracedecoroutinator.provider;
11 | requires java.instrument;
12 | requires dev.reformator.stacktracedecoroutinator.classtransformer;
13 |
14 | exports dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal to
15 | dev.reformator.stacktracedecoroutinator.jvm;
16 |
17 | provides BaseContinuationAccessorProvider with AgentBaseContinuationAccessorProvider;
18 | }
19 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/custom-loader/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 |
3 | plugins {
4 | alias(libs.plugins.kotlin.jvm.latest)
5 | id("dev.reformator.bytecodeprocessor")
6 | alias(libs.plugins.shadow)
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | //noinspection UseTomlInstead
15 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
16 | implementation(libs.kotlinx.coroutines.jdk8.build)
17 | implementation(libs.junit5.api)
18 | }
19 |
20 | tasks.shadowJar {
21 | failOnDuplicateEntries = true
22 | }
23 |
24 | bytecodeProcessor {
25 | processors = setOf(
26 | GetCurrentFileNameProcessor,
27 | GetOwnerClassProcessor
28 | )
29 | }
30 |
31 | tasks.test {
32 | useJUnitPlatform()
33 | }
34 |
35 | val kotlinSources = sourceSets.main.get().kotlin
36 | kotlinSources.srcDirs("../../../test-utils/custom-loader/src/main/kotlin")
37 |
--------------------------------------------------------------------------------
/intrinsics/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.ChangeClassNameProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.forcevariantjavaversion")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
16 | testImplementation(kotlin("test"))
17 | }
18 |
19 | tasks.test {
20 | useJUnitPlatform()
21 | }
22 |
23 | java {
24 | sourceCompatibility = JavaVersion.VERSION_1_9
25 | targetCompatibility = JavaVersion.VERSION_1_9
26 | }
27 |
28 | kotlin {
29 | compilerOptions {
30 | jvmTarget = JvmTarget.JVM_1_8
31 | }
32 | }
33 |
34 | sourceSets {
35 | main {
36 | kotlin.destinationDirectory = java.destinationDirectory
37 | }
38 | }
39 |
40 | bytecodeProcessor {
41 | processors = listOf(
42 | ChangeClassNameProcessor
43 | )
44 | skipUpdate = true
45 | }
46 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-reflect-stub/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | compileOnly(project(":intrinsics"))
15 | implementation(project(":stacktrace-decoroutinator-provider"))
16 | }
17 |
18 | bytecodeProcessor {
19 | dependentProjects = listOf(
20 | project(":intrinsics"),
21 | project(":stacktrace-decoroutinator-provider")
22 | )
23 | processors = listOf(
24 | ChangeClassNameProcessor
25 | )
26 | }
27 |
28 | java {
29 | sourceCompatibility = JavaVersion.VERSION_1_8
30 | targetCompatibility = JavaVersion.VERSION_1_8
31 | }
32 |
33 | tasks.withType {
34 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
35 | }
36 |
37 | kotlin {
38 | compilerOptions {
39 | jvmTarget = JvmTarget.JVM_1_8
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/embedded-debug-probes-stdlib/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | dependencies {
12 | //noinspection UseTomlInstead
13 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
14 | compileOnly(project(":intrinsics"))
15 | }
16 |
17 | java {
18 | sourceCompatibility = JavaVersion.VERSION_1_8
19 | targetCompatibility = JavaVersion.VERSION_1_8
20 | }
21 |
22 | kotlin {
23 | compilerOptions {
24 | jvmTarget = JvmTarget.JVM_1_8
25 | freeCompilerArgs.add("-Xallow-kotlin-package")
26 | }
27 | }
28 |
29 | sourceSets {
30 | main {
31 | kotlin.destinationDirectory = java.destinationDirectory
32 | }
33 | test {
34 | kotlin.destinationDirectory = java.destinationDirectory
35 | }
36 | }
37 |
38 | val kotlinSources = sourceSets.main.get().kotlin
39 | kotlinSources.srcDirs("../../../gradle-plugin/embedded-debug-probes-stdlib/src/main/kotlin")
40 |
--------------------------------------------------------------------------------
/gradle-plugin/gradle-groovy-dsl-tests/build.gradle:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | id 'dev.reformator.stacktracedecoroutinator'
5 | id 'org.jetbrains.kotlin.jvm'
6 | }
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | stacktraceDecoroutinator {
13 | regularDependencyConfigurations.include = []
14 | androidDependencyConfigurations.include = []
15 | jvmDependencyConfigurations.include = []
16 | addJvmRuntimeDependency = false
17 | }
18 |
19 | java {
20 | sourceCompatibility = JavaVersion.VERSION_1_9
21 | targetCompatibility = JavaVersion.VERSION_1_9
22 | }
23 |
24 | kotlin {
25 | compilerOptions {
26 | jvmTarget = JvmTarget.JVM_1_8
27 | }
28 | }
29 |
30 | assertTrue(decoroutinatorCommon().startsWith("dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-common:"))
31 | assertTrue(File.class.isInstance(decoroutinatorAndroidProGuardRules()))
32 |
33 | static def assertTrue(Boolean value) {
34 | if (!value) {
35 | throw new RuntimeException("check failed")
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/provider/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.provider.internal.DecoroutinatorProvider;
2 |
3 | module dev.reformator.stacktracedecoroutinator.provider {
4 | requires static kotlin.stdlib;
5 | requires static dev.reformator.bytecodeprocessor.intrinsics;
6 |
7 | exports dev.reformator.stacktracedecoroutinator.provider;
8 | exports dev.reformator.stacktracedecoroutinator.provider.internal to
9 | kotlin.stdlib,
10 | dev.reformator.stacktracedecoroutinator.common,
11 | dev.reformator.stacktracedecoroutinator.mhinvoker,
12 | dev.reformator.stacktracedecoroutinator.generatorjvm,
13 | dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub,
14 | dev.reformator.stacktracedecoroutinator.jvmagentcommon,
15 | dev.reformator.stacktracedecoroutinator.generator.tests,
16 | dev.reformator.stacktracedecoroutinator.specmethodbuilder,
17 | dev.reformator.stacktracedecoroutinator.classtransformer;
18 |
19 | uses DecoroutinatorProvider;
20 | }
21 |
--------------------------------------------------------------------------------
/_plugins/force-variant-java-version/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | buildscript {
4 | repositories {
5 | mavenCentral()
6 | gradlePluginPortal()
7 | }
8 | }
9 |
10 | plugins {
11 | alias(libs.plugins.kotlin.jvm.build)
12 | alias(libs.plugins.gradle.plugin.publish)
13 | }
14 |
15 | group = "dev.reformator.forcevariantjavaversion"
16 | version = "0.0.1-SNAPSHOT"
17 |
18 | repositories {
19 | mavenCentral()
20 | }
21 |
22 | dependencies {
23 | implementation(libs.kotlin.logging.jvm)
24 | }
25 |
26 | java {
27 | sourceCompatibility = JavaVersion.VERSION_1_8
28 | targetCompatibility = JavaVersion.VERSION_1_8
29 | }
30 |
31 | kotlin {
32 | compilerOptions {
33 | jvmTarget = JvmTarget.JVM_1_8
34 | }
35 | }
36 |
37 |
38 | gradlePlugin {
39 | plugins {
40 | create("forcevariantjavaversionPlugin") {
41 | id = "dev.reformator.forcevariantjavaversion"
42 | implementationClass = "dev.reformator.forcevariantjavaversion.ForceVariantJavaVersionPlugin"
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/jvm-agent/jdk8-tests-ja/src/test/kotlin/tests-jdk8-jvm-agent.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.coroutines.runBlocking
2 | import kotlinx.coroutines.yield
3 | import kotlin.test.Test
4 |
5 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
6 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
7 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
8 | class CustomClassLoaderTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTailCallDeoptimizedTest()
9 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
10 | class JvmTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTailCallDeoptimizedTest()
11 |
12 | // Jacoco only instruments this class
13 | class JacocoInstrumentedMethodTest {
14 | @Test
15 | fun jacocoInstrumentedMethodTest(): Unit = runBlocking {
16 | suspend fun jacocoInstrumentedMethod() {
17 | yield()
18 | yield()
19 | }
20 | jacocoInstrumentedMethod()
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/_plugins/force-variant-java-version/src/main/kotlin/forceVariantJavaVersion.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.forcevariantjavaversion
4 |
5 | import org.gradle.api.Plugin
6 | import org.gradle.api.Project
7 | import org.gradle.api.attributes.java.TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE
8 |
9 | class ForceVariantJavaVersionPlugin: Plugin {
10 | override fun apply(target: Project) {
11 | with(target) {
12 | afterEvaluate { _ ->
13 | configurations.forEach { conf ->
14 | if (conf.attributes.getAttribute(TARGET_JVM_VERSION_ATTRIBUTE) == 9) {
15 | conf.attributes.attribute(TARGET_JVM_VERSION_ATTRIBUTE, 8)
16 | }
17 | conf.outgoing.variants.forEach { variant ->
18 | if (variant.attributes.getAttribute(TARGET_JVM_VERSION_ATTRIBUTE) == 9) {
19 | variant.attributes.attribute(TARGET_JVM_VERSION_ATTRIBUTE, 8)
20 | }
21 | }
22 | }
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/gradle-plugin/embedded-debug-probes-stdlib/src/main/kotlin/embedded-debug-probes-stdlib.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("DebugProbesKt")
3 |
4 | package kotlin.coroutines.jvm.internal
5 |
6 | import java.util.ServiceLoader
7 | import kotlin.coroutines.Continuation
8 |
9 | interface DecoroutinatorDebugProbesProvider {
10 | fun probeCoroutineCreated(completion: Continuation): Continuation
11 | fun probeCoroutineResumed(frame: Continuation<*>)
12 | fun probeCoroutineSuspended(frame: Continuation<*>)
13 | }
14 |
15 | private val provider: DecoroutinatorDebugProbesProvider =
16 | ServiceLoader.load(DecoroutinatorDebugProbesProvider::class.java).iterator().next()
17 |
18 | @Suppress("unused")
19 | fun probeCoroutineCreated(completion: Continuation): Continuation =
20 | provider.probeCoroutineCreated(completion)
21 |
22 | @Suppress("unused")
23 | fun probeCoroutineResumed(frame: Continuation<*>) {
24 | provider.probeCoroutineResumed(frame)
25 | }
26 |
27 | @Suppress("unused")
28 | fun probeCoroutineSuspended(frame: Continuation<*>) {
29 | provider.probeCoroutineSuspended(frame)
30 | }
31 |
--------------------------------------------------------------------------------
/gradle-plugin/base-continuation-accessor/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.ChangeClassNameProcessor
2 | import dev.reformator.bytecodeprocessor.plugins.LoadConstantProcessor
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | kotlin("jvm")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | bytecodeProcessor {
11 | dependentProjects = listOf(project(":intrinsics"))
12 | processors = listOf(
13 | ChangeClassNameProcessor,
14 | LoadConstantProcessor
15 | )
16 | }
17 |
18 | repositories {
19 | mavenCentral()
20 | }
21 |
22 | dependencies {
23 | //noinspection UseTomlInstead
24 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
25 | compileOnly(project(":stacktrace-decoroutinator-provider"))
26 | compileOnly(project(":intrinsics"))
27 | }
28 |
29 | java {
30 | sourceCompatibility = JavaVersion.VERSION_1_8
31 | targetCompatibility = JavaVersion.VERSION_1_8
32 | }
33 |
34 | kotlin {
35 | compilerOptions {
36 | jvmTarget = JvmTarget.JVM_1_8
37 | freeCompilerArgs.add("-Xallow-kotlin-package")
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test-utils/custom-loader/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | alias(libs.plugins.shadow)
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | //noinspection UseTomlInstead
16 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
17 |
18 | implementation(libs.kotlinx.coroutines.jdk8.build)
19 | implementation(libs.junit5.api)
20 | }
21 |
22 | tasks.shadowJar {
23 | failOnDuplicateEntries = true
24 | }
25 |
26 | bytecodeProcessor {
27 | processors = listOf(
28 | GetCurrentFileNameProcessor,
29 | GetOwnerClassProcessor
30 | )
31 | }
32 |
33 | java {
34 | sourceCompatibility = JavaVersion.VERSION_1_8
35 | targetCompatibility = JavaVersion.VERSION_1_8
36 | }
37 |
38 | tasks.withType {
39 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
40 | }
41 |
42 | kotlin {
43 | compilerOptions {
44 | jvmTarget = JvmTarget.JVM_1_8
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/gradle-plugin/aar-builder/src/main/kotlin/aar-builder.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.aarbuilder
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
6 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
7 | import dev.reformator.bytecodeprocessor.intrinsics.ownerClassName
8 | import dev.reformator.bytecodeprocessor.intrinsics.ownerMethodName
9 |
10 | @Suppress("unused")
11 | val suspendFunFromAarOwnerClassName = ownerClassName
12 | @Suppress("unused")
13 | val suspendFunFromAarMethodName: String
14 | get() = _suspendFunFromAarMethodName
15 | @Suppress("unused")
16 | val suspendFunFromAarFileName = currentFileName
17 | @Suppress("unused")
18 | val suspendFunFromAarLineNumber: Int
19 | get() = _suspendFunFromAarLineNumber
20 |
21 | @Suppress("unused")
22 | suspend fun suspendFunFromAar(body: suspend () -> T): T {
23 | _suspendFunFromAarMethodName = ownerMethodName
24 | _suspendFunFromAarLineNumber = currentLineNumber + 1
25 | return body()
26 | }
27 |
28 |
29 | private lateinit var _suspendFunFromAarMethodName: String
30 | private var _suspendFunFromAarLineNumber = 0
31 |
--------------------------------------------------------------------------------
/gradle-plugin/base-continuation-accessor/src/main/kotlin/base-continuation-accessor.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package kotlin.coroutines.jvm.internal
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.ClassNameConstant
6 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessor
8 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
9 | import java.lang.invoke.MethodHandles
10 |
11 | @Suppress("unused")
12 | @ClassNameConstant("baseContinuationAccessorImplClassName")
13 | class DecoroutinatorBaseContinuationAccessorImpl: BaseContinuationAccessor, BaseContinuationAccessorProvider {
14 | override fun invokeSuspend(baseContinuation: Any, result: Any?): Any? =
15 | (baseContinuation as BaseContinuation).invokeSuspend(result)
16 |
17 | override fun releaseIntercepted(baseContinuation: Any) {
18 | (baseContinuation as BaseContinuation).releaseIntercepted()
19 | }
20 |
21 | override fun createAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor =
22 | this
23 | }
24 |
--------------------------------------------------------------------------------
/jvm-agent/tests-ja/src/test/kotlin/tests-jvm-agent.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.coroutines.runBlocking
2 | import kotlinx.coroutines.yield
3 | import kotlin.test.Test
4 |
5 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
6 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
7 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
8 | class CustomClassLoaderTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTailCallDeoptimizedTest()
9 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
10 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
11 | class JvmTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTailCallDeoptimizedTest()
12 |
13 | // Jacoco only instruments this class
14 | class JacocoInstrumentedMethodTest {
15 | @Test
16 | fun jacocoInstrumentedMethodTest(): Unit = runBlocking {
17 | suspend fun jacocoInstrumentedMethod() {
18 | yield()
19 | yield()
20 | }
21 | jacocoInstrumentedMethod()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/intrinsics/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.ChangeClassNameProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | //noinspection UseTomlInstead
15 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
16 | }
17 |
18 | java {
19 | sourceCompatibility = JavaVersion.VERSION_1_8
20 | targetCompatibility = JavaVersion.VERSION_1_8
21 | }
22 |
23 | kotlin {
24 | compilerOptions {
25 | jvmTarget = JvmTarget.JVM_1_8
26 | }
27 | }
28 |
29 | sourceSets {
30 | main {
31 | kotlin.destinationDirectory = java.destinationDirectory
32 | }
33 | test {
34 | kotlin.destinationDirectory = java.destinationDirectory
35 | }
36 | }
37 |
38 | bytecodeProcessor {
39 | processors = listOf(
40 | ChangeClassNameProcessor
41 | )
42 | skipUpdate = true
43 | }
44 |
45 | val kotlinSources = sourceSets.main.get().kotlin
46 | kotlinSources.srcDirs("../../../intrinsics/src/main/kotlin")
47 |
--------------------------------------------------------------------------------
/jvm-agent/jdk8-tests-ja/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2 |
3 | plugins {
4 | kotlin("jvm")
5 | jacoco
6 | }
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 | testImplementation(project(":test-utils"))
14 | testImplementation(project(":test-utils-jvm"))
15 | testImplementation(kotlin("test"))
16 | testImplementation(libs.kotlinx.coroutines.jdk8.build)
17 | testImplementation(project(":stacktrace-decoroutinator-jvm-agent", configuration = "shadow"))
18 | }
19 |
20 | tasks.test {
21 | useJUnitPlatform()
22 | val shadowJarTask = project(":stacktrace-decoroutinator-jvm-agent").tasks.named("shadowJar")
23 | dependsOn(shadowJarTask)
24 | val agentJar = shadowJarTask.get().outputs.files.singleFile
25 | jvmArgs(
26 | "-javaagent:${agentJar.absolutePath}",
27 | "-Ddev.reformator.stacktracedecoroutinator.jvmAgentDebugMetadataInfoResolveStrategy=SYSTEM_RESOURCE"
28 | )
29 | extensions.configure(JacocoTaskExtension::class) {
30 | includes = listOf("JacocoInstrumentedMethodTest*")
31 | }
32 | }
33 |
34 | kotlin {
35 | jvmToolchain(8)
36 | }
37 |
--------------------------------------------------------------------------------
/mh-invoker/src/main/kotlin/internal/unknown.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:AndroidKeep
3 |
4 | package dcunknown
5 |
6 | import dev.reformator.bytecodeprocessor.intrinsics.GetOwnerClass
7 | import dev.reformator.bytecodeprocessor.intrinsics.fail
8 | import dev.reformator.stacktracedecoroutinator.common.internal.specMethodType
9 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorSpec
10 | import dev.reformator.stacktracedecoroutinator.provider.internal.AndroidKeep
11 | import java.lang.invoke.MethodHandle
12 | import java.lang.invoke.MethodHandles
13 |
14 | internal val unknownSpecClass: Class<*>
15 | @GetOwnerClass get() = fail()
16 |
17 | @Suppress("unused")
18 | private fun unknown(spec: DecoroutinatorSpec, result: Any?): Any? {
19 | val updatedResult = if (!spec.isLastSpec) {
20 | spec.nextSpecHandle.invokeExact(spec.nextSpec, result)
21 | } else {
22 | result
23 | }
24 | return spec.resumeNext(updatedResult)
25 | }
26 |
27 | internal fun getUnknownSpecMethodHandle(): MethodHandle =
28 | MethodHandles.lookup().findStatic(
29 | unknownSpecClass,
30 | ::unknown.name,
31 | specMethodType
32 | )
33 |
--------------------------------------------------------------------------------
/gradle-plugin/embedded-debug-probes-xcoroutines/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.DeleteClassProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | bytecodeProcessor {
10 | processors = setOf(
11 | DeleteClassProcessor
12 | )
13 | }
14 |
15 | repositories {
16 | mavenCentral()
17 | }
18 |
19 | dependencies {
20 | //noinspection UseTomlInstead
21 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
22 | compileOnly(project(":gradle-plugin:embedded-debug-probes-stdlib"))
23 |
24 | implementation(project(":stacktrace-decoroutinator-runtime-settings"))
25 | }
26 |
27 | java {
28 | sourceCompatibility = JavaVersion.VERSION_1_9
29 | targetCompatibility = JavaVersion.VERSION_1_9
30 | }
31 |
32 | kotlin {
33 | compilerOptions {
34 | jvmTarget = JvmTarget.JVM_1_8
35 | }
36 | }
37 |
38 | sourceSets {
39 | main {
40 | kotlin.destinationDirectory = java.destinationDirectory
41 | }
42 | test {
43 | kotlin.destinationDirectory = java.destinationDirectory
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "latest-kotlin-kmp-gradle-plugin-test"
2 |
3 | includeBuild("../../_plugins/gradle-plugin-test")
4 | includeBuild("../../_plugins/bytecode-processor")
5 |
6 | pluginManagement {
7 | includeBuild("../../_plugins/gradle-plugin-test")
8 | includeBuild("../../_plugins/bytecode-processor")
9 | repositories {
10 | google {
11 | mavenContent {
12 | includeGroupAndSubgroups("androidx")
13 | includeGroupAndSubgroups("com.android")
14 | includeGroupAndSubgroups("com.google")
15 | }
16 | }
17 | mavenCentral()
18 | gradlePluginPortal()
19 | }
20 | }
21 |
22 | dependencyResolutionManagement {
23 | versionCatalogs {
24 | create("libs") {
25 | from(files("../../gradle/libs.versions.toml"))
26 | }
27 | }
28 | repositories {
29 | google {
30 | mavenContent {
31 | includeGroupAndSubgroups("androidx")
32 | includeGroupAndSubgroups("com.android")
33 | includeGroupAndSubgroups("com.google")
34 | }
35 | }
36 | mavenCentral()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/provider/src/main/kotlin/internal/utils-provider.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.provider.internal
2 |
3 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorSpec
4 | import java.lang.invoke.MethodHandle
5 |
6 | val specLineNumberMethodName: String = DecoroutinatorSpec::class.java.methods
7 | .find { it.returnType == Int::class.javaPrimitiveType }!!
8 | .name
9 |
10 | val isLastSpecMethodName: String = DecoroutinatorSpec::class.java.methods
11 | .find { it.returnType == Boolean::class.javaPrimitiveType }!!
12 | .name
13 |
14 | @Suppress("NewApi")
15 | val nextSpecHandleMethodName: String = DecoroutinatorSpec::class.java.methods
16 | .find { it.returnType == MethodHandle::class.java }!!
17 | .name
18 |
19 | val nextSpecMethodName: String = DecoroutinatorSpec::class.java.methods
20 | .find { it.returnType == DecoroutinatorSpec::class.java }!!
21 | .name
22 |
23 | val resumeNextMethodName: String = DecoroutinatorSpec::class.java.methods
24 | .find { it.returnType == Object::class.java && it.parameterCount == 1 }!!
25 | .name
26 |
27 | @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
28 | val String.internalName: String
29 | get() = (this as java.lang.String).replace('.', '/')
30 |
--------------------------------------------------------------------------------
/generator-jvm/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.AnnotationMetadataResolver;
2 | import dev.reformator.stacktracedecoroutinator.generatorjvm.internal.GeneratorJvmSpecMethodsFactory;
3 | import dev.reformator.stacktracedecoroutinator.common.internal.SpecMethodsFactory;
4 | import dev.reformator.stacktracedecoroutinator.generatorjvm.internal.AnnotationMetadataResolverImpl;
5 |
6 | module dev.reformator.stacktracedecoroutinator.generatorjvm {
7 | requires static dev.reformator.bytecodeprocessor.intrinsics;
8 | requires static intrinsics;
9 |
10 | requires kotlin.stdlib;
11 | requires org.objectweb.asm.tree;
12 | requires dev.reformator.stacktracedecoroutinator.provider;
13 | requires dev.reformator.stacktracedecoroutinator.common;
14 | requires dev.reformator.stacktracedecoroutinator.specmethodbuilder;
15 |
16 | exports dev.reformator.stacktracedecoroutinator.generatorjvm.internal to
17 | dev.reformator.stacktracedecoroutinator.jvmagentcommon,
18 | dev.reformator.stacktracedecoroutinator.generator.tests;
19 |
20 | provides SpecMethodsFactory with GeneratorJvmSpecMethodsFactory;
21 | provides AnnotationMetadataResolver with AnnotationMetadataResolverImpl;
22 | }
23 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/src/test/kotlin/last-kotlin-gradle-plugin-test.kt:
--------------------------------------------------------------------------------
1 | import kotlinx.coroutines.ExperimentalCoroutinesApi
2 | import kotlinx.coroutines.debug.DebugProbes
3 | import kotlinx.coroutines.runBlocking
4 | import kotlinx.coroutines.suspendCancellableCoroutine
5 | import org.junit.jupiter.api.Assertions.assertTrue
6 | import org.junit.jupiter.api.Test
7 | import kotlin.coroutines.resume
8 |
9 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
10 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
11 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest()
12 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
13 | class JvmTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTailCallDeoptimizedTest()
14 |
15 | @OptIn(ExperimentalCoroutinesApi::class)
16 | class DebugProbesTest {
17 | @Test
18 | fun performDebugProbes() {
19 | runBlocking {
20 | suspendCancellableCoroutine { continuation ->
21 | assertTrue(DebugProbes.dumpCoroutinesInfo().isNotEmpty())
22 | continuation.resume(Unit)
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/jvm/jdk8-tests-j/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | kotlin("jvm")
3 | jacoco
4 | }
5 |
6 | repositories {
7 | mavenCentral()
8 | }
9 |
10 | dependencies {
11 | testImplementation(project(":stacktrace-decoroutinator-provider"))
12 | testImplementation(project(":stacktrace-decoroutinator-jvm"))
13 | testImplementation(libs.kotlinx.coroutines.jdk8.build)
14 | testImplementation(kotlin("test"))
15 | testImplementation(project(":test-utils"))
16 | testImplementation(project(":test-utils-jvm"))
17 |
18 | testCompileOnly(project(":intrinsics"))
19 | }
20 |
21 | tasks.test {
22 | useJUnitPlatform()
23 | extensions.configure(JacocoTaskExtension::class) {
24 | includes = listOf("JacocoInstrumentedMethodTest*")
25 | }
26 | systemProperty("testReloadBaseConfiguration", false)
27 | }
28 |
29 | val testReloadBaseConfigurationTask = tasks.register("testReloadBaseConfiguration") {
30 | useJUnitPlatform()
31 | classpath = tasks.test.get().classpath
32 | extensions.configure(JacocoTaskExtension::class) {
33 | excludes = listOf("*")
34 | }
35 | systemProperty("testReloadBaseConfiguration", true)
36 | }
37 | tasks.test.get().dependsOn(testReloadBaseConfigurationTask)
38 |
39 | kotlin {
40 | jvmToolchain(8)
41 | }
42 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-stub/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | id("dev.reformator.forcevariantjavaversion")
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | compileOnly(project(":intrinsics"))
16 | implementation(project(":stacktrace-decoroutinator-provider"))
17 | }
18 |
19 | bytecodeProcessor {
20 | dependentProjects = listOf(
21 | project(":intrinsics"),
22 | project(":stacktrace-decoroutinator-provider")
23 | )
24 | processors = listOf(
25 | ChangeClassNameProcessor
26 | )
27 | }
28 |
29 | java {
30 | sourceCompatibility = JavaVersion.VERSION_1_9
31 | targetCompatibility = JavaVersion.VERSION_1_9
32 | }
33 |
34 | tasks.withType {
35 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
36 | }
37 |
38 | kotlin {
39 | compilerOptions {
40 | jvmTarget = JvmTarget.JVM_1_8
41 | freeCompilerArgs.add("-Xjvm-default=all")
42 | }
43 | }
44 |
45 | sourceSets {
46 | main {
47 | kotlin.destinationDirectory = java.destinationDirectory
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/gradle-plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | kotlin("jvm")
5 | alias(libs.plugins.gradle.plugin.publish)
6 | }
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 | implementation(libs.kotlin.gradle.plugin.api)
14 | api(project(":bytecode-processor-api"))
15 | api(project(":bytecode-processor-plugins"))
16 | implementation(libs.asm.utils)
17 | implementation(libs.jackson.core)
18 | implementation(libs.jackson.kotlin)
19 | testImplementation(kotlin("test"))
20 | }
21 |
22 | tasks.test {
23 | useJUnitPlatform()
24 | }
25 |
26 | java {
27 | sourceCompatibility = JavaVersion.VERSION_1_8
28 | targetCompatibility = JavaVersion.VERSION_1_8
29 | }
30 |
31 | tasks.withType {
32 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
33 | }
34 |
35 | kotlin {
36 | compilerOptions {
37 | jvmTarget = JvmTarget.JVM_1_8
38 | }
39 | }
40 |
41 | gradlePlugin {
42 | plugins {
43 | create("bytecodeProcessor") {
44 | id = "dev.reformator.bytecodeprocessor"
45 | implementationClass = "dev.reformator.bytecodeprocessor.gradleplugin.BytecodeProcessorPlugin"
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/gradle-plugin/aar-builder/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.GetCurrentFileNameProcessor
2 | import dev.reformator.bytecodeprocessor.plugins.GetOwnerClassProcessor
3 |
4 | plugins {
5 | alias(libs.plugins.android.library)
6 | kotlin("android")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | google()
13 | }
14 |
15 | dependencies {
16 | //noinspection UseTomlInstead
17 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
18 | }
19 |
20 | bytecodeProcessor {
21 | processors = listOf(
22 | GetOwnerClassProcessor,
23 | GetCurrentFileNameProcessor
24 | )
25 | }
26 |
27 | android {
28 | namespace = "dev.reformator.stacktracedecoroutinator.aarbuilder"
29 | compileSdk = 36
30 | defaultConfig {
31 | minSdk = 26
32 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
33 | }
34 | packaging {
35 | resources.pickFirsts.add("META-INF/*")
36 | resources.excludes.add("win32-x86-64/attach_hotspot_windows.dll")
37 | resources.excludes.add("win32-x86/attach_hotspot_windows.dll")
38 | resources.excludes.add("META-INF/licenses/*")
39 | }
40 | kotlin {
41 | jvmToolchain(8)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test-utils-jvm/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | id("dev.reformator.forcevariantjavaversion")
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | //noinspection UseTomlInstead
16 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
17 |
18 | implementation(libs.junit5.api)
19 | implementation(libs.kotlinx.coroutines.jdk8.build)
20 | implementation(libs.kotlin.logging.jvm)
21 |
22 | runtimeOnly(libs.logback.classic)
23 | }
24 |
25 | bytecodeProcessor {
26 | processors = setOf(
27 | GetCurrentFileNameProcessor,
28 | GetOwnerClassProcessor
29 | )
30 | }
31 |
32 | java {
33 | sourceCompatibility = JavaVersion.VERSION_1_9
34 | targetCompatibility = JavaVersion.VERSION_1_9
35 | }
36 |
37 | tasks.withType {
38 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
39 | }
40 |
41 | kotlin {
42 | compilerOptions {
43 | jvmTarget = JvmTarget.JVM_1_8
44 | freeCompilerArgs.add("-Xjvm-default=all")
45 | }
46 | }
47 |
48 | sourceSets {
49 | main {
50 | kotlin.destinationDirectory = java.destinationDirectory
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/main/kotlin/internal/di-jvm-agent-common.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal
4 |
5 | import dev.reformator.stacktracedecoroutinator.runtimesettings.DecoroutinatorMetadataInfoResolveStrategy
6 | import dev.reformator.stacktracedecoroutinator.runtimesettings.internal.getRuntimeSettingsValue
7 |
8 | internal val isBaseContinuationRedefinitionAllowed =
9 | getRuntimeSettingsValue({ isBaseContinuationRedefinitionAllowed }) {
10 | System.getProperty(
11 | "dev.reformator.stacktracedecoroutinator.isBaseContinuationRedefinitionAllowed",
12 | "true"
13 | ).toBoolean()
14 | }
15 |
16 | internal val isRedefinitionAllowed =
17 | getRuntimeSettingsValue({ isRedefinitionAllowed }) {
18 | System.getProperty(
19 | "dev.reformator.stacktracedecoroutinator.isRedefinitionAllowed",
20 | "false"
21 | ).toBoolean()
22 | }
23 |
24 | internal val metadataInfoResolveStrategy =
25 | getRuntimeSettingsValue({ metadataInfoResolveStrategy }) {
26 | DecoroutinatorMetadataInfoResolveStrategy.valueOf(System.getProperty(
27 | "dev.reformator.stacktracedecoroutinator.metadataInfoResolveStrategy",
28 | DecoroutinatorMetadataInfoResolveStrategy.SYSTEM_RESOURCE_AND_CLASS.name
29 | ))
30 | }.resolveFunction
31 |
--------------------------------------------------------------------------------
/generator-jvm/android-wrong-generator-tests/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.library)
3 | kotlin("android")
4 | id("decoroutinatorTransformBaseContinuation")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | google()
10 | }
11 |
12 | android {
13 | namespace = "dev.reformator.stacktracedecoroutinator.generatorjvm.androidwronggeneratortests"
14 | compileSdk = 36
15 | defaultConfig {
16 | minSdk = 14
17 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18 | }
19 | packaging {
20 | resources.pickFirsts.add("META-INF/*")
21 | }
22 | kotlin {
23 | jvmToolchain(8)
24 | }
25 | }
26 |
27 | dependencies {
28 | androidTestImplementation(project(":stacktrace-decoroutinator-common"))
29 | androidTestImplementation(libs.kotlinx.coroutines.jdk8.build)
30 | androidTestImplementation(libs.junit4)
31 |
32 | androidTestRuntimeOnly(libs.androidx.test.runner)
33 | androidTestRuntimeOnly(project(":test-utils:base-continuation-accessor-reflect-stub"))
34 | androidTestRuntimeOnly(project(":stacktrace-decoroutinator-mh-invoker-android"))
35 | androidTestRuntimeOnly(project(":stacktrace-decoroutinator-generator-jvm"))
36 | }
37 |
38 | afterEvaluate {
39 | configurations["debugAndroidTestRuntimeClasspath"].attributes.attribute(decoroutinatorTransformedBaseContinuationAttribute, true)
40 | }
41 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/provider/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.*
2 | import dev.reformator.bytecodeprocessor.plugins.GetOwnerClassProcessor
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | kotlin("jvm")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | //noinspection UseTomlInstead
16 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
17 |
18 | testImplementation(kotlin("test"))
19 | }
20 |
21 | bytecodeProcessor {
22 | processors = listOf(
23 | RemoveKotlinStdlibProcessor,
24 | GetOwnerClassProcessor,
25 | LoadConstantProcessor
26 | )
27 | }
28 |
29 | tasks.test {
30 | useJUnitPlatform()
31 | }
32 |
33 | java {
34 | sourceCompatibility = JavaVersion.VERSION_1_8
35 | targetCompatibility = JavaVersion.VERSION_1_8
36 | }
37 |
38 | tasks.withType {
39 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
40 | }
41 |
42 | kotlin {
43 | compilerOptions {
44 | jvmTarget = JvmTarget.JVM_1_8
45 | }
46 | }
47 |
48 | sourceSets {
49 | main {
50 | kotlin.destinationDirectory = java.destinationDirectory
51 | }
52 | }
53 |
54 | val kotlinSources = sourceSets.main.get().kotlin
55 | kotlinSources.srcDirs("../../../provider/src/main/kotlin")
56 |
--------------------------------------------------------------------------------
/generator-jvm/src/test/kotlin/printSpecMethod.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package printspecmethod
4 |
5 | import dev.reformator.stacktracedecoroutinator.specmethodbuilder.internal.buildSpecMethodNode
6 | import org.objectweb.asm.ClassReader
7 | import org.objectweb.asm.ClassWriter
8 | import org.objectweb.asm.Opcodes
9 | import org.objectweb.asm.Type
10 | import org.objectweb.asm.tree.*
11 | import org.objectweb.asm.util.TraceClassVisitor
12 | import java.io.PrintWriter
13 |
14 | fun main() {
15 | val classNode = ClassNode(Opcodes.ASM9).apply {
16 | version = Opcodes.V1_8
17 | access = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
18 | name = "dev/reformator/stacktracedecoroutinator/jvmcommon/StacktraceMethodPrinter"
19 | superName = Type.getInternalName(java.lang.Object::class.java)
20 | sourceFile = "internal/unknown.kt"
21 | }
22 | classNode.methods = mutableListOf(buildSpecMethodNode(
23 | methodName = "stacktraceMethod",
24 | lineNumbers = setOf(10, 20, 25, 30),
25 | makePrivate = true,
26 | makeFinal = true
27 | ))
28 |
29 | val classWriter = ClassWriter(ClassWriter.COMPUTE_FRAMES)
30 | classNode.accept(classWriter)
31 | val classReader = ClassReader(classWriter.toByteArray())
32 |
33 | PrintWriter(System.out.writer()).use {
34 | classReader.accept(TraceClassVisitor(it), 0)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/generator-jvm/src/main/kotlin/internal/specMethodsFactory-generator.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.generatorjvm.internal
4 |
5 | import dev.reformator.stacktracedecoroutinator.common.internal.*
6 | import java.lang.invoke.MethodHandle
7 | import java.util.concurrent.CopyOnWriteArrayList
8 |
9 | internal class GeneratorJvmSpecMethodsFactory: BaseSpecMethodsFactory() {
10 | init {
11 | //assert the platform
12 | DecoroutinatorClassLoader().buildClassAndGetSpecHandlesByMethod(
13 | className = "stub",
14 | fileName = "unknown",
15 | lineNumbersByMethod = emptyMap()
16 | )
17 | }
18 |
19 | override fun generateSpecMethodHandles(
20 | className: String,
21 | classRevision: Int,
22 | fileName: String?,
23 | lineNumbersByMethod: Map>
24 | ): Map {
25 | while (loadersByRevision.size <= classRevision) loadersByRevision.add(DecoroutinatorClassLoader())
26 | val loader = loadersByRevision[classRevision]
27 | return loader.buildClassAndGetSpecHandlesByMethod(
28 | className = className,
29 | fileName = fileName,
30 | lineNumbersByMethod = lineNumbersByMethod
31 | )
32 | }
33 |
34 | private val loadersByRevision: MutableList = CopyOnWriteArrayList()
35 | }
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidInstrumentedTest/kotlin/tests-last-kotlin-kmp-gradle-plugin-android.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
2 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
3 | import dev.reformator.stacktracedecoroutinator.test.checkStacktrace
4 | import kotlinx.coroutines.runBlocking
5 | import kotlinx.coroutines.yield
6 | import org.junit.Test
7 |
8 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
9 |
10 | class TestLocalFile {
11 | @Test
12 | fun localTest(): Unit = runBlocking {
13 | fun1()
14 | }
15 |
16 | suspend fun fun1() {
17 | fun2(currentLineNumber)
18 | }
19 |
20 | suspend fun fun2(fun1LineNumber: Int) {
21 | val fun1Frame = StackTraceElement(
22 | TestLocalFile::class.qualifiedName,
23 | ::fun1.name,
24 | currentFileName,
25 | fun1LineNumber
26 | )
27 | yield()
28 | fun3(fun1Frame, currentLineNumber)
29 | }
30 |
31 | suspend fun fun3(fun1Frame: StackTraceElement, fun2LineNumber: Int) {
32 | val fun2Frame = StackTraceElement(
33 | TestLocalFile::class.qualifiedName,
34 | ::fun2.name,
35 | currentFileName,
36 | fun2LineNumber
37 | )
38 | yield()
39 | checkStacktrace(fun2Frame, fun1Frame)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidUnitTest/kotlin/tests-last-kotlin-kmp-gradle-plugin-android-unit-test.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
2 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
3 | import dev.reformator.stacktracedecoroutinator.test.checkStacktrace
4 | import kotlinx.coroutines.runBlocking
5 | import kotlinx.coroutines.yield
6 | import org.junit.Test
7 |
8 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
9 |
10 | class TestLocalFile {
11 | @Test
12 | fun localTest(): Unit = runBlocking {
13 | fun1()
14 | }
15 |
16 | suspend fun fun1() {
17 | fun2(currentLineNumber)
18 | }
19 |
20 | suspend fun fun2(fun1LineNumber: Int) {
21 | val fun1Frame = StackTraceElement(
22 | TestLocalFile::class.qualifiedName,
23 | ::fun1.name,
24 | currentFileName,
25 | fun1LineNumber
26 | )
27 | yield()
28 | fun3(fun1Frame, currentLineNumber)
29 | }
30 |
31 | suspend fun fun3(fun1Frame: StackTraceElement, fun2LineNumber: Int) {
32 | val fun2Frame = StackTraceElement(
33 | TestLocalFile::class.qualifiedName,
34 | ::fun2.name,
35 | currentFileName,
36 | fun2LineNumber
37 | )
38 | yield()
39 | checkStacktrace(fun2Frame, fun1Frame)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/jvm/src/main/kotlin/api-jvm.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.jvm
4 |
5 | import dev.reformator.stacktracedecoroutinator.intrinsics.BASE_CONTINUATION_CLASS_NAME
6 | import dev.reformator.stacktracedecoroutinator.jvm.internal.isTransformed
7 | import dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal.addDecoroutinatorTransformer
8 | import net.bytebuddy.agent.ByteBuddyAgent
9 | import java.util.concurrent.locks.ReentrantLock
10 | import kotlin.concurrent.withLock
11 |
12 | object DecoroutinatorJvmApi {
13 | fun install() {
14 | lock.withLock {
15 | if (!initialized) {
16 | val inst = ByteBuddyAgent.install()
17 | addDecoroutinatorTransformer(inst)
18 | initialized = true
19 | }
20 | }
21 | val baseContinuation = Class.forName(BASE_CONTINUATION_CLASS_NAME)
22 | if (!baseContinuation.isTransformed) {
23 | ByteBuddyAgent.install().retransformClasses(baseContinuation)
24 | }
25 | if (!baseContinuation.isTransformed) {
26 | error("Cannot install Decoroutinator runtime " +
27 | "because class [$BASE_CONTINUATION_CLASS_NAME] is already loaded " +
28 | "and class retransformations is not allowed.")
29 | }
30 | }
31 |
32 | private val lock = ReentrantLock()
33 | private var initialized = false
34 | }
35 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/base-continuation-accessor/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.ChangeClassNameProcessor
2 | import dev.reformator.bytecodeprocessor.plugins.LoadConstantProcessor
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | kotlin("jvm")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | bytecodeProcessor {
11 | dependentProjects = listOf(
12 | project(":intrinsics")
13 | )
14 | processors = listOf(
15 | LoadConstantProcessor,
16 | ChangeClassNameProcessor
17 | )
18 | }
19 |
20 | repositories {
21 | mavenCentral()
22 | }
23 |
24 | dependencies {
25 | //noinspection UseTomlInstead
26 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
27 | compileOnly(project(":provider"))
28 | compileOnly(project(":intrinsics"))
29 | }
30 |
31 | java {
32 | sourceCompatibility = JavaVersion.VERSION_1_8
33 | targetCompatibility = JavaVersion.VERSION_1_8
34 | }
35 |
36 | kotlin {
37 | compilerOptions {
38 | jvmTarget = JvmTarget.JVM_1_8
39 | freeCompilerArgs.add("-Xallow-kotlin-package")
40 | }
41 | }
42 |
43 | val kotlinSources = sourceSets.main.get().kotlin
44 | val resourcesSources = sourceSets.main.get().resources
45 | kotlinSources.srcDirs("../../../gradle-plugin/base-continuation-accessor/src/main/kotlin")
46 | resourcesSources.srcDirs("../../../gradle-plugin/base-continuation-accessor/src/main/resources")
47 |
--------------------------------------------------------------------------------
/_plugins/gradle-plugin-test/embedded-debug-probes-xcoroutines/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.DeleteClassProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | bytecodeProcessor {
10 | processors = setOf(
11 | DeleteClassProcessor
12 | )
13 | }
14 |
15 | repositories {
16 | mavenCentral()
17 | }
18 |
19 | dependencies {
20 | //noinspection UseTomlInstead
21 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
22 | compileOnly(project(":runtime-settings"))
23 | compileOnly(project(":embedded-debug-probes-stdlib"))
24 | }
25 |
26 | java {
27 | sourceCompatibility = JavaVersion.VERSION_1_8
28 | targetCompatibility = JavaVersion.VERSION_1_8
29 | }
30 |
31 | kotlin {
32 | compilerOptions {
33 | jvmTarget = JvmTarget.JVM_1_8
34 | }
35 | }
36 |
37 | sourceSets {
38 | main {
39 | kotlin.destinationDirectory = java.destinationDirectory
40 | }
41 | test {
42 | kotlin.destinationDirectory = java.destinationDirectory
43 | }
44 | }
45 |
46 | val kotlinSources = sourceSets.main.get().kotlin
47 | val resourcesSources = sourceSets.main.get().resources
48 | kotlinSources.srcDirs("../../../gradle-plugin/embedded-debug-probes-xcoroutines/src/main/kotlin")
49 | resourcesSources.srcDirs("../../../gradle-plugin/embedded-debug-probes-xcoroutines/src/main/resources")
50 |
--------------------------------------------------------------------------------
/generator-jvm/src/test/kotlin/showResumeWithAppendix.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.provider.internal.awakeBaseContinuation
2 | import dev.reformator.stacktracedecoroutinator.provider.internal.baseContinuationAccessor
3 | import dev.reformator.stacktracedecoroutinator.provider.internal.getElementFactoryStacktraceElement
4 | import dev.reformator.stacktracedecoroutinator.provider.internal.prepareBaseContinuationAccessor
5 | import dev.reformator.stacktracedecoroutinator.provider.isDecoroutinatorEnabled
6 | import dev.reformator.stacktracedecoroutinator.provider.isUsingElementFactoryForBaseContinuationEnabled
7 | import org.junit.jupiter.api.Assertions.fail
8 | import java.lang.invoke.MethodHandles
9 |
10 | class BaseContinuation
11 |
12 | @Suppress("unused")
13 | fun BaseContinuation.resumeWith(result: Any?) {
14 | if (isDecoroutinatorEnabled) {
15 | awakeBaseContinuation(
16 | accessor = baseContinuationAccessor ?: prepareBaseContinuationAccessor(MethodHandles.lookup()),
17 | baseContinuation = this,
18 | result =result
19 | )
20 | return
21 | }
22 | default()
23 | }
24 |
25 | @Suppress("unused")
26 | fun BaseContinuation.getStackTraceElement(): StackTraceElement? {
27 | if (isUsingElementFactoryForBaseContinuationEnabled) {
28 | return getElementFactoryStacktraceElement(this)
29 | }
30 | default()
31 | }
32 |
33 | @Suppress("UnusedReceiverParameter")
34 | fun BaseContinuation.default(): Nothing = fail()
35 |
--------------------------------------------------------------------------------
/common/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.common.internal.*;
2 | import dev.reformator.stacktracedecoroutinator.provider.internal.DecoroutinatorProvider;
3 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider;
4 |
5 | module dev.reformator.stacktracedecoroutinator.common {
6 | requires static dev.reformator.bytecodeprocessor.intrinsics;
7 | requires static intrinsics;
8 |
9 | requires kotlin.stdlib;
10 | requires dev.reformator.stacktracedecoroutinator.provider;
11 | requires dev.reformator.stacktracedecoroutinator.runtimesettings;
12 |
13 | exports dev.reformator.stacktracedecoroutinator.common;
14 | exports dev.reformator.stacktracedecoroutinator.common.internal to
15 | dev.reformator.stacktracedecoroutinator.generatorjvm,
16 | dev.reformator.stacktracedecoroutinator.jvmagentcommon,
17 | dev.reformator.stacktracedecoroutinator.jvm,
18 | dev.reformator.stacktracedecoroutinator.generator.tests,
19 | dev.reformator.stacktracedecoroutinator.jvm.tests,
20 | dev.reformator.stacktracedecoroutinator.mhinvoker,
21 | dev.reformator.stacktracedecoroutinator.mhinvokerjvm;
22 |
23 | provides DecoroutinatorProvider with Provider;
24 |
25 | uses SpecMethodsFactory;
26 | uses AnnotationMetadataResolver;
27 | uses MethodHandleInvoker;
28 | uses VarHandleInvoker;
29 | uses BaseContinuationAccessorProvider;
30 | }
31 |
--------------------------------------------------------------------------------
/provider/src/main/kotlin/internal/provider-api-internal.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("DecoroutinatorProviderInternalApiKt")
3 |
4 | package dev.reformator.stacktracedecoroutinator.provider.internal
5 |
6 | import dev.reformator.bytecodeprocessor.intrinsics.GetOwnerClass
7 | import dev.reformator.bytecodeprocessor.intrinsics.MethodNameConstant
8 | import dev.reformator.bytecodeprocessor.intrinsics.fail
9 | import java.lang.invoke.MethodHandles
10 |
11 | val baseContinuationAccessor: BaseContinuationAccessor?
12 | @MethodNameConstant("getBaseContinuationAccessorMethodName") get() = provider.baseContinuationAccessor
13 |
14 | @MethodNameConstant("prepareBaseContinuationAccessorMethodName")
15 | fun prepareBaseContinuationAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor =
16 | provider.prepareBaseContinuationAccessor(lookup)
17 |
18 | @MethodNameConstant("awakeBaseContinuationMethodName")
19 | fun awakeBaseContinuation(accessor: BaseContinuationAccessor, baseContinuation: Any, result: Any?) {
20 | provider.awakeBaseContinuation(
21 | accessor = accessor,
22 | baseContinuation = baseContinuation,
23 | result = result
24 | )
25 | }
26 |
27 | @MethodNameConstant("getElementFactoryStacktraceElementMethodName")
28 | fun getElementFactoryStacktraceElement(baseContinuation: Any): StackTraceElement? =
29 | provider.getElementFactoryStacktraceElement(baseContinuation)
30 |
31 | val providerInternalApiClass: Class<*>
32 | @GetOwnerClass get() { fail() }
33 |
--------------------------------------------------------------------------------
/test-utils-jvm/src/main/kotlin/jvm-test.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.testjvm
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
6 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
7 | import dev.reformator.bytecodeprocessor.intrinsics.ownerClassName
8 | import dev.reformator.bytecodeprocessor.intrinsics.ownerMethodName
9 | import kotlinx.coroutines.runBlocking
10 | import kotlinx.coroutines.yield
11 | import org.junit.jupiter.api.Test
12 |
13 |
14 | open class JvmTest {
15 | @Test
16 | fun `load method with spaces`() = runBlocking {
17 | yield()
18 | }
19 |
20 | @Test
21 | fun `method with spaces`() = runBlocking {
22 | val lineNumber = currentLineNumber + 1
23 | check(StackTraceElement(
24 | ownerClassName,
25 | ownerMethodName,
26 | currentFileName,
27 | lineNumber
28 | ))
29 | tailCallDeoptimize()
30 | }
31 | }
32 |
33 | open class JvmTailCallDeoptimizedTest {
34 | @Test
35 | fun `method with spaces`() = runBlocking {
36 | val lineNumber = currentLineNumber + 1
37 | check(StackTraceElement(
38 | ownerClassName,
39 | ownerMethodName,
40 | currentFileName,
41 | lineNumber
42 | ))
43 | }
44 | }
45 |
46 | private fun tailCallDeoptimize() { }
47 |
48 | private suspend fun check(parent: StackTraceElement) {
49 | yield()
50 | checkStacktrace(parent)
51 | }
52 |
--------------------------------------------------------------------------------
/gradle-plugin/jdk8-tests-gp/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.GetCurrentFileNameProcessor
2 |
3 | plugins {
4 | kotlin("jvm")
5 | id("dev.reformator.stacktracedecoroutinator")
6 | id("dev.reformator.bytecodeprocessor")
7 | }
8 |
9 | stacktraceDecoroutinator {
10 | regularDependencyConfigurations.include = emptySet()
11 | androidDependencyConfigurations.include = emptySet()
12 | jvmDependencyConfigurations.include = emptySet()
13 | addJvmRuntimeDependency = false
14 | useTransformedClassesForCompilation = true
15 | embeddedDebugProbesConfigurations.include = setOf("runtimeClasspath", "testRuntimeClasspath")
16 | }
17 |
18 | repositories {
19 | mavenCentral()
20 | }
21 |
22 | dependencies {
23 | //noinspection UseTomlInstead
24 | testCompileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
25 |
26 | testRuntimeOnly(project(":stacktrace-decoroutinator-common"))
27 | testRuntimeOnly(project(":stacktrace-decoroutinator-mh-invoker"))
28 |
29 | testImplementation(project(":test-utils"))
30 | testImplementation(project(":test-utils-jvm"))
31 | testImplementation(kotlin("test"))
32 | testImplementation(libs.kotlinx.coroutines.jdk8.build)
33 | testImplementation(libs.kotlinx.coroutines.debug.build)
34 | testRuntimeOnly(project(":stacktrace-decoroutinator-runtime-settings"))
35 | }
36 |
37 | bytecodeProcessor {
38 | processors = listOf(
39 | GetCurrentFileNameProcessor
40 | )
41 | }
42 |
43 | tasks.test {
44 | useJUnitPlatform()
45 | }
46 |
47 | kotlin {
48 | jvmToolchain(8)
49 | }
50 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/kotlin/attribute-gradle-plugin.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("AttributeGradlePluginKt")
3 |
4 | package dev.reformator.stacktracedecoroutinator.gradleplugin
5 |
6 | import io.github.oshai.kotlinlogging.KotlinLogging
7 | import org.gradle.api.Plugin
8 | import org.gradle.api.Project
9 | import org.gradle.api.artifacts.type.ArtifactTypeDefinition
10 | import org.gradle.kotlin.dsl.stacktraceDecoroutinatorAttribute
11 |
12 | private val log = KotlinLogging.logger { }
13 |
14 | @Suppress("unused")
15 | class DecoroutinatorAttributePlugin: Plugin {
16 | override fun apply(target: Project) {
17 | log.debug { "applying Decoroutinator attribute plugin to [${target.name}]" }
18 | with (target) {
19 | val pluginExtension = extensions.create(
20 | ::stacktraceDecoroutinatorAttribute.name,
21 | DecoroutinatorAttributePluginExtension::class.java
22 | )
23 | afterEvaluate { _ ->
24 | createUnsetDecoroutinatorTransformedStateAttributeAction(
25 | artifactTypes = pluginExtension.artifactTypesForAttributes
26 | ).execute(target)
27 | }
28 | }
29 | }
30 | }
31 |
32 | open class DecoroutinatorAttributePluginExtension {
33 | var artifactTypesForAttributes = setOf(
34 | ArtifactTypeDefinition.JAR_TYPE,
35 | ArtifactTypeDefinition.JVM_CLASS_DIRECTORY,
36 | ArtifactTypeDefinition.ZIP_TYPE,
37 | "aar",
38 | "android-classes-directory",
39 | "android-classes-jar"
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/commonMain/kotlin/org/example/project/App.kt:
--------------------------------------------------------------------------------
1 | package org.example.project
2 |
3 | import androidx.compose.animation.AnimatedVisibility
4 | import androidx.compose.foundation.Image
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.fillMaxWidth
7 | import androidx.compose.material.Button
8 | import androidx.compose.material.MaterialTheme
9 | import androidx.compose.material.Text
10 | import androidx.compose.runtime.*
11 | import androidx.compose.ui.Alignment
12 | import androidx.compose.ui.Modifier
13 | import latest_kotlin_kmp_gradle_plugin_test.generated.resources.Res
14 | import latest_kotlin_kmp_gradle_plugin_test.generated.resources.compose_multiplatform
15 | import org.jetbrains.compose.resources.painterResource
16 | import org.jetbrains.compose.ui.tooling.preview.Preview
17 |
18 |
19 | @Composable
20 | @Preview
21 | fun App() {
22 | MaterialTheme {
23 | var showContent by remember { mutableStateOf(false) }
24 | Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
25 | Button(onClick = { showContent = !showContent }) {
26 | Text("Click me!")
27 | }
28 | AnimatedVisibility(showContent) {
29 | val greeting = remember { Greeting().greet() }
30 | Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
31 | Image(painterResource(Res.drawable.compose_multiplatform), null)
32 | Text("Compose: $greeting")
33 | }
34 | }
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/intrinsics/src/main/kotlin/intrinsics.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.intrinsics
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.ChangeClassName
6 | import dev.reformator.bytecodeprocessor.intrinsics.fail
7 | import kotlin.coroutines.Continuation
8 | import kotlin.coroutines.jvm.internal.CoroutineStackFrame
9 |
10 | const val BASE_CONTINUATION_CLASS_NAME = "kotlin.coroutines.jvm.internal.BaseContinuationImpl"
11 | const val UNKNOWN_LINE_NUMBER = -1
12 | const val PROVIDER_MODULE_NAME = "dev.reformator.stacktracedecoroutinator.provider"
13 | const val LABEL_FIELD_NAME = "label"
14 |
15 | @ChangeClassName(toName = BASE_CONTINUATION_CLASS_NAME, deleteAfterChanging = true)
16 | abstract class BaseContinuation: Continuation, CoroutineStackFrame {
17 | @Suppress("RedundantNullableReturnType")
18 | val completion: Continuation?
19 | get() { fail() }
20 |
21 | final override fun resumeWith(result: Result) { fail() }
22 |
23 | init { fail() }
24 |
25 | override fun getStackTraceElement(): StackTraceElement? { fail() }
26 |
27 | abstract fun invokeSuspend(result: Any?): Any?
28 |
29 | open fun releaseIntercepted() { fail() }
30 |
31 | override val callerFrame: CoroutineStackFrame?
32 | get() = fail()
33 | }
34 |
35 | @ChangeClassName(
36 | toName = "kotlin.coroutines.jvm.internal.DebugMetadata",
37 | deleteAfterChanging = true
38 | )
39 | @Target(AnnotationTarget.CLASS)
40 | annotation class DebugMetadata(
41 | val f: String = "",
42 | val l: IntArray = [],
43 | val m: String = "",
44 | val c: String = ""
45 | )
46 |
--------------------------------------------------------------------------------
/spec-method-builder/src/main/kotlin/internal/utils-spec-method-builder.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.specmethodbuilder.internal
2 |
3 | import dev.reformator.stacktracedecoroutinator.intrinsics.DebugMetadata
4 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorTransformed
5 | import org.objectweb.asm.ClassReader
6 | import org.objectweb.asm.Opcodes
7 | import org.objectweb.asm.Type
8 | import org.objectweb.asm.tree.AnnotationNode
9 | import org.objectweb.asm.tree.ClassNode
10 | import java.io.InputStream
11 |
12 | fun getClassNode(classBody: InputStream, skipCode: Boolean = false): ClassNode? {
13 | return try {
14 | val classReader = ClassReader(classBody)
15 | val classNode = ClassNode(Opcodes.ASM9)
16 | classReader.accept(classNode, if (skipCode) ClassReader.SKIP_CODE else 0)
17 | classNode
18 | } catch (_: Exception) {
19 | null
20 | }
21 | }
22 |
23 | val ClassNode.decoroutinatorTransformedAnnotation: AnnotationNode?
24 | get() = visibleAnnotations
25 | .orEmpty()
26 | .firstOrNull { it.desc == Type.getDescriptor(DecoroutinatorTransformed::class.java) }
27 |
28 | fun AnnotationNode.getField(name: String): Any? {
29 | var index = 0
30 | while (index < values.orEmpty().size) {
31 | if (values[index] == name) {
32 | return values[index + 1]
33 | }
34 | index += 2
35 | }
36 | return null
37 | }
38 |
39 | val ClassNode.kotlinDebugMetadataAnnotation: AnnotationNode?
40 | get() = visibleAnnotations
41 | .orEmpty()
42 | .firstOrNull { it.desc == Type.getDescriptor(DebugMetadata::class.java) }
43 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/kotlin/gradle-noop-transformer.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.gradleplugin
4 |
5 | import io.github.oshai.kotlinlogging.KotlinLogging
6 | import org.gradle.api.artifacts.transform.CacheableTransform
7 | import org.gradle.api.artifacts.transform.InputArtifact
8 | import org.gradle.api.artifacts.transform.TransformAction
9 | import org.gradle.api.artifacts.transform.TransformOutputs
10 | import org.gradle.api.artifacts.transform.TransformParameters
11 | import org.gradle.api.file.FileSystemLocation
12 | import org.gradle.api.provider.Provider
13 | import org.gradle.api.tasks.PathSensitive
14 | import org.gradle.api.tasks.PathSensitivity
15 |
16 | private val log = KotlinLogging.logger { }
17 |
18 | @CacheableTransform
19 | abstract class DecoroutinatorNoopTransformAction: TransformAction {
20 | @get:InputArtifact
21 | @get:PathSensitive(PathSensitivity.RELATIVE)
22 | abstract val inputArtifact: Provider
23 |
24 | override fun transform(outputs: TransformOutputs) {
25 | val root = inputArtifact.get().asFile
26 | log.debug { "noop transformation for [${root.absolutePath}]" }
27 | if (root.isFile) {
28 | log.debug { "artifact [${root.absolutePath}] is a file" }
29 | outputs.file(inputArtifact)
30 | } else if (root.isDirectory) {
31 | log.debug { "artifact [${root.absolutePath}] is a directory" }
32 | outputs.dir(inputArtifact)
33 | } else {
34 | log.debug { "artifact [${root.absolutePath}] does not exist" }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/test-utils/custom-loader/src/main/kotlin/stub-test-utils-custom-loader.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.test
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
6 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
7 | import dev.reformator.bytecodeprocessor.intrinsics.ownerMethodName
8 | import kotlinx.coroutines.runBlocking
9 | import kotlinx.coroutines.yield
10 |
11 | @Suppress("unused")
12 | class ClassWithSuspendFunctionsStub {
13 | fun performCheck(allowTailCallOptimization: Boolean) {
14 | runBlocking {
15 | if (allowTailCallOptimization) {
16 | tailCallOptimizedCheck()
17 | } else {
18 | basicCheck()
19 | }
20 | }
21 | }
22 |
23 | suspend fun tailCallOptimizedCheck() {
24 | val lineNumber = currentLineNumber + 1
25 | check(StackTraceElement(
26 | ClassWithSuspendFunctionsStub::class.java.name,
27 | ownerMethodName,
28 | currentFileName,
29 | lineNumber
30 | ))
31 | tailCallDeoptimizer()
32 | }
33 |
34 | suspend fun basicCheck() {
35 | val lineNumber = currentLineNumber + 1
36 | check(StackTraceElement(
37 | ClassWithSuspendFunctionsStub::class.java.name,
38 | ownerMethodName,
39 | currentFileName,
40 | lineNumber
41 | ))
42 | }
43 |
44 | suspend fun check(parentFrame: StackTraceElement) {
45 | yield()
46 | checkStacktrace(parentFrame)
47 | }
48 |
49 | private fun tailCallDeoptimizer() { }
50 | }
51 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/api/src/main/kotlin/asm-plugin-api.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.api
4 |
5 | import org.objectweb.asm.tree.ClassNode
6 | import org.objectweb.asm.tree.ModuleNode
7 |
8 | interface ProcessingClass {
9 | val node: ClassNode
10 | fun markModified()
11 | fun delete()
12 | }
13 |
14 | interface ProcessingModule {
15 | val node: ModuleNode
16 | fun markModified()
17 | }
18 |
19 | interface ProcessingDirectory {
20 | val classes: Sequence
21 | val module: ProcessingModule?
22 | }
23 |
24 | interface BytecodeProcessorContext {
25 | interface Key {
26 | val id: String
27 | val default: T
28 | fun merge(value1: T, value2: T): T
29 | }
30 |
31 | operator fun get(key: Key): T
32 |
33 | fun merge(key: Key, value: T): T
34 | }
35 |
36 | @JvmInline
37 | value class BytecodeProcessorContextImpl private constructor(
38 | val values: MutableMap
39 | ): BytecodeProcessorContext {
40 | constructor(): this(hashMapOf())
41 |
42 | @Suppress("UNCHECKED_CAST")
43 | override fun get(key: BytecodeProcessorContext.Key): T =
44 | values[key.id]?.let { it as T } ?: key.default
45 |
46 | @Suppress("UNCHECKED_CAST")
47 | override fun merge(key: BytecodeProcessorContext.Key, value: T): T =
48 | values.merge(key.id, value) { value1, value2 ->
49 | key.merge(value1 as T, value2 as T)
50 | } as T
51 | }
52 |
53 | fun interface Processor {
54 | fun process(directory: ProcessingDirectory, context: BytecodeProcessorContext)
55 | }
56 |
--------------------------------------------------------------------------------
/jvm-agent/tests-ja/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | jacoco
7 | }
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | testImplementation(project(":test-utils")) {
15 | exclude(module = "stacktrace-decoroutinator-common")
16 | exclude(module = "stacktrace-decoroutinator-provider")
17 | }
18 | testImplementation(project(":test-utils-jvm"))
19 | testImplementation(kotlin("test"))
20 | testImplementation(libs.kotlinx.coroutines.jdk8.build)
21 | testImplementation(project(":stacktrace-decoroutinator-jvm-agent", configuration = "shadow"))
22 | }
23 |
24 | tasks.test {
25 | useJUnitPlatform()
26 | val shadowJarTask = project(":stacktrace-decoroutinator-jvm-agent").tasks.named("shadowJar")
27 | dependsOn(shadowJarTask)
28 | val agentJar = shadowJarTask.get().outputs.files.singleFile
29 | jvmArgs(
30 | "-javaagent:${agentJar.absolutePath}",
31 | "-Ddev.reformator.stacktracedecoroutinator.jvmAgentDebugMetadataInfoResolveStrategy=SYSTEM_RESOURCE"
32 | )
33 | extensions.configure(JacocoTaskExtension::class) {
34 | includes = listOf("JacocoInstrumentedMethodTest*")
35 | }
36 | }
37 |
38 | java {
39 | sourceCompatibility = JavaVersion.VERSION_1_9
40 | targetCompatibility = JavaVersion.VERSION_1_9
41 | }
42 |
43 | kotlin {
44 | compilerOptions {
45 | jvmTarget = JvmTarget.JVM_1_8
46 | }
47 | }
48 |
49 | sourceSets {
50 | main {
51 | kotlin.destinationDirectory = java.destinationDirectory
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-stub/src/main/kotlin/base-continuation-accessor-stub.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub
4 |
5 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
6 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessor
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
8 | import java.lang.invoke.MethodHandles
9 | import java.lang.invoke.MethodType
10 |
11 | class TestBaseContinuationAccessorProviderAccessor: BaseContinuationAccessorProvider {
12 | override fun createAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor {
13 | val invokeSuspendHandle = lookup.findVirtual(
14 | BaseContinuation::class.java,
15 | BaseContinuation::invokeSuspend.name,
16 | MethodType.methodType(Object::class.java, Object::class.java)
17 | )
18 | val releaseInterceptedHandle = lookup.findVirtual(
19 | BaseContinuation::class.java,
20 | BaseContinuation::releaseIntercepted.name,
21 | MethodType.methodType(Void::class.javaPrimitiveType)
22 | )
23 | return object : BaseContinuationAccessor {
24 | override fun invokeSuspend(baseContinuation: Any, result: Any?): Any? =
25 | invokeSuspendHandle.invokeExact(baseContinuation as BaseContinuation, result)
26 |
27 | override fun releaseIntercepted(baseContinuation: Any) {
28 | releaseInterceptedHandle.invokeExact(baseContinuation as BaseContinuation)
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test-utils/base-continuation-accessor-reflect-stub/src/main/kotlin/base-continuation-accessor-reflect-stub.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.test.basecontinuationaccessorstub
4 |
5 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
6 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessor
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
8 | import java.lang.invoke.MethodHandles
9 | import java.lang.reflect.InvocationTargetException
10 |
11 | class TestReflectBaseContinuationAccessorProviderAccessor: BaseContinuationAccessorProvider {
12 | override fun createAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor {
13 | val invokeSuspendMethod = BaseContinuation::class.java.getDeclaredMethod(
14 | BaseContinuation::invokeSuspend.name,
15 | Object::class.java
16 | )
17 | invokeSuspendMethod.isAccessible = true
18 | val releaseInterceptedMethod =
19 | BaseContinuation::class.java.getDeclaredMethod(BaseContinuation::releaseIntercepted.name)
20 | releaseInterceptedMethod.isAccessible = true
21 | return object: BaseContinuationAccessor {
22 | override fun invokeSuspend(baseContinuation: Any, result: Any?): Any? =
23 | try {
24 | invokeSuspendMethod.invoke(baseContinuation, result)
25 | } catch (e: InvocationTargetException) {
26 | e.cause?.let { throw it }
27 | throw e
28 | }
29 |
30 | override fun releaseIntercepted(baseContinuation: Any) {
31 | releaseInterceptedMethod.invoke(baseContinuation)
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/mh-invoker-android/src/main/kotlin/mh-invoker-android.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("MhInvokerAndroidKt")
3 |
4 | package dev.reformator.stacktracedecoroutinator.mhinvokerandroid
5 |
6 | import android.util.Base64
7 | import dev.reformator.bytecodeprocessor.intrinsics.LoadConstant
8 | import dev.reformator.bytecodeprocessor.intrinsics.fail
9 | import dalvik.system.InMemoryDexClassLoader
10 | import dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
11 | import dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker
12 | import java.nio.ByteBuffer
13 |
14 | internal class AndroidMethodHandleInvoker: MethodHandleInvoker by loadRegularMethodHandleInvoker()
15 |
16 | internal class AndroidVarHandleInvoker: VarHandleInvoker by loadRegularVarHandleInvoker()
17 |
18 | private val regularMethodHandleDexBase64: String
19 | @LoadConstant("regularMethodHandleDexBase64") get() { fail() }
20 |
21 | private val String.decodeBase64: ByteArray
22 | get() = Base64.decode(this, Base64.DEFAULT)
23 |
24 | @Suppress("NewApi")
25 | private val regularMethodHandleLoader = InMemoryDexClassLoader(
26 | ByteBuffer.wrap(regularMethodHandleDexBase64.decodeBase64),
27 | MethodHandleInvoker::class.java.classLoader
28 | )
29 |
30 | private fun loadRegularMethodHandleInvoker(): MethodHandleInvoker =
31 | regularMethodHandleLoader.loadClass("dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularMethodHandleInvoker")
32 | .getDeclaredConstructor()
33 | .newInstance() as MethodHandleInvoker
34 |
35 | private fun loadRegularVarHandleInvoker(): VarHandleInvoker =
36 | regularMethodHandleLoader.loadClass("dev.reformator.stacktracedecoroutinator.mhinvoker.internal.RegularVarHandleInvoker")
37 | .getDeclaredConstructor()
38 | .newInstance() as VarHandleInvoker
39 |
--------------------------------------------------------------------------------
/runtime-settings/src/main/kotlin/runtime-settings.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.runtimesettings
4 |
5 | import dev.reformator.stacktracedecoroutinator.runtimesettings.internal.defaultValue
6 |
7 | interface DecoroutinatorRuntimeSettingsProvider {
8 | //Common settings
9 |
10 | val enabled: Boolean
11 | get() = defaultValue()
12 |
13 | val recoveryExplicitStacktrace: Boolean
14 | get() = defaultValue()
15 |
16 | val recoveryExplicitStacktraceTimeoutMs: UInt
17 | get() = defaultValue()
18 |
19 | val tailCallDeoptimize: Boolean
20 | get() = defaultValue()
21 |
22 | val methodsNumberThreshold: Int
23 | get() = defaultValue()
24 |
25 | val fillUnknownElementsWithClassName: Boolean
26 | get() = defaultValue()
27 |
28 | val isUsingElementFactoryForBaseContinuationEnabled: Boolean
29 | get() = defaultValue()
30 |
31 | // JVM Agent settings
32 |
33 | val metadataInfoResolveStrategy: DecoroutinatorMetadataInfoResolveStrategy
34 | get() = defaultValue()
35 |
36 | val isBaseContinuationRedefinitionAllowed: Boolean
37 | get() = defaultValue()
38 |
39 | val isRedefinitionAllowed: Boolean
40 | get() = defaultValue()
41 |
42 | // Embedded Debug Probes settings
43 |
44 | val enableCreationStackTraces: Boolean
45 | get() = defaultValue()
46 |
47 | val installDebugProbes: Boolean
48 | get() = defaultValue()
49 |
50 | // Generator Android settings
51 |
52 | val androidGeneratorAttemptsCount: Int
53 | get() = defaultValue()
54 |
55 | // end
56 |
57 | val priority: Int
58 | get() = 0
59 | }
60 |
61 | enum class DecoroutinatorMetadataInfoResolveStrategy {
62 | SYSTEM_RESOURCE, CLASS, SYSTEM_RESOURCE_AND_CLASS
63 | }
64 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-kmp-gradle-plugin-test/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/groovy/GroovyDslInitializerImpl.groovy:
--------------------------------------------------------------------------------
1 | //file:noinspection GrPackage
2 |
3 | package dev.reformator.stacktracedecoroutinator.gradleplugin.groovy
4 |
5 | import dev.reformator.stacktracedecoroutinator.gradleplugin.GroovyDslInitializer
6 | import org.gradle.api.Project
7 | import org.gradle.kotlin.dsl.ApiGradlePluginDecoroutinatorKt
8 | import org.jetbrains.annotations.NotNull
9 |
10 |
11 | class GroovyDslInitializerImpl implements GroovyDslInitializer {
12 | @Override
13 | void initGroovyDsl(@NotNull Project target) {
14 | target.metaClass.decoroutinatorAndroidProGuardRules = { ->
15 | ApiGradlePluginDecoroutinatorKt.decoroutinatorAndroidProGuardRules(target)
16 | }
17 |
18 | target.metaClass.decoroutinatorCommon = { ->
19 | ApiGradlePluginDecoroutinatorKt.decoroutinatorCommon()
20 | }
21 |
22 | target.metaClass.decoroutinatorJvmRuntime = { ->
23 | ApiGradlePluginDecoroutinatorKt.decoroutinatorJvmRuntime()
24 | }
25 |
26 | target.metaClass.decoroutinatorAndroidRuntime = { ->
27 | ApiGradlePluginDecoroutinatorKt.decoroutinatorAndroidRuntime()
28 | }
29 |
30 | target.metaClass.decoroutinatorRegularMethodHandleInvoker = { ->
31 | ApiGradlePluginDecoroutinatorKt.decoroutinatorRegularMethodHandleInvoker()
32 | }
33 |
34 | target.metaClass.decoroutinatorAndroidMethodHandleInvoker = { ->
35 | ApiGradlePluginDecoroutinatorKt.decoroutinatorAndroidMethodHandleInvoker()
36 | }
37 |
38 | target.metaClass.decoroutinatorJvmMethodHandleInvoker = { ->
39 | ApiGradlePluginDecoroutinatorKt.decoroutinatorJvmMethodHandleInvoker()
40 | }
41 |
42 | target.metaClass.decoroutinatorRuntimeSettings = { ->
43 | ApiGradlePluginDecoroutinatorKt.decoroutinatorRuntimeSettings()
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | mavenCentral()
5 | gradlePluginPortal()
6 | }
7 |
8 | dependencies {
9 | classpath(libs.shadow.gradle.plugin)
10 | }
11 | }
12 |
13 | plugins {
14 | alias(libs.plugins.kotlin.jvm.latest)
15 | id("dev.reformator.stacktracedecoroutinator")
16 | }
17 |
18 | stacktraceDecoroutinator {
19 | regularDependencyConfigurations.include = emptySet()
20 | androidDependencyConfigurations.include = emptySet()
21 | jvmDependencyConfigurations.include = emptySet()
22 | addJvmRuntimeDependency = false
23 | useTransformedClassesForCompilation = true
24 | embeddedDebugProbesConfigurations.include = setOf("runtimeClasspath", "testRuntimeClasspath")
25 | }
26 |
27 | repositories {
28 | mavenCentral()
29 | }
30 |
31 | dependencies {
32 | runtimeOnly(files("../../provider/build/libs/").asFileTree)
33 | implementation(files("../../common/build/libs/").asFileTree)
34 | implementation(files("../../mh-invoker/build/libs/").asFileTree)
35 | implementation(files("../../generator-jvm/build/libs/").asFileTree)
36 | implementation(files("../../runtime-settings/build/libs/").asFileTree)
37 | implementation(files("../../class-transformer/build/libs/").asFileTree)
38 | implementation(files("../../spec-method-builder/build/libs/").asFileTree)
39 | runtimeOnly(libs.asm.utils)
40 |
41 | //noinspection UseTomlInstead
42 | testCompileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
43 |
44 | implementation(libs.kotlinx.coroutines.jdk8.latest)
45 | implementation(libs.kotlinx.coroutines.debug.latest)
46 | testImplementation(kotlin("test"))
47 | testImplementation(project(":test-utils"))
48 | testImplementation(files("../../test-utils/retrace-repack/build/libs/").asFileTree)
49 | }
50 |
51 | tasks.test {
52 | useJUnitPlatform()
53 | }
54 |
--------------------------------------------------------------------------------
/_latest-gradle-test/gradle-plugin-android-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | alias(libs.plugins.android.application)
3 | kotlin("android")
4 | id("dev.reformator.stacktracedecoroutinator")
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | google()
10 | }
11 |
12 | stacktraceDecoroutinator {
13 | regularDependencyConfigurations.include = emptySet()
14 | androidDependencyConfigurations.include = emptySet()
15 | jvmDependencyConfigurations.include = emptySet()
16 | addJvmRuntimeDependency = false
17 | addAndroidRuntimeDependency = false
18 | useTransformedClassesForCompilation = true
19 | embedDebugProbesForAndroid = true
20 | runtimeSettingsDependencyConfigurations.include = emptySet()
21 | }
22 |
23 | dependencies {
24 | implementation(libs.junit4)
25 |
26 | runtimeOnly(libs.androidx.test.runner)
27 | }
28 |
29 | android {
30 | namespace = "dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests"
31 | compileSdk = 36
32 | defaultConfig {
33 | applicationId = "dev.reformator.stacktracedecoroutinator.gradlepluginandroidtests"
34 | versionCode = 1
35 | versionName = "1.0"
36 | minSdk = 26
37 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
38 | }
39 | packaging {
40 | resources.pickFirsts.add("META-INF/*")
41 | resources.excludes.add("win32-x86-64/attach_hotspot_windows.dll")
42 | resources.excludes.add("win32-x86/attach_hotspot_windows.dll")
43 | resources.excludes.add("META-INF/licenses/*")
44 | }
45 | kotlin {
46 | jvmToolchain(8)
47 | }
48 | buildTypes {
49 | debug {
50 | isMinifyEnabled = true
51 | isDebuggable = false
52 | testProguardFiles(decoroutinatorAndroidProGuardRules(), "proguard-rules.pro")
53 | proguardFiles(decoroutinatorAndroidProGuardRules(), "proguard-rules.pro")
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/gradle-plugin/tests-gp/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.GetCurrentFileNameProcessor
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | id("dev.reformator.stacktracedecoroutinator")
7 | id("dev.reformator.bytecodeprocessor")
8 | }
9 |
10 | stacktraceDecoroutinator {
11 | regularDependencyConfigurations.include = emptySet()
12 | androidDependencyConfigurations.include = emptySet()
13 | jvmDependencyConfigurations.include = emptySet()
14 | addJvmRuntimeDependency = false
15 | useTransformedClassesForCompilation = true
16 | embeddedDebugProbesConfigurations.include = setOf("runtimeClasspath", "testRuntimeClasspath")
17 | }
18 |
19 | repositories {
20 | mavenCentral()
21 | }
22 |
23 | dependencies {
24 | implementation(project(":gradle-plugin:empty-module-tests"))
25 |
26 | //noinspection UseTomlInstead
27 | testCompileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
28 |
29 | testRuntimeOnly(project(":stacktrace-decoroutinator-common"))
30 | testRuntimeOnly(project(":stacktrace-decoroutinator-mh-invoker"))
31 |
32 | testImplementation(project(":test-utils"))
33 | testImplementation(project(":test-utils-jvm"))
34 | testImplementation(kotlin("test"))
35 | testImplementation(libs.kotlinx.coroutines.jdk8.build)
36 | testImplementation(project(":gradle-plugin:duplicate-entity-jar-builder", configuration = "duplicateJar"))
37 | }
38 |
39 | bytecodeProcessor {
40 | processors = listOf(
41 | GetCurrentFileNameProcessor,
42 | )
43 | }
44 |
45 | tasks.test {
46 | useJUnitPlatform()
47 | }
48 |
49 | java {
50 | sourceCompatibility = JavaVersion.VERSION_1_9
51 | targetCompatibility = JavaVersion.VERSION_1_9
52 | }
53 |
54 | kotlin {
55 | compilerOptions {
56 | jvmTarget = JvmTarget.JVM_1_8
57 | }
58 | }
59 |
60 | sourceSets {
61 | test {
62 | kotlin.destinationDirectory = java.destinationDirectory
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/mh-invoker/src/main/kotlin/internal/mh-invoker.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.mhinvoker.internal
4 |
5 | import dcunknown.getUnknownSpecMethodHandle
6 | import dcunknown.unknownSpecClass
7 | import dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
8 | import dev.reformator.stacktracedecoroutinator.common.internal.VarHandleInvoker
9 | import dev.reformator.stacktracedecoroutinator.common.internal.assert
10 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorSpec
11 | import dev.reformator.stacktracedecoroutinator.provider.internal.AndroidKeep
12 | import java.lang.invoke.MethodHandle
13 | import java.lang.invoke.MethodHandles
14 | import java.lang.invoke.VarHandle
15 |
16 | internal class RegularMethodHandleInvoker: MethodHandleInvoker {
17 | override val unknownSpecMethodHandle = getUnknownSpecMethodHandle()
18 |
19 | override fun callSpecMethod(handle: MethodHandle, spec: DecoroutinatorSpec, result: Any?): Any? =
20 | handle.invokeExact(spec, result)
21 |
22 | override val unknownSpecMethodClass: Class<*>
23 | get() = unknownSpecClass
24 |
25 | override val supportsVarHandle: Boolean =
26 | try {
27 | _supportsVarHandleStub().verify()
28 | true
29 | } catch (_: Throwable) {
30 | false
31 | }
32 | }
33 |
34 | internal class RegularVarHandleInvoker: VarHandleInvoker {
35 | override fun getIntVar(handle: VarHandle, owner: Any): Int =
36 | handle[owner] as Int
37 | }
38 |
39 | @Suppress("ClassName")
40 | @AndroidKeep
41 | private class _supportsVarHandleStub {
42 | private var field: Int = 0
43 | fun verify() {
44 | val varHandle = MethodHandles.lookup().findVarHandle(
45 | _supportsVarHandleStub::class.java,
46 | ::field.name,
47 | Int::class.javaPrimitiveType
48 | )
49 | val fieldValue = varHandle[this] as Int
50 | assert { fieldValue == 0 }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/_tests/latest-kotlin-gradle-plugin-test/test-utils/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2 | import dev.reformator.bytecodeprocessor.plugins.*
3 |
4 |
5 |
6 | plugins {
7 | alias(libs.plugins.kotlin.jvm.latest)
8 | id("dev.reformator.bytecodeprocessor")
9 | }
10 |
11 | repositories {
12 | mavenCentral()
13 | }
14 |
15 | dependencies {
16 | implementation(files("../../../test-utils/retrace-repack/build/libs/").asFileTree)
17 | implementation(files("../../../common/build/libs/").asFileTree)
18 | implementation(kotlin("test"))
19 | implementation(libs.junit5.api)
20 | implementation(libs.junit4)
21 | implementation(libs.kotlinx.coroutines.jdk8.latest)
22 | implementation(libs.kotlin.logging.jvm)
23 |
24 | //noinspection UseTomlInstead
25 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
26 |
27 | runtimeOnly(libs.ktor.io.jvm)
28 | runtimeOnly(libs.logback.classic)
29 | }
30 |
31 | bytecodeProcessor {
32 | processors = setOf(
33 | GetCurrentFileNameProcessor,
34 | GetOwnerClassProcessor,
35 | LoadConstantProcessor
36 | )
37 | }
38 |
39 | val fillConstantProcessorTask = tasks.register("fillConstantProcessor") {
40 | val customLoaderProject = project(":custom-loader")
41 | val customLoaderJarTask = customLoaderProject.tasks.named("shadowJar")
42 | dependsOn(customLoaderJarTask)
43 | doLast {
44 | val customLoaderJarUri = customLoaderJarTask.get().archiveFile.get().asFile.toURI().toString()
45 | bytecodeProcessor {
46 | initContext {
47 | LoadConstantProcessor.addValues(
48 | context = this,
49 | valuesByKeys = mapOf("customLoaderJarUri" to customLoaderJarUri)
50 | )
51 | }
52 | }
53 | }
54 | }
55 |
56 | bytecodeProcessorInitTask.dependsOn(fillConstantProcessorTask)
57 |
58 | val kotlinSources = sourceSets.main.get().kotlin
59 | kotlinSources.srcDirs("../../../test-utils/src/main/kotlin")
60 | kotlinSources.srcDirs("../../../test-utils-jvm/src/main/kotlin")
61 |
--------------------------------------------------------------------------------
/common/src/main/kotlin/intrinsics/intrinsics-common.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.common.intrinsics
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.ChangeClassName
6 | import dev.reformator.bytecodeprocessor.intrinsics.ChangeInvocationsOwner
7 | import dev.reformator.bytecodeprocessor.intrinsics.SkipInvocations
8 | import dev.reformator.bytecodeprocessor.intrinsics.fail
9 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
10 | import kotlin.coroutines.Continuation
11 | import kotlin.coroutines.CoroutineContext
12 | import kotlin.coroutines.jvm.internal.CoroutineStackFrame
13 |
14 | @ChangeClassName(
15 | toName = "kotlin.Result\$Failure",
16 | deleteAfterChanging = true
17 | )
18 | internal class FailureResult {
19 | @JvmField val exception: Throwable = fail()
20 | }
21 |
22 | @ChangeClassName(
23 | toName = "kotlin._Assertions",
24 | deleteAfterChanging = true
25 | )
26 | @PublishedApi
27 | @Suppress("ClassName")
28 | internal object _Assertions {
29 | @JvmField
30 | val ENABLED: Boolean = fail()
31 | }
32 |
33 | @Suppress("UnusedReceiverParameter")
34 | internal val Any?.toResult: Result<*>
35 | @SkipInvocations get() { fail() }
36 |
37 | @Suppress("UNUSED_PARAMETER")
38 | @ChangeInvocationsOwner(
39 | toName = "kotlin.coroutines.jvm.internal.DebugProbesKt",
40 | deleteAfterChanging = true
41 | )
42 | internal fun probeCoroutineResumed(frame: Continuation<*>) { fail() }
43 |
44 | @Suppress("UNUSED_PARAMETER")
45 | @ChangeInvocationsOwner(
46 | toName = "kotlin.ResultKt",
47 | deleteAfterChanging = true
48 | )
49 | internal fun createFailure(exception: Throwable): Any { fail() }
50 |
51 | @ChangeClassName(toName = "kotlin.coroutines.jvm.internal.ContinuationImpl", deleteAfterChanging = true)
52 | internal abstract class ContinuationImpl(
53 | @Suppress("UNUSED_PARAMETER") completion: Continuation?
54 | ): BaseContinuation(), CoroutineStackFrame {
55 | override val context: CoroutineContext
56 | get() { fail() }
57 |
58 | override val callerFrame: CoroutineStackFrame?
59 | get() { fail() }
60 |
61 | override fun getStackTraceElement(): StackTraceElement? { fail() }
62 | }
63 |
--------------------------------------------------------------------------------
/gradle-plugin/jdk8-tests-gp/src/test/kotlin/tests-jdk8-gradle-plugin.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
2 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
3 | import dev.reformator.stacktracedecoroutinator.test.checkStacktrace
4 | import kotlinx.coroutines.ExperimentalCoroutinesApi
5 | import kotlinx.coroutines.debug.DebugProbes
6 | import kotlinx.coroutines.runBlocking
7 | import kotlinx.coroutines.suspendCancellableCoroutine
8 | import kotlinx.coroutines.yield
9 | import org.junit.jupiter.api.Assertions.*
10 | import kotlin.coroutines.resume
11 | import kotlin.test.Test
12 |
13 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
14 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
15 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
16 | class JvmTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTailCallDeoptimizedTest()
17 |
18 | class TestLocalFile {
19 | @Test
20 | fun localTest(): Unit = runBlocking {
21 | fun1()
22 | }
23 |
24 | suspend fun fun1() {
25 | fun2(currentLineNumber)
26 | }
27 |
28 | suspend fun fun2(fun1LineNumber: Int) {
29 | val fun1Frame = StackTraceElement(
30 | TestLocalFile::class.qualifiedName,
31 | ::fun1.name,
32 | currentFileName,
33 | fun1LineNumber
34 | )
35 | yield()
36 | fun3(fun1Frame, currentLineNumber)
37 | }
38 |
39 | suspend fun fun3(fun1Frame: StackTraceElement, fun2LineNumber: Int) {
40 | val fun2Frame = StackTraceElement(
41 | TestLocalFile::class.qualifiedName,
42 | ::fun2.name,
43 | currentFileName,
44 | fun2LineNumber
45 | )
46 | yield()
47 | checkStacktrace(fun2Frame, fun1Frame)
48 | }
49 | }
50 |
51 | @OptIn(ExperimentalCoroutinesApi::class)
52 | class DebugProbesTest {
53 | @Test
54 | fun performDebugProbes() {
55 | runBlocking {
56 | suspendCancellableCoroutine { continuation ->
57 | assertTrue(DebugProbes.dumpCoroutinesInfo().isNotEmpty())
58 | continuation.resume(Unit)
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/test-utils/src/main/kotlin/test-utils.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.test
4 |
5 | import dev.reformator.retracerepack.obfuscate.MappingReader
6 | import dev.reformator.retracerepack.retrace.FrameInfo
7 | import dev.reformator.retracerepack.retrace.FrameRemapper
8 | import org.junit.jupiter.api.Assertions.assertTrue
9 | import java.io.File
10 |
11 | private var mappers = emptyList()
12 |
13 | fun setRetraceMappingFiles(vararg files: String) {
14 | mappers = files.map { file ->
15 | val reader = MappingReader(File(file))
16 | FrameRemapper().apply { reader.pump(this) }
17 | }
18 | }
19 |
20 | fun Array.checkStacktrace(vararg elements: StackTraceElement, fromIndex: Int = 0) {
21 | if (elements.isEmpty()) {
22 | return
23 | }
24 | var startIndex = fromIndex
25 | while (!(this[startIndex] eq elements[0])) startIndex++
26 | elements.forEachIndexed { index, element ->
27 | assertTrue(element eq this[startIndex + index])
28 | }
29 | }
30 |
31 | fun checkStacktrace(vararg elements: StackTraceElement) {
32 | Exception().stackTrace.checkStacktrace(*elements)
33 | }
34 |
35 | private infix fun StackTraceElement.eq(other: StackTraceElement): Boolean {
36 | if (
37 | className == other.className &&
38 | methodName == other.methodName &&
39 | fileName == other.fileName &&
40 | lineNumber == other.lineNumber
41 | ) return true
42 |
43 | fun StackTraceElement.toFrameInfo() =
44 | FrameInfo(className, null, lineNumber, null, null, methodName, null)
45 |
46 | val frame1 = toFrameInfo()
47 | val frame2 = other.toFrameInfo()
48 | mappers.forEach { mapper ->
49 | infix fun FrameInfo.deobfuscateEq(other: FrameInfo) =
50 | mapper.transform(this).orEmpty().any { deobfuscatedFrame ->
51 | deobfuscatedFrame.className == other.className && deobfuscatedFrame.methodName == other.methodName &&
52 | deobfuscatedFrame.lineNumber == other.lineNumber
53 | }
54 |
55 | if (frame1 deobfuscateEq frame2 || frame2 deobfuscateEq frame1) {
56 | return true
57 | }
58 | }
59 |
60 | return false
61 | }
62 |
63 | typealias Junit4Test = org.junit.Test
64 | typealias Junit5Test = org.junit.jupiter.api.Test
65 |
--------------------------------------------------------------------------------
/_plugins/bytecode-processor/plugins/src/main/kotlin/internal/utils-plugins.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.bytecodeprocessor.plugins.internal
4 |
5 | import org.objectweb.asm.ClassReader
6 | import org.objectweb.asm.Opcodes
7 | import org.objectweb.asm.Type
8 | import org.objectweb.asm.tree.*
9 |
10 | val String.internalName: String
11 | get() = replace('.', '/')
12 |
13 | internal fun List?.find(type: Class): AnnotationNode? =
14 | this?.find { it.desc == Type.getDescriptor(type) }
15 |
16 | internal fun AnnotationNode.getParameter(name: String): Any? {
17 | var index = 0
18 | while (index < values.orEmpty().size) {
19 | if (values[index] == name) return values[index + 1]
20 | index += 2
21 | }
22 | return null
23 | }
24 |
25 | internal fun AnnotationNode.setParameter(name: String, value: Any) {
26 | val parameters: MutableList = values ?: run { values = mutableListOf(); values }
27 | var index = 0
28 | while (index < parameters.size) {
29 | if (parameters[index] == name) {
30 | parameters[index + 1] = value
31 | return
32 | }
33 | index += 2
34 | }
35 | parameters.add(name)
36 | parameters.add(value)
37 | }
38 |
39 | internal val MethodNode.isStatic: Boolean
40 | get() = access and Opcodes.ACC_STATIC != 0
41 |
42 |
43 | internal fun ClassNode.getOrCreateClinit(): MethodNode =
44 | methods?.firstOrNull {
45 | it.name == "" && it.desc == "()V" && it.isStatic
46 | } ?: MethodNode(Opcodes.ASM9).apply {
47 | name = ""
48 | desc = "()V"
49 | access = Opcodes.ACC_STATIC or Opcodes.ACC_SYNTHETIC
50 | instructions.add(InsnNode(Opcodes.RETURN))
51 | val methods: MutableList = methods ?: run { methods = mutableListOf(); methods }
52 | methods.add(this)
53 | }
54 |
55 | internal fun Class<*>.readAsm(): ClassNode =
56 | classLoader.getResourceAsStream(name.internalName + ".class")!!.use {
57 | val classReader = ClassReader(it)
58 | val classNode = ClassNode(Opcodes.ASM9)
59 | classReader.accept(classNode, 0)
60 | classNode
61 | }
62 |
63 | internal infix fun MethodInsnNode.eq(other: MethodInsnNode): Boolean =
64 | opcode == other.opcode && owner == other.owner && name == other.name && desc == other.desc
65 |
--------------------------------------------------------------------------------
/test-utils/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
2 | import dev.reformator.bytecodeprocessor.plugins.*
3 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
4 |
5 | plugins {
6 | kotlin("jvm")
7 | id("dev.reformator.bytecodeprocessor")
8 | id("dev.reformator.forcevariantjavaversion")
9 | }
10 |
11 | repositories {
12 | mavenCentral()
13 | }
14 |
15 | dependencies {
16 | //noinspection UseTomlInstead
17 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
18 |
19 | implementation(libs.junit5.api)
20 | implementation(libs.junit4)
21 | implementation(libs.kotlinx.coroutines.core.build)
22 | implementation(libs.kotlin.logging.jvm)
23 | implementation(project(":test-utils:retrace-repack", configuration = "shadow"))
24 | implementation(project(":stacktrace-decoroutinator-common"))
25 |
26 | runtimeOnly(libs.ktor.io.jvm) {
27 | exclude(group = "org.jetbrains.kotlinx", module = "kotlinx-coroutines-jdk8")
28 | }
29 | runtimeOnly(libs.logback.classic)
30 | }
31 |
32 | bytecodeProcessor {
33 | processors = listOf(
34 | GetCurrentFileNameProcessor,
35 | GetOwnerClassProcessor,
36 | LoadConstantProcessor
37 | )
38 | }
39 |
40 | val fillConstantProcessorTask = tasks.register("fillConstantProcessor") {
41 | val customLoaderProject = project(":test-utils:custom-loader")
42 | val customLoaderJarTask = customLoaderProject.tasks.named("shadowJar")
43 | dependsOn(customLoaderJarTask)
44 | doLast {
45 | val customLoaderJarUri = customLoaderJarTask.get().archiveFile.get().asFile.toURI().toString()
46 | bytecodeProcessor {
47 | initContext {
48 | LoadConstantProcessor.addValues(
49 | context = this,
50 | valuesByKeys = mapOf("customLoaderJarUri" to customLoaderJarUri)
51 | )
52 | }
53 | }
54 | }
55 | }
56 |
57 | bytecodeProcessorInitTask.dependsOn(fillConstantProcessorTask)
58 |
59 | java {
60 | sourceCompatibility = JavaVersion.VERSION_1_9
61 | targetCompatibility = JavaVersion.VERSION_1_9
62 | }
63 |
64 | tasks.withType {
65 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
66 | }
67 |
68 | kotlin {
69 | compilerOptions {
70 | jvmTarget = JvmTarget.JVM_1_8
71 | freeCompilerArgs.add("-Xjvm-default=all")
72 | }
73 | }
74 |
75 | sourceSets {
76 | main {
77 | kotlin.destinationDirectory = java.destinationDirectory
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/jvm/jdk8-tests-j/src/test/kotlin/tests-jdk8-jvm.kt:
--------------------------------------------------------------------------------
1 | import dev.reformator.stacktracedecoroutinator.intrinsics.BASE_CONTINUATION_CLASS_NAME
2 | import dev.reformator.stacktracedecoroutinator.jvm.DecoroutinatorJvmApi
3 | import dev.reformator.stacktracedecoroutinator.jvm.internal.isTransformed
4 | import kotlinx.coroutines.runBlocking
5 | import kotlinx.coroutines.yield
6 | import org.junit.jupiter.api.condition.DisabledIfSystemProperty
7 | import org.junit.jupiter.api.condition.EnabledIfSystemProperty
8 | import kotlin.test.BeforeTest
9 | import kotlin.test.Test
10 | import kotlin.test.assertFalse
11 | import kotlin.test.assertTrue
12 |
13 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
14 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest() {
15 | @BeforeTest
16 | fun setup() {
17 | setupTest()
18 | }
19 | }
20 |
21 | // Jacoco only instruments this class
22 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
23 | class JacocoInstrumentedMethodTest {
24 | @BeforeTest
25 | fun setup() {
26 | setupTest()
27 | }
28 |
29 | @Test
30 | fun jacocoInstrumentedMethodTest(): Unit = runBlocking {
31 | suspend fun jacocoInstrumentedMethod() {
32 | yield()
33 | yield()
34 | }
35 | jacocoInstrumentedMethod()
36 | }
37 | }
38 |
39 | @EnabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
40 | class ReloadBaseContinuationTest {
41 | @Test
42 | fun reloadBaseContinuation() {
43 | val baseContinuationClass = Class.forName(BASE_CONTINUATION_CLASS_NAME)
44 | assertFalse(baseContinuationClass.isTransformed)
45 | DecoroutinatorJvmApi.install()
46 | assertTrue(baseContinuationClass.isTransformed)
47 | }
48 | }
49 |
50 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
51 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest() {
52 | @BeforeTest
53 | fun setup() {
54 | setupTest()
55 | }
56 | }
57 |
58 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
59 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest() {
60 | @BeforeTest
61 | fun setup() {
62 | setupTest()
63 | }
64 | }
65 |
66 | fun setupTest() {
67 | System.setProperty(
68 | "dev.reformator.stacktracedecoroutinator.jvmAgentDebugMetadataInfoResolveStrategy",
69 | "SYSTEM_RESOURCE"
70 | )
71 | DecoroutinatorJvmApi.install()
72 | }
73 |
--------------------------------------------------------------------------------
/gradle-plugin/src/main/kotlin/api-gradle-plugin-decoroutinator.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("ApiGradlePluginDecoroutinatorKt")
3 |
4 | package org.gradle.kotlin.dsl
5 |
6 | import dev.reformator.bytecodeprocessor.intrinsics.LoadConstant
7 | import dev.reformator.bytecodeprocessor.intrinsics.fail
8 | import dev.reformator.stacktracedecoroutinator.gradleplugin.ANDROID_CURRENT_PROGUARD_RULES_FILE_NAME
9 | import dev.reformator.stacktracedecoroutinator.gradleplugin.DecoroutinatorAttributePluginExtension
10 | import dev.reformator.stacktracedecoroutinator.gradleplugin.DecoroutinatorPluginExtension
11 | import dev.reformator.stacktracedecoroutinator.gradleplugin.decoroutinatorDir
12 | import org.gradle.api.Project
13 | import java.io.File
14 |
15 | fun Project.stacktraceDecoroutinator(configure: DecoroutinatorPluginExtension.() -> Unit) {
16 | extensions.configure(::stacktraceDecoroutinator.name, configure)
17 | }
18 |
19 | fun Project.stacktraceDecoroutinatorAttribute(configure: DecoroutinatorAttributePluginExtension.() -> Unit) {
20 | extensions.configure(::stacktraceDecoroutinatorAttribute.name, configure)
21 | }
22 |
23 | @Suppress("unused")
24 | @Deprecated("replace with method", replaceWith = ReplaceWith("decoroutinatorAndroidProGuardRules()"))
25 | val Project.decoroutinatorAndroidProGuardRules: File
26 | get() = decoroutinatorAndroidProGuardRules()
27 |
28 | fun Project.decoroutinatorAndroidProGuardRules(): File =
29 | decoroutinatorDir.resolve(ANDROID_CURRENT_PROGUARD_RULES_FILE_NAME)
30 |
31 | fun decoroutinatorCommon(): Any =
32 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-common:$projectVersionIntrinsic"
33 |
34 | fun decoroutinatorJvmRuntime(): Any =
35 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-generator-jvm:$projectVersionIntrinsic"
36 |
37 | fun decoroutinatorAndroidRuntime(): Any =
38 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-generator-android:$projectVersionIntrinsic"
39 |
40 | fun decoroutinatorRegularMethodHandleInvoker(): Any =
41 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-mh-invoker:$projectVersionIntrinsic"
42 |
43 | fun decoroutinatorAndroidMethodHandleInvoker(): Any =
44 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-mh-invoker-android:$projectVersionIntrinsic"
45 |
46 | fun decoroutinatorJvmMethodHandleInvoker(): Any =
47 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-mh-invoker-jvm:$projectVersionIntrinsic"
48 |
49 | fun decoroutinatorRuntimeSettings(): Any =
50 | "dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-runtime-settings:$projectVersionIntrinsic"
51 |
52 | private val projectVersionIntrinsic: String
53 | @LoadConstant("version") get() { fail() }
54 |
--------------------------------------------------------------------------------
/runtime-settings/src/main/kotlin/internal/runtime-settings-internal.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.runtimesettings.internal
4 |
5 | import dev.reformator.stacktracedecoroutinator.runtimesettings.DecoroutinatorRuntimeSettingsProvider
6 | import java.util.ServiceLoader
7 |
8 | @Suppress("ObjectInheritsException", "JavaIoSerializableObjectMustHaveReadResolve")
9 | private object DefaultValueException: Exception()
10 |
11 | internal fun defaultValue(): Nothing =
12 | throw DefaultValueException
13 |
14 | sealed interface RuntimeSettingsValue {
15 | object Default: RuntimeSettingsValue
16 | class Value(val value: T): RuntimeSettingsValue
17 | }
18 |
19 | private class RuntimeSettingsProviderWithPriority(
20 | val provider: DecoroutinatorRuntimeSettingsProvider,
21 | val priority: Int
22 | )
23 |
24 | private val runtimeSettingsProviderInstances =
25 | ServiceLoader.load(DecoroutinatorRuntimeSettingsProvider::class.java)
26 | .asSequence()
27 | .map { RuntimeSettingsProviderWithPriority(it, it.priority) }
28 | .sortedByDescending { it.priority }
29 | .toList()
30 |
31 | fun getRuntimeSettingsValue(get: DecoroutinatorRuntimeSettingsProvider.() -> T): RuntimeSettingsValue {
32 | var index = 0
33 | val value = run {
34 | while (index < runtimeSettingsProviderInstances.size) {
35 | try {
36 | return@run runtimeSettingsProviderInstances[index].provider.get()
37 | } catch (_: DefaultValueException) {
38 | index++
39 | }
40 | }
41 | return RuntimeSettingsValue.Default
42 | }
43 | val provider = runtimeSettingsProviderInstances[index].provider
44 | val priority = runtimeSettingsProviderInstances[index].priority
45 | index++
46 | while (index < runtimeSettingsProviderInstances.size && runtimeSettingsProviderInstances[index].priority == priority) {
47 | try {
48 | val otherProvider = runtimeSettingsProviderInstances[index].provider
49 | val otherValue = otherProvider.get()
50 | if (otherValue != value) {
51 | error("different values with the same priority[$priority]: [$value] from [$provider] and [$otherValue] from [$otherProvider]")
52 | }
53 | } catch (_: DefaultValueException) { }
54 | index++
55 | }
56 | return RuntimeSettingsValue.Value(value)
57 | }
58 |
59 | inline fun getRuntimeSettingsValue(
60 | noinline get: DecoroutinatorRuntimeSettingsProvider.() -> T,
61 | default: () -> T
62 | ): T =
63 | when(val value = getRuntimeSettingsValue(get)) {
64 | is RuntimeSettingsValue.Value -> value.value
65 | RuntimeSettingsValue.Default -> default()
66 | }
67 |
--------------------------------------------------------------------------------
/common/src/main/kotlin/internal/interfaces-common.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.common.internal
4 |
5 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
6 | import dev.reformator.stacktracedecoroutinator.provider.DecoroutinatorSpec
7 | import dev.reformator.stacktracedecoroutinator.provider.internal.AndroidLegacyKeep
8 | import java.io.InputStream
9 | import java.lang.invoke.MethodHandle
10 | import java.lang.invoke.MethodHandles
11 | import java.lang.invoke.VarHandle
12 |
13 | interface TransformedClassesRegistry {
14 | class TransformedClassSpec(
15 | val transformedClass: Class<*>,
16 | val fileName: String?,
17 | val lookup: MethodHandles.Lookup,
18 | val lineNumbersByMethod: Map,
19 | val skipSpecMethods: Boolean
20 | )
21 |
22 | fun interface Listener {
23 | fun onNewTransformedClass(spec: TransformedClassSpec)
24 | fun onException(exception: Throwable) { }
25 | }
26 |
27 | val transformedClasses: Collection
28 | operator fun get(clazz: Class<*>): TransformedClassSpec?
29 | fun addListener(listener: Listener)
30 | fun registerTransformedClass(lookup: MethodHandles.Lookup)
31 | }
32 |
33 | fun interface SpecMethodsFactory {
34 | fun getSpecMethodHandle(element: StackTraceElement): MethodHandle?
35 | }
36 |
37 | data class TransformationMetadata(
38 | val fileName: String?,
39 | val methods: List,
40 | val skipSpecMethods: Boolean
41 | ) {
42 | class Method(
43 | val name: String,
44 | val lineNumbers: IntArray
45 | )
46 | }
47 |
48 | @Suppress("ArrayInDataClass")
49 | data class KotlinDebugMetadata(
50 | val sourceFile: String,
51 | val className: String,
52 | val methodName: String,
53 | val lineNumbers: IntArray
54 | )
55 |
56 | interface AnnotationMetadataResolver {
57 | fun getTransformationMetadata(classBody: InputStream): TransformationMetadata?
58 | fun getKotlinDebugMetadata(classBody: InputStream): KotlinDebugMetadata?
59 | }
60 |
61 | @AndroidLegacyKeep
62 | interface MethodHandleInvoker {
63 | val unknownSpecMethodHandle: MethodHandle
64 | fun callSpecMethod(handle: MethodHandle, spec: DecoroutinatorSpec, result: Any?): Any?
65 | val unknownSpecMethodClass: Class<*>
66 | val supportsVarHandle: Boolean
67 | }
68 |
69 | @AndroidLegacyKeep
70 | interface VarHandleInvoker {
71 | fun getIntVar(handle: VarHandle, owner: Any): Int
72 | }
73 |
74 | internal interface StacktraceElementsFactory {
75 | fun getStacktraceElement(baseContinuation: BaseContinuation): StackTraceElement?
76 | fun getLabel(baseContinuation: BaseContinuation): Int
77 | }
78 |
79 | internal const val NONE_LABEL = Int.MIN_VALUE / 2
80 | internal const val UNKNOWN_LABEL = NONE_LABEL - 1
81 |
--------------------------------------------------------------------------------
/gradle-plugin/duplicate-entity-jar-builder/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import dev.reformator.bytecodeprocessor.plugins.GetCurrentFileNameProcessor
2 | import dev.reformator.bytecodeprocessor.plugins.GetOwnerClassProcessor
3 | import org.apache.tools.zip.ZipEntry
4 | import org.apache.tools.zip.ZipOutputStream
5 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
6 | import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
7 |
8 | plugins {
9 | kotlin("jvm")
10 | id("dev.reformator.bytecodeprocessor")
11 | }
12 |
13 | repositories {
14 | mavenCentral()
15 | }
16 |
17 | dependencies {
18 | //noinspection UseTomlInstead
19 | compileOnly("dev.reformator.bytecodeprocessor:bytecode-processor-intrinsics")
20 | }
21 |
22 | bytecodeProcessor {
23 | processors = setOf(
24 | GetCurrentFileNameProcessor,
25 | GetOwnerClassProcessor
26 | )
27 | }
28 |
29 | tasks.test {
30 | useJUnitPlatform()
31 | }
32 |
33 | java {
34 | sourceCompatibility = JavaVersion.VERSION_1_9
35 | targetCompatibility = JavaVersion.VERSION_1_9
36 | }
37 |
38 | kotlin {
39 | compilerOptions {
40 | jvmTarget = JvmTarget.JVM_1_8
41 | }
42 | }
43 |
44 | sourceSets {
45 | main {
46 | kotlin.destinationDirectory = java.destinationDirectory
47 | }
48 | }
49 |
50 | val duplicateJarConfig = configurations.create("duplicateJar")
51 |
52 | val createDuplicateJarTask = tasks.register("createDuplicateJar") {
53 | val compileJavaTask = tasks.named("compileJava")
54 | val compileKotlinTask = tasks.named("compileKotlin")
55 | dependsOn(compileJavaTask, compileKotlinTask)
56 | outputs.file(layout.buildDirectory.file("duplicate-entities.jar"))
57 | doLast {
58 | ZipOutputStream(outputs.files.singleFile).use { output ->
59 | output.putDirectoryDuplicate(compileJavaTask.get().destinationDirectory.asFile.get())
60 | output.putDirectoryDuplicate(compileKotlinTask.get().destinationDirectory.asFile.get())
61 | }
62 | }
63 | }
64 |
65 | artifacts.add(duplicateJarConfig.name, createDuplicateJarTask)
66 |
67 | fun ZipOutputStream.putDirectoryDuplicate(root: File) {
68 | root.walk().forEach { file ->
69 | if (file == root) return@forEach
70 | val path = file.relativeTo(root).path.replace(File.pathSeparatorChar, '/')
71 | if (file.isDirectory) {
72 | val dirPath = "$path/"
73 | putEntry(dirPath)
74 | putEntry(dirPath)
75 | } else {
76 | val buffer = file.readBytes()
77 | putEntry(path)
78 | write(buffer)
79 | putEntry(path)
80 | write(buffer)
81 | }
82 | }
83 | }
84 |
85 | private fun ZipOutputStream.putEntry(name: String) {
86 | putNextEntry(ZipEntry(name).apply {
87 | method = ZipEntry.DEFLATED
88 | })
89 | }
90 |
--------------------------------------------------------------------------------
/runtime-settings/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.dokka.gradle.AbstractDokkaTask
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | kotlin("jvm")
6 | alias(libs.plugins.dokka)
7 | `maven-publish`
8 | signing
9 | id("dev.reformator.forcevariantjavaversion")
10 | }
11 |
12 | repositories {
13 | mavenCentral()
14 | }
15 |
16 | java {
17 | sourceCompatibility = JavaVersion.VERSION_1_9
18 | targetCompatibility = JavaVersion.VERSION_1_9
19 | }
20 |
21 | tasks.withType {
22 | options.compilerArgs.addAll(listOf("-parameters", "-Xlint:-module"))
23 | }
24 |
25 | kotlin {
26 | compilerOptions {
27 | jvmTarget = JvmTarget.JVM_1_8
28 | freeCompilerArgs.add("-Xjvm-default=all")
29 | }
30 | }
31 |
32 | sourceSets {
33 | main {
34 | kotlin.destinationDirectory = java.destinationDirectory
35 | }
36 | }
37 |
38 | val dokkaJavadocsJar = tasks.register("dokkaJavadocsJar") {
39 | val dokkaJavadocTask = tasks.named("dokkaJavadoc").get()
40 | dependsOn(dokkaJavadocTask)
41 | archiveClassifier.set("javadoc")
42 | from(dokkaJavadocTask.outputDirectory)
43 | }
44 |
45 | val mavenPublicationName = "maven"
46 |
47 | publishing {
48 | publications {
49 | create(mavenPublicationName) {
50 | from(components["java"])
51 | artifact(dokkaJavadocsJar)
52 | artifact(tasks.named("kotlinSourcesJar"))
53 | pom {
54 | name.set("Stacktrace-decoroutinator runtime settings provider lib.")
55 | description.set("Library for recovering stack trace in exceptions thrown in Kotlin coroutines.")
56 | url.set("https://github.com/Anamorphosee/stacktrace-decoroutinator")
57 | licenses {
58 | license {
59 | name.set("The Apache License, Version 2.0")
60 | url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
61 | }
62 | }
63 | developers {
64 | developer {
65 | name.set("Denis Berestinskii")
66 | email.set("berestinsky@gmail.com")
67 | url.set("https://github.com/Anamorphosee")
68 | }
69 | }
70 | scm {
71 | connection.set("scm:git:git://github.com/Anamorphosee/stacktrace-decoroutinator.git")
72 | developerConnection.set("scm:git:ssh://github.com:Anamorphosee/stacktrace-decoroutinator.git")
73 | url.set("http://github.com/Anamorphosee/stacktrace-decoroutinator/tree/master")
74 | }
75 | }
76 | }
77 | }
78 | }
79 |
80 | signing {
81 | useGpgCmd()
82 | sign(publishing.publications[mavenPublicationName])
83 | }
84 |
--------------------------------------------------------------------------------
/jvm/src/test/kotlin/tests-jvm.kt:
--------------------------------------------------------------------------------
1 | package dev.reformator.stacktracedecoroutinator.jvmtests
2 |
3 | import dev.reformator.stacktracedecoroutinator.intrinsics.BASE_CONTINUATION_CLASS_NAME
4 | import dev.reformator.stacktracedecoroutinator.jvm.DecoroutinatorJvmApi
5 | import dev.reformator.stacktracedecoroutinator.jvm.internal.isTransformed
6 | import kotlinx.coroutines.runBlocking
7 | import kotlinx.coroutines.yield
8 | import org.junit.jupiter.api.condition.DisabledIfSystemProperty
9 | import org.junit.jupiter.api.condition.EnabledIfSystemProperty
10 | import kotlin.test.BeforeTest
11 | import kotlin.test.Test
12 | import kotlin.test.assertFalse
13 | import kotlin.test.assertTrue
14 |
15 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
16 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest() {
17 | @BeforeTest
18 | fun setup() {
19 | setupTest()
20 | }
21 | }
22 |
23 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
24 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest() {
25 | @BeforeTest
26 | fun setup() {
27 | setupTest()
28 | }
29 | }
30 |
31 | // Jacoco only instruments this class
32 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
33 | class JacocoInstrumentedMethodTest {
34 | @BeforeTest
35 | fun setup() {
36 | setupTest()
37 | }
38 |
39 | @Test
40 | fun jacocoInstrumentedMethodTest(): Unit = runBlocking {
41 | suspend fun jacocoInstrumentedMethod() {
42 | yield()
43 | yield()
44 | }
45 |
46 | jacocoInstrumentedMethod()
47 | }
48 | }
49 |
50 | @EnabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
51 | class ReloadBaseContinuationTest {
52 | @Test
53 | fun reloadBaseContinuation() {
54 | val baseContinuationClass = Class.forName(BASE_CONTINUATION_CLASS_NAME)
55 | assertFalse(baseContinuationClass.isTransformed)
56 | DecoroutinatorJvmApi.install()
57 | assertTrue(baseContinuationClass.isTransformed)
58 | }
59 | }
60 |
61 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
62 | class CustomClassLoaderTest: dev.reformator.stacktracedecoroutinator.test.CustomClassLoaderTest() {
63 | @BeforeTest
64 | fun setup() {
65 | setupTest()
66 | }
67 | }
68 |
69 | @DisabledIfSystemProperty(named = "testReloadBaseConfiguration", matches = "true")
70 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest() {
71 | @BeforeTest
72 | fun setup() {
73 | setupTest()
74 | }
75 | }
76 |
77 | fun setupTest() {
78 | System.setProperty(
79 | "dev.reformator.stacktracedecoroutinator.jvmAgentDebugMetadataInfoResolveStrategy",
80 | "SYSTEM_RESOURCE"
81 | )
82 | DecoroutinatorJvmApi.install()
83 | }
84 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "stacktrace-decoroutinator"
2 | include(
3 | "provider",
4 | "common",
5 | "generator-jvm",
6 | "gradle-plugin",
7 | "jvm-agent-common",
8 | "jvm",
9 | "jvm-agent",
10 | "generator-android",
11 | "mh-invoker",
12 | "mh-invoker-android",
13 | "mh-invoker-jvm",
14 | "runtime-settings",
15 | "class-transformer",
16 | "spec-method-builder",
17 |
18 | "intrinsics",
19 | "test-utils",
20 | "test-utils:base-continuation-accessor-stub",
21 | "test-utils:base-continuation-accessor-reflect-stub",
22 | "test-utils-jvm",
23 | "test-utils:custom-loader",
24 | "generator-jvm:jdk8-tests-g",
25 | "gradle-plugin:tests-gp",
26 | "gradle-plugin:android-tests",
27 | "gradle-plugin:jdk8-tests-gp",
28 | "gradle-plugin:duplicate-entity-jar-builder",
29 | "gradle-plugin:android-legacy-tests",
30 | "gradle-plugin:empty-module-tests",
31 | "gradle-plugin:embedded-debug-probes-stdlib",
32 | "gradle-plugin:embedded-debug-probes-xcoroutines",
33 | "gradle-plugin:base-continuation-accessor",
34 | "jvm-agent:tests-ja",
35 | "jvm-agent:jdk8-tests-ja",
36 | "jvm:jdk8-tests-j",
37 | "mh-invoker-jvm:jdk8-tests-mij",
38 | "jvm-agent-common:suspend-class-stub",
39 | "generator-jvm:android-wrong-generator-tests",
40 | "gradle-plugin:gradle-groovy-dsl-tests",
41 | "test-utils:retrace-repack",
42 | "gradle-plugin:aar-builder"
43 | )
44 | project(":provider").name = "stacktrace-decoroutinator-provider"
45 | project(":common").name = "stacktrace-decoroutinator-common"
46 | project(":generator-jvm").name = "stacktrace-decoroutinator-generator-jvm"
47 | project(":gradle-plugin").name = "stacktrace-decoroutinator-gradle-plugin"
48 | project(":jvm-agent-common").name = "stacktrace-decoroutinator-jvm-agent-common"
49 | project(":jvm").name = "stacktrace-decoroutinator-jvm"
50 | project(":jvm-agent").name = "stacktrace-decoroutinator-jvm-agent"
51 | project(":generator-android").name = "stacktrace-decoroutinator-generator-android"
52 | project(":mh-invoker").name = "stacktrace-decoroutinator-mh-invoker"
53 | project(":mh-invoker-android").name = "stacktrace-decoroutinator-mh-invoker-android"
54 | project(":mh-invoker-jvm").name = "stacktrace-decoroutinator-mh-invoker-jvm"
55 | project(":runtime-settings").name = "stacktrace-decoroutinator-runtime-settings"
56 | project(":class-transformer").name = "stacktrace-decoroutinator-class-transformer"
57 | project(":spec-method-builder").name = "stacktrace-decoroutinator-spec-method-builder"
58 |
59 | includeBuild("_plugins/bytecode-processor")
60 | includeBuild("_plugins/gradle-plugin-test")
61 | includeBuild("_plugins/force-variant-java-version")
62 |
63 | includeBuild("_tests/latest-kotlin-gradle-plugin-test")
64 | includeBuild("_tests/latest-kotlin-kmp-gradle-plugin-test")
65 |
66 | pluginManagement {
67 | includeBuild("_plugins/bytecode-processor")
68 | includeBuild("_plugins/gradle-plugin-test")
69 | includeBuild("_plugins/force-variant-java-version")
70 | }
71 |
--------------------------------------------------------------------------------
/generator-jvm/src/main/kotlin/internal/classLoader-generator.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 | @file:JvmName("ClassLoaderGeneratorKt")
3 |
4 | package dev.reformator.stacktracedecoroutinator.generatorjvm.internal
5 |
6 | import dev.reformator.bytecodeprocessor.intrinsics.MakeStatic
7 | import dev.reformator.stacktracedecoroutinator.common.internal.MethodHandleInvoker
8 | import dev.reformator.stacktracedecoroutinator.common.internal.specMethodType
9 | import dev.reformator.stacktracedecoroutinator.provider.internal.internalName
10 | import dev.reformator.stacktracedecoroutinator.specmethodbuilder.internal.buildSpecMethodNode
11 | import org.objectweb.asm.ClassWriter
12 | import org.objectweb.asm.Opcodes
13 | import org.objectweb.asm.Type
14 | import org.objectweb.asm.tree.ClassNode
15 | import java.lang.invoke.MethodHandle
16 | import java.lang.invoke.MethodHandles
17 |
18 | internal class DecoroutinatorClassLoader: ClassLoader(MethodHandleInvoker::class.java.classLoader) {
19 | fun buildClassAndGetSpecHandlesByMethod(
20 | className: String,
21 | fileName: String?,
22 | lineNumbersByMethod: Map>
23 | ): Map {
24 | val body = getClassBody(
25 | className = className,
26 | fileName = fileName,
27 | lineNumbersByMethod = lineNumbersByMethod
28 | )
29 | val clazz = defineClass(className, body)
30 | return lineNumbersByMethod.mapValues { (methodName, _) ->
31 | MethodHandles.publicLookup().findStatic(clazz, methodName, specMethodType)
32 | }
33 | }
34 |
35 | @Suppress("unused")
36 | @MakeStatic(addToStaticInitializer = true)
37 | private fun clinit() {
38 | assert(registerAsParallelCapable())
39 | }
40 |
41 | private fun defineClass(className: String, classBody: ByteArray): Class<*> {
42 | synchronized(getClassLoadingLock(className)) {
43 | return defineClass(className, classBody, 0, classBody.size)
44 | }
45 | }
46 | }
47 |
48 | private fun getClassBody(
49 | className: String,
50 | fileName: String?,
51 | lineNumbersByMethod: Map>
52 | ): ByteArray {
53 | val classNode = ClassNode(Opcodes.ASM9).apply {
54 | version = Opcodes.V1_8
55 | access = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
56 | name = className.internalName
57 | superName = Type.getInternalName(Object::class.java)
58 | sourceFile = fileName
59 | methods = lineNumbersByMethod.asSequence()
60 | .map { (methodName, lineNumbers) ->
61 | buildSpecMethodNode(
62 | methodName = methodName,
63 | lineNumbers = lineNumbers,
64 | makePrivate = false,
65 | makeFinal = true
66 | )
67 | }
68 | .toList()
69 | }
70 | val writer = ClassWriter(ClassWriter.COMPUTE_MAXS)
71 | classNode.accept(writer)
72 | return writer.toByteArray()
73 | }
74 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/provider/src/main/kotlin/internal/provider.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.provider.internal
4 |
5 | import java.lang.invoke.MethodHandles
6 | import java.util.ServiceLoader
7 |
8 | interface DecoroutinatorProvider {
9 | val isDecoroutinatorEnabled: Boolean
10 | val baseContinuationAccessor: BaseContinuationAccessor?
11 | fun prepareBaseContinuationAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor
12 | fun awakeBaseContinuation(accessor: BaseContinuationAccessor, baseContinuation: Any, result: Any?)
13 | fun registerTransformedClass(lookup: MethodHandles.Lookup)
14 | fun getBaseContinuation(
15 | completion: Any?,
16 | fileName: String?,
17 | className: String,
18 | methodName: String,
19 | lineNumber: Int
20 | ): Any?
21 | val isUsingElementFactoryForBaseContinuationEnabled: Boolean
22 | fun getElementFactoryStacktraceElement(baseContinuation: Any): StackTraceElement?
23 | }
24 |
25 | internal val provider: DecoroutinatorProvider =
26 | try {
27 | ServiceLoader.load(DecoroutinatorProvider::class.java).iterator().next()
28 | } catch (_: Throwable) {
29 | null
30 | } ?: NoopProvider()
31 |
32 | private class NoopProvider: DecoroutinatorProvider {
33 | override val isDecoroutinatorEnabled: Boolean
34 | get() = false
35 |
36 | override val baseContinuationAccessor: BaseContinuationAccessor
37 | get() = error("not supported")
38 |
39 | override fun prepareBaseContinuationAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor =
40 | error("not supported")
41 |
42 | override fun awakeBaseContinuation(
43 | accessor: BaseContinuationAccessor,
44 | baseContinuation: Any,
45 | result: Any?
46 | ) {
47 | error("not supported")
48 | }
49 |
50 | override fun registerTransformedClass(lookup: MethodHandles.Lookup) {
51 | error("not supported")
52 | }
53 |
54 | override fun getBaseContinuation(
55 | completion: Any?,
56 | fileName: String?,
57 | className: String,
58 | methodName: String,
59 | lineNumber: Int
60 | ): Any? =
61 | completion
62 |
63 | override val isUsingElementFactoryForBaseContinuationEnabled: Boolean
64 | get() = false
65 |
66 | override fun getElementFactoryStacktraceElement(baseContinuation: Any): StackTraceElement =
67 | error("not supported")
68 | }
69 |
70 | interface BaseContinuationAccessor {
71 | fun invokeSuspend(baseContinuation: Any, result: Any?): Any?
72 | fun releaseIntercepted(baseContinuation: Any)
73 | }
74 |
75 | fun interface BaseContinuationAccessorProvider {
76 | fun createAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor
77 | }
78 |
79 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
80 | @Retention(AnnotationRetention.BINARY)
81 | annotation class AndroidKeep
82 |
83 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
84 | @Retention(AnnotationRetention.BINARY)
85 | annotation class AndroidLegacyKeep
86 |
--------------------------------------------------------------------------------
/jvm-agent-common/src/main/kotlin/internal/base-continuation-accessor-agent-common.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package dev.reformator.stacktracedecoroutinator.jvmagentcommon.internal
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.LoadConstant
6 | import dev.reformator.bytecodeprocessor.intrinsics.fail
7 | import dev.reformator.stacktracedecoroutinator.intrinsics.BaseContinuation
8 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessor
9 | import dev.reformator.stacktracedecoroutinator.provider.internal.BaseContinuationAccessorProvider
10 | import java.lang.invoke.MethodHandles
11 | import java.lang.invoke.MethodType
12 | import java.util.Base64
13 | import java.util.zip.ZipInputStream
14 |
15 | internal class AgentBaseContinuationAccessorProvider: BaseContinuationAccessorProvider {
16 | override fun createAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor {
17 | try {
18 | return loadRegularAccessor(lookup)
19 | } catch (_: Throwable) { }
20 |
21 | val invokeSuspendHandle = lookup.findVirtual(
22 | BaseContinuation::class.java,
23 | BaseContinuation::invokeSuspend.name,
24 | MethodType.methodType(Object::class.java, Object::class.java)
25 | )
26 | val releaseInterceptedHandle = lookup.findVirtual(
27 | BaseContinuation::class.java,
28 | BaseContinuation::releaseIntercepted.name,
29 | MethodType.methodType(Void::class.javaPrimitiveType)
30 | )
31 | return object: BaseContinuationAccessor {
32 | override fun invokeSuspend(baseContinuation: Any, result: Any?): Any? =
33 | invokeSuspendHandle.invokeExact(baseContinuation as BaseContinuation, result)
34 |
35 | override fun releaseIntercepted(baseContinuation: Any) {
36 | releaseInterceptedHandle.invokeExact(baseContinuation as BaseContinuation)
37 | }
38 | }
39 | }
40 | }
41 |
42 | private fun loadRegularAccessor(lookup: MethodHandles.Lookup): BaseContinuationAccessor {
43 | var baseContinuationAccessorClass: Class<*>? = null
44 | ZipInputStream(Base64.getDecoder().decode(baseContinuationAccessorJarBase64).inputStream()).use { input ->
45 | while (true) {
46 | val entry = input.nextEntry ?: break
47 | if (entry.name.endsWith(".class")) {
48 | val body = input.readBytes()
49 | lookup.defineClass(body).let { definedClass ->
50 | if (definedClass.name == baseContinuationAccessorImplClassName) {
51 | baseContinuationAccessorClass = definedClass
52 | }
53 | }
54 | }
55 | }
56 | }
57 | return baseContinuationAccessorClass!!.getDeclaredConstructor().newInstance() as BaseContinuationAccessor
58 | }
59 |
60 | private val baseContinuationAccessorJarBase64: String
61 | @LoadConstant("baseContinuationAccessorJarBase64") get() { fail() }
62 |
63 | private val baseContinuationAccessorImplClassName: String
64 | @LoadConstant("baseContinuationAccessorImplClassName") get() { fail() }
65 |
--------------------------------------------------------------------------------
/gradle-plugin/embedded-debug-probes-xcoroutines/src/main/kotlin/embedded-debug-probes-provider.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("PackageDirectoryMismatch")
2 |
3 | package kotlinx.coroutines.debug.internal
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.DeleteClass
6 | import dev.reformator.bytecodeprocessor.intrinsics.fail
7 | import dev.reformator.stacktracedecoroutinator.runtimesettings.internal.getRuntimeSettingsValue
8 | import kotlin.coroutines.Continuation
9 | import kotlin.coroutines.jvm.internal.DecoroutinatorDebugProbesProvider
10 |
11 | @Suppress("unused")
12 | class DecoroutinatorDebugProbesProviderImpl: DecoroutinatorDebugProbesProvider {
13 | init {
14 | val enableCreationStackTraces = getRuntimeSettingsValue({ enableCreationStackTraces }) {
15 | System.getProperty(
16 | "dev.reformator.stacktracedecoroutinator.enableCreationStackTraces",
17 | "false"
18 | ).toBoolean()
19 | }
20 | val installDebugProbes = getRuntimeSettingsValue({ installDebugProbes }) {
21 | System.getProperty(
22 | "dev.reformator.stacktracedecoroutinator.installDebugProbes",
23 | "true"
24 | ).toBoolean()
25 | }
26 | AgentInstallationType.isInstalledStatically = true
27 | DebugProbesImpl.enableCreationStackTraces = enableCreationStackTraces
28 | if (installDebugProbes) {
29 | DebugProbesImpl.install()
30 | }
31 | }
32 |
33 | override fun probeCoroutineCreated(completion: Continuation): Continuation =
34 | DebugProbesImpl.probeCoroutineCreated(completion)
35 |
36 | override fun probeCoroutineResumed(frame: Continuation<*>) {
37 | DebugProbesImpl.probeCoroutineResumed(frame)
38 | }
39 |
40 | override fun probeCoroutineSuspended(frame: Continuation<*>) {
41 | DebugProbesImpl.probeCoroutineSuspended(frame)
42 | }
43 | }
44 |
45 | @DeleteClass
46 | @Suppress("UNUSED_PARAMETER")
47 | private object DebugProbesImpl {
48 | var enableCreationStackTraces: Boolean
49 | @JvmName("getEnableCreationStackTraces\$kotlinx_coroutines_core")
50 | get() = fail()
51 | @JvmName("setEnableCreationStackTraces\$kotlinx_coroutines_core")
52 | set(value) { fail() }
53 |
54 | @JvmName("install\$kotlinx_coroutines_core")
55 | fun install() { fail() }
56 |
57 | @JvmName("probeCoroutineCreated\$kotlinx_coroutines_core")
58 | fun probeCoroutineCreated(completion: Continuation): Continuation { fail() }
59 |
60 | @JvmName("probeCoroutineResumed\$kotlinx_coroutines_core")
61 | fun probeCoroutineResumed(frame: Continuation<*>) { fail() }
62 |
63 | @JvmName("probeCoroutineSuspended\$kotlinx_coroutines_core")
64 | fun probeCoroutineSuspended(frame: Continuation<*>) { fail() }
65 | }
66 |
67 | @DeleteClass
68 | @Suppress("UNUSED_PARAMETER")
69 | private object AgentInstallationType {
70 | var isInstalledStatically: Boolean
71 | @JvmName("isInstalledStatically\$kotlinx_coroutines_core")
72 | get() = fail()
73 | @JvmName("setInstalledStatically\$kotlinx_coroutines_core")
74 | set(value) { fail() }
75 | }
76 |
--------------------------------------------------------------------------------
/gradle-plugin/tests-gp/src/test/kotlin/tests-gradle-plugin.kt:
--------------------------------------------------------------------------------
1 | @file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
2 |
3 | package dev.reformator.stacktracedecoroutinator.gradleplugintests
4 |
5 | import dev.reformator.bytecodeprocessor.intrinsics.currentFileName
6 | import dev.reformator.bytecodeprocessor.intrinsics.currentLineNumber
7 | import dev.reformator.stacktracedecoroutinator.duplicatejar.*
8 | import dev.reformator.stacktracedecoroutinator.test.checkStacktrace
9 | import kotlinx.coroutines.flow.collect
10 | import kotlinx.coroutines.flow.flowOf
11 | import kotlinx.coroutines.flow.transform
12 | import kotlinx.coroutines.runBlocking
13 | import kotlinx.coroutines.suspendCancellableCoroutine
14 | import kotlinx.coroutines.yield
15 | import org.junit.jupiter.api.Assertions.*
16 | import kotlin.coroutines.resume
17 | import kotlin.test.Test
18 |
19 | class PerformanceTest: dev.reformator.stacktracedecoroutinator.test.PerformanceTest()
20 | class RuntimeTest: dev.reformator.stacktracedecoroutinator.test.RuntimeTest()
21 | class TailCallDeoptimizeTest: dev.reformator.stacktracedecoroutinator.test.TailCallDeoptimizeTest()
22 | class JvmTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTest()
23 | class JvmTailCallDeoptimizedTest: dev.reformator.stacktracedecoroutinator.testjvm.JvmTailCallDeoptimizedTest()
24 |
25 | class TestLocalFile {
26 | @Test
27 | fun localTest(): Unit = runBlocking {
28 | fun1()
29 | }
30 |
31 | @Test
32 | fun inlineTransformedClassForKotlinc() {
33 | runBlocking {
34 | flowOf(1)
35 | .transform { emit(it) }
36 | .collect()
37 | }
38 | }
39 |
40 | @Test
41 | fun transformedDuplicateEntityJar() {
42 | runBlocking {
43 | call {
44 | yield()
45 | checkStacktrace(StackTraceElement(
46 | duplicateJarCallClassName,
47 | duplicateJarCallMethodName,
48 | duplicateJarFileName,
49 | duplicateJarCallLineNumber
50 | ))
51 | }
52 | }
53 | }
54 |
55 | suspend fun fun1() {
56 | fun2(currentLineNumber)
57 | }
58 |
59 | suspend fun fun2(fun1LineNumber: Int) {
60 | val fun1Frame = StackTraceElement(
61 | TestLocalFile::class.qualifiedName,
62 | ::fun1.name,
63 | currentFileName,
64 | fun1LineNumber
65 | )
66 | yield()
67 | fun3(fun1Frame, currentLineNumber)
68 | }
69 |
70 | suspend fun fun3(fun1Frame: StackTraceElement, fun2LineNumber: Int) {
71 | val fun2Frame = StackTraceElement(
72 | TestLocalFile::class.qualifiedName,
73 | ::fun2.name,
74 | currentFileName,
75 | fun2LineNumber
76 | )
77 | yield()
78 | checkStacktrace(fun2Frame, fun1Frame)
79 | }
80 | }
81 |
82 | class DebugProbesTest {
83 | @Test
84 | fun performDebugProbes() {
85 | runBlocking {
86 | suspendCancellableCoroutine { continuation ->
87 | assertTrue(DebugProbesAccessor.dumpCoroutinesInfo().isNotEmpty())
88 | continuation.resume(Unit)
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------