@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
53
53
import org.jetbrains.kotlin.lexer.KtTokens.*
54
54
import org.jetbrains.kotlin.name.*
55
55
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
56
+ import org.jetbrains.kotlin.types.ConstantValueKind
56
57
import org.jetbrains.kotlin.util.getChildren
57
58
import org.jetbrains.kotlin.utils.addToStdlib.runIf
58
59
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
@@ -96,7 +97,12 @@ class LightTreeRawFirDeclarationBuilder(
96
97
}
97
98
IMPORT_LIST -> importList + = convertImportDirectives(child)
98
99
CLASS -> firDeclarationList + = convertClass(child)
99
- FUN -> firDeclarationList + = convertFunctionDeclaration(child) as FirDeclaration
100
+ FUN -> {
101
+ val functionDeclaration = convertFunctionDeclaration(child)
102
+ if (functionDeclaration != null ) {
103
+ firDeclarationList + = functionDeclaration as FirDeclaration
104
+ }
105
+ }
100
106
KtNodeTypes .PROPERTY -> firDeclarationList + = convertPropertyDeclaration(child)
101
107
TYPEALIAS -> firDeclarationList + = convertTypeAlias(child)
102
108
OBJECT_DECLARATION -> firDeclarationList + = convertClass(child)
@@ -142,7 +148,12 @@ class LightTreeRawFirDeclarationBuilder(
142
148
val firStatements = block.forEachChildrenReturnList { node, container ->
143
149
when (node.tokenType) {
144
150
CLASS , OBJECT_DECLARATION -> container + = convertClass(node) as FirStatement
145
- FUN -> container + = convertFunctionDeclaration(node)
151
+ FUN -> {
152
+ val functionDeclaration = convertFunctionDeclaration(node)
153
+ if (functionDeclaration != null ) {
154
+ container + = functionDeclaration
155
+ }
156
+ }
146
157
KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node) as FirStatement
147
158
DESTRUCTURING_DECLARATION -> container + =
148
159
convertDestructingDeclaration(node).toFirDestructingDeclaration(this , baseModuleData)
@@ -938,7 +949,11 @@ class LightTreeRawFirDeclarationBuilder(
938
949
when (node.tokenType) {
939
950
ENUM_ENTRY -> container + = convertEnumEntry(node, classWrapper!! )
940
951
CLASS -> container + = convertClass(node)
941
- FUN -> container + = convertFunctionDeclaration(node) as FirDeclaration
952
+ FUN -> {
953
+ val functionDeclaration = convertFunctionDeclaration(node)
954
+ if (functionDeclaration != null )
955
+ container + = functionDeclaration as FirDeclaration
956
+ }
942
957
KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node, classWrapper)
943
958
TYPEALIAS -> container + = convertTypeAlias(node)
944
959
OBJECT_DECLARATION -> container + = convertClass(node)
@@ -1238,6 +1253,7 @@ class LightTreeRawFirDeclarationBuilder(
1238
1253
modifiers?.convertAnnotationsTo(annotations)
1239
1254
typeParameters + = constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
1240
1255
valueParameters + = firValueParameters.map { it.firValueParameter }
1256
+ // TODO-HEADER-COMPILATION: Potentially remove this and produce an empty constructor body.
1241
1257
val (body, contractDescription) = withForcedLocalContext {
1242
1258
convertFunctionBody(block, null , allowLegacyContractDescription = true )
1243
1259
}
@@ -1759,6 +1775,10 @@ class LightTreeRawFirDeclarationBuilder(
1759
1775
valueParameters + = firValueParameters
1760
1776
}
1761
1777
val allowLegacyContractDescription = outerContractDescription == null
1778
+ // TODO-HEADER-COMPILATION: Potentially remove getter/setter code.
1779
+ // (headerCompilationMode) {
1780
+ // buildEmptyExpressionBlock() to null
1781
+ // }
1762
1782
val bodyWithContractDescription = withForcedLocalContext {
1763
1783
convertFunctionBody(block, expression, allowLegacyContractDescription)
1764
1784
}
@@ -1922,7 +1942,7 @@ class LightTreeRawFirDeclarationBuilder(
1922
1942
/* *
1923
1943
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseFunction
1924
1944
*/
1925
- fun convertFunctionDeclaration (functionDeclaration : LighterASTNode ): FirStatement {
1945
+ fun convertFunctionDeclaration (functionDeclaration : LighterASTNode ): FirStatement ? {
1926
1946
var modifiers: ModifierList ? = null
1927
1947
var identifier: String? = null
1928
1948
var valueParametersList: LighterASTNode ? = null
@@ -1976,8 +1996,23 @@ class LightTreeRawFirDeclarationBuilder(
1976
1996
else implicitType
1977
1997
}
1978
1998
1999
+ // TODO-HEADER-COMPILE: While it's a good idea to try to avoid
2000
+ // producing private functions, this breaks when the function is
2001
+ // decorated with @JvmStatic since it makes it visible to Java
2002
+ // programs and causes symbol not found errors.
2003
+ // Fix would be to check if the annotation is there and then skip.
2004
+ /*
2005
+ if (headerCompilationMode) {
2006
+ if (calculatedModifiers.getVisibility() == Visibilities.Private) {
2007
+ return null
2008
+ }
2009
+ }
2010
+ */
2011
+
1979
2012
val receiverTypeCalculator = receiverTypeNode?.let { { convertType(it) } }
1980
2013
val functionBuilder = if (isAnonymousFunction) {
2014
+ if (headerCompilationMode)
2015
+ return null
1981
2016
FirAnonymousFunctionBuilder ().apply {
1982
2017
source = functionSource
1983
2018
receiverParameter = receiverTypeCalculator?.let { createReceiverParameter(it, baseModuleData, functionSymbol) }
@@ -2064,8 +2099,41 @@ class LightTreeRawFirDeclarationBuilder(
2064
2099
}
2065
2100
2066
2101
val allowLegacyContractDescription = outerContractDescription == null
2067
- val bodyWithContractDescription = withForcedLocalContext {
2068
- convertFunctionBody(block, expression, allowLegacyContractDescription)
2102
+
2103
+ // TODO: HEADER-COMPILATION
2104
+ // replacing method bodies with `return null!!` doesn't seem to be ideal since it's producing a rather
2105
+ // long bytecode sequence:
2106
+ // Code:
2107
+ // 0: aconst_null
2108
+ // 1: dup
2109
+ // 2: invokestatic #18 // Method kotlin/jvm/internal/Intrinsics.checkNotNull:(Ljava/lang/Object;)V
2110
+ // 5: pop
2111
+ // 6: new #26 // class kotlin/KotlinNothingValueException
2112
+ // 9: dup
2113
+ // 10: invokespecial #27 // Method kotlin/KotlinNothingValueException."<init>":()V
2114
+ // 13: athrow
2115
+ //
2116
+ // Consider unconditionally throwing an exception instead.
2117
+ fun buildReturnNullExclExclBlock () = (
2118
+ FirSingleExpressionBlock (
2119
+ buildReturnExpression {
2120
+ this .target = target
2121
+ result = buildCheckNotNullCall {
2122
+ argumentList = buildUnaryArgumentList(
2123
+ buildLiteralExpression(null , ConstantValueKind .Null , null , setType = true )
2124
+ )
2125
+ }
2126
+ }
2127
+ ) to null )
2128
+
2129
+ // Block is null when you have an interface or abstract function declaration.
2130
+ // In such cases, for header compile mode you shall not generate any code either.
2131
+ val bodyWithContractDescription = if (headerCompilationMode && block != null ) {
2132
+ buildReturnNullExclExclBlock()
2133
+ } else {
2134
+ withForcedLocalContext {
2135
+ convertFunctionBody(block, expression, allowLegacyContractDescription)
2136
+ }
2069
2137
}
2070
2138
this .body = bodyWithContractDescription.first
2071
2139
val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
0 commit comments