diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index d99036b23d9..ba4f67f1d59 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -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<*> { diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/local.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/localFunction.kt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/local.kt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/localFunction.kt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/local.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/localFunction.txt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/local.txt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/localFunction.txt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberFunction.kt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.kt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberFunction.kt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberFunction.txt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/member.txt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberFunction.txt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.kt new file mode 100644 index 00000000000..4e304b774af --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.kt @@ -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() + } + } +} \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.txt new file mode 100644 index 00000000000..b642e42fb9f --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/memberProperty.txt @@ -0,0 +1,6 @@ +public? final? val test/classes/Outer.Inner.foo: Int + public? get(): Int { + lval /outer: = Outer#() + lval /inner: = outer#.Inner#() + ^ inner#.bar#() + } diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleFunction.kt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.kt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleFunction.kt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleFunction.txt similarity index 100% rename from compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simple.txt rename to compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleFunction.txt diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.kt new file mode 100644 index 00000000000..5efc88c0425 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.kt @@ -0,0 +1,7 @@ +// PROPERTY: foo + +package test + +val bar: Int = 10 + +val foo: Int = 0 \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.txt new file mode 100644 index 00000000000..0e66ab3dcf3 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVal.txt @@ -0,0 +1,2 @@ +public? final? val test/foo: Int = IntegerLiteral(0) + public? get(): Int diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.kt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.kt new file mode 100644 index 00000000000..5c3dae0ebd8 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.kt @@ -0,0 +1,7 @@ +// PROPERTY: foo + +package test + +val bar: Int = 10 + +var foo: Int = 0 \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.txt b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.txt new file mode 100644 index 00000000000..359d962bde5 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/partialRawBuilder/simpleVar.txt @@ -0,0 +1,3 @@ +public? final? var test/foo: Int = IntegerLiteral(0) + public? get(): Int + public? set(value: Int): R|kotlin/Unit| diff --git a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractPartialRawFirBuilderTestCase.kt b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractPartialRawFirBuilderTestCase.kt index e2d05f276e9..c86bf81a189 100644 --- a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractPartialRawFirBuilderTestCase.kt +++ b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractPartialRawFirBuilderTestCase.kt @@ -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 { it.name == nameToFind }!! }, + RawFirBuilder::buildFunctionWithBody + ) + } + + private fun testPropertyPartialBuilding(filePath: String, nameToFind: String) { + testPartialBuilding( + filePath, + { file -> file.findDescendantOfType { it.name == nameToFind }!! }, + RawFirBuilder::buildPropertyWithBody + ) + } + + private fun testPartialBuilding( + filePath: String, + findPsiElement: (KtFile) -> T, + buildFirElement: (RawFirBuilder, T) -> FirElement + ) { val file = createKtFile(filePath) - val functionToBuild = file.findDescendantOfType { 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: " } } diff --git a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/PartialRawFirBuilderTestCaseGenerated.java b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/PartialRawFirBuilderTestCaseGenerated.java index 91521a7158a..98144114ff8 100644 --- a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/PartialRawFirBuilderTestCaseGenerated.java +++ b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/PartialRawFirBuilderTestCaseGenerated.java @@ -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"); } }