diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 1f23516ec06..a5333f7c53c 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -880,7 +880,8 @@ class DeclarationsConverter( */ private fun visitBlock(block: LighterASTNode?): FirBlock { return if (!stubMode) { - TODO("not implemented") + //TODO("not implemented") + FirBlockImpl(session, null) //visitStatements(ctx.statements()) } else { FirSingleExpressionBlock( diff --git a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index 2dc218c1e2f..e1de8d158ed 100644 --- a/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/lightTree/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -34,7 +34,7 @@ class ExpressionsConverter( STRING_TEMPLATE -> return convertStringTemplate(expression) is KtConstantExpressionElementType -> return convertConstantExpression(expression) } - TODO("not implemented") + //TODO("not implemented") } return FirExpressionStub(session, null) diff --git a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/DummyElement.kt b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/DummyElement.kt new file mode 100644 index 00000000000..b62e2f70800 --- /dev/null +++ b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/DummyElement.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.compare + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionBase +import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirFunction +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.declarations.impl.FirVariableImpl +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.impl.FirUnknownTypeCallWithArgumentList +import org.jetbrains.kotlin.fir.expressions.impl.FirUnknownTypeExpression +import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.transformSingle +import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.FirVisitor +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames + +interface DummyElement + +class DummyFirStatement( + psi: PsiElement? = null, + session: FirSession = object : FirSessionBase(null) {} +) : FirUnknownTypeExpression(session, psi), DummyElement + +class DummyFirVariable( + override val psi: PsiElement? = null, + override val session: FirSession = object : FirSessionBase(null) {}, + override val annotations: List = mutableListOf(), + override val receiverTypeRef: FirTypeRef? = null, + override val name: Name = SpecialNames.NO_NAME_PROVIDED, + override var returnTypeRef: FirTypeRef = FirImplicitTypeRefImpl(session, psi), + override val isVar: Boolean = false, + override var initializer: FirExpression? = null, + override val symbol: FirVariableSymbol = FirVariableSymbol(name), + override var delegate: FirExpression? = null +) : FirVariable, DummyElement { + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } +} + +class DummyFirAnonymousFunction( + psi: PsiElement? = null, + session: FirSession = object : FirSessionBase(null) {}, + override val valueParameters: List = listOf(), + override val body: FirBlock? = null, + override val receiverTypeRef: FirTypeRef? = null, + override var returnTypeRef: FirTypeRef = FirImplicitTypeRefImpl(session, psi) +) : FirAnonymousFunction(session, psi), + DummyElement { + override fun transformReturnTypeRef(transformer: FirTransformer, data: D) { + returnTypeRef = returnTypeRef.transformSingle(transformer, data) + } +} + +class DummyFirDeclaration( + override val psi: PsiElement? = null, + override val session: FirSession = object : FirSessionBase(null) {}, + override val annotations: List = listOf() +) : FirDeclaration, FirStatement, DummyElement { + override fun accept(visitor: FirVisitor, data: D): R = + visitor.visitDeclaration(this, data) +} \ No newline at end of file diff --git a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirComparator.kt b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirComparator.kt new file mode 100644 index 00000000000..cc6583daf92 --- /dev/null +++ b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirComparator.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.compare + +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid + +class FirVisitorForComparator : FirVisitorVoid() { + val firTreeNodesClasses: MutableList = mutableListOf() + + override fun visitElement(element: FirElement) { + if (element !is DummyElement) { + firTreeNodesClasses += element.javaClass.canonicalName + element.acceptChildren(this) + } + } +} + +fun FirFile.areEqualTo(firFile: FirFile): Boolean { + val thisFirList = FirVisitorForComparator().apply { visitFile(this@areEqualTo) }.firTreeNodesClasses + val otherFirList = FirVisitorForComparator().apply { visitFile(firFile) }.firTreeNodesClasses + + if (thisFirList.size != otherFirList.size) return false + + for (i in 0 until thisFirList.size) { + if (thisFirList[i] != otherFirList[i]) { + return false + } + } + + return true +} \ No newline at end of file diff --git a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirPartialTransformer.kt b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirPartialTransformer.kt index c525e4a942f..b2059d46bd9 100644 --- a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirPartialTransformer.kt +++ b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/FirPartialTransformer.kt @@ -5,14 +5,93 @@ package org.jetbrains.kotlin.fir.lightTree.compare -import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirAbstractCallableMember +import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractTreeTransformer import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.psi.KtForExpression class FirPartialTransformer( - private val visitAnnotation: Boolean = true + private val visitAnonymousFunction: Boolean = false, + private val visitNamedFunction: Boolean = false, + private val visitMemberDeclaration: Boolean = false, + private val visitVariable: Boolean = false, + private val visitAnnotation: Boolean = false, + private val visitOperationCall: Boolean = false, + private val visitTypeOperatorCall: Boolean = false, + private val visitStringConcatenationCall: Boolean = false, + private val visitArrayOfCall: Boolean = false, + private val visitFunctionCall: Boolean = false, + private val visitGetClassCall: Boolean = false, + private val visitBreakExpression: Boolean = false, + private val visitContinueExpression: Boolean = false, + private val visitReturnExpression: Boolean = false, + private val visitThrowExpression: Boolean = false, + private val visitForLoop: Boolean = false, + private val visitClassReferenceExpression: Boolean = false, + private val visitConstExpression: Boolean = false, + private val visitQualifiedAccessExpression: Boolean = false, + private val visitCallableReferenceAccess: Boolean = false, + private val visitTryExpression: Boolean = false, + private val visitWhenExpression: Boolean = false, + private val visitNamedArgumentExpression: Boolean = false, + private val visitSpreadArgumentExpression: Boolean = false, + private val visitAnonymousObject: Boolean = false, + private val visitDoWhileLoop: Boolean = false, + private val visitWhileLoop: Boolean = false, + private val visitAssignment: Boolean = false ) : FirAbstractTreeTransformer() { + override fun transformAnonymousFunction( + anonymousFunction: FirAnonymousFunction, + data: Nothing? + ): CompositeTransformResult { + return if (visitAnonymousFunction) { + (anonymousFunction.transformChildren(this, data) as FirAnonymousFunction).compose() + } else { + DummyFirAnonymousFunction().compose() + } + } + + override fun transformNamedFunction(namedFunction: FirNamedFunction, data: Nothing?): CompositeTransformResult { + return if (!visitNamedFunction || (namedFunction is FirAbstractCallableMember && namedFunction.visibility == Visibilities.LOCAL)) { + DummyFirDeclaration().compose() + } else { + (namedFunction.transformChildren(this, data) as FirNamedFunction).compose() + } + } + + override fun transformMemberDeclaration( + memberDeclaration: FirMemberDeclaration, + data: Nothing? + ): CompositeTransformResult { + return if (!visitMemberDeclaration || memberDeclaration.visibility == Visibilities.LOCAL) { + DummyFirDeclaration().compose() + } else { + (memberDeclaration.transformChildren(this, data) as FirMemberDeclaration).compose() + } + } + + override fun transformVariable(variable: FirVariable, data: Nothing?): CompositeTransformResult { + return if (visitVariable) { + (variable.transformChildren(this, data) as FirVariable).compose() + } else { + DummyFirVariable().compose() + } + } + + override fun transformExpression(expression: FirExpression, data: Nothing?): CompositeTransformResult { + return if (expression is FirExpressionStub) { + DummyFirStatement().compose() + } else { + super.transformExpression(expression, data) + } + } + override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: Nothing?): CompositeTransformResult { return if (visitAnnotation) { (annotationCall.transformChildren(this, data) as FirAnnotationCall).compose() @@ -20,4 +99,212 @@ class FirPartialTransformer( CompositeTransformResult.empty() } } + + override fun transformOperatorCall(operatorCall: FirOperatorCall, data: Nothing?): CompositeTransformResult { + return if (visitOperationCall) { + (operatorCall.transformChildren(this, data) as FirOperatorCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Nothing?): CompositeTransformResult { + return if (visitTypeOperatorCall) { + (typeOperatorCall.transformChildren(this, data) as FirTypeOperatorCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformStringConcatenationCall( + stringConcatenationCall: FirStringConcatenationCall, + data: Nothing? + ): CompositeTransformResult { + return if (visitStringConcatenationCall) { + (stringConcatenationCall.transformChildren(this, data) as FirStringConcatenationCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: Nothing?): CompositeTransformResult { + return if (visitArrayOfCall) { + (arrayOfCall.transformChildren(this, data) as FirArrayOfCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformFunctionCall(functionCall: FirFunctionCall, data: Nothing?): CompositeTransformResult { + return if (visitFunctionCall) { + (functionCall.transformChildren(this, data) as FirFunctionCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Nothing?): CompositeTransformResult { + return if (visitGetClassCall) { + (getClassCall.transformChildren(this, data) as FirGetClassCall).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformBreakExpression(breakExpression: FirBreakExpression, data: Nothing?): CompositeTransformResult { + return if (visitBreakExpression) { + (breakExpression.transformChildren(this, data) as FirBreakExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformContinueExpression( + continueExpression: FirContinueExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitContinueExpression) { + (continueExpression.transformChildren(this, data) as FirContinueExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformReturnExpression(returnExpression: FirReturnExpression, data: Nothing?): CompositeTransformResult { + return if (visitReturnExpression) { + (returnExpression.transformChildren(this, data) as FirReturnExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformThrowExpression(throwExpression: FirThrowExpression, data: Nothing?): CompositeTransformResult { + return if (visitThrowExpression) { + (throwExpression.transformChildren(this, data) as FirThrowExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformBlock(block: FirBlock, data: Nothing?): CompositeTransformResult { + return if (!visitForLoop && block.psi is KtForExpression) { + DummyFirStatement().compose() + } else { + super.transformBlock(block, data) + } + } + + override fun transformClassReferenceExpression( + classReferenceExpression: FirClassReferenceExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitClassReferenceExpression) { + (classReferenceExpression.transformChildren(this, data) as FirClassReferenceExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformConstExpression( + constExpression: FirConstExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitConstExpression) { + (constExpression.transformChildren(this, data) as FirConstExpression<*>).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformQualifiedAccessExpression( + qualifiedAccessExpression: FirQualifiedAccessExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitQualifiedAccessExpression) { + (qualifiedAccessExpression.transformChildren(this, data) as FirQualifiedAccessExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformCallableReferenceAccess( + callableReferenceAccess: FirCallableReferenceAccess, + data: Nothing? + ): CompositeTransformResult { + return if (visitCallableReferenceAccess) { + (callableReferenceAccess.transformChildren(this, data) as FirCallableReferenceAccess).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformTryExpression(tryExpression: FirTryExpression, data: Nothing?): CompositeTransformResult { + return if (visitTryExpression) { + (tryExpression.transformChildren(this, data) as FirTryExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Nothing?): CompositeTransformResult { + return if (visitWhenExpression) { + (whenExpression.transformChildren(this, data) as FirWhenExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformNamedArgumentExpression( + namedArgumentExpression: FirNamedArgumentExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitNamedArgumentExpression) { + (namedArgumentExpression.transformChildren(this, data) as FirNamedArgumentExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformSpreadArgumentExpression( + spreadArgumentExpression: FirSpreadArgumentExpression, + data: Nothing? + ): CompositeTransformResult { + return if (visitSpreadArgumentExpression) { + (spreadArgumentExpression.transformChildren(this, data) as FirSpreadArgumentExpression).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformAnonymousObject(anonymousObject: FirAnonymousObject, data: Nothing?): CompositeTransformResult { + return if (visitAnonymousObject) { + (anonymousObject.transformChildren(this, data) as FirAnonymousObject).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformDoWhileLoop(doWhileLoop: FirDoWhileLoop, data: Nothing?): CompositeTransformResult { + return if (visitDoWhileLoop) { + (doWhileLoop.transformChildren(this, data) as FirDoWhileLoop).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformWhileLoop(whileLoop: FirWhileLoop, data: Nothing?): CompositeTransformResult { + return if (visitWhileLoop) { + (whileLoop.transformChildren(this, data) as FirWhileLoop).compose() + } else { + DummyFirStatement().compose() + } + } + + override fun transformAssignment(assignment: FirAssignment, data: Nothing?): CompositeTransformResult { + return if (visitAssignment) { + (assignment.transformChildren(this, data) as FirAssignment).compose() + } else { + DummyFirStatement().compose() + } + } } \ No newline at end of file diff --git a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt index 69fec69214b..d46b04621e8 100644 --- a/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt +++ b/compiler/fir/lightTree/tests/org/jetbrains/kotlin/fir/lightTree/compare/TreesCompareTest.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.testFramework.TestDataPath import com.intellij.util.PathUtil +import junit.framework.TestCase import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir @@ -22,10 +23,7 @@ import java.io.File @TestDataPath("\$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners::class) class TreesCompareTest : AbstractRawFirBuilderTestCase() { - private fun compare( - stubMode: Boolean, - visitAnnotation: Boolean = true - ) { + private fun compareBase(stubMode: Boolean, compareFir: (File, LightTree2Fir) -> Boolean) { val path = System.getProperty("user.dir") var counter = 0 var errorCounter = 0 @@ -33,42 +31,126 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() { val parserDefinition = KotlinParserDefinition() val lexer = parserDefinition.createLexer(myProject) val lightTreeConverter = LightTree2Fir(stubMode, parserDefinition, lexer) - val firVisitor = FirPartialTransformer(visitAnnotation = visitAnnotation) println("BASE PATH: $path") path.walkTopDown { file -> - val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() - - //light tree - val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name) - val treeFromLightTree = - StringBuilder().also { FirRenderer(it).visitFile(firVisitor.transformFile(firFileFromLightTree, null).single) }.toString() - - //psi - val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile - val firFileFromPsi = ktFile.toFirFile(stubMode) - val treeFromPsi = - StringBuilder().also { FirRenderer(it).visitFile(firVisitor.transformFile(firFileFromPsi, null).single) }.toString() - - if (treeFromLightTree != treeFromPsi) { - errorCounter++ - //TestCase.assertEquals(treeFromPsi, treeFromLightTree) - } + if (!compareFir(file, lightTreeConverter)) errorCounter++ counter++ } println("All scanned files: $counter") println("Files that aren't equal to FIR: $errorCounter") + TestCase.assertEquals(0, errorCounter) + } + + private fun compareAll(stubMode: Boolean) { + compareBase(stubMode) { file, lightTreeConverter -> + val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() + + //light tree + val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name) + val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString() + + //psi + val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile + val firFileFromPsi = ktFile.toFirFile(stubMode) + val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString() + + return@compareBase treeFromLightTree == treeFromPsi + } + } + + private fun compare( + stubMode: Boolean, + visitAnonymousFunction: Boolean = false, + visitNamedFunction: Boolean = false, + visitMemberDeclaration: Boolean = false, + visitVariable: Boolean = false, + visitAnnotation: Boolean = false, + visitOperationCall: Boolean = false, + visitTypeOperatorCall: Boolean = false, + visitStringConcatenationCall: Boolean = false, + visitArrayOfCall: Boolean = false, + visitFunctionCall: Boolean = false, + visitGetClassCall: Boolean = false, + visitBreakExpression: Boolean = false, + visitContinueExpression: Boolean = false, + visitReturnExpression: Boolean = false, + visitThrowExpression: Boolean = false, + visitForLoop: Boolean = false, + visitClassReferenceExpression: Boolean = false, + visitConstExpression: Boolean = false, + visitQualifiedAccessExpression: Boolean = false, + visitCallableReferenceAccess: Boolean = false, + visitTryExpression: Boolean = false, + visitWhenExpression: Boolean = false, + visitNamedArgumentExpression: Boolean = false, + visitSpreadArgumentExpression: Boolean = false, + visitAnonymousObject: Boolean = false, + visitDoWhileLoop: Boolean = false, + visitWhileLoop: Boolean = false, + visitAssignment: Boolean = false + ) { + val firVisitor = FirPartialTransformer( + visitAnonymousFunction = visitAnonymousFunction, + visitNamedFunction = visitNamedFunction, + visitMemberDeclaration = visitMemberDeclaration, + visitVariable = visitVariable, + visitAnnotation = visitAnnotation, + visitOperationCall = visitOperationCall, + visitTypeOperatorCall = visitTypeOperatorCall, + visitStringConcatenationCall = visitStringConcatenationCall, + visitArrayOfCall = visitArrayOfCall, + visitFunctionCall = visitFunctionCall, + visitGetClassCall = visitGetClassCall, + visitBreakExpression = visitBreakExpression, + visitContinueExpression = visitContinueExpression, + visitReturnExpression = visitReturnExpression, + visitThrowExpression = visitThrowExpression, + visitForLoop = visitForLoop, + visitClassReferenceExpression = visitClassReferenceExpression, + visitConstExpression = visitConstExpression, + visitQualifiedAccessExpression = visitQualifiedAccessExpression, + visitCallableReferenceAccess = visitCallableReferenceAccess, + visitTryExpression = visitTryExpression, + visitWhenExpression = visitWhenExpression, + visitNamedArgumentExpression = visitNamedArgumentExpression, + visitSpreadArgumentExpression = visitSpreadArgumentExpression, + visitAnonymousObject = visitAnonymousObject, + visitDoWhileLoop = visitDoWhileLoop, + visitWhileLoop = visitWhileLoop, + visitAssignment = visitAssignment + ) + compareBase(stubMode) { file, lightTreeConverter -> + val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() + + //light tree + val firFileFromLightTree = lightTreeConverter.buildFirFile(text, file.name) + firVisitor.transformFile(firFileFromLightTree, null) + //val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firVisitor.transformFile(firFileFromLightTree, null).single) }.toString() + + //psi + val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile + val firFileFromPsi = ktFile.toFirFile(stubMode) + firVisitor.transformFile(firFileFromPsi, null) + //val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firVisitor.transformFile(firFileFromPsi, null).single) }.toString() + + return@compareBase firFileFromPsi.areEqualTo(firFileFromLightTree) + } } fun testStubCompareAll() { - compare(stubMode = true) + compareAll(stubMode = true) } fun testCompareAll() { - compare(stubMode = false) + compareAll(stubMode = false) } fun testStubCompareWithoutAnnotations() { compare(stubMode = true, visitAnnotation = false) } + + fun testConstExpression() { + compare(stubMode = false, visitConstExpression = true, visitAnnotation = true) + } }