[FIR] Remove stubMode flag from RawFirBuilder and LightTree2Fir converter

This commit is contained in:
Dmitriy Novozhilov
2021-09-03 17:21:18 +03:00
committed by teamcityserver
parent a2e4ebd820
commit 116a1c1e46
13 changed files with 104 additions and 241 deletions
@@ -143,7 +143,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
val firProvider = session.firProvider as FirProviderImpl val firProvider = session.firProvider as FirProviderImpl
val firFiles = if (USE_LIGHT_TREE) { val firFiles = if (USE_LIGHT_TREE) {
val lightTree2Fir = LightTree2Fir(session, firProvider.kotlinScopeProvider, stubMode = false) val lightTree2Fir = LightTree2Fir(session, firProvider.kotlinScopeProvider)
val allSourceFiles = moduleData.sources.flatMap { val allSourceFiles = moduleData.sources.flatMap {
if (it.isDirectory) { if (it.isDirectory) {
@@ -22,25 +22,20 @@ import java.nio.file.Path
class LightTree2Fir( class LightTree2Fir(
val session: FirSession, val session: FirSession,
private val scopeProvider: FirScopeProvider, private val scopeProvider: FirScopeProvider
private val stubMode: Boolean = false
) { ) {
//private val ktDummyFile = KtFile(SingleRootFileViewProvider(PsiManager.getInstance(project), LightVirtualFile()), false)
companion object { companion object {
private val parserDefinition = KotlinParserDefinition() private val parserDefinition = KotlinParserDefinition()
private fun makeLexer() = KotlinLexer() private fun makeLexer() = KotlinLexer()
fun buildLightTreeBlockExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> { fun buildLightTreeBlockExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code) val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code)
//KotlinParser.parseBlockExpression(builder)
KotlinLightParser.parseBlockExpression(builder) KotlinLightParser.parseBlockExpression(builder)
return builder.lightTree return builder.lightTree
} }
fun buildLightTreeLambdaExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> { fun buildLightTreeLambdaExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code) val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code)
//KotlinParser.parseLambdaExpression(builder)
KotlinLightParser.parseLambdaExpression(builder) KotlinLightParser.parseLambdaExpression(builder)
return builder.lightTree return builder.lightTree
} }
@@ -57,7 +52,6 @@ class LightTree2Fir(
fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> { fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code) val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, makeLexer(), code)
//KotlinParser(project).parse(null, builder, ktDummyFile)
KotlinLightParser.parse(builder) KotlinLightParser.parse(builder)
return builder.lightTree return builder.lightTree
} }
@@ -65,7 +59,7 @@ class LightTree2Fir(
fun buildFirFile(code: String, fileName: String): FirFile { fun buildFirFile(code: String, fileName: String): FirFile {
val lightTree = buildLightTree(code) val lightTree = buildLightTree(code)
return DeclarationsConverter(session, scopeProvider, stubMode, lightTree) return DeclarationsConverter(session, scopeProvider, lightTree)
.convertFile(lightTree.root, fileName) .convertFile(lightTree.root, fileName)
} }
} }
@@ -70,11 +70,9 @@ fun LighterASTNode.isExpression(): Boolean {
} }
} }
fun <T : FirCallBuilder> T.extractArgumentsFrom(container: List<FirExpression>, stubMode: Boolean): T { fun <T : FirCallBuilder> T.extractArgumentsFrom(container: List<FirExpression>): T {
if (!stubMode || this is FirAnnotationCallBuilder) { argumentList = buildArgumentList {
argumentList = buildArgumentList { arguments += container
arguments += container
}
} }
return this return this
} }
@@ -55,7 +55,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf
class DeclarationsConverter( class DeclarationsConverter(
session: FirSession, session: FirSession,
private val baseScopeProvider: FirScopeProvider, private val baseScopeProvider: FirScopeProvider,
private val stubMode: Boolean,
tree: FlyweightCapableTreeStructure<LighterASTNode>, tree: FlyweightCapableTreeStructure<LighterASTNode>,
offset: Int = 0, offset: Int = 0,
context: Context<LighterASTNode> = Context() context: Context<LighterASTNode> = Context()
@@ -74,7 +73,7 @@ class DeclarationsConverter(
} }
} }
private val expressionConverter = ExpressionsConverter(session, stubMode, tree, this, context) private val expressionConverter = ExpressionsConverter(session, tree, this, context)
/** /**
* [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile] * [org.jetbrains.kotlin.parsing.KotlinParsing.parseFile]
@@ -362,7 +361,7 @@ class DeclarationsConverter(
?.toFirSourceElement() ?.toFirSourceElement()
this.name = name this.name = name
} }
extractArgumentsFrom(constructorCalleePair.second, stubMode) extractArgumentsFrom(constructorCalleePair.second)
} }
} }
@@ -821,7 +820,7 @@ class DeclarationsConverter(
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
} }
extractArgumentsFrom(classWrapper.superTypeCallEntry, stubMode) extractArgumentsFrom(classWrapper.superTypeCallEntry)
} }
val explicitVisibility = runIf(primaryConstructor != null) { val explicitVisibility = runIf(primaryConstructor != null) {
@@ -871,7 +870,7 @@ class DeclarationsConverter(
source = anonymousInitializer.toFirSourceElement() source = anonymousInitializer.toFirSourceElement()
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
body = if (stubMode) buildEmptyExpressionBlock() else firBlock ?: buildEmptyExpressionBlock() body = firBlock ?: buildEmptyExpressionBlock()
} }
} }
@@ -975,7 +974,7 @@ class DeclarationsConverter(
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
} }
} }
extractArgumentsFrom(firValueArguments, stubMode) extractArgumentsFrom(firValueArguments)
} }
} }
@@ -1106,7 +1105,6 @@ class DeclarationsConverter(
classWrapper?.classBuilder?.ownerRegularOrAnonymousObjectSymbol, classWrapper?.classBuilder?.ownerRegularOrAnonymousObjectSymbol,
classWrapper?.classBuilder?.ownerRegularClassTypeParametersCount, classWrapper?.classBuilder?.ownerRegularClassTypeParametersCount,
isExtension = false, isExtension = false,
stubMode = stubMode,
receiver = receiver receiver = receiver
) )
} else { } else {
@@ -1175,7 +1173,6 @@ class DeclarationsConverter(
classWrapper?.classBuilder?.ownerRegularOrAnonymousObjectSymbol, classWrapper?.classBuilder?.ownerRegularOrAnonymousObjectSymbol,
classWrapper?.classBuilder?.ownerRegularClassTypeParametersCount, classWrapper?.classBuilder?.ownerRegularClassTypeParametersCount,
isExtension = receiverType != null, isExtension = receiverType != null,
stubMode = stubMode,
receiver = receiver receiver = receiver
) )
} }
@@ -1636,17 +1633,11 @@ class DeclarationsConverter(
expressionConverter.getAsFirExpression(block) expressionConverter.getAsFirExpression(block)
) )
} }
return if (!stubMode) {
val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText) val blockTree = LightTree2Fir.buildLightTreeBlockExpression(block.asText)
return DeclarationsConverter( return DeclarationsConverter(
baseSession, baseScopeProvider, stubMode, blockTree, offset = offset + tree.getStartOffset(block), context baseSession, baseScopeProvider, blockTree, offset = offset + tree.getStartOffset(block), context
).convertBlockExpression(blockTree.root) ).convertBlockExpression(blockTree.root)
} else {
val firExpression = buildExpressionStub()
FirSingleExpressionBlock(
firExpression.toReturn(baseSource = firExpression.source)
)
}
} }
/** /**
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
class ExpressionsConverter( class ExpressionsConverter(
session: FirSession, session: FirSession,
private val stubMode: Boolean,
tree: FlyweightCapableTreeStructure<LighterASTNode>, tree: FlyweightCapableTreeStructure<LighterASTNode>,
private val declarationsConverter: DeclarationsConverter, private val declarationsConverter: DeclarationsConverter,
context: Context<LighterASTNode> = Context() context: Context<LighterASTNode> = Context()
@@ -65,56 +64,52 @@ class ExpressionsConverter(
/***** EXPRESSIONS *****/ /***** EXPRESSIONS *****/
fun convertExpression(expression: LighterASTNode, errorReason: String): FirElement { fun convertExpression(expression: LighterASTNode, errorReason: String): FirElement {
if (!stubMode) { return when (expression.tokenType) {
return when (expression.tokenType) { LAMBDA_EXPRESSION -> {
LAMBDA_EXPRESSION -> { val lambdaTree = LightTree2Fir.buildLightTreeLambdaExpression(expression.asText)
val lambdaTree = LightTree2Fir.buildLightTreeLambdaExpression(expression.asText) declarationsConverter.withOffset(offset + expression.startOffset) {
declarationsConverter.withOffset(offset + expression.startOffset) { ExpressionsConverter(baseSession, lambdaTree, declarationsConverter, context)
ExpressionsConverter(baseSession, stubMode, lambdaTree, declarationsConverter, context) .convertLambdaExpression(lambdaTree.root)
.convertLambdaExpression(lambdaTree.root)
}
} }
BINARY_EXPRESSION -> convertBinaryExpression(expression)
BINARY_WITH_TYPE -> convertBinaryWithTypeRHSExpression(expression) {
this.getOperationSymbol().toFirOperation()
}
IS_EXPRESSION -> convertBinaryWithTypeRHSExpression(expression) {
if (this == "is") FirOperation.IS else FirOperation.NOT_IS
}
LABELED_EXPRESSION -> convertLabeledExpression(expression)
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
CLASS_LITERAL_EXPRESSION -> convertClassLiteralExpression(expression)
CALLABLE_REFERENCE_EXPRESSION -> convertCallableReferenceExpression(expression)
in QUALIFIED_ACCESS -> convertQualifiedExpression(expression)
CALL_EXPRESSION -> convertCallExpression(expression)
WHEN -> convertWhenExpression(expression)
ARRAY_ACCESS_EXPRESSION -> convertArrayAccessExpression(expression)
COLLECTION_LITERAL_EXPRESSION -> convertCollectionLiteralExpression(expression)
STRING_TEMPLATE -> convertStringTemplate(expression)
is KtConstantExpressionElementType -> convertConstantExpression(expression)
REFERENCE_EXPRESSION -> convertSimpleNameExpression(expression)
DO_WHILE -> convertDoWhile(expression)
WHILE -> convertWhile(expression)
FOR -> convertFor(expression)
TRY -> convertTryExpression(expression)
IF -> convertIfExpression(expression)
BREAK, CONTINUE -> convertLoopJump(expression)
RETURN -> convertReturn(expression)
THROW -> convertThrow(expression)
PARENTHESIZED -> getAsFirExpression(expression.getExpressionInParentheses(), "Empty parentheses")
PROPERTY_DELEGATE, INDICES, CONDITION, LOOP_RANGE ->
getAsFirExpression(expression.getExpressionInParentheses(), errorReason)
THIS_EXPRESSION -> convertThisExpression(expression)
SUPER_EXPRESSION -> convertSuperExpression(expression)
OBJECT_LITERAL -> declarationsConverter.convertObjectLiteral(expression)
FUN -> declarationsConverter.convertFunctionDeclaration(expression)
else -> buildErrorExpression(null, ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
} }
} BINARY_EXPRESSION -> convertBinaryExpression(expression)
BINARY_WITH_TYPE -> convertBinaryWithTypeRHSExpression(expression) {
this.getOperationSymbol().toFirOperation()
}
IS_EXPRESSION -> convertBinaryWithTypeRHSExpression(expression) {
if (this == "is") FirOperation.IS else FirOperation.NOT_IS
}
LABELED_EXPRESSION -> convertLabeledExpression(expression)
PREFIX_EXPRESSION, POSTFIX_EXPRESSION -> convertUnaryExpression(expression)
ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
CLASS_LITERAL_EXPRESSION -> convertClassLiteralExpression(expression)
CALLABLE_REFERENCE_EXPRESSION -> convertCallableReferenceExpression(expression)
in QUALIFIED_ACCESS -> convertQualifiedExpression(expression)
CALL_EXPRESSION -> convertCallExpression(expression)
WHEN -> convertWhenExpression(expression)
ARRAY_ACCESS_EXPRESSION -> convertArrayAccessExpression(expression)
COLLECTION_LITERAL_EXPRESSION -> convertCollectionLiteralExpression(expression)
STRING_TEMPLATE -> convertStringTemplate(expression)
is KtConstantExpressionElementType -> convertConstantExpression(expression)
REFERENCE_EXPRESSION -> convertSimpleNameExpression(expression)
DO_WHILE -> convertDoWhile(expression)
WHILE -> convertWhile(expression)
FOR -> convertFor(expression)
TRY -> convertTryExpression(expression)
IF -> convertIfExpression(expression)
BREAK, CONTINUE -> convertLoopJump(expression)
RETURN -> convertReturn(expression)
THROW -> convertThrow(expression)
PARENTHESIZED -> getAsFirExpression(expression.getExpressionInParentheses(), "Empty parentheses")
PROPERTY_DELEGATE, INDICES, CONDITION, LOOP_RANGE ->
getAsFirExpression(expression.getExpressionInParentheses(), errorReason)
THIS_EXPRESSION -> convertThisExpression(expression)
SUPER_EXPRESSION -> convertSuperExpression(expression)
return buildExpressionStub() OBJECT_LITERAL -> declarationsConverter.convertObjectLiteral(expression)
FUN -> declarationsConverter.convertFunctionDeclaration(expression)
else -> buildErrorExpression(null, ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
}
} }
/** /**
@@ -641,7 +636,7 @@ class ExpressionsConverter(
this.calleeReference = calleeReference this.calleeReference = calleeReference
context.calleeNamesForLambda += calleeReference.name context.calleeNamesForLambda += calleeReference.name
this.extractArgumentsFrom(valueArguments.flatMap { convertValueArguments(it) }, stubMode) this.extractArgumentsFrom(valueArguments.flatMap { convertValueArguments(it) })
context.calleeNamesForLambda.removeLast() context.calleeNamesForLambda.removeLast()
} }
} else { } else {
@@ -20,8 +20,7 @@ abstract class AbstractLightTree2FirConverterTestCase : AbstractRawFirBuilderTes
fun doTest(filePath: String) { fun doTest(filePath: String) {
val firFile = LightTree2Fir( val firFile = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = false
).buildFirFile(Paths.get(filePath)) ).buildFirFile(Paths.get(filePath))
val firDump = firFile.render(mode = FirRenderer.RenderMode.WithDeclarationAttributes) val firDump = firFile.render(mode = FirRenderer.RenderMode.WithDeclarationAttributes)
@@ -1,82 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.lightTree
import com.intellij.lang.impl.PsiBuilderFactoryImpl
import com.intellij.psi.PsiManager
import com.intellij.psi.impl.DebugUtil
import com.intellij.psi.impl.PsiManagerEx
import com.intellij.testFramework.LightVirtualFile
import com.intellij.testFramework.TestDataPath
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.parsing.KotlinParser
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.junit.runner.RunWith
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
@TestDataPath("\$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners::class)
class SimpleTestCase : AbstractRawFirBuilderTestCase() {
fun test() {
val file = KtFile(
(PsiManager.getInstance(myProject) as PsiManagerEx).fileManager.createFileViewProvider(
LightVirtualFile(
"foo",
KotlinFileType.INSTANCE,
""
), true
), false
)
val parserDefinition = KotlinParserDefinition()
val lexer = parserDefinition.createLexer(myProject)
val code = """
class SimpleClass {
val x: Int
}
""".trimIndent()
val builder = PsiBuilderFactoryImpl().createBuilder(
parserDefinition,
lexer,
code
)
val ktParsing = parserDefinition.createParser(myProject) as KotlinParser
ktParsing.parse(null, builder, file)
println("LightTree")
println(DebugUtil.lightTreeToString(builder.lightTree, false))
println("AST Tree")
println(DebugUtil.nodeTreeToString(builder.treeBuilt, false))
val firFromLightTreeFile = DeclarationsConverter(
FirSessionFactory.createEmptySession(),
StubFirScopeProvider,
true,
builder.lightTree
).convertFile(builder.lightTree.root)
println("Fir from LightTree")
println(StringBuilder().also { FirRenderer(it).visitFile(firFromLightTreeFile) }.toString())
val psiFile = createPsiFile("foo", code) as KtFile
val firFromPsiFile = psiFile.toFirFile(BodyBuildingMode.STUBS)
println("Fir from PSI")
println(StringBuilder().also { FirRenderer(it).visitFile(firFromPsiFile) }.toString())
}
}
@@ -51,8 +51,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = true
) )
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter") if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
@@ -20,8 +20,7 @@ open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase
override fun generateBaseTree(text: String, file: File) { override fun generateBaseTree(text: String, file: File) {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = false
) )
val lightTree = lightTreeConverter.buildLightTree(text) val lightTree = lightTreeConverter.buildLightTree(text)
DebugUtil.lightTreeToString(lightTree, false) DebugUtil.lightTreeToString(lightTree, false)
@@ -30,8 +29,7 @@ open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase
override fun generateFir(text: String, file: File, stubMode: Boolean) { override fun generateFir(text: String, file: File, stubMode: Boolean) {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = stubMode
) )
val firFile = lightTreeConverter.buildFirFile(text, file.name) val firFile = lightTreeConverter.buildFirFile(text, file.name)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString() StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
@@ -13,7 +13,6 @@ import junit.framework.TestCase
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.Companion.DIAGNOSTIC_IN_TESTDATA_PATTERN import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest.Companion.DIAGNOSTIC_IN_TESTDATA_PATTERN
import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider import org.jetbrains.kotlin.fir.builder.StubFirScopeProvider
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
import org.jetbrains.kotlin.fir.lightTree.walkTopDown import org.jetbrains.kotlin.fir.lightTree.walkTopDown
@@ -55,18 +54,17 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
TestCase.assertEquals(0, errorCounter) TestCase.assertEquals(0, errorCounter)
} }
private fun compareAll(stubMode: Boolean) { private fun compareAll() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = stubMode
) )
compareBase(System.getProperty("user.dir"), withTestData = false) { file -> compareBase(System.getProperty("user.dir"), withTestData = false) { file ->
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
//psi //psi
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile
val firFileFromPsi = ktFile.toFirFile(BodyBuildingMode.stubs(stubMode)) val firFileFromPsi = ktFile.toFirFile()
val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString() val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString()
//light tree //light tree
@@ -80,8 +78,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testCompareDiagnostics() { fun testCompareDiagnostics() {
val lightTreeConverter = LightTree2Fir( val lightTreeConverter = LightTree2Fir(
session = FirSessionFactory.createEmptySession(), session = FirSessionFactory.createEmptySession(),
scopeProvider = StubFirScopeProvider, scopeProvider = StubFirScopeProvider
stubMode = false
) )
compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file -> compareBase("compiler/testData/diagnostics/tests", withTestData = true) { file ->
if (file.name.endsWith(".fir.kt")) { if (file.name.endsWith(".fir.kt")) {
@@ -109,11 +106,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
} }
} }
fun testStubCompareAll() {
compareAll(stubMode = true)
}
fun testCompareAll() { fun testCompareAll() {
compareAll(stubMode = false) compareAll()
} }
} }
@@ -60,8 +60,6 @@ open class RawFirBuilder(
constructor(session: FirSession, baseScopeProvider: FirScopeProvider, mode: BodyBuildingMode = BodyBuildingMode.NORMAL) : constructor(session: FirSession, baseScopeProvider: FirScopeProvider, mode: BodyBuildingMode = BodyBuildingMode.NORMAL) :
this(session, baseScopeProvider, psiMode = PsiHandlingMode.IDE, bodyBuildingMode = mode) this(session, baseScopeProvider, psiMode = PsiHandlingMode.IDE, bodyBuildingMode = mode)
private val stubMode get() = mode == BodyBuildingMode.STUBS
protected open fun bindFunctionTarget(target: FirFunctionTarget, function: FirFunction) = target.bind(function) protected open fun bindFunctionTarget(target: FirFunctionTarget, function: FirFunction) = target.bind(function)
var mode: BodyBuildingMode = bodyBuildingMode var mode: BodyBuildingMode = bodyBuildingMode
@@ -200,8 +198,7 @@ open class RawFirBuilder(
// Here we accept lambda as receiver to prevent expression calculation in stub mode // Here we accept lambda as receiver to prevent expression calculation in stub mode
private fun (() -> KtExpression?).toFirExpression(errorReason: String): FirExpression = private fun (() -> KtExpression?).toFirExpression(errorReason: String): FirExpression =
if (stubMode) buildExpressionStub() with(this()) {
else with(this()) {
convertSafe() ?: buildErrorExpression( convertSafe() ?: buildErrorExpression(
this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected), this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected),
) )
@@ -211,41 +208,37 @@ open class RawFirBuilder(
errorReason: String, errorReason: String,
kind: DiagnosticKind = DiagnosticKind.ExpressionExpected kind: DiagnosticKind = DiagnosticKind.ExpressionExpected
): FirExpression { ): FirExpression {
if (stubMode) { val result = this.convertSafe<FirExpression>()
return buildExpressionStub()
} else {
val result = this.convertSafe<FirExpression>()
if (result != null) { if (result != null) {
if (this == null) { if (this == null) {
return result return result
}
val callExpressionCallee = (this as? KtCallExpression)?.calleeExpression?.unwrapParenthesesLabelsAndAnnotations()
if (this is KtNameReferenceExpression ||
this is KtConstantExpression ||
(this is KtCallExpression && callExpressionCallee !is KtLambdaExpression) ||
getQualifiedExpressionForSelector() == null
) {
return result
}
return buildErrorExpression {
source = callExpressionCallee?.toFirSourceElement() ?: toFirSourceElement()
diagnostic =
ConeSimpleDiagnostic(
"The expression cannot be a selector (occur after a dot)",
if (callExpressionCallee == null) DiagnosticKind.IllegalSelector else DiagnosticKind.NoReceiverAllowed
)
expression = result
}
} }
return buildErrorExpression( val callExpressionCallee = (this as? KtCallExpression)?.calleeExpression?.unwrapParenthesesLabelsAndAnnotations()
this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, kind),
) if (this is KtNameReferenceExpression ||
this is KtConstantExpression ||
(this is KtCallExpression && callExpressionCallee !is KtLambdaExpression) ||
getQualifiedExpressionForSelector() == null
) {
return result
}
return buildErrorExpression {
source = callExpressionCallee?.toFirSourceElement() ?: toFirSourceElement()
diagnostic =
ConeSimpleDiagnostic(
"The expression cannot be a selector (occur after a dot)",
if (callExpressionCallee == null) DiagnosticKind.IllegalSelector else DiagnosticKind.NoReceiverAllowed
)
expression = result
}
} }
return buildErrorExpression(
this?.toFirSourceElement(), ConeSimpleDiagnostic(errorReason, kind),
)
} }
private inline fun KtExpression.toFirStatement(errorReasonLazy: () -> String): FirStatement = private inline fun KtExpression.toFirStatement(errorReasonLazy: () -> String): FirStatement =
@@ -314,15 +307,13 @@ open class RawFirBuilder(
} }
block to null block to null
} }
hasBlockBody() -> if (!stubMode) { hasBlockBody() -> {
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
if (hasContractEffectList()) { if (hasContractEffectList()) {
block to null block to null
} else { } else {
block.extractContractDescriptionIfPossible() block.extractContractDescriptionIfPossible()
} }
} else {
FirSingleExpressionBlock(buildExpressionStub { source = this@buildFirBody.toFirSourceElement() }.toReturn()) to null
} }
else -> { else -> {
val result = { bodyExpression }.toFirExpression("Function has no body (but should)") val result = { bodyExpression }.toFirExpression("Function has no body (but should)")
@@ -827,9 +818,7 @@ open class RawFirBuilder(
?: this@buildDelegatedConstructorCall.source?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall) ?: this@buildDelegatedConstructorCall.source?.fakeElement(FirFakeSourceElementKind.DelegatingConstructorCall)
superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
} }
if (!stubMode) { superTypeCallEntry?.extractArgumentsTo(this)
superTypeCallEntry?.extractArgumentsTo(this)
}
} }
// See DescriptorUtils#getDefaultConstructorVisibility in core.descriptors // See DescriptorUtils#getDefaultConstructorVisibility in core.descriptors
@@ -1445,9 +1434,7 @@ open class RawFirBuilder(
this.superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef this.superTypeRef = this@buildDelegatedConstructorCall.constructedTypeRef
} }
} }
if (!stubMode) { extractArgumentsTo(this)
extractArgumentsTo(this)
}
} }
} }
@@ -1510,8 +1497,6 @@ open class RawFirBuilder(
ownerRegularOrAnonymousObjectSymbol = null, ownerRegularOrAnonymousObjectSymbol = null,
ownerRegularClassTypeParametersCount = null, ownerRegularClassTypeParametersCount = null,
isExtension = false, isExtension = false,
stubMode = stubMode,
//TODO This expression should be the same for wrapper and receiver
receiver = extractDelegateExpression() receiver = extractDelegateExpression()
) )
} }
@@ -1573,8 +1558,6 @@ open class RawFirBuilder(
ownerRegularOrAnonymousObjectSymbol, ownerRegularOrAnonymousObjectSymbol,
ownerRegularClassTypeParametersCount, ownerRegularClassTypeParametersCount,
isExtension = receiverTypeReference != null, isExtension = receiverTypeReference != null,
stubMode = stubMode,
//TODO This expression should be the same for wrapper and receiver
receiver = extractDelegateExpression() receiver = extractDelegateExpression()
) )
} }
@@ -1593,7 +1576,7 @@ open class RawFirBuilder(
source = initializer.toFirSourceElement() source = initializer.toFirSourceElement()
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
body = if (stubMode) buildEmptyExpressionBlock() else initializer.body.toFirBlock() body = initializer.body.toFirBlock()
} }
} }
@@ -2473,9 +2456,6 @@ enum class BodyBuildingMode {
companion object { companion object {
fun lazyBodies(lazyBodies: Boolean): BodyBuildingMode = fun lazyBodies(lazyBodies: Boolean): BodyBuildingMode =
if (lazyBodies) LAZY_BODIES else NORMAL if (lazyBodies) LAZY_BODIES else NORMAL
fun stubs(stubs: Boolean): BodyBuildingMode =
if (stubs) STUBS else NORMAL
} }
} }
@@ -316,7 +316,6 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
ownerRegularOrAnonymousObjectSymbol: FirClassSymbol<*>?, ownerRegularOrAnonymousObjectSymbol: FirClassSymbol<*>?,
ownerRegularClassTypeParametersCount: Int?, ownerRegularClassTypeParametersCount: Int?,
isExtension: Boolean, isExtension: Boolean,
stubMode: Boolean,
receiver: FirExpression? receiver: FirExpression?
) { ) {
if (delegateBuilder == null) return if (delegateBuilder == null) return
@@ -399,7 +398,7 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
} }
} }
delegateBuilder.delegateProvider = if (stubMode) buildExpressionStub() else buildFunctionCall { delegateBuilder.delegateProvider = buildFunctionCall {
explicitReceiver = receiver explicitReceiver = receiver
calleeReference = buildSimpleNamedReference { calleeReference = buildSimpleNamedReference {
source = fakeSource source = fakeSource
@@ -409,7 +408,6 @@ fun FirPropertyBuilder.generateAccessorsByDelegate(
origin = FirFunctionCallOrigin.Operator origin = FirFunctionCallOrigin.Operator
} }
delegate = delegateBuilder.build() delegate = delegateBuilder.build()
if (stubMode) return
if (getter == null || getter is FirDefaultPropertyAccessor) { if (getter == null || getter is FirDefaultPropertyAccessor) {
val annotations = getter?.annotations val annotations = getter?.annotations
val returnTarget = FirFunctionTarget(null, isLambda = false) val returnTarget = FirFunctionTarget(null, isLambda = false)
@@ -129,7 +129,7 @@ abstract class AbstractFirBaseDiagnosticsTest : BaseDiagnosticsTest() {
private fun mapKtFilesToFirFiles(session: FirSession, ktFiles: List<KtFile>, firFiles: MutableList<FirFile>, useLightTree: Boolean) { private fun mapKtFilesToFirFiles(session: FirSession, ktFiles: List<KtFile>, firFiles: MutableList<FirFile>, useLightTree: Boolean) {
val firProvider = (session.firProvider as FirProviderImpl) val firProvider = (session.firProvider as FirProviderImpl)
if (useLightTree) { if (useLightTree) {
val lightTreeBuilder = LightTree2Fir(session, firProvider.kotlinScopeProvider, stubMode = false) val lightTreeBuilder = LightTree2Fir(session, firProvider.kotlinScopeProvider)
ktFiles.mapTo(firFiles) { ktFiles.mapTo(firFiles) {
val firFile = lightTreeBuilder.buildFirFile(it.text, it.name) val firFile = lightTreeBuilder.buildFirFile(it.text, it.name)
(session.firProvider as FirProviderImpl).recordFile(firFile) (session.firProvider as FirProviderImpl).recordFile(firFile)