From e2def0c60edb12bd1b0780ef93c4d4f1b009a8ac Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 5 Dec 2017 17:11:09 +0100 Subject: [PATCH] Do not report "invalid type of annotation member" on error types In case the referred type is actually an enum that is not found in dependencies due to a configuration problem, this usage could be valid. So we can avoid reporting an error here, to reduce the number of diagnostics. Also do not report "default value of annotation parameter must be a compile-time constant" in the same case for the same reason --- .../kotlin/resolve/CompileTimeConstantUtils.java | 10 ++++++---- .../types/expressions/ValueParameterResolver.kt | 15 ++++++++------- .../invalidTypesInAnnotationConstructor.kt | 4 ++++ .../invalidTypesInAnnotationConstructor.txt | 8 ++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java index c9658296368..fb48eaa8037 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompileTimeConstantUtils.java @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.KotlinTypeKt; import org.jetbrains.kotlin.types.TypeProjection; import org.jetbrains.kotlin.types.TypeUtils; @@ -78,10 +79,10 @@ public class CompileTimeConstantUtils { } private static boolean isAcceptableTypeForAnnotationParameter(@NotNull KotlinType parameterType) { + if (KotlinTypeKt.isError(parameterType)) return true; + ClassDescriptor typeDescriptor = TypeUtils.getClassDescriptor(parameterType); - if (typeDescriptor == null) { - return false; - } + if (typeDescriptor == null) return false; if (isEnumClass(typeDescriptor) || isAnnotationClass(typeDescriptor) || @@ -89,7 +90,7 @@ public class CompileTimeConstantUtils { KotlinBuiltIns.isPrimitiveArray(parameterType) || KotlinBuiltIns.isPrimitiveType(parameterType) || KotlinBuiltIns.isString(parameterType)) { - return true; + return true; } if (KotlinBuiltIns.isArray(parameterType)) { @@ -108,6 +109,7 @@ public class CompileTimeConstantUtils { } } } + return false; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt index 1e6f91e930b..15dca7c8981 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ValueParameterResolver.kt @@ -30,13 +30,13 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.isError class ValueParameterResolver( private val expressionTypingServices: ExpressionTypingServices, private val constantExpressionEvaluator: ConstantExpressionEvaluator, private val languageVersionSettings: LanguageVersionSettings ) { - fun resolveValueParameters( valueParameters: List, valueParameterDescriptors: List, @@ -60,17 +60,18 @@ class ValueParameterResolver( private fun resolveDefaultValue( valueParameterDescriptor: ValueParameterDescriptor, - jetParameter: KtParameter, + parameter: KtParameter, context: ExpressionTypingContext ) { if (!valueParameterDescriptor.declaresDefaultValue()) return - val defaultValue = jetParameter.defaultValue ?: return - expressionTypingServices.getTypeInfo(defaultValue, context.replaceExpectedType(valueParameterDescriptor.type)) + val defaultValue = parameter.defaultValue ?: return + val type = valueParameterDescriptor.type + expressionTypingServices.getTypeInfo(defaultValue, context.replaceExpectedType(type)) if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(context.scope))) { - val constant = constantExpressionEvaluator.evaluateExpression(defaultValue, context.trace, valueParameterDescriptor.type) - if (constant == null || constant.usesNonConstValAsConstant) { + val constant = constantExpressionEvaluator.evaluateExpression(defaultValue, context.trace, type) + if ((constant == null || constant.usesNonConstValAsConstant) && !type.isError) { context.trace.report(Errors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT.on(defaultValue)) } } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt index 10e4fd9b28e..3c79f703665 100644 --- a/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt +++ b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt @@ -33,6 +33,10 @@ annotation class Ann8(val p1: Array, val p3: Array, val p4: Array) +annotation class Ann9( + val error: Unresolved = Unresolved.VALUE +) + // INCORRECT annotation class InAnn1(val p1: Int?, diff --git a/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.txt b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.txt index 758f439c0bf..0e6079fca84 100644 --- a/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.txt +++ b/compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.txt @@ -83,6 +83,14 @@ package test { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + public final annotation class Ann9 : kotlin.Annotation { + public constructor Ann9(/*0*/ error: [ERROR : Unresolved] = ...) + public final val error: [ERROR : Unresolved] + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + public final annotation class InAnn1 : kotlin.Annotation { public constructor InAnn1(/*0*/ p1: kotlin.Int?, /*1*/ p3: kotlin.Short?, /*2*/ p4: kotlin.Long?, /*3*/ p5: kotlin.Double?, /*4*/ p6: kotlin.Float?, /*5*/ p7: kotlin.Char?, /*6*/ p8: kotlin.Boolean?) public final val p1: kotlin.Int?