JS: do not report declaration clash when common redeclaration diagnostic applies. See KT-14577
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
// FILE: first.kt
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
|
||||||
|
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
|
||||||
|
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun f(): Int<!> = 23
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun f(): Int<!> = 99
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun g(): String<!> = "23"
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun g(): Int<!> = 23
|
||||||
|
|
||||||
|
val <!REDECLARATION!>x<!>: Int = 42
|
||||||
|
val <!REDECLARATION!>x<!>: Int = 99
|
||||||
|
|
||||||
|
val <!REDECLARATION!>y<!>: String = "42"
|
||||||
|
val <!REDECLARATION!>y<!>: Int = 42
|
||||||
|
|
||||||
|
class B {
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun f(): Int<!> = 23
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun f(): Int<!> = 99
|
||||||
|
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun g(): String<!> = "23"
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun g(): Int<!> = 23
|
||||||
|
|
||||||
|
val <!REDECLARATION!>x<!>: Int = 42
|
||||||
|
val <!REDECLARATION!>x<!>: Int = 99
|
||||||
|
|
||||||
|
val <!REDECLARATION!>y<!>: String = "42"
|
||||||
|
val <!REDECLARATION!>y<!>: Int = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: second.kt
|
||||||
|
package foo
|
||||||
|
|
||||||
|
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
package foo {
|
||||||
|
public val x: kotlin.Int = 42
|
||||||
|
public val x: kotlin.Int = 99
|
||||||
|
public val y: kotlin.Int = 42
|
||||||
|
public val y: kotlin.String = "42"
|
||||||
|
public fun f(): kotlin.Int
|
||||||
|
public fun f(): kotlin.Int
|
||||||
|
public fun g(): kotlin.Int
|
||||||
|
public fun g(): kotlin.String
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A()
|
||||||
|
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 class A {
|
||||||
|
public constructor A()
|
||||||
|
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 class B {
|
||||||
|
public constructor B()
|
||||||
|
public final val x: kotlin.Int = 42
|
||||||
|
public final val x: kotlin.Int = 99
|
||||||
|
public final val y: kotlin.Int = 42
|
||||||
|
public final val y: kotlin.String = "42"
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun f(): kotlin.Int
|
||||||
|
public final fun f(): kotlin.Int
|
||||||
|
public final fun g(): kotlin.Int
|
||||||
|
public final fun g(): kotlin.String
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
public constructor C()
|
||||||
|
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 class C {
|
||||||
|
public constructor C()
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -428,6 +428,12 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("declarationClash.kt")
|
||||||
|
public void testDeclarationClash() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/name/declarationClash.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("extensionPropertyAndMethod.kt")
|
@TestMetadata("extensionPropertyAndMethod.kt")
|
||||||
public void testExtensionPropertyAndMethod() throws Exception {
|
public void testExtensionPropertyAndMethod() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/name/extensionPropertyAndMethod.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLib/name/extensionPropertyAndMethod.kt");
|
||||||
|
|||||||
+19
-3
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.resolve.diagnostics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
||||||
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
@@ -29,6 +30,13 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtensionProperty
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
|
||||||
class JsNameClashChecker : SimpleDeclarationChecker {
|
class JsNameClashChecker : SimpleDeclarationChecker {
|
||||||
|
companion object {
|
||||||
|
private val COMMON_DIAGNOSTICS = setOf(
|
||||||
|
Errors.REDECLARATION,
|
||||||
|
Errors.CONFLICTING_OVERLOADS,
|
||||||
|
Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION)
|
||||||
|
}
|
||||||
|
|
||||||
private val nameSuggestion = NameSuggestion()
|
private val nameSuggestion = NameSuggestion()
|
||||||
private val scopes = mutableMapOf<DeclarationDescriptor, MutableMap<String, DeclarationDescriptor>>()
|
private val scopes = mutableMapOf<DeclarationDescriptor, MutableMap<String, DeclarationDescriptor>>()
|
||||||
private val clashedFakeOverrides = mutableMapOf<DeclarationDescriptor, Pair<DeclarationDescriptor, DeclarationDescriptor>>()
|
private val clashedFakeOverrides = mutableMapOf<DeclarationDescriptor, Pair<DeclarationDescriptor, DeclarationDescriptor>>()
|
||||||
@@ -43,11 +51,14 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
|||||||
// We don't generate JS properties for extension properties, we generate methods instead, so in this case
|
// We don't generate JS properties for extension properties, we generate methods instead, so in this case
|
||||||
// check name clash only for accessors, not properties
|
// check name clash only for accessors, not properties
|
||||||
if (!descriptor.isExtensionProperty) {
|
if (!descriptor.isExtensionProperty) {
|
||||||
checkDescriptor(descriptor, declaration, diagnosticHolder)
|
checkDescriptor(descriptor, declaration, diagnosticHolder, bindingContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkDescriptor(descriptor: DeclarationDescriptor, declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {
|
private fun checkDescriptor(
|
||||||
|
descriptor: DeclarationDescriptor, declaration: KtDeclaration,
|
||||||
|
diagnosticHolder: DiagnosticSink, bindingContext: BindingContext
|
||||||
|
) {
|
||||||
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) return
|
||||||
|
|
||||||
val suggested = nameSuggestion.suggest(descriptor)!!
|
val suggested = nameSuggestion.suggest(descriptor)!!
|
||||||
@@ -58,7 +69,8 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
|||||||
if (existing != null &&
|
if (existing != null &&
|
||||||
existing != descriptor &&
|
existing != descriptor &&
|
||||||
existing.isImpl == descriptor.isImpl &&
|
existing.isImpl == descriptor.isImpl &&
|
||||||
existing.isHeader == descriptor.isHeader
|
existing.isHeader == descriptor.isHeader &&
|
||||||
|
!bindingContext.isCommonDiagnosticReported(declaration)
|
||||||
) {
|
) {
|
||||||
diagnosticHolder.report(ErrorsJs.JS_NAME_CLASH.on(declaration, name, existing))
|
diagnosticHolder.report(ErrorsJs.JS_NAME_CLASH.on(declaration, name, existing))
|
||||||
val existingDeclaration = existing.findPsi()
|
val existingDeclaration = existing.findPsi()
|
||||||
@@ -93,6 +105,10 @@ class JsNameClashChecker : SimpleDeclarationChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun BindingContext.isCommonDiagnosticReported(declaration: KtDeclaration): Boolean {
|
||||||
|
return diagnostics.forElement(declaration).any { it.factory in COMMON_DIAGNOSTICS }
|
||||||
|
}
|
||||||
|
|
||||||
private val DeclarationDescriptor.isImpl: Boolean
|
private val DeclarationDescriptor.isImpl: Boolean
|
||||||
get() = this is MemberDescriptor && this.isImpl
|
get() = this is MemberDescriptor && this.isImpl
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user