KT-13961 REDECLARATION not reported on private-in-file 'foo' vs public 'foo' in different file

Private-in-file declarations conflict with public overload-equivalent declarations
in other files in the same package.

Move functions for grouping possible redeclarations to OverloadResolver
(since they are used only there).

Refactor redeclarations / conflicting overloads reporting.
This commit is contained in:
Dmitry Petrov
2016-09-21 18:12:24 +03:00
parent 0120085443
commit 06101dba52
42 changed files with 293 additions and 297 deletions
@@ -65,7 +65,10 @@ public interface Errors {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DiagnosticFactory1<PsiElement, String> REDECLARATION = DiagnosticFactory1.create(ERROR, FOR_REDECLARATION); DiagnosticFactory1<PsiElement, Collection<DeclarationDescriptor>> REDECLARATION =
DiagnosticFactory1.create(ERROR, FOR_REDECLARATION);
DiagnosticFactory1<PsiElement, String> PACKAGE_OR_CLASSIFIER_REDECLARATION =
DiagnosticFactory1.create(ERROR, FOR_REDECLARATION);
DiagnosticFactory1<KtReferenceExpression, KtReferenceExpression> UNRESOLVED_REFERENCE = DiagnosticFactory1<KtReferenceExpression, KtReferenceExpression> UNRESOLVED_REFERENCE =
DiagnosticFactory1.create(ERROR, FOR_UNRESOLVED_REFERENCE); DiagnosticFactory1.create(ERROR, FOR_UNRESOLVED_REFERENCE);
@@ -315,8 +318,8 @@ public interface Errors {
// Members // Members
DiagnosticFactory2<PsiElement, CallableMemberDescriptor, DeclarationDescriptor> CONFLICTING_OVERLOADS = DiagnosticFactory1<PsiElement, Collection<DeclarationDescriptor>> CONFLICTING_OVERLOADS =
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
DiagnosticFactory0<KtNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition( DiagnosticFactory0<KtNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition(
KtTokens.OPEN_KEYWORD)); KtTokens.OPEN_KEYWORD));
@@ -17,14 +17,16 @@
package org.jetbrains.kotlin.diagnostics package org.jetbrains.kotlin.diagnostics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtLambdaExpression import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.context.CallPosition import org.jetbrains.kotlin.resolve.calls.context.CallPosition
@@ -139,3 +141,22 @@ fun ResolutionContext<*>.reportTypeMismatchDueToScalaLikeNamedFunctionSyntax(
private fun isScalaLikeEqualsBlock(expression: KtElement): Boolean = private fun isScalaLikeEqualsBlock(expression: KtElement): Boolean =
expression is KtLambdaExpression && expression is KtLambdaExpression &&
expression.parent.let { it is KtNamedFunction && it.equalsToken != null } expression.parent.let { it is KtNamedFunction && it.equalsToken != null }
inline fun reportOnDeclaration(trace: BindingTrace, descriptor: DeclarationDescriptor, what: (PsiElement) -> Diagnostic) {
DescriptorToSourceUtils.descriptorToDeclaration(descriptor)?.let { psiElement ->
trace.report(what(psiElement))
}
}
inline fun reportOnDeclarationOrFail(trace: BindingTrace, descriptor: DeclarationDescriptor, what: (PsiElement) -> Diagnostic) {
DescriptorToSourceUtils.descriptorToDeclaration(descriptor)?.let { psiElement ->
trace.report(what(psiElement))
} ?: throw AssertionError("No declaration for $descriptor")
}
inline fun <reified T : KtDeclaration> reportOnDeclarationAs(trace: BindingTrace, descriptor: DeclarationDescriptor, what: (T) -> Diagnostic) {
DescriptorToSourceUtils.descriptorToDeclaration(descriptor)?.let { psiElement ->
(psiElement as? T)?.let {
trace.report(what(it))
} ?: throw AssertionError("Declaration for $descriptor is expected to be ${T::class.simpleName}, actual declaration: $psiElement")
} ?: throw AssertionError("No declaration for $descriptor")
}
@@ -110,7 +110,9 @@ public class DefaultErrorMessages {
MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, RENDER_COLLECTION_OF_TYPES); MAP.put(INACCESSIBLE_TYPE, "Type {0} is inaccessible in this context due to: {1}", RENDER_TYPE, RENDER_COLLECTION_OF_TYPES);
MAP.put(REDECLARATION, "Redeclaration: {0}", STRING); MAP.put(REDECLARATION, "Conflicting declarations: {0}", commaSeparated(COMPACT_WITH_MODIFIERS));
MAP.put(PACKAGE_OR_CLASSIFIER_REDECLARATION, "Redeclaration: {0}", STRING);
MAP.put(NAME_SHADOWING, "Name shadowed: {0}", STRING); MAP.put(NAME_SHADOWING, "Name shadowed: {0}", STRING);
MAP.put(ACCESSOR_PARAMETER_NAME_SHADOWING, "Accessor parameter name 'field' is shadowed by backing field variable"); MAP.put(ACCESSOR_PARAMETER_NAME_SHADOWING, "Accessor parameter name 'field' is shadowed by backing field variable");
@@ -631,8 +633,7 @@ public class DefaultErrorMessages {
MAP.put(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, "{0} must override {1} because it inherits multiple interface methods of it", MAP.put(MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED, "{0} must override {1} because it inherits multiple interface methods of it",
RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES); RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES);
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' conflicts with another declaration in {1}", COMPACT_WITH_MODIFIERS, MAP.put(CONFLICTING_OVERLOADS, "Conflicting overloads: {0}", commaSeparated(FQ_NAMES_IN_TYPES));
DECLARATION_NAME_WITH_KIND);
MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. " + MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. " +
"The function ''" + OperatorNameConventions.INVOKE.asString() + "()'' is not found", "The function ''" + OperatorNameConventions.INVOKE.asString() + "()'' is not found",
@@ -18,14 +18,13 @@ package org.jetbrains.kotlin.resolve
import com.google.common.collect.HashMultimap import com.google.common.collect.HashMultimap
import com.google.common.collect.Multimap import com.google.common.collect.Multimap
import com.google.common.collect.Sets
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION import org.jetbrains.kotlin.diagnostics.Errors.REDECLARATION
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
import org.jetbrains.kotlin.diagnostics.reportOnDeclarationOrFail
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -60,40 +59,19 @@ class DeclarationResolver(
} }
} }
reportRedeclarations(descriptorMap) reportRedeclarationsWithClassifiers(descriptorMap)
} }
} }
private fun reportRedeclarations(descriptorMap: Multimap<Name, DeclarationDescriptor>) { private fun reportRedeclarationsWithClassifiers(descriptorMap: Multimap<Name, DeclarationDescriptor>) {
val redeclarations = Sets.newHashSet<Pair<PsiElement, Name>>()
for (name in descriptorMap.keySet()) { for (name in descriptorMap.keySet()) {
val descriptors = descriptorMap[name] val descriptors = descriptorMap[name]
if (descriptors.size <= 1) { if (descriptors.size > 1 && descriptors.any { it is ClassifierDescriptor }) {
continue for (descriptor in descriptors) {
} reportOnDeclaration(trace, descriptor) { REDECLARATION.on(it, descriptors) }
// We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at OverloadResolver
for (descriptor in descriptors) {
if (descriptor is ClassifierDescriptor) {
for (descriptor2 in descriptors) {
if (descriptor === descriptor2) {
continue
}
DescriptorToSourceUtils.getSourceFromDescriptor(descriptor)?.let {
redeclarations.add(Pair(it, descriptor.getName()))
}
if (descriptor2 is PropertyDescriptor) {
DescriptorToSourceUtils.descriptorToDeclaration(descriptor2)?.let {
redeclarations.add(Pair(it, descriptor2.getName()))
}
}
}
} }
} }
} }
for ((first, second) in redeclarations) {
trace.report(REDECLARATION.on(first, second.asString()))
}
} }
fun checkRedeclarationsInPackages(topLevelDescriptorProvider: TopLevelDescriptorProvider, topLevelFqNames: Multimap<FqName, KtElement>) { fun checkRedeclarationsInPackages(topLevelDescriptorProvider: TopLevelDescriptorProvider, topLevelFqNames: Multimap<FqName, KtElement>) {
@@ -107,7 +85,7 @@ class DeclarationResolver(
val reportAt = val reportAt =
if (declarationOrPackageDirective is KtPackageDirective) declarationOrPackageDirective.getNameIdentifier() if (declarationOrPackageDirective is KtPackageDirective) declarationOrPackageDirective.getNameIdentifier()
else declarationOrPackageDirective else declarationOrPackageDirective
trace.report(Errors.REDECLARATION.on(reportAt!!, fqName.shortName().asString())) trace.report(Errors.PACKAGE_OR_CLASSIFIER_REDECLARATION.on(reportAt!!, fqName.shortName().asString()))
} }
} }
} }
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.singletonOrEmptyList import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
class OverloadChecker(val specificityComparator: TypeSpecificityComparator) { class OverloadChecker(val specificityComparator: TypeSpecificityComparator) {
/** /**
@@ -98,118 +99,4 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) {
error("Unexpected declaration kind: $a") error("Unexpected declaration kind: $a")
} }
fun groupModulePackageMembersByFqName(
c: BodiesResolveContext,
overloadFilter: OverloadFilter
): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> {
val packageMembersByName = MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>()
collectModulePackageMembersWithSameName(
packageMembersByName,
c.functions.values + c.declaredClasses.values + c.typeAliases.values,
overloadFilter
) {
scope, name ->
val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
when (classifier) {
is ClassDescriptor ->
if (!classifier.kind.isSingleton)
functions + classifier.constructors
else
functions
is TypeAliasDescriptor ->
functions + classifier.getTypeAliasConstructors()
else ->
functions
}
}
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
scope, name ->
val variables = scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
variables + classifier.singletonOrEmptyList()
}
return packageMembersByName
}
private inline fun collectModulePackageMembersWithSameName(
packageMembersByName: MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>,
interestingDescriptors: Collection<DeclarationDescriptor>,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
) {
val observedFQNs = hashSetOf<FqNameUnsafe>()
for (descriptor in interestingDescriptors) {
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) continue
val descriptorFQN = DescriptorUtils.getFqName(descriptor)
if (observedFQNs.contains(descriptorFQN)) continue
observedFQNs.add(descriptorFQN)
val packageMembersWithSameName = getModulePackageMembersWithSameName(descriptor, overloadFilter, getMembersByName)
packageMembersByName.putValues(descriptorFQN, packageMembersWithSameName)
}
}
private inline fun getModulePackageMembersWithSameName(
descriptor: DeclarationDescriptor,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
): Collection<DeclarationDescriptorNonRoot> {
val containingPackage = descriptor.containingDeclaration
if (containingPackage !is PackageFragmentDescriptor) {
throw AssertionError("$descriptor is not a top-level package member")
}
val containingModule = DescriptorUtils.getContainingModuleOrNull(descriptor) ?:
return when (descriptor) {
is CallableMemberDescriptor -> listOf(descriptor)
is ClassDescriptor -> descriptor.constructors
else -> throw AssertionError("Unexpected descriptor kind: $descriptor")
}
val containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope
val possibleOverloads =
getMembersByName(containingPackageScope, descriptor.name).filter {
// NB memberScope for PackageViewDescriptor includes module dependencies
DescriptorUtils.getContainingModule(it) == containingModule
}
return overloadFilter.filterPackageMemberOverloads(possibleOverloads)
}
private fun DeclarationDescriptor.isPrivate() =
this is DeclarationDescriptorWithVisibility &&
Visibilities.isPrivate(this.visibility)
fun getPossibleRedeclarationGroups(
members: Collection<DeclarationDescriptorNonRoot>
): Collection<Collection<DeclarationDescriptorNonRoot>> {
val result = arrayListOf<Collection<DeclarationDescriptorNonRoot>>()
val nonPrivates = members.filter { !it.isPrivate() }
if (nonPrivates.size > 1) {
result.add(nonPrivates)
}
val bySourceFile = MultiMap.createSmart<SourceFile, DeclarationDescriptorNonRoot>()
for (member in members) {
val sourceFile = DescriptorUtils.getContainingSourceFile(member)
if (sourceFile != SourceFile.NO_SOURCE_FILE) {
bySourceFile.putValue(sourceFile, member)
}
}
for ((sourceFile, membersInFile) in bySourceFile.entrySet()) {
// File member groups are interesting in redeclaration check if at least one file member is private.
if (membersInFile.size > 1 && membersInFile.any { it.isPrivate() }) {
result.add(membersInFile)
}
}
return result
}
} }
@@ -19,11 +19,15 @@ package org.jetbrains.kotlin.resolve
import com.intellij.util.containers.MultiMap import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
class OverloadResolver( class OverloadResolver(
private val trace: BindingTrace, private val trace: BindingTrace,
@@ -73,13 +77,96 @@ class OverloadResolver(
} }
private fun checkOverloadsInPackages(c: BodiesResolveContext) { private fun checkOverloadsInPackages(c: BodiesResolveContext) {
val membersByName = overloadChecker.groupModulePackageMembersByFqName(c, overloadFilter) val membersByName = groupModulePackageMembersByFqName(c, overloadFilter)
for (e in membersByName.entrySet()) { for (e in membersByName.entrySet()) {
checkOverloadsInPackage(e.value) checkOverloadsInPackage(e.value)
} }
} }
private fun groupModulePackageMembersByFqName(
c: BodiesResolveContext,
overloadFilter: OverloadFilter
): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> {
val packageMembersByName = MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>()
collectModulePackageMembersWithSameName(
packageMembersByName,
c.functions.values + c.declaredClasses.values + c.typeAliases.values,
overloadFilter
) {
scope, name ->
val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
when (classifier) {
is ClassDescriptor ->
if (!classifier.kind.isSingleton)
functions + classifier.constructors
else
functions
is TypeAliasDescriptor ->
functions + classifier.getTypeAliasConstructors()
else ->
functions
}
}
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
scope, name ->
val variables = scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
variables + classifier.singletonOrEmptyList()
}
return packageMembersByName
}
private inline fun collectModulePackageMembersWithSameName(
packageMembersByName: MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>,
interestingDescriptors: Collection<DeclarationDescriptor>,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
) {
val observedFQNs = hashSetOf<FqNameUnsafe>()
for (descriptor in interestingDescriptors) {
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) continue
val descriptorFQN = DescriptorUtils.getFqName(descriptor)
if (observedFQNs.contains(descriptorFQN)) continue
observedFQNs.add(descriptorFQN)
val packageMembersWithSameName = getModulePackageMembersWithSameName(descriptor, overloadFilter, getMembersByName)
packageMembersByName.putValues(descriptorFQN, packageMembersWithSameName)
}
}
private inline fun getModulePackageMembersWithSameName(
descriptor: DeclarationDescriptor,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
): Collection<DeclarationDescriptorNonRoot> {
val containingPackage = descriptor.containingDeclaration
if (containingPackage !is PackageFragmentDescriptor) {
throw AssertionError("$descriptor is not a top-level package member")
}
val containingModule = DescriptorUtils.getContainingModuleOrNull(descriptor) ?:
return when (descriptor) {
is CallableMemberDescriptor -> listOf(descriptor)
is ClassDescriptor -> descriptor.constructors
else -> throw AssertionError("Unexpected descriptor kind: $descriptor")
}
val containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope
val possibleOverloads =
getMembersByName(containingPackageScope, descriptor.name).filter {
// NB memberScope for PackageViewDescriptor includes module dependencies
DescriptorUtils.getContainingModule(it) == containingModule
}
return overloadFilter.filterPackageMemberOverloads(possibleOverloads)
}
private fun checkOverloadsInClass( private fun checkOverloadsInClass(
classDescriptor: ClassDescriptorWithResolutionScopes, classDescriptor: ClassDescriptorWithResolutionScopes,
nestedClassConstructors: Collection<FunctionDescriptor> nestedClassConstructors: Collection<FunctionDescriptor>
@@ -102,11 +189,52 @@ class OverloadResolver(
private fun checkOverloadsInPackage(members: Collection<DeclarationDescriptorNonRoot>) { private fun checkOverloadsInPackage(members: Collection<DeclarationDescriptorNonRoot>) {
if (members.size == 1) return if (members.size == 1) return
for (redeclarationGroup in overloadChecker.getPossibleRedeclarationGroups(members)) {
reportRedeclarations(findRedeclarations(redeclarationGroup)) val redeclarationsMap = LinkedHashMap<DeclarationDescriptorNonRoot, MutableSet<DeclarationDescriptorNonRoot>>()
for (redeclarationGroup in getPossibleRedeclarationGroups(members)) {
val redeclarations = findRedeclarations(redeclarationGroup)
redeclarations.forEach {
redeclarationsMap.getOrPut(it) { LinkedHashSet() }.addAll(redeclarations)
}
}
val reported = HashSet<DeclarationDescriptorNonRoot>()
for ((member, conflicting) in redeclarationsMap) {
if (!reported.contains(member)) {
reported.addAll(conflicting)
reportRedeclarations(conflicting)
}
} }
} }
private fun getPossibleRedeclarationGroups(members: Collection<DeclarationDescriptorNonRoot>): Collection<Collection<DeclarationDescriptorNonRoot>> {
val result = arrayListOf<Collection<DeclarationDescriptorNonRoot>>()
val nonPrivates = members.filter { !it.isPrivate() }
val bySourceFile = members.groupBy { DescriptorUtils.getContainingSourceFile(it) }
var hasGroupIncludingNonPrivateMembers = false
for ((sourceFile, membersInFile) in bySourceFile) {
// File member groups are interesting in redeclaration check if at least one file member is private.
if (membersInFile.any { it.isPrivate() }) {
hasGroupIncludingNonPrivateMembers = true
val group = LinkedHashSet<DeclarationDescriptorNonRoot>(nonPrivates) + membersInFile
result.add(group)
}
}
if (!hasGroupIncludingNonPrivateMembers && nonPrivates.size > 1) {
result.add(nonPrivates)
}
return result
}
private fun DeclarationDescriptor.isPrivate() =
this is DeclarationDescriptorWithVisibility &&
Visibilities.isPrivate(this.visibility)
private fun checkOverloadsInClass(members: Collection<CallableMemberDescriptor>) { private fun checkOverloadsInClass(members: Collection<CallableMemberDescriptor>) {
if (members.size == 1) return if (members.size == 1) return
reportRedeclarations(findRedeclarations(members)) reportRedeclarations(findRedeclarations(members))
@@ -115,8 +243,8 @@ class OverloadResolver(
private fun DeclarationDescriptor.isSynthesized() = private fun DeclarationDescriptor.isSynthesized() =
this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.SYNTHESIZED this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.SYNTHESIZED
private fun findRedeclarations(members: Collection<DeclarationDescriptorNonRoot>): Set<Pair<KtDeclaration?, DeclarationDescriptorNonRoot>> { private fun findRedeclarations(members: Collection<DeclarationDescriptorNonRoot>): Collection<DeclarationDescriptorNonRoot> {
val redeclarations = linkedSetOf<Pair<KtDeclaration?, DeclarationDescriptorNonRoot>>() val redeclarations = linkedSetOf<DeclarationDescriptorNonRoot>()
for (member1 in members) { for (member1 in members) {
if (member1.isSynthesized()) continue if (member1.isSynthesized()) continue
@@ -126,8 +254,7 @@ class OverloadResolver(
if (isTopLevelMainInDifferentFiles(member1, member2)) continue if (isTopLevelMainInDifferentFiles(member1, member2)) continue
if (!overloadChecker.isOverloadable(member1, member2)) { if (!overloadChecker.isOverloadable(member1, member2)) {
val ktDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(member1) as KtDeclaration? redeclarations.add(member1)
redeclarations.add(ktDeclaration to member1)
} }
} }
} }
@@ -154,33 +281,16 @@ class OverloadResolver(
return file1 == null || file2 == null || file1 !== file2 return file1 == null || file2 == null || file1 !== file2
} }
private fun reportRedeclarations(redeclarations: Set<Pair<KtDeclaration?, DeclarationDescriptorNonRoot>>) { private fun reportRedeclarations(redeclarations: Collection<DeclarationDescriptorNonRoot>) {
if (redeclarations.isEmpty()) return if (redeclarations.isEmpty()) return
val redeclarationsIterator = redeclarations.iterator() for (memberDescriptor in redeclarations) {
val firstRedeclarationDescriptor = redeclarationsIterator.next().second
val otherRedeclarationDescriptor = redeclarationsIterator.check { it.hasNext() }?.next()?.second
for ((ktDeclaration, memberDescriptor) in redeclarations) {
if (ktDeclaration == null) continue
when (memberDescriptor) { when (memberDescriptor) {
is PropertyDescriptor, is PropertyDescriptor,
is ClassifierDescriptor -> { is ClassifierDescriptor ->
trace.report(Errors.REDECLARATION.on(ktDeclaration, memberDescriptor.name.asString())) reportOnDeclaration(trace, memberDescriptor) { Errors.REDECLARATION.on(it, redeclarations) }
} is FunctionDescriptor ->
is FunctionDescriptor -> { reportOnDeclaration(trace, memberDescriptor) { Errors.CONFLICTING_OVERLOADS.on(it, redeclarations) }
val redeclarationDescriptor =
if (otherRedeclarationDescriptor == null)
firstRedeclarationDescriptor
else if (memberDescriptor == firstRedeclarationDescriptor)
otherRedeclarationDescriptor
else
firstRedeclarationDescriptor
trace.report(Errors.CONFLICTING_OVERLOADS.on(ktDeclaration, memberDescriptor,
redeclarationDescriptor.containingDeclaration))
}
} }
} }
} }
@@ -23,14 +23,13 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERR
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportOnDeclarationAs
import org.jetbrains.kotlin.diagnostics.reportOnDeclarationOrFail
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.incremental.record import org.jetbrains.kotlin.incremental.record
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProvider
@@ -107,13 +106,13 @@ open class LazyClassMemberScope(
} }
override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) { override fun overrideConflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override") reportOnDeclarationOrFail(trace, fromCurrent) { Errors.CONFLICTING_OVERLOADS.on(it, listOf(fromCurrent, fromSuper)) }
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper.containingDeclaration))
} }
override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) { override fun inheritanceConflict(first: CallableMemberDescriptor, second: CallableMemberDescriptor) {
val thisClassDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(thisDescriptor) as? KtClassOrObject ?: error("No class declaration") reportOnDeclarationAs<KtClassOrObject>(trace, thisDescriptor) { ktClassOrObject ->
trace.report(Errors.CONFLICTING_INHERITED_MEMBERS.on(thisClassDeclaration, thisDescriptor, listOf(first, second))) Errors.CONFLICTING_INHERITED_MEMBERS.on(ktClassOrObject, thisDescriptor, listOf(first, second))
}
} }
}) })
OverrideResolver.resolveUnknownVisibilities(result, trace) OverrideResolver.resolveUnknownVisibilities(result, trace)
@@ -16,8 +16,12 @@
package org.jetbrains.kotlin.resolve.scopes package org.jetbrains.kotlin.resolve.scopes
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.reportOnDeclarationOrFail
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -77,32 +81,12 @@ class ThrowingLocalRedeclarationChecker(overloadChecker: OverloadChecker) : Abst
class TraceBasedLocalRedeclarationChecker(val trace: BindingTrace, overloadChecker: OverloadChecker): AbstractLocalRedeclarationChecker(overloadChecker) { class TraceBasedLocalRedeclarationChecker(val trace: BindingTrace, overloadChecker: OverloadChecker): AbstractLocalRedeclarationChecker(overloadChecker) {
override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) { override fun handleRedeclaration(first: DeclarationDescriptor, second: DeclarationDescriptor) {
reportRedeclaration(first) reportOnDeclarationOrFail(trace, first) { Errors.REDECLARATION.on(it, listOf(first, second))}
reportRedeclaration(second) reportOnDeclarationOrFail(trace, second) { Errors.REDECLARATION.on(it, listOf(first, second))}
} }
override fun handleConflictingOverloads(first: CallableMemberDescriptor, second: CallableMemberDescriptor) { override fun handleConflictingOverloads(first: CallableMemberDescriptor, second: CallableMemberDescriptor) {
reportConflictingOverloads(first, second.containingDeclaration) reportOnDeclarationOrFail(trace, first) { Errors.CONFLICTING_OVERLOADS.on(it, listOf(first, second)) }
reportConflictingOverloads(second, first.containingDeclaration) reportOnDeclarationOrFail(trace, second) { Errors.CONFLICTING_OVERLOADS.on(it, listOf(first, second)) }
}
private fun reportConflictingOverloads(conflicting: CallableMemberDescriptor, withContainedIn: DeclarationDescriptor) {
val reportElement = DescriptorToSourceUtils.descriptorToDeclaration(conflicting)
if (reportElement != null) {
trace.report(Errors.CONFLICTING_OVERLOADS.on(reportElement, conflicting, withContainedIn))
}
else {
throw IllegalStateException("No declaration found for " + conflicting)
}
}
private fun reportRedeclaration(descriptor: DeclarationDescriptor) {
val firstElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
if (firstElement != null) {
trace.report(Errors.REDECLARATION.on(firstElement, descriptor.name.asString()))
}
else {
throw IllegalStateException("No declaration found for " + descriptor)
}
} }
} }
+2 -2
View File
@@ -1,7 +1,7 @@
compiler/testData/cli/jvm/conflictingOverloads.kt:1:1: error: 'public fun a(): List<Int>' conflicts with another declaration in package '<root>' compiler/testData/cli/jvm/conflictingOverloads.kt:1:1: error: conflicting overloads: public fun a(): List<Int> defined in root package, public fun a(): List<String> defined in root package
fun a(): List<Int> = null!! fun a(): List<Int> = null!!
^ ^
compiler/testData/cli/jvm/conflictingOverloads.kt:2:1: error: 'public fun a(): List<String>' conflicts with another declaration in package '<root>' compiler/testData/cli/jvm/conflictingOverloads.kt:2:1: error: conflicting overloads: public fun a(): List<Int> defined in root package, public fun a(): List<String> defined in root package
fun a(): List<String> = null!! fun a(): List<String> = null!!
^ ^
COMPILATION_ERROR COMPILATION_ERROR
+9 -9
View File
@@ -1,28 +1,28 @@
compiler/testData/cli/jvm/diagnosticsOrder1.kt:1:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:1:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:2:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:2:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:3:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:3:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:4:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:4:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:5:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:5:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:6:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:6:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder1.kt:7:5: error: redeclaration: x compiler/testData/cli/jvm/diagnosticsOrder1.kt:7:5: error: conflicting declarations: public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int, public val x: Int
val x = 5 val x = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder2.kt:1:5: error: redeclaration: y compiler/testData/cli/jvm/diagnosticsOrder2.kt:1:5: error: conflicting declarations: public val y: Int, public val y: Int
val y = 5 val y = 5
^ ^
compiler/testData/cli/jvm/diagnosticsOrder2.kt:2:5: error: redeclaration: y compiler/testData/cli/jvm/diagnosticsOrder2.kt:2:5: error: conflicting declarations: public val y: Int, public val y: Int
val y = 5 val y = 5
^ ^
COMPILATION_ERROR COMPILATION_ERROR
@@ -16,7 +16,7 @@ private fun overlapping() = "oops #1"
@file:[JvmName("MultifileClass") JvmMultifileClass] @file:[JvmName("MultifileClass") JvmMultifileClass]
package a package a
fun overlapping() = "OK" private fun overlapping() = "OK"
fun ok() = overlapping() fun ok() = overlapping()
@@ -4,7 +4,7 @@
import a.* import a.*
fun box(): String = overlapping fun box(): String = ok()
// FILE: part1.kt // FILE: part1.kt
@file:[JvmName("MultifileClass") JvmMultifileClass] @file:[JvmName("MultifileClass") JvmMultifileClass]
@@ -16,7 +16,9 @@ private val overlapping = run { "oops #1" }
@file:[JvmName("MultifileClass") JvmMultifileClass] @file:[JvmName("MultifileClass") JvmMultifileClass]
package a package a
val overlapping = run { "OK" } private val overlapping = run { "OK" }
fun ok() = overlapping
// FILE: part3.kt // FILE: part3.kt
@file:[JvmName("MultifileClass") JvmMultifileClass] @file:[JvmName("MultifileClass") JvmMultifileClass]
@@ -1,11 +1,11 @@
// FILE: f1.kt // FILE: f1.kt
package test package test
class <!REDECLARATION!>A<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class F1 class F1
// FILE: f2.kt // FILE: f2.kt
package test package test
class <!REDECLARATION!>A<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class F2 class F2
@@ -1,7 +1,7 @@
// FILE: f.kt // FILE: f.kt
package a package a
class <!REDECLARATION!>b<!> {} class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>b<!> {}
// FILE: f.kt // FILE: f.kt
package a.<!REDECLARATION!>b<!> package a.<!PACKAGE_OR_CLASSIFIER_REDECLARATION!>b<!>
// FILE: f.kt // FILE: f.kt
package a.<!REDECLARATION!>b<!> package a.<!PACKAGE_OR_CLASSIFIER_REDECLARATION!>b<!>
@@ -1,15 +1,15 @@
// FILE: f.kt // FILE: f.kt
package redeclarations package redeclarations
object <!REDECLARATION, REDECLARATION!>A<!> { object <!PACKAGE_OR_CLASSIFIER_REDECLARATION, REDECLARATION!>A<!> {
val x : Int = 0 val x : Int = 0
val A = 1 val A = 1
} }
class <!REDECLARATION!>A<!> {} class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {}
val <!REDECLARATION, REDECLARATION!>A<!> = 1 val <!PACKAGE_OR_CLASSIFIER_REDECLARATION, REDECLARATION!>A<!> = 1
// FILE: f.kt // FILE: f.kt
package redeclarations.<!REDECLARATION!>A<!> package redeclarations.<!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class A {} class A {}
@@ -5,8 +5,14 @@ interface A
interface B : A interface B : A
private fun validFun() {} private fun validFun() {}
private val validVal = 1
private val validProp = 1 <!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {}
private val <!REDECLARATION!>invalidProp0<!> = 1
// NB invalidFun0 and invalidProp0 are conflicting overloads, since the following is an ambiguity:
fun useInvalidFun0() = <!OVERLOAD_RESOLUTION_AMBIGUITY!>invalidFun0<!>()
fun useInvalidProp0() = <!OVERLOAD_RESOLUTION_AMBIGUITY!>invalidProp0<!>
<!CONFLICTING_OVERLOADS!>private fun invalidFun1()<!> {} <!CONFLICTING_OVERLOADS!>private fun invalidFun1()<!> {}
<!CONFLICTING_OVERLOADS!>private fun invalidFun1()<!> {} <!CONFLICTING_OVERLOADS!>private fun invalidFun1()<!> {}
@@ -17,7 +23,7 @@ private val validProp = 1
<!CONFLICTING_OVERLOADS!>public fun invalidFun3()<!> {} <!CONFLICTING_OVERLOADS!>public fun invalidFun3()<!> {}
<!CONFLICTING_OVERLOADS!>private fun invalidFun4()<!> {} <!CONFLICTING_OVERLOADS!>private fun invalidFun4()<!> {}
<!CONFLICTING_OVERLOADS, CONFLICTING_OVERLOADS!>public fun invalidFun4()<!> {} <!CONFLICTING_OVERLOADS!>public fun invalidFun4()<!> {}
public fun validFun2(a: A) = a public fun validFun2(a: A) = a
public fun validFun2(b: B) = b public fun validFun2(b: B) = b
@@ -26,8 +32,11 @@ public fun validFun2(b: B) = b
package a package a
private fun validFun() {} private fun validFun() {}
private val validVal = 1
private val validProp = 1 <!CONFLICTING_OVERLOADS!>private fun invalidFun0()<!> {}
private val <!REDECLARATION!>invalidProp0<!> = 1
<!CONFLICTING_OVERLOADS!>internal fun invalidFun3()<!> {} <!CONFLICTING_OVERLOADS!>internal fun invalidFun3()<!> {}
<!CONFLICTING_OVERLOADS!>internal fun invalidFun4()<!> {} <!CONFLICTING_OVERLOADS!>internal fun invalidFun4()<!> {}
@@ -35,6 +44,6 @@ private val validProp = 1
// FILE: c.kt // FILE: c.kt
package a package a
public fun validFun() {} <!CONFLICTING_OVERLOADS!>public fun invalidFun0()<!> {}
public val validProp = 1 public val <!REDECLARATION!>invalidProp0<!> = 1
@@ -1,9 +1,14 @@
package package
package a { package a {
private val validProp: kotlin.Int = 1 private val invalidProp0: kotlin.Int = 1
private val validProp: kotlin.Int = 1 private val invalidProp0: kotlin.Int = 1
public val validProp: kotlin.Int = 1 public val invalidProp0: kotlin.Int = 1
private val validVal: kotlin.Int = 1
private val validVal: kotlin.Int = 1
private fun invalidFun0(): kotlin.Unit
private fun invalidFun0(): kotlin.Unit
public fun invalidFun0(): kotlin.Unit
private fun invalidFun1(): kotlin.Unit private fun invalidFun1(): kotlin.Unit
private fun invalidFun1(): kotlin.Unit private fun invalidFun1(): kotlin.Unit
private fun invalidFun2(): kotlin.Unit private fun invalidFun2(): kotlin.Unit
@@ -13,9 +18,10 @@ package a {
internal fun invalidFun4(): kotlin.Unit internal fun invalidFun4(): kotlin.Unit
private fun invalidFun4(): kotlin.Unit private fun invalidFun4(): kotlin.Unit
public fun invalidFun4(): kotlin.Unit public fun invalidFun4(): kotlin.Unit
public fun useInvalidFun0(): [ERROR : Error function type]
public fun useInvalidProp0(): [ERROR : Error function type]
private fun validFun(): kotlin.Unit private fun validFun(): kotlin.Unit
private fun validFun(): kotlin.Unit private fun validFun(): kotlin.Unit
public fun validFun(): kotlin.Unit
public fun validFun2(/*0*/ a: a.A): a.A public fun validFun2(/*0*/ a: a.A): a.A
public fun validFun2(/*0*/ b: a.B): a.B public fun validFun2(/*0*/ b: a.B): a.B
@@ -1,7 +1,7 @@
// FILE: f1.kt // FILE: f1.kt
package test package test
class <!REDECLARATION!>A<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class F1 class F1
// FILE: A.kts // FILE: A.kts
@@ -7,7 +7,7 @@ interface <!REDECLARATION!>Test2<!>
val <!REDECLARATION!>Test3<!> = null val <!REDECLARATION!>Test3<!> = null
object <!REDECLARATION!>Test3<!> object <!REDECLARATION!>Test3<!>
val <!REDECLARATION, REDECLARATION!>Test4<!> = null val <!PACKAGE_OR_CLASSIFIER_REDECLARATION, REDECLARATION!>Test4<!> = null
class <!REDECLARATION, REDECLARATION!>Test4<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION, REDECLARATION!>Test4<!>
interface <!REDECLARATION!>Test4<!> interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Test4<!>
object <!REDECLARATION!>Test4<!> object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>Test4<!>
@@ -1,9 +1,9 @@
// FILE: file1.kt // FILE: file1.kt
class <!REDECLARATION!>SomeClass<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!>
typealias <!REDECLARATION!>SomeClass<!> = Any typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!> = Any
typealias <!REDECLARATION!>SomeClass<!> = Any typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!> = Any
typealias <!REDECLARATION!>SomeClass<!> = Any typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!> = Any
class Outer { class Outer {
class <!REDECLARATION!>Nested<!> class <!REDECLARATION!>Nested<!>
@@ -14,4 +14,4 @@ class Outer {
} }
// FILE: file2.kt // FILE: file2.kt
typealias <!REDECLARATION!>SomeClass<!> = Any typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>SomeClass<!> = Any
+2 -2
View File
@@ -1,4 +1,4 @@
// JET-11 Redeclaration & Forward reference for classes cause an exception // JET-11 Redeclaration & Forward reference for classes cause an exception
open class <!REDECLARATION!>NoC<!> open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>NoC<!>
class NoC1 : NoC() class NoC1 : NoC()
open class <!REDECLARATION!>NoC<!> open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>NoC<!>
@@ -1,5 +1,5 @@
class <!REDECLARATION!>A<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!>
class <!REDECLARATION!>A<!> { class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
constructor() constructor()
} }
@@ -1,9 +1,9 @@
// FILE: file1.kt // FILE: file1.kt
private class <!REDECLARATION!>C<!> { private class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
companion object companion object
} }
private typealias <!REDECLARATION!>TA<!> = C private typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = C
private val test1: C = C() private val test1: C = C()
private val test1co: C.Companion = C private val test1co: C.Companion = C
@@ -18,5 +18,5 @@ private val test1co: <!INVISIBLE_REFERENCE!>C<!>.<!INVISIBLE_REFERENCE!>Companio
private val test2: <!INVISIBLE_REFERENCE!>TA<!> = <!INVISIBLE_MEMBER!>TA<!>() private val test2: <!INVISIBLE_REFERENCE!>TA<!> = <!INVISIBLE_MEMBER!>TA<!>()
private val test2co = <!INVISIBLE_MEMBER!>TA<!> private val test2co = <!INVISIBLE_MEMBER!>TA<!>
private class <!REDECLARATION!>C<!> private class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!>
private typealias <!REDECLARATION!>TA<!> = Int private typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = Int
@@ -135,8 +135,6 @@ public class IdeErrorMessages {
MAP.put(MANY_IMPL_MEMBER_NOT_IMPLEMENTED, "<html>{0} must override {1}<br />because it inherits many implementations of it</html>", MAP.put(MANY_IMPL_MEMBER_NOT_IMPLEMENTED, "<html>{0} must override {1}<br />because it inherits many implementations of it</html>",
RENDER_CLASS_OR_OBJECT, HTML); RENDER_CLASS_OR_OBJECT, HTML);
MAP.put(CONFLICTING_OVERLOADS, "<html>''{0}''<br />conflicts with another declaration in {1}</html>",
IdeRenderers.HTML_COMPACT_WITH_MODIFIERS, Renderers.DECLARATION_NAME_WITH_KIND);
MAP.put(RESULT_TYPE_MISMATCH, "<html>Function return type mismatch." + MAP.put(RESULT_TYPE_MISMATCH, "<html>Function return type mismatch." +
"<table><tr><td>Expected:</td><td>{1}</td></tr>" + "<table><tr><td>Expected:</td><td>{1}</td></tr>" +
@@ -1,5 +1,5 @@
// ERROR: 'public open fun foo(): Unit' conflicts with another declaration in class 'C' // ERROR: Conflicting overloads: public open fun foo(): Unit defined in C, public open fun foo(): Unit defined in C
// ERROR: 'public open fun foo(): Unit' conflicts with another declaration in class 'C' // ERROR: Conflicting overloads: public open fun foo(): Unit defined in C, public open fun foo(): Unit defined in C
interface I { interface I {
open fun foo(){} open fun foo(){}
} }
@@ -1,3 +0,0 @@
<!-- conflictingOverloadsClass1 -->
<html>
'<b>public</b> <b>final</b> <b>fun</b> lol(x: Int): Int'<br />conflicts with another declaration in class 'conflictingOverloads'</html>
@@ -0,0 +1,2 @@
<!-- conflictingOverloadsClass1 -->
Conflicting overloads: public final fun lol(x: Int): Int defined in conflictingOverloads, public final fun lol(y: Int): Int defined in conflictingOverloads
@@ -1,3 +0,0 @@
<!-- conflictingOverloadsClass2 -->
<html>
'<b>public</b> <b>final</b> <b>fun</b> lol(y: Int): Int'<br />conflicts with another declaration in class 'conflictingOverloads'</html>
@@ -0,0 +1,2 @@
<!-- conflictingOverloadsClass2 -->
Conflicting overloads: public final fun lol(x: Int): Int defined in conflictingOverloads, public final fun lol(y: Int): Int defined in conflictingOverloads
@@ -1,2 +1,2 @@
<!-- conflictingOverloadsDefaultPackage1 --> <!-- conflictingOverloadsDefaultPackage1 -->
'public fun foo(x: Int): Int' conflicts with another declaration in package '<root>' Conflicting overloads: public fun foo(x: Int): Int defined in root package, public fun foo(y: Int): Int defined in root package
@@ -1,2 +1,2 @@
<!-- conflictingOverloadsDefaultPackage2 --> <!-- conflictingOverloadsDefaultPackage2 -->
'public fun foo(y: Int): Int' conflicts with another declaration in package '<root>' Conflicting overloads: public fun foo(x: Int): Int defined in root package, public fun foo(y: Int): Int defined in root package
@@ -1,2 +1,2 @@
<!-- constructorsRedeclaration1 --> <!-- constructorsRedeclaration1 -->
'public constructor Element(x: String)' conflicts with another declaration in class 'Element' Conflicting overloads: public constructor Element(x: String) defined in Element, public constructor Element(x: String) defined in Element
@@ -1,2 +1,2 @@
<!-- constructorsRedeclaration2 --> <!-- constructorsRedeclaration2 -->
'public constructor Element(x: String)' conflicts with another declaration in class 'Element' Conflicting overloads: public constructor Element(x: String) defined in Element, public constructor Element(x: String) defined in Element
@@ -1,2 +1,2 @@
<!-- constructorsRedeclarationTopLevel1 --> <!-- constructorsRedeclarationTopLevel1 -->
'public fun Element(x: String): Unit' conflicts with another declaration in class 'Element' Conflicting overloads: public fun Element(x: String): Unit defined in root package, public constructor Element(x: String) defined in Element
@@ -1,2 +1,2 @@
<!-- constructorsRedeclarationTopLevel2 --> <!-- constructorsRedeclarationTopLevel2 -->
'public constructor Element(x: String)' conflicts with another declaration in package '<root>' Conflicting overloads: public fun Element(x: String): Unit defined in root package, public constructor Element(x: String) defined in Element
@@ -1,8 +1,8 @@
// "Add constructor parameters from Base(Int, Int, Any, String, String,...)" "true" // "Add constructor parameters from Base(Int, Int, Any, String, String,...)" "true"
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
open class Base<T>(p1: Int, private val p2: Int, p3: Any, p4: String, p5: T, p6: Int) open class Base<T>(p1: Int, private val p2: Int, p3: Any, p4: String, p5: T, p6: Int)
class C(p: Int, p2: Int, p3: String, p4: Any, p5: String, val p6: Int) : Base<String><caret> class C(p: Int, p2: Int, p3: String, p4: Any, p5: String, val p6: Int) : Base<String><caret>
@@ -1,8 +1,8 @@
// "Add constructor parameters from Base(Int, Int, Any, String, String,...)" "true" // "Add constructor parameters from Base(Int, Int, Any, String, String,...)" "true"
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
// ERROR: Redeclaration: p4 // ERROR: Conflicting declarations: value-parameter p4: Any, value-parameter p4: String
open class Base<T>(p1: Int, private val p2: Int, p3: Any, p4: String, p5: T, p6: Int) open class Base<T>(p1: Int, private val p2: Int, p3: Any, p4: String, p5: T, p6: Int)
class C(p: Int, p2: Int, p3: String, p4: Any, p5: String, val p6: Int, p1: Int, p4: String) : Base<String><caret>(p1, p2, p3, p4, p5, p6) class C(p: Int, p2: Int, p3: String, p4: Any, p5: String, val p6: Int, p1: Int, p4: String) : Base<String>(p1, p2, p3, p4, p5, p6)
@@ -9,7 +9,7 @@ End of files
Exit code: ABORT Exit code: ABORT
------------------------------------------ ------------------------------------------
COMPILATION FAILED COMPILATION FAILED
'public constructor A(x: String)' conflicts with another declaration in package '<root>' Conflicting overloads: public constructor A(x: String) defined in A, public fun A(x: String): A defined in root package
================ Step #2 ================= ================ Step #2 =================
@@ -10,4 +10,4 @@ End of files
Exit code: ABORT Exit code: ABORT
------------------------------------------ ------------------------------------------
COMPILATION FAILED COMPILATION FAILED
'public fun function(): Unit' conflicts with another declaration in package 'test' Conflicting overloads: public fun function(): Unit defined in test, public fun function(): Unit defined in test
@@ -10,4 +10,4 @@ End of files
Exit code: ABORT Exit code: ABORT
------------------------------------------ ------------------------------------------
COMPILATION FAILED COMPILATION FAILED
'public constructor function()' conflicts with another declaration in package 'test' Conflicting overloads: public constructor function() defined in test.function, public fun function(): Unit defined in test
@@ -10,4 +10,4 @@ End of files
Exit code: ABORT Exit code: ABORT
------------------------------------------ ------------------------------------------
COMPILATION FAILED COMPILATION FAILED
Redeclaration: property Conflicting declarations: public val property: Int, public val property: Int