@@ -56,6 +56,7 @@ import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
5656import org.jetbrains.kotlin.util.getChildren
5757import org.jetbrains.kotlin.utils.addToStdlib.runIf
5858import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
59+ import org.jetbrains.kotlin.config.AnalysisFlags
5960
6061class LightTreeRawFirDeclarationBuilder (
6162 session : FirSession ,
@@ -65,6 +66,7 @@ class LightTreeRawFirDeclarationBuilder(
6566) : AbstractLightTreeRawFirBuilder(session, tree, context) {
6667
6768 private val expressionConverter = LightTreeRawFirExpressionBuilder (session, tree, this , context)
69+ private val headerMode = session.languageVersionSettings.getFlag(AnalysisFlags .headerMode)
6870
6971 /* *
7072 * [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
@@ -133,21 +135,33 @@ class LightTreeRawFirDeclarationBuilder(
133135 /* *
134136 * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlockExpression
135137 */
136- fun convertBlockExpression (block : LighterASTNode ): FirBlock {
137- return convertBlockExpressionWithoutBuilding(block).build()
138+ fun convertBlockExpression (
139+ block : LighterASTNode ,
140+ convertOnlyFirstStatement : Boolean = false,
141+ ): FirBlock {
142+ return convertBlockExpressionWithoutBuilding(block, convertOnlyFirstStatement = convertOnlyFirstStatement).build()
138143 }
139144
140- fun convertBlockExpressionWithoutBuilding (block : LighterASTNode , kind : KtFakeSourceElementKind ? = null): FirBlockBuilder {
145+ /* *
146+ * @param convertOnlyFirstStatement Convert only the first statement of the block, which can be a contract, for header generation.
147+ */
148+ fun convertBlockExpressionWithoutBuilding (
149+ block : LighterASTNode ,
150+ kind : KtFakeSourceElementKind ? = null,
151+ convertOnlyFirstStatement : Boolean = false
152+ ): FirBlockBuilder {
141153 val firStatements = block.forEachChildrenReturnList { node, container ->
142- when (node.tokenType) {
143- CLASS , OBJECT_DECLARATION -> container + = convertClass(node) as FirStatement
144- FUN -> container + = convertFunctionDeclaration(node)
145- KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node) as FirStatement
146- DESTRUCTURING_DECLARATION -> container + =
147- convertDestructingDeclaration(node).toFirDestructingDeclaration(this , baseModuleData)
148- TYPEALIAS -> container + = convertTypeAlias(node) as FirStatement
149- CLASS_INITIALIZER -> shouldNotBeCalled(" CLASS_INITIALIZER expected to be processed during class body conversion" )
150- else -> if (node.isExpression()) container + = expressionConverter.getAsFirStatement(node)
154+ if (! convertOnlyFirstStatement || container.isEmpty()) {
155+ when (node.tokenType) {
156+ CLASS , OBJECT_DECLARATION -> container + = convertClass(node) as FirStatement
157+ FUN -> container + = convertFunctionDeclaration(node)
158+ KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node) as FirStatement
159+ DESTRUCTURING_DECLARATION -> container + =
160+ convertDestructingDeclaration(node).toFirDestructingDeclaration(this , baseModuleData)
161+ TYPEALIAS -> container + = convertTypeAlias(node) as FirStatement
162+ CLASS_INITIALIZER -> shouldNotBeCalled(" CLASS_INITIALIZER expected to be processed during class body conversion" )
163+ else -> if (node.isExpression()) container + = expressionConverter.getAsFirStatement(node)
164+ }
151165 }
152166 }
153167 return FirBlockBuilder ().apply {
@@ -2104,9 +2118,10 @@ class LightTreeRawFirDeclarationBuilder(
21042118 expression : LighterASTNode ? ,
21052119 allowLegacyContractDescription : Boolean
21062120 ): Pair <FirBlock ?, FirContractDescription ?> {
2121+ val generateHeader = headerMode && ! context.forceKeepingTheBodyInHeaderMode
21072122 return when {
21082123 blockNode != null -> {
2109- val block = convertBlock(blockNode)
2124+ val block = convertBlock(blockNode, convertOnlyFirstStatement = generateHeader )
21102125 val contractDescription = runIf(allowLegacyContractDescription) {
21112126 val blockSource = block.source
21122127 val diagnostic = when {
@@ -2116,7 +2131,11 @@ class LightTreeRawFirDeclarationBuilder(
21162131 }
21172132 processLegacyContractDescription(block, diagnostic)
21182133 }
2119- block to contractDescription
2134+ if (generateHeader) {
2135+ return buildEmptyExpressionBlock() to contractDescription
2136+ } else {
2137+ block to contractDescription
2138+ }
21202139 }
21212140 expression != null -> FirSingleExpressionBlock (
21222141 expressionConverter.getAsFirExpression<FirExpression >(expression, " Function has no body (but should)" ).toReturn()
@@ -2138,15 +2157,18 @@ class LightTreeRawFirDeclarationBuilder(
21382157 /* *
21392158 * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlock
21402159 */
2141- fun convertBlock (block : LighterASTNode ? ): FirBlock {
2160+ fun convertBlock (
2161+ block : LighterASTNode ? ,
2162+ convertOnlyFirstStatement : Boolean = false,
2163+ ): FirBlock {
21422164 if (block == null ) return buildEmptyExpressionBlock()
21432165 if (block.tokenType != BLOCK ) {
21442166 return FirSingleExpressionBlock (
21452167 expressionConverter.getAsFirStatement(block)
21462168 )
21472169 }
21482170
2149- return convertBlockExpression(block)
2171+ return convertBlockExpression(block, convertOnlyFirstStatement )
21502172 }
21512173
21522174 /* *
0 commit comments