From a3566174d6dd24fc59c5409f222895a23bcdf9d6 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Tue, 25 Oct 2016 17:44:26 +0300 Subject: [PATCH] Support destructuring in lambda parameters (KT-14422) and skipping some components in a destructuring declaration (KT-14507). --- .../multiDecl/VarCapturedInFunctionLiteral.kt | 2 + .../multiDecl/VarCapturedInLocalFunction.kt | 2 + .../multiDecl/VarCapturedInObjectLiteral.kt | 2 + .../codegen/box/multiDecl/component.kt | 4 +- .../kotlin/generators/tests/GenerateTests.kt | 8 + .../LambdaDestructuringTestsGenerated.java | 85 +++ .../MultiDeclarationTestsGenerated.java | 520 ++++++++++++++++++ .../abstractClassesForGeneratedTests.kt | 6 +- .../DestructuringDeclarationTranslator.java | 6 +- .../expression/LiteralFunctionTranslator.kt | 20 +- .../js/translate/general/Translation.java | 3 + 11 files changed, 653 insertions(+), 5 deletions(-) create mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LambdaDestructuringTestsGenerated.java create mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/MultiDeclarationTestsGenerated.java diff --git a/compiler/testData/codegen/box/multiDecl/VarCapturedInFunctionLiteral.kt b/compiler/testData/codegen/box/multiDecl/VarCapturedInFunctionLiteral.kt index e0eb2cb5edd..74b5e5773f8 100644 --- a/compiler/testData/codegen/box/multiDecl/VarCapturedInFunctionLiteral.kt +++ b/compiler/testData/codegen/box/multiDecl/VarCapturedInFunctionLiteral.kt @@ -1,3 +1,5 @@ +// TODO: enable JS backend when issue KT-14535 is fixed +// TARGET_BACKEND: JVM class A { operator fun component1() = 1 operator fun component2() = 2 diff --git a/compiler/testData/codegen/box/multiDecl/VarCapturedInLocalFunction.kt b/compiler/testData/codegen/box/multiDecl/VarCapturedInLocalFunction.kt index 5c2a87c9d65..7116e806bfb 100644 --- a/compiler/testData/codegen/box/multiDecl/VarCapturedInLocalFunction.kt +++ b/compiler/testData/codegen/box/multiDecl/VarCapturedInLocalFunction.kt @@ -1,3 +1,5 @@ +// TODO: enable JS backend when issue KT-14535 is fixed +// TARGET_BACKEND: JVM class A { } diff --git a/compiler/testData/codegen/box/multiDecl/VarCapturedInObjectLiteral.kt b/compiler/testData/codegen/box/multiDecl/VarCapturedInObjectLiteral.kt index 48534b362c6..dbb3b2c2e01 100644 --- a/compiler/testData/codegen/box/multiDecl/VarCapturedInObjectLiteral.kt +++ b/compiler/testData/codegen/box/multiDecl/VarCapturedInObjectLiteral.kt @@ -1,3 +1,5 @@ +// TODO: enable JS backend when issue KT-14535 is fixed +// TARGET_BACKEND: JVM class A { operator fun component1() = 1 operator fun component2() = 2 diff --git a/compiler/testData/codegen/box/multiDecl/component.kt b/compiler/testData/codegen/box/multiDecl/component.kt index 9595a700b3b..c6c822ddb69 100644 --- a/compiler/testData/codegen/box/multiDecl/component.kt +++ b/compiler/testData/codegen/box/multiDecl/component.kt @@ -3,7 +3,7 @@ class S(val a: String, val b: String) { operator fun component2() : String = b } -operator fun S.component3() = ((a + b) as java.lang.String).substring(2) +operator fun S.component3() = ((a + b) as String).substring(2) class Tester() { fun box() : String { @@ -11,7 +11,7 @@ class Tester() { return o + k + ok + ok2 } - operator fun S.component4() = ((a + b) as java.lang.String).substring(2) + operator fun S.component4() = ((a + b) as String).substring(2) } fun box() = Tester().box() \ No newline at end of file diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 5161e1a2ef9..ec50ef73652 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -1213,6 +1213,14 @@ fun main(args: Array) { testClass() { model("codegen/box/binaryOp", targetBackend = TargetBackend.JS) } + + testClass() { + model("codegen/box/destructuringDeclInLambdaParam/", targetBackend = TargetBackend.JS) + } + + testClass() { + model("codegen/box/multiDecl/", targetBackend = TargetBackend.JS) + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LambdaDestructuringTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LambdaDestructuringTestsGenerated.java new file mode 100644 index 00000000000..9f43a25e483 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/LambdaDestructuringTestsGenerated.java @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics; + +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/testData/codegen/box/destructuringDeclInLambdaParam") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class LambdaDestructuringTestsGenerated extends AbstractLambdaDestructuringTests { + public void testAllFilesPresentInDestructuringDeclInLambdaParam() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/destructuringDeclInLambdaParam"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("extensionComponents.kt") + public void testExtensionComponents() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/extensionComponents.kt"); + doTest(fileName); + } + + @TestMetadata("generic.kt") + public void testGeneric() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/generic.kt"); + doTest(fileName); + } + + @TestMetadata("inline.kt") + public void testInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/inline.kt"); + doTest(fileName); + } + + @TestMetadata("otherParameters.kt") + public void testOtherParameters() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/otherParameters.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/simple.kt"); + doTest(fileName); + } + + @TestMetadata("stdlibUsages.kt") + public void testStdlibUsages() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/stdlibUsages.kt"); + doTest(fileName); + } + + @TestMetadata("underscoreNames.kt") + public void testUnderscoreNames() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/underscoreNames.kt"); + doTest(fileName); + } + + @TestMetadata("withIndexed.kt") + public void testWithIndexed() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/destructuringDeclInLambdaParam/withIndexed.kt"); + doTest(fileName); + } +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/MultiDeclarationTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/MultiDeclarationTestsGenerated.java new file mode 100644 index 00000000000..c1fd88f8fdf --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/MultiDeclarationTestsGenerated.java @@ -0,0 +1,520 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics; + +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/testData/codegen/box/multiDecl") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class MultiDeclarationTestsGenerated extends AbstractMultiDeclarationTests { + @TestMetadata("VarCapturedInFunctionLiteral.kt") + public void ignoredVarCapturedInFunctionLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/VarCapturedInFunctionLiteral.kt"); + doTest(fileName); + } + + @TestMetadata("VarCapturedInLocalFunction.kt") + public void ignoredVarCapturedInLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/VarCapturedInLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("VarCapturedInObjectLiteral.kt") + public void ignoredVarCapturedInObjectLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/VarCapturedInObjectLiteral.kt"); + doTest(fileName); + } + + public void testAllFilesPresentInMultiDecl() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ComplexInitializer.kt") + public void testComplexInitializer() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ComplexInitializer.kt"); + doTest(fileName); + } + + @TestMetadata("component.kt") + public void testComponent() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/component.kt"); + doTest(fileName); + } + + @TestMetadata("kt9828_hashMap.kt") + public void testKt9828_hashMap() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/kt9828_hashMap.kt"); + doTest(fileName); + } + + @TestMetadata("returnInElvis.kt") + public void testReturnInElvis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/returnInElvis.kt"); + doTest(fileName); + } + + @TestMetadata("SimpleVals.kt") + public void testSimpleVals() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/SimpleVals.kt"); + doTest(fileName); + } + + @TestMetadata("SimpleValsExtensions.kt") + public void testSimpleValsExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/SimpleValsExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("SimpleVarsExtensions.kt") + public void testSimpleVarsExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/SimpleVarsExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("UnderscoreNames.kt") + public void testUnderscoreNames() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/UnderscoreNames.kt"); + doTest(fileName); + } + + @TestMetadata("ValCapturedInFunctionLiteral.kt") + public void testValCapturedInFunctionLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ValCapturedInFunctionLiteral.kt"); + doTest(fileName); + } + + @TestMetadata("ValCapturedInLocalFunction.kt") + public void testValCapturedInLocalFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ValCapturedInLocalFunction.kt"); + doTest(fileName); + } + + @TestMetadata("ValCapturedInObjectLiteral.kt") + public void testValCapturedInObjectLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/ValCapturedInObjectLiteral.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forIterator") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForIterator extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInForIterator() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forIterator"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclFor.kt") + public void testMultiDeclFor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/MultiDeclFor.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForValCaptured.kt") + public void testMultiDeclForValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/MultiDeclForValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forIterator/longIterator") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class LongIterator extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInLongIterator() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forIterator/longIterator"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/longIterator/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forIterator/longIterator/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForRange extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInForRange() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclFor.kt") + public void testMultiDeclFor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/MultiDeclFor.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForValCaptured.kt") + public void testMultiDeclForValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/MultiDeclForValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("UnderscoreNames.kt") + public void testUnderscoreNames() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNames.kt"); + doTest(fileName); + } + + @TestMetadata("UnderscoreNamesDontCallComponent.kt") + public void testUnderscoreNamesDontCallComponent() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/UnderscoreNamesDontCallComponent.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ExplicitRangeTo extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInExplicitRangeTo() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclFor.kt") + public void testMultiDeclFor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/MultiDeclFor.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForValCaptured.kt") + public void testMultiDeclForValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/MultiDeclForValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Int extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInInt() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Long extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInLong() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeTo/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ExplicitRangeToWithDot extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInExplicitRangeToWithDot() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclFor.kt") + public void testMultiDeclFor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/MultiDeclFor.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForValCaptured.kt") + public void testMultiDeclForValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/MultiDeclForValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Int extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInInt() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Long extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInLong() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/explicitRangeToWithDot/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/int") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Int extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInInt() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/int"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/int/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/int/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/int/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/int/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + + @TestMetadata("compiler/testData/codegen/box/multiDecl/forRange/long") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Long extends AbstractMultiDeclarationTests { + public void testAllFilesPresentInLong() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiDecl/forRange/long"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MultiDeclForComponentExtensions.kt") + public void testMultiDeclForComponentExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/long/MultiDeclForComponentExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentExtensionsValCaptured.kt") + public void testMultiDeclForComponentExtensionsValCaptured() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/long/MultiDeclForComponentExtensionsValCaptured.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensions.kt") + public void testMultiDeclForComponentMemberExtensions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/long/MultiDeclForComponentMemberExtensions.kt"); + doTest(fileName); + } + + @TestMetadata("MultiDeclForComponentMemberExtensionsInExtensionFunction.kt") + public void testMultiDeclForComponentMemberExtensionsInExtensionFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/multiDecl/forRange/long/MultiDeclForComponentMemberExtensionsInExtensionFunction.kt"); + doTest(fileName); + } + } + } +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt index ea9789660a1..0b9a3d70180 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt @@ -61,4 +61,8 @@ abstract class AbstractNonLocalReturnsTest : BorrowedInlineTest("nonLocalReturns abstract class AbstractTypeAliasesTests : BorrowedTest("typealias/") -abstract class AbstractBinaryOpTests : BorrowedTest("binaryOp/") \ No newline at end of file +abstract class AbstractBinaryOpTests : BorrowedTest("binaryOp/") + +abstract class AbstractLambdaDestructuringTests : BorrowedTest("destructuringDeclInLambdaParam/") + +abstract class AbstractMultiDeclarationTests : BorrowedTest("multiDecl/") \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java index 90367133e32..8640dd192a1 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/DestructuringDeclarationTranslator.java @@ -79,6 +79,10 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator { JsNameRef multiObjNameRef = multiObjectName.makeRef(); for (KtDestructuringDeclarationEntry entry : multiDeclaration.getEntries()) { + VariableDescriptor descriptor = BindingContextUtils.getNotNull( context().bindingContext(), BindingContext.VARIABLE, entry); + // Do not call `componentX` for destructuring entry called _ + if (descriptor.getName().isSpecial()) continue; + ResolvedCall entryInitCall = context().bindingContext().get(BindingContext.COMPONENT_RESOLVED_CALL, entry); assert entryInitCall != null : "Entry init call must be not null"; JsExpression entryInitializer = CallTranslator.translate(context(), entryInitCall, multiObjNameRef); @@ -86,7 +90,7 @@ public class DestructuringDeclarationTranslator extends AbstractTranslator { if (CallExpressionTranslator.shouldBeInlined(candidateDescriptor)) { setInlineCallMetadata(entryInitializer, entry, entryInitCall, context()); } - VariableDescriptor descriptor = BindingContextUtils.getNotNull( context().bindingContext(), BindingContext.VARIABLE, entry); + JsName name = context().getNameForDescriptor(descriptor); jsVars.add(new JsVars.JsVar(name, entryInitializer)); } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt index 92882d055db..10ad72f7f73 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/LiteralFunctionTranslator.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.expression import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.metadata.* import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.js.inline.util.getInnerFunction import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.getNameForCapturedDescriptor @@ -30,6 +31,8 @@ import org.jetbrains.kotlin.js.translate.utils.FunctionBodyTranslator.translateF import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunction import org.jetbrains.kotlin.psi.KtDeclarationWithBody +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.inline.InlineUtil class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslator(context) { @@ -39,8 +42,14 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato val lambda = invokingContext.getFunctionObject(descriptor) val functionContext = invokingContext.newFunctionBodyWithUsageTracker(lambda, descriptor) - FunctionTranslator.addParameters(lambda.parameters, descriptor, functionContext) + + descriptor.valueParameters.forEach { + if (it is ValueParameterDescriptorImpl.WithDestructuringDeclaration) { + lambda.body.statements.add(it.translate(functionContext)) + } + } + val functionBody = translateFunctionBody(descriptor, declaration, functionContext) lambda.body.statements.addAll(functionBody.statements) lambda.functionDescriptor = descriptor @@ -62,6 +71,15 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato lambda.isLocal = true return invokingContext.define(descriptor, lambda).apply { sideEffects = SideEffectKind.PURE } } + + fun ValueParameterDescriptorImpl.WithDestructuringDeclaration.translate(context: TranslationContext): JsVars { + val destructuringDeclaration = + (DescriptorToSourceUtils.descriptorToDeclaration(this) as? KtParameter)?.destructuringDeclaration + ?: error("Destructuring declaration for descriptor $this not found") + + val jsParameter = JsParameter(context.getNameForDescriptor(this)) + return DestructuringDeclarationTranslator.translate(destructuringDeclaration, jsParameter.name, null, context) + } } fun JsFunction.withCapturedParameters(context: TranslationContext, invokingContext: TranslationContext, descriptor: MemberDescriptor): JsExpression { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index 341c2755ff1..391a1db5139 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -253,6 +253,9 @@ public final class Translation { StaticContext staticContext = StaticContext.generateStaticContext(bindingTrace, config, moduleDescriptor); JsProgram program = staticContext.getProgram(); + // Prohibit using "_" as a variable name + program.getRootScope().declareName("_"); + JsFunction rootFunction = JsAstUtils.createFunctionWithEmptyBody(program.getScope()); JsBlock rootBlock = rootFunction.getBody(); List statements = rootBlock.getStatements();