extensionsUtils.kt uses FuzzyType + more correct treatment of receiver nullability there
This commit is contained in:
+32
-35
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.types.TypeUtils
|
||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lexer.JetTokens
|
||||
import org.jetbrains.jet.plugin.util.CallType
|
||||
import org.jetbrains.jet.plugin.util.substituteExtensionIfCallable
|
||||
|
||||
public class ReferenceVariantsHelper(
|
||||
@@ -43,12 +44,6 @@ public class ReferenceVariantsHelper(
|
||||
private val visibilityFilter: (DeclarationDescriptor) -> Boolean
|
||||
) {
|
||||
|
||||
public enum class CallType {
|
||||
NORMAL
|
||||
INFIX
|
||||
SAFE
|
||||
}
|
||||
|
||||
public data class ReceiversData(
|
||||
public val receivers: Collection<ReceiverValue>,
|
||||
public val callType: CallType
|
||||
@@ -114,7 +109,7 @@ public class ReferenceVariantsHelper(
|
||||
variant.getMemberScope().getDescriptorsFiltered(mask, nameFilter).filterTo(descriptors, ::filterIfInfix)
|
||||
}
|
||||
|
||||
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType == CallType.INFIX, kindFilter, nameFilter)
|
||||
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter)
|
||||
}
|
||||
|
||||
return descriptors
|
||||
@@ -132,7 +127,7 @@ public class ReferenceVariantsHelper(
|
||||
|
||||
for (descriptor in resolutionScope.getDescriptorsFiltered(kindFilter, nameFilter)) {
|
||||
if (descriptor is CallableDescriptor && descriptor.getExtensionReceiverParameter() != null) {
|
||||
descriptorsSet.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, false))
|
||||
descriptorsSet.addAll(descriptor.substituteExtensionIfCallable(receiverValues, context, dataFlowInfo, CallType.NORMAL))
|
||||
}
|
||||
else {
|
||||
descriptorsSet.add(descriptor)
|
||||
@@ -165,42 +160,17 @@ public class ReferenceVariantsHelper(
|
||||
return type
|
||||
}
|
||||
|
||||
private fun getReferenceVariantsReceiver(expression: JetSimpleNameExpression): Pair<JetExpression, CallType>? {
|
||||
val receiverExpression = expression.getReceiverExpression() ?: return null
|
||||
val parent = expression.getParent()
|
||||
val callType = when (parent) {
|
||||
is JetBinaryExpression -> CallType.INFIX
|
||||
|
||||
is JetCallExpression -> {
|
||||
if ((parent.getParent() as JetQualifiedExpression).getOperationSign() == JetTokens.SAFE_ACCESS)
|
||||
CallType.SAFE
|
||||
else
|
||||
CallType.NORMAL
|
||||
}
|
||||
|
||||
is JetQualifiedExpression -> {
|
||||
if (parent.getOperationSign() == JetTokens.SAFE_ACCESS)
|
||||
CallType.SAFE
|
||||
else
|
||||
CallType.NORMAL
|
||||
}
|
||||
|
||||
else -> return null
|
||||
}
|
||||
return receiverExpression to callType
|
||||
}
|
||||
|
||||
private fun MutableCollection<DeclarationDescriptor>.addCallableExtensions(
|
||||
resolutionScope: JetScope,
|
||||
receiver: ReceiverValue,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
isInfixCall: Boolean,
|
||||
callType: CallType,
|
||||
kindFilter: DescriptorKindFilter,
|
||||
nameFilter: (Name) -> Boolean
|
||||
) {
|
||||
if (!kindFilter.excludes.contains(DescriptorKindExclude.Extensions)) {
|
||||
for (callable in resolutionScope.getDescriptorsFiltered(kindFilter.exclude(DescriptorKindExclude.NonExtensions), nameFilter)) {
|
||||
addAll((callable as CallableDescriptor).substituteExtensionIfCallable(receiver, isInfixCall, context, dataFlowInfo))
|
||||
addAll((callable as CallableDescriptor).substituteExtensionIfCallable(receiver, callType, context, dataFlowInfo))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,4 +182,31 @@ public class ReferenceVariantsHelper(
|
||||
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
|
||||
return resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.PACKAGES, nameFilter).filter(visibilityFilter)
|
||||
}
|
||||
|
||||
class object {
|
||||
public fun getReferenceVariantsReceiver(expression: JetSimpleNameExpression): Pair<JetExpression, CallType>? {
|
||||
val receiverExpression = expression.getReceiverExpression() ?: return null
|
||||
val parent = expression.getParent()
|
||||
val callType = when (parent) {
|
||||
is JetBinaryExpression -> CallType.INFIX
|
||||
|
||||
is JetCallExpression -> {
|
||||
if ((parent.getParent() as JetQualifiedExpression).getOperationSign() == JetTokens.SAFE_ACCESS)
|
||||
CallType.SAFE
|
||||
else
|
||||
CallType.NORMAL
|
||||
}
|
||||
|
||||
is JetQualifiedExpression -> {
|
||||
if (parent.getOperationSign() == JetTokens.SAFE_ACCESS)
|
||||
CallType.SAFE
|
||||
else
|
||||
CallType.NORMAL
|
||||
}
|
||||
|
||||
else -> return null
|
||||
}
|
||||
return receiverExpression to callType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@ import java.util.LinkedHashMap
|
||||
import org.jetbrains.jet.lang.types.Variance
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil
|
||||
import org.jetbrains.jet.plugin.util.makeNotNullable
|
||||
import org.jetbrains.jet.plugin.util.makeNullable
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor
|
||||
import org.jetbrains.jet.lang.types.typeUtil.isSubtypeOf
|
||||
|
||||
@@ -36,7 +34,6 @@ fun CallableDescriptor.fuzzyReturnType(): FuzzyType? {
|
||||
return FuzzyType(returnType, getTypeParameters())
|
||||
}
|
||||
|
||||
//TODO: replace code in extensionsUtils.kt with use of FuzzyType
|
||||
fun CallableDescriptor.fuzzyExtensionReceiverType(): FuzzyType? {
|
||||
val receiverParameter = getExtensionReceiverParameter()
|
||||
return if (receiverParameter != null) FuzzyType(receiverParameter.getType(), getTypeParameters()) else null
|
||||
@@ -64,10 +61,30 @@ class FuzzyType(
|
||||
}
|
||||
}
|
||||
|
||||
public fun matchedSubstitutor(expectedType: JetType): TypeSubstitutor? {
|
||||
public fun checkIsSubtypeOf(otherType: JetType): TypeSubstitutor?
|
||||
= matchedSubstitutor(otherType, MatchKind.IS_SUBTYPE)
|
||||
|
||||
public fun checkIsSuperTypeOf(otherType: JetType): TypeSubstitutor?
|
||||
= matchedSubstitutor(otherType, MatchKind.IS_SUPERTYPE)
|
||||
|
||||
private enum class MatchKind {
|
||||
IS_SUBTYPE
|
||||
IS_SUPERTYPE
|
||||
}
|
||||
|
||||
private fun matchedSubstitutor(otherType: JetType, matchKind: MatchKind): TypeSubstitutor? {
|
||||
if (type.isError()) return null
|
||||
if (otherType.isError()) return null
|
||||
|
||||
fun JetType.checkInheritance(otherType: JetType): Boolean {
|
||||
return when (matchKind) {
|
||||
MatchKind.IS_SUBTYPE -> this.isSubtypeOf(otherType)
|
||||
MatchKind.IS_SUPERTYPE -> otherType.isSubtypeOf(this)
|
||||
}
|
||||
}
|
||||
|
||||
if (usedTypeParameters == null || usedTypeParameters.isEmpty()) {
|
||||
return if (type.isSubtypeOf(expectedType)) TypeSubstitutor.EMPTY else null
|
||||
return if (type.checkInheritance(otherType)) TypeSubstitutor.EMPTY else null
|
||||
}
|
||||
|
||||
val constraintSystem = ConstraintSystemImpl()
|
||||
@@ -79,11 +96,15 @@ class FuzzyType(
|
||||
}
|
||||
constraintSystem.registerTypeVariables(typeVariables)
|
||||
|
||||
constraintSystem.addSubtypeConstraint(type, expectedType, ConstraintPosition.SPECIAL/*TODO?*/)
|
||||
when (matchKind) {
|
||||
MatchKind.IS_SUBTYPE -> constraintSystem.addSubtypeConstraint(type, otherType, ConstraintPosition.SPECIAL)
|
||||
MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType, type, ConstraintPosition.SPECIAL)
|
||||
}
|
||||
|
||||
if (constraintSystem.getStatus().isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, true)) {
|
||||
val substitutor = constraintSystem.getResultingSubstitutor()
|
||||
val substitutedType = substitutor.substitute(type, Variance.INVARIANT/*TODO?*/)
|
||||
return if (substitutedType.isSubtypeOf(expectedType)) substitutor else null
|
||||
val substitutedType = substitutor.substitute(type, Variance.INVARIANT)
|
||||
return if (substitutedType != null && substitutedType.checkInheritance(otherType)) substitutor else null
|
||||
}
|
||||
else {
|
||||
return null
|
||||
|
||||
@@ -23,23 +23,19 @@ import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils
|
||||
import org.jetbrains.jet.lang.types.JetType
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl
|
||||
import java.util.LinkedHashMap
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.jet.lang.types.Variance
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition
|
||||
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil
|
||||
import org.jetbrains.jet.utils.addIfNotNull
|
||||
import java.util.HashSet
|
||||
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor
|
||||
import org.jetbrains.jet.lang.types.TypeUtils
|
||||
|
||||
public enum class CallType {
|
||||
NORMAL
|
||||
SAFE
|
||||
INFIX
|
||||
}
|
||||
|
||||
public fun CallableDescriptor.substituteExtensionIfCallable(receivers: Collection<ReceiverValue>,
|
||||
context: BindingContext,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
isInfixCall: Boolean): Collection<CallableDescriptor> {
|
||||
val stream = receivers.stream().flatMap { substituteExtensionIfCallable(it, isInfixCall, context, dataFlowInfo).stream() }
|
||||
callType: CallType): Collection<CallableDescriptor> {
|
||||
val stream = receivers.stream().flatMap { substituteExtensionIfCallable(it, callType, context, dataFlowInfo).stream() }
|
||||
if (getTypeParameters().isEmpty()) { // optimization for non-generic callables
|
||||
return stream.firstOrNull()?.let { listOf(it) } ?: listOf()
|
||||
}
|
||||
@@ -49,24 +45,36 @@ public fun CallableDescriptor.substituteExtensionIfCallable(receivers: Collectio
|
||||
}
|
||||
|
||||
public fun CallableDescriptor.substituteExtensionIfCallableWithImplicitReceiver(scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection<CallableDescriptor>
|
||||
= substituteExtensionIfCallable(scope.getImplicitReceiversHierarchy().map { it.getValue() }, context, dataFlowInfo, false)
|
||||
= substituteExtensionIfCallable(scope.getImplicitReceiversHierarchy().map { it.getValue() }, context, dataFlowInfo, CallType.NORMAL)
|
||||
|
||||
public fun CallableDescriptor.substituteExtensionIfCallable(
|
||||
receiver: ReceiverValue,
|
||||
isInfixCall: Boolean,
|
||||
callType: CallType,
|
||||
bindingContext: BindingContext,
|
||||
dataFlowInfo: DataFlowInfo
|
||||
): Collection<CallableDescriptor> {
|
||||
val receiverParameter = getExtensionReceiverParameter()!!
|
||||
if (!receiver.exists()) return listOf()
|
||||
|
||||
if (isInfixCall && (this !is SimpleFunctionDescriptor || getValueParameters().size() != 1)) {
|
||||
if (callType == CallType.INFIX && (this !is SimpleFunctionDescriptor || getValueParameters().size() != 1)) {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
val substitutors = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, dataFlowInfo)
|
||||
.stream()
|
||||
.map { checkReceiverResolution(it, receiverParameter, getTypeParameters()) }
|
||||
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, dataFlowInfo).stream()
|
||||
|
||||
if (callType == CallType.SAFE) {
|
||||
types = types.map { it.makeNotNullable() }
|
||||
}
|
||||
|
||||
val extensionReceiverType = fuzzyExtensionReceiverType()!!
|
||||
val substitutors = types
|
||||
.map {
|
||||
var substitutor = extensionReceiverType.checkIsSuperTypeOf(it)
|
||||
// check if we may fail due to receiver expression being nullable
|
||||
if (substitutor == null && TypeUtils.isNullableType(it) && !TypeUtils.isNullableType(extensionReceiverType.type)) {
|
||||
substitutor = extensionReceiverType.checkIsSuperTypeOf(it.makeNotNullable())
|
||||
}
|
||||
substitutor
|
||||
}
|
||||
.filterNotNull()
|
||||
if (getTypeParameters().isEmpty()) { // optimization for non-generic callables
|
||||
return if (substitutors.any()) listOf(this) else listOf()
|
||||
@@ -76,38 +84,3 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkReceiverResolution(
|
||||
receiverType: JetType,
|
||||
receiverParameter: ReceiverParameterDescriptor,
|
||||
typeParameters: List<TypeParameterDescriptor>
|
||||
): TypeSubstitutor? {
|
||||
val typeParamsInReceiver = HashSet<TypeParameterDescriptor>()
|
||||
typeParamsInReceiver.addUsedTypeParameters(receiverParameter.getType())
|
||||
|
||||
val constraintSystem = ConstraintSystemImpl()
|
||||
val typeVariables = LinkedHashMap<TypeParameterDescriptor, Variance>()
|
||||
for (typeParameter in typeParameters) {
|
||||
if (typeParamsInReceiver.contains(typeParameter)) {
|
||||
typeVariables[typeParameter] = Variance.INVARIANT
|
||||
}
|
||||
}
|
||||
constraintSystem.registerTypeVariables(typeVariables)
|
||||
|
||||
constraintSystem.addSubtypeConstraint(receiverType, receiverParameter.getType(), ConstraintPosition.RECEIVER_POSITION)
|
||||
|
||||
if (constraintSystem.getStatus().isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, true)) {
|
||||
return constraintSystem.getResultingSubstitutor()
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableSet<TypeParameterDescriptor>.addUsedTypeParameters(jetType: JetType) {
|
||||
addIfNotNull(jetType.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor)
|
||||
|
||||
for (argument in jetType.getArguments()) {
|
||||
addUsedTypeParameters(argument.getType())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import org.jetbrains.jet.lang.psi.*
|
||||
import org.jetbrains.jet.lang.resolve.*
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.util.HashSet
|
||||
@@ -36,6 +35,8 @@ import org.jetbrains.jet.lang.resolve.calls.smartcasts.DataFlowInfo
|
||||
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||
import org.jetbrains.jet.plugin.caches.resolve.ResolutionFacade
|
||||
import org.jetbrains.jet.plugin.util.substituteExtensionIfCallable
|
||||
import org.jetbrains.jet.plugin.util.CallType
|
||||
import org.jetbrains.jet.plugin.codeInsight.ReferenceVariantsHelper
|
||||
|
||||
public class KotlinIndicesHelper(
|
||||
private val project: Project,
|
||||
@@ -110,9 +111,9 @@ public class KotlinIndicesHelper(
|
||||
dataFlowInfo: DataFlowInfo) {
|
||||
val matchingNames = fqNames.filter { nameFilter(it.shortName().asString()) }
|
||||
|
||||
val receiverExpression = expression.getReceiverExpression()
|
||||
if (receiverExpression != null) {
|
||||
val isInfixCall = expression.getParent() is JetBinaryExpression
|
||||
val receiverPair = ReferenceVariantsHelper.getReferenceVariantsReceiver(expression)
|
||||
if (receiverPair != null) {
|
||||
val (receiverExpression, callType) = receiverPair
|
||||
|
||||
val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE, receiverExpression]
|
||||
if (expressionType == null || expressionType.isError()) return
|
||||
@@ -122,7 +123,7 @@ public class KotlinIndicesHelper(
|
||||
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
|
||||
|
||||
matchingNames.flatMapTo(this) {
|
||||
findSuitableExtensions(it, index, receiverValue, dataFlowInfo, isInfixCall, resolutionScope, moduleDescriptor, bindingContext)
|
||||
findSuitableExtensions(it, index, receiverValue, dataFlowInfo, callType, resolutionScope, moduleDescriptor, bindingContext)
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -130,7 +131,7 @@ public class KotlinIndicesHelper(
|
||||
|
||||
for (receiver in resolutionScope.getImplicitReceiversHierarchy()) {
|
||||
matchingNames.flatMapTo(this) {
|
||||
findSuitableExtensions(it, index, receiver.getValue(), dataFlowInfo, false, resolutionScope, moduleDescriptor, bindingContext)
|
||||
findSuitableExtensions(it, index, receiver.getValue(), dataFlowInfo, CallType.NORMAL, resolutionScope, moduleDescriptor, bindingContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,7 +144,7 @@ public class KotlinIndicesHelper(
|
||||
index: StringStubIndexExtension<out JetCallableDeclaration>?,
|
||||
receiverValue: ReceiverValue,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
isInfixCall: Boolean,
|
||||
callType: CallType,
|
||||
resolutionScope: JetScope,
|
||||
module: ModuleDescriptor,
|
||||
bindingContext: BindingContext): Stream<CallableDescriptor> {
|
||||
@@ -162,7 +163,7 @@ public class KotlinIndicesHelper(
|
||||
|
||||
return descriptors.stream()
|
||||
.filter(visibilityFilter)
|
||||
.flatMap { it.substituteExtensionIfCallable(receiverValue, isInfixCall, bindingContext, dataFlowInfo).stream() }
|
||||
.flatMap { it.substituteExtensionIfCallable(receiverValue, callType, bindingContext, dataFlowInfo).stream() }
|
||||
}
|
||||
|
||||
public fun getClassDescriptors(nameFilter: (String) -> Boolean, kindFilter: (ClassKind) -> Boolean): Collection<ClassDescriptor> {
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.jet.plugin.refactoring.comparePossiblyOverridingDescriptors
|
||||
import kotlin.properties.Delegates
|
||||
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.jet.plugin.util.makeNotNullable
|
||||
import org.jetbrains.jet.plugin.util.CallType
|
||||
|
||||
class CompletionSessionConfiguration(
|
||||
val completeNonImportedDeclarations: Boolean,
|
||||
@@ -80,7 +81,7 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
|
||||
var receiverTypes = receivers.flatMap {
|
||||
SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(it, bindingContext, dataFlowInfo)
|
||||
}
|
||||
if (callType == ReferenceVariantsHelper.CallType.SAFE) {
|
||||
if (callType == CallType.SAFE) {
|
||||
receiverTypes = receiverTypes.map { it.makeNotNullable() }
|
||||
}
|
||||
receiverTypes
|
||||
|
||||
@@ -129,12 +129,12 @@ class SmartCompletion(val expression: JetSimpleNameExpression,
|
||||
val result = ArrayList<LookupElement>()
|
||||
val types = descriptor.fuzzyTypes(smartCastTypes)
|
||||
val classifier = { (expectedInfo: ExpectedInfo) ->
|
||||
val substitutor = types.stream().map { it.matchedSubstitutor(expectedInfo.type) }.firstOrNull()
|
||||
val substitutor = types.stream().map { it.checkIsSubtypeOf(expectedInfo.type) }.firstOrNull()
|
||||
if (substitutor != null) {
|
||||
ExpectedInfoClassification.matches(substitutor)
|
||||
}
|
||||
else {
|
||||
val substitutor2 = types.stream().map { it.makeNotNullable().matchedSubstitutor(expectedInfo.type) }.firstOrNull()
|
||||
val substitutor2 = types.stream().map { it.makeNotNullable().checkIsSubtypeOf(expectedInfo.type) }.firstOrNull()
|
||||
if (substitutor2 != null) {
|
||||
ExpectedInfoClassification.matchesIfNotNullable(substitutor2)
|
||||
}
|
||||
|
||||
@@ -111,13 +111,13 @@ class ExpectedInfoClassification private(val substitutor: TypeSubstitutor?, val
|
||||
}
|
||||
|
||||
fun FuzzyType.classifyExpectedInfo(expectedInfo: ExpectedInfo): ExpectedInfoClassification {
|
||||
val substitutor = matchedSubstitutor(expectedInfo.type)
|
||||
val substitutor = checkIsSubtypeOf(expectedInfo.type)
|
||||
if (substitutor != null) {
|
||||
return ExpectedInfoClassification.matches(substitutor)
|
||||
}
|
||||
|
||||
if (isNullable()) {
|
||||
val substitutor2 = makeNotNullable().matchedSubstitutor(expectedInfo.type)
|
||||
val substitutor2 = makeNotNullable().checkIsSubtypeOf(expectedInfo.type)
|
||||
if (substitutor2 != null) {
|
||||
return ExpectedInfoClassification.matchesIfNotNullable(substitutor2)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fun<T> T.doSomething(t: T): T = t
|
||||
|
||||
fun foo(s: String?) {
|
||||
s.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { itemText: "doSomething", tailText: "(t: String?) for T in <root>", typeText: "String?" }
|
||||
@@ -0,0 +1,7 @@
|
||||
fun<T> T.doSomething(t: T): T = t
|
||||
|
||||
fun foo(s: String?) {
|
||||
s?.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { itemText: "doSomething", tailText: "(t: String) for T in <root>", typeText: "String" }
|
||||
@@ -826,6 +826,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSignature5.kt")
|
||||
public void testSubstitutedSignature5() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubstitutedSignature5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSignature6.kt")
|
||||
public void testSubstitutedSignature6() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubstitutedSignature6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TopLevelClassCompletionInQualifiedCall.kt")
|
||||
public void testTopLevelClassCompletionInQualifiedCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/TopLevelClassCompletionInQualifiedCall.kt");
|
||||
|
||||
@@ -826,6 +826,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSignature5.kt")
|
||||
public void testSubstitutedSignature5() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubstitutedSignature5.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SubstitutedSignature6.kt")
|
||||
public void testSubstitutedSignature6() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/SubstitutedSignature6.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TopLevelClassCompletionInQualifiedCall.kt")
|
||||
public void testTopLevelClassCompletionInQualifiedCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/TopLevelClassCompletionInQualifiedCall.kt");
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.completion;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.jet.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user