From ad9953724f140c3efc58e6bde39b32f7cfaed977 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 17 Oct 2018 14:15:10 +0300 Subject: [PATCH] Basic infrastructure for psi2ir tests with JS front-end --- .../ir/irJsText/dynamic/invokeOperator.kt | 5 ++ .../ir/irJsText/dynamic/invokeOperator.txt | 41 ++++++++++++++++ .../kotlin/ir/AbstractIrGeneratorTestCase.kt | 41 ++++++++++++++-- .../kotlin/ir/AbstractIrJsTextTestCase.kt | 18 +++++++ .../generators/tests/GenerateCompilerTests.kt | 5 ++ .../kotlin/ir/IrJsTextTestCaseGenerated.java | 49 +++++++++++++++++++ 6 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/ir/irJsText/dynamic/invokeOperator.kt create mode 100644 compiler/testData/ir/irJsText/dynamic/invokeOperator.txt create mode 100644 compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrJsTextTestCase.kt create mode 100644 compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java diff --git a/compiler/testData/ir/irJsText/dynamic/invokeOperator.kt b/compiler/testData/ir/irJsText/dynamic/invokeOperator.kt new file mode 100644 index 00000000000..3df0f2fc80f --- /dev/null +++ b/compiler/testData/ir/irJsText/dynamic/invokeOperator.kt @@ -0,0 +1,5 @@ +fun test1(a: dynamic) = a(1) +fun test1a(a: dynamic) = a.invoke(1) +fun test2(a: dynamic, b: dynamic) = a(b) +fun test2a(a: dynamic, b: dynamic) = a.invoke(b) +fun test2b(a: dynamic, b: dynamic) = a(b)(b) \ No newline at end of file diff --git a/compiler/testData/ir/irJsText/dynamic/invokeOperator.txt b/compiler/testData/ir/irJsText/dynamic/invokeOperator.txt new file mode 100644 index 00000000000..30b4c3f4860 --- /dev/null +++ b/compiler/testData/ir/irJsText/dynamic/invokeOperator.txt @@ -0,0 +1,41 @@ +FILE fqName: fileName:/invokeOperator.kt + FUN name:test1 visibility:public modality:FINAL <> (a:dynamic) returnType:dynamic flags: + VALUE_PARAMETER name:a index:0 type:dynamic flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='test1(dynamic): dynamic' + CALL 'invoke(dynamic): dynamic' type=dynamic origin=INVOKE + $this: GET_VAR 'value-parameter a: dynamic' type=dynamic origin=VARIABLE_AS_FUNCTION + p0: CONST Int type=kotlin.Int value=1 + FUN name:test1a visibility:public modality:FINAL <> (a:dynamic) returnType:dynamic flags: + VALUE_PARAMETER name:a index:0 type:dynamic flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='test1a(dynamic): dynamic' + CALL 'invoke(dynamic): dynamic' type=dynamic origin=null + $this: GET_VAR 'value-parameter a: dynamic' type=dynamic origin=null + p0: CONST Int type=kotlin.Int value=1 + FUN name:test2 visibility:public modality:FINAL <> (a:dynamic, b:dynamic) returnType:dynamic flags: + VALUE_PARAMETER name:a index:0 type:dynamic flags: + VALUE_PARAMETER name:b index:1 type:dynamic flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='test2(dynamic, dynamic): dynamic' + CALL 'invoke(dynamic): dynamic' type=dynamic origin=INVOKE + $this: GET_VAR 'value-parameter a: dynamic' type=dynamic origin=VARIABLE_AS_FUNCTION + p0: GET_VAR 'value-parameter b: dynamic' type=dynamic origin=null + FUN name:test2a visibility:public modality:FINAL <> (a:dynamic, b:dynamic) returnType:dynamic flags: + VALUE_PARAMETER name:a index:0 type:dynamic flags: + VALUE_PARAMETER name:b index:1 type:dynamic flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='test2a(dynamic, dynamic): dynamic' + CALL 'invoke(dynamic): dynamic' type=dynamic origin=null + $this: GET_VAR 'value-parameter a: dynamic' type=dynamic origin=null + p0: GET_VAR 'value-parameter b: dynamic' type=dynamic origin=null + FUN name:test2b visibility:public modality:FINAL <> (a:dynamic, b:dynamic) returnType:dynamic flags: + VALUE_PARAMETER name:a index:0 type:dynamic flags: + VALUE_PARAMETER name:b index:1 type:dynamic flags: + BLOCK_BODY + RETURN type=kotlin.Nothing from='test2b(dynamic, dynamic): dynamic' + CALL 'invoke(dynamic): dynamic' type=dynamic origin=null + $this: CALL 'invoke(dynamic): dynamic' type=dynamic origin=INVOKE + $this: GET_VAR 'value-parameter a: dynamic' type=dynamic origin=VARIABLE_AS_FUNCTION + p0: GET_VAR 'value-parameter b: dynamic' type=dynamic origin=null + p0: GET_VAR 'value-parameter b: dynamic' type=dynamic origin=null diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt index 0712f9998e5..bf84daf52d1 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.ir import junit.framework.TestCase +import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.CodegenTestCase @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator @@ -90,14 +92,18 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { protected fun generateIrModule(ignoreErrors: Boolean = false, shouldGenerate: (KtFile) -> Boolean = { true }): IrModuleFragment { assert(myFiles != null) { "myFiles not initialized" } assert(myEnvironment != null) { "myEnvironment not initialized" } - return generateIrModule( - myFiles.psiFiles, - myEnvironment, + return doGenerateIrModule( Psi2IrTranslator(myEnvironment.configuration.languageVersionSettings, Psi2IrConfiguration(ignoreErrors)), shouldGenerate ) } + protected open fun doGenerateIrModule( + psi2IrTranslator: Psi2IrTranslator, + shouldGenerate: (KtFile) -> Boolean + ): IrModuleFragment = + generateIrModuleWithJvmResolve(myFiles.psiFiles, myEnvironment, psi2IrTranslator, shouldGenerate) + protected fun generateIrFilesAsSingleModule(testFiles: List, ignoreErrors: Boolean = false): Map { val irModule = generateIrModule(ignoreErrors) val ktFiles = testFiles.filter { it.name.endsWith(".kt") } @@ -121,13 +127,38 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { return textFile } - fun generateIrModule( + fun generateIrModuleWithJsResolve( ktFilesToAnalyze: List, environment: KotlinCoreEnvironment, psi2ir: Psi2IrTranslator, shouldGenerate: (KtFile) -> Boolean + ): IrModuleFragment = + generateIrModule( + TopDownAnalyzerFacadeForJS.analyzeFiles( + ktFilesToAnalyze, environment.project, environment.configuration, + moduleDescriptors = emptyList(), + friendModuleDescriptors = emptyList() + ), + psi2ir, ktFilesToAnalyze, shouldGenerate + ) + + fun generateIrModuleWithJvmResolve( + ktFilesToAnalyze: List, + environment: KotlinCoreEnvironment, + psi2ir: Psi2IrTranslator, + shouldGenerate: (KtFile) -> Boolean + ): IrModuleFragment = + generateIrModule( + JvmResolveUtil.analyze(ktFilesToAnalyze, environment), + psi2ir, ktFilesToAnalyze, shouldGenerate + ) + + private fun generateIrModule( + analysisResult: AnalysisResult, + psi2ir: Psi2IrTranslator, + ktFilesToAnalyze: List, + shouldGenerate: (KtFile) -> Boolean ): IrModuleFragment { - val analysisResult = JvmResolveUtil.analyze(ktFilesToAnalyze, environment) if (!psi2ir.configuration.ignoreErrors) { analysisResult.throwIfError() AnalyzingUtils.throwExceptionOnErrors(analysisResult.bindingContext) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrJsTextTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrJsTextTestCase.kt new file mode 100644 index 00000000000..67675ae09b4 --- /dev/null +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrJsTextTestCase.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.ir + +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator + +abstract class AbstractIrJsTextTestCase : AbstractIrTextTestCase() { + override fun doGenerateIrModule( + psi2IrTranslator: Psi2IrTranslator, + shouldGenerate: (KtFile) -> Boolean + ): IrModuleFragment = + generateIrModuleWithJsResolve(myFiles.psiFiles, myEnvironment, psi2IrTranslator, shouldGenerate) +} diff --git a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt index 00a5ac1050b..ccecb4f549d 100644 --- a/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt +++ b/compiler/tests/org/jetbrains/kotlin/generators/tests/GenerateCompilerTests.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.generators.tests.generator.testGroup import org.jetbrains.kotlin.generators.util.KT_OR_KTS_WITHOUT_DOTS_IN_NAME import org.jetbrains.kotlin.integration.AbstractAntTaskTest import org.jetbrains.kotlin.ir.AbstractIrCfgTestCase +import org.jetbrains.kotlin.ir.AbstractIrJsTextTestCase import org.jetbrains.kotlin.ir.AbstractIrSourceRangesTestCase import org.jetbrains.kotlin.ir.AbstractIrTextTestCase import org.jetbrains.kotlin.jvm.compiler.* @@ -184,6 +185,10 @@ fun main(args: Array) { model("ir/irText") } + testClass { + model("ir/irJsText") + } + testClass { model("ir/irCfg") } diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java new file mode 100644 index 00000000000..27c90f25273 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrJsTextTestCaseGenerated.java @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. 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.ir; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +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/testData/ir/irJsText") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class IrJsTextTestCaseGenerated extends AbstractIrJsTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInIrJsText() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irJsText"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("compiler/testData/ir/irJsText/dynamic") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Dynamic extends AbstractIrJsTextTestCase { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInDynamic() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irJsText/dynamic"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("invokeOperator.kt") + public void testInvokeOperator() throws Exception { + runTest("compiler/testData/ir/irJsText/dynamic/invokeOperator.kt"); + } + } +}