Partial raw FIR building
This commit is contained in:
committed by
Ilya Kirillov
parent
a1b621d987
commit
6129f4bcef
@@ -44,9 +44,7 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -66,6 +64,23 @@ class RawFirBuilder(
|
||||
return reference.accept(Visitor(), Unit) as FirTypeRef
|
||||
}
|
||||
|
||||
fun buildFunctionWithBody(function: KtNamedFunction): FirFunction<*> {
|
||||
assert(!stubMode) { "Building FIR function with body isn't supported in stub mode" }
|
||||
val parentsUpToFile = function.parents
|
||||
for (parent in parentsUpToFile.toList().asReversed()) {
|
||||
when (parent) {
|
||||
is KtFile -> {
|
||||
context.packageFqName = parent.packageFqName
|
||||
}
|
||||
is KtClassOrObject -> {
|
||||
context.className = context.className.child(parent.nameAsSafeName)
|
||||
context.localBits.add(parent.isLocal || parent.getStrictParentOfType<KtEnumEntry>() != null)
|
||||
}
|
||||
}
|
||||
}
|
||||
return function.accept(Visitor(), Unit) as FirFunction<*>
|
||||
}
|
||||
|
||||
override fun PsiElement.toFirSourceElement(kind: FirFakeSourceElementKind?): FirPsiSourceElement<*> {
|
||||
val actualKind = kind ?: this@RawFirBuilder.context.forcedElementSourceKind ?: FirRealSourceElementKind
|
||||
return this.toFirPsiSourceElement(actualKind)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// FUNCTION: bar
|
||||
|
||||
package test.locals
|
||||
|
||||
class Owner {
|
||||
fun foo(i: Int) {
|
||||
var x = true
|
||||
|
||||
fun bar() {
|
||||
baz(i, x)
|
||||
}
|
||||
}
|
||||
|
||||
fun baz(j: Int, y: Boolean) {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
local final? fun <local>/bar(): R|kotlin/Unit| {
|
||||
baz#(i#, x#)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// FUNCTION: foo
|
||||
|
||||
package test.classes
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
fun bar()
|
||||
|
||||
fun foo() {
|
||||
val outer = Outer()
|
||||
val inner = outer.Inner()
|
||||
inner.bar()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public? final? fun test/classes/Outer.Inner.foo(): R|kotlin/Unit| {
|
||||
lval <local>/outer: <implicit> = Outer#()
|
||||
lval <local>/inner: <implicit> = outer#.Inner#()
|
||||
inner#.bar#()
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// FUNCTION: foo
|
||||
|
||||
package test
|
||||
|
||||
fun bar(): Int {
|
||||
return -1
|
||||
}
|
||||
|
||||
fun foo(): Int {
|
||||
return 0
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public? final? fun test/foo(): Int {
|
||||
^foo IntegerLiteral(0)
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.builder
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractPartialRawFirBuilderTestCase : AbstractRawFirBuilderTestCase() {
|
||||
|
||||
override fun doRawFirTest(filePath: String) {
|
||||
val nameToFind = File(filePath).useLines {
|
||||
it.first().run {
|
||||
assert(startsWith(Companion.prefix))
|
||||
drop(Companion.prefix.length)
|
||||
}
|
||||
}
|
||||
val file = createKtFile(filePath)
|
||||
val functionToBuild = file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!!
|
||||
val firFunction = RawFirBuilder(
|
||||
object : FirSession(null) {}, StubFirScopeProvider, false
|
||||
).buildFunctionWithBody(functionToBuild)
|
||||
val firDump = firFunction.render(FirRenderer.RenderMode.WithFqNames)
|
||||
val expectedPath = filePath.replace(".kt", ".txt")
|
||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firDump)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val prefix = "// FUNCTION: "
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -60,7 +60,7 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
||||
}
|
||||
}
|
||||
|
||||
protected fun doRawFirTest(filePath: String) {
|
||||
protected open fun doRawFirTest(filePath: String) {
|
||||
val file = createKtFile(filePath)
|
||||
val firFile = file.toFirFile(stubMode = false)
|
||||
val firFileDump = StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.builder;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class PartialRawFirBuilderTestCaseGenerated extends AbstractPartialRawFirBuilderTestCase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doRawFirTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPartialRawBuilder() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("local.kt")
|
||||
public void testLocal() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/local.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("member.kt")
|
||||
public void testMember() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.kt");
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -119,7 +119,9 @@ fun CFGNode<*>.render(): String =
|
||||
)
|
||||
}
|
||||
|
||||
private object CfgRenderMode : FirRenderer.RenderMode(renderLambdaBodies = false, renderCallArguments = false)
|
||||
private object CfgRenderMode : FirRenderer.RenderMode(
|
||||
renderLambdaBodies = false, renderCallArguments = false, renderCallableFqNames = false
|
||||
)
|
||||
|
||||
private fun FirFunction<*>.name(): String = when (this) {
|
||||
is FirSimpleFunction -> name.asString()
|
||||
|
||||
@@ -50,8 +50,14 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
||||
)
|
||||
}
|
||||
|
||||
abstract class RenderMode(val renderLambdaBodies: Boolean, val renderCallArguments: Boolean) {
|
||||
object Normal : RenderMode(renderLambdaBodies = true, renderCallArguments = true)
|
||||
abstract class RenderMode(
|
||||
val renderLambdaBodies: Boolean,
|
||||
val renderCallArguments: Boolean,
|
||||
val renderCallableFqNames: Boolean
|
||||
) {
|
||||
object Normal : RenderMode(renderLambdaBodies = true, renderCallArguments = true, renderCallableFqNames = false)
|
||||
|
||||
object WithFqNames: RenderMode(renderLambdaBodies = true, renderCallArguments = true, renderCallableFqNames = true)
|
||||
}
|
||||
|
||||
private val printer = Printer(builder)
|
||||
@@ -150,8 +156,20 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
||||
print(".")
|
||||
}
|
||||
when (callableDeclaration) {
|
||||
is FirSimpleFunction -> print(callableDeclaration.name)
|
||||
is FirVariable<*> -> print(callableDeclaration.name)
|
||||
is FirSimpleFunction -> {
|
||||
if (!mode.renderCallableFqNames) {
|
||||
print(callableDeclaration.name)
|
||||
} else {
|
||||
print(callableDeclaration.symbol.callableId)
|
||||
}
|
||||
}
|
||||
is FirVariable<*> -> {
|
||||
if (!mode.renderCallableFqNames) {
|
||||
print(callableDeclaration.name)
|
||||
} else {
|
||||
print(callableDeclaration.symbol.callableId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callableDeclaration is FirFunction<*>) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.defaultConstructor.AbstractDefaultArgumentsR
|
||||
import org.jetbrains.kotlin.codegen.flags.AbstractWriteFlagsTest
|
||||
import org.jetbrains.kotlin.codegen.ir.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.builder.AbstractPartialRawFirBuilderTestCase
|
||||
import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase
|
||||
import org.jetbrains.kotlin.fir.java.AbstractFirOldFrontendLightClassesTest
|
||||
import org.jetbrains.kotlin.fir.java.AbstractFirTypeEnhancementTest
|
||||
@@ -544,6 +545,12 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("compiler/fir/raw-fir/psi2fir/tests", "compiler/fir/raw-fir/psi2fir/testData") {
|
||||
testClass<AbstractPartialRawFirBuilderTestCase> {
|
||||
model("partialRawBuilder", testMethod = "doRawFirTest")
|
||||
}
|
||||
}
|
||||
|
||||
testGroup("compiler/fir/raw-fir/light-tree2fir/tests", "compiler/fir/raw-fir/psi2fir/testData") {
|
||||
testClass<AbstractLightTree2FirConverterTestCase> {
|
||||
model("rawBuilder")
|
||||
|
||||
Reference in New Issue
Block a user