From d5ad424e8fa765aaf9607301668b6d5c7fe036e6 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 24 Sep 2020 22:52:38 +0300 Subject: [PATCH] FIR: introduce source element mappings tests for raw FIR --- .../qualifiedExpression.kt | 3 + .../qualifiedExpression.txt | 1 + ...wFirBuilderSourceElementMappingTestCase.kt | 75 +++++++++++++++++++ ...SourceElementMappingTestCaseGenerated.java | 35 +++++++++ .../generators/tests/GenerateCompilerTests.kt | 5 ++ 5 files changed, 119 insertions(+) create mode 100644 compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.kt create mode 100644 compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.txt create mode 100644 compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderSourceElementMappingTestCase.kt create mode 100644 compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/RawFirBuilderSourceElementMappingTestCaseGenerated.java diff --git a/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.kt b/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.kt new file mode 100644 index 00000000000..fa5fcfeac30 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.kt @@ -0,0 +1,3 @@ +fun x(a: List) { + a.size +} \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.txt b/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.txt new file mode 100644 index 00000000000..b333beb57ba --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.txt @@ -0,0 +1 @@ +a#.size# \ No newline at end of file diff --git a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderSourceElementMappingTestCase.kt b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderSourceElementMappingTestCase.kt new file mode 100644 index 00000000000..e2871e37ca8 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/AbstractRawFirBuilderSourceElementMappingTestCase.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2018 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.openapi.util.TextRange +import com.intellij.openapi.util.io.FileUtil +import com.intellij.util.PathUtil +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.realPsi +import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.visitors.FirVisitor +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.psiUtil.elementsInRange +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + +abstract class AbstractRawFirBuilderSourceElementMappingTestCase : AbstractRawFirBuilderTestCase() { + override fun doRawFirTest(filePath: String) { + val fileTextWithCaret = loadFile(filePath)!! + val fileTextWithoutCaret = fileTextWithCaret.replace(START_EXPRESSION_TAG, "").replace(END_EXPRESSION_TAG, "") + val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(filePath)), fileTextWithoutCaret) as KtFile + val selectedExpression = run { + val startCaretPosition = fileTextWithCaret.indexOf(START_EXPRESSION_TAG) + if (startCaretPosition < 0) { + error("$START_EXPRESSION_TAG was not found in the file") + } + val endCaretPosition = fileTextWithCaret.indexOf(END_EXPRESSION_TAG) + if (endCaretPosition < 0) { + error("$END_EXPRESSION_TAG was not found in the file") + } + val elements = ktFile.elementsInRange(TextRange(startCaretPosition, endCaretPosition - START_EXPRESSION_TAG.length)) + if (elements.size != 1) { + error("Expected one element at rage but found ${elements.size} [${elements.joinToString { it.text }}]") + } + elements.single() as KtElement + } + val firFile = ktFile.toFirFile(stubMode = false) + val foundElement = run { + val foundElements = FindElementVisitor.find(firFile, selectedExpression) + if (foundElements.size != 1) { + error("One element expected but found [${foundElements.joinToString { "${it::class.simpleName} `${it.render()}`" }}]") + } + foundElements.single() + } + + val expectedPath = filePath.replace(".kt", ".txt") + KotlinTestUtils.assertEqualsToFile(File(expectedPath), foundElement.render()) + } + + companion object { + private const val START_EXPRESSION_TAG = "" + private const val END_EXPRESSION_TAG = "" + } + + private object FindElementVisitor : FirVisitor() { + override fun visitElement(element: FirElement, data: ElementFindingResult) { + element.realPsi?.let { psi -> + if (data.psi == psi) { + data.result += element + } + } + element.acceptChildren(this, data) + } + + fun find(firFile: FirFile, element: KtElement): Set = + ElementFindingResult(element, mutableSetOf()).also { firFile.accept(this, it) }.result + } + + private data class ElementFindingResult(val psi: KtElement, val result: MutableSet) +} diff --git a/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/RawFirBuilderSourceElementMappingTestCaseGenerated.java b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/RawFirBuilderSourceElementMappingTestCaseGenerated.java new file mode 100644 index 00000000000..6e1fa89ec78 --- /dev/null +++ b/compiler/fir/raw-fir/psi2fir/tests/org/jetbrains/kotlin/fir/builder/RawFirBuilderSourceElementMappingTestCaseGenerated.java @@ -0,0 +1,35 @@ +/* + * 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/sourceElementMapping") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class RawFirBuilderSourceElementMappingTestCaseGenerated extends AbstractRawFirBuilderSourceElementMappingTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doRawFirTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSourceElementMapping() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("qualifiedExpression.kt") + public void testQualifiedExpression() throws Exception { + runTest("compiler/fir/raw-fir/psi2fir/testData/sourceElementMapping/qualifiedExpression.kt"); + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt index a6f039dcfb7..7b4c74676bd 100644 --- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt +++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt @@ -23,6 +23,7 @@ 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.AbstractRawFirBuilderSourceElementMappingTestCase import org.jetbrains.kotlin.fir.builder.AbstractRawFirBuilderTestCase import org.jetbrains.kotlin.fir.java.AbstractFirOldFrontendLightClassesTest import org.jetbrains.kotlin.fir.java.AbstractFirTypeEnhancementTest @@ -579,6 +580,10 @@ fun main(args: Array) { testClass { model("rawBuilder", testMethod = "doRawFirTest") } + + testClass { + model("sourceElementMapping", testMethod = "doRawFirTest") + } } testGroup("compiler/fir/raw-fir/psi2fir/tests", "compiler/fir/raw-fir/psi2fir/testData") {