LL API: add basic tests for kt -> fir mapping

This commit is contained in:
Ilya Kirillov
2021-07-09 16:37:37 +02:00
committed by teamcityserver
parent 609296a46b
commit c0eb669191
93 changed files with 824 additions and 7 deletions
@@ -62,6 +62,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
val renderPropertyAccessors: Boolean = true,
val renderDeclarationAttributes: Boolean = false,
val renderDeclarationOrigin: Boolean = false,
val renderPackageDirective: Boolean = false,
) {
companion object {
val Normal = RenderMode(
@@ -1368,4 +1369,10 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
override fun visitContractDescription(contractDescription: FirContractDescription) {
require(contractDescription is FirEmptyContractDescription)
}
override fun visitPackageDirective(packageDirective: FirPackageDirective) {
if (mode.renderPackageDirective) {
println("package ${packageDirective.packageFqName.asString()}")
}
}
}
@@ -16,10 +16,7 @@ import org.jetbrains.kotlin.idea.fir.frontend.api.scopes.AbstractMemberScopeByFq
import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByFqNameTest
import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByPsiTest
import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByReferenceTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyBodiesCalculatorTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyDeclarationResolveTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirOnAirResolveTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractPartialRawFirBuilderTestCase
import org.jetbrains.kotlin.idea.fir.low.level.api.*
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractDiagnosticTraversalCounterTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractFirContextCollectionTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataSpecTest
@@ -115,6 +112,10 @@ fun main(args: Array<String>) {
testClass<AbstractPartialRawFirBuilderTestCase> {
model("partialRawBuilder", testMethod = "doRawFirTest")
}
testClass<AbstractGetOrBuildFirTest> {
model("getOrBuildFir")
}
}
testGroup(
@@ -0,0 +1 @@
import <expr>a</expr>.b.c
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirImportImpl
FIR element rendered:
import a.b.c
@@ -0,0 +1 @@
import a.<expr>b</expr>.c
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirImportImpl
FIR element rendered:
import a.b.c
@@ -0,0 +1 @@
import <expr>a.b</expr>.c
@@ -0,0 +1,5 @@
KT element: KtDotQualifiedExpression
FIR element: FirImportImpl
FIR element rendered:
import a.b.c
@@ -0,0 +1,3 @@
// LOOK_UP_FOR_ELEMENT_OF_TYPE: org.jetbrains.kotlin.psi.KtImportDirective
<expr>import a.b.c</expr>
@@ -0,0 +1,5 @@
KT element: KtImportDirective
FIR element: FirImportImpl
FIR element rendered:
import a.b.c
@@ -0,0 +1 @@
import <expr>a.b.c</expr>
@@ -0,0 +1,5 @@
KT element: KtDotQualifiedExpression
FIR element: FirImportImpl
FIR element rendered:
import a.b.c
@@ -0,0 +1 @@
package <expr>a</expr>.b.c
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirPackageDirectiveImpl
FIR element rendered:
package a.b.c
@@ -0,0 +1 @@
package a.<expr>b</expr>.c
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirPackageDirectiveImpl
FIR element rendered:
package a.b.c
@@ -0,0 +1 @@
package <expr>a.b</expr>.c
@@ -0,0 +1,5 @@
KT element: KtDotQualifiedExpression
FIR element: FirPackageDirectiveImpl
FIR element rendered:
package a.b.c
@@ -0,0 +1 @@
<expr>package a.b.c</expr>
@@ -0,0 +1,5 @@
KT element: KtPackageDirective
FIR element: FirPackageDirectiveImpl
FIR element rendered:
package a.b.c
@@ -0,0 +1 @@
package <expr>a.b.c</expr>
@@ -0,0 +1,5 @@
KT element: KtDotQualifiedExpression
FIR element: FirPackageDirectiveImpl
FIR element rendered:
package a.b.c
@@ -0,0 +1,11 @@
class A {
class B {
class C {
val x = 10
}
}
}
fun x() {
<expr>A</expr>.B.C().x
}
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirFunctionCallImpl
FIR element rendered:
Q|A.B|.R|/A.B.C.C|()
@@ -0,0 +1,11 @@
class A {
class B {
class C {
val x = 10
}
}
}
fun x() {
A.B.<expr>C()</expr>.x
}
@@ -0,0 +1,5 @@
KT element: KtCallExpression
FIR element: FirFunctionCallImpl
FIR element rendered:
Q|A.B|.R|/A.B.C.C|()
@@ -0,0 +1,11 @@
class A {
class B {
class C {
val x = 10
}
}
}
fun x() {
A.<expr>B</expr>.C().x
}
@@ -0,0 +1,5 @@
KT element: KtNameReferenceExpression
FIR element: FirResolvedQualifierImpl
FIR element rendered:
Q|A.B|
@@ -0,0 +1,11 @@
class A {
class B {
class C {
val x = 10
}
}
}
fun x() {
<expr>A.B</expr>.C().x
}
@@ -0,0 +1,5 @@
KT element: KtDotQualifiedExpression
FIR element: FirFunctionCallImpl
FIR element rendered:
Q|A.B|.R|/A.B.C.C|()
@@ -0,0 +1 @@
fun x(): <expr>List<Int, String></expr> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeReference
FIR element: FirErrorTypeRefImpl
FIR element rendered:
<ERROR TYPE REF: Wrong number of type arguments>
@@ -0,0 +1 @@
fun x(): List<Int, <expr>String</expr>> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/String|
@@ -0,0 +1 @@
fun x(): List< <expr>String</expr>, Int > = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/String|
@@ -0,0 +1 @@
fun x(): List<Int, <expr>String</expr>> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/String|
@@ -0,0 +1 @@
fun x(): Map<String, List< <expr> Int </expr> >> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/Int|
@@ -0,0 +1 @@
fun x(): Map<String, <expr> List<Int> </expr> > = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/collections/List<kotlin/Int>|
@@ -0,0 +1 @@
fun x(): <expr>List<UNRESOVLED></expr> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeReference
FIR element: FirResolvedTypeRefImpl
FIR element rendered:
R|kotlin/collections/List<ERROR CLASS: Symbol not found for UNRESOVLED>|
@@ -0,0 +1 @@
fun x(): UNRESOLVED<String, List< <expr> Int </expr> >> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/Int|
@@ -0,0 +1 @@
fun x(): UNRESOLVED<String, <expr> List<Int> </expr> > = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeProjection
FIR element: FirTypeProjectionWithVarianceImpl
FIR element rendered:
R|kotlin/collections/List<kotlin/Int>|
@@ -0,0 +1 @@
fun x(): <expr> Map<String, List<Int>> </expr> = TODO()
@@ -0,0 +1,5 @@
KT element: KtTypeReference
FIR element: FirResolvedTypeRefImpl
FIR element rendered:
R|kotlin/collections/Map<kotlin/String, kotlin/collections/List<kotlin/Int>>|
@@ -0,0 +1 @@
class X< <expr>T</expr> >()
@@ -0,0 +1,5 @@
KT element: KtTypeParameter
FIR element: FirTypeParameterImpl
FIR element rendered:
T
@@ -0,0 +1,3 @@
enum class X {
<expr>ENTRY</expr>
}
@@ -0,0 +1,5 @@
KT element: KtEnumEntry
FIR element: FirEnumEntryImpl
FIR element rendered:
public final static enum entry ENTRY: R|X|
@@ -0,0 +1 @@
fun x< <expr>T</expr> > foo(){}
@@ -0,0 +1,5 @@
KT element: KtTypeParameter
FIR element: FirTypeParameterImpl
FIR element rendered:
T
@@ -0,0 +1,3 @@
fun foo(<expr>x: Int</expr>) {
}
@@ -0,0 +1,5 @@
KT element: KtParameter
FIR element: FirValueParameterImpl
FIR element rendered:
x: R|kotlin/Int|
@@ -0,0 +1,2 @@
val x: String
<expr>get() = ""</expr>
@@ -0,0 +1,7 @@
KT element: KtPropertyAccessor
FIR element: FirPropertyAccessorImpl
FIR element rendered:
public get(): R|kotlin/String| {
^ String()
}
@@ -0,0 +1,7 @@
fun y() {
<expr>
class X {
fun y(): String
}
</expr>
}
@@ -0,0 +1,12 @@
KT element: KtClass
FIR element: FirRegularClassImpl
FIR element rendered:
local final class X : R|kotlin/Any| {
public constructor(): R|X| {
super<R|kotlin/Any|>()
}
public final fun y(): R|kotlin/String|
}
@@ -0,0 +1,5 @@
fun y() {
<expr>
fun x(): String = ""
</expr>
}
@@ -0,0 +1,7 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR element rendered:
local final fun x(): R|kotlin/String| {
^x String()
}
@@ -0,0 +1,5 @@
fun y() {
<expr>
val x: String = ""
</expr>
}
@@ -0,0 +1,5 @@
KT element: KtProperty
FIR element: FirPropertyImpl
FIR element rendered:
lval x: R|kotlin/String| = String()
@@ -0,0 +1,5 @@
class Y {
<expr>
fun x(): String = ""
</expr>
}
@@ -0,0 +1,7 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR element rendered:
public final fun x(): R|kotlin/String| {
^x String()
}
@@ -0,0 +1,5 @@
class Y {
<expr>
val x: String = ""
</expr>
}
@@ -0,0 +1,6 @@
KT element: KtProperty
FIR element: FirPropertyImpl
FIR element rendered:
public final val x: R|kotlin/String| = String()
public get(): R|kotlin/String|
@@ -0,0 +1,5 @@
class Y {
<expr>
typealias Str = String
</expr>
}
@@ -0,0 +1,5 @@
KT element: KtTypeAlias
FIR element: FirTypeAliasImpl
FIR element rendered:
public final typealias Str = R|kotlin/String|
@@ -0,0 +1,7 @@
class Y {
<expr>
class X {
fun y(): String
}
</expr>
}
@@ -0,0 +1,12 @@
KT element: KtClass
FIR element: FirRegularClassImpl
FIR element rendered:
public final class X : R|kotlin/Any| {
public constructor(): R|Y.X| {
super<R|kotlin/Any|>()
}
public final fun y(): R|kotlin/String|
}
@@ -0,0 +1 @@
class X(<expr>val x: Int</expr>)
@@ -0,0 +1,5 @@
KT element: KtParameter
FIR element: FirValueParameterImpl
FIR element rendered:
x: R|kotlin/Int|
@@ -0,0 +1,5 @@
KT element: KtParameter
FIR element: FirValueParameterImpl
FIR element rendered:
x: R|kotlin/Int|
@@ -0,0 +1,3 @@
class X(x: Int) {
constructor(<expr>y: String</expr>): this(1)
}
@@ -0,0 +1,5 @@
KT element: KtParameter
FIR element: FirValueParameterImpl
FIR element rendered:
y: R|kotlin/String|
@@ -0,0 +1,2 @@
var x: String
<expr>set(value) {}</expr>
@@ -0,0 +1,6 @@
KT element: KtPropertyAccessor
FIR element: FirPropertyAccessorImpl
FIR element rendered:
public set(value: R|kotlin/String|): R|kotlin/Unit| {
}
@@ -0,0 +1,5 @@
<expr>
class X {
fun y(): String
}
</expr>
@@ -0,0 +1,12 @@
KT element: KtClass
FIR element: FirRegularClassImpl
FIR element rendered:
public final class X : R|kotlin/Any| {
public constructor(): R|X| {
super<R|kotlin/Any|>()
}
public final fun y(): R|kotlin/String|
}
@@ -0,0 +1,5 @@
<expr>
fun x() {
fun y(): String
}
</expr>
@@ -0,0 +1,8 @@
KT element: KtNamedFunction
FIR element: FirSimpleFunctionImpl
FIR element rendered:
public final fun x(): R|kotlin/Unit| {
local final fun y(): R|kotlin/String|
}
@@ -0,0 +1,3 @@
<expr>
val x = 1
</expr>
@@ -0,0 +1,6 @@
KT element: KtProperty
FIR element: FirPropertyImpl
FIR element rendered:
public final val x: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
@@ -0,0 +1,3 @@
<expr>
typealias Str = String
</expr>
@@ -0,0 +1,5 @@
KT element: KtTypeAlias
FIR element: FirTypeAliasImpl
FIR element rendered:
public final typealias Str = R|kotlin/String|
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2021 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.idea.fir.low.level.api
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirImport
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.AbstractLowLevelApiSingleFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() {
override fun configureTest(builder: TestConfigurationBuilder) {
super.configureTest(builder)
with(builder) {
useDirectives(Directives)
}
}
override fun doTestByFileStructure(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices) {
val selectedElement = getElementOfType(ktFile, moduleStructure, testServices) as KtElement
val actual = resolveWithClearCaches(ktFile) { state ->
val fir = selectedElement.getOrBuildFir(state)
"""|KT element: ${selectedElement::class.simpleName}
|FIR element: ${fir::class.simpleName}
|
|FIR element rendered:
|${render(fir)}""".trimMargin()
}
testServices.assertions.assertEqualsToFile(testDataFileSibling(".txt"), actual)
}
private fun getElementOfType(ktFile: KtFile, moduleStructure: TestModuleStructure, testServices: TestServices): PsiElement {
val selectedElement = testServices.expressionMarkerProvider.getSelectedElement(ktFile)
val expectedType = moduleStructure.allDirectives[Directives.LOOK_UP_FOR_ELEMENT_OF_TYPE].firstOrNull() ?: return selectedElement
@Suppress("UNCHECKED_CAST") val expectedClass = Class.forName(expectedType) as Class<PsiElement>
if (expectedClass.isInstance(selectedElement)) return selectedElement
return listOfNotNull(
PsiTreeUtil.getChildOfType(selectedElement, expectedClass),
).single { it.textRange == selectedElement.textRange }
}
private fun render(firElement: FirElement): String = when (firElement) {
is FirImport -> "import ${firElement.importedFqName}"
else -> firElement.render(renderingMode)
}
private val renderingMode = FirRenderer.RenderMode.Normal.copy(
renderPackageDirective = true,
)
private object Directives : SimpleDirectivesContainer() {
val LOOK_UP_FOR_ELEMENT_OF_TYPE by stringDirective("LOOK_UP_FOR_ELEMENT_OF_TYPE")
}
}
@@ -0,0 +1,340 @@
/*
* Copyright 2010-2021 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.idea.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir")
@TestDataPath("$PROJECT_ROOT")
public class GetOrBuildFirTestGenerated extends AbstractGetOrBuildFirTest {
@Test
public void testAllFilesPresentInGetOrBuildFir() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Nested
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport")
@TestDataPath("$PROJECT_ROOT")
public class InImport {
@Test
public void testAllFilesPresentInInImport() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("firstImportNamePart.kt")
public void testFirstImportNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport/firstImportNamePart.kt");
}
@Test
@TestMetadata("middleImportNamePart.kt")
public void testMiddleImportNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport/middleImportNamePart.kt");
}
@Test
@TestMetadata("qualifiedImportNamePart.kt")
public void testQualifiedImportNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport/qualifiedImportNamePart.kt");
}
@Test
@TestMetadata("wholeImportDirective.kt")
public void testWholeImportDirective() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport/wholeImportDirective.kt");
}
@Test
@TestMetadata("wholeImportName.kt")
public void testWholeImportName() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inImport/wholeImportName.kt");
}
}
@Nested
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage")
@TestDataPath("$PROJECT_ROOT")
public class InPackage {
@Test
public void testAllFilesPresentInInPackage() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("firstPackageNamePart.kt")
public void testFirstPackageNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage/firstPackageNamePart.kt");
}
@Test
@TestMetadata("middlePackageNamePart.kt")
public void testMiddlePackageNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage/middlePackageNamePart.kt");
}
@Test
@TestMetadata("qualifiedPackageNamePart.kt")
public void testQualifiedPackageNamePart() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage/qualifiedPackageNamePart.kt");
}
@Test
@TestMetadata("wholePackageDirective.kt")
public void testWholePackageDirective() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage/wholePackageDirective.kt");
}
@Test
@TestMetadata("wholePackageName.kt")
public void testWholePackageName() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/inPackage/wholePackageName.kt");
}
}
@Nested
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions")
@TestDataPath("$PROJECT_ROOT")
public class QualifiedExpressions {
@Test
public void testAllFilesPresentInQualifiedExpressions() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("firstPartOfQualifiedCallWithNestedClasses.kt")
public void testFirstPartOfQualifiedCallWithNestedClasses() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions/firstPartOfQualifiedCallWithNestedClasses.kt");
}
@Test
@TestMetadata("lastPartOfQualifiedCallWithNestedClasses.kt")
public void testLastPartOfQualifiedCallWithNestedClasses() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions/lastPartOfQualifiedCallWithNestedClasses.kt");
}
@Test
@TestMetadata("middlePartOfQualifiedCallWithNestedClasses.kt")
public void testMiddlePartOfQualifiedCallWithNestedClasses() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions/middlePartOfQualifiedCallWithNestedClasses.kt");
}
@Test
@TestMetadata("qualifiedPartOfQualifiedCallWithNestedClasses.kt")
public void testQualifiedPartOfQualifiedCallWithNestedClasses() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/qualifiedExpressions/qualifiedPartOfQualifiedCallWithNestedClasses.kt");
}
}
@Nested
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types")
@TestDataPath("$PROJECT_ROOT")
public class Types {
@Test
public void testAllFilesPresentInTypes() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("invalidTypeArgumentsCount.kt")
public void testInvalidTypeArgumentsCount() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/invalidTypeArgumentsCount.kt");
}
@Test
@TestMetadata("invalidTypeArgumentsCountArgument.kt")
public void testInvalidTypeArgumentsCountArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/invalidTypeArgumentsCountArgument.kt");
}
@Test
@TestMetadata("invalidTypeArgumentsCountFirstArgument.kt")
public void testInvalidTypeArgumentsCountFirstArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/invalidTypeArgumentsCountFirstArgument.kt");
}
@Test
@TestMetadata("invalidTypeArgumentsCountLastArgument.kt")
public void testInvalidTypeArgumentsCountLastArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/invalidTypeArgumentsCountLastArgument.kt");
}
@Test
@TestMetadata("nestedTypeArgument.kt")
public void testNestedTypeArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/nestedTypeArgument.kt");
}
@Test
@TestMetadata("typeArgument.kt")
public void testTypeArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/typeArgument.kt");
}
@Test
@TestMetadata("unresolvedTypeArgumentResolvedTypeConsturctor.kt")
public void testUnresolvedTypeArgumentResolvedTypeConsturctor() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/unresolvedTypeArgumentResolvedTypeConsturctor.kt");
}
@Test
@TestMetadata("unresolvedTypeConsturctorResolvedNestedTypeArgument.kt")
public void testUnresolvedTypeConsturctorResolvedNestedTypeArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/unresolvedTypeConsturctorResolvedNestedTypeArgument.kt");
}
@Test
@TestMetadata("unresolvedTypeConsturctorResolvedTypeArgument.kt")
public void testUnresolvedTypeConsturctorResolvedTypeArgument() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/unresolvedTypeConsturctorResolvedTypeArgument.kt");
}
@Test
@TestMetadata("wholeType.kt")
public void testWholeType() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/types/wholeType.kt");
}
}
@Nested
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration")
@TestDataPath("$PROJECT_ROOT")
public class WholeDeclaration {
@Test
public void testAllFilesPresentInWholeDeclaration() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("classTypeParemeter.kt")
public void testClassTypeParemeter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/classTypeParemeter.kt");
}
@Test
@TestMetadata("enumEntry.kt")
public void testEnumEntry() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/enumEntry.kt");
}
@Test
@TestMetadata("functionTypeParemeter.kt")
public void testFunctionTypeParemeter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/functionTypeParemeter.kt");
}
@Test
@TestMetadata("functionValueParameter.kt")
public void testFunctionValueParameter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/functionValueParameter.kt");
}
@Test
@TestMetadata("getter.kt")
public void testGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/getter.kt");
}
@Test
@TestMetadata("localClass.kt")
public void testLocalClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/localClass.kt");
}
@Test
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/localFunction.kt");
}
@Test
@TestMetadata("localProperty.kt")
public void testLocalProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/localProperty.kt");
}
@Test
@TestMetadata("memberFunction.kt")
public void testMemberFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/memberFunction.kt");
}
@Test
@TestMetadata("memberProperty.kt")
public void testMemberProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/memberProperty.kt");
}
@Test
@TestMetadata("memberTypeAlias.kt")
public void testMemberTypeAlias() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/memberTypeAlias.kt");
}
@Test
@TestMetadata("nestedClass.kt")
public void testNestedClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/nestedClass.kt");
}
@Test
@TestMetadata("primaryConstructorValValueParameter.kt")
public void testPrimaryConstructorValValueParameter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/primaryConstructorValValueParameter.kt");
}
@Test
@TestMetadata("primaryConstructorValueParameter.kt")
public void testPrimaryConstructorValueParameter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/primaryConstructorValueParameter.kt");
}
@Test
@TestMetadata("secondaryConstructorValueParameter.kt")
public void testSecondaryConstructorValueParameter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/secondaryConstructorValueParameter.kt");
}
@Test
@TestMetadata("setter.kt")
public void testSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/setter.kt");
}
@Test
@TestMetadata("topLevelClass.kt")
public void testTopLevelClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/topLevelClass.kt");
}
@Test
@TestMetadata("topLevelFunction.kt")
public void testTopLevelFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/topLevelFunction.kt");
}
@Test
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/topLevelProperty.kt");
}
@Test
@TestMetadata("topLevelTypelTypeAlias.kt")
public void testTopLevelTypelTypeAlias() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/getOrBuildFir/wholeDeclaration/topLevelTypelTypeAlias.kt");
}
}
}
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.test.base
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.util.parentOfType
import org.jetbrains.kotlin.psi.KtElement
@@ -55,7 +57,9 @@ internal class ExpressionMarkersSourceFilePreprocessor(testServices: TestService
class ExpressionMarkerProvider(testServices: TestServices) : TestService {
private val selected = mutableMapOf<String, TextRange>()
@PrivateForInline val atCaret = mutableMapOf<String, Int>()
@PrivateForInline
val atCaret = mutableMapOf<String, Int>()
fun addSelectedExpression(file: TestFile, range: TextRange) {
selected[file.relativePath] = range
@@ -79,12 +83,16 @@ class ExpressionMarkerProvider(testServices: TestServices) : TestService {
fun getSelectedElement(file: KtFile): KtElement {
val range = selected[file.name]
?: error("No selected expression found in file")
val elements = file.elementsInRange(range)
val elements = file.elementsInRange(range).trimWhitespaces()
if (elements.size != 1) {
error("Expected one element at rage but found ${elements.size} [${elements.joinToString { it.text }}]")
error("Expected one element at rage but found ${elements.size} [${elements.joinToString { it::class.simpleName + ": " + it.text }}]")
}
return elements.single() as KtElement
}
private fun List<PsiElement>.trimWhitespaces(): List<PsiElement> =
dropWhile { it is PsiWhiteSpace }
.dropLastWhile { it is PsiWhiteSpace }
}
val TestServices.expressionMarkerProvider: ExpressionMarkerProvider by TestServices.testServiceAccessor()