Fixed duplication of some generic functions in code completion

This commit is contained in:
Valentin Kipyatkov
2015-05-08 12:07:51 +03:00
parent ce3492f270
commit 09f478fc0f
5 changed files with 48 additions and 4 deletions
@@ -97,3 +97,9 @@ public fun JetType.isArrayOfJavaLangClass(): Boolean =
KotlinBuiltIns.isArray(this) && getArguments().firstOrNull()?.getType()?.isJavaLangClass() ?: false
public fun JetType.isJavaLangClassOrArray(): Boolean = isJavaLangClass() || isArrayOfJavaLangClass()
public fun JetTypeChecker.equalTypesOrNulls(type1: JetType?, type2: JetType?): Boolean {
if (type1 identityEquals type2) return true
if (type1 == null || type2 == null) return false
return equalTypes(type1, type2)
}
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -39,6 +38,9 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.typeUtil.equalTypesOrNulls
import java.util.ArrayList
enum class ItemPriority {
@@ -144,12 +146,28 @@ fun descriptorsEqualWithSubstitution(descriptor1: DeclarationDescriptor?, descri
// optimization:
if (descriptor1 == descriptor1.getOriginal() && descriptor2 == descriptor2.getOriginal()) return true
if (descriptor1.getReturnType() != descriptor2.getReturnType()) return false
val typeChecker = JetTypeChecker.withAxioms(object: JetTypeChecker.TypeConstructorEquality {
override fun equals(a: TypeConstructor, b: TypeConstructor): Boolean {
val typeParam1 = a.getDeclarationDescriptor() as? TypeParameterDescriptor
val typeParam2 = b.getDeclarationDescriptor() as? TypeParameterDescriptor
if (typeParam1 != null
&& typeParam2 != null
&& typeParam1.getContainingDeclaration() == descriptor1
&& typeParam2.getContainingDeclaration() == descriptor2) {
return typeParam1.getIndex() == typeParam2.getIndex()
}
return a == b
}
})
if (!typeChecker.equalTypesOrNulls(descriptor1.getReturnType(), descriptor2.getReturnType())) return false
val parameters1 = descriptor1.getValueParameters()
val parameters2 = descriptor2.getValueParameters()
if (parameters1.size() != parameters2.size()) return false
for (i in parameters1.indices) {
if (parameters1[i].getType() != parameters2[i].getType()) return false
for ((param1, param2) in parameters1.zip(parameters2)) {
if (!typeChecker.equalTypes(param1.getType(), param2.getType())) return false
}
return true
}
@@ -0,0 +1,5 @@
package dependency
class MyPair<A, B>(public val first: A, public val second: B)
public fun <A, B> A.pair(that: B): MyPair<A, B> = MyPair(this, that)
@@ -0,0 +1,9 @@
// this test tests correct substitution equality checking for generic functions
import dependency.pair
fun foo() {
1 pai<caret>
}
// EXIST: pair
// NUMBER: 1
@@ -131,6 +131,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ
doTest(fileName);
}
@TestMetadata("NoGenericFunDuplication")
public void testNoGenericFunDuplication() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/NoGenericFunDuplication/");
doTest(fileName);
}
@TestMetadata("NotImportedExtensionForImplicitReceiver")
public void testNotImportedExtensionForImplicitReceiver() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/NotImportedExtensionForImplicitReceiver/");