Skip to content

Commit

Permalink
Upgrade Kotlin/Closure to Kotlin 2.1.0
Browse files Browse the repository at this point in the history
For now the standard library is being pinned to the previous version as there's
quite a few changes that need to be made as it's finally upgrading to K2.

This is largely all just compiler API changes, with a few tweaks to IR
deserialization provided by dramaix@.

One concerning change is that function inlining got quite a bit more verbose
with additional temporary variables being created. We'll likely need to follow
up on that as the code is now quite complicated to read and may inhibit the JSC
from optimizing as well as it otherwise could.

PiperOrigin-RevId: 714104373
  • Loading branch information
kevinoconnor7 authored and copybara-github committed Jan 10, 2025
1 parent bb73154 commit ac0c69f
Show file tree
Hide file tree
Showing 33 changed files with 754 additions and 754 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ class CompilationUnitBuilder(
is IrSetValue -> convertSetValue(irExpression)
is IrSetField -> convertSetField(irExpression)
is IrGetField -> convertGetField(irExpression)
is IrConst<*> -> convertConstant(irExpression)
is IrConst -> convertConstant(irExpression)
is IrTypeOperatorCall -> convertTypeOperatorCall(irExpression)
is IrGetEnumValue -> convertGetEnumValue(irExpression)
is IrFunctionAccessExpression -> convertFunctionAccessExpression(irExpression)
Expand Down Expand Up @@ -1207,7 +1207,7 @@ class CompilationUnitBuilder(
throw IllegalStateException("Unknown value ${target.render()}")
}

private fun convertConstant(irConst: IrConst<*>): Expression =
private fun convertConstant(irConst: IrConst): Expression =
environment.getTypeDescriptor(irConst.type).let { typeDescriptor ->
if (irConst.kind == IrConstKind.Null) typeDescriptor.nullValue
else Literal.fromValue(irConst.value, typeDescriptor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.configureSourceRoots
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.IncrementalCompilationApi
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.ModuleCompilerInput
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.compileModuleToAnalyzedFir
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.compileModuleToAnalyzedFirViaLightTreeIncrementally
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.convertToIrAndActualizeForJvm
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.createProjectEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.withModule
Expand Down Expand Up @@ -83,8 +84,6 @@ import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms

/** A parser for Kotlin sources that builds {@code CompilationtUnit}s. */
class KotlinParser(private val problems: Problems) {
Expand Down Expand Up @@ -195,21 +194,21 @@ class KotlinParser(private val problems: Problems) {
)

val module = compilerConfiguration.get(MODULES)!![0]
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter(messageCollector)

val analysisResults =
compileModuleToAnalyzedFir(
@OptIn(IncrementalCompilationApi::class)
compileModuleToAnalyzedFirViaLightTreeIncrementally(
projectEnvironment,
messageCollector,
compilerConfiguration,
ModuleCompilerInput(
TargetId(module),
collectSources(compilerConfiguration, projectEnvironment, messageCollector),
CommonPlatforms.defaultCommonPlatform,
JvmPlatforms.unspecifiedJvmPlatform,
compilerConfiguration,
),
projectEnvironment,
emptyList(),
null,
diagnosticsReporter,
incrementalExcludesScope = null,
)

diagnosticsReporter.maybeReportErrorsAndAbort(messageCollector, compilerConfiguration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.*
Expand All @@ -78,7 +77,6 @@ import org.jetbrains.kotlin.utils.memoryOptimizedMap

// Copied from org.jetbrains.kotlin.backend.jvm.serialization.IrBodyDeserializer to access internal
// api.
@Suppress("CheckReturnValue")
class IrBodyDeserializer(
private val builtIns: IrBuiltIns,
private val allowErrorNodes: Boolean,
Expand Down Expand Up @@ -259,14 +257,17 @@ class IrBodyDeserializer(
type: IrType,
): IrConstructorCall {
val symbol = deserializeTypedSymbol<IrConstructorSymbol>(proto.symbol, CONSTRUCTOR_SYMBOL)
return IrConstructorCallImpl(
return IrConstructorCallImplWithShape(
start,
end,
type,
symbol,
typeArgumentsCount = proto.memberAccess.typeArgumentCount,
constructorTypeArgumentsCount = proto.constructorTypeArgumentsCount,
valueArgumentsCount = proto.memberAccess.valueArgumentCount,
contextParameterCount = 0,
hasDispatchReceiver = proto.memberAccess.hasDispatchReceiver(),
hasExtensionReceiver = proto.memberAccess.hasExtensionReceiver(),
origin = deserializeIrStatementOrigin(proto.hasOriginName()) { proto.originName },
)
.also { deserializeMemberAccessCommon(it, proto.memberAccess) }
Expand All @@ -280,13 +281,16 @@ class IrBodyDeserializer(

val call: IrCall =
// TODO: implement the last three args here.
IrCallImpl(
IrCallImplWithShape(
start,
end,
type,
symbol,
proto.memberAccess.typeArgumentCount,
proto.memberAccess.valueArgumentList.size,
contextParameterCount = 0,
hasDispatchReceiver = proto.memberAccess.hasDispatchReceiver(),
hasExtensionReceiver = proto.memberAccess.hasExtensionReceiver(),
origin,
superSymbol,
)
Expand Down Expand Up @@ -315,13 +319,16 @@ class IrBodyDeserializer(
): IrDelegatingConstructorCall {
val symbol = deserializeTypedSymbol<IrConstructorSymbol>(proto.symbol, CONSTRUCTOR_SYMBOL)
val call =
IrDelegatingConstructorCallImpl(
IrDelegatingConstructorCallImplWithShape(
start,
end,
builtIns.unitType,
symbol,
proto.memberAccess.typeArgumentCount,
proto.memberAccess.valueArgumentCount,
contextParameterCount = 0,
hasDispatchReceiver = proto.memberAccess.hasDispatchReceiver(),
hasExtensionReceiver = proto.memberAccess.hasExtensionReceiver(),
)

deserializeMemberAccessCommon(call, proto.memberAccess)
Expand All @@ -335,13 +342,16 @@ class IrBodyDeserializer(
): IrEnumConstructorCall {
val symbol = deserializeTypedSymbol<IrConstructorSymbol>(proto.symbol, CONSTRUCTOR_SYMBOL)
val call =
IrEnumConstructorCallImpl(
IrEnumConstructorCallImplWithShape(
start,
end,
builtIns.unitType,
symbol,
proto.memberAccess.typeArgumentCount,
proto.memberAccess.valueArgumentCount,
contextParameterCount = 0,
hasDispatchReceiver = proto.memberAccess.hasDispatchReceiver(),
hasExtensionReceiver = proto.memberAccess.hasExtensionReceiver(),
)
deserializeMemberAccessCommon(call, proto.memberAccess)
return call
Expand Down Expand Up @@ -412,13 +422,16 @@ class IrBodyDeserializer(
proto.reflectionTargetSymbol
}
val callable =
IrFunctionReferenceImpl(
IrFunctionReferenceImplWithShape(
start,
end,
type,
symbol,
proto.memberAccess.typeArgumentCount,
proto.memberAccess.valueArgumentCount,
contextParameterCount = 0,
hasDispatchReceiver = proto.memberAccess.hasDispatchReceiver(),
hasExtensionReceiver = proto.memberAccess.hasExtensionReceiver(),
reflectionTarget,
origin,
)
Expand Down Expand Up @@ -551,11 +564,13 @@ class IrBodyDeserializer(
val origin = deserializeIrStatementOrigin(proto.hasOriginName()) { proto.originName }

val callable =
IrPropertyReferenceImpl(
IrPropertyReferenceImplWithShape(
start,
end,
type,
symbol,
proto.memberAccess.hasDispatchReceiver(),
proto.memberAccess.hasExtensionReceiver(),
proto.memberAccess.typeArgumentCount,
field,
getter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import org.jetbrains.kotlin.utils.*

// Copied and modified from
// org.jetbrains.kotlin.backend.jvm.serialization.IrDeclarationDeserializer.
@Suppress("CheckReturnValue")
@SuppressWarnings("CheckReturnValue")
class IrDeclarationDeserializer(
builtIns: IrBuiltIns,
private val symbolTable: SymbolTable,
Expand Down Expand Up @@ -112,6 +112,8 @@ class IrDeclarationDeserializer(
return makeTypeProjection(deserializeIrType(encoding.typeIndex), encoding.variance)
}

// Deserializes all annotations, even having SOURCE retention, since they might be needed in
// backends, like @Volatile
internal fun deserializeAnnotations(
annotations: List<ProtoConstructorCall>
): List<IrConstructorCall> {
Expand Down Expand Up @@ -321,7 +323,6 @@ class IrDeclarationDeserializer(

private fun deserializeIrValueParameter(
proto: ProtoValueParameter,
index: Int,
setParent: Boolean = true,
): IrValueParameter =
withDeserializedIrDeclarationBase(proto.base, setParent) {
Expand All @@ -342,7 +343,6 @@ class IrDeclarationDeserializer(
type = deserializeIrType(nameAndType.typeIndex),
isAssignable = flags.isAssignable,
symbol = symbol.checkSymbolType(fallbackSymbolKind = null),
index = index,
varargElementType =
if (proto.hasVarargElementType()) deserializeIrType(proto.varargElementType) else null,
isCrossinline = flags.isCrossInline,
Expand Down Expand Up @@ -401,6 +401,8 @@ class IrDeclarationDeserializer(

superTypes = proto.superTypeList.memoryOptimizedMap { deserializeIrType(it) }

// TODO(b/388547409): mapNotNullTo is perfectly valid to be unused.
@Suppress("CheckReturnValue")
withExternalValue(isExternal) {
val oldDeclarations = declarations.toSet()
proto.declarationList
Expand All @@ -413,7 +415,7 @@ class IrDeclarationDeserializer(
}
}

thisReceiver = deserializeIrValueParameter(proto.thisReceiver, -1)
thisReceiver = deserializeIrValueParameter(proto.thisReceiver)

// MODIFIED BY GOOGLE:
// Fir2IrLazyClass compute the valueClassRepresentation field and does not allow to modify
Expand Down Expand Up @@ -538,9 +540,7 @@ class IrDeclarationDeserializer(
private fun deserializeValueParameters(
protos: List<ProtoValueParameter>
): List<IrValueParameter> {
return protos.memoryOptimizedMapIndexed { index, proto ->
deserializeIrValueParameter(proto, index)
}
return protos.memoryOptimizedMap { proto -> deserializeIrValueParameter(proto) }
}

/**
Expand Down Expand Up @@ -641,12 +641,10 @@ class IrDeclarationDeserializer(
withBodyGuard {
valueParameters = deserializeValueParameters(proto.valueParameterList)
dispatchReceiverParameter =
if (proto.hasDispatchReceiver())
deserializeIrValueParameter(proto.dispatchReceiver, -1)
if (proto.hasDispatchReceiver()) deserializeIrValueParameter(proto.dispatchReceiver)
else null
extensionReceiverParameter =
if (proto.hasExtensionReceiver())
deserializeIrValueParameter(proto.extensionReceiver, -1)
if (proto.hasExtensionReceiver()) deserializeIrValueParameter(proto.extensionReceiver)
else null
contextReceiverParametersCount =
if (proto.hasContextReceiverParametersCount()) proto.contextReceiverParametersCount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.google.j2cl.transpiler.frontend.kotlin.ir

import java.lang.IllegalArgumentException
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant.Companion.ENHANCED_NULLABILITY_MARK
import org.jetbrains.kotlin.backend.common.serialization.signature.PublicIdSignatureComputer
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
Expand Down Expand Up @@ -140,21 +141,40 @@ class IrProviderFromPublicSignature(val pluginContext: IrPluginContext) : IrProv
signature: CommonSignature
): T = this!!.owner.declarations.filterIsInstance<T>().matchingSignature(signature)

private fun computeIdWithoutNullabilityAnnotation(signature: CommonSignature): Long? {
if (signature.id == null) {
return null
}
if (signature.toString().contains(ENHANCED_NULLABILITY_MARK)) {
// The declaration is coming from java. The enhanced nullability annotation is not part of the
// serialized IR
// and added by Kotlinc. Let's replace that marker by the simple nullability marker to avoid
// missing a match
return with(JvmIrMangler) {
signature.description!!.replace(ENHANCED_NULLABILITY_MARK, "?").hashMangle
}
}
return signature.id
}

private fun <T : IrDeclaration> Collection<T>.matchingSignature(signature: CommonSignature): T =
single {
singleOrNull {
val declarationSignature = irSignaturer.computeSignature(it).asPublic()!!
val declarationSignatureId = computeIdWithoutNullabilityAnnotation(declarationSignature)
val signatureId = computeIdWithoutNullabilityAnnotation(signature)

// When matching declarations that can be inherited, we need to use the id of the signature.
// This is because the symbol signature for a call on a child class to an inherited function
// differs from the signature of the function declared in the parent class, even though they
// represent the same underlying declaration. Using the id ensures consistent matching
// across inheritance hierarchies.
if (signature.id != null) {
signature.id == declarationSignature.id
if (signatureId != null) {
signatureId == declarationSignatureId
} else {
// Signature of declaration that cannot be inherited (like enum entries) does not have id.
signature == declarationSignature
}
}
} ?: error("Signature $signature not found")

private fun <T : IrDeclaration> Collection<IrBindableSymbol<*, T>>.matchingDeclarationSignature(
signature: CommonSignature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrBreakContinue
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
Expand Down Expand Up @@ -492,7 +491,7 @@ fun IrClass.getWasmInfo(): String? = (this as IrDeclaration).getWasmInfo()

private fun IrDeclaration.getWasmInfo(): String? =
findAnnotation(WASM_ANNOTATION_FQ_NAME)
?.getValueArgumentAsConst(WASM_ANNOTATION_VALUE_NAME, IrConstKind.String)
?.getValueArgumentAsConst<String>(WASM_ANNOTATION_VALUE_NAME)

private val WASM_ANNOTATION_FQ_NAME: FqName = FqName(WASM_ANNOTATION_NAME)
private val WASM_ANNOTATION_VALUE_NAME = Name.identifier("value")
Expand All @@ -507,10 +506,8 @@ private fun IrDeclaration.findAnnotation(name: FqName): IrConstructorCall? {
}
}

fun <T> IrConstructorCall.getValueArgumentAsConst(name: Name, kind: IrConstKind<T>): T? {
val valueArgumentAsConst = getValueArgument(name) as? IrConst<*> ?: return null
return kind.valueOf(valueArgumentAsConst)
}
inline fun <reified T> IrConstructorCall.getValueArgumentAsConst(name: Name): T? =
(getValueArgument(name) as? IrConst)?.value as T?

val IrDeclaration.isSynthetic
get() =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.isUnit
Expand Down Expand Up @@ -121,10 +120,10 @@ private val IrField.canBeJsProperty: Boolean
private val IrConstructorCall.jsAnnotationInfo: JsAnnotationInfo
get() =
JsAnnotationInfo(
getValueArgumentAsConst(Name.identifier("name"), IrConstKind.String),
getValueArgumentAsConst(Name.identifier("namespace"), IrConstKind.String),
(getValueArgumentAsConst(Name.identifier("isNative"), IrConstKind.Boolean) ?: false),
(getValueArgumentAsConst(Name.identifier("hasCustomValue"), IrConstKind.Boolean) ?: false),
getValueArgumentAsConst<String>(Name.identifier("name")),
getValueArgumentAsConst<String>(Name.identifier("namespace")),
(getValueArgumentAsConst<Boolean>(Name.identifier("isNative")) ?: false),
(getValueArgumentAsConst<Boolean>(Name.identifier("hasCustomValue")) ?: false),
)

fun IrClass.getJsEnumInfo(): JsEnumInfo? {
Expand Down
Loading

0 comments on commit ac0c69f

Please sign in to comment.