@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
5757import org.jetbrains.kotlin.util.getChildren
5858import org.jetbrains.kotlin.utils.addToStdlib.runIf
5959import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
60+ import org.jetbrains.kotlin.config.AnalysisFlags
6061
6162class LightTreeRawFirDeclarationBuilder (
6263 session : FirSession ,
@@ -66,6 +67,7 @@ class LightTreeRawFirDeclarationBuilder(
6667) : AbstractLightTreeRawFirBuilder(session, tree, context) {
6768
6869 private val expressionConverter = LightTreeRawFirExpressionBuilder (session, tree, this , context)
70+ private val headerMode = session.languageVersionSettings.getFlag(AnalysisFlags .headerMode)
6971
7072 /* *
7173 * [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
@@ -134,21 +136,23 @@ class LightTreeRawFirDeclarationBuilder(
134136 /* *
135137 * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlockExpression
136138 */
137- fun convertBlockExpression (block : LighterASTNode ): FirBlock {
138- return convertBlockExpressionWithoutBuilding(block).build()
139+ fun convertBlockExpression (block : LighterASTNode , generateHeader : Boolean = false ): FirBlock {
140+ return convertBlockExpressionWithoutBuilding(block, generateHeader = generateHeader ).build()
139141 }
140142
141- fun convertBlockExpressionWithoutBuilding (block : LighterASTNode , kind : KtFakeSourceElementKind ? = null): FirBlockBuilder {
143+ fun convertBlockExpressionWithoutBuilding (block : LighterASTNode , kind : KtFakeSourceElementKind ? = null, generateHeader : Boolean = false ): FirBlockBuilder {
142144 val firStatements = block.forEachChildrenReturnList { node, container ->
143- when (node.tokenType) {
144- CLASS , OBJECT_DECLARATION -> container + = convertClass(node) as FirStatement
145- FUN -> container + = convertFunctionDeclaration(node)
146- KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node) as FirStatement
147- DESTRUCTURING_DECLARATION -> container + =
148- convertDestructingDeclaration(node).toFirDestructingDeclaration(this , baseModuleData)
149- TYPEALIAS -> container + = convertTypeAlias(node) as FirStatement
150- CLASS_INITIALIZER -> shouldNotBeCalled(" CLASS_INITIALIZER expected to be processed during class body conversion" )
151- else -> if (node.isExpression()) container + = expressionConverter.getAsFirStatement(node)
145+ if (! generateHeader || container.isEmpty()) { // Take only the first statement which could be a contract for header generation.
146+ when (node.tokenType) {
147+ CLASS , OBJECT_DECLARATION -> container + = convertClass(node) as FirStatement
148+ FUN -> container + = convertFunctionDeclaration(node)
149+ KtNodeTypes .PROPERTY -> container + = convertPropertyDeclaration(node) as FirStatement
150+ DESTRUCTURING_DECLARATION -> container + =
151+ convertDestructingDeclaration(node).toFirDestructingDeclaration(this , baseModuleData)
152+ TYPEALIAS -> container + = convertTypeAlias(node) as FirStatement
153+ CLASS_INITIALIZER -> shouldNotBeCalled(" CLASS_INITIALIZER expected to be processed during class body conversion" )
154+ else -> if (node.isExpression()) container + = expressionConverter.getAsFirStatement(node)
155+ }
152156 }
153157 }
154158 return FirBlockBuilder ().apply {
@@ -688,7 +692,9 @@ class LightTreeRawFirDeclarationBuilder(
688692 }
689693 }
690694 }.also {
691- it.isFromInlineFunction = context.containedWithinInlineFunction
695+ if (context.containedWithinInlineFunction) {
696+ it.isFromInlineFunction = true
697+ }
692698 if (classNode.getParent()?.elementType == KtStubElementTypes .CLASS_BODY ) {
693699 it.initContainingClassForLocalAttr()
694700 }
@@ -2061,8 +2067,9 @@ class LightTreeRawFirDeclarationBuilder(
20612067
20622068 val allowLegacyContractDescription = outerContractDescription == null
20632069 val containedWithinInlineFunction = context.containedWithinInlineFunction || functionBuilder.status.isInline
2070+ val generateHeaders = headerMode && ! containedWithinInlineFunction && (returnTypeRef !is FirImplicitTypeRef )
20642071 val bodyWithContractDescription = withForcedLocalContext(containedWithinInlineFunction) {
2065- convertFunctionBody(block, expression, allowLegacyContractDescription)
2072+ convertFunctionBody(block, expression, allowLegacyContractDescription, generateHeaders )
20662073 }
20672074 this .body = bodyWithContractDescription.first
20682075 val contractDescription = outerContractDescription ? : bodyWithContractDescription.second
@@ -2076,7 +2083,9 @@ class LightTreeRawFirDeclarationBuilder(
20762083 }
20772084 context.firFunctionTargets.removeLast()
20782085 }.build().also {
2079- it.isFromInlineFunction = context.containedWithinInlineFunction
2086+ if (context.containedWithinInlineFunction) {
2087+ it.isFromInlineFunction = true
2088+ }
20802089 target.bind(it)
20812090 fillDanglingConstraintsTo(firTypeParameters, typeConstraints, it)
20822091 }
@@ -2100,11 +2109,12 @@ class LightTreeRawFirDeclarationBuilder(
21002109 private fun convertFunctionBody (
21012110 blockNode : LighterASTNode ? ,
21022111 expression : LighterASTNode ? ,
2103- allowLegacyContractDescription : Boolean
2112+ allowLegacyContractDescription : Boolean ,
2113+ generateHeader : Boolean = false,
21042114 ): Pair <FirBlock ?, FirContractDescription ?> {
21052115 return when {
21062116 blockNode != null -> {
2107- val block = convertBlock(blockNode)
2117+ val block = convertBlock(blockNode, generateHeader )
21082118 val contractDescription = runIf(allowLegacyContractDescription) {
21092119 val blockSource = block.source
21102120 val diagnostic = when {
@@ -2114,7 +2124,11 @@ class LightTreeRawFirDeclarationBuilder(
21142124 }
21152125 processLegacyContractDescription(block, diagnostic)
21162126 }
2117- block to contractDescription
2127+ if (generateHeader) {
2128+ return buildEmptyExpressionBlock() to contractDescription
2129+ } else {
2130+ block to contractDescription
2131+ }
21182132 }
21192133 expression != null -> FirSingleExpressionBlock (
21202134 expressionConverter.getAsFirExpression<FirExpression >(expression, " Function has no body (but should)" ).toReturn()
@@ -2136,15 +2150,15 @@ class LightTreeRawFirDeclarationBuilder(
21362150 /* *
21372151 * @see org.jetbrains.kotlin.parsing.KotlinParsing.parseBlock
21382152 */
2139- fun convertBlock (block : LighterASTNode ? ): FirBlock {
2153+ fun convertBlock (block : LighterASTNode ? , generateHeader : Boolean = false ): FirBlock {
21402154 if (block == null ) return buildEmptyExpressionBlock()
21412155 if (block.tokenType != BLOCK ) {
21422156 return FirSingleExpressionBlock (
21432157 expressionConverter.getAsFirStatement(block)
21442158 )
21452159 }
21462160
2147- return convertBlockExpression(block)
2161+ return convertBlockExpression(block, generateHeader )
21482162 }
21492163
21502164 /* *
0 commit comments