Fixed auto-import of operator functions broken before + fixed bug in its implementation
This commit is contained in:
@@ -84,8 +84,6 @@ public class ReferenceVariantsHelper(
|
|||||||
val pair = getExplicitReceiverData(expression)
|
val pair = getExplicitReceiverData(expression)
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
val (receiverExpression, callType) = pair
|
val (receiverExpression, callType) = pair
|
||||||
fun filterIfInfix(descriptor: DeclarationDescriptor)
|
|
||||||
= if (callType == CallType.INFIX) descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size == 1 else true
|
|
||||||
|
|
||||||
// Process as call expression
|
// Process as call expression
|
||||||
val descriptors = HashSet<DeclarationDescriptor>()
|
val descriptors = HashSet<DeclarationDescriptor>()
|
||||||
@@ -93,7 +91,7 @@ public class ReferenceVariantsHelper(
|
|||||||
val qualifier = context[BindingContext.QUALIFIER, receiverExpression]
|
val qualifier = context[BindingContext.QUALIFIER, receiverExpression]
|
||||||
if (qualifier != null) {
|
if (qualifier != null) {
|
||||||
// It's impossible to add extension function for package or class (if it's class object, expression type is not null)
|
// It's impossible to add extension function for package or class (if it's class object, expression type is not null)
|
||||||
qualifier.scope.getDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.Extensions, nameFilter).filterTo(descriptors, ::filterIfInfix)
|
qualifier.scope.getDescriptorsFiltered(kindFilter exclude DescriptorKindExclude.Extensions, nameFilter).filterTo(descriptors) { callType.canCall(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val expressionType = if (shouldCastToRuntimeType)
|
val expressionType = if (shouldCastToRuntimeType)
|
||||||
@@ -106,7 +104,7 @@ public class ReferenceVariantsHelper(
|
|||||||
|
|
||||||
val mask = kindFilter.withoutKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK).exclude(DescriptorKindExclude.Extensions)
|
val mask = kindFilter.withoutKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK).exclude(DescriptorKindExclude.Extensions)
|
||||||
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, dataFlowInfo)) {
|
for (variant in SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, dataFlowInfo)) {
|
||||||
variant.getMemberScope().getDescriptorsFiltered(mask, nameFilter).filterTo(descriptors, ::filterIfInfix)
|
variant.getMemberScope().getDescriptorsFiltered(mask, nameFilter).filterTo(descriptors) { callType.canCall(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter)
|
descriptors.addCallableExtensions(resolutionScope, receiverValue, dataFlowInfo, callType, kindFilter, nameFilter)
|
||||||
@@ -204,6 +202,8 @@ public class ReferenceVariantsHelper(
|
|||||||
CallType.NORMAL
|
CallType.NORMAL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is JetUnaryExpression -> CallType.UNARY
|
||||||
|
|
||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
return receiverExpression to callType
|
return receiverExpression to callType
|
||||||
|
|||||||
@@ -24,11 +24,23 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope
|
|||||||
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils
|
import org.jetbrains.jet.lang.resolve.calls.smartcasts.SmartCastUtils
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils
|
import org.jetbrains.jet.lang.types.TypeUtils
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||||
|
|
||||||
public enum class CallType {
|
public enum class CallType {
|
||||||
NORMAL
|
NORMAL
|
||||||
SAFE
|
SAFE
|
||||||
INFIX
|
|
||||||
|
INFIX {
|
||||||
|
override fun canCall(descriptor: DeclarationDescriptor)
|
||||||
|
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
UNARY {
|
||||||
|
override fun canCall(descriptor: DeclarationDescriptor)
|
||||||
|
= descriptor is SimpleFunctionDescriptor && descriptor.getValueParameters().size == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public open fun canCall(descriptor: DeclarationDescriptor): Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun CallableDescriptor.substituteExtensionIfCallable(receivers: Collection<ReceiverValue>,
|
public fun CallableDescriptor.substituteExtensionIfCallable(receivers: Collection<ReceiverValue>,
|
||||||
@@ -54,10 +66,7 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
|
|||||||
dataFlowInfo: DataFlowInfo
|
dataFlowInfo: DataFlowInfo
|
||||||
): Collection<CallableDescriptor> {
|
): Collection<CallableDescriptor> {
|
||||||
if (!receiver.exists()) return listOf()
|
if (!receiver.exists()) return listOf()
|
||||||
|
if (!callType.canCall(this)) return listOf()
|
||||||
if (callType == CallType.INFIX && (this !is SimpleFunctionDescriptor || getValueParameters().size() != 1)) {
|
|
||||||
return listOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, dataFlowInfo).stream()
|
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, dataFlowInfo).stream()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// "Import" "false"
|
||||||
|
// ACTION: Create function 'inc'
|
||||||
|
// ACTION: Create local variable '++'
|
||||||
|
// ACTION: Create parameter '++'
|
||||||
|
// ACTION: Inspection 'UNUSED_CHANGED_VALUE' options
|
||||||
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
// ERROR: Unresolved reference: ++
|
||||||
|
|
||||||
|
package h
|
||||||
|
|
||||||
|
trait H
|
||||||
|
|
||||||
|
fun f(h: H?) {
|
||||||
|
var h1 = h
|
||||||
|
h1<caret>++
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
fun h.H.inc(p: Int): h.H {
|
||||||
|
}
|
||||||
@@ -86,6 +86,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
doTestWithExtraFile(fileName);
|
doTestWithExtraFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("falsePostfixOperator.before.Main.kt")
|
||||||
|
public void testFalsePostfixOperator() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/falsePostfixOperator.before.Main.kt");
|
||||||
|
doTestWithExtraFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionImport.before.Main.kt")
|
@TestMetadata("functionImport.before.Main.kt")
|
||||||
public void testFunctionImport() throws Exception {
|
public void testFunctionImport() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/functionImport.before.Main.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/functionImport.before.Main.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user