From 2ae1a2c81bd1bf1e857d7650134033d775217cdc Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Mon, 30 Sep 2013 20:09:09 +0400 Subject: [PATCH] Added copyToArray intrinsic method. #KT-3352 fixed --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../jet/codegen/intrinsics/CopyToArray.java | 36 +++++++++++++++++++ .../codegen/intrinsics/IntrinsicMethods.java | 4 ++- .../boxWithStdlib/toArray/copyToArray.kt | 11 ++++++ .../toArray/kt3177-copyToArray.kt | 15 ++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 21 ++++++++++- js/js.libraries/src/core/kotlin.kt | 2 ++ .../testFiles/java/arrayList/cases/misc.kt | 2 +- .../testFiles/java/arrayList/cases/toArray.kt | 2 +- js/js.translator/testFiles/kotlin_lib.js | 10 ++++++ libraries/stdlib/src/kotlin/ArraysJVM.kt | 5 ++- .../stdlib/test/js/javautilCollectionsTest.kt | 5 +++ .../kotlin/gradle/plugin/KotlinPlugin.kt | 2 +- 13 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CopyToArray.java create mode 100644 compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 92dd75e06a8..97975cc7290 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2018,7 +2018,7 @@ public class ExpressionCodegen extends JetVisitor implem for (ValueArgument argument : call.getValueArguments()) { args.add(argument.getArgumentExpression()); } - JetType type = resolvedCall.getCandidateDescriptor().getReturnType(); + JetType type = resolvedCall.getResultingDescriptor().getReturnType(); assert type != null; Type callType = typeMapper.mapType(type); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CopyToArray.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CopyToArray.java new file mode 100644 index 00000000000..fb528c70794 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/CopyToArray.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.codegen.state.GenerationState; +import org.jetbrains.jet.lang.psi.JetExpression; + +import java.util.List; + +public class CopyToArray implements IntrinsicMethod { + @Override + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + @Nullable PsiElement element, + @Nullable List arguments, + @Nullable StackValue receiver, + @NotNull GenerationState state + ) { + assert receiver != null; + receiver.put(receiver.type, v); + v.dup(); + v.invokeinterface("java/util/Collection", "size", "()I"); + + v.newarray(expectedType.getElementType()); + v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;"); + + return StackValue.onStack(expectedType); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 69b4a44be93..01e596881d8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -58,8 +58,9 @@ public class IntrinsicMethods { private static final ArrayGet ARRAY_GET = new ArrayGet(); private static final StringPlus STRING_PLUS = new StringPlus(); public static final String KOTLIN_JAVA_CLASS_FUNCTION = "kotlin.javaClass.function"; - public static final String KOTLIN_ARRAYS_ARRAY = "kotlin.arrays.array"; private static final String KOTLIN_JAVA_CLASS_PROPERTY = "kotlin.javaClass.property"; + public static final String KOTLIN_ARRAYS_ARRAY = "kotlin.arrays.array"; + public static final String KOTLIN_COPY_TO_ARRAY = "kotlin.collections.copyToArray"; private static final String KOTLIN_TO_STRING = "kotlin.toString"; private static final String KOTLIN_HASH_CODE = "kotlin.hashCode"; private static final EnumValues ENUM_VALUES = new EnumValues(); @@ -76,6 +77,7 @@ public class IntrinsicMethods { namedMethods.put(KOTLIN_JAVA_CLASS_FUNCTION, new JavaClassFunction()); namedMethods.put(KOTLIN_JAVA_CLASS_PROPERTY, new JavaClassProperty()); namedMethods.put(KOTLIN_ARRAYS_ARRAY, new JavaClassArray()); + namedMethods.put(KOTLIN_COPY_TO_ARRAY, new CopyToArray()); namedMethods.put(KOTLIN_HASH_CODE, HASH_CODE); namedMethods.put(KOTLIN_TO_STRING, TO_STRING); diff --git a/compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt b/compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt new file mode 100644 index 00000000000..7b9c8724125 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt @@ -0,0 +1,11 @@ +import java.util.Arrays + +fun box(): String { + val array = Arrays.asList(2, 3, 9).copyToArray() + if (array !is Array) return array.javaClass.toString() + + val str = Arrays.toString(array) + if (str != "[2, 3, 9]") return str + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt b/compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt new file mode 100644 index 00000000000..0b7ee4c99d3 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt @@ -0,0 +1,15 @@ +import java.util.ArrayList +import java.util.Arrays + +fun box(): String { + val list = ArrayList>() + list.add(Pair("Sample", "http://cyber.law.harvard.edu/rss/examples/rss2sample.xml")) + list.add(Pair("Scripting", "http://static.scripting.com/rss.xml")) + + val keys = list.map { it.first }.copyToArray() + + val keysToString = Arrays.toString(keys) + if (keysToString != "[Sample, Scripting]") return keysToString + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 1242eb4b177..d86abac4d31 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class}) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true); @@ -940,6 +940,24 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/toArray") + public static class ToArray extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInToArray() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/toArray"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("copyToArray.kt") + public void testCopyToArray() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/toArray/copyToArray.kt"); + } + + @TestMetadata("kt3177-copyToArray.kt") + public void testKt3177_copyToArray() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/toArray/kt3177-copyToArray.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated"); suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class); @@ -952,6 +970,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode suite.addTest(Ranges.innerSuite()); suite.addTestSuite(Regressions.class); suite.addTestSuite(Strings.class); + suite.addTestSuite(ToArray.class); return suite; } } diff --git a/js/js.libraries/src/core/kotlin.kt b/js/js.libraries/src/core/kotlin.kt index ab661372076..ee186ee6f2c 100644 --- a/js/js.libraries/src/core/kotlin.kt +++ b/js/js.libraries/src/core/kotlin.kt @@ -24,3 +24,5 @@ public fun byteArray(vararg content : Byte): ByteArray = js.noImpl public fun booleanArray(vararg content : Boolean): BooleanArray = js.noImpl +library("copyToArray") +public fun Collection.copyToArray(): Array = js.noImpl diff --git a/js/js.translator/testFiles/java/arrayList/cases/misc.kt b/js/js.translator/testFiles/java/arrayList/cases/misc.kt index 7cf1fff3661..0d694323b8a 100644 --- a/js/js.translator/testFiles/java/arrayList/cases/misc.kt +++ b/js/js.translator/testFiles/java/arrayList/cases/misc.kt @@ -47,7 +47,7 @@ fun box(): Boolean { a.clear() assertThat(a.isEmpty(), true) - val array = list.toArray(Array(0, {it})) + val array = list.copyToArray() assertThat(array[0], 1) assertThat(array[1], 500) diff --git a/js/js.translator/testFiles/java/arrayList/cases/toArray.kt b/js/js.translator/testFiles/java/arrayList/cases/toArray.kt index 6c5cdd93d45..cae96339b97 100644 --- a/js/js.translator/testFiles/java/arrayList/cases/toArray.kt +++ b/js/js.translator/testFiles/java/arrayList/cases/toArray.kt @@ -12,6 +12,6 @@ fun box(): Boolean { // test addAt list.add(1, 500) - val array = list.toArray() + val array = list.copyToArray() return array[0] == 1 && array[1] == 500 && array[2] == 2 && array[3] == 3 && JSON.stringify(list) == "[1,500,2,3]"; } \ No newline at end of file diff --git a/js/js.translator/testFiles/kotlin_lib.js b/js/js.translator/testFiles/kotlin_lib.js index 071d3bf32d5..06f39c502d0 100644 --- a/js/js.translator/testFiles/kotlin_lib.js +++ b/js/js.translator/testFiles/kotlin_lib.js @@ -492,6 +492,16 @@ String.prototype.contains = function (s) { } }; + Kotlin.copyToArray = function (collection) { + var array = []; + var it = collection.iterator(); + while (it.hasNext()) { + array.push(it.next()); + } + + return array; + }; + Kotlin.StringBuilder = Kotlin.createClass(null, function () { diff --git a/libraries/stdlib/src/kotlin/ArraysJVM.kt b/libraries/stdlib/src/kotlin/ArraysJVM.kt index 753e64e5995..7f007fba326 100644 --- a/libraries/stdlib/src/kotlin/ArraysJVM.kt +++ b/libraries/stdlib/src/kotlin/ArraysJVM.kt @@ -107,4 +107,7 @@ public inline fun ByteArray.inputStream(offset: Int, length: Int) : ByteArrayInp public inline fun ByteArray.toString(encoding: String): String = String(this, encoding) public inline fun ByteArray.toString(): String = String(this) -public inline fun ByteArray.toString(encoding: Charset) : String = String(this, encoding) \ No newline at end of file +public inline fun ByteArray.toString(encoding: Charset) : String = String(this, encoding) + +[Intrinsic("kotlin.collections.copyToArray")] public fun Collection.copyToArray(): Array = + throw UnsupportedOperationException() diff --git a/libraries/stdlib/test/js/javautilCollectionsTest.kt b/libraries/stdlib/test/js/javautilCollectionsTest.kt index 9908fcf2675..7f0b8addb22 100644 --- a/libraries/stdlib/test/js/javautilCollectionsTest.kt +++ b/libraries/stdlib/test/js/javautilCollectionsTest.kt @@ -29,4 +29,9 @@ class JavautilCollectionsTest { Collections.sort(list, COMPARATOR) assertEquals(SORTED_TEST_LIST, list) } + + test fun collectionToArray() { + val array = TEST_LIST.copyToArray() + assertEquals(array.toList(), TEST_LIST) + } } diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 0d70a75e5c5..e083583120d 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -279,7 +279,7 @@ open class GradleUtils() { val configurationsContainer : ConfigurationContainer = project.getBuildscript().getConfigurations() val deps = coordinates.map { dependencyHandler.create(it) } - val configuration = configurationsContainer.detachedConfiguration(*deps.toArray(array())) + val configuration = configurationsContainer.detachedConfiguration(*deps.copyToArray()) return configuration.getResolvedConfiguration().getFiles(KSpec({ dep -> true }))!! }