Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
# Keep past dev versions too; try to target active versions of IntelliJ based on tags in
# https://github.com/JetBrains/kotlin. Can also use
# https://github.com/ZacSweers/metro/blob/main/docs/compatibility.md as a reference.
poko_sample_kotlin_version: [ 2.4.0-dev-2124, 2.4.0, ~, 2.4.20-dev-4664, 2.4.20 ]
poko_sample_kotlin_version: [ 2.4.0-dev-2124, 2.4.0, 2.4.10, 2.4.20-dev-4664, ~ ]
env:
poko_sample_kotlin_version: ${{ matrix.poko_sample_kotlin_version }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

androidx-compose-runtime = "1.12.1"

kotlin = "2.4.10"
kotlin = "2.4.20"
kotlinCompileTesting = "1.6.0"
# https://central.sonatype.com/artifact/dev.zacsweers.kctfork/core/versions:
kotlinCompileTestingFork = "0.13.0"
Expand Down
16 changes: 8 additions & 8 deletions kotlin-js-store/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ js-yaml@^4.1.0:
dependencies:
argparse "^2.0.1"

kotlin-web-helpers@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-3.0.0.tgz#3ed6b48f694f74bb60a737a9d7e2c0e3b29abdb9"
integrity sha512-kdQO4AJQkUPvpLh9aglkXDRyN+CfXO7pKq+GESEnxooBFkQpytLrqZis3ABvmFN1cGw/ZQ/K38u5sRGW+NfBnw==
kotlin-web-helpers@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/kotlin-web-helpers/-/kotlin-web-helpers-3.3.0.tgz#4c0bf6bcfa64752f6f1531e4c84583943bc7e9d6"
integrity sha512-sXnwHZ2YGMtIia+NQlf/c0UDtwVNHhXsIH+uHkTv87AvvZQJjJ+XbdkvUUuomPWgBC5TgcQLDEGLcjL48QkFkQ==
dependencies:
format-util "^1.0.5"

Expand Down Expand Up @@ -293,10 +293,10 @@ minimatch@^9.0.4, minimatch@^9.0.5:
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.3.tgz#79389b4eb1bb2d003a9bba87d492f2bd37bdc65b"
integrity sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==

mocha@11.7.5:
version "11.7.5"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.7.5.tgz#58f5bbfa5e0211ce7e5ee6128107cefc2515a627"
integrity sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==
mocha@11.7.6:
version "11.7.6"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.7.6.tgz#ebbe22989d04cbb9424a36307320476624c41a33"
integrity sha512-nS9xOGbw2I3cjCpxwZAEJ9xK9lmJ08vEkQvLtz4du9ZrF9UrjRpeJGiIgl2Z+Qs++pmB4ecDe48Fwsh+j+j7xA==
dependencies:
browser-stdout "^1.3.1"
chokidar "^4.0.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package dev.drewhamilton.poko

import com.google.auto.service.AutoService
import dev.drewhamilton.poko.BuildConfig.DEFAULT_POKO_FIR_IDE_MODE
import dev.drewhamilton.poko.BuildConfig.DEFAULT_POKO_ANNOTATION
import dev.drewhamilton.poko.BuildConfig.DEFAULT_POKO_ENABLED
import dev.drewhamilton.poko.BuildConfig.DEFAULT_POKO_FIR_IDE_MODE
import dev.drewhamilton.poko.fir.PokoFirExtensionRegistrar
import dev.drewhamilton.poko.ir.PokoIrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
import org.jetbrains.kotlin.name.ClassId
Expand All @@ -34,15 +32,9 @@ public class PokoCompilerPluginRegistrar : CompilerPluginRegistrar() {
FirIdeMode.valueOf(DEFAULT_POKO_FIR_IDE_MODE),
)

val messageCollector = configuration.get(
CommonConfigurationKeys.MESSAGE_COLLECTOR_KEY,
MessageCollector.NONE,
)

IrGenerationExtension.registerExtension(
PokoIrGenerationExtension(
pokoAnnotationName = pokoAnnotationClassId,
messageCollector = messageCollector,
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import dev.drewhamilton.poko.fir.PokoKey
import org.jetbrains.kotlin.GeneratedDeclarationKey
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
Expand All @@ -26,7 +25,6 @@ import org.jetbrains.kotlin.name.ClassId
internal class PokoFunctionBodyFiller(
private val pokoAnnotation: ClassId,
private val context: IrPluginContext,
private val messageCollector: MessageCollector,
) : IrVisitorVoid() {

override fun visitSimpleFunction(declaration: IrSimpleFunction) {
Expand All @@ -47,8 +45,7 @@ internal class PokoFunctionBodyFiller(
val pokoClass = declaration.parentAsClass
val pokoProperties = pokoClass.pokoProperties(pokoAnnotation).also {
if (it.isEmpty()) {
messageCollector.log("No primary constructor properties")
messageCollector.reportErrorOnClass(
context.diagnosticReporter.reportErrorOnClass(
irClass = pokoClass,
message = "Poko class primary constructor must have at least one not-skipped property",
)
Expand All @@ -66,15 +63,13 @@ internal class PokoFunctionBodyFiller(
irClass = pokoClass,
functionDeclaration = declaration,
classProperties = pokoProperties,
messageCollector = messageCollector,
)

PokoFunction.HashCode -> generateHashCodeMethodBody(
pokoAnnotation = pokoAnnotation,
context = this@PokoFunctionBodyFiller.context,
functionDeclaration = declaration,
classProperties = pokoProperties,
messageCollector = messageCollector,
)

PokoFunction.ToString -> generateToStringMethodBody(
Expand All @@ -83,7 +78,6 @@ internal class PokoFunctionBodyFiller(
irClass = pokoClass,
functionDeclaration = declaration,
classProperties = pokoProperties,
messageCollector = messageCollector,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,28 @@ package dev.drewhamilton.poko.ir

import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.validation.IrValidationSeverity
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.ClassId

internal class PokoIrGenerationExtension(
private val pokoAnnotationName: ClassId,
private val messageCollector: MessageCollector
) : IrGenerationExtension {

override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
if (pluginContext.referenceClass(pokoAnnotationName) == null) {
moduleFragment.reportError("Could not find class <$pokoAnnotationName>")
pluginContext.diagnosticReporter.report(
factory = IrValidationSeverity.ERROR.factory,
message = "Could not find class <$pokoAnnotationName>",
)
return
}

val bodyFiller = PokoFunctionBodyFiller(
pokoAnnotation = pokoAnnotationName,
context = pluginContext,
messageCollector = messageCollector,
)
moduleFragment.acceptChildrenVoid(bodyFiller)
}

private fun IrModuleFragment.reportError(message: String) {
val psi = descriptor.findPsi()
val location = MessageUtil.psiElementToMessageLocation(psi)
messageCollector.report(CompilerMessageSeverity.ERROR, message, location)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package dev.drewhamilton.poko.ir
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irBranch
Expand Down Expand Up @@ -55,7 +54,6 @@ internal fun IrBlockBodyBuilder.generateEqualsMethodBody(
irClass: IrClass,
functionDeclaration: IrFunction,
classProperties: List<IrProperty>,
messageCollector: MessageCollector,
) {
val irType = irClass.defaultType
fun irOther(): IrExpression = IrGetValueImpl(
Expand All @@ -78,7 +76,6 @@ internal fun IrBlockBodyBuilder.generateEqualsMethodBody(
receiver = arg1,
argument = arg2,
property = property,
messageCollector = messageCollector,
),
)
}
Expand All @@ -102,7 +99,6 @@ private fun IrBuilderWithScope.irArrayContentDeepEquals(
receiver: IrExpression,
argument: IrExpression,
property: IrProperty,
messageCollector: MessageCollector,
): IrExpression {
val propertyType = property.type
val propertyClassifier = propertyType.classifierOrFail
Expand All @@ -113,7 +109,7 @@ private fun IrBuilderWithScope.irArrayContentDeepEquals(
return if (mayBeRuntimeArray) {
irRuntimeArrayContentDeepEquals(context, receiver, argument)
} else {
messageCollector.reportErrorOnProperty(
context.diagnosticReporter.reportErrorOnProperty(
property = property,
message = "@ReadArrayContent is only supported on properties with array type or `Any` type",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package dev.drewhamilton.poko.ir
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
import org.jetbrains.kotlin.ir.builders.irBranch
import org.jetbrains.kotlin.ir.builders.irCall
Expand Down Expand Up @@ -54,7 +53,6 @@ internal fun IrBlockBodyBuilder.generateHashCodeMethodBody(
context: IrPluginContext,
functionDeclaration: IrFunction,
classProperties: List<IrProperty>,
messageCollector: MessageCollector,
) {
if (classProperties.isEmpty()) {
+irReturn(irInt(0))
Expand All @@ -66,7 +64,6 @@ internal fun IrBlockBodyBuilder.generateHashCodeMethodBody(
context = context,
function = functionDeclaration,
property = classProperties[0],
messageCollector = messageCollector,
),
)
return
Expand All @@ -91,7 +88,6 @@ internal fun IrBlockBodyBuilder.generateHashCodeMethodBody(
context = context,
function = functionDeclaration,
property = classProperties[0],
messageCollector = messageCollector,
)
}
+irResultVar
Expand All @@ -112,7 +108,6 @@ internal fun IrBlockBodyBuilder.generateHashCodeMethodBody(
context = context,
function = functionDeclaration,
property = property,
messageCollector = messageCollector,
),
)
+irSet(irResultVar.symbol, rhs)
Expand All @@ -130,7 +125,6 @@ private fun IrBlockBodyBuilder.getHashCodeOfProperty(
context: IrPluginContext,
function: IrFunction,
property: IrProperty,
messageCollector: MessageCollector,
): IrExpression {
val field = property.backingField!!
val irGetField = { irGetField(receiver(function), field) }
Expand All @@ -139,9 +133,9 @@ private fun IrBlockBodyBuilder.getHashCodeOfProperty(
type = context.irBuiltIns.intType,
subject = irGetField(),
thenPart = irInt(0),
elsePart = getHashCodeOf(pokoAnnotation, context, property, irGetField(), messageCollector)
elsePart = getHashCodeOf(pokoAnnotation, context, property, irGetField())
)
else -> getHashCodeOf(pokoAnnotation, context, property, irGetField(), messageCollector)
else -> getHashCodeOf(pokoAnnotation, context, property, irGetField())
}
}

Expand All @@ -155,7 +149,6 @@ private fun IrBlockBodyBuilder.getHashCodeOf(
context: IrPluginContext,
property: IrProperty,
value: IrExpression,
messageCollector: MessageCollector,
): IrExpression {
// Fast path for integers which are already their own hashCode value.
if (property.type.isInt()) {
Expand All @@ -179,7 +172,7 @@ private fun IrBlockBodyBuilder.getHashCodeOf(

// Non-null if content-based hashCode will be used, else null:
val contentHashCodeFunctionSymbol = if (hasReadArrayContentAnnotation) {
maybeFindArrayContentHashCodeFunction(context, property, messageCollector)
maybeFindArrayContentHashCodeFunction(context, property)
} else {
null
}
Expand Down Expand Up @@ -273,13 +266,12 @@ private fun IrBlockBodyBuilder.irArrayTypeCheckAndContentDeepHashCodeBranch(
private fun maybeFindArrayContentHashCodeFunction(
context: IrPluginContext,
property: IrProperty,
messageCollector: MessageCollector,
): IrSimpleFunctionSymbol? {
val propertyClassifier = property.type.classifierOrFail

val isArray = propertyClassifier.isArrayOrPrimitiveArray(context.irBuiltIns)
if (!isArray) {
messageCollector.reportErrorOnProperty(
context.diagnosticReporter.reportErrorOnProperty(
property = property,
message = "@ReadArrayContent is only supported on properties with array type or `Any` type",
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
package dev.drewhamilton.poko.ir

import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.ir.IrDiagnosticReporter
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.validation.IrValidationSeverity
import org.jetbrains.kotlin.resolve.source.getPsi

internal fun MessageCollector.log(message: String) {
report(CompilerMessageSeverity.LOGGING, "POKO COMPILER PLUGIN (IR): $message")
}

internal fun MessageCollector.reportErrorOnClass(irClass: IrClass, message: String) {
internal fun IrDiagnosticReporter.reportErrorOnClass(irClass: IrClass, message: String) {
val psi = irClass.source.getPsi()
val location = MessageUtil.psiElementToMessageLocation(psi)
report(CompilerMessageSeverity.ERROR, message, location)
report(IrValidationSeverity.ERROR.factory, message, location)
}

@OptIn(ObsoleteDescriptorBasedAPI::class) // Only needed for non-K2 compilation
internal fun MessageCollector.reportErrorOnProperty(property: IrProperty, message: String) {
@OptIn(ObsoleteDescriptorBasedAPI::class) // TODO: Try to do this without the descriptor
internal fun IrDiagnosticReporter.reportErrorOnProperty(property: IrProperty, message: String) {
val psi = property.descriptor.source.getPsi()
val location = MessageUtil.psiElementToMessageLocation(psi)
report(CompilerMessageSeverity.ERROR, message, location)
report(IrValidationSeverity.ERROR.factory, message, location)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dev.drewhamilton.poko.ir

import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.builders.IrBlockBodyBuilder
import org.jetbrains.kotlin.ir.builders.irBranch
import org.jetbrains.kotlin.ir.builders.irCall
Expand Down Expand Up @@ -48,7 +47,6 @@ internal fun IrBlockBodyBuilder.generateToStringMethodBody(
irClass: IrClass,
functionDeclaration: IrFunction,
classProperties: List<IrProperty>,
messageCollector: MessageCollector,
) {
val irConcat = irConcat()
irConcat.addArgument(irString(irClass.name.asString() + "("))
Expand All @@ -74,7 +72,6 @@ internal fun IrBlockBodyBuilder.generateToStringMethodBody(
val toStringFunctionSymbol = maybeFindArrayDeepToStringFunction(
context = context,
property = property,
messageCollector = messageCollector
) ?: context.irBuiltIns.dataClassArrayMemberToStringSymbol
irCallToStringFunction(
toStringFunctionSymbol = toStringFunctionSymbol,
Expand Down Expand Up @@ -107,13 +104,12 @@ internal fun IrBlockBodyBuilder.generateToStringMethodBody(
private fun maybeFindArrayDeepToStringFunction(
context: IrPluginContext,
property: IrProperty,
messageCollector: MessageCollector,
): IrSimpleFunctionSymbol? {
val propertyClassifier = property.type.classifierOrFail

val isArray = propertyClassifier.isArrayOrPrimitiveArray(context.irBuiltIns)
if (!isArray) {
messageCollector.reportErrorOnProperty(
context.diagnosticReporter.reportErrorOnProperty(
property = property,
message = "@ReadArrayContent is only supported on properties with array type or `Any` type",
)
Expand Down
Loading