Skip to content

Commit

Permalink
Add an AffectedComposable class that provides the name and package of…
Browse files Browse the repository at this point in the history
… the composable
  • Loading branch information
jisungbin committed Nov 20, 2023
1 parent 337689a commit 3e24ff4
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
package land.sungbin.composeinvestigator.compiler.test.source

import androidx.compose.runtime.Composable
import land.sungbin.composeinvestigator.runtime.AffectedComposable
import land.sungbin.composeinvestigator.runtime.ComposeInvestigateLogType
import land.sungbin.composeinvestigator.runtime.ComposeInvestigateLogger

@ComposeInvestigateLogger
fun composeInvestigateLogger(composableName: String, logType: ComposeInvestigateLogType) {
fun composeInvestigateLogger(composable: AffectedComposable, logType: ComposeInvestigateLogType) {
when (logType) {
is ComposeInvestigateLogType.InvalidationProcessed -> {
println("<$composableName> InvalidationProcessed. DiffParams: ${logType.diffParams}")
println("<${composable.name} in ${composable.pkg}> InvalidationProcessed. DiffParams: ${logType.diffParams}")
}
is ComposeInvestigateLogType.InvalidationSkipped -> {
println("<$composableName> InvalidationSkipped")
println("<${composable.name} in ${composable.pkg}> InvalidationSkipped")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package land.sungbin.composeinvestigator.compiler.internal.logger

import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_AFFECTED_COMPOSABLE_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_LOG_TYPE_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_LOG_TYPE_INVALIDATION_PROCESSED_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_LOG_TYPE_INVALIDATION_SKIPPED_FQN
Expand All @@ -28,6 +29,8 @@ internal object InvestigateLogger {
private var loggerSymbol: IrSimpleFunctionSymbol? = null
private var loggerType: LoggerType? = null

private var affectedComposableSymbol: IrClassSymbol? = null

private var logTypeSymbol: IrClassSymbol? = null
private var logTypeInvalidationProcessedSymbol: IrClassSymbol? = null
private var logTypeInvalidationSkippedSymbol: IrClassSymbol? = null
Expand Down Expand Up @@ -58,7 +61,7 @@ internal object InvestigateLogger {
}

internal fun makeIrCall(
composableName: IrConst<String>,
composable: IrDeclarationReference,
logType: IrDeclarationReference,
originalMessage: IrConst<String>,
): IrCall =
Expand All @@ -72,12 +75,20 @@ internal object InvestigateLogger {
putValueArgument(0, originalMessage)
}
LoggerType.Custom -> {
putValueArgument(0, composableName)
putValueArgument(0, composable)
putValueArgument(1, logType)
}
}
}

internal fun obtainAffectedComposableSymbol(context: IrPluginContext): IrClassSymbol {
if (affectedComposableSymbol == null) {
affectedComposableSymbol =
context.referenceClass(ClassId.topLevel(COMPOSE_INVESTIGATE_AFFECTED_COMPOSABLE_FQN))
}
return affectedComposableSymbol!!
}

internal fun obtainLogTypeSymbol(context: IrPluginContext): IrClassSymbol {
if (logTypeSymbol == null) {
logTypeSymbol = context.referenceClass(ClassId.topLevel(COMPOSE_INVESTIGATE_LOG_TYPE_FQN))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package land.sungbin.composeinvestigator.compiler.internal.logger

import land.sungbin.composeinvestigator.compiler.internal.COMPOSABLE_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_AFFECTED_COMPOSABLE_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_LOGGER_FQN
import land.sungbin.composeinvestigator.compiler.internal.COMPOSE_INVESTIGATE_LOG_TYPE_FQN
import land.sungbin.composeinvestigator.compiler.internal.origin.InvestigateLoggerUsedFuntionOrigin
Expand All @@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.isString
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.hasAnnotation
Expand Down Expand Up @@ -51,7 +51,7 @@ internal class InvestigateLoggerVisitor(
// 4. no extension receiver and no context receiver
// 5. not suspend
// 6. unit type
// 7. has only two parameters: <String, LogType>
// 7. has only two parameters: <AffectedComposable, ComposeInvestigateLogType>
private fun IrFunction.isValidComposeInvestigateLoggerFunction(): Boolean =
hasAnnotation(COMPOSE_INVESTIGATE_LOGGER_FQN) &&
!hasAnnotation(COMPOSABLE_FQN) &&
Expand All @@ -62,6 +62,6 @@ internal class InvestigateLoggerVisitor(
!isSuspend &&
returnType.isUnit() &&
valueParameters.size == 2 &&
valueParameters[0].type.isString() &&
valueParameters[0].type.classFqName == COMPOSE_INVESTIGATE_AFFECTED_COMPOSABLE_FQN &&
valueParameters[1].type.classFqName == COMPOSE_INVESTIGATE_LOG_TYPE_FQN
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal val COMPOSER_FQN = FqName("$AndroidxComposeRuntime.Composer")
internal val COMPOSER_KT_FQN = FqName("$AndroidxComposeRuntime.ComposerKt")

internal val COMPOSE_INVESTIGATE_LOGGER_FQN = FqName("$ComposeInvestigatorRuntime.ComposeInvestigateLogger")
internal val COMPOSE_INVESTIGATE_AFFECTED_COMPOSABLE_FQN = FqName("$ComposeInvestigatorRuntime.AffectedComposable")
internal val COMPOSE_INVESTIGATE_LOG_TYPE_FQN = FqName("$ComposeInvestigatorRuntime.ComposeInvestigateLogType")
internal val COMPOSE_INVESTIGATE_LOG_TYPE_INVALIDATION_PROCESSED_FQN = COMPOSE_INVESTIGATE_LOG_TYPE_FQN.child(Name.identifier("InvalidationProcessed"))
internal val COMPOSE_INVESTIGATE_LOG_TYPE_INVALIDATION_SKIPPED_FQN = COMPOSE_INVESTIGATE_LOG_TYPE_FQN.child(Name.identifier("InvalidationSkipped"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrCall
Expand All @@ -23,9 +24,11 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.isInt
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.types.isString
import org.jetbrains.kotlin.ir.util.kotlinFqName
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.utils.addToStdlib.cast

internal abstract class AbstractInvalidationTrackingLower(context: IrPluginContext) :
Expand Down Expand Up @@ -74,6 +77,20 @@ internal abstract class AbstractInvalidationTrackingLower(context: IrPluginConte
return (currentFunctionOrNull ?: return "<unknown>").name.asString()
}

protected fun getCurrentFunctionPackage() = currentFunctionOrNull?.kotlinFqName?.asString() ?: "<unknown>"

protected fun getCurrentFunctionNameIntercepttedAnonymous(): String {
val currentFunctionName = currentFunctionOrNull?.name
return if (currentFunctionName == SpecialNames.ANONYMOUS) {
try {
val parent = currentFunction!!.irElement.cast<IrSimpleFunction>().parent
"${SpecialNames.ANONYMOUS_STRING} in ${parent.kotlinFqName.asString()}"
} catch (_: Exception) {
SpecialNames.ANONYMOUS_STRING
}
} else currentFunctionName?.asString() ?: "<unknown>"
}

protected fun irGetValue(value: IrValueDeclaration): IrGetValue =
IrGetValueImpl(
startOffset = UNDEFINED_OFFSET,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrCall
Expand All @@ -54,7 +53,6 @@ import org.jetbrains.kotlin.ir.util.isTopLevel
import org.jetbrains.kotlin.ir.util.kotlinFqName
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.cast

Expand Down Expand Up @@ -165,6 +163,14 @@ internal class InvalidationTrackableTransformer(
newStatements += computeDiffParamsIfPresentVariable

val originalLogMessage = irString("[INVALIDATION_TRACKER] <${getCurrentFunctionNameIntercepttedAnonymous()}> invalidation processed")
val affectedComposableSymbol = InvestigateLogger.obtainAffectedComposableSymbol(context)
val affectedComposableCall = IrConstructorCallImpl.fromSymbolOwner(
type = affectedComposableSymbol.owner.defaultType,
constructorSymbol = affectedComposableSymbol.constructors.single(),
).apply {
putValueArgument(0, irString(currentFunctionName))
putValueArgument(1, irString(getCurrentFunctionPackage()))
}
val logTypeSymbol = InvestigateLogger.obtainLogTypeSymbol(context)
val logTypeInvalidationProcessedSymbol = InvestigateLogger.obtainLogTypeInvalidationProcessedSymbol(context)
val logTypeCall = IrConstructorCallImpl.fromSymbolOwner(
Expand All @@ -174,7 +180,7 @@ internal class InvalidationTrackableTransformer(
putValueArgument(0, irGetValue(computeDiffParamsIfPresentVariable))
}
val loggerCall = InvestigateLogger.makeIrCall(
composableName = irString(currentFunctionName),
composable = affectedComposableCall,
logType = logTypeCall,
originalMessage = originalLogMessage,
)
Expand Down Expand Up @@ -218,6 +224,14 @@ internal class InvalidationTrackableTransformer(
// SKIP_TO_GROUP_END is declared in 'androidx.compose.runtime.Composer'
if (fnName == SKIP_TO_GROUP_END && fnParentFqn == COMPOSER_FQN) {
val originalLogMessage = irString("[INVALIDATION_TRACKER] <${getCurrentFunctionNameIntercepttedAnonymous()}> invalidation skipped")
val affectedComposableSymbol = InvestigateLogger.obtainAffectedComposableSymbol(context)
val affectedComposableCall = IrConstructorCallImpl.fromSymbolOwner(
type = affectedComposableSymbol.owner.defaultType,
constructorSymbol = affectedComposableSymbol.constructors.single(),
).apply {
putValueArgument(0, irString(currentFunctionName))
putValueArgument(1, irString(getCurrentFunctionPackage()))
}
val logTypeSymbol = InvestigateLogger.obtainLogTypeSymbol(context)
val logTypeInvalidationSkippedSymbol = InvestigateLogger.obtainLogTypeInvalidationSkippedSymbol(context)
val logTypeCall = IrGetObjectValueImpl(
Expand All @@ -227,7 +241,7 @@ internal class InvalidationTrackableTransformer(
symbol = logTypeInvalidationSkippedSymbol,
)
val loggerCall = InvestigateLogger.makeIrCall(
composableName = irString(currentFunctionName),
composable = affectedComposableCall,
logType = logTypeCall,
originalMessage = originalLogMessage,
)
Expand All @@ -247,18 +261,6 @@ internal class InvalidationTrackableTransformer(
return super.visitElseBranch(branch)
}

private fun getCurrentFunctionNameIntercepttedAnonymous(): String {
val currentFunctionName = currentFunctionOrNull?.name
return if (currentFunctionName == SpecialNames.ANONYMOUS) {
try {
val parent = currentFunction!!.irElement.cast<IrSimpleFunction>().parent
"${SpecialNames.ANONYMOUS_STRING} in ${parent.kotlinFqName.asString()}"
} catch (_: Exception) {
SpecialNames.ANONYMOUS_STRING
}
} else currentFunctionName?.asString() ?: "<unknown>"
}

private fun IrWhen.isComposerTrackBranch(): Boolean {
val branch = branches.singleOrNull() ?: return false
val `if` = (branch.condition as? IrCall ?: return false).symbol.owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ package land.sungbin.composeinvestigator.runtime
/**
* ```
* @ComposeInvestigateLogger
* public fun composeInvestigateLogger(composableName: String, logType: ComposeInvestigateLogType) {
* public fun composeInvestigateLogger(composable: AffectedComposable, logType: ComposeInvestigateLogType) {
* // Your logger code here
* }
* ```
Expand All @@ -20,6 +20,8 @@ package land.sungbin.composeinvestigator.runtime
@Target(AnnotationTarget.FUNCTION)
public annotation class ComposeInvestigateLogger

public data class AffectedComposable(public val name: String, public val pkg: String)

public sealed class ComposeInvestigateLogType {
public class InvalidationProcessed(public val diffParams: DiffParams?) : ComposeInvestigateLogType()
public data object InvalidationSkipped : ComposeInvestigateLogType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import land.sungbin.composeinvestigator.runtime.AffectedComposable
import land.sungbin.composeinvestigator.runtime.ComposeInvestigateLogType
import land.sungbin.composeinvestigator.runtime.ComposeInvestigateLogger

@Suppress("unused")
@ComposeInvestigateLogger
fun composeInvestigateLogger(composable: AffectedComposable, logType: ComposeInvestigateLogType) {
when (logType) {
is ComposeInvestigateLogType.InvalidationProcessed -> {
println("<${composable.name} in ${composable.pkg}> InvalidationProcessed. DiffParams: ${logType.diffParams}")
}
is ComposeInvestigateLogType.InvalidationSkipped -> {
println("<${composable.name} in ${composable.pkg}> InvalidationSkipped")
}
}
}

class SampleActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down

0 comments on commit 3e24ff4

Please sign in to comment.