FIR IDE: Implement RawFirBuilder::buildPropertyWithBody, add tests
This commit is contained in:
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import java.util.*
|
||||
|
||||
class RawFirBuilder(
|
||||
session: FirSession, val baseScopeProvider: FirScopeProvider, val stubMode: Boolean
|
||||
@@ -63,7 +62,19 @@ class RawFirBuilder(
|
||||
|
||||
fun buildFunctionWithBody(function: KtNamedFunction): FirFunction<*> {
|
||||
assert(!stubMode) { "Building FIR function with body isn't supported in stub mode" }
|
||||
val parentsUpToFile = function.parents
|
||||
setupContextForPosition(function)
|
||||
return function.accept(Visitor(), Unit) as FirFunction<*>
|
||||
}
|
||||
|
||||
fun buildPropertyWithBody(property: KtProperty): FirProperty {
|
||||
require(!property.isLocal) { "Should not be used to build local properties (variables)" }
|
||||
assert(!stubMode) { "Building FIR function with body isn't supported in stub mode" }
|
||||
setupContextForPosition(property)
|
||||
return property.accept(Visitor(), Unit) as FirProperty
|
||||
}
|
||||
|
||||
private fun setupContextForPosition(position: KtElement) {
|
||||
val parentsUpToFile = position.parents
|
||||
for (parent in parentsUpToFile.toList().asReversed()) {
|
||||
when (parent) {
|
||||
is KtFile -> {
|
||||
@@ -75,7 +86,6 @@ class RawFirBuilder(
|
||||
}
|
||||
}
|
||||
}
|
||||
return function.accept(Visitor(), Unit) as FirFunction<*>
|
||||
}
|
||||
|
||||
override fun PsiElement.toFirSourceElement(kind: FirFakeSourceElementKind?): FirPsiSourceElement<*> {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// PROPERTY: foo
|
||||
|
||||
package test.classes
|
||||
|
||||
class Outer {
|
||||
inner class Inner {
|
||||
fun bar(): Int
|
||||
|
||||
val foo: Int
|
||||
get() {
|
||||
val outer = Outer()
|
||||
val inner = outer.Inner()
|
||||
return inner.bar()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public? final? val test/classes/Outer.Inner.foo: Int
|
||||
public? get(): Int {
|
||||
lval <local>/outer: <implicit> = Outer#()
|
||||
lval <local>/inner: <implicit> = outer#.Inner#()
|
||||
^ inner#.bar#()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// PROPERTY: foo
|
||||
|
||||
package test
|
||||
|
||||
val bar: Int = 10
|
||||
|
||||
val foo: Int = 0
|
||||
@@ -0,0 +1,2 @@
|
||||
public? final? val test/foo: Int = IntegerLiteral(0)
|
||||
public? get(): Int
|
||||
@@ -0,0 +1,7 @@
|
||||
// PROPERTY: foo
|
||||
|
||||
package test
|
||||
|
||||
val bar: Int = 10
|
||||
|
||||
var foo: Int = 0
|
||||
@@ -0,0 +1,3 @@
|
||||
public? final? var test/foo: Int = IntegerLiteral(0)
|
||||
public? get(): Int
|
||||
public? set(value: Int): R|kotlin/Unit|
|
||||
+43
-10
@@ -5,36 +5,69 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.builder
|
||||
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
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 fileText = File(filePath).readText()
|
||||
val functionName = InTextDirectivesUtils.findStringWithPrefixes(fileText, FUNCTION_DIRECTIVE)
|
||||
val propertyName = InTextDirectivesUtils.findStringWithPrefixes(fileText, PROPERTY_DIRECTIVE)
|
||||
|
||||
when {
|
||||
functionName != null -> testFunctionPartialBuilding(filePath, functionName)
|
||||
propertyName != null -> testPropertyPartialBuilding(filePath, propertyName)
|
||||
else -> fail("No '$FUNCTION_DIRECTIVE' or '$PROPERTY_DIRECTIVE' directives found!")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun testFunctionPartialBuilding(filePath: String, nameToFind: String) {
|
||||
testPartialBuilding(
|
||||
filePath,
|
||||
{ file -> file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!! },
|
||||
RawFirBuilder::buildFunctionWithBody
|
||||
)
|
||||
}
|
||||
|
||||
private fun testPropertyPartialBuilding(filePath: String, nameToFind: String) {
|
||||
testPartialBuilding(
|
||||
filePath,
|
||||
{ file -> file.findDescendantOfType<KtProperty> { it.name == nameToFind }!! },
|
||||
RawFirBuilder::buildPropertyWithBody
|
||||
)
|
||||
}
|
||||
|
||||
private fun <T : KtElement> testPartialBuilding(
|
||||
filePath: String,
|
||||
findPsiElement: (KtFile) -> T,
|
||||
buildFirElement: (RawFirBuilder, T) -> FirElement
|
||||
) {
|
||||
val file = createKtFile(filePath)
|
||||
val functionToBuild = file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!!
|
||||
val elementToBuild = findPsiElement(file)
|
||||
|
||||
val session = FirSessionFactory.createEmptySession()
|
||||
|
||||
val firFunction = RawFirBuilder(session, StubFirScopeProvider, false)
|
||||
.buildFunctionWithBody(functionToBuild)
|
||||
val firElement = buildFirElement(RawFirBuilder(session, StubFirScopeProvider, false), elementToBuild)
|
||||
|
||||
val firDump = firFunction.render(FirRenderer.RenderMode.WithFqNames)
|
||||
val firDump = firElement.render(FirRenderer.RenderMode.WithFqNames)
|
||||
val expectedPath = filePath.replace(".kt", ".txt")
|
||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firDump)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val prefix = "// FUNCTION: "
|
||||
private const val FUNCTION_DIRECTIVE = "// FUNCTION: "
|
||||
private const val PROPERTY_DIRECTIVE = "// PROPERTY: "
|
||||
}
|
||||
}
|
||||
|
||||
+24
-9
@@ -28,18 +28,33 @@ public class PartialRawFirBuilderTestCaseGenerated extends AbstractPartialRawFir
|
||||
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("localFunction.kt")
|
||||
public void testLocalFunction() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/localFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("member.kt")
|
||||
public void testMember() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.kt");
|
||||
@TestMetadata("memberFunction.kt")
|
||||
public void testMemberFunction() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.kt");
|
||||
@TestMetadata("memberProperty.kt")
|
||||
public void testMemberProperty() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleFunction.kt")
|
||||
public void testSimpleFunction() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleVal.kt")
|
||||
public void testSimpleVal() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleVar.kt")
|
||||
public void testSimpleVar() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.kt");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user