@@ -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 }
@@ -1737,8 +1743,12 @@ class LightTreeRawFirDeclarationBuilder(
1737
1743
}
1738
1744
val allowLegacyContractDescription = outerContractDescription == null
1739
1745
// TODO-HEADER-COMPILATION: Potentially remove getter/setter code.
1740
- val bodyWithContractDescription = withForcedLocalContext {
1741
- convertFunctionBody(block, expression, allowLegacyContractDescription)
1746
+ val bodyWithContractDescription = if (headerCompilationMode) {
1747
+ buildEmptyExpressionBlock() to null
1748
+ } else {
1749
+ withForcedLocalContext {
1750
+ convertFunctionBody(block, expression, allowLegacyContractDescription)
1751
+ }
1742
1752
}
1743
1753
this .body = bodyWithContractDescription.first
1744
1754
val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
@@ -2042,8 +2052,39 @@ class LightTreeRawFirDeclarationBuilder(
2042
2052
}
2043
2053
2044
2054
val allowLegacyContractDescription = outerContractDescription == null
2045
- val bodyWithContractDescription = withForcedLocalContext {
2046
- convertFunctionBody(block, expression, allowLegacyContractDescription)
2055
+
2056
+ // TODO: HEADER-COMPILATION
2057
+ // replacing method bodies with `return null!!` doesn't seem to be ideal since it's producing a rather
2058
+ // long bytecode sequence:
2059
+ // Code:
2060
+ // 0: aconst_null
2061
+ // 1: dup
2062
+ // 2: invokestatic #18 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
2063
+ // 5: pop
2064
+ // 6: new #26 // class kotlin/KotlinNothingValueException
2065
+ // 9: dup
2066
+ // 10: invokespecial #27 // Method kotlin/KotlinNothingValueException."<init>":()V
2067
+ // 13: athrow
2068
+ //
2069
+ // Consider unconditionally throwing an exception instead.
2070
+ fun buildReturnNullExclExclBlock () = (
2071
+ FirSingleExpressionBlock (
2072
+ buildReturnExpression {
2073
+ this .target = target
2074
+ result = buildCheckNotNullCall {
2075
+ argumentList = buildUnaryArgumentList(
2076
+ buildLiteralExpression(null , ConstantValueKind .Null , null , setType = true )
2077
+ )
2078
+ }
2079
+ }
2080
+ ) to null )
2081
+
2082
+ val bodyWithContractDescription = if (headerCompilationMode) {
2083
+ buildReturnNullExclExclBlock()
2084
+ } else {
2085
+ withForcedLocalContext {
2086
+ convertFunctionBody(block, expression, allowLegacyContractDescription)
2087
+ }
2047
2088
}
2048
2089
this .body = bodyWithContractDescription.first
2049
2090
val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
@@ -2082,10 +2123,6 @@ class LightTreeRawFirDeclarationBuilder(
2082
2123
expression : LighterASTNode ? ,
2083
2124
allowLegacyContractDescription : Boolean
2084
2125
): Pair <FirBlock ?, FirContractDescription ?> {
2085
- // TODO-HEADER-COMPILATION: Another option to produce empty methods
2086
- // TODO-HEADER-COMPILATION: is to make this function return nothing.
2087
- if (headerCompilationMode)
2088
- return null to null
2089
2126
return when {
2090
2127
blockNode != null -> {
2091
2128
val block = convertBlock(blockNode)
@@ -2121,8 +2158,6 @@ class LightTreeRawFirDeclarationBuilder(
2121
2158
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlock
2122
2159
*/
2123
2160
fun convertBlock (block : LighterASTNode ? ): FirBlock {
2124
- // TODO-HEADER-COMPILATION: One option is to prevent the frontend
2125
- // TODO-HEADER-COMPILATION: from producing IR here.
2126
2161
if (block == null ) return buildEmptyExpressionBlock()
2127
2162
if (block.tokenType != BLOCK ) {
2128
2163
return FirSingleExpressionBlock (
0 commit comments