Fix resolve (members/extensions with 'infix' has higher priority)
This commit is contained in:
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.utils.asJetScope
|
import org.jetbrains.kotlin.resolve.scopes.utils.asJetScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsFileScope
|
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsFileScope
|
||||||
|
import org.jetbrains.kotlin.resolve.validation.InfixValidator
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
@@ -138,15 +139,25 @@ public class TaskPrioritizer(
|
|||||||
) {
|
) {
|
||||||
val explicitReceiverTypeIsDynamic = explicitReceiver.value.type.isDynamic()
|
val explicitReceiverTypeIsDynamic = explicitReceiver.value.type.isDynamic()
|
||||||
|
|
||||||
// Members and extensions with 'operator' modifier have higher priority
|
fun addMembersAndExtensionsWithFilter(filter: (CallableDescriptor) -> Boolean) {
|
||||||
if (isConventionCall(c.context.call)) {
|
// If the explicit receiver is erroneous, an error function is returned by getMembersByName().
|
||||||
val filter = { d: CallableDescriptor -> (d is FunctionDescriptor && d.isOperator) || ErrorUtils.isError(d) }
|
// An error function should not be sorted out by our custom filters to prevent looking for extension functions.
|
||||||
|
if (explicitReceiver.types.any { it.isError }) return
|
||||||
|
|
||||||
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit, filter = filter)
|
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit, filter = filter)
|
||||||
if (!explicitReceiverTypeIsDynamic) {
|
if (!explicitReceiverTypeIsDynamic) {
|
||||||
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit, filter)
|
addExtensionCandidates(explicitReceiver, implicitReceivers, c, isExplicit, filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Members and extensions with 'operator' and 'infix' modifiers have higher priority
|
||||||
|
if (isConventionCall(c.context.call)) {
|
||||||
|
addMembersAndExtensionsWithFilter { d: CallableDescriptor -> d is FunctionDescriptor && d.isOperator }
|
||||||
|
}
|
||||||
|
if (InfixValidator.isInfixCall(c.context.call.calleeExpression)) {
|
||||||
|
addMembersAndExtensionsWithFilter { d: CallableDescriptor -> d is FunctionDescriptor && d.isInfix }
|
||||||
|
}
|
||||||
|
|
||||||
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit)
|
addMembers(explicitReceiver, c, staticMembers = false, isExplicit = isExplicit)
|
||||||
|
|
||||||
if (explicitReceiverTypeIsDynamic) {
|
if (explicitReceiverTypeIsDynamic) {
|
||||||
|
|||||||
+12
-4
@@ -3,26 +3,34 @@
|
|||||||
class Example
|
class Example
|
||||||
|
|
||||||
fun Example.plus(other: Example) = 0
|
fun Example.plus(other: Example) = 0
|
||||||
operator fun Example.minus(other: Example) = 0
|
operator infix fun Example.minus(other: Example) = 0
|
||||||
|
|
||||||
operator fun Example.times(other: Example) = 0
|
operator infix fun Example.times(other: Example) = 0
|
||||||
fun Example.div(other: Example) = 0
|
fun Example.div(other: Example) = 0
|
||||||
|
|
||||||
fun a() {
|
fun a() {
|
||||||
with (Example()) {
|
with (Example()) {
|
||||||
operator fun Example.plus(other: Example) = ""
|
operator infix fun Example.plus(other: Example) = ""
|
||||||
fun Example.minus(other: Example) = ""
|
fun Example.minus(other: Example) = ""
|
||||||
|
|
||||||
operator fun Example.times(other: Example) = ""
|
operator infix fun Example.times(other: Example) = ""
|
||||||
fun Example.div(other: Example) = ""
|
fun Example.div(other: Example) = ""
|
||||||
|
|
||||||
with (Example()) {
|
with (Example()) {
|
||||||
val a = Example()
|
val a = Example()
|
||||||
val b = Example()
|
val b = Example()
|
||||||
|
|
||||||
consumeString(a + b)
|
consumeString(a + b)
|
||||||
consumeInt(a - b)
|
consumeInt(a - b)
|
||||||
|
|
||||||
|
consumeString(a plus b)
|
||||||
|
consumeInt(a minus b)
|
||||||
|
|
||||||
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>*<!> b
|
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>*<!> b
|
||||||
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>/<!> b
|
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>/<!> b
|
||||||
|
|
||||||
|
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>times<!> b
|
||||||
|
a <!OVERLOAD_RESOLUTION_AMBIGUITY!>div<!> b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -5,9 +5,9 @@ public fun consumeInt(/*0*/ i: kotlin.Int): kotlin.Unit
|
|||||||
public fun consumeString(/*0*/ s: kotlin.String): kotlin.Unit
|
public fun consumeString(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
||||||
public fun Example.div(/*0*/ other: Example): kotlin.Int
|
public fun Example.div(/*0*/ other: Example): kotlin.Int
|
||||||
public operator fun Example.minus(/*0*/ other: Example): kotlin.Int
|
public operator infix fun Example.minus(/*0*/ other: Example): kotlin.Int
|
||||||
public fun Example.plus(/*0*/ other: Example): kotlin.Int
|
public fun Example.plus(/*0*/ other: Example): kotlin.Int
|
||||||
public operator fun Example.times(/*0*/ other: Example): kotlin.Int
|
public operator infix fun Example.times(/*0*/ other: Example): kotlin.Int
|
||||||
|
|
||||||
public final class Example {
|
public final class Example {
|
||||||
public constructor Example()
|
public constructor Example()
|
||||||
+15
-4
@@ -1,32 +1,43 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
class Example {
|
class Example {
|
||||||
operator fun plus(other: Example) = 0
|
operator infix fun plus(other: Example) = 0
|
||||||
fun minus(other: Example) = 0
|
fun minus(other: Example) = 0
|
||||||
|
|
||||||
operator fun times(other: Example) = 0
|
operator infix fun times(other: Example) = 0
|
||||||
fun div(other: Example) = 0
|
fun div(other: Example) = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Example.plus(other: Example) = ""
|
fun Example.plus(other: Example) = ""
|
||||||
operator fun Example.minus(other: Example) = ""
|
operator infix fun Example.minus(other: Example) = ""
|
||||||
|
|
||||||
operator fun Example.times(other: Example) = ""
|
operator infix fun Example.times(other: Example) = ""
|
||||||
fun Example.div(other: Example) = ""
|
fun Example.div(other: Example) = ""
|
||||||
|
|
||||||
fun a() {
|
fun a() {
|
||||||
val a = Example()
|
val a = Example()
|
||||||
val b = Example()
|
val b = Example()
|
||||||
|
|
||||||
a + b
|
a + b
|
||||||
a - b
|
a - b
|
||||||
a * b
|
a * b
|
||||||
a <!OPERATOR_MODIFIER_REQUIRED!>/<!> b
|
a <!OPERATOR_MODIFIER_REQUIRED!>/<!> b
|
||||||
|
|
||||||
|
a plus b
|
||||||
|
a minus b
|
||||||
|
a times b
|
||||||
|
a <!INFIX_MODIFIER_REQUIRED!>div<!> b
|
||||||
|
|
||||||
with (Example()) {
|
with (Example()) {
|
||||||
consumeInt(this + a)
|
consumeInt(this + a)
|
||||||
consumeString(this - b)
|
consumeString(this - b)
|
||||||
consumeInt(this * a)
|
consumeInt(this * a)
|
||||||
consumeInt(this <!OPERATOR_MODIFIER_REQUIRED!>/<!> b)
|
consumeInt(this <!OPERATOR_MODIFIER_REQUIRED!>/<!> b)
|
||||||
|
|
||||||
|
consumeInt(this plus a)
|
||||||
|
consumeString(this minus b)
|
||||||
|
consumeInt(this times a)
|
||||||
|
consumeInt(this <!INFIX_MODIFIER_REQUIRED!>div<!> b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+4
-4
@@ -5,9 +5,9 @@ public fun consumeInt(/*0*/ i: kotlin.Int): kotlin.Unit
|
|||||||
public fun consumeString(/*0*/ s: kotlin.String): kotlin.Unit
|
public fun consumeString(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
public fun </*0*/ T, /*1*/ R> with(/*0*/ receiver: T, /*1*/ f: T.() -> R): R
|
||||||
public fun Example.div(/*0*/ other: Example): kotlin.String
|
public fun Example.div(/*0*/ other: Example): kotlin.String
|
||||||
public operator fun Example.minus(/*0*/ other: Example): kotlin.String
|
public operator infix fun Example.minus(/*0*/ other: Example): kotlin.String
|
||||||
public fun Example.plus(/*0*/ other: Example): kotlin.String
|
public fun Example.plus(/*0*/ other: Example): kotlin.String
|
||||||
public operator fun Example.times(/*0*/ other: Example): kotlin.String
|
public operator infix fun Example.times(/*0*/ other: Example): kotlin.String
|
||||||
|
|
||||||
public final class Example {
|
public final class Example {
|
||||||
public constructor Example()
|
public constructor Example()
|
||||||
@@ -15,7 +15,7 @@ public final class Example {
|
|||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
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 hashCode(): kotlin.Int
|
||||||
public final fun minus(/*0*/ other: Example): kotlin.Int
|
public final fun minus(/*0*/ other: Example): kotlin.Int
|
||||||
public final operator fun plus(/*0*/ other: Example): kotlin.Int
|
public final operator infix fun plus(/*0*/ other: Example): kotlin.Int
|
||||||
public final operator fun times(/*0*/ other: Example): kotlin.Int
|
public final operator infix fun times(/*0*/ other: Example): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
+7
@@ -8,6 +8,8 @@ open class Example {
|
|||||||
fun component2() = 0
|
fun component2() = 0
|
||||||
|
|
||||||
fun inc() = Example()
|
fun inc() = Example()
|
||||||
|
|
||||||
|
fun plus(o: Example) = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
class Example2 : Example()
|
class Example2 : Example()
|
||||||
@@ -20,8 +22,11 @@ operator fun Example.component2() = ""
|
|||||||
|
|
||||||
operator fun Example.inc() = Example2()
|
operator fun Example.inc() = Example2()
|
||||||
|
|
||||||
|
infix fun Example.plus(o: Example) = ""
|
||||||
|
|
||||||
fun a() {
|
fun a() {
|
||||||
var a = Example()
|
var a = Example()
|
||||||
|
val b = Example()
|
||||||
|
|
||||||
consumeString(a())
|
consumeString(a())
|
||||||
consumeString(a[1])
|
consumeString(a[1])
|
||||||
@@ -31,6 +36,8 @@ fun a() {
|
|||||||
consumeString(y)
|
consumeString(y)
|
||||||
|
|
||||||
consumeExample2(++a)
|
consumeExample2(++a)
|
||||||
|
|
||||||
|
consumeString(a plus b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun consumeInt(i: Int) {}
|
fun consumeInt(i: Int) {}
|
||||||
+3
@@ -9,6 +9,7 @@ public operator fun Example.component2(): kotlin.String
|
|||||||
public operator fun Example.get(/*0*/ i: kotlin.Int): kotlin.String
|
public operator fun Example.get(/*0*/ i: kotlin.Int): kotlin.String
|
||||||
public operator fun Example.inc(): Example2
|
public operator fun Example.inc(): Example2
|
||||||
public operator fun Example.invoke(): kotlin.String
|
public operator fun Example.invoke(): kotlin.String
|
||||||
|
public infix fun Example.plus(/*0*/ o: Example): kotlin.String
|
||||||
|
|
||||||
public open class Example {
|
public open class Example {
|
||||||
public constructor Example()
|
public constructor Example()
|
||||||
@@ -19,6 +20,7 @@ public open class Example {
|
|||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public final fun inc(): Example
|
public final fun inc(): Example
|
||||||
public final fun invoke(): kotlin.Int
|
public final fun invoke(): kotlin.Int
|
||||||
|
public final fun plus(/*0*/ o: Example): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,5 +33,6 @@ public final class Example2 : Example {
|
|||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public final override /*1*/ /*fake_override*/ fun inc(): Example
|
public final override /*1*/ /*fake_override*/ fun inc(): Example
|
||||||
public final override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
|
public final override /*1*/ /*fake_override*/ fun invoke(): kotlin.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun plus(/*0*/ o: Example): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
@@ -9261,29 +9261,29 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/modifiers/operator")
|
@TestMetadata("compiler/testData/diagnostics/tests/modifiers/operatorInfix")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Operator extends AbstractJetDiagnosticsTest {
|
public static class OperatorInfix extends AbstractJetDiagnosticsTest {
|
||||||
public void testAllFilesPresentInOperator() throws Exception {
|
public void testAllFilesPresentInOperatorInfix() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/modifiers/operator"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/modifiers/operatorInfix"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("LocalFunctions.kt")
|
@TestMetadata("LocalFunctions.kt")
|
||||||
public void testLocalFunctions() throws Exception {
|
public void testLocalFunctions() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operator/LocalFunctions.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operatorInfix/LocalFunctions.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("MemberFunctions.kt")
|
@TestMetadata("MemberFunctions.kt")
|
||||||
public void testMemberFunctions() throws Exception {
|
public void testMemberFunctions() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operator/MemberFunctions.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operatorInfix/MemberFunctions.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("Simple.kt")
|
@TestMetadata("Simple.kt")
|
||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operator/Simple.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/modifiers/operatorInfix/Simple.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ var <PROPERTY_WITH_BACKING_FIELD><PACKAGE_PROPERTY><MUTABLE_VARIABLE>globalCount
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getAttributeDescriptors(): Array<AttributesDescriptor> {
|
override fun getAttributeDescriptors(): Array<AttributesDescriptor> {
|
||||||
fun String.to(key: TextAttributesKey) = AttributesDescriptor(this, key)
|
infix fun String.to(key: TextAttributesKey) = AttributesDescriptor(this, key)
|
||||||
|
|
||||||
return arrayOf(OptionsBundle.message("options.java.attribute.descriptor.keyword") to JetHighlightingColors.KEYWORD,
|
return arrayOf(OptionsBundle.message("options.java.attribute.descriptor.keyword") to JetHighlightingColors.KEYWORD,
|
||||||
JetBundle.message("options.kotlin.attribute.descriptor.builtin.annotation") to JetHighlightingColors.BUILTIN_ANNOTATION,
|
JetBundle.message("options.kotlin.attribute.descriptor.builtin.annotation") to JetHighlightingColors.BUILTIN_ANNOTATION,
|
||||||
|
|||||||
Reference in New Issue
Block a user