Fix KT-10764 IDEA doesn't show overload conflict between constructor and function...
When checking for overloads in package, consider functions and top-level class constructors as possibly conflicting between each other. NB OverloadUtil uses containing package scope from module descriptor. Change diagnostic message for CONFLICTING_OVERLOAD: it's misleading in case of fun vs constructor conflict. Add custom multifile test for diagnostics in IDE (probably not the best; should preprocess file content if it's required to check highlighting in multiple files, not only in the first file). Add test for KT-10765 Incremental compilation misses overload conflict between constructor and function ...
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.jvm
|
package org.jetbrains.kotlin.resolve.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||||
@@ -40,12 +41,14 @@ object JvmOverloadFilter : OverloadFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (overload in overloads) {
|
for (overload in overloads) {
|
||||||
|
if (overload is ConstructorDescriptor) continue
|
||||||
if (overload !is DeserializedCallableMemberDescriptor) continue
|
if (overload !is DeserializedCallableMemberDescriptor) continue
|
||||||
|
|
||||||
val containingDeclaration = overload.containingDeclaration
|
val containingDeclaration = overload.containingDeclaration
|
||||||
if (containingDeclaration !is PackageFragmentDescriptor) {
|
if (containingDeclaration !is PackageFragmentDescriptor) {
|
||||||
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
|
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
|
||||||
}
|
}
|
||||||
|
|
||||||
val implClassName = JvmFileClassUtil.getImplClassName(overload) ?:
|
val implClassName = JvmFileClassUtil.getImplClassName(overload) ?:
|
||||||
throw AssertionError("No implClassName: $overload")
|
throw AssertionError("No implClassName: $overload")
|
||||||
val implClassFQN = containingDeclaration.fqName.child(implClassName)
|
val implClassFQN = containingDeclaration.fqName.child(implClassName)
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ public interface Errors {
|
|||||||
|
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
DiagnosticFactory2<KtDeclaration, CallableMemberDescriptor, String> CONFLICTING_OVERLOADS =
|
DiagnosticFactory2<KtDeclaration, CallableMemberDescriptor, CallableMemberDescriptor> CONFLICTING_OVERLOADS =
|
||||||
DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
DiagnosticFactory2.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(
|
||||||
|
|||||||
+1
-1
@@ -611,7 +611,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}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING);
|
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' conflicts with another declaration: {1}", COMPACT_WITH_MODIFIERS, COMPACT_WITH_MODIFIERS);
|
||||||
|
|
||||||
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",
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ import org.jetbrains.kotlin.name.Name;
|
|||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
|
|
||||||
|
|
||||||
public class OverloadResolver {
|
public class OverloadResolver {
|
||||||
@NotNull private final BindingTrace trace;
|
@NotNull private final BindingTrace trace;
|
||||||
@NotNull private final OverloadFilter overloadFilter;
|
@NotNull private final OverloadFilter overloadFilter;
|
||||||
@@ -50,49 +49,43 @@ public class OverloadResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkOverloads(@NotNull BodiesResolveContext c) {
|
private void checkOverloads(@NotNull BodiesResolveContext c) {
|
||||||
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = MultiMap.create();
|
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = findConstructorsInNestedClasses(c);
|
||||||
MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages = MultiMap.create();
|
|
||||||
fillGroupedConstructors(c, inClasses, inPackages);
|
|
||||||
|
|
||||||
for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
for (Map.Entry<KtClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
||||||
checkOverloadsInAClass(entry.getValue(), entry.getKey(), inClasses.get(entry.getValue()));
|
checkOverloadsInAClass(entry.getValue(), entry.getKey(), inClasses.get(entry.getValue()));
|
||||||
}
|
}
|
||||||
checkOverloadsInPackages(c, inPackages);
|
checkOverloadsInPackages(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fillGroupedConstructors(
|
private static MultiMap<ClassDescriptor, ConstructorDescriptor> findConstructorsInNestedClasses(@NotNull BodiesResolveContext c) {
|
||||||
@NotNull BodiesResolveContext c,
|
MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses = MultiMap.create();
|
||||||
@NotNull MultiMap<ClassDescriptor, ConstructorDescriptor> inClasses,
|
|
||||||
@NotNull MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages
|
|
||||||
) {
|
|
||||||
for (ClassDescriptorWithResolutionScopes klass : c.getDeclaredClasses().values()) {
|
for (ClassDescriptorWithResolutionScopes klass : c.getDeclaredClasses().values()) {
|
||||||
if (klass.getKind().isSingleton() || klass.getName().isSpecial()) {
|
if (klass.getKind().isSingleton() || klass.getName().isSpecial()) {
|
||||||
// Constructors of singletons or anonymous object aren't callable from the code, so they shouldn't participate in overload name checking
|
// Constructors of singletons or anonymous object aren't callable from the code, so they shouldn't participate in overload name checking
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclarationDescriptor containingDeclaration = klass.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = klass.getContainingDeclaration();
|
||||||
if (containingDeclaration instanceof ClassDescriptor) {
|
if (containingDeclaration instanceof ScriptDescriptor) {
|
||||||
|
// TODO: check overload conflicts of functions with constructors in scripts
|
||||||
|
}
|
||||||
|
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||||
inClasses.putValues(classDescriptor, klass.getConstructors());
|
inClasses.putValues(classDescriptor, klass.getConstructors());
|
||||||
}
|
}
|
||||||
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
else if (!(containingDeclaration instanceof FunctionDescriptor ||
|
||||||
inPackages.putValues(getFqName(klass), klass.getConstructors());
|
containingDeclaration instanceof PropertyDescriptor ||
|
||||||
}
|
containingDeclaration instanceof PackageFragmentDescriptor)) {
|
||||||
else if (containingDeclaration instanceof ScriptDescriptor) {
|
|
||||||
// TODO: check overload conflicts of functions with constructors in scripts
|
|
||||||
}
|
|
||||||
else if (!(containingDeclaration instanceof FunctionDescriptor || containingDeclaration instanceof PropertyDescriptor)) {
|
|
||||||
throw new IllegalStateException("Illegal class container: " + containingDeclaration);
|
throw new IllegalStateException("Illegal class container: " + containingDeclaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return inClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkOverloadsInPackages(
|
private void checkOverloadsInPackages(@NotNull BodiesResolveContext c) {
|
||||||
@NotNull BodiesResolveContext c,
|
|
||||||
@NotNull MultiMap<FqNameUnsafe, ConstructorDescriptor> inPackages
|
|
||||||
) {
|
|
||||||
MultiMap<FqNameUnsafe, CallableMemberDescriptor> membersByName =
|
MultiMap<FqNameUnsafe, CallableMemberDescriptor> membersByName =
|
||||||
OverloadUtil.groupModulePackageMembersByFqName(c, inPackages, overloadFilter);
|
OverloadUtil.groupModulePackageMembersByFqName(c, overloadFilter);
|
||||||
|
|
||||||
for (Map.Entry<FqNameUnsafe, Collection<CallableMemberDescriptor>> e : membersByName.entrySet()) {
|
for (Map.Entry<FqNameUnsafe, Collection<CallableMemberDescriptor>> e : membersByName.entrySet()) {
|
||||||
FqNameUnsafe fqName = e.getKey().parent();
|
FqNameUnsafe fqName = e.getKey().parent();
|
||||||
@@ -203,22 +196,38 @@ public class OverloadResolver {
|
|||||||
return file == null || file2 == null || file != file2;
|
return file == null || file2 == null || file != file2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportRedeclarations(@NotNull String functionContainer,
|
private void reportRedeclarations(
|
||||||
@NotNull Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations) {
|
@NotNull String functionContainer,
|
||||||
|
@NotNull Set<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarations
|
||||||
|
) {
|
||||||
|
if (redeclarations.isEmpty()) return;
|
||||||
|
|
||||||
|
Iterator<Pair<KtDeclaration, CallableMemberDescriptor>> redeclarationsIterator = redeclarations.iterator();
|
||||||
|
CallableMemberDescriptor firstRedeclarationDescriptor = redeclarationsIterator.next().getSecond();
|
||||||
|
CallableMemberDescriptor otherRedeclarationDescriptor = redeclarationsIterator.hasNext()
|
||||||
|
? redeclarationsIterator.next().getSecond()
|
||||||
|
: null;
|
||||||
|
|
||||||
for (Pair<KtDeclaration, CallableMemberDescriptor> redeclaration : redeclarations) {
|
for (Pair<KtDeclaration, CallableMemberDescriptor> redeclaration : redeclarations) {
|
||||||
|
KtDeclaration ktDeclaration = redeclaration.getFirst();
|
||||||
CallableMemberDescriptor memberDescriptor = redeclaration.getSecond();
|
CallableMemberDescriptor memberDescriptor = redeclaration.getSecond();
|
||||||
|
|
||||||
KtDeclaration ktDeclaration = redeclaration.getFirst();
|
CallableMemberDescriptor redeclarationDescriptor;
|
||||||
|
if (otherRedeclarationDescriptor == null) {
|
||||||
|
redeclarationDescriptor = firstRedeclarationDescriptor;
|
||||||
|
}
|
||||||
|
else if (firstRedeclarationDescriptor == memberDescriptor) {
|
||||||
|
redeclarationDescriptor = otherRedeclarationDescriptor;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
redeclarationDescriptor = firstRedeclarationDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
if (memberDescriptor instanceof PropertyDescriptor) {
|
if (memberDescriptor instanceof PropertyDescriptor) {
|
||||||
trace.report(Errors.REDECLARATION.on(ktDeclaration, memberDescriptor.getName().asString()));
|
trace.report(Errors.REDECLARATION.on(ktDeclaration, memberDescriptor.getName().asString()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String containingClassName = ktDeclaration instanceof KtSecondaryConstructor ?
|
trace.report(Errors.CONFLICTING_OVERLOADS.on(ktDeclaration, memberDescriptor, redeclarationDescriptor));
|
||||||
((KtSecondaryConstructor) ktDeclaration).getContainingClassOrObject().getName() : null;
|
|
||||||
|
|
||||||
trace.report(Errors.CONFLICTING_OVERLOADS.on(
|
|
||||||
ktDeclaration, memberDescriptor,
|
|
||||||
containingClassName != null ? containingClassName : functionContainer));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,14 +82,18 @@ object OverloadUtil {
|
|||||||
|
|
||||||
@JvmStatic fun groupModulePackageMembersByFqName(
|
@JvmStatic fun groupModulePackageMembersByFqName(
|
||||||
c: BodiesResolveContext,
|
c: BodiesResolveContext,
|
||||||
constructorsInPackages: MultiMap<FqNameUnsafe, ConstructorDescriptor>,
|
|
||||||
overloadFilter: OverloadFilter
|
overloadFilter: OverloadFilter
|
||||||
): MultiMap<FqNameUnsafe, CallableMemberDescriptor> {
|
): MultiMap<FqNameUnsafe, CallableMemberDescriptor> {
|
||||||
val packageMembersByName = MultiMap<FqNameUnsafe, CallableMemberDescriptor>()
|
val packageMembersByName = MultiMap<FqNameUnsafe, CallableMemberDescriptor>()
|
||||||
|
|
||||||
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values, overloadFilter) {
|
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values + c.declaredClasses.values, overloadFilter) {
|
||||||
scope, name ->
|
scope, name ->
|
||||||
scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||||
|
val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
|
||||||
|
if (classifier is ClassDescriptor && !classifier.kind.isSingleton)
|
||||||
|
functions + classifier.constructors
|
||||||
|
else
|
||||||
|
functions
|
||||||
}
|
}
|
||||||
|
|
||||||
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
|
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
|
||||||
@@ -97,15 +101,12 @@ object OverloadUtil {
|
|||||||
scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS).filterIsInstance<CallableMemberDescriptor>()
|
scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS).filterIsInstance<CallableMemberDescriptor>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO handle constructor redeclarations in modules. See also: https://youtrack.jetbrains.com/issue/KT-3632
|
|
||||||
packageMembersByName.putAllValues(constructorsInPackages)
|
|
||||||
|
|
||||||
return packageMembersByName
|
return packageMembersByName
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun collectModulePackageMembersWithSameName(
|
private inline fun collectModulePackageMembersWithSameName(
|
||||||
packageMembersByName: MultiMap<FqNameUnsafe, CallableMemberDescriptor>,
|
packageMembersByName: MultiMap<FqNameUnsafe, CallableMemberDescriptor>,
|
||||||
interestingDescriptors: Collection<CallableMemberDescriptor>,
|
interestingDescriptors: Collection<DeclarationDescriptor>,
|
||||||
overloadFilter: OverloadFilter,
|
overloadFilter: OverloadFilter,
|
||||||
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
|
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
|
||||||
) {
|
) {
|
||||||
@@ -123,20 +124,25 @@ object OverloadUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inline fun getModulePackageMembersWithSameName(
|
private inline fun getModulePackageMembersWithSameName(
|
||||||
packageMember: CallableMemberDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
overloadFilter: OverloadFilter,
|
overloadFilter: OverloadFilter,
|
||||||
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
|
getMembersByName: (MemberScope, Name) -> Collection<CallableMemberDescriptor>
|
||||||
): Collection<CallableMemberDescriptor> {
|
): Collection<CallableMemberDescriptor> {
|
||||||
val containingPackage = packageMember.containingDeclaration
|
val containingPackage = descriptor.containingDeclaration
|
||||||
if (containingPackage !is PackageFragmentDescriptor) {
|
if (containingPackage !is PackageFragmentDescriptor) {
|
||||||
throw AssertionError("$packageMember is not a top-level package member")
|
throw AssertionError("$descriptor is not a top-level package member")
|
||||||
}
|
}
|
||||||
|
|
||||||
val containingModule = DescriptorUtils.getContainingModuleOrNull(packageMember) ?: return listOf(packageMember)
|
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 containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope
|
||||||
val possibleOverloads =
|
val possibleOverloads =
|
||||||
getMembersByName(containingPackageScope, packageMember.name).filter {
|
getMembersByName(containingPackageScope, descriptor.name).filter {
|
||||||
// NB memberScope for PackageViewDescriptor includes module dependencies
|
// NB memberScope for PackageViewDescriptor includes module dependencies
|
||||||
DescriptorUtils.getContainingModule(it) == containingModule
|
DescriptorUtils.getContainingModule(it) == containingModule
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -108,7 +108,7 @@ open class LazyClassMemberScope(
|
|||||||
|
|
||||||
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
|
override fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor) {
|
||||||
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override")
|
val declaration = DescriptorToSourceUtils.descriptorToDeclaration(fromCurrent) as? KtDeclaration ?: error("fromCurrent can not be a fake override")
|
||||||
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()))
|
trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromSuper))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
OverrideResolver.resolveUnknownVisibilities(result, trace)
|
OverrideResolver.resolveUnknownVisibilities(result, trace)
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
compiler/testData/cli/jvm/conflictingOverloads.kt:1:1: error: 'public fun a(): kotlin.collections.List<kotlin.Int>' is already defined in root package
|
compiler/testData/cli/jvm/conflictingOverloads.kt:1:1: error: 'public fun a(): kotlin.collections.List<kotlin.Int>' conflicts with another declaration: public fun a(): kotlin.collections.List<kotlin.String>
|
||||||
fun a(): List<Int> = null!!
|
fun a(): List<Int> = null!!
|
||||||
^
|
^
|
||||||
compiler/testData/cli/jvm/conflictingOverloads.kt:2:1: error: 'public fun a(): kotlin.collections.List<kotlin.String>' is already defined in root package
|
compiler/testData/cli/jvm/conflictingOverloads.kt:2:1: error: 'public fun a(): kotlin.collections.List<kotlin.String>' conflicts with another declaration: public fun a(): kotlin.collections.List<kotlin.Int>
|
||||||
fun a(): List<String> = null!!
|
fun a(): List<String> = null!!
|
||||||
^
|
^
|
||||||
COMPILATION_ERROR
|
COMPILATION_ERROR
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
|
// !DIAGNOSTICS: -DUPLICATE_CLASS_NAMES
|
||||||
<!FUNCTION_DECLARATION_WITH_NO_NAME!>fun ()<!> {
|
<!FUNCTION_DECLARATION_WITH_NO_NAME, CONFLICTING_OVERLOADS!>fun ()<!> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
package<!SYNTAX!><!>
|
package<!SYNTAX!><!>
|
||||||
|
|
||||||
<!FUNCTION_DECLARATION_WITH_NO_NAME!>fun ()<!> {
|
<!FUNCTION_DECLARATION_WITH_NO_NAME, CONFLICTING_OVERLOADS!>fun ()<!> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// FILE: test1.kt
|
||||||
|
class <!CONFLICTING_OVERLOADS!>A<!>
|
||||||
|
class B<!CONFLICTING_OVERLOADS!>(val x: Int)<!> {
|
||||||
|
<!CONFLICTING_OVERLOADS!>constructor(x: Int, y: Int)<!>: this(x + y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test2.kt
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun A()<!> {}
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun B(x: Int)<!> = x
|
||||||
|
<!CONFLICTING_OVERLOADS!>fun B(x: Int, y: Int)<!> = x + y
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun A(): kotlin.Unit
|
||||||
|
public fun B(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
|
public fun B(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int
|
||||||
|
|
||||||
|
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(/*0*/ x: kotlin.Int)
|
||||||
|
public constructor B(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||||
|
public final val x: kotlin.Int
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -13083,6 +13083,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunVsCtorInDifferentFiles.kt")
|
||||||
|
public void testFunVsCtorInDifferentFiles() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/FunVsCtorInDifferentFiles.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt2418.kt")
|
@TestMetadata("kt2418.kt")
|
||||||
public void testKt2418() throws Exception {
|
public void testKt2418() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/kt2418.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/kt2418.kt");
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ 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, DescriptorRenderer.HTML);
|
RENDER_CLASS_OR_OBJECT, DescriptorRenderer.HTML);
|
||||||
MAP.put(CONFLICTING_OVERLOADS, "<html>''{0}''<br />is already defined in {1}</html>",
|
MAP.put(CONFLICTING_OVERLOADS, "<html>''{0}''<br />conflicts with another declaration: {1}</html>",
|
||||||
IdeRenderers.HTML_COMPACT_WITH_MODIFIERS, STRING);
|
IdeRenderers.HTML_COMPACT_WITH_MODIFIERS, IdeRenderers.HTML_COMPACT_WITH_MODIFIERS);
|
||||||
|
|
||||||
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>" +
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class A<error>(val x: Int)</error> {
|
||||||
|
<error>constructor()</error>: this(0)
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fun A() {}
|
||||||
|
fun A(x: Int) = x
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<error>fun A()</error> {}
|
||||||
|
<error>fun A(x: Int)</error> = x
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class A(val x: Int) {
|
||||||
|
constructor(): this(0)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// ERROR: 'public open fun foo(): kotlin.Unit' is already defined in C
|
// ERROR: 'public open fun foo(): kotlin.Unit' conflicts with another declaration: public open fun foo(): kotlin.Unit
|
||||||
// ERROR: 'public open fun foo(): kotlin.Unit' is already defined in C
|
// ERROR: 'public open fun foo(): kotlin.Unit' conflicts with another declaration: public open fun foo(): kotlin.Unit
|
||||||
interface I {
|
interface I {
|
||||||
open fun foo(){}
|
open fun foo(){}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<!-- conflictingOverloadsClass1 -->
|
<!-- conflictingOverloadsClass1 -->
|
||||||
<html>
|
<html>
|
||||||
'<b>public</b> <b>final</b> <b>fun</b> lol(x: kotlin.Int): kotlin.Int'<br />is already defined in conflictingOverloads</html>
|
'<b>public</b> <b>final</b> <b>fun</b> lol(x: kotlin.Int): kotlin.Int'<br />conflicts with another declaration: <b>public</b> <b>final</b> <b>fun</b> lol(y: kotlin.Int): kotlin.Int</html>
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
<!-- conflictingOverloadsClass2 -->
|
<!-- conflictingOverloadsClass2 -->
|
||||||
<html>
|
<html>
|
||||||
'<b>public</b> <b>final</b> <b>fun</b> lol(y: kotlin.Int): kotlin.Int'<br />is already defined in conflictingOverloads</html>
|
'<b>public</b> <b>final</b> <b>fun</b> lol(y: kotlin.Int): kotlin.Int'<br />conflicts with another declaration: <b>public</b> <b>final</b> <b>fun</b> lol(x: kotlin.Int): kotlin.Int</html>
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- conflictingOverloadsDefaultPackage1 -->
|
<!-- conflictingOverloadsDefaultPackage1 -->
|
||||||
'public fun foo(x: kotlin.Int): kotlin.Int' is already defined in root package
|
'public fun foo(x: kotlin.Int): kotlin.Int' conflicts with another declaration: public fun foo(y: kotlin.Int): kotlin.Int
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- conflictingOverloadsDefaultPackage2 -->
|
<!-- conflictingOverloadsDefaultPackage2 -->
|
||||||
'public fun foo(y: kotlin.Int): kotlin.Int' is already defined in root package
|
'public fun foo(y: kotlin.Int): kotlin.Int' conflicts with another declaration: public fun foo(x: kotlin.Int): kotlin.Int
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- constructorsRedeclaration1 -->
|
<!-- constructorsRedeclaration1 -->
|
||||||
'public constructor Element(x: kotlin.String)' is already defined in Element
|
'public constructor Element(x: kotlin.String)' conflicts with another declaration: public constructor Element(x: kotlin.String)
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- constructorsRedeclaration2 -->
|
<!-- constructorsRedeclaration2 -->
|
||||||
'public constructor Element(x: kotlin.String)' is already defined in Element
|
'public constructor Element(x: kotlin.String)' conflicts with another declaration: public constructor Element(x: kotlin.String)
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- constructorsRedeclarationTopLevel1 -->
|
<!-- constructorsRedeclarationTopLevel1 -->
|
||||||
'public fun Element(x: kotlin.String): kotlin.Unit' is already defined in root package
|
'public fun Element(x: kotlin.String): kotlin.Unit' conflicts with another declaration: public constructor Element(x: kotlin.String)
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
<!-- constructorsRedeclarationTopLevel2 -->
|
<!-- constructorsRedeclarationTopLevel2 -->
|
||||||
'public constructor Element(x: kotlin.String)' is already defined in Element
|
'public constructor Element(x: kotlin.String)' conflicts with another declaration: public fun Element(x: kotlin.String): kotlin.Unit
|
||||||
@@ -31,6 +31,11 @@ public abstract class AbstractPsiCheckerTest extends KotlinLightCodeInsightFixtu
|
|||||||
checkHighlighting(true, false, false);
|
checkHighlighting(true, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void doTest(@NotNull String... filePath) throws Exception {
|
||||||
|
myFixture.configureByFiles(filePath);
|
||||||
|
checkHighlighting(true, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
public void doTestWithInfos(@NotNull String filePath) throws Exception {
|
public void doTestWithInfos(@NotNull String filePath) throws Exception {
|
||||||
try {
|
try {
|
||||||
myFixture.configureByFile(filePath);
|
myFixture.configureByFile(filePath);
|
||||||
|
|||||||
@@ -23,10 +23,22 @@ class PsiCheckerCustomTest : AbstractPsiCheckerTest() {
|
|||||||
val testAnnotation = "MyTestAnnotation"
|
val testAnnotation = "MyTestAnnotation"
|
||||||
EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.add(testAnnotation)
|
EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.add(testAnnotation)
|
||||||
try {
|
try {
|
||||||
doTest("idea/testData/checker/custom/noUnusedParameterWhenCustom.kt")
|
doTest(getTestDataFile("noUnusedParameterWhenCustom.kt"))
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.remove(testAnnotation)
|
EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.remove(testAnnotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testConflictingOverloadsMultifile1() {
|
||||||
|
doTest(getTestDataFile("conflictingOverloadsMultifile1a.kt"),
|
||||||
|
getTestDataFile("conflictingOverloadsMultifile1b.kt"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testConflictingOverloadsMultifile2() {
|
||||||
|
doTest(getTestDataFile("conflictingOverloadsMultifile2a.kt"),
|
||||||
|
getTestDataFile("conflictingOverloadsMultifile2b.kt"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTestDataFile(localName: String) = "idea/testData/checker/custom/$localName"
|
||||||
}
|
}
|
||||||
+6
@@ -335,6 +335,12 @@ public class ExperimentalIncrementalJpsTestGenerated extends AbstractExperimenta
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funVsConstructorOverloadConflict")
|
||||||
|
public void testFunVsConstructorOverloadConflict() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/funVsConstructorOverloadConflict/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionBecameInline")
|
@TestMetadata("functionBecameInline")
|
||||||
public void testFunctionBecameInline() throws Exception {
|
public void testFunctionBecameInline() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/functionBecameInline/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/functionBecameInline/");
|
||||||
|
|||||||
@@ -335,6 +335,12 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funVsConstructorOverloadConflict")
|
||||||
|
public void testFunVsConstructorOverloadConflict() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/funVsConstructorOverloadConflict/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionBecameInline")
|
@TestMetadata("functionBecameInline")
|
||||||
public void testFunctionBecameInline() throws Exception {
|
public void testFunctionBecameInline() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/functionBecameInline/");
|
String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/functionBecameInline/");
|
||||||
|
|||||||
+11
-18
@@ -4,9 +4,19 @@ End of files
|
|||||||
Compiling files:
|
Compiling files:
|
||||||
src/A.kt
|
src/A.kt
|
||||||
End of files
|
End of files
|
||||||
|
COMPILATION FAILED
|
||||||
|
'public constructor A(x: kotlin.String)' conflicts with another declaration: public constructor A(x: kotlin.String)
|
||||||
|
|
||||||
|
|
||||||
|
Cleaning output files:
|
||||||
|
out/production/module/AConstructorFunctionKt.class
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/A.kt
|
||||||
|
End of files
|
||||||
Cleaning output files:
|
Cleaning output files:
|
||||||
out/production/module/AChild.class
|
out/production/module/AChild.class
|
||||||
out/production/module/AConstructorFunctionKt.class
|
|
||||||
out/production/module/CreateAFromIntKt.class
|
out/production/module/CreateAFromIntKt.class
|
||||||
out/production/module/CreateAFromStringKt.class
|
out/production/module/CreateAFromStringKt.class
|
||||||
out/production/module/META-INF/module.kotlin_module
|
out/production/module/META-INF/module.kotlin_module
|
||||||
@@ -14,23 +24,6 @@ out/production/module/UseAKt.class
|
|||||||
End of files
|
End of files
|
||||||
Compiling files:
|
Compiling files:
|
||||||
src/AChild.kt
|
src/AChild.kt
|
||||||
src/AConstructorFunction.kt
|
|
||||||
src/createAFromInt.kt
|
|
||||||
src/createAFromString.kt
|
|
||||||
src/useA.kt
|
|
||||||
End of files
|
|
||||||
COMPILATION FAILED
|
|
||||||
Overload resolution ambiguity:
|
|
||||||
public constructor A(x: kotlin.String) defined in A
|
|
||||||
public fun A(x: kotlin.String): A defined in root package
|
|
||||||
|
|
||||||
|
|
||||||
Cleaning output files:
|
|
||||||
out/production/module/A.class
|
|
||||||
End of files
|
|
||||||
Compiling files:
|
|
||||||
src/A.kt
|
|
||||||
src/AChild.kt
|
|
||||||
src/createAFromInt.kt
|
src/createAFromInt.kt
|
||||||
src/createAFromString.kt
|
src/createAFromString.kt
|
||||||
src/useA.kt
|
src/useA.kt
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ Compiling files:
|
|||||||
src/fun2.kt
|
src/fun2.kt
|
||||||
End of files
|
End of files
|
||||||
COMPILATION FAILED
|
COMPILATION FAILED
|
||||||
'public fun function(): kotlin.Unit' is already defined in test
|
'public fun function(): kotlin.Unit' conflicts with another declaration: public fun function(): kotlin.Unit
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
Cleaning output files:
|
||||||
|
out/production/module/META-INF/module.kotlin_module
|
||||||
|
out/production/module/test/Fun2Kt.class
|
||||||
|
End of files
|
||||||
|
Compiling files:
|
||||||
|
src/fun2.kt
|
||||||
|
End of files
|
||||||
|
COMPILATION FAILED
|
||||||
|
'public constructor function()' conflicts with another declaration: public constructor function()
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun function() {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val x = 1
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
val x = 1
|
||||||
|
|
||||||
|
class function
|
||||||
Reference in New Issue
Block a user