[IR] Add a kdoc for IrValueParameter.isHidden

This commit is contained in:
Sergej Jaskiewicz
2023-05-23 11:50:24 +02:00
committed by Space Team
parent 9a77632f1c
commit 2fc5316c1b
7 changed files with 78 additions and 11 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -35,6 +36,36 @@ abstract class IrValueParameter : IrDeclarationBase(), IrValueDeclaration {
abstract var isNoinline: Boolean
/**
* If `true`, the value parameter does not participate in [IdSignature] computation.
*
* This is a workaround that is needed for better support of compiler plugins.
* Suppose you have the following code and some IR plugin that adds a value parameter to
* functions
* marked with the `@PluginMarker` annotation.
* ```kotlin
* @PluginMarker
* fun foo(defined: Int) { /* ... */ }
* ```
*
* Suppose that after applying the plugin the function is changed to:
* ```kotlin
* @PluginMarker
* fun foo(defined: Int, $extra: String) { /* ... */ }
* ```
*
* If a compiler plugin adds parameters to an [IrFunction],
* the representations of the function in the frontend and in the backend may diverge,
* potentially causing signature mismatch and
* linkage errors (see [KT-40980](https://youtrack.jetbrains.com/issue/KT-40980)).
* We wouldn't want IR plugins to affect the frontend representation, since in an IDE you'd want
* to be able to see those
* declarations in their original form (without the `$extra` parameter).
*
* To fix this problem, [isHidden] was introduced.
*
* TODO: consider dropping [isHidden] if it isn't used by any known plugin.
*/
abstract var isHidden: Boolean
abstract var defaultValue: IrExpressionBody?
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.ir.generator
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
@@ -23,6 +20,7 @@ import org.jetbrains.kotlin.ir.generator.config.SimpleFieldConfig
import org.jetbrains.kotlin.ir.generator.model.Element.Companion.elementName2typeName
import org.jetbrains.kotlin.ir.generator.print.toPoet
import org.jetbrains.kotlin.ir.generator.util.*
import org.jetbrains.kotlin.ir.generator.util.Import
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
@@ -165,11 +163,36 @@ object IrTree : AbstractTreeBuilder() {
+field("varargElementType", irTypeType, nullable = true)
+field("isCrossinline", boolean)
+field("isNoinline", boolean)
// if true parameter is not included into IdSignature.
// Skipping hidden params makes IrFunction be look similar to FE.
// NOTE: it is introduced to fix KT-40980 because more clear solution was not possible to implement.
// Once we are able to load any top-level declaration from klib this hack should be deprecated and removed.
+field("isHidden", boolean)
+field("isHidden", boolean) {
additionalImports.add(Import("org.jetbrains.kotlin.ir.util", "IdSignature"))
kdoc = """
If `true`, the value parameter does not participate in [IdSignature] computation.
This is a workaround that is needed for better support of compiler plugins.
Suppose you have the following code and some IR plugin that adds a value parameter to functions
marked with the `@PluginMarker` annotation.
```kotlin
@PluginMarker
fun foo(defined: Int) { /* ... */ }
```
Suppose that after applying the plugin the function is changed to:
```kotlin
@PluginMarker
fun foo(defined: Int, ${'$'}extra: String) { /* ... */ }
```
If a compiler plugin adds parameters to an [${elementName2typeName(function.name)}],
the representations of the function in the frontend and in the backend may diverge, potentially causing signature mismatch and
linkage errors (see [KT-40980](https://youtrack.jetbrains.com/issue/KT-40980)).
We wouldn't want IR plugins to affect the frontend representation, since in an IDE you'd want to be able to see those
declarations in their original form (without the `${'$'}extra` parameter).
To fix this problem, [$name] was introduced.
TODO: consider dropping [$name] if it isn't used by any known plugin.
""".trimIndent()
}
+field("defaultValue", expressionBody, nullable = true, isChild = true)
}
val `class`: ElementConfig by element(Declaration) {
@@ -24,6 +24,7 @@ class ElementConfig(
val params = mutableListOf<TypeVariable>()
val parents = mutableListOf<TypeRef>()
val fields = mutableListOf<FieldConfig>()
val additionalImports = mutableListOf<Import>()
var visitorName: String? = null
var visitorParent: ElementConfig? = null
@@ -43,6 +43,7 @@ class Element(
val suppressPrint = config.suppressPrint
val propertyName = config.propertyName
val kDoc = config.kDoc
val additionalImports: List<Import> = config.additionalImports
override fun toString() = name
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.generator.print
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.TypeSpec
import org.jetbrains.kotlin.ir.generator.util.GeneratedFile
import org.jetbrains.kotlin.ir.generator.util.Import
import java.io.File
private val COPYRIGHT by lazy { File("license/COPYRIGHT_HEADER.txt").readText() }
@@ -17,8 +18,16 @@ private val GENERATED_MESSAGE = """
""".trimIndent()
private val PREFIX by lazy { "$COPYRIGHT\n\n$GENERATED_MESSAGE\n\n" }
fun printTypeCommon(generationPath: File, packageName: String, type: TypeSpec): GeneratedFile {
fun printTypeCommon(
generationPath: File,
packageName: String,
type: TypeSpec,
additionalImports: List<Import> = emptyList(),
): GeneratedFile {
val code = FileSpec.builder(packageName, type.name!!)
.apply {
additionalImports.forEach { addImport(it.packageName, it.className) }
}
.indent(" ")
.addType(type)
.build()
@@ -266,7 +266,7 @@ fun printElements(generationPath: File, model: Model) = sequence {
element.generationCallback?.invoke(this)
}.build()
yield(printTypeCommon(generationPath, elementName.packageName, elementType))
yield(printTypeCommon(generationPath, elementName.packageName, elementType, element.additionalImports))
}
}
@@ -14,6 +14,8 @@ import java.io.File
class GeneratedFile(val file: File, val newText: String)
class Import(val packageName: String, val className: String)
fun ClassName.parameterizedByIfAny(typeArguments: List<TypeName>) =
if (typeArguments.isNotEmpty()) parameterizedBy(typeArguments) else this