From 68b35aa0ac3de1baa071c9ddf6f981ce5e3edc94 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Fri, 18 Nov 2016 15:29:57 +0300 Subject: [PATCH] JS inliner: Don't treat 'bar' as unused in the presence of 'bar.call' expressions --- .../codegen/boxInline/noInline/noInline.kt | 6 ++ .../kotlin/generators/tests/GenerateTests.kt | 9 ++- .../removeUnusedLocalFunctionDeclarations.kt | 9 +-- .../semantics/NoInlineTestsGenerated.java | 80 +++++++++++++++++++ .../abstractClassesForGeneratedTests.kt | 2 + 5 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/NoInlineTestsGenerated.java diff --git a/compiler/testData/codegen/boxInline/noInline/noInline.kt b/compiler/testData/codegen/boxInline/noInline/noInline.kt index 09e11aa1940..8c313f6bba9 100644 --- a/compiler/testData/codegen/boxInline/noInline/noInline.kt +++ b/compiler/testData/codegen/boxInline/noInline/noInline.kt @@ -5,6 +5,8 @@ inline fun calc(s: (Int) -> Int, noinline p: (Int) -> Int) : Int { return s(11) + z(11) + p(11) } +inline fun extensionLambda(noinline bar: Int.() -> Int) = 10.bar() + // FILE: 2.kt //NO_CHECK_LAMBDA_INLINING @@ -12,9 +14,13 @@ fun test1(): Int { return calc( { l: Int -> 2*l}, { l: Int -> 4*l}) } +fun test2(): Int { + return extensionLambda({this * 16}) +} fun box(): String { if (test1() != 110) return "test1: ${test1()}" + if (test2() != 160) return "test2: ${test2()}" return "OK" } diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 85b15a6fd44..b62878a9425 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -130,10 +130,6 @@ import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest import org.jetbrains.kotlin.jps.build.* import org.jetbrains.kotlin.jps.build.android.AbstractAndroidJpsTestCase import org.jetbrains.kotlin.jps.incremental.AbstractProtoComparisonTest -import org.jetbrains.kotlin.js.test.semantics.AbstractBoxJsTest -import org.jetbrains.kotlin.js.test.semantics.AbstractJsCodegenBoxTest -import org.jetbrains.kotlin.js.test.semantics.AbstractNonLocalReturnsTest -import org.jetbrains.kotlin.js.test.semantics.AbstractPropertyAccessorsInlineTests import org.jetbrains.kotlin.jvm.compiler.* import org.jetbrains.kotlin.jvm.runtime.AbstractJvm8RuntimeDescriptorLoaderTest import org.jetbrains.kotlin.jvm.runtime.AbstractJvmRuntimeDescriptorLoaderTest @@ -158,6 +154,7 @@ import org.jetbrains.kotlin.shortenRefs.AbstractShortenRefsTest import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.types.AbstractTypeBindingTest import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest +import org.jetbrains.kotlin.js.test.semantics.* import java.io.File import java.lang.IllegalArgumentException import java.util.* @@ -1193,6 +1190,10 @@ fun main(args: Array) { testClass() { model("codegen/boxInline/property/", targetBackend = TargetBackend.JS) } + + testClass() { + model("codegen/boxInline/noInline/", targetBackend = TargetBackend.JS) + } } } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedLocalFunctionDeclarations.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedLocalFunctionDeclarations.kt index 97e7db0d874..d66078289d8 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedLocalFunctionDeclarations.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/removeUnusedLocalFunctionDeclarations.kt @@ -62,12 +62,11 @@ private class UnusedInstanceCollector : JsVisitorWithContextImpl() { } override fun visit(x: JsNameRef, ctx: JsContext<*>): Boolean { - val name = x.name - - if (name != null) { - tracker.markReachable(name) + var q: JsNameRef? = x + while (q != null) { + q.name?.let { tracker.markReachable(it) } + q = q.qualifier as? JsNameRef } - return false } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/NoInlineTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/NoInlineTestsGenerated.java new file mode 100644 index 00000000000..2cd7d6e2b88 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/NoInlineTestsGenerated.java @@ -0,0 +1,80 @@ +/* + * 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.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/codegen/boxInline/noInline") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class NoInlineTestsGenerated extends AbstractNoInlineTests { + public void testAllFilesPresentInNoInline() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/noInline"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("extensionReceiver.kt") + public void testExtensionReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/extensionReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("lambdaAsGeneric.kt") + public void testLambdaAsGeneric() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsGeneric.kt"); + doTest(fileName); + } + + @TestMetadata("lambdaAsNonFunction.kt") + public void testLambdaAsNonFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/lambdaAsNonFunction.kt"); + doTest(fileName); + } + + @TestMetadata("noInline.kt") + public void testNoInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInline.kt"); + doTest(fileName); + } + + @TestMetadata("noInlineLambdaChain.kt") + public void testNoInlineLambdaChain() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInlineLambdaChain.kt"); + doTest(fileName); + } + + @TestMetadata("noInlineLambdaChainWithCapturedInline.kt") + public void testNoInlineLambdaChainWithCapturedInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/noInlineLambdaChainWithCapturedInline.kt"); + doTest(fileName); + } + + @TestMetadata("withoutInline.kt") + public void testWithoutInline() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/noInline/withoutInline.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 4ff74ccaa57..7507305974b 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 @@ -31,6 +31,8 @@ abstract class AbstractNonLocalReturnsTest : BorrowedInlineTest("nonLocalReturns abstract class AbstractPropertyAccessorsInlineTests : BorrowedInlineTest("property/") +abstract class AbstractNoInlineTests : BorrowedInlineTest("noInline/") + abstract class AbstractBoxJsTest() : BasicBoxTest( BasicBoxTest.TEST_DATA_DIR_PATH + "box/", BasicBoxTest.TEST_DATA_DIR_PATH + "out/box/"