From 12e4cf9a4f8a03360f7e3f0b778b03406f295a86 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 17 Nov 2016 12:02:47 +0100 Subject: [PATCH] Report @JvmOverloads errors on annotation, not on entire declaration (KT-12701) --- .../DefaultParameterValueSubstitutor.kt | 6 ++---- .../kotlin/resolve/jvm/annotationUtil.kt | 7 +------ .../jvm/checkers/declarationCheckers.kt | 19 +++++++++++-------- .../resolve/jvm/diagnostics/ErrorsJvm.java | 6 +++--- .../jvmOverloads/JvmOverloadWithNoDefaults.kt | 4 ++-- .../jvmOverloadsOnAbstractMethods.kt | 4 ++-- .../jvmOverloads/jvmOverloadsOnPrivate.kt | 6 +++--- 7 files changed, 24 insertions(+), 28 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt index a26b65787a8..f2ccfb0db3c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.jvm.AsmTypes -import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation +import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes @@ -83,9 +83,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) { classBuilder: ClassBuilder, memberCodegen: MemberCodegen<*> ): Boolean { - if (!functionDescriptor.hasJvmOverloadsAnnotation()) { - return false - } + functionDescriptor.findJvmOverloadsAnnotation() ?: return false val count = functionDescriptor.countDefaultParameters() diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt index ed16f409b01..8fa28f2cada 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt @@ -16,16 +16,11 @@ package org.jetbrains.kotlin.resolve.jvm.annotations -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils -fun DeclarationDescriptor.hasJvmOverloadsAnnotation(): Boolean { - return annotations.findAnnotation(FqName("kotlin.jvm.JvmOverloads")) != null -} +fun DeclarationDescriptor.findJvmOverloadsAnnotation() = annotations.findAnnotation(FqName("kotlin.jvm.JvmOverloads")) fun DeclarationDescriptor.findJvmFieldAnnotation() = DescriptorUtils.getAnnotationByFqName(annotations, FqName("kotlin.jvm.JvmField")) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt index 6b2727ff79f..00087d699a9 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.kt @@ -25,13 +25,13 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation +import org.jetbrains.kotlin.resolve.checkers.SimpleDeclarationChecker import org.jetbrains.kotlin.resolve.inline.InlineUtil +import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmFieldAnnotation -import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmOverloadsAnnotation import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm class LocalFunInlineChecker : SimpleDeclarationChecker { @@ -183,24 +183,27 @@ class OverloadsAnnotationChecker: SimpleDeclarationChecker { diagnosticHolder: DiagnosticSink, bindingContext: BindingContext ) { - if (descriptor.hasJvmOverloadsAnnotation()) { - checkDeclaration(declaration, descriptor, diagnosticHolder) + descriptor.findJvmOverloadsAnnotation()?.let { annotation -> + val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) + if (annotationEntry != null) { + checkDeclaration(annotationEntry, descriptor, diagnosticHolder) + } } } - private fun checkDeclaration(declaration: KtDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) { + private fun checkDeclaration(annotationEntry: KtAnnotationEntry, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) { if (descriptor !is CallableDescriptor) { return } if (descriptor is FunctionDescriptor && descriptor.modality == Modality.ABSTRACT) { - diagnosticHolder.report(ErrorsJvm.OVERLOADS_ABSTRACT.on(declaration)) + diagnosticHolder.report(ErrorsJvm.OVERLOADS_ABSTRACT.on(annotationEntry)) } else if ((!descriptor.visibility.isPublicAPI && descriptor.visibility != Visibilities.INTERNAL) || DescriptorUtils.isLocal(descriptor)) { - diagnosticHolder.report(ErrorsJvm.OVERLOADS_PRIVATE.on(declaration)) + diagnosticHolder.report(ErrorsJvm.OVERLOADS_PRIVATE.on(annotationEntry)) } else if (descriptor.valueParameters.none { it.declaresDefaultValue() }) { - diagnosticHolder.report(ErrorsJvm.OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS.on(declaration)) + diagnosticHolder.report(ErrorsJvm.OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS.on(annotationEntry)) } } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index b0a34f6334e..83e627296cc 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -57,9 +57,9 @@ public interface ErrorsJvm { DiagnosticFactory0 VOLATILE_ON_DELEGATE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SYNCHRONIZED_ON_ABSTRACT = DiagnosticFactory0.create(ERROR); - DiagnosticFactory0 OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); - DiagnosticFactory0 OVERLOADS_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory0 OVERLOADS_PRIVATE = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE); + DiagnosticFactory0 OVERLOADS_WITHOUT_DEFAULT_ARGUMENTS = DiagnosticFactory0.create(WARNING); + DiagnosticFactory0 OVERLOADS_ABSTRACT = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 OVERLOADS_PRIVATE = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 EXTERNAL_DECLARATION_CANNOT_BE_ABSTRACT = DiagnosticFactory0.create(ERROR, ABSTRACT_MODIFIER); DiagnosticFactory0 EXTERNAL_DECLARATION_CANNOT_HAVE_BODY = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/JvmOverloadWithNoDefaults.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/JvmOverloadWithNoDefaults.kt index b5b1390eec1..67cff340322 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/JvmOverloadWithNoDefaults.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/JvmOverloadWithNoDefaults.kt @@ -1,7 +1,7 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER class C { - @kotlin.jvm.JvmOverloads constructor() { + @kotlin.jvm.JvmOverloads constructor() { } - @kotlin.jvm.JvmOverloads fun foo(s: String) {} + @kotlin.jvm.JvmOverloads1 fun foo(s: String) {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt index e13adead1dd..4b53347c431 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnAbstractMethods.kt @@ -1,8 +1,8 @@ interface T { - @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") + @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") } abstract class C { - @kotlin.jvm.JvmOverloads abstract fun foo(s: String = "OK") + @kotlin.jvm.JvmOverloads abstract fun foo(s: String = "OK") } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt index 5feabdafa57..c4e706acaa8 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmOverloads/jvmOverloadsOnPrivate.kt @@ -1,6 +1,6 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER class C { - @kotlin.jvm.JvmOverloads private fun foo(s: String = "OK") { + @kotlin.jvm.JvmOverloads private fun foo(s: String = "OK") { } @kotlin.jvm.JvmOverloads fun bar(s: String = "OK") { @@ -9,12 +9,12 @@ class C { fun foo() { class D { - @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") { + @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") { } } val x = object { - @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") { + @kotlin.jvm.JvmOverloads fun foo(s: String = "OK") { } } } \ No newline at end of file