diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 46c0f426584..a78bdd78c7d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3439,6 +3439,20 @@ public class ExpressionCodegen extends KtVisitor impleme public CallableDescriptor getResultingDescriptor() { return descriptor; } + + @NotNull + @Override + public Map getTypeArguments() { + Map originalArgs = super.getTypeArguments(); + if (originalArgs.isEmpty()) return originalArgs; + + assert originalArgs.size() == 1 : "Unknown constructor called: " + originalArgs.size() + " type arguments"; + + return Collections.singletonMap( + CollectionsKt.single(descriptor.getTypeParameters()), + CollectionsKt.single(originalArgs.values()) + ); + } }; return invokeFunction(fakeResolvedCall, StackValue.singleton(intrinsicConstructors, typeMapper)); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java index a977a99a61b..ae0dfb8e457 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/ReifiedTypeParameterSubstitutionChecker.java @@ -18,9 +18,8 @@ package org.jetbrains.kotlin.resolve.calls.checkers; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.CallableDescriptor; -import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; +import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtExpression; @@ -40,24 +39,25 @@ public class ReifiedTypeParameterSubstitutionChecker implements CallChecker { for (Map.Entry entry : typeArguments.entrySet()) { TypeParameterDescriptor parameter = entry.getKey(); KotlinType argument = entry.getValue(); - ClassifierDescriptor argumentDeclarationDescription = argument.getConstructor().getDeclarationDescriptor(); + ClassifierDescriptor argumentDeclarationDescriptor = argument.getConstructor().getDeclarationDescriptor(); - if (parameter.isReified()) { - if (argumentDeclarationDescription instanceof TypeParameterDescriptor && - !((TypeParameterDescriptor) argumentDeclarationDescription).isReified() - ) { - context.trace.report( - Errors.TYPE_PARAMETER_AS_REIFIED.on(getElementToReport(context, parameter.getIndex()), parameter) - ); - } - else if (TypeUtilsKt.cannotBeReified(argument)) { - context.trace.report( - Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument)); - } - else if (TypeUtilsKt.unsafeAsReifiedArgument(argument) && !hasPureReifiableAnnotation(parameter)) { - context.trace.report( - Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument)); - } + if (!parameter.isReified() && !isTypeParameterOfKotlinArray(parameter)) { + continue; + } + + if (argumentDeclarationDescriptor instanceof TypeParameterDescriptor && + !((TypeParameterDescriptor) argumentDeclarationDescriptor).isReified()) { + context.trace.report( + Errors.TYPE_PARAMETER_AS_REIFIED.on(getElementToReport(context, parameter.getIndex()), parameter) + ); + } + else if (TypeUtilsKt.cannotBeReified(argument)) { + context.trace.report( + Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument)); + } + else if (TypeUtilsKt.unsafeAsReifiedArgument(argument) && !hasPureReifiableAnnotation(parameter)) { + context.trace.report( + Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(getElementToReport(context, parameter.getIndex()), argument)); } } } @@ -65,7 +65,13 @@ public class ReifiedTypeParameterSubstitutionChecker implements CallChecker { private static final FqName PURE_REIFIABLE_ANNOTATION_FQ_NAME = new FqName("kotlin.internal.PureReifiable"); private static boolean hasPureReifiableAnnotation(@NotNull TypeParameterDescriptor parameter) { - return parameter.getAnnotations().hasAnnotation(PURE_REIFIABLE_ANNOTATION_FQ_NAME); + return parameter.getAnnotations().hasAnnotation(PURE_REIFIABLE_ANNOTATION_FQ_NAME) || + isTypeParameterOfKotlinArray(parameter); + } + + private static boolean isTypeParameterOfKotlinArray(@NotNull TypeParameterDescriptor parameter) { + DeclarationDescriptor container = parameter.getContainingDeclaration(); + return container instanceof ClassDescriptor && KotlinBuiltIns.isNonPrimitiveArray((ClassDescriptor) container); } @NotNull diff --git a/compiler/testData/builtin-classes-kotlin.txt b/compiler/testData/builtin-classes-kotlin.txt index 36c27ecf1db..8c219a655e9 100644 --- a/compiler/testData/builtin-classes-kotlin.txt +++ b/compiler/testData/builtin-classes-kotlin.txt @@ -1,14 +1,5 @@ package-fragment kotlin -public inline fun Array(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.Array -public inline fun BooleanArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.BooleanArray -public inline fun ByteArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.ByteArray -public inline fun CharArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.CharArray -public inline fun DoubleArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.DoubleArray -public inline fun FloatArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.FloatArray -public inline fun IntArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.IntArray -public inline fun LongArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.LongArray -public inline fun ShortArray(/*0*/ size: kotlin.Int, /*1*/ init: kotlin.Function1): kotlin.ShortArray public inline fun arrayOf(/*0*/ vararg elements: T /*kotlin.Array*/): kotlin.Array public fun arrayOfNulls(/*0*/ size: kotlin.Int): kotlin.Array public fun booleanArrayOf(/*0*/ vararg elements: kotlin.Boolean /*kotlin.BooleanArray*/): kotlin.BooleanArray @@ -31,7 +22,7 @@ public open class Any { } public final class Array : kotlin.Cloneable { - /*primary*/ private constructor Array() + /*primary*/ public constructor Array(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> T) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.Array @@ -51,6 +42,7 @@ public final class Boolean : kotlin.Comparable { public final class BooleanArray : kotlin.Cloneable { /*primary*/ public constructor BooleanArray(/*0*/ size: kotlin.Int) + public constructor BooleanArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Boolean) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.BooleanArray @@ -124,6 +116,7 @@ public final class Byte : kotlin.Number, kotlin.Comparable { public final class ByteArray : kotlin.Cloneable { /*primary*/ public constructor ByteArray(/*0*/ size: kotlin.Int) + public constructor ByteArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Byte) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.ByteArray @@ -168,6 +161,7 @@ public final class Char : kotlin.Comparable { public final class CharArray : kotlin.Cloneable { /*primary*/ public constructor CharArray(/*0*/ size: kotlin.Int) + public constructor CharArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Char) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.CharArray @@ -290,6 +284,7 @@ public final class Double : kotlin.Number, kotlin.Comparable { public final class DoubleArray : kotlin.Cloneable { /*primary*/ public constructor DoubleArray(/*0*/ size: kotlin.Int) + public constructor DoubleArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Double) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.DoubleArray @@ -383,6 +378,7 @@ public final class Float : kotlin.Number, kotlin.Comparable { public final class FloatArray : kotlin.Cloneable { /*primary*/ public constructor FloatArray(/*0*/ size: kotlin.Int) + public constructor FloatArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Float) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.FloatArray @@ -466,6 +462,7 @@ public final class Int : kotlin.Number, kotlin.Comparable { public final class IntArray : kotlin.Cloneable { /*primary*/ public constructor IntArray(/*0*/ size: kotlin.Int) + public constructor IntArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Int) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.IntArray @@ -546,6 +543,7 @@ public final class Long : kotlin.Number, kotlin.Comparable { public final class LongArray : kotlin.Cloneable { /*primary*/ public constructor LongArray(/*0*/ size: kotlin.Int) + public constructor LongArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Long) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.LongArray @@ -642,6 +640,7 @@ public final class Short : kotlin.Number, kotlin.Comparable { public final class ShortArray : kotlin.Cloneable { /*primary*/ public constructor ShortArray(/*0*/ size: kotlin.Int) + public constructor ShortArray(/*0*/ size: kotlin.Int, /*1*/ init: (kotlin.Int) -> kotlin.Short) public final val size: kotlin.Int public final fun (): kotlin.Int public open override /*1*/ fun clone(): kotlin.ShortArray diff --git a/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedArray.kt b/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedArray.kt index 1a2bee24db9..9b20ee1ca1a 100644 --- a/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedArray.kt +++ b/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedArray.kt @@ -1,4 +1,4 @@ -inline fun jaggedArray(x: (Int, Int) -> T): Array> = Array(1) { i -> +inline fun jaggedArray(crossinline x: (Int, Int) -> T): Array> = Array(1) { i -> Array(1) { j -> x(i, j) } } diff --git a/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedDeep.kt b/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedDeep.kt index aa8f36fc23e..1ae45dea39b 100644 --- a/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedDeep.kt +++ b/compiler/testData/codegen/boxWithStdlib/reified/arraysReification/jaggedDeep.kt @@ -1,4 +1,4 @@ -inline fun jaggedArray(x: (Int, Int, Int) -> T): Array>> = Array(1) { i -> +inline fun jaggedArray(crossinline x: (Int, Int, Int) -> T): Array>> = Array(1) { i -> Array(1) { j -> Array(1) { k -> x(i, j, k) } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/kt1558.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/kt1558.kt index 83498b46b76..2db5bd7fee7 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/kt1558.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/kt1558.kt @@ -8,19 +8,19 @@ fun T?.sure() : T = this!! fun List<*>.toArray(ar: Array): Array = ar fun testArrays(ci: List, cii: List?) { - val c1: Array = cii.sure().toArray(Array) + val c1: Array = cii.sure().toArray(Array) - val c2: Array = ci.toArray(Array()) + val c2: Array = ci.toArray(Array()) - val c3 = Array() + val c3 = Array() - val c4 = ci.toArray(Array()) + val c4 = ci.toArray(Array()) - val c5 = ci.toArray(Array()) + val c5 = ci.toArray(Array()) checkSubtype>(c1) checkSubtype>(c2) checkSubtype>(c3) checkSubtype>(c4) checkSubtype>(c5) -} \ No newline at end of file +} diff --git a/core/builtins/native/kotlin/Array.kt b/core/builtins/native/kotlin/Array.kt index 0f8135603b1..b2dfcbdd8c5 100644 --- a/core/builtins/native/kotlin/Array.kt +++ b/core/builtins/native/kotlin/Array.kt @@ -22,8 +22,10 @@ package kotlin * standard library functions. * See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays) * for more information on arrays. + * @constructor Creates a new array with the specified [size], where each element is calculated by calling the specified + * [init] function. The [init] function returns an array element given its index. */ -public class Array private (): Cloneable { +public class Array(size: Int, init: (Int) -> T): Cloneable { /** * Returns the array element at the specified [index]. This method can be called using the * index operator: diff --git a/core/builtins/src/kotlin/ArrayIntrinsics.kt b/core/builtins/src/kotlin/ArrayIntrinsics.kt index f1df2409803..ac09d8f7d4b 100644 --- a/core/builtins/src/kotlin/ArrayIntrinsics.kt +++ b/core/builtins/src/kotlin/ArrayIntrinsics.kt @@ -18,66 +18,52 @@ package kotlin import kotlin.internal.PureReifiable -/** - * Returns an array with the specified [size], where each element is calculated by calling the specified - * [init] function. The `init` function returns an array element given its index. - */ -public inline fun Array(size: Int, init: (Int) -> T): Array { - val result = arrayOfNulls(size) - for (i in 0..size - 1) - result[i] = init(i) - return result as Array -} - /** * Returns an empty array of the specified type [T]. */ public inline fun emptyArray(): Array = arrayOfNulls(0) as Array - -// Array "constructor" /** * Returns an array containing the specified elements. */ -public inline fun arrayOf(vararg elements: T) : Array = elements as Array +public inline fun arrayOf(vararg elements: T): Array = elements as Array -// "constructors" for primitive types array /** * Returns an array containing the specified [Double] numbers. */ -public fun doubleArrayOf(vararg elements: Double) : DoubleArray = elements +public fun doubleArrayOf(vararg elements: Double): DoubleArray = elements /** * Returns an array containing the specified [Float] numbers. */ -public fun floatArrayOf(vararg elements: Float) : FloatArray = elements +public fun floatArrayOf(vararg elements: Float): FloatArray = elements /** * Returns an array containing the specified [Long] numbers. */ -public fun longArrayOf(vararg elements: Long) : LongArray = elements +public fun longArrayOf(vararg elements: Long): LongArray = elements /** * Returns an array containing the specified [Int] numbers. */ -public fun intArrayOf(vararg elements: Int) : IntArray = elements +public fun intArrayOf(vararg elements: Int): IntArray = elements /** * Returns an array containing the specified characters. */ -public fun charArrayOf(vararg elements: Char) : CharArray = elements +public fun charArrayOf(vararg elements: Char): CharArray = elements /** * Returns an array containing the specified [Short] numbers. */ -public fun shortArrayOf(vararg elements: Short) : ShortArray = elements +public fun shortArrayOf(vararg elements: Short): ShortArray = elements /** * Returns an array containing the specified [Byte] numbers. */ -public fun byteArrayOf(vararg elements: Byte) : ByteArray = elements +public fun byteArrayOf(vararg elements: Byte): ByteArray = elements /** * Returns an array containing the specified boolean values. */ -public fun booleanArrayOf(vararg elements: Boolean) : BooleanArray = elements +public fun booleanArrayOf(vararg elements: Boolean): BooleanArray = elements diff --git a/core/runtime.jvm/src/kotlin/jvm/internal/IntrinsicArrayConstructors.kt b/core/runtime.jvm/src/kotlin/jvm/internal/IntrinsicArrayConstructors.kt index 105d068bece..79050d1531b 100644 --- a/core/runtime.jvm/src/kotlin/jvm/internal/IntrinsicArrayConstructors.kt +++ b/core/runtime.jvm/src/kotlin/jvm/internal/IntrinsicArrayConstructors.kt @@ -18,6 +18,14 @@ package kotlin.jvm.internal @Suppress("unused") object IntrinsicArrayConstructors { + private inline fun Array(size: Int, init: (Int) -> T): Array { + val result = arrayOfNulls(size) + for (i in 0..size - 1) { + result[i] = init(i) + } + return result as Array + } + private inline fun DoubleArray(size: Int, init: (Int) -> Double): DoubleArray { val result = DoubleArray(size) for (i in 0..size - 1) { diff --git a/idea/testData/decompiler/builtIns/kotlin_package.stubs b/idea/testData/decompiler/builtIns/kotlin_package.stubs index 6f05dd3f3f5..3fe1b009d4f 100644 --- a/idea/testData/decompiler/builtIns/kotlin_package.stubs +++ b/idea/testData/decompiler/builtIns/kotlin_package.stubs @@ -2,282 +2,6 @@ PsiJetFileStubImpl[package=kotlin] PACKAGE_DIRECTIVE: REFERENCE_EXPRESSION:[referencedName=kotlin] IMPORT_LIST: - FUN:[fqName=kotlin.Array, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=false, isTopLevel=true, name=Array] - MODIFIER_LIST:[public inline] - TYPE_PARAMETER_LIST: - TYPE_PARAMETER:[fqName=null, isInVariance=false, isOutVariance=false, name=T] - MODIFIER_LIST:[reified] - ANNOTATION_ENTRY:[hasValueArguments=false, shortName=PureReifiable] - CONSTRUCTOR_CALLEE: - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=internal] - REFERENCE_EXPRESSION:[referencedName=PureReifiable] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=T] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Array] - TYPE_ARGUMENT_LIST: - TYPE_PROJECTION:[projectionKind=NONE] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=T] - FUN:[fqName=kotlin.BooleanArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=BooleanArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Boolean] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=BooleanArray] - FUN:[fqName=kotlin.ByteArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=ByteArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Byte] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=ByteArray] - FUN:[fqName=kotlin.CharArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=CharArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Char] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=CharArray] - FUN:[fqName=kotlin.DoubleArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=DoubleArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Double] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=DoubleArray] - FUN:[fqName=kotlin.FloatArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=FloatArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Float] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=FloatArray] - FUN:[fqName=kotlin.IntArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=IntArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=IntArray] - FUN:[fqName=kotlin.LongArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=LongArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Long] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=LongArray] - FUN:[fqName=kotlin.ShortArray, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=ShortArray] - MODIFIER_LIST:[public inline] - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=size] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=init] - TYPE_REFERENCE: - FUNCTION_TYPE: - VALUE_PARAMETER_LIST: - VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=null] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Int] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=Short] - TYPE_REFERENCE: - USER_TYPE:[isAbsoluteInRootPackage=false] - USER_TYPE:[isAbsoluteInRootPackage=false] - REFERENCE_EXPRESSION:[referencedName=kotlin] - REFERENCE_EXPRESSION:[referencedName=ShortArray] FUN:[fqName=kotlin.arrayOf, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=true, isExtension=false, isTopLevel=true, name=arrayOf] MODIFIER_LIST:[public inline] TYPE_PARAMETER_LIST: diff --git a/idea/testData/decompiler/builtIns/kotlin_package.text b/idea/testData/decompiler/builtIns/kotlin_package.text index d5172790b88..37404764e8c 100644 --- a/idea/testData/decompiler/builtIns/kotlin_package.text +++ b/idea/testData/decompiler/builtIns/kotlin_package.text @@ -3,24 +3,6 @@ package kotlin -public inline fun Array(size: kotlin.Int, init: (kotlin.Int) -> T): kotlin.Array { /* compiled code */ } - -public inline fun BooleanArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Boolean): kotlin.BooleanArray { /* compiled code */ } - -public inline fun ByteArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Byte): kotlin.ByteArray { /* compiled code */ } - -public inline fun CharArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Char): kotlin.CharArray { /* compiled code */ } - -public inline fun DoubleArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Double): kotlin.DoubleArray { /* compiled code */ } - -public inline fun FloatArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Float): kotlin.FloatArray { /* compiled code */ } - -public inline fun IntArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Int): kotlin.IntArray { /* compiled code */ } - -public inline fun LongArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Long): kotlin.LongArray { /* compiled code */ } - -public inline fun ShortArray(size: kotlin.Int, init: (kotlin.Int) -> kotlin.Short): kotlin.ShortArray { /* compiled code */ } - public inline fun arrayOf(vararg elements: T): kotlin.Array { /* compiled code */ } public fun arrayOfNulls(size: kotlin.Int): kotlin.Array { /* compiled code */ } @@ -46,3 +28,4 @@ public fun shortArrayOf(vararg elements: kotlin.Short): kotlin.ShortArray { /* c public operator fun kotlin.String?.plus(other: kotlin.Any?): kotlin.String { /* compiled code */ } public fun kotlin.Any?.toString(): kotlin.String { /* compiled code */ } + diff --git a/js/js.libraries/src/core/kotlin.kt b/js/js.libraries/src/core/kotlin.kt index 8118a5d2a3c..96e0c8eded2 100644 --- a/js/js.libraries/src/core/kotlin.kt +++ b/js/js.libraries/src/core/kotlin.kt @@ -2,18 +2,6 @@ package kotlin import java.util.* -// TODO: @library("arrayFromFun") -/** - * Returns an array with the specified [size], where each element is calculated by calling the specified - * [init] function. The `init` function returns an array element given its index. - */ -public inline fun Array(size: Int, init: (Int) -> T): Array { - val result = arrayOfNulls(size) - for (i in 0..size - 1) - result[i] = init(i) - return result as Array -} - /** * Returns an empty array of the specified type [T]. */ diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/StandardClassesTest.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/StandardClassesTest.java index 4dd47475015..dc549476250 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/StandardClassesTest.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/StandardClassesTest.java @@ -28,26 +28,26 @@ public final class StandardClassesTest extends SingleFileTranslationTest { fooBoxTest(); } - public void testArrayAccess() throws Exception { fooBoxTest(); } - public void testArrayIsFilledWithNulls() throws Exception { fooBoxTest(); } - public void testArrayFunctionConstructor() throws Exception { fooBoxTest(); } - public void testArraySize() throws Exception { fooBoxTest(); } + public void testArrayConstructorsWithLambda() throws Exception { + checkFooBoxIsOk(); + } + //TODO: this feature in not supported for some time //TODO: support it. Probably configurable. // (expected = JavaScriptException.class) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java index b0815f9547d..5442d25f8c8 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/intrinsic/functions/factories/ArrayFIF.java @@ -21,14 +21,16 @@ import com.google.dart.compiler.backend.js.ast.JsArrayAccess; import com.google.dart.compiler.backend.js.ast.JsExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.PrimitiveType; +import org.jetbrains.kotlin.js.patterns.DescriptorPredicate; +import org.jetbrains.kotlin.js.patterns.NamePredicate; import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic; -import org.jetbrains.kotlin.js.patterns.DescriptorPredicate; -import org.jetbrains.kotlin.js.patterns.NamePredicate; import org.jetbrains.kotlin.name.Name; +import java.util.Arrays; import java.util.List; import static com.intellij.openapi.util.text.StringUtil.decapitalize; @@ -40,6 +42,7 @@ public final class ArrayFIF extends CompositeFIF { private static final NamePredicate CHAR_ARRAY; private static final NamePredicate BOOLEAN_ARRAY; private static final NamePredicate LONG_ARRAY; + private static final NamePredicate ARRAY; private static final NamePredicate ARRAYS; private static final DescriptorPredicate ARRAY_FACTORY_METHODS; @@ -54,7 +57,7 @@ public final class ArrayFIF extends CompositeFIF { arrayFactoryMethodNames.add(Name.identifier(decapitalize(arrayTypeName.asString() + "Of"))); } - Name arrayName = Name.identifier("Array"); + Name arrayName = KotlinBuiltIns.FQ_NAMES.array.shortName(); Name booleanArrayName = PrimitiveType.BOOLEAN.getArrayTypeName(); Name charArrayName = PrimitiveType.CHAR.getArrayTypeName(); Name longArrayName = PrimitiveType.LONG.getArrayTypeName(); @@ -63,6 +66,7 @@ public final class ArrayFIF extends CompositeFIF { CHAR_ARRAY = new NamePredicate(charArrayName); BOOLEAN_ARRAY = new NamePredicate(booleanArrayName); LONG_ARRAY = new NamePredicate(longArrayName); + ARRAY = new NamePredicate(arrayName); arrayTypeNames.add(charArrayName); arrayTypeNames.add(booleanArrayName); @@ -123,10 +127,14 @@ public final class ArrayFIF extends CompositeFIF { add(pattern(ARRAYS, "set"), SET_INTRINSIC); add(pattern(ARRAYS, ""), LENGTH_PROPERTY_INTRINSIC); add(pattern(ARRAYS, "iterator"), new KotlinFunctionIntrinsic("arrayIterator")); - add(pattern(NUMBER_ARRAY, ""),new KotlinFunctionIntrinsic("numberArrayOfSize")); - add(pattern(CHAR_ARRAY, ""), new KotlinFunctionIntrinsic("charArrayOfSize")); - add(pattern(BOOLEAN_ARRAY, ""), new KotlinFunctionIntrinsic("booleanArrayOfSize")); - add(pattern(LONG_ARRAY, ""), new KotlinFunctionIntrinsic("longArrayOfSize")); + + add(pattern(NUMBER_ARRAY, "(Int)"), new KotlinFunctionIntrinsic("numberArrayOfSize")); + add(pattern(CHAR_ARRAY, "(Int)"), new KotlinFunctionIntrinsic("charArrayOfSize")); + add(pattern(BOOLEAN_ARRAY, "(Int)"), new KotlinFunctionIntrinsic("booleanArrayOfSize")); + add(pattern(LONG_ARRAY, "(Int)"), new KotlinFunctionIntrinsic("longArrayOfSize")); + + add(pattern(ARRAYS, "(Int,Function1)"), new KotlinFunctionIntrinsic("arrayFromFun")); + add(ARRAY_FACTORY_METHODS, ARRAY_INTRINSIC); } } diff --git a/js/js.translator/testData/standardClasses/cases/arrayConstructorsWithLambda.kt b/js/js.translator/testData/standardClasses/cases/arrayConstructorsWithLambda.kt new file mode 100644 index 00000000000..4d12441d279 --- /dev/null +++ b/js/js.translator/testData/standardClasses/cases/arrayConstructorsWithLambda.kt @@ -0,0 +1,25 @@ +package foo + +fun box(): String { + val s = Array(3) { it.toString() } + if (s.size != 3) return "Fail Array size: ${s.size}" + if (s[1] != "1") return "Fail Array value: ${s[1]}" + + val i = IntArray(3) { it } + if (i.size != 3) return "Fail IntArray size: ${i.size}" + if (i[1] != 1) return "Fail IntArray value: ${i[1]}" + + val c = CharArray(3) { it.toChar() } + if (c.size != 3) return "Fail CharArray size: ${c.size}" + if (c[1] != 1.toChar()) return "Fail CharArray value: ${c[1]}" + + val b = BooleanArray(3) { true } + if (b.size != 3) return "Fail BooleanArray size: ${b.size}" + if (b[1] != true) return "Fail BooleanArray value: ${b[1]}" + + val l = LongArray(3) { it.toLong() } + if (l.size != 3) return "Fail LongArray size: ${l.size}" + if (l[1] != 1L) return "Fail LongArray value: ${l[1]}" + + return "OK" +}