@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.diagnostics.*
33
33
import org.jetbrains.kotlin.fir.expressions.*
34
34
import org.jetbrains.kotlin.fir.expressions.builder.*
35
35
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
36
+ import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
36
37
import org.jetbrains.kotlin.fir.lightTree.fir.*
37
38
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.ModifierList
38
39
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifierList
@@ -53,6 +54,7 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
53
54
import org.jetbrains.kotlin.lexer.KtTokens.*
54
55
import org.jetbrains.kotlin.name.*
55
56
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
57
+ import org.jetbrains.kotlin.types.ConstantValueKind
56
58
import org.jetbrains.kotlin.util.getChildren
57
59
import org.jetbrains.kotlin.utils.addToStdlib.runIf
58
60
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@@ -1239,8 +1241,12 @@ class LightTreeRawFirDeclarationBuilder(
1239
1241
typeParameters + = constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
1240
1242
valueParameters + = firValueParameters.map { it.firValueParameter }
1241
1243
// TODO-HEADER-COMPILATION: Potentially remove this and produce an empty constructor body.
1242
- val (body, contractDescription) = withForcedLocalContext {
1243
- convertFunctionBody(block, null , allowLegacyContractDescription = true )
1244
+ val (body, contractDescription) = if (headerCompilationMode) {
1245
+ buildEmptyExpressionBlock() to null
1246
+ } else {
1247
+ withForcedLocalContext {
1248
+ convertFunctionBody(block, null , allowLegacyContractDescription = true )
1249
+ }
1244
1250
}
1245
1251
this .body = body
1246
1252
contractDescription?.let { this .contractDescription = it }
@@ -1761,8 +1767,12 @@ class LightTreeRawFirDeclarationBuilder(
1761
1767
}
1762
1768
val allowLegacyContractDescription = outerContractDescription == null
1763
1769
// TODO-HEADER-COMPILATION: Potentially remove getter/setter code.
1764
- val bodyWithContractDescription = withForcedLocalContext {
1765
- convertFunctionBody(block, expression, allowLegacyContractDescription)
1770
+ val bodyWithContractDescription = if (headerCompilationMode) {
1771
+ buildEmptyExpressionBlock() to null
1772
+ } else {
1773
+ withForcedLocalContext {
1774
+ convertFunctionBody(block, expression, allowLegacyContractDescription)
1775
+ }
1766
1776
}
1767
1777
this .body = bodyWithContractDescription.first
1768
1778
val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
@@ -2066,8 +2076,39 @@ class LightTreeRawFirDeclarationBuilder(
2066
2076
}
2067
2077
2068
2078
val allowLegacyContractDescription = outerContractDescription == null
2069
- val bodyWithContractDescription = withForcedLocalContext {
2070
- convertFunctionBody(block, expression, allowLegacyContractDescription)
2079
+
2080
+ // TODO: HEADER-COMPILATION
2081
+ // replacing method bodies with `return null!!` doesn't seem to be ideal since it's producing a rather
2082
+ // long bytecode sequence:
2083
+ // Code:
2084
+ // 0: aconst_null
2085
+ // 1: dup
2086
+ // 2: invokestatic #18 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
2087
+ // 5: pop
2088
+ // 6: new #26 // class kotlin/KotlinNothingValueException
2089
+ // 9: dup
2090
+ // 10: invokespecial #27 // Method kotlin/KotlinNothingValueException."<init>":()V
2091
+ // 13: athrow
2092
+ //
2093
+ // Consider unconditionally throwing an exception instead.
2094
+ fun buildReturnNullExclExclBlock () = (
2095
+ FirSingleExpressionBlock (
2096
+ buildReturnExpression {
2097
+ this .target = target
2098
+ result = buildCheckNotNullCall {
2099
+ argumentList = buildUnaryArgumentList(
2100
+ buildLiteralExpression(null , ConstantValueKind .Null , null , setType = true )
2101
+ )
2102
+ }
2103
+ }
2104
+ ) to null )
2105
+
2106
+ val bodyWithContractDescription = if (headerCompilationMode) {
2107
+ buildReturnNullExclExclBlock()
2108
+ } else {
2109
+ withForcedLocalContext {
2110
+ convertFunctionBody(block, expression, allowLegacyContractDescription)
2111
+ }
2071
2112
}
2072
2113
this .body = bodyWithContractDescription.first
2073
2114
val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
@@ -2106,10 +2147,6 @@ class LightTreeRawFirDeclarationBuilder(
2106
2147
expression : LighterASTNode ? ,
2107
2148
allowLegacyContractDescription : Boolean
2108
2149
): Pair <FirBlock ?, FirContractDescription ?> {
2109
- // TODO-HEADER-COMPILATION: Another option to produce empty methods
2110
- // TODO-HEADER-COMPILATION: is to make this function return nothing.
2111
- if (headerCompilationMode)
2112
- return null to null
2113
2150
return when {
2114
2151
blockNode != null -> {
2115
2152
val block = convertBlock(blockNode)
@@ -2145,8 +2182,6 @@ class LightTreeRawFirDeclarationBuilder(
2145
2182
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlock
2146
2183
*/
2147
2184
fun convertBlock (block : LighterASTNode ? ): FirBlock {
2148
- // TODO-HEADER-COMPILATION: One option is to prevent the frontend
2149
- // TODO-HEADER-COMPILATION: from producing IR here.
2150
2185
if (block == null ) return buildEmptyExpressionBlock()
2151
2186
if (block.tokenType != BLOCK ) {
2152
2187
return FirSingleExpressionBlock (
0 commit comments