From d19a23aae57f054f4e62b79a6d993ed447e05c80 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Tue, 8 Aug 2023 20:42:16 +0200 Subject: [PATCH] [LL FIR] implement tests on dependent copy session analyze ^KT-60987 --- ...ExpressionMarkersSourceFilePreprocessor.kt | 34 ++++++++++--- .../testdata/dependentCopy/class.context.txt | 19 ++++++++ .../testdata/dependentCopy/class.fir.txt | 15 ++++++ .../testdata/dependentCopy/class.kt | 3 ++ .../dependentCopy/classBody.context.txt | 19 ++++++++ .../testdata/dependentCopy/classBody.fir.txt | 6 +++ .../testdata/dependentCopy/classBody.kt | 3 ++ .../dependentCopy/classBodyScript.context.txt | 38 +++++++++++++++ .../dependentCopy/classBodyScript.fir.txt | 6 +++ .../dependentCopy/classBodyScript.kts | 3 ++ .../dependentCopy/classScript.context.txt | 38 +++++++++++++++ .../dependentCopy/classScript.fir.txt | 15 ++++++ .../testdata/dependentCopy/classScript.kts | 3 ++ .../api/fir/AbstractContextCollectorTest.kt | 2 +- .../fir/AbstractDependentCopyContextTest.kt | 37 ++++++++++++++ .../api/fir/AbstractDependentCopyFirTest.kt | 32 +++++++++++++ .../api/fir/AbstractDependentCopyTest.kt | 48 +++++++++++++++++++ ...riptDependentCopyContextTestGenerated.java | 38 +++++++++++++++ .../ScriptDependentCopyFirTestGenerated.java | 38 +++++++++++++++ ...urceDependentCopyContextTestGenerated.java | 38 +++++++++++++++ .../SourceDependentCopyFirTestGenerated.java | 38 +++++++++++++++ .../tests/analysis/api/firLowLevel.kt | 16 +++++++ 22 files changed, 482 insertions(+), 7 deletions(-) create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/class.context.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/class.fir.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/class.kt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBody.context.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBody.fir.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBody.kt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.context.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.fir.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.kts create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classScript.context.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classScript.fir.txt create mode 100644 analysis/low-level-api-fir/testdata/dependentCopy/classScript.kts create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractDependentCopyContextTest.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractDependentCopyFirTest.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractDependentCopyTest.kt create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/ScriptDependentCopyContextTestGenerated.java create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/ScriptDependentCopyFirTestGenerated.java create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceDependentCopyContextTestGenerated.java create mode 100644 analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/SourceDependentCopyFirTestGenerated.java diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ExpressionMarkersSourceFilePreprocessor.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ExpressionMarkersSourceFilePreprocessor.kt index cacf444a156..c07afe6d7f7 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ExpressionMarkersSourceFilePreprocessor.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/ExpressionMarkersSourceFilePreprocessor.kt @@ -17,8 +17,12 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType import org.jetbrains.kotlin.psi.psiUtil.elementsInRange import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer +import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue import org.jetbrains.kotlin.test.model.TestFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.SourceFilePreprocessor @@ -101,6 +105,18 @@ class ExpressionMarkerProvider : TestService { ?: error("No expression found at caret") } + inline fun getElementOfTypeAtCaretByDirective( + file: KtFile, + registeredDirectives: RegisteredDirectives, + caretTag: String? = null, + ): P { + val elementAtCaret = getElementOfTypeAtCaret

(file, caretTag) + val expectedType = expectedTypeClass(registeredDirectives) ?: return elementAtCaret + return (elementAtCaret as PsiElement).parentsWithSelf.firstNotNullOfOrNull { currentElement -> + currentElement.takeIf(expectedType::isInstance) as? P + } ?: error("Element of ${P::class.simpleName} & ${expectedType.simpleName} is not found") + } + @OptIn(PrivateForInline::class) inline fun getElementsOfTypeAtCarets( files: Collection, @@ -136,16 +152,22 @@ class ExpressionMarkerProvider : TestService { return elements.single() } - fun getSelectedElementOfTypeByDirective(ktFile: KtFile, module: TestModule): PsiElement { - val selectedElement = getSelectedElement(ktFile) - val expectedType = module.directives[Directives.LOOK_UP_FOR_ELEMENT_OF_TYPE].firstOrNull() ?: return selectedElement + fun expectedTypeClass(registeredDirectives: RegisteredDirectives): Class? { + val expectedType = registeredDirectives.singleOrZeroValue(Directives.LOOK_UP_FOR_ELEMENT_OF_TYPE) ?: return null val ktPsiPackage = "org.jetbrains.kotlin.psi." val expectedTypeFqName = ktPsiPackage + expectedType.removePrefix(ktPsiPackage) - @Suppress("UNCHECKED_CAST") val expectedClass = Class.forName(expectedTypeFqName) as Class - if (expectedClass.isInstance(selectedElement)) return selectedElement + + @Suppress("UNCHECKED_CAST") + return Class.forName(expectedTypeFqName) as Class + } + + fun getSelectedElementOfTypeByDirective(ktFile: KtFile, module: TestModule): PsiElement { + val selectedElement = getSelectedElement(ktFile) + val expectedType = expectedTypeClass(module.directives) ?: return selectedElement + if (expectedType.isInstance(selectedElement)) return selectedElement return selectedElement.collectDescendantsOfType { - expectedClass.isInstance(it) + expectedType.isInstance(it) }.single { it.textRange == selectedElement.textRange } } diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/class.context.txt b/analysis/low-level-api-fir/testdata/dependentCopy/class.context.txt new file mode 100644 index 00000000000..37c3571711b --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/class.context.txt @@ -0,0 +1,19 @@ +Tower Data Context: + Element 0 + Scope: FirDefaultStarImportingScope + Element 1 + Scope: FirDefaultSimpleImportingScope + Element 2 + Scope: FirExplicitStarImportingScope + Element 3 + Scope: FirDefaultSimpleImportingScope + Element 4 + Scope: FirDefaultSimpleImportingScope + Element 5 + Scope: FirPackageMemberScope + Element 6 + Scope: FirExplicitSimpleImportingScope + Element 7 + Implicit receiver: + FirRegularClassSymbol public final class A : R|kotlin/Any| + Type: A diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/class.fir.txt b/analysis/low-level-api-fir/testdata/dependentCopy/class.fir.txt new file mode 100644 index 00000000000..eb68d2f58f0 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/class.fir.txt @@ -0,0 +1,15 @@ +KT element: KtClass +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] class A : R|kotlin/Any| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=A] constructor(): R|A| { + super() + } + + public final [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Int| { + ^foo Int(42) + } + +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/class.kt b/analysis/low-level-api-fir/testdata/dependentCopy/class.kt new file mode 100644 index 00000000000..0afee429141 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/class.kt @@ -0,0 +1,3 @@ +class A() { + fun foo() = 42 +} diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/classBody.context.txt b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.context.txt new file mode 100644 index 00000000000..37c3571711b --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.context.txt @@ -0,0 +1,19 @@ +Tower Data Context: + Element 0 + Scope: FirDefaultStarImportingScope + Element 1 + Scope: FirDefaultSimpleImportingScope + Element 2 + Scope: FirExplicitStarImportingScope + Element 3 + Scope: FirDefaultSimpleImportingScope + Element 4 + Scope: FirDefaultSimpleImportingScope + Element 5 + Scope: FirPackageMemberScope + Element 6 + Scope: FirExplicitSimpleImportingScope + Element 7 + Implicit receiver: + FirRegularClassSymbol public final class A : R|kotlin/Any| + Type: A diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/classBody.fir.txt b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.fir.txt new file mode 100644 index 00000000000..e1eab7e9877 --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.fir.txt @@ -0,0 +1,6 @@ +KT element: KtClassBody +FIR element: null +FIR source kind: null + +FIR element rendered: +null \ No newline at end of file diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/classBody.kt b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.kt new file mode 100644 index 00000000000..d1a03fe0b9c --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/classBody.kt @@ -0,0 +1,3 @@ +class A() { + fun foo() = 42 +} diff --git a/analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.context.txt b/analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.context.txt new file mode 100644 index 00000000000..2f7b580710e --- /dev/null +++ b/analysis/low-level-api-fir/testdata/dependentCopy/classBodyScript.context.txt @@ -0,0 +1,38 @@ +Tower Data Context: + Element 0 + Scope: FirDefaultStarImportingScope + Element 1 + Scope: FirDefaultSimpleImportingScope + Element 2 + Scope: FirExplicitStarImportingScope + Element 3 + Scope: FirDefaultSimpleImportingScope + Element 4 + Scope: FirDefaultSimpleImportingScope + Element 5 + Scope: FirPackageMemberScope + Element 6 + Scope: FirExplicitSimpleImportingScope + Element 7 + Scope: FirScriptDeclarationsScope + Classifiers: + FirRegularClassSymbol public? final? class A : R|kotlin/Any| + Element 8 + Scope: FirLocalScope + Classifiers: + FirRegularClassSymbol public final class A : R|kotlin/Any| + Properties: + FirPropertySymbol lval args: R|kotlin/Array| + Element 9 + Context receivers: + FirScriptSymbol context(