diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/ArrayFqNames.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/ArrayFqNames.kt index f5387e1dbbe..b7bdc1f24df 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/ArrayFqNames.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/resolve/ArrayFqNames.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.builtins.PrimitiveType +import org.jetbrains.kotlin.builtins.StandardNames.FqNames +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name object ArrayFqNames { @@ -20,5 +22,20 @@ object ArrayFqNames { PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf") ) - val ARRAY_OF_FUNCTION = Name.identifier("arrayOf") -} \ No newline at end of file + val UNSIGNED_TYPE_TO_ARRAY: Map = hashMapOf( + FqNames.uByteFqName to Name.identifier("ubyteArrayOf"), + FqNames.uShortFqName to Name.identifier("ushortArrayOf"), + FqNames.uIntFqName to Name.identifier("uintArrayOf"), + FqNames.uLongFqName to Name.identifier("ulongArrayOf") + ) + + val ARRAY_OF_FUNCTION: Name = Name.identifier("arrayOf") + + val EMPTY_ARRAY: Name = Name.identifier("emptyArray") + + val ARRAY_CALL_NAMES: Set = + setOf(ARRAY_OF_FUNCTION, EMPTY_ARRAY) + PRIMITIVE_TYPE_TO_ARRAY.values.toSet() + UNSIGNED_TYPE_TO_ARRAY.values.toSet() + + @JvmField + val ARRAY_CALL_FQ_NAMES: Set = ARRAY_CALL_NAMES.map { FqName("kotlin." + it.identifier) }.toSet() +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index 0906933f0e0..a11d42fd289 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -16,13 +16,13 @@ package org.jetbrains.kotlin.resolve; -import kotlin.collections.SetsKt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.UnsignedTypes; import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.VariableDescriptor; +import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.psi.KtExpression; import org.jetbrains.kotlin.psi.KtParameter; import org.jetbrains.kotlin.psi.KtPsiUtil; @@ -39,33 +39,16 @@ import org.jetbrains.kotlin.types.TypeProjection; import org.jetbrains.kotlin.types.TypeUtils; import java.util.List; -import java.util.Set; import static org.jetbrains.kotlin.diagnostics.Errors.INVALID_TYPE_OF_ANNOTATION_MEMBER; import static org.jetbrains.kotlin.diagnostics.Errors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER; +import static org.jetbrains.kotlin.resolve.ArrayFqNames.ARRAY_CALL_FQ_NAMES; import static org.jetbrains.kotlin.resolve.BindingContext.VALUE_PARAMETER; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isAnnotationClass; import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass; public class CompileTimeConstantUtils { - private final static Set ARRAY_CALL_NAMES = SetsKt.hashSetOf( - "kotlin.arrayOf", - "kotlin.doubleArrayOf", - "kotlin.floatArrayOf", - "kotlin.longArrayOf", - "kotlin.intArrayOf", - "kotlin.charArrayOf", - "kotlin.shortArrayOf", - "kotlin.byteArrayOf", - "kotlin.booleanArrayOf", - "kotlin.emptyArray", - "kotlin.ubyteArrayOf", - "kotlin.ushortArrayOf", - "kotlin.uintArrayOf", - "kotlin.ulongArrayOf" - ); - public static void checkConstructorParametersType(@NotNull List parameters, @NotNull BindingTrace trace) { for (KtParameter parameter : parameters) { VariableDescriptor parameterDescriptor = trace.getBindingContext().get(VALUE_PARAMETER, parameter); @@ -121,7 +104,10 @@ public class CompileTimeConstantUtils { } public static boolean isArrayFunctionCall(@NotNull ResolvedCall resolvedCall) { - return ARRAY_CALL_NAMES.contains(DescriptorUtils.getFqName(resolvedCall.getCandidateDescriptor()).asString()); + FqNameUnsafe unsafe = DescriptorUtils.getFqName(resolvedCall.getCandidateDescriptor()); + // If the fully qualified name is unsafe, i.e., contains < or >, it shouldn't be any of `arrayOf` calls. + if (!unsafe.isSafe()) return false; + return ARRAY_CALL_FQ_NAMES.contains(unsafe.toSafe()); } public static boolean canBeReducedToBooleanConstant( diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/scriptAnnotationsPreprocessing.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/scriptAnnotationsPreprocessing.kt index 4d973e75eea..46d78e9972d 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/scriptAnnotationsPreprocessing.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/scriptAnnotationsPreprocessing.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTraceContext import org.jetbrains.kotlin.resolve.ArrayFqNames.ARRAY_OF_FUNCTION +import org.jetbrains.kotlin.resolve.ArrayFqNames.EMPTY_ARRAY import org.jetbrains.kotlin.resolve.ArrayFqNames.PRIMITIVE_TYPE_TO_ARRAY import org.jetbrains.kotlin.resolve.constants.ArrayValue import org.jetbrains.kotlin.resolve.constants.ConstantValue @@ -29,7 +30,7 @@ import kotlin.reflect.KClass import kotlin.reflect.KParameter import kotlin.reflect.full.primaryConstructor -private val ARRAY_OF_METHODS = setOf(ARRAY_OF_FUNCTION) + PRIMITIVE_TYPE_TO_ARRAY.values.toSet() + Name.identifier("emptyArray") +private val ARRAY_OF_METHODS = setOf(ARRAY_OF_FUNCTION, EMPTY_ARRAY) + PRIMITIVE_TYPE_TO_ARRAY.values.toSet() // basic text comparison of function name, todo: better handling? private val KtCallExpression.isArrayCall: Boolean get() = Name.identifier(calleeExpression!!.text) in ARRAY_OF_METHODS