When checking overrides, compare methods structurally

Because they may come from different copies of the same class from different modules
This commit is contained in:
Andrey Breslav
2014-05-29 17:41:46 +04:00
parent 5a864dbc62
commit 204fa76691
27 changed files with 1158 additions and 5 deletions
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.resolve
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
import org.jetbrains.jet.lang.descriptors.Visibilities
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
import org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo
import org.jetbrains.jet.lang.resolve
object DescriptorEquivalenceForOverrides {
public fun areEquivalent(a: DeclarationDescriptor?, b: DeclarationDescriptor?): Boolean {
return when {
a is ClassDescriptor &&
b is ClassDescriptor -> areClassesEquivalent(a, b)
a is TypeParameterDescriptor &&
b is TypeParameterDescriptor -> areTypeParametersEquivalent(a, b)
a is CallableMemberDescriptor &&
b is CallableMemberDescriptor -> areCallableMemberDescriptorsEquivalent(a, b)
a is PackageFragmentDescriptor &&
b is PackageFragmentDescriptor -> (a).fqName == (b).fqName
else -> a == b
}
}
private fun areClassesEquivalent(a: ClassDescriptor, b: ClassDescriptor): Boolean {
// type constructors are compared by fqName
return a.getTypeConstructor() == b.getTypeConstructor()
}
private fun areTypeParametersEquivalent(
a: TypeParameterDescriptor,
b: TypeParameterDescriptor,
equivalentCallables: (DeclarationDescriptor?, DeclarationDescriptor?) -> Boolean = {x, y -> false}
): Boolean {
if (a == b) return true
if (a.getContainingDeclaration() == b.getContainingDeclaration()) return false
if (!ownersEquivalent(a, b, equivalentCallables)) return false
return a.getIndex() == b.getIndex() // We ignore type parameter names
}
private fun areCallableMemberDescriptorsEquivalent(a: CallableMemberDescriptor, b: CallableMemberDescriptor): Boolean {
if (a == b) return true
if (a.getName() != b.getName()) return false
if (a.getContainingDeclaration() == b.getContainingDeclaration()) return false
// Distinct locals are not equivalent
if (DescriptorUtils.isLocal(a) || DescriptorUtils.isLocal(b)) return false
if (!ownersEquivalent(a, b, {x, y -> false})) return false
val overridingUtil = OverridingUtil.createWithEqualityAxioms @eq {
(c1, c2): Boolean ->
if (c1 == c2) return@eq true
val d1 = c1.getDeclarationDescriptor()
val d2 = c2.getDeclarationDescriptor()
if (d1 !is TypeParameterDescriptor || d2 !is TypeParameterDescriptor) return@eq false
areTypeParametersEquivalent(d1, d2, {x, y -> x == a && y == b})
}
return overridingUtil.isOverridableBy(a, b).getResult() == OverrideCompatibilityInfo.Result.OVERRIDABLE
&& overridingUtil.isOverridableBy(b, a).getResult() == OverrideCompatibilityInfo.Result.OVERRIDABLE
}
private fun ownersEquivalent(
a: DeclarationDescriptor,
b: DeclarationDescriptor,
equivalentCallables: (DeclarationDescriptor?, DeclarationDescriptor?) -> Boolean
): Boolean {
val aOwner = a.getContainingDeclaration()
val bOwner = b.getContainingDeclaration()
// This check is needed when we call areTypeParametersEquivalent() from areCallableMemberDescriptorsEquivalent:
// if the type parameter owners are, e.g., functions, we'll go into infinite recursion here
if (aOwner is CallableMemberDescriptor || bOwner is CallableMemberDescriptor) {
return equivalentCallables(aOwner, bOwner)
}
else {
return areEquivalent(aOwner, bOwner)
}
}
}
@@ -24,6 +24,7 @@ import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.LinkedMultiMap;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.hash.EqualityPolicy;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
@@ -40,6 +41,7 @@ import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.utils.HashSetUtil;
import javax.inject.Inject;
import java.util.*;
@@ -225,14 +227,37 @@ public class OverrideResolver {
@NotNull
private static <D> Set<D> filterOverrides(
@NotNull Set<D> candidateSet,
@NotNull Function<? super D, ? extends CallableDescriptor> transform,
@NotNull final Function<? super D, ? extends CallableDescriptor> transform,
@NotNull Filtering filtering
) {
if (candidateSet.size() <= 1) return candidateSet;
// In a multi-module project different "copies" of the same class may be present in different libraries,
// that's why we use structural equivalence for members (DescriptorEquivalenceForOverrides).
// Here we filter out structurally equivalent descriptors before processing overrides, because such descriptors
// "override" each other (overrides(f, g) = overrides(g, f) = true) and the code below removes them all from the
// candidates, unless we first compute noDuplicates
Set<D> noDuplicates = HashSetUtil.linkedHashSet(
candidateSet,
new EqualityPolicy<D>() {
@Override
public int getHashCode(D d) {
return DescriptorUtils.getFqName(transform.fun(d).getContainingDeclaration()).hashCode();
}
@Override
public boolean isEqual(D d1, D d2) {
CallableDescriptor f = transform.fun(d1);
CallableDescriptor g = transform.fun(d2);
return DescriptorEquivalenceForOverrides.instance$.areEquivalent(f.getOriginal(), g.getOriginal());
}
});
Set<D> candidates = Sets.newLinkedHashSet();
outerLoop:
for (D meD : candidateSet) {
for (D meD : noDuplicates) {
CallableDescriptor me = transform.fun(meD);
for (D otherD : candidateSet) {
for (D otherD : noDuplicates) {
CallableDescriptor other = transform.fun(otherD);
if (me == other) continue;
if (filtering == Filtering.RETAIN_OVERRIDING) {
@@ -259,13 +284,22 @@ public class OverrideResolver {
}
candidates.add(meD);
}
assert !candidates.isEmpty() : "All candidates filtered out from " + candidateSet;
return candidates;
}
// check whether f overrides g
public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
// This first check cover the case of duplicate classes in different modules:
// when B is defined in modules m1 and m2, and C (indirectly) inherits from both versions,
// we'll be getting sets of members that do not override each other, but are structurally equivalent.
// As other code relies on no equal descriptors passed here, we guard against f == g, but this may not be necessary
if (!f.equals(g) && DescriptorEquivalenceForOverrides.instance$.areEquivalent(f.getOriginal(), g.getOriginal())) return true;
CallableDescriptor originalG = g.getOriginal();
for (D overriddenFunction : getAllOverriddenDescriptors(f)) {
if (originalG.equals(overriddenFunction.getOriginal())) return true;
if (DescriptorEquivalenceForOverrides.instance$.areEquivalent(originalG, overriddenFunction.getOriginal())) return true;
}
return false;
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B<T> {
public fun foo(a: T)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C<X> : B<X> {
override fun foo(a: X)
}
// MODULE: m3
// FILE: b.kt
package p
public trait B<T> {
public fun foo(a: T)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B<String>?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo("")
}
}
@@ -0,0 +1,38 @@
// !DIAGNOSTICS: -BASE_WITH_NULLABLE_UPPER_BOUND -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B<T> {
public fun foo(a: T?)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C<X> : B<X> {
override fun foo(a: X?)
}
// MODULE: m3
// FILE: b.kt
package p
public trait Tr
public trait B<T: Tr?> {
public fun foo(a: T?)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B<Tr>?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo(null)
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -BASE_WITH_NULLABLE_UPPER_BOUND
// MODULE: m1
// FILE: a.kt
package p
public trait B<T, _> {
public fun foo(a: T?)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C<X, _> : B<X, _> {
override fun foo(a: X?)
}
// MODULE: m3
// FILE: b.kt
package p
public trait B<_, T> {
public fun foo(a: T?)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun <Y, Z> test(b: B<Y, Z>?) {
if (b is C<Y, Z>) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null)
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B<T> {
public fun foo(a: T)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C<X> : B<X> {
override fun foo(a: X)
}
// MODULE: m3
// FILE: b.kt
package p
public trait B<T1> {
public fun foo(a: T1)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun <Y> test(b: B<Y>?, y: Y) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo(y)
}
}
@@ -0,0 +1,36 @@
// MODULE: m1
// FILE: a.kt
package p
public trait B<T> {
public fun <R> foo(a: T, b : R)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B<Any?> {
override fun <R> foo(a: Any?, b : R)
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun <T, R> foo(a: T, b: R)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?, c: C) {
b?.foo(1, 1)
c.foo(1, 1)
if (b is C) {
b?.<!CANNOT_COMPLETE_RESOLVE!>foo<!>(1, 1)
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun foo(a: Int, b: String): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun foo(a: Int, b: String): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun foo(a1: Int, b1: String): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo(1, "")
}
}
@@ -0,0 +1,43 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m0
// FILE: a.kt
package p
public trait G1<T>
public trait G2<A, B>
// MODULE: m1(m0)
// FILE: a.kt
package p
public trait B {
public fun foo(a: G1<Int>?, b: G2<B, String>?)
}
// MODULE: m2(m1, m0)
// FILE: b.kt
package p
public trait C : B {
override fun foo(a: G1<Int>?, b: G2<B, String>?)
}
// MODULE: m3(m0)
// FILE: b.kt
package p
public trait B {
public fun foo(a: G1<out Any?>?, b: G2<Int, out Any?>?)
}
// MODULE: m4(m3, m2, m0)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(null, null)
}
}
@@ -0,0 +1,34 @@
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun foo(a: Int, b: String): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun foo(a: Int, b: String): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun foo(a: Int, b: String, c: Int = 0): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(1, "")
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun getParent(): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun getParent(): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun getParent(): Int
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.getParent()
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun String.getParent(): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public class C : B {
override fun String.getParent(): B? = null
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun String.getParent(): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun B.test() {
if (this is C) {
"".getParent()
}
}
@@ -0,0 +1,42 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun <T> foo(a: T): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo<String>("")
}
}
fun test1(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo("")
}
}
@@ -0,0 +1,40 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun <T> foo(a: T): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait Tr
public trait B {
public fun <T: Tr?> foo(a: T): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
// hard to find parameters for an ambiguous call, so we rely on NONE_APPLICABLE here
// as opposed to diagnostics for a single unmatched candidate
b?.<!NONE_APPLICABLE!>foo<!>()
}
}
@@ -0,0 +1,52 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun <T> foo(a: T): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b == null) return
b?.foo<String>("")
}
fun test1(b: B?) {
if (b != null) {
b?.foo<String>("")
}
}
fun test2(b: B?) {
if (b == null) return
b?.foo("")
}
fun test3(b: B?) {
if (b != null) {
b?.foo("")
}
}
@@ -0,0 +1,40 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun <T> foo(a: T): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun <T> foo(a: T): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b !is C) return
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo("")
}
fun test1(b: B?) {
if (b !is C) return
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo<String>("")
}
@@ -0,0 +1,35 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun foo(a: Int, b: String): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun foo(a: Int, b: String): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun foo(a: Int, b: String): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo(1, "")
}
}
@@ -0,0 +1,36 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun getParent(): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public class C : B {
override fun getParent(): B? = null
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun getParent(): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.getParent()
}
}
@@ -0,0 +1,43 @@
// !DIAGNOSTICS: -UNNECESSARY_SAFE_CALL
// MODULE: m0
// FILE: a.kt
package p
public trait G1<T>
public trait G2<A, B>
// MODULE: m1(m0)
// FILE: a.kt
package p
public trait B {
public fun foo(a: G1<Int>, b: G2<B, String>): B?
}
// MODULE: m2(m1, m0)
// FILE: b.kt
package p
public trait C : B {
override fun foo(a: G1<Int>, b: G2<B, String>): B?
}
// MODULE: m3(m0)
// FILE: b.kt
package p
public trait B {
public fun foo(a: G1<Int>, b: G2<B, String>): B?
}
// MODULE: m4(m3, m2, m0)
// FILE: c.kt
import p.*
fun test(b: B?, a: G1<Int>, b1: G2<B, String>) {
if (b is C) {
<!DEBUG_INFO_AUTOCAST!>b<!>?.foo(a, b1)
}
}
@@ -0,0 +1,38 @@
// MODULE: m1
// FILE: a.kt
package p
public trait B {
public fun getParent(): B?
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B {
override fun getParent(): B?
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun getParent(): B?
}
public trait D : B {
override fun getParent(): B?
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C && b is D) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>getParent<!>()
}
}
@@ -0,0 +1,34 @@
// MODULE: m1
// FILE: a.kt
package p
public trait B<T> {
public fun foo(a: T)
}
// MODULE: m2(m1)
// FILE: b.kt
package p
public trait C : B<String> {
override fun foo(a: String)
}
// MODULE: m3
// FILE: b.kt
package p
public trait B {
public fun foo(a: String)
}
// MODULE: m4(m3, m2)
// FILE: c.kt
import p.*
fun test(b: B?) {
if (b is C) {
b?.<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>("")
}
}
@@ -0,0 +1,31 @@
// MODULE: m1
// FILE: x.kt
package p
public trait Base {
public fun foo() {}
}
public trait A : Base {
override fun foo() {}
}
public trait C : A
// MODULE: m2
// FILE: x.kt
package p
public trait Base {
public fun foo() {}
}
public trait B : Base
// MODULE: m3(m1, m2)
// FILE: x.kt
import p.*
class Foo: C, B
@@ -0,0 +1,26 @@
// MODULE: m1
// FILE: x.kt
package p
public trait Base {
public fun foo() {}
}
public trait A : Base
// MODULE: m2
// FILE: x.kt
package p
public trait Base {
public fun foo() {}
}
public trait B : Base
// MODULE: m3(m1, m2)
// FILE: x.kt
import p.*
class Foo: A, B
@@ -0,0 +1,29 @@
// MODULE: m1
// FILE: x.kt
package p
public trait Base {
public fun <T> foo(t: Array<T>) {}
}
public trait A : Base
// MODULE: m2
// FILE: x.kt
package p
public trait Base {
public fun <T: Base> foo(t: Array<T>) {}
}
public trait B : Base
// MODULE: m3(m1, m2)
// FILE: x.kt
import p.*
class Foo: A, B {
override fun <T> foo(t: Array<T>) {}
override fun <T: Base> foo(t: Array<T>) {}
}
@@ -0,0 +1,26 @@
// MODULE: m1
// FILE: x.kt
package p
public trait Base<T> {
public fun foo(t: T) {}
}
public trait A<T> : Base<T>
// MODULE: m2
// FILE: x.kt
package p
public trait Base<T> {
public fun foo(t: T) {}
}
public trait B : Base<String>
// MODULE: m3(m1, m2)
// FILE: x.kt
import p.*
class Foo: A<String>, B
@@ -4687,7 +4687,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
}
@TestMetadata("compiler/testData/diagnostics/tests/multimodule")
@InnerTestClasses({Multimodule.DuplicateClass.class})
@InnerTestClasses({Multimodule.DuplicateClass.class, Multimodule.DuplicateMethod.class, Multimodule.DuplicateSuper.class})
public static class Multimodule extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInMultimodule() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -4771,10 +4771,143 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
}
@TestMetadata("compiler/testData/diagnostics/tests/multimodule/duplicateMethod")
public static class DuplicateMethod extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInDuplicateMethod() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/multimodule/duplicateMethod"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("classGenericsInParams.kt")
public void testClassGenericsInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParams.kt");
}
@TestMetadata("classGenericsInParamsBoundMismatch.kt")
public void testClassGenericsInParamsBoundMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsBoundMismatch.kt");
}
@TestMetadata("classGenericsInParamsIndexMismatch.kt")
public void testClassGenericsInParamsIndexMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsIndexMismatch.kt");
}
@TestMetadata("classGenericsInParamsNameMismatch.kt")
public void testClassGenericsInParamsNameMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classGenericsInParamsNameMismatch.kt");
}
@TestMetadata("classVsFunctionGenericsInParamsMismatch.kt")
public void testClassVsFunctionGenericsInParamsMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/classVsFunctionGenericsInParamsMismatch.kt");
}
@TestMetadata("differenceInParamNames.kt")
public void testDifferenceInParamNames() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/differenceInParamNames.kt");
}
@TestMetadata("differentGenericsInParams.kt")
public void testDifferentGenericsInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/differentGenericsInParams.kt");
}
@TestMetadata("differentNumberOfParams.kt")
public void testDifferentNumberOfParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/differentNumberOfParams.kt");
}
@TestMetadata("differentReturnTypes.kt")
public void testDifferentReturnTypes() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/differentReturnTypes.kt");
}
@TestMetadata("extensionMatch.kt")
public void testExtensionMatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/extensionMatch.kt");
}
@TestMetadata("functionGenericsInParams.kt")
public void testFunctionGenericsInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParams.kt");
}
@TestMetadata("functionGenericsInParamsBoundsMismatch.kt")
public void testFunctionGenericsInParamsBoundsMismatch() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsBoundsMismatch.kt");
}
@TestMetadata("functionGenericsInParamsEqNull.kt")
public void testFunctionGenericsInParamsEqNull() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsEqNull.kt");
}
@TestMetadata("functionGenericsInParamsNotIs.kt")
public void testFunctionGenericsInParamsNotIs() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/functionGenericsInParamsNotIs.kt");
}
@TestMetadata("noGenericsInParams.kt")
public void testNoGenericsInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/noGenericsInParams.kt");
}
@TestMetadata("noParams.kt")
public void testNoParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/noParams.kt");
}
@TestMetadata("sameGenericsInParams.kt")
public void testSameGenericsInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/sameGenericsInParams.kt");
}
@TestMetadata("simpleWithInheritance.kt")
public void testSimpleWithInheritance() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/simpleWithInheritance.kt");
}
@TestMetadata("substitutedGenericInParams.kt")
public void testSubstitutedGenericInParams() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateMethod/substitutedGenericInParams.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/multimodule/duplicateSuper")
public static class DuplicateSuper extends AbstractJetDiagnosticsTest {
public void testAllFilesPresentInDuplicateSuper() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/multimodule/duplicateSuper"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("differentSuperTraits.kt")
public void testDifferentSuperTraits() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateSuper/differentSuperTraits.kt");
}
@TestMetadata("sameSuperTrait.kt")
public void testSameSuperTrait() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateSuper/sameSuperTrait.kt");
}
@TestMetadata("sameSuperTraitDifferentBounds.kt")
public void testSameSuperTraitDifferentBounds() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateSuper/sameSuperTraitDifferentBounds.kt");
}
@TestMetadata("sameSuperTraitGenerics.kt")
public void testSameSuperTraitGenerics() throws Exception {
doTest("compiler/testData/diagnostics/tests/multimodule/duplicateSuper/sameSuperTraitGenerics.kt");
}
}
public static Test innerSuite() {
TestSuite suite = new TestSuite("Multimodule");
suite.addTestSuite(Multimodule.class);
suite.addTestSuite(DuplicateClass.class);
suite.addTestSuite(DuplicateMethod.class);
suite.addTestSuite(DuplicateSuper.class);
return suite;
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.utils;
import com.intellij.util.containers.hash.EqualityPolicy;
import com.intellij.util.containers.hash.LinkedHashMap;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Set;
public class HashSetUtil {
@NotNull
public static <T> Set<T> linkedHashSet(@NotNull Set<T> set, @NotNull EqualityPolicy<T> policy) {
// this implementation of LinkedHashMap doesn't admit nulls as values
Map<T, String> map = new LinkedHashMap<T, String>(policy);
for (T t : set) {
map.put(t, "");
}
return map.keySet();
}
}