@@ -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 {
@@ -2099,9 +2113,10 @@ class LightTreeRawFirDeclarationBuilder(
20992113 expression : LighterASTNode ? ,
21002114 allowLegacyContractDescription : Boolean
21012115 ): Pair <FirBlock ?, FirContractDescription ?> {
2116+ val generateHeader = headerMode && ! context.forceKeepingTheBodyInHeaderMode
21022117 return when {
21032118 blockNode != null -> {
2104- val block = convertBlock(blockNode)
2119+ val block = convertBlock(blockNode, convertOnlyFirstStatement = generateHeader )
21052120 val contractDescription = runIf(allowLegacyContractDescription) {
21062121 val blockSource = block.source
21072122 val diagnostic = when {
@@ -2111,7 +2126,11 @@ class LightTreeRawFirDeclarationBuilder(
21112126 }
21122127 processLegacyContractDescription(block, diagnostic)
21132128 }
2114- block to contractDescription
2129+ if (generateHeader) {
2130+ return buildEmptyExpressionBlock() to contractDescription
2131+ } else {
2132+ block to contractDescription
2133+ }
21152134 }
21162135 expression != null -> FirSingleExpressionBlock (
21172136 expressionConverter.getAsFirExpression<FirExpression >(expression, " Function has no body (but should)" ).toReturn()
@@ -2133,15 +2152,18 @@ class LightTreeRawFirDeclarationBuilder(
21332152 /* *
21342153 * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlock
21352154 */
2136- fun convertBlock (block : LighterASTNode ? ): FirBlock {
2155+ fun convertBlock (
2156+ block : LighterASTNode ? ,
2157+ convertOnlyFirstStatement : Boolean = false,
2158+ ): FirBlock {
21372159 if (block == null ) return buildEmptyExpressionBlock()
21382160 if (block.tokenType != BLOCK ) {
21392161 return FirSingleExpressionBlock (
21402162 expressionConverter.getAsFirStatement(block)
21412163 )
21422164 }
21432165
2144- return convertBlockExpression(block)
2166+ return convertBlockExpression(block, convertOnlyFirstStatement )
21452167 }
21462168
21472169 /* *
0 commit comments