From 472e6f462f4a71b04754271e7add0ffde5449d46 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 2 Oct 2017 13:26:39 +0300 Subject: [PATCH] Report some actual declaration problems on declaration name Related to KT-20398 --- .../src/org/jetbrains/kotlin/diagnostics/Errors.java | 10 +++++----- .../kotlin/diagnostics/PositioningStrategies.kt | 11 +++++++++++ .../checkers/ExpectedActualDeclarationChecker.kt | 6 ++++-- .../headerClass/noImplKeywordOnMember.kt | 2 +- .../output.txt | 4 ++-- .../simpleNoImplKeywordOnTopLevelFunction/output.txt | 4 ++-- .../idea/highlighter/PlatformExpectedAnnotator.kt | 3 ++- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 9acbcfdb981..4d172c515a1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -576,17 +576,17 @@ public interface Errors { DiagnosticFactory0 ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); DiagnosticFactory0 ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory3>> NO_ACTUAL_FOR_EXPECT = DiagnosticFactory3.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory2>> ACTUAL_WITHOUT_EXPECT = DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory2>>>> NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS = - DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE); - DiagnosticFactory0 ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE); + DiagnosticFactory2.create(ERROR, ACTUAL_DECLARATION_NAME); + DiagnosticFactory0 ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, ACTUAL_DECLARATION_NAME); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 65e664099be..e85894a5976 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -96,6 +96,17 @@ object PositioningStrategies { } } + @JvmField val ACTUAL_DECLARATION_NAME: PositioningStrategy = object : DeclarationHeader() { + override fun mark(element: KtNamedDeclaration): List { + val nameIdentifier = element.nameIdentifier + return when { + nameIdentifier != null -> markElement(nameIdentifier) + element is KtNamedFunction -> DECLARATION_SIGNATURE.mark(element) + else -> DEFAULT.mark(element) + } + } + } + @JvmField val DECLARATION_NAME: PositioningStrategy = object : DeclarationHeader() { override fun mark(element: KtNamedDeclaration): List { val nameIdentifier = element.nameIdentifier diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index 5a7cda82f86..1e8bd107bdd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtConstructor import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils @@ -59,6 +60,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { ) { if (!languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return + if (declaration !is KtNamedDeclaration) return if (descriptor !is MemberDescriptor || DescriptorUtils.isEnumEntry(descriptor)) return if (descriptor.isExpect) { @@ -71,7 +73,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { } fun checkExpectedDeclarationHasActual( - reportOn: KtDeclaration, + reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, platformModule: ModuleDescriptor @@ -120,7 +122,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker { } private fun checkActualDeclarationHasExpected( - reportOn: KtDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, checkActual: Boolean + reportOn: KtNamedDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticSink, checkActual: Boolean ) { // Using the platform module instead of the common module is sort of fine here because the former always depends on the latter. // However, it would be clearer to find the common module this platform module implements and look for expected there instead. diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt index 0ebfd66c455..d024554a27f 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/noImplKeywordOnMember.kt @@ -10,5 +10,5 @@ expect class Foo { // FILE: jvm.kt actual class Foo { - fun bar(): String = "bar" + fun bar(): String = "bar" } diff --git a/compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/output.txt b/compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/output.txt index d0ef99e3046..46258567763 100644 --- a/compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/output.txt +++ b/compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/output.txt @@ -5,7 +5,7 @@ Output: -- JVM -- Exit code: COMPILATION_ERROR Output: -compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/jvm.kt:3:1: error: actual class 'Writer' has no corresponding members for expected class members: +compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeAlias/jvm.kt:3:18: error: actual class 'Writer' has no corresponding members for expected class members: protected constructor Writer() @@ -15,4 +15,4 @@ compiler/testData/multiplatform/regressions/incompatibleClassScopesWithImplTypeA protected/*protected and package*/ constructor Writer(p0: Any!) actual typealias Writer = java.io.Writer -^ + ^ diff --git a/compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/output.txt b/compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/output.txt index 1d624d94df6..b4da3aa3e89 100644 --- a/compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/output.txt +++ b/compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/output.txt @@ -5,6 +5,6 @@ Output: -- JVM -- Exit code: COMPILATION_ERROR Output: -compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/jvm.kt:3:1: error: declaration should be marked with 'actual' (suppress with -Xno-check-actual) +compiler/testData/multiplatform/simpleNoImplKeywordOnTopLevelFunction/jvm.kt:3:5: error: declaration should be marked with 'actual' (suppress with -Xno-check-actual) fun foo(s: String): Array = arrayOf(s) -^ + ^ diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt index 4ccb08c6fca..48958c6163b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.facet.implementingDescriptors import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.resolve.BindingTraceContext @@ -36,7 +37,7 @@ import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics class PlatformExpectedAnnotator : Annotator { override fun annotate(element: PsiElement, holder: AnnotationHolder) { - val declaration = element as? KtDeclaration ?: return + val declaration = element as? KtNamedDeclaration ?: return if (!isExpectedDeclaration(declaration)) return if (TargetPlatformDetector.getPlatform(declaration.containingKtFile) !is TargetPlatform.Common) return