Reformat LightTree2Fir class to be able to parse block of code

This commit is contained in:
Ivan Cilcic
2019-07-11 21:43:29 +03:00
committed by Mikhail Glukhikh
parent bfe83d0bfd
commit be073ce2e6
7 changed files with 66 additions and 19 deletions
@@ -9,21 +9,45 @@ import com.intellij.lang.LighterASTNode
import com.intellij.lang.ParserDefinition import com.intellij.lang.ParserDefinition
import com.intellij.lang.impl.PsiBuilderFactoryImpl import com.intellij.lang.impl.PsiBuilderFactoryImpl
import com.intellij.lexer.Lexer import com.intellij.lexer.Lexer
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.psi.DummyHolderViewProvider
import com.intellij.psi.PsiManager
import com.intellij.psi.SingleRootFileViewProvider
import com.intellij.psi.impl.PsiManagerEx
import com.intellij.testFramework.LightVirtualFile
import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.fir.FirSessionBase import org.jetbrains.kotlin.fir.FirSessionBase
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter import org.jetbrains.kotlin.fir.lightTree.converter.DeclarationsConverter
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.parsing.KotlinParser
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.parsing.MyKotlinParser import org.jetbrains.kotlin.parsing.MyKotlinParser
import org.jetbrains.kotlin.psi.KtFile
import java.io.File import java.io.File
import java.nio.file.Path import java.nio.file.Path
class LightTree2Fir( class LightTree2Fir(
private val stubMode: Boolean, private val stubMode: Boolean,
private val parserDefinition: ParserDefinition, private val project: Project
private val lexer: Lexer
) { ) {
private val ktDummyFile = KtFile(SingleRootFileViewProvider(PsiManager.getInstance(project), LightVirtualFile()), false)
companion object {
private val parserDefinition = KotlinParserDefinition()
private val lexer = KotlinLexer()
fun buildLightTreeBlockExpression(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, code)
//KotlinParser.parseBlockExpression(builder)
MyKotlinParser.parseBlockExpression(builder)
return builder.lightTree
}
}
fun buildFirFile(path: Path): FirFile { fun buildFirFile(path: Path): FirFile {
return buildFirFile(path.toFile()) return buildFirFile(path.toFile())
} }
@@ -35,6 +59,7 @@ class LightTree2Fir(
fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> { fun buildLightTree(code: String): FlyweightCapableTreeStructure<LighterASTNode> {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, code) val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, code)
//KotlinParser(project).parse(null, builder, ktDummyFile)
MyKotlinParser.parse(builder) MyKotlinParser.parse(builder)
return builder.lightTree return builder.lightTree
} }
@@ -21,9 +21,7 @@ class LightTree2FirConverterTestCases : AbstractRawFirBuilderTestCase() {
private val testDirPath = "compiler/fir/psi2fir/testData/rawBuilder/declarations" private val testDirPath = "compiler/fir/psi2fir/testData/rawBuilder/declarations"
private fun executeTest(filePath: String) { private fun executeTest(filePath: String) {
val parserDefinition = KotlinParserDefinition() val lightTree2Fir = LightTree2Fir(true, myProject).buildFirFile(Paths.get(filePath)).render()
val lexer = parserDefinition.createLexer(myProject)
val lightTree2Fir = LightTree2Fir(true, parserDefinition, lexer).buildFirFile(Paths.get(filePath)).render()
val file = createKtFile(filePath) val file = createKtFile(filePath)
val firFile = file.toFirFile(stubMode = true) val firFile = file.toFirFile(stubMode = true)
@@ -47,9 +47,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
var counter = 0 var counter = 0
var time = 0L var time = 0L
val parserDefinition = KotlinParserDefinition() val lightTreeConverter = LightTree2Fir(true, myProject)
val lexer = parserDefinition.createLexer(myProject)
val lightTreeConverter = LightTree2Fir(true, parserDefinition, lexer)
if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter") if (onlyLightTree) println("LightTree generation") else println("Fir from LightTree converter")
println("BASE PATH: $path") println("BASE PATH: $path")
@@ -29,9 +29,7 @@ open class LightTree2FirGenerator : TreeGenerator, AbstractRawFirBuilderTestCase
} }
private fun createConverter() { private fun createConverter() {
val parserDefinition = KotlinParserDefinition() lightTreeConverter = LightTree2Fir(true, myProject)
val lexer = parserDefinition.createLexer(project)
lightTreeConverter = LightTree2Fir(true, parserDefinition, lexer)
} }
override fun setUp() { override fun setUp() {
@@ -15,9 +15,11 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirAbstractTreeTransformer
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
import org.jetbrains.kotlin.fir.visitors.compose import org.jetbrains.kotlin.fir.visitors.compose
import org.jetbrains.kotlin.psi.KtForExpression import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.KtLambdaExpression
class FirPartialTransformer( class FirPartialTransformer(
private val visitAnonymousFunction: Boolean = false, private val visitAnonymousFunction: Boolean = false,
private val visitLambdaExpression: Boolean = false,
private val visitNamedFunction: Boolean = false, private val visitNamedFunction: Boolean = false,
private val visitMemberDeclaration: Boolean = false, private val visitMemberDeclaration: Boolean = false,
private val visitVariable: Boolean = false, private val visitVariable: Boolean = false,
@@ -40,6 +42,7 @@ class FirPartialTransformer(
private val visitTryExpression: Boolean = false, private val visitTryExpression: Boolean = false,
private val visitWhenExpression: Boolean = false, private val visitWhenExpression: Boolean = false,
private val visitNamedArgumentExpression: Boolean = false, private val visitNamedArgumentExpression: Boolean = false,
private val visitLambdaArgumentExpression: Boolean = false,
private val visitSpreadArgumentExpression: Boolean = false, private val visitSpreadArgumentExpression: Boolean = false,
private val visitAnonymousObject: Boolean = false, private val visitAnonymousObject: Boolean = false,
private val visitDoWhileLoop: Boolean = false, private val visitDoWhileLoop: Boolean = false,
@@ -52,6 +55,8 @@ class FirPartialTransformer(
): CompositeTransformResult<FirDeclaration> { ): CompositeTransformResult<FirDeclaration> {
return if (visitAnonymousFunction) { return if (visitAnonymousFunction) {
(anonymousFunction.transformChildren(this, data) as FirAnonymousFunction).compose() (anonymousFunction.transformChildren(this, data) as FirAnonymousFunction).compose()
} else if (visitLambdaExpression && anonymousFunction.psi is KtLambdaExpression) {
(anonymousFunction.transformChildren(this, data) as FirAnonymousFunction).compose()
} else { } else {
DummyFirAnonymousFunction().compose() DummyFirAnonymousFunction().compose()
} }
@@ -265,6 +270,17 @@ class FirPartialTransformer(
} }
} }
override fun transformLambdaArgumentExpression(
lambdaArgumentExpression: FirLambdaArgumentExpression,
data: Nothing?
): CompositeTransformResult<FirStatement> {
return if (visitLambdaArgumentExpression) {
(lambdaArgumentExpression.transformChildren(this, data) as FirLambdaArgumentExpression).compose()
} else {
DummyFirStatement().compose()
}
}
override fun transformSpreadArgumentExpression( override fun transformSpreadArgumentExpression(
spreadArgumentExpression: FirSpreadArgumentExpression, spreadArgumentExpression: FirSpreadArgumentExpression,
data: Nothing? data: Nothing?
@@ -23,18 +23,14 @@ import java.io.File
@TestDataPath("\$PROJECT_ROOT") @TestDataPath("\$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners::class) @RunWith(JUnit3RunnerWithInners::class)
class TreesCompareTest : AbstractRawFirBuilderTestCase() { class TreesCompareTest : AbstractRawFirBuilderTestCase() {
private fun compareBase(stubMode: Boolean, compareFir: (File, LightTree2Fir) -> Boolean) { private fun compareBase(stubMode: Boolean, compareFir: (File) -> Boolean) {
val path = System.getProperty("user.dir") val path = System.getProperty("user.dir")
var counter = 0 var counter = 0
var errorCounter = 0 var errorCounter = 0
val parserDefinition = KotlinParserDefinition()
val lexer = parserDefinition.createLexer(myProject)
val lightTreeConverter = LightTree2Fir(stubMode, parserDefinition, lexer)
println("BASE PATH: $path") println("BASE PATH: $path")
path.walkTopDown { file -> path.walkTopDown { file ->
if (!compareFir(file, lightTreeConverter)) errorCounter++ if (!compareFir(file)) errorCounter++
counter++ counter++
} }
println("All scanned files: $counter") println("All scanned files: $counter")
@@ -43,7 +39,8 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
} }
private fun compareAll(stubMode: Boolean) { private fun compareAll(stubMode: Boolean) {
compareBase(stubMode) { file, lightTreeConverter -> val lightTreeConverter = LightTree2Fir(stubMode, myProject)
compareBase(stubMode) { file ->
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
//light tree //light tree
@@ -62,6 +59,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
private fun compare( private fun compare(
stubMode: Boolean, stubMode: Boolean,
visitAnonymousFunction: Boolean = false, visitAnonymousFunction: Boolean = false,
visitLambdaExpression: Boolean = false,
visitNamedFunction: Boolean = false, visitNamedFunction: Boolean = false,
visitMemberDeclaration: Boolean = false, visitMemberDeclaration: Boolean = false,
visitVariable: Boolean = false, visitVariable: Boolean = false,
@@ -84,6 +82,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
visitTryExpression: Boolean = false, visitTryExpression: Boolean = false,
visitWhenExpression: Boolean = false, visitWhenExpression: Boolean = false,
visitNamedArgumentExpression: Boolean = false, visitNamedArgumentExpression: Boolean = false,
visitLambdaArgumentExpression: Boolean = false,
visitSpreadArgumentExpression: Boolean = false, visitSpreadArgumentExpression: Boolean = false,
visitAnonymousObject: Boolean = false, visitAnonymousObject: Boolean = false,
visitDoWhileLoop: Boolean = false, visitDoWhileLoop: Boolean = false,
@@ -92,6 +91,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
) { ) {
val firVisitor = FirPartialTransformer( val firVisitor = FirPartialTransformer(
visitAnonymousFunction = visitAnonymousFunction, visitAnonymousFunction = visitAnonymousFunction,
visitLambdaExpression = visitLambdaExpression,
visitNamedFunction = visitNamedFunction, visitNamedFunction = visitNamedFunction,
visitMemberDeclaration = visitMemberDeclaration, visitMemberDeclaration = visitMemberDeclaration,
visitVariable = visitVariable, visitVariable = visitVariable,
@@ -114,13 +114,15 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
visitTryExpression = visitTryExpression, visitTryExpression = visitTryExpression,
visitWhenExpression = visitWhenExpression, visitWhenExpression = visitWhenExpression,
visitNamedArgumentExpression = visitNamedArgumentExpression, visitNamedArgumentExpression = visitNamedArgumentExpression,
visitLambdaArgumentExpression = visitLambdaArgumentExpression,
visitSpreadArgumentExpression = visitSpreadArgumentExpression, visitSpreadArgumentExpression = visitSpreadArgumentExpression,
visitAnonymousObject = visitAnonymousObject, visitAnonymousObject = visitAnonymousObject,
visitDoWhileLoop = visitDoWhileLoop, visitDoWhileLoop = visitDoWhileLoop,
visitWhileLoop = visitWhileLoop, visitWhileLoop = visitWhileLoop,
visitAssignment = visitAssignment visitAssignment = visitAssignment
) )
compareBase(stubMode) { file, lightTreeConverter -> val lightTreeConverter = LightTree2Fir(stubMode, myProject)
compareBase(stubMode) { file ->
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim() val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
//light tree //light tree
@@ -153,4 +155,8 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
fun testConstExpression() { fun testConstExpression() {
compare(stubMode = false, visitConstExpression = true, visitAnnotation = true) compare(stubMode = false, visitConstExpression = true, visitAnnotation = true)
} }
fun testCallExpression() {
compare(stubMode = false, visitFunctionCall = true, visitLambdaExpression = false)
}
} }
@@ -16,4 +16,10 @@ public class MyKotlinParser {
return builder.getLightTree(); return builder.getLightTree();
} }
public static FlyweightCapableTreeStructure<LighterASTNode> parseBlockExpression(PsiBuilder builder) {
KotlinParsing ktParsing = KotlinParsing.createForTopLevel(new SemanticWhitespaceAwarePsiBuilderImpl(builder));
ktParsing.parseBlockExpression();
return builder.getLightTree();
}
} }