Add some test cases to test performance and tree construction correctness

This commit is contained in:
Ivan Kylchik
2019-04-19 18:41:38 +03:00
committed by Mikhail Glukhikh
parent d1e87eb90c
commit 343dcca79d
4 changed files with 239 additions and 44 deletions
@@ -0,0 +1,35 @@
/*
* 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.ParserDefinition
import com.intellij.lang.impl.PsiBuilderFactoryImpl
import com.intellij.lexer.Lexer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.CharsetToolkit
import org.jetbrains.kotlin.fir.FirSessionBase
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.parsing.MyKotlinParser
import java.io.File
import java.nio.file.Path
class LightTree2Fir(val stubMode: Boolean, private val parserDefinition: ParserDefinition, private val lexer: Lexer) {
fun buildFirFile(path: Path): FirFile {
return buildFirFile(path.toFile())
}
fun buildFirFile(file: File): FirFile {
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
return buildFirFile(text, file.name)
}
fun buildFirFile(text: String, fileName: String): FirFile {
val builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, text)
MyKotlinParser.parse(builder)
return Converter(object : FirSessionBase() {}, stubMode, builder.lightTree).convertFile(builder.lightTree.root, fileName)
}
}
@@ -0,0 +1,108 @@
/*
* 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.testFramework.TestDataPath
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.junit.runner.RunWith
import java.nio.file.Paths
@TestDataPath("\$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners::class)
class LightTree2FirConverterTestCases : AbstractRawFirBuilderTestCase() {
private fun executeTest(filePath: String) {
val parserDefinition = KotlinParserDefinition()
val lexer = parserDefinition.createLexer(myProject)
val lightTree2Fir = LightTree2Fir(true, parserDefinition, lexer).buildFirFile(Paths.get(filePath)).render()
val file = createKtFile(filePath)
val firFile = file.toFirFile(stubMode = true)
val firFileDump = StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
TestCase.assertEquals(firFileDump, lightTree2Fir)
}
fun testComplexTypes() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt")
}
fun testDerivedClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt")
}
fun testEnums() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/enums.kt")
}
fun testEnums2() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/enums2.kt")
}
fun testExpectActual() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt")
}
fun testF() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/F.kt")
}
fun testFunctionTypes() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/functionTypes.kt")
}
fun testGenericFunctions() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/genericFunctions.kt")
}
fun testNestedClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/nestedClass.kt")
}
fun testNestedOfAliasedType() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/NestedOfAliasedType.kt")
}
fun testNestedSuperType() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/NestedSuperType.kt")
}
fun testNoPrimaryConstructor() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.kt")
}
fun testSimpleClass() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleClass.kt")
}
fun testSimpleFun() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleFun.kt")
}
fun testSimpleTypeAlias() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt")
}
fun testTypeAliasWithGeneric() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt")
}
fun testTypeParameterVsNested() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameterVsNested.kt")
}
fun testTypeParameters() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/typeParameters.kt")
}
fun testWhere() {
executeTest("compiler/fir/psi2fir/testData/rawBuilder/declarations/where.kt")
}
}
@@ -14,49 +14,20 @@ import com.intellij.psi.impl.PsiManagerEx
import com.intellij.testFramework.LightVirtualFile
import com.intellij.testFramework.TestDataPath
import com.intellij.util.PathUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.parsing.*
import org.jetbrains.kotlin.parsing.KotlinParser
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.jetbrains.kotlin.test.testFramework.KtParsingTestCase
import org.junit.runner.RunWith
import java.io.File
import kotlin.system.measureNanoTime
/*
* 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 BaseTestCase : KtParsingTestCase(
"",
"kt",
KotlinParserDefinition()
) {
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 builder = PsiBuilderFactoryImpl().createBuilder(parserDefinition, lexer, "class Base { val x: Int = 1 }")
val ktParsing = parserDefinition.createParser(myProject) as KotlinParser
ktParsing.parse(null, builder, file)
println(DebugUtil.lightTreeToString(builder.lightTree, false))
println(DebugUtil.nodeTreeToString(builder.treeBuilt, false))
}
class LightTree2FirConverterTotalKotlin : AbstractRawFirBuilderTestCase() {
fun testTotalKotlinLight() {
val path = System.getProperty("user.dir")
val root = File(path)
@@ -65,7 +36,7 @@ class BaseTestCase : KtParsingTestCase(
val parserDefinition = KotlinParserDefinition()
val lexer = parserDefinition.createLexer(myProject)
val psiBuilder = PsiBuilderFactoryImpl()
val lightTreeConverter = LightTree2Fir(true, parserDefinition, lexer)
println("light test")
println("BASE PATH: $path")
@@ -76,11 +47,8 @@ class BaseTestCase : KtParsingTestCase(
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
time += measureNanoTime {
val builder = psiBuilder.createBuilder(parserDefinition, lexer, text)
MyKotlinParser.parse(builder)
//builder.lightTree.hashCode()
DebugUtil.lightTreeToString(builder.lightTree, false)
val firFile = lightTreeConverter.buildFirFile(text, file.name)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
}
counter++
@@ -106,8 +74,8 @@ class BaseTestCase : KtParsingTestCase(
val text = FileUtil.loadFile(file, CharsetToolkit.UTF8, true).trim()
time += measureNanoTime {
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile
//ktFile.hashCode()
DebugUtil.psiTreeToString(ktFile, false)
val firFile = ktFile.toFirFile(stubMode = true)
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
}
counter++
@@ -116,5 +84,4 @@ class BaseTestCase : KtParsingTestCase(
println("TIME PER FILE: ${(time / counter) * 1e-6} ms, COUNTER: $counter")
}
}
}
@@ -0,0 +1,85 @@
/*
* 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.ParserDefinition
import com.intellij.lang.impl.PsiBuilderFactoryImpl
import com.intellij.lexer.Lexer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.CharsetToolkit
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 com.intellij.util.PathUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.FirSessionBase
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.parsing.*
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners
import org.junit.runner.RunWith
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.system.measureNanoTime
/*
* 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 = Converter(object : FirSessionBase() {}, 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(stubMode = true)
println("Fir from PSI")
println(StringBuilder().also { FirRenderer(it).visitFile(firFromPsiFile) }.toString())
}
}