Allow to use emptyArray in annotation as argument

#KT-14236 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-02-06 20:17:03 +03:00
parent 9f0403f72c
commit d7093db5c5
10 changed files with 62 additions and 20 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 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.
@@ -56,7 +56,8 @@ public class CompileTimeConstantUtils {
"kotlin.charArrayOf",
"kotlin.shortArrayOf",
"kotlin.byteArrayOf",
"kotlin.booleanArrayOf"
"kotlin.booleanArrayOf",
"kotlin.emptyArray"
);
public static void checkConstructorParametersType(@NotNull List<KtParameter> parameters, @NotNull BindingTrace trace) {
@@ -110,7 +111,7 @@ public class CompileTimeConstantUtils {
return false;
}
public static boolean isArrayMethodCall(@NotNull ResolvedCall<?> resolvedCall) {
public static boolean isArrayFunctionCall(@NotNull ResolvedCall<?> resolvedCall) {
return ARRAY_CALL_NAMES.contains(DescriptorUtils.getFqName(resolvedCall.getCandidateDescriptor()).asString());
}
@@ -166,23 +166,24 @@ class ConstantExpressionEvaluator(
trace: BindingTrace
): Pair<List<KtExpression>, KotlinType?>? {
val resolvedCall = expression.getResolvedCall(trace.bindingContext)
if (resolvedCall == null || !CompileTimeConstantUtils.isArrayMethodCall(resolvedCall)) {
if (resolvedCall == null || !CompileTimeConstantUtils.isArrayFunctionCall(resolvedCall)) {
return null
}
val argumentEntry = resolvedCall.valueArguments.entries.single()
val elementType = argumentEntry.key.varargElementType ?: return null
val returnType = resolvedCall.resultingDescriptor.returnType ?: return null
val componentType = builtIns.getArrayElementType(returnType)
val result = arrayListOf<KtExpression>()
for (valueArgument in argumentEntry.value.arguments) {
val valueArgumentExpression = valueArgument.getArgumentExpression()
if (valueArgumentExpression != null) {
result.add(valueArgumentExpression)
for ((_, resolvedValueArgument) in resolvedCall.valueArguments) {
for (valueArgument in resolvedValueArgument.arguments) {
val valueArgumentExpression = valueArgument.getArgumentExpression()
if (valueArgumentExpression != null) {
result.add(valueArgumentExpression)
}
}
}
return Pair<List<KtExpression>, KotlinType>(result, elementType)
return Pair<List<KtExpression>, KotlinType>(result, componentType)
}
private fun hasSpread(argument: ResolvedValueArgument): Boolean {
@@ -646,13 +647,14 @@ private class ConstantExpressionEvaluatorVisitor(
val resultingDescriptor = call.resultingDescriptor
// arrayOf()
if (CompileTimeConstantUtils.isArrayMethodCall(call)) {
val varargType = resultingDescriptor.valueParameters.first().varargElementType!!
// arrayOf() or emptyArray()
if (CompileTimeConstantUtils.isArrayFunctionCall(call)) {
val returnType = resultingDescriptor.returnType ?: return null
val componentType = constantExpressionEvaluator.builtIns.getArrayElementType(returnType)
val arguments = call.valueArguments.values.flatMap { resolveArguments(it.arguments, varargType) }
val arguments = call.valueArguments.values.flatMap { resolveArguments(it.arguments, componentType) }
return factory.createArrayValue(arguments.map { it.toConstantValue(varargType) }, resultingDescriptor.returnType!!).
return factory.createArrayValue(arguments.map { it.toConstantValue(componentType) }, resultingDescriptor.returnType!!).
wrap(
usesVariableAsConstant = arguments.any { it.usesVariableAsConstant },
usesNonConstValAsConstant = arguments.any { it.usesNonConstValAsConstant }