Replace Kotlin reflection with Java reflection in Setter DSL for Mocking#736
Merged
Replace Kotlin reflection with Java reflection in Setter DSL for Mocking#736
Conversation
…mpatibility Jetpack Compose UI previews fail in Android Studio with Kotlin 2.3+ because layoutlib has a shaded kotlin-reflect that lacks K2 MetadataExtensions. This causes crashes when DataClassSetDsl calls KClass.isData or memberProperties. Changes: - Add DataClassJavaReflection.kt with Java reflection utilities: - isData: duck-type data class detection via copy$default/componentN methods - callCopy(): invoke copy$default with bitmask pattern for default params - getPropertyValue(): access properties via getters or field reflection - Update DataClassSetDsl to use Java reflection instead of Kotlin reflection - Add 25 tests covering core utilities and DSL integration JDK 22 compatibility: - Update Robolectric 4.10.3 -> 4.16.1 (older ASM can't read JDK 22 class files) - Add test AndroidManifest.xml files with tools:overrideLibrary to allow Robolectric's minSdk 21 test deps while keeping library minSdk at 16 Also includes: - Add publishing.gradle for custom Artifactory repository publishing
The buildPropertyIndexMap function was iterating through all fields (including body properties with backing fields) and matching them to componentN methods. When a body property had the same type and value as a constructor property (e.g., multiple Boolean = false fields), the body property could incorrectly "steal" the component slot. The fix iterates through componentN methods first (only constructor params have these), then finds the matching field for each. This ensures body properties don't get mapped since they lack componentN methods. Added tests for data classes with body properties to prevent regression. Version bump: 3.1.0-airbnb4 -> 3.1.0-airbnb5
Value-based field matching fails when R8 reorders fields and multiple fields share the same type and runtime value (e.g., Boolean body property becoming true after a prior callCopy sets a constructor parameter to true). This caused crashes in mock builders that call callCopy sequentially. Replace with two strategies: 1. Primary: Parse data class toString() output for parameter names in constructor order (names are string literals that survive R8) 2. Fallback: Mutation-probe disambiguation — temporarily change each candidate field's value to identify which one backs the componentN method Version bump: 3.1.0-airbnb5 -> 3.1.0-airbnb6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Jetpack Compose UI previews fail in Android Studio with Kotlin 2.3+ because layoutlib has a shaded kotlin-reflect that lacks K2 MetadataExtensions. This causes crashes when DataClassSetDsl calls KClass.isData or memberProperties.
Changes: