Allow invoke-convention on dynamic expressions

This commit is contained in:
Andrey Breslav
2014-11-27 09:37:40 +03:00
parent 53bbf20b0d
commit b7dd63465b
4 changed files with 20 additions and 6 deletions
@@ -124,8 +124,7 @@ public class TaskPrioritizer {
) { ) {
ProgressIndicatorProvider.checkCanceled(); ProgressIndicatorProvider.checkCanceled();
ReceiverValue dispatchReceiver = c.context.call.getDispatchReceiver(); boolean resolveInvoke = c.context.call.getDispatchReceiver().exists();
boolean resolveInvoke = dispatchReceiver.exists() && !TypesPackage.isDynamic(dispatchReceiver.getType());
if (resolveInvoke) { if (resolveInvoke) {
addCandidatesForInvoke(receiver, c); addCandidatesForInvoke(receiver, c);
return; return;
@@ -61,6 +61,12 @@ object DynamicCallableDescriptors {
override fun getFunctions(name: Name): Collection<FunctionDescriptor> { override fun getFunctions(name: Name): Collection<FunctionDescriptor> {
if (isAugmentedAssignmentConvention(name)) return listOf() if (isAugmentedAssignmentConvention(name)) return listOf()
if (call.getCallType() == Call.CallType.INVOKE
&& call.getValueArgumentList() == null && call.getFunctionLiteralArguments().isEmpty()) {
// this means that we are looking for "imaginary" invokes,
// e.g. in `+d` we are looking for property "plus" with member "invoke"
return listOf()
}
return listOf(createDynamicFunction(owner, name, call)) return listOf(createDynamicFunction(owner, name, call))
} }
@@ -40,10 +40,17 @@ fun test(d: dynamic) {
<!DEBUG_INFO_DYNAMIC!>d[1]<!><!DEBUG_INFO_DYNAMIC!>--<!> <!DEBUG_INFO_DYNAMIC!>d[1]<!><!DEBUG_INFO_DYNAMIC!>--<!>
<!DEBUG_INFO_DYNAMIC!>--<!><!DEBUG_INFO_DYNAMIC!>d[1]<!> <!DEBUG_INFO_DYNAMIC!>--<!><!DEBUG_INFO_DYNAMIC!>d[1]<!>
// d() <!DEBUG_INFO_DYNAMIC!>d()<!>
// d(1) <!DEBUG_INFO_DYNAMIC!>d(1)<!>
// d(name = 1) <!DEBUG_INFO_DYNAMIC!>d(name = 1)<!>
// d {} <!DEBUG_INFO_DYNAMIC!>d {}<!>
class C {
val plus: dynamic = null
}
C() <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+<!> 5
C().<!DEBUG_INFO_DYNAMIC!>plus(5)<!>
d == d d == d
d != d d != d
+2
View File
@@ -72,6 +72,8 @@ Internally, `dynamic` is represented as a flexible type `Nothing..Any?`, with th
If needed, one can force a call to an extension by casting the receiver to a static type: `(d as Foo).bar()` If needed, one can force a call to an extension by casting the receiver to a static type: `(d as Foo).bar()`
- Augmented assignments on dynamic receivers (e.g. `dyn += foo`) are resolved to `plusAssign()` function, not `plus`, for generality: - Augmented assignments on dynamic receivers (e.g. `dyn += foo`) are resolved to `plusAssign()` function, not `plus`, for generality:
this permits calling them on vals (e.g. those holding collection-like objects) this permits calling them on vals (e.g. those holding collection-like objects)
- The invoke convention is limited so that for calls like `dyn.foo()` we do not look for property `foo` that has `invoke` defined on it
(same for other cases like `+dyn` etc)
## Type Argument Inference ## Type Argument Inference