diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 9dbc8cefccf..58a4e739636 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -208,9 +208,10 @@ public interface Errors { DiagnosticFactory2 DEPRECATED_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING); DiagnosticFactory2 DEPRECATED_MODIFIER = DiagnosticFactory2.create(WARNING); DiagnosticFactory2 REDUNDANT_MODIFIER_FOR_TARGET = DiagnosticFactory2.create(WARNING); - DiagnosticFactory0 NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_MODIFIERS_AND_NAME); + DiagnosticFactory0 NO_EXPLICIT_VISIBILITY_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_START_TO_NAME); DiagnosticFactory0 NO_EXPLICIT_RETURN_TYPE_IN_API_MODE = DiagnosticFactory0.create(ERROR, DECLARATION_NAME); - DiagnosticFactory0 NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_MODIFIERS_AND_NAME); + DiagnosticFactory0 NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING = DiagnosticFactory0.create(WARNING, + DECLARATION_START_TO_NAME); DiagnosticFactory0 NO_EXPLICIT_RETURN_TYPE_IN_API_MODE_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_NAME); DiagnosticFactory2 WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR); DiagnosticFactory2 DEPRECATED_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(WARNING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 9cd0f7c4f91..bc8a5f08f3e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -1,24 +1,15 @@ /* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.diagnostics import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import com.intellij.psi.PsiNameIdentifierOwner +import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.tree.TokenSet import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.cfg.UnreachableCode @@ -189,9 +180,27 @@ object PositioningStrategies { } @JvmField - val DECLARATION_MODIFIERS_AND_NAME: PositioningStrategy = object : DeclarationHeader() { + val DECLARATION_START_TO_NAME: PositioningStrategy = object : DeclarationHeader() { + + private fun PsiElement.firstNonCommentNonAnnotationLeaf(): PsiElement? { + var child: PsiElement? = firstChild ?: return this // this is leaf + while (true) { + if (child is PsiComment || child is PsiWhiteSpace || child is KtAnnotationEntry) { + child = child.nextSibling + continue + } + if (child == null) return null // no children of accepted type in this + val leaf = child.firstNonCommentNonAnnotationLeaf() + if (leaf == null) { + child = child.nextSibling + continue + } + return leaf + } + } + override fun mark(element: KtDeclaration): List { - val startElement = element.firstChild + val startElement = element.firstNonCommentNonAnnotationLeaf() ?: element val nameIdentifier = (element as? KtNamedDeclaration)?.nameIdentifier return if (nameIdentifier != null) { markRange(startElement, nameIdentifier) diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/annotations.kt b/compiler/testData/diagnostics/testsWithExplicitApi/annotations.kt new file mode 100644 index 00000000000..e1859d6cd30 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithExplicitApi/annotations.kt @@ -0,0 +1,45 @@ +// SKIP_TXT + +annotation class A + +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FUNCTION +) +public annotation class B + +/** + * Foo1 KDoc + */ +@B +class Foo1() {} + +public class Foo2() { + /** + * KDoc for methodWithAnnotations + */ + @B + fun methodWithAnnotations() {} + + /** + * Property KDoc + */ + @B + var simple: Int = 10 +} + +public open class ClassWithOpen { + /** + * constructor KDoc + */ + @B + constructor() {} + + /** + * KDoc for openAnnotatedMethod + */ + @B + open fun openAnnotatedMethod() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/classes.kt b/compiler/testData/diagnostics/testsWithExplicitApi/classes.kt index 49699871fcd..af2abfdf7ec 100644 --- a/compiler/testData/diagnostics/testsWithExplicitApi/classes.kt +++ b/compiler/testData/diagnostics/testsWithExplicitApi/classes.kt @@ -1,9 +1,19 @@ // SKIP_TXT +/** + * KDoc for Foo1 + */ class Foo1() {} public class Foo2() { + /** + * KDoc for method + */ fun method() {} + + /** + * KDoc for method2 + */ public fun method2() {} private fun method3() {} @@ -12,6 +22,18 @@ public class Foo2() { public fun implicit3(): Int = 10 } +public open class ClassWithOpen() { + /** + * KDoc for method + */ + fun method() {} + + /** + * KDoc for openMethod + */ + open fun openMethod() {} +} + public data class FooData(val i: Int, val s: String) data class FooData2(val i: Int, val s: String) diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/companionObject.kt b/compiler/testData/diagnostics/testsWithExplicitApi/companionObject.kt index 0ac35aad619..a1d4401322b 100644 --- a/compiler/testData/diagnostics/testsWithExplicitApi/companionObject.kt +++ b/compiler/testData/diagnostics/testsWithExplicitApi/companionObject.kt @@ -9,5 +9,8 @@ public class Bar2 { } public class Bar3 { + /** + * Nested object KDoc + */ object NestedObject {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/constructors.kt b/compiler/testData/diagnostics/testsWithExplicitApi/constructors.kt index 0aa5e90d962..1274e474233 100644 --- a/compiler/testData/diagnostics/testsWithExplicitApi/constructors.kt +++ b/compiler/testData/diagnostics/testsWithExplicitApi/constructors.kt @@ -6,6 +6,9 @@ public class Foo3 public constructor() {} public class Foo4 private constructor() {} public class Foo5 { + /** + * constructor KDoc + */ constructor() {} } diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/properties.kt b/compiler/testData/diagnostics/testsWithExplicitApi/properties.kt index 1335aa10ddb..fdbd7c2b141 100644 --- a/compiler/testData/diagnostics/testsWithExplicitApi/properties.kt +++ b/compiler/testData/diagnostics/testsWithExplicitApi/properties.kt @@ -1,6 +1,9 @@ // SKIP_TXT public class Foo(val bar: Int, private var bar2: String, internal var bar3: Long, public var bar4: Int) { + /** + * Property KDoc + */ var simple: Int = 10 public var simple2: Int = 10 diff --git a/compiler/testData/diagnostics/testsWithExplicitApi/toplevel.kt b/compiler/testData/diagnostics/testsWithExplicitApi/toplevel.kt index 3813b990605..54e92fd6f88 100644 --- a/compiler/testData/diagnostics/testsWithExplicitApi/toplevel.kt +++ b/compiler/testData/diagnostics/testsWithExplicitApi/toplevel.kt @@ -1,5 +1,8 @@ // SKIP_TXT +/** + * foo KDoc + */ fun foo() {} public fun foo2() {} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithExplicitApiGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithExplicitApiGenerated.java index 5d6b181cfdc..d09f0f826f2 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithExplicitApiGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithExplicitApiGenerated.java @@ -28,6 +28,11 @@ public class DiagnosticsWithExplicitApiGenerated extends AbstractDiagnosticsWith KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithExplicitApi"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + runTest("compiler/testData/diagnostics/testsWithExplicitApi/annotations.kt"); + } + @TestMetadata("classes.kt") public void testClasses() throws Exception { runTest("compiler/testData/diagnostics/testsWithExplicitApi/classes.kt");