changed local extensions priority
local extensions aren't longer chosen before members
This commit is contained in:
+4
-31
@@ -36,9 +36,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
|
|||||||
private final PriorityProvider<ResolutionCandidate<D>> priorityProvider;
|
private final PriorityProvider<ResolutionCandidate<D>> priorityProvider;
|
||||||
private final boolean isSafeCall;
|
private final boolean isSafeCall;
|
||||||
|
|
||||||
private final Collection<Collection<ResolutionCandidate<D>>> localExtensions = Sets.newLinkedHashSet();
|
private final Collection<Collection<ResolutionCandidate<D>>> candidatesList = Lists.newArrayList();
|
||||||
private final Collection<Collection<ResolutionCandidate<D>>> members = Sets.newLinkedHashSet();
|
|
||||||
private final Collection<Collection<ResolutionCandidate<D>>> nonLocalExtensions = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
private List<ResolutionTask<D, F>> tasks = null;
|
private List<ResolutionTask<D, F>> tasks = null;
|
||||||
|
|
||||||
@@ -59,44 +57,19 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
public void addCandidates(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
||||||
if (!candidates.isEmpty()) {
|
if (!candidates.isEmpty()) {
|
||||||
localExtensions.add(setIsSafeCall(candidates));
|
candidatesList.add(setIsSafeCall(candidates));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMembers(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
|
||||||
if (!candidates.isEmpty()) {
|
|
||||||
members.add(setIsSafeCall(candidates));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addNonLocalExtensions(@NotNull Collection<ResolutionCandidate<D>> candidates) {
|
|
||||||
if (!candidates.isEmpty()) {
|
|
||||||
nonLocalExtensions.add(setIsSafeCall(candidates));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResolutionTask<D, F>> getTasks() {
|
public List<ResolutionTask<D, F>> getTasks() {
|
||||||
if (tasks == null) {
|
if (tasks == null) {
|
||||||
tasks = Lists.newArrayList();
|
tasks = Lists.newArrayList();
|
||||||
List<Collection<ResolutionCandidate<D>>> candidateList = Lists.newArrayList();
|
|
||||||
// If the call is of the form super.foo(), it can actually be only a member
|
|
||||||
// But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension
|
|
||||||
// Thus, put members first
|
|
||||||
if (TaskPrioritizer.getReceiverSuper(basicCallResolutionContext.call.getExplicitReceiver()) != null) {
|
|
||||||
candidateList.addAll(members);
|
|
||||||
candidateList.addAll(localExtensions);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
candidateList.addAll(localExtensions);
|
|
||||||
candidateList.addAll(members);
|
|
||||||
}
|
|
||||||
candidateList.addAll(nonLocalExtensions);
|
|
||||||
|
|
||||||
for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) {
|
for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) {
|
||||||
final int finalPriority = priority;
|
final int finalPriority = priority;
|
||||||
for (Collection<ResolutionCandidate<D>> candidates : candidateList) {
|
for (Collection<ResolutionCandidate<D>> candidates : candidatesList) {
|
||||||
Collection<ResolutionCandidate<D>> filteredCandidates = Collections2.filter(candidates, new Predicate<ResolutionCandidate<D>>() {
|
Collection<ResolutionCandidate<D>> filteredCandidates = Collections2.filter(candidates, new Predicate<ResolutionCandidate<D>>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(@Nullable ResolutionCandidate<D> input) {
|
public boolean apply(@Nullable ResolutionCandidate<D> input) {
|
||||||
|
|||||||
+10
-13
@@ -147,29 +147,26 @@ public class TaskPrioritizer {
|
|||||||
if (receiver.exists()) {
|
if (receiver.exists()) {
|
||||||
List<ReceiverValue> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
List<ReceiverValue> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
||||||
|
|
||||||
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
|
|
||||||
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
|
|
||||||
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
|
|
||||||
//noinspection unchecked,RedundantTypeArguments
|
|
||||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals);
|
|
||||||
|
|
||||||
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
|
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
|
||||||
for (ReceiverValue variant : variantsForExplicitReceiver) {
|
for (ReceiverValue variant : variantsForExplicitReceiver) {
|
||||||
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name);
|
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name);
|
||||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject);
|
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant),
|
||||||
|
Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.addLocalExtensions(locals);
|
result.addCandidates(members);
|
||||||
result.addMembers(members);
|
|
||||||
|
|
||||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||||
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
|
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
|
||||||
implicitReceiver.getType().getMemberScope(), name);
|
implicitReceiver.getType().getMemberScope(), name);
|
||||||
List<ReceiverValue> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
List<ReceiverValue> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||||
result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver, hasExplicitThisObject));
|
result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver,
|
||||||
|
variantsForExplicitReceiver, hasExplicitThisObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
result.addNonLocalExtensions(nonlocals);
|
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(
|
||||||
|
scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
|
||||||
|
result.addCandidates(extensionFunctions);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector
|
Collection<ResolutionCandidate<D>> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector
|
||||||
@@ -180,12 +177,12 @@ public class TaskPrioritizer {
|
|||||||
//noinspection unchecked,RedundantTypeArguments
|
//noinspection unchecked,RedundantTypeArguments
|
||||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||||
|
|
||||||
result.addLocalExtensions(locals);
|
result.addCandidates(locals);
|
||||||
|
|
||||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||||
doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector);
|
doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector);
|
||||||
}
|
}
|
||||||
result.addNonLocalExtensions(nonlocals);
|
result.addCandidates(nonlocals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
fun box() : String {
|
|
||||||
if (!B().test()) return "fail 1";
|
|
||||||
if (!D().test()) return "fail 2"
|
|
||||||
if (!F().test()) return "fail 3"
|
|
||||||
if (!L().test()) return "fail 4"
|
|
||||||
if (!H().test()) return "fail 5"
|
|
||||||
if (!N().test()) return "fail 6"
|
|
||||||
return "OK"
|
|
||||||
}
|
|
||||||
|
|
||||||
class A {
|
|
||||||
fun foo() = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class B {
|
|
||||||
fun foo() = 2
|
|
||||||
|
|
||||||
fun A.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = A().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class C {
|
|
||||||
fun D.foo() = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
class D {
|
|
||||||
fun C.foo() = 1
|
|
||||||
|
|
||||||
fun C.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = C().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class E
|
|
||||||
fun E.foo() = 2
|
|
||||||
|
|
||||||
class F {
|
|
||||||
fun foo() = 1
|
|
||||||
|
|
||||||
fun E.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = E().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class G
|
|
||||||
fun G.foo() = 2
|
|
||||||
|
|
||||||
class H {
|
|
||||||
fun G.foo() = 1
|
|
||||||
|
|
||||||
fun G.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = G().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class K
|
|
||||||
class L {
|
|
||||||
fun K.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = K().bar() == 1
|
|
||||||
}
|
|
||||||
fun K.foo() = 1
|
|
||||||
fun L.foo() = 2
|
|
||||||
|
|
||||||
class M
|
|
||||||
class N {
|
|
||||||
fun foo() = 1
|
|
||||||
fun M.foo() = 2
|
|
||||||
|
|
||||||
fun M.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = M().bar() == 1
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A {
|
||||||
|
fun B.foo() = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
~A.foo~fun A.foo() = 1
|
||||||
|
|
||||||
|
fun A.bar() = `A.foo`foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A
|
||||||
|
|
||||||
|
class B {
|
||||||
|
fun A.bar() = `A.foo`foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
~A.foo~fun A.foo() = 1
|
||||||
|
|
||||||
|
fun B.foo() = 2
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A
|
||||||
|
class B {
|
||||||
|
fun foo() = 1
|
||||||
|
~A.foo~fun A.foo() = 2
|
||||||
|
|
||||||
|
fun A.bar() = `A.foo`foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class A
|
||||||
|
fun A.foo() = 2
|
||||||
|
|
||||||
|
class B {
|
||||||
|
~foo~fun A.foo() = 1
|
||||||
|
|
||||||
|
fun A.bar() = `foo`foo()
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
class A {
|
||||||
|
fun foo() = 1
|
||||||
|
}
|
||||||
|
class B {
|
||||||
|
}
|
||||||
|
~B.foo~fun B.foo() = 2
|
||||||
|
|
||||||
|
fun test(a: A, b: B) {
|
||||||
|
with (a) {
|
||||||
|
with (b) {
|
||||||
|
`B.foo`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class A {
|
||||||
|
}
|
||||||
|
~extension~fun A.foo() = 1
|
||||||
|
fun foo() = 2
|
||||||
|
|
||||||
|
fun test(a: A) {
|
||||||
|
with (a) {
|
||||||
|
`extension`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class A {
|
||||||
|
fun foo() = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
fun ~local~foo() = 2
|
||||||
|
`local`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A {
|
||||||
|
fun ~member~foo() = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
this.`member`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun A.foo() = 2
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class A {
|
||||||
|
fun ~member~foo() = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
this.`member`foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun A.foo() = 2
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class A {
|
||||||
|
fun ~member~foo() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun A.foo() = 2
|
||||||
|
|
||||||
|
fun test(a: A) {
|
||||||
|
with (a) {
|
||||||
|
this.`member`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
class A {
|
||||||
|
fun ~member~foo() = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
fun A.foo() = 2
|
||||||
|
this.`member`foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A {
|
||||||
|
~A.foo~fun foo() = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
fun foo() = 2
|
||||||
|
|
||||||
|
fun A.bar() = `A.foo`foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class A
|
||||||
|
|
||||||
|
class B {
|
||||||
|
fun foo() = 2
|
||||||
|
|
||||||
|
fun A.bar() = `A.foo`foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
~A.foo~fun A.foo() = 1
|
||||||
@@ -1105,11 +1105,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/classes/propertyInInitializer.kt");
|
doTest("compiler/testData/codegen/box/classes/propertyInInitializer.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("resolveOrder.kt")
|
|
||||||
public void testResolveOrder() throws Exception {
|
|
||||||
doTest("compiler/testData/codegen/box/classes/resolveOrder.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("rightHandOverride.kt")
|
@TestMetadata("rightHandOverride.kt")
|
||||||
public void testRightHandOverride() throws Exception {
|
public void testRightHandOverride() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/classes/rightHandOverride.kt");
|
doTest("compiler/testData/codegen/box/classes/rightHandOverride.kt");
|
||||||
|
|||||||
@@ -168,9 +168,74 @@ public class JetResolveTestGenerated extends AbstractResolveTest {
|
|||||||
doTest("compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve");
|
doTest("compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("preferImplicitThisToNoReceiver.resolve")
|
@TestMetadata("closerReceiver1.resolve")
|
||||||
public void testPreferImplicitThisToNoReceiver() throws Exception {
|
public void testCloserReceiver1() throws Exception {
|
||||||
doTest("compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve");
|
doTest("compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("closerReceiver2.resolve")
|
||||||
|
public void testCloserReceiver2() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("closerReceiver3.resolve")
|
||||||
|
public void testCloserReceiver3() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("closerScope.resolve")
|
||||||
|
public void testCloserScope() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/closerScope.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionToCloserReceiverVsMember.resolve")
|
||||||
|
public void testExtensionToCloserReceiverVsMember() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("implicitThisVsNoReceiver.resolve")
|
||||||
|
public void testImplicitThisVsNoReceiver() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("implicitThisVsNoReceiver2.resolve")
|
||||||
|
public void testImplicitThisVsNoReceiver2() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localVsImplicitThis.resolve")
|
||||||
|
public void testLocalVsImplicitThis() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("memberVsExtension1.resolve")
|
||||||
|
public void testMemberVsExtension1() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("memberVsExtension2.resolve")
|
||||||
|
public void testMemberVsExtension2() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("memberVsExtension3.resolve")
|
||||||
|
public void testMemberVsExtension3() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("memberVsLocalExtension.resolve")
|
||||||
|
public void testMemberVsLocalExtension() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("receiverVsThisObject.resolve")
|
||||||
|
public void testReceiverVsThisObject() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("receiverVsThisObject2.resolve")
|
||||||
|
public void testReceiverVsThisObject2() throws Exception {
|
||||||
|
doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
fun box() : String {
|
|
||||||
if (!B().test()) return "fail 1";
|
|
||||||
if (!D().test()) return "fail 2"
|
|
||||||
if (!F().test()) return "fail 3"
|
|
||||||
if (!L().test()) return "fail 4"
|
|
||||||
if (!H().test()) return "fail 5"
|
|
||||||
if (!N().test()) return "fail 6"
|
|
||||||
return "OK"
|
|
||||||
}
|
|
||||||
|
|
||||||
class A {
|
|
||||||
fun foo() = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class B {
|
|
||||||
fun foo() = 2
|
|
||||||
|
|
||||||
fun A.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = A().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class C {
|
|
||||||
fun D.foo() = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
class D {
|
|
||||||
fun C.foo() = 1
|
|
||||||
|
|
||||||
fun C.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = C().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class E
|
|
||||||
fun E.foo() = 2
|
|
||||||
|
|
||||||
class F {
|
|
||||||
fun foo() = 1
|
|
||||||
|
|
||||||
fun E.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = E().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class G
|
|
||||||
fun G.foo() = 2
|
|
||||||
|
|
||||||
class H {
|
|
||||||
fun G.foo() = 1
|
|
||||||
|
|
||||||
fun G.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = G().bar() == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
class K
|
|
||||||
class L {
|
|
||||||
fun K.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = K().bar() == 1
|
|
||||||
}
|
|
||||||
fun K.foo() = 1
|
|
||||||
fun L.foo() = 2
|
|
||||||
|
|
||||||
class M
|
|
||||||
class N {
|
|
||||||
fun foo() = 1
|
|
||||||
fun M.foo() = 2
|
|
||||||
|
|
||||||
fun M.bar() = foo()
|
|
||||||
|
|
||||||
fun test() = M().bar() == 1
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user