Skip to content

Commit 6777cab

Browse files
committed
refactor: update field generation logic and improve logging in compiler extensions /
fix multiple generations and errors in same constructor call for different qualifiers
1 parent ce9af36 commit 6777cab

File tree

4 files changed

+33
-16
lines changed

4 files changed

+33
-16
lines changed

compiler-plugin/src/main/kotlin/io/github/stslex/compiler_plugin/DistinctChangeCache.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@ import io.github.stslex.compiler_plugin.model.DistinctChangeConfig
44
import io.github.stslex.compiler_plugin.utils.RuntimeLogger
55
import org.jetbrains.kotlin.utils.addToStdlib.runIf
66

7-
internal class DistinctChangeCache(
8-
private val config: DistinctChangeConfig
9-
) {
7+
internal const val GENERATED_FIELD_NAME = "_generatedField"
8+
9+
internal class DistinctChangeCache {
1010

1111
private val cache = mutableMapOf<String, Pair<List<Any?>, Any?>>()
12-
private val logger = runIf(config.logging) { RuntimeLogger.tag("DistinctChangeLogger") }
1312

1413
@Suppress("UNCHECKED_CAST")
1514
internal operator fun <R> invoke(
1615
key: String,
1716
args: List<Any?>,
17+
config: DistinctChangeConfig,
1818
body: () -> R,
1919
): R {
2020
val entry = cache[key]
21+
val logger = runIf(config.logging) { RuntimeLogger.tag("DistinctChangeLogger") }
2122

2223
logger?.i("name: ${config.name} key: $key, config:$config, entry: $entry, args: $args")
2324

compiler-plugin/src/main/kotlin/io/github/stslex/compiler_plugin/transformers/IrFunctionTransformer.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal class IrFunctionTransformer(
4949
val argsListExpr = pluginContext.buildArgsListExpression(declaration)
5050
val lambdaExpr = pluginContext.buildLambdaForBody(originalBody, declaration)
5151

52-
val backingField = pluginContext.generateFields(declaration, qualifierArgs, logger)
52+
val backingField = pluginContext.generateFields(declaration, logger)
5353

5454
logger.i("backingField = $backingField")
5555
val memoizeCall = pluginContext.buildSaveInCacheCall(
@@ -58,7 +58,8 @@ internal class IrFunctionTransformer(
5858
lambdaExpr = lambdaExpr,
5959
function = declaration,
6060
backingField = backingField,
61-
logger = logger
61+
logger = logger,
62+
qualifierArgs = qualifierArgs
6263
)
6364

6465
declaration.body = pluginContext.irFactory.createExpressionBody(memoizeCall)

compiler-plugin/src/main/kotlin/io/github/stslex/compiler_plugin/utils/CompilerExtensions.kt

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package io.github.stslex.compiler_plugin.utils
22

33
import io.github.stslex.compiler_plugin.DistinctChangeCache
4+
import io.github.stslex.compiler_plugin.GENERATED_FIELD_NAME
45
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
56
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
67
import org.jetbrains.kotlin.backend.jvm.ir.fileParentOrNull
78
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
89
import org.jetbrains.kotlin.descriptors.Modality
10+
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
911
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
1012
import org.jetbrains.kotlin.ir.declarations.IrClass
1113
import org.jetbrains.kotlin.ir.declarations.IrConstructor
@@ -116,7 +118,8 @@ internal fun IrPluginContext.buildSaveInCacheCall(
116118
lambdaExpr: IrExpression,
117119
function: IrSimpleFunction,
118120
logger: CompileLogger,
119-
backingField: IrFieldSymbolImpl
121+
backingField: IrFieldSymbolImpl,
122+
qualifierArgs: IrExpression
120123
): IrExpression {
121124
logger.i("buildSaveInCacheCall for ${function.name}, args: ${argsListExpr.dump()}")
122125

@@ -150,7 +153,7 @@ internal fun IrPluginContext.buildSaveInCacheCall(
150153
type = function.returnType,
151154
symbol = invokeFunSymbol.symbol,
152155
typeArgumentsCount = 1,
153-
valueArgumentsCount = 3,
156+
valueArgumentsCount = 4,
154157
origin = null
155158
)
156159
.also { it.patchDeclarationParents(function.parent) }
@@ -160,21 +163,36 @@ internal fun IrPluginContext.buildSaveInCacheCall(
160163
putTypeArgument(0, function.returnType)
161164
putValueArgument(0, keyLiteral)
162165
putValueArgument(1, argsListExpr)
163-
putValueArgument(2, lambdaExpr)
166+
putValueArgument(2, qualifierArgs)
167+
putValueArgument(3, lambdaExpr)
164168
}
165169
}
166170

167-
@OptIn(UnsafeDuringIrConstructionAPI::class)
171+
@OptIn(UnsafeDuringIrConstructionAPI::class, ObsoleteDescriptorBasedAPI::class)
168172
internal fun IrPluginContext.generateFields(
169173
function: IrSimpleFunction,
170-
qualifierArgs: IrExpression,
171174
logger: CompileLogger
172175
): IrFieldSymbolImpl {
173176
logger.i("generateFields for ${function.name} parent: ${function.file}")
174177

175178
val parentClass = function.parentClassOrNull
176179
val parentFile = function.fileParentOrNull
177180

181+
// check if parentClass or parentFile already contains _generatedField
182+
val createdField = when {
183+
parentClass != null -> parentClass.declarations.find {
184+
it.descriptor.name.identifierOrNullIfSpecial == GENERATED_FIELD_NAME
185+
}
186+
187+
parentFile != null -> parentFile.declarations.find {
188+
it.descriptor.name.identifierOrNullIfSpecial == GENERATED_FIELD_NAME
189+
}
190+
191+
else -> null
192+
}?.symbol as? IrFieldSymbolImpl
193+
194+
if (createdField != null) return createdField
195+
178196
val errorNotFound =
179197
"function ${function.name} in ${function.file} couldn't be used with @DistinctUntilChangeFun"
180198

@@ -194,7 +212,7 @@ internal fun IrPluginContext.generateFields(
194212
endOffset = endOffset,
195213
origin = IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
196214
symbol = fieldSymbol,
197-
name = Name.identifier("_distinctCache"),
215+
name = Name.identifier(GENERATED_FIELD_NAME),
198216
type = distinctChangeClass.defaultType,
199217
visibility = DescriptorVisibilities.PRIVATE,
200218
isFinal = true,
@@ -213,9 +231,6 @@ internal fun IrPluginContext.generateFields(
213231
type = distinctChangeClass.defaultType,
214232
constructorSymbol = constructorSymbol.symbol
215233
)
216-
.apply {
217-
putValueArgument(0, qualifierArgs)
218-
}
219234

220235
backingField.parent = function.parent
221236
backingField.initializer = irFactory.createExpressionBody(callDistInit)

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ activity = "1.10.0"
1414
constraintLayout = "2.2.0"
1515
jetbrainsKotlinJvm = "2.0.20"
1616

17-
stslexCompilerPlugin = "0.0.4"
17+
stslexCompilerPlugin = "0.0.5"
1818

1919
[libraries]
2020
android-desugarJdkLibs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }

0 commit comments

Comments
 (0)