Skip to content

Commit 2b049be

Browse files
authored
Improved handling of typealiases (#106)
* Improved handling of typealiases * Improved documentation and adjusted tests * Avoid catching Throwable in typealias expansion * Fix typealias & function-type detection in stability analyzer * Fixed typo in Immutable collection name detection * Corrected arrow detection * Improved resolutions of typealiases in other files, classes, objects or modules * Fix false runtime-stability warnings in K2 when @composable typealiases resolve to ComposableFunctionN * Added safeguard against StackOverflowError during analysis of complex types * Corrected imports in tests * Added guard for simple-name function fallback * Rolled back broad exception handling in ktStabilityOfInternal, now checking only for Stack Overflow
1 parent 87f2762 commit 2b049be

8 files changed

Lines changed: 1296 additions & 27 deletions

File tree

compose-stability-analyzer-idea/src/main/kotlin/com/skydoves/compose/stability/idea/StabilityAnalysisConstants.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@ internal object StabilityAnalysisConstants {
232232
"MessageLite",
233233
)
234234

235+
// K2 sometimes fails to provide classId / fqName for Kotlin FunctionN interfaces,
236+
// but the symbol still has a simple name like "Function0/SuspendFunction1/ComposableFunction2".
237+
// So we fall back to a identifying them as mutable interfaces and reporting runtime stability
238+
private val FUNCTION_SIMPLE_NAME_REGEX = Regex("^(K)?Function\\d+$")
239+
private val SUSPEND_FUNCTION_SIMPLE_NAME_REGEX = Regex("^SuspendFunction\\d+$")
240+
private val COMPOSABLE_FUNCTION_SIMPLE_NAME_REGEX = Regex("^ComposableFunction\\d+$")
241+
235242
/**
236243
* Check if a type's simple name is a known stable type.
237244
*/
@@ -267,12 +274,19 @@ internal object StabilityAnalysisConstants {
267274
return fqName in PRIMITIVE_TYPE_FQ_NAMES
268275
}
269276

277+
internal fun isFunctionTypeBySimpleName(simpleName: String): Boolean {
278+
return FUNCTION_SIMPLE_NAME_REGEX.matches(simpleName) ||
279+
SUSPEND_FUNCTION_SIMPLE_NAME_REGEX.matches(simpleName) ||
280+
COMPOSABLE_FUNCTION_SIMPLE_NAME_REGEX.matches(simpleName)
281+
}
282+
270283
/**
271284
* Check if FqName is a function type.
272285
*/
273286
internal fun isFunctionType(fqName: String): Boolean {
274287
return fqName.startsWith("kotlin.Function") ||
275288
fqName.startsWith("kotlin.jvm.functions.Function") ||
276-
fqName.startsWith("kotlin.coroutines.SuspendFunction")
289+
fqName.startsWith("kotlin.coroutines.SuspendFunction") ||
290+
fqName.startsWith("androidx.compose.runtime.internal.ComposableFunction")
277291
}
278292
}

0 commit comments

Comments
 (0)