KT-3189 Function invoke is called with no reason
prioritize tasks specially for invoke #KT-3189 Fixed #KT-3190 Fixed #KT-3297 Fixed
This commit is contained in:
+183
-63
@@ -75,8 +75,12 @@ public class TaskPrioritizer {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks(@NotNull final BasicCallResolutionContext context, @NotNull Name name,
|
||||
@NotNull JetReferenceExpression functionReference, @NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors) {
|
||||
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull Name name,
|
||||
@NotNull JetReferenceExpression functionReference,
|
||||
@NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors
|
||||
) {
|
||||
ReceiverValue explicitReceiver = context.call.getExplicitReceiver();
|
||||
JetScope scope;
|
||||
if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) {
|
||||
@@ -89,88 +93,176 @@ public class TaskPrioritizer {
|
||||
}
|
||||
|
||||
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(functionReference, context, new MyPriorityProvider<D>(context));
|
||||
doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollectors);
|
||||
TaskPrioritizerContext<D, F> c = new TaskPrioritizerContext<D, F>(name, result, context, scope, callableDescriptorCollectors);
|
||||
doComputeTasks(explicitReceiver, c);
|
||||
return result.getTasks();
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor, F extends D> void doComputeTasks(
|
||||
@NotNull JetScope scope, @NotNull ReceiverValue receiver,
|
||||
@NotNull Name name, @NotNull ResolutionTaskHolder<D, F> result,
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors
|
||||
@NotNull ReceiverValue receiver,
|
||||
@NotNull TaskPrioritizerContext<D, F> c
|
||||
) {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
|
||||
AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
|
||||
List<ReceiverValue> implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(scope);
|
||||
boolean hasExplicitThisObject = context.call.getThisObject().exists();
|
||||
if (hasExplicitThisObject) {
|
||||
implicitReceivers.add(context.call.getThisObject());
|
||||
boolean resolveInvoke = c.context.call.getThisObject().exists();
|
||||
if (resolveInvoke) {
|
||||
addCandidatesForInvoke(receiver, c);
|
||||
return;
|
||||
}
|
||||
List<ReceiverValue> implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope);
|
||||
if (receiver.exists()) {
|
||||
List<ReceiverValue> variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver);
|
||||
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : callableDescriptorCollectors) {
|
||||
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
|
||||
for (ReceiverValue variant : variantsForExplicitReceiver) {
|
||||
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name);
|
||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant),
|
||||
Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject);
|
||||
}
|
||||
result.addCandidates(members);
|
||||
}
|
||||
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : callableDescriptorCollectors) {
|
||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
|
||||
implicitReceiver.getType().getMemberScope(), name);
|
||||
List<ReceiverValue> variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||
result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver,
|
||||
variantsForExplicitReceiver, hasExplicitThisObject));
|
||||
}
|
||||
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(
|
||||
scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name));
|
||||
result.addCandidates(extensionFunctions);
|
||||
}
|
||||
addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*resolveInvoke=*/false);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
List<Collection<ResolutionCandidate<D>>> localsList = Lists.newArrayList();
|
||||
List<Collection<ResolutionCandidate<D>>> nonlocalsList = Lists.newArrayList();
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : callableDescriptorCollectors) {
|
||||
addCandidatesForNoReceiver(implicitReceivers, c);
|
||||
}
|
||||
|
||||
Collection<ResolutionCandidate<D>> functions =
|
||||
convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector
|
||||
.getNonExtensionsByName(scope, name));
|
||||
private static <D extends CallableDescriptor, F extends D> void addCandidatesForExplicitReceiver(
|
||||
@NotNull ReceiverValue receiver,
|
||||
@NotNull List<ReceiverValue> implicitReceivers,
|
||||
@NotNull TaskPrioritizerContext<D, F> c,
|
||||
boolean resolveInvoke
|
||||
) {
|
||||
|
||||
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals);
|
||||
List<ReceiverValue> variantsForExplicitReceiver = c.autoCastService.getVariantsForReceiver(receiver);
|
||||
|
||||
localsList.add(locals);
|
||||
nonlocalsList.add(nonlocals);
|
||||
//members
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
||||
Collection<ResolutionCandidate<D>> members = Lists.newArrayList();
|
||||
for (ReceiverValue variant : variantsForExplicitReceiver) {
|
||||
Collection<? extends D> membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), c.name);
|
||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant),
|
||||
Collections.singletonList(NO_RECEIVER), members, resolveInvoke);
|
||||
}
|
||||
c.result.addCandidates(members);
|
||||
}
|
||||
|
||||
result.addCandidates(localsList);
|
||||
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
||||
//member extensions
|
||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||
doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollectors);
|
||||
addMemberExtensionCandidates(implicitReceiver, variantsForExplicitReceiver,
|
||||
callableDescriptorCollector, c, resolveInvoke);
|
||||
}
|
||||
result.addCandidates(nonlocalsList);
|
||||
//extensions
|
||||
Collection<ResolutionCandidate<D>> extensionFunctions = convertWithImpliedThis(
|
||||
c.scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(c.scope, c.name));
|
||||
c.result.addCandidates(extensionFunctions);
|
||||
}
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(Collection<? extends D> descriptors, Iterable<ReceiverValue> thisObjects,
|
||||
Iterable<ReceiverValue> receiverParameters, boolean hasExplicitThisObject) {
|
||||
private static <D extends CallableDescriptor, F extends D> void addMemberExtensionCandidates(
|
||||
@NotNull ReceiverValue implicitReceiver,
|
||||
@NotNull List<ReceiverValue> variantsForExplicitReceiver,
|
||||
@NotNull CallableDescriptorCollector<? extends D> callableDescriptorCollector, TaskPrioritizerContext<D, F> c,
|
||||
boolean resolveInvoke
|
||||
) {
|
||||
Collection<? extends D> memberExtensions = callableDescriptorCollector.getNonMembersByName(
|
||||
implicitReceiver.getType().getMemberScope(), c.name);
|
||||
List<ReceiverValue> variantsForImplicitReceiver = c.autoCastService.getVariantsForReceiver(implicitReceiver);
|
||||
c.result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver,
|
||||
variantsForExplicitReceiver, resolveInvoke));
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor, F extends D> void addCandidatesForNoReceiver(
|
||||
@NotNull List<ReceiverValue> implicitReceivers,
|
||||
@NotNull TaskPrioritizerContext<D, F> c
|
||||
) {
|
||||
List<Collection<ResolutionCandidate<D>>> localsList = Lists.newArrayList();
|
||||
List<Collection<ResolutionCandidate<D>>> nonlocalsList = Lists.newArrayList();
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
||||
|
||||
Collection<ResolutionCandidate<D>> functions =
|
||||
convertWithImpliedThis(c.scope, Collections.singletonList(NO_RECEIVER), callableDescriptorCollector
|
||||
.getNonExtensionsByName(c.scope, c.name));
|
||||
|
||||
List<ResolutionCandidate<D>> nonlocals = Lists.newArrayList();
|
||||
List<ResolutionCandidate<D>> locals = Lists.newArrayList();
|
||||
//noinspection unchecked,RedundantTypeArguments
|
||||
TaskPrioritizer.<D>splitLexicallyLocalDescriptors(functions, c.scope.getContainingDeclaration(), locals, nonlocals);
|
||||
|
||||
localsList.add(locals);
|
||||
nonlocalsList.add(nonlocals);
|
||||
}
|
||||
|
||||
//locals
|
||||
c.result.addCandidates(localsList);
|
||||
|
||||
//try all implicit receivers as explicit
|
||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||
addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, /*resolveInvoke=*/false);
|
||||
}
|
||||
|
||||
//nonlocals
|
||||
c.result.addCandidates(nonlocalsList);
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor, F extends D> void addCandidatesForInvoke(
|
||||
@NotNull ReceiverValue explicitReceiver,
|
||||
@NotNull TaskPrioritizerContext<D, F> c
|
||||
) {
|
||||
List<ReceiverValue> implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope);
|
||||
|
||||
// For 'a.foo()' where foo has function type,
|
||||
// a is explicitReceiver, foo is variableReceiver.
|
||||
ReceiverValue variableReceiver = c.context.call.getThisObject();
|
||||
assert variableReceiver.exists() : "'Invoke' call hasn't got variable receiver";
|
||||
|
||||
// For invocation a.foo() explicit receiver 'a'
|
||||
// can be a receiver for 'foo' variable
|
||||
// or for 'invoke' function.
|
||||
|
||||
// (1) a.foo + foo.invoke()
|
||||
if (!explicitReceiver.exists()) {
|
||||
addCandidatesForExplicitReceiver(variableReceiver, implicitReceivers, c, /*resolveInvoke=*/true);
|
||||
}
|
||||
|
||||
// (2) foo + a.invoke()
|
||||
|
||||
// 'invoke' is member extension to explicit receiver while variable receiver is 'this object'
|
||||
//trait A
|
||||
//trait Foo { fun A.invoke() }
|
||||
|
||||
if (explicitReceiver.exists()) {
|
||||
//a.foo()
|
||||
addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver(variableReceiver, explicitReceiver, c);
|
||||
return;
|
||||
}
|
||||
// with (a) { foo() }
|
||||
for (ReceiverValue implicitReceiver : implicitReceivers) {
|
||||
addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver(variableReceiver, implicitReceiver, c);
|
||||
}
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor, F extends D> void addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver(
|
||||
@NotNull ReceiverValue variableReceiver,
|
||||
@NotNull ReceiverValue explicitReceiver,
|
||||
@NotNull TaskPrioritizerContext<D, F> c
|
||||
) {
|
||||
List<ReceiverValue> variantsForExplicitReceiver = c.autoCastService.getVariantsForReceiver(explicitReceiver);
|
||||
|
||||
for (CallableDescriptorCollector<? extends D> callableDescriptorCollector : c.callableDescriptorCollectors) {
|
||||
addMemberExtensionCandidates(variableReceiver, variantsForExplicitReceiver, callableDescriptorCollector, c, /*resolveInvoke=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithReceivers(
|
||||
@NotNull Collection<? extends D> descriptors,
|
||||
@NotNull Iterable<ReceiverValue> thisObjects,
|
||||
@NotNull Iterable<ReceiverValue> receiverParameters,
|
||||
boolean hasExplicitThisObject
|
||||
) {
|
||||
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
|
||||
convertWithReceivers(descriptors, thisObjects, receiverParameters, result, hasExplicitThisObject);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> void convertWithReceivers(Collection<? extends D> descriptors, Iterable<ReceiverValue> thisObjects, Iterable<ReceiverValue> receiverParameters,
|
||||
Collection<ResolutionCandidate<D>> result, boolean hasExplicitThisObject) {
|
||||
|
||||
private static <D extends CallableDescriptor> void convertWithReceivers(
|
||||
@NotNull Collection<? extends D> descriptors,
|
||||
@NotNull Iterable<ReceiverValue> thisObjects,
|
||||
@NotNull Iterable<ReceiverValue> receiverParameters,
|
||||
@NotNull Collection<ResolutionCandidate<D>> result,
|
||||
boolean hasExplicitThisObject
|
||||
) {
|
||||
for (ReceiverValue thisObject : thisObjects) {
|
||||
for (ReceiverValue receiverParameter : receiverParameters) {
|
||||
for (D extension : descriptors) {
|
||||
@@ -189,7 +281,11 @@ public class TaskPrioritizer {
|
||||
}
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithImpliedThis(JetScope scope, Collection<ReceiverValue> receiverParameters, Collection<? extends D> descriptors) {
|
||||
public static <D extends CallableDescriptor> Collection<ResolutionCandidate<D>> convertWithImpliedThis(
|
||||
@NotNull JetScope scope,
|
||||
@NotNull Collection<ReceiverValue> receiverParameters,
|
||||
@NotNull Collection<? extends D> descriptors
|
||||
) {
|
||||
Collection<ResolutionCandidate<D>> result = Lists.newArrayList();
|
||||
for (ReceiverValue receiverParameter : receiverParameters) {
|
||||
for (D descriptor : descriptors) {
|
||||
@@ -221,7 +317,10 @@ public class TaskPrioritizer {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean setImpliedThis(@NotNull JetScope scope, ResolutionCandidate<D> candidate) {
|
||||
private static <D extends CallableDescriptor> boolean setImpliedThis(
|
||||
@NotNull JetScope scope,
|
||||
@NotNull ResolutionCandidate<D> candidate
|
||||
) {
|
||||
ReceiverParameterDescriptor expectedThisObject = candidate.getDescriptor().getExpectedThisObject();
|
||||
if (expectedThisObject == null) return true;
|
||||
List<ReceiverParameterDescriptor> receivers = scope.getImplicitReceiversHierarchy();
|
||||
@@ -245,9 +344,6 @@ public class TaskPrioritizer {
|
||||
return result.getTasks();
|
||||
}
|
||||
|
||||
private TaskPrioritizer() {
|
||||
}
|
||||
|
||||
private static class MyPriorityProvider<D extends CallableDescriptor>
|
||||
implements ResolutionTaskHolder.PriorityProvider<ResolutionCandidate<D>> {
|
||||
private final BasicCallResolutionContext context;
|
||||
@@ -279,4 +375,28 @@ public class TaskPrioritizer {
|
||||
isOrOverridesSynthesized((CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TaskPrioritizerContext<D extends CallableDescriptor, F extends D> {
|
||||
@NotNull public final Name name;
|
||||
@NotNull public final ResolutionTaskHolder<D, F> result;
|
||||
@NotNull public final BasicCallResolutionContext context;
|
||||
@NotNull public final JetScope scope;
|
||||
@NotNull public final List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors;
|
||||
@NotNull AutoCastServiceImpl autoCastService;
|
||||
|
||||
private TaskPrioritizerContext(
|
||||
@NotNull Name name,
|
||||
@NotNull ResolutionTaskHolder<D, F> result,
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors
|
||||
) {
|
||||
this.name = name;
|
||||
this.result = result;
|
||||
this.context = context;
|
||||
this.scope = scope;
|
||||
this.callableDescriptorCollectors = callableDescriptorCollectors;
|
||||
autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//KT-3189 Function invoke is called with no reason
|
||||
|
||||
fun box(): String {
|
||||
|
||||
val bad = Bad({ 1 })
|
||||
|
||||
return if (bad.test() == 1) "OK" else "fail"
|
||||
}
|
||||
|
||||
class Bad(val a: () -> Int) {
|
||||
|
||||
fun test(): Int = a()
|
||||
|
||||
fun invoke(): Int = 2
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//KT-3190 Compiler crash if function called 'invoke' calls a closure
|
||||
|
||||
fun box(): String {
|
||||
val test = Cached<Int,Int>({ it + 2 })
|
||||
return if (test(1) == 3) "OK" else "fail"
|
||||
}
|
||||
|
||||
class Cached<K, V>(private val generate: (K)->V): jet.Function1<K, V> {
|
||||
val store = java.util.HashMap<K, V>()
|
||||
|
||||
// Everything works just fine if 'invoke' method is renamed to, for example, 'get'
|
||||
override fun invoke(p1: K) = store.getOrPut(p1) { generate(p1) }
|
||||
}
|
||||
|
||||
//from library
|
||||
fun <K,V> MutableMap<K,V>.getOrPut(key: K, defaultValue: ()-> V) : V {
|
||||
if (this.containsKey(key)) {
|
||||
return this.get(key) as V
|
||||
} else {
|
||||
val answer = defaultValue()
|
||||
this.put(key, answer)
|
||||
return answer
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//KT-3297 Calling the wrong function inside an extension method to the Function0 class
|
||||
|
||||
fun <R> Function0<R>.or(alt: () -> R): R {
|
||||
try {
|
||||
return this()
|
||||
} catch (e: Exception) {
|
||||
return alt()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return {
|
||||
throw RuntimeException("fail")
|
||||
} or {
|
||||
"OK"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
class Foo {}
|
||||
|
||||
fun Foo.invoke() {}
|
||||
|
||||
//no variable
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait A {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
|
||||
fun test(a: A) {
|
||||
a.foo()
|
||||
|
||||
with (a) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as extension
|
||||
trait B {
|
||||
}
|
||||
val B.foo = Foo()
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait C
|
||||
|
||||
trait D {
|
||||
val C.foo: Foo
|
||||
|
||||
fun test(c: C) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(d: D, c: C) {
|
||||
with (d) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
@@ -0,0 +1,62 @@
|
||||
class Foo {
|
||||
fun invoke() {}
|
||||
}
|
||||
|
||||
//no variable
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait A {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
fun test(a: A) {
|
||||
a.foo()
|
||||
|
||||
with (a) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as extension
|
||||
trait B {}
|
||||
val B.foo = Foo()
|
||||
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait C
|
||||
|
||||
trait D {
|
||||
val C.foo: Foo
|
||||
|
||||
fun test(c: C) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(d: D, c: C) {
|
||||
with (d) {
|
||||
c.foo()
|
||||
|
||||
with (c) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
@@ -0,0 +1,125 @@
|
||||
class Foo
|
||||
|
||||
//no variable
|
||||
trait A {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(foo: Foo) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member
|
||||
trait B {
|
||||
val foo: Foo
|
||||
}
|
||||
|
||||
class C {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(b: B) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(c: C, b: B) {
|
||||
with (c) {
|
||||
b.foo()
|
||||
|
||||
with (b) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//variable as extension,
|
||||
trait D {
|
||||
}
|
||||
val D.foo = Foo()
|
||||
|
||||
class E {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun test(d: D) {
|
||||
d.foo()
|
||||
|
||||
with (d) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(e: E, d: D) {
|
||||
with (e) {
|
||||
d.foo()
|
||||
|
||||
with (d) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension
|
||||
trait F
|
||||
|
||||
trait G {
|
||||
val F.foo: Foo
|
||||
fun Foo.invoke()
|
||||
|
||||
fun test(f: F) {
|
||||
f.foo()
|
||||
|
||||
with (f) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(g: G, f: F) {
|
||||
with (g) {
|
||||
f.foo()
|
||||
|
||||
with (f) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//variable as member extension (2)
|
||||
trait X
|
||||
|
||||
trait U {
|
||||
val X.foo: Foo
|
||||
}
|
||||
|
||||
trait V {
|
||||
fun Foo.invoke() {}
|
||||
|
||||
fun U.test(x: X) {
|
||||
x.foo()
|
||||
|
||||
with (x) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test(u: U, v: V, x: X) {
|
||||
with (v) {
|
||||
with (u) {
|
||||
x.foo()
|
||||
|
||||
with (x) {
|
||||
foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------
|
||||
fun <T, R> with(receiver: T, f: T.() -> R) : R = receiver.f()
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
trait A
|
||||
trait Foo {
|
||||
fun A.invoke()
|
||||
}
|
||||
|
||||
fun test(a: A, foo: Foo) {
|
||||
a.foo()
|
||||
}
|
||||
|
||||
fun test(a: Int, foo: Int.()->Unit) {
|
||||
a.foo()
|
||||
}
|
||||
@@ -4510,6 +4510,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/resolve")
|
||||
@InnerTestClasses({Resolve.Invoke.class})
|
||||
public static class Resolve extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
public void testAllFilesPresentInResolve() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/resolve"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
@@ -4545,6 +4546,40 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/resolve/invoke")
|
||||
public static class Invoke extends AbstractDiagnosticsTestWithEagerResolve {
|
||||
public void testAllFilesPresentInInvoke() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/resolve/invoke"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("invokeAsExtension.kt")
|
||||
public void testInvokeAsExtension() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeAsMember.kt")
|
||||
public void testInvokeAsMember() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeAsMemberExtension.kt")
|
||||
public void testInvokeAsMemberExtension() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeAsMemberExtensionToExplicitReceiver.kt")
|
||||
public void testInvokeAsMemberExtensionToExplicitReceiver() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test innerSuite() {
|
||||
TestSuite suite = new TestSuite("Resolve");
|
||||
suite.addTestSuite(Resolve.class);
|
||||
suite.addTestSuite(Invoke.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/scopes")
|
||||
@@ -5087,7 +5122,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
suite.addTestSuite(Recovery.class);
|
||||
suite.addTestSuite(Redeclarations.class);
|
||||
suite.addTestSuite(Regressions.class);
|
||||
suite.addTestSuite(Resolve.class);
|
||||
suite.addTest(Resolve.innerSuite());
|
||||
suite.addTestSuite(Scopes.class);
|
||||
suite.addTestSuite(SenselessComparison.class);
|
||||
suite.addTestSuite(Shadowing.class);
|
||||
|
||||
+30
-6
@@ -2092,7 +2092,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||
@InnerTestClasses({Functions.LocalFunctions.class})
|
||||
@InnerTestClasses({Functions.Invoke.class, Functions.LocalFunctions.class})
|
||||
public static class Functions extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInFunctions() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
@@ -2168,11 +2168,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/functions/functionNtoString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invoke.kt")
|
||||
public void testInvoke() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/invoke.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt1038.kt")
|
||||
public void testKt1038() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/kt1038.kt");
|
||||
@@ -2268,6 +2263,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions/invoke")
|
||||
public static class Invoke extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInInvoke() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions/invoke"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("invoke.kt")
|
||||
public void testInvoke() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/invoke/invoke.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3189.kt")
|
||||
public void testKt3189() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/invoke/kt3189.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3190.kt")
|
||||
public void testKt3190() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/invoke/kt3190.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt3297.kt")
|
||||
public void testKt3297() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/invoke/kt3297.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions/localFunctions")
|
||||
public static class LocalFunctions extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||
@@ -2284,6 +2307,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public static Test innerSuite() {
|
||||
TestSuite suite = new TestSuite("Functions");
|
||||
suite.addTestSuite(Functions.class);
|
||||
suite.addTestSuite(Invoke.class);
|
||||
suite.addTestSuite(LocalFunctions.class);
|
||||
return suite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user