diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index a13992510c4..c9658296368 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -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 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()); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt index 4534f320f20..1df918d5dd1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/constants/evaluate/ConstantExpressionEvaluator.kt @@ -166,23 +166,24 @@ class ConstantExpressionEvaluator( trace: BindingTrace ): Pair, 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() - 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, KotlinType>(result, elementType) + return Pair, 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 } diff --git a/compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt b/compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt new file mode 100644 index 00000000000..1bf88131f44 --- /dev/null +++ b/compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt @@ -0,0 +1,8 @@ +annotation class Anno(val x: Array = emptyArray()) + +@Anno fun test1() = 1 +@Anno(arrayOf("K")) fun test2() = 2 + +fun box(): String { + return if (test1() + test2() == 3) "OK" else "Fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/light-analysis/defaultArguments/constructor/annotationWithEmptyArray.txt b/compiler/testData/codegen/light-analysis/defaultArguments/constructor/annotationWithEmptyArray.txt new file mode 100644 index 00000000000..332cb8b8a74 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/defaultArguments/constructor/annotationWithEmptyArray.txt @@ -0,0 +1,12 @@ +@java.lang.annotation.Retention +@kotlin.Metadata +public annotation class Anno { + public abstract method x(): java.lang.String[] +} + +@kotlin.Metadata +public final class AnnotationWithEmptyArrayKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static @Anno method test1(): int + public final static @Anno method test2(): int +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.kt index 2f45c70358e..5b2937fffe5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.kt @@ -19,6 +19,7 @@ val i2 = foo() fun foo(): Int = 1 +@AnnSA(emptyArray()) class MyClass { val i = 1 } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.txt index d90b2254f2f..b7234304a5f 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameterMustBeConstant/simple.txt @@ -37,7 +37,7 @@ public final annotation class AnnSA : kotlin.Annotation { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -public final class MyClass { +@AnnSA(sa = {}) public final class MyClass { public constructor MyClass() public final val i: kotlin.Int = 1 public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ee54da9d8ab..3afc3c4ba99 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5845,6 +5845,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("annotationWithEmptyArray.kt") + public void testAnnotationWithEmptyArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt"); + doTest(fileName); + } + @TestMetadata("checkIfConstructorIsSynthetic.kt") public void testCheckIfConstructorIsSynthetic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 7f60a76c2eb..f7236a660de 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5845,6 +5845,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("annotationWithEmptyArray.kt") + public void testAnnotationWithEmptyArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt"); + doTest(fileName); + } + @TestMetadata("checkIfConstructorIsSynthetic.kt") public void testCheckIfConstructorIsSynthetic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index 764465f045d..9fc1c92a6a6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 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. @@ -500,7 +500,7 @@ class CodeInliner( val argumentExpression = argument.getArgumentExpression() ?: return@forEachDescendantOfType val resolvedCall = argumentExpression.getResolvedCall(argumentExpression.analyze(BodyResolveMode.PARTIAL)) ?: return@forEachDescendantOfType val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return@forEachDescendantOfType - if (CompileTimeConstantUtils.isArrayMethodCall(resolvedCall)) { + if (CompileTimeConstantUtils.isArrayFunctionCall(resolvedCall)) { argumentsToExpand.add(argument to callExpression.valueArguments) } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 86bace69f07..960869c1279 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -6614,6 +6614,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("annotationWithEmptyArray.kt") + public void testAnnotationWithEmptyArray() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/annotationWithEmptyArray.kt"); + doTest(fileName); + } + @TestMetadata("checkIfConstructorIsSynthetic.kt") public void testCheckIfConstructorIsSynthetic() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/defaultArguments/constructor/checkIfConstructorIsSynthetic.kt");