## NoSuchMethod Forwarding

Author: eernst@

**Status**: Under implementation.

**Version**: 0.6 (2018-03-22)

**This document** is an informal specification of the support in Dart 2 for
invoking `noSuchMethod` in situations where an attempt is made to invoke a
method that does not exist.

**The feature** described here, *noSuchMethod forwarding*, is a particular
approach whereby an implementation of `noSuchMethod` in a class _C_ causes
_C_ to be extended with a set of compiler generated forwarding methods, such
that an invocation of any method in the static interface of _C_ will become
a regular method invocation, which in turn invokes `noSuchMethod`.


## Motivation

In Dart 1.x, `noSuchMethod` will be invoked whenever an attempt is made to
call a method that does not exist.

In other words, consider an instance method invocation of a member named
_m_ on a receiver _o_ whose class _C_ does not have a member named _m_ (or
it has a member named _m_, but it does not admit the given invocation,
e.g., because the number of arguments is wrong). The properties of the
invocation are then specified using an instance _i_ of `Invocation`, and
`noSuchMethod` is then invoked with _i_ as the actual argument. Among other
things, _i_ specifies whether the invocation was a method call or an
invocation of a getter or a setter, and it specifies which actual arguments
were passed.

One difficulty with this design is that it requires developers to take
both method invocations and getter invocations into account, in order to
support a given method using `noSuchMethod`:
```dart
class Foo {
  foo(x) {}
}

class MockFoo implements Foo {
  // PS: Make sure that a tear-off of `_mockFoo` has the same type
  // as a tear-off of `Foo.foo`.
  _mockFoo(x) {
    // ... implement mock behavior for `foo` here.
  }

  noSuchMethod(Invocation i) {
    if (i.memberName == #foo) {
      if (i.isMethod &&
          i.positionalArguments.length == 1 &&
          i.namedArguments.isEmpty) {
        return _mockFoo(i.positionalArguments[0]);
      } else if (i.isGetter) {
        return _mockFoo;
      }
    }
    return super.noSuchMethod(i);
  }
}
```
The reason why the type of a tear-off of `_mockFoo` should be the same
as the type of a tear-off of `foo` is that the former should be able to
emulate the properties of the latter faithfully, including the response
it gives rise to when subjected to type tests, either explicitly or
implicitly.

Obviously, this is verbose, tedious, and difficult to maintain if the
claimed superinterfaces (`implements ...`) in the mock class introduce
a large number of methods with complex signatures. It is particularly
inconvenient if the mock behavior is simple and largely independent of
all those types.

The noSuchMethod forwarding approach eliminates much of this tedium
by means of compiler generated forwarding methods corresponding to all
the unimplemented methods. The example could then be expressed as
follows:
```dart
class Foo {
  foo(x) {}
}

class MockFoo implements Foo {
  noSuchMethod(Invocation i) {
    if (i.memberName == #foo) {
      if (i.isMethod &&
          i.positionalArguments.length == 1 &&
          i.namedArguments.isEmpty) {
        // ... implement mock behavior for `foo` here.
      }
    }
    return super.noSuchMethod(i);
  }
}
```
With noSuchMethod forwarding, this causes a `foo` forwarding
method to be generated, with the signature declared in `Foo`
and with the necessary code to create and initialize a suitable
`Invocation` which will be passed to `noSuchMethod`.


## Syntax

The grammar remains unchanged.


## Static Analysis

We say that a class _C_ _has a non-trivial_ `noSuchMethod` if _C_ declares
or inherits a non-abstract method named `noSuchMethod` which is distinct
from the declaration in the built-in class `Object`.

*Note that such a declaration cannot be a getter or setter, and it must
accept one positional argument of type `Invocation`, due to the
requirement that it must correctly override the declaration of
`noSuchMethod` in the class `Object`. For instance, in addition to the
obvious choice `noSuchMethod(Invocation i)` it can be
`noSuchMethod(Object i, [String s])`, but not
`noSuchMethod(Invocation i, String s)`.*

If a non-abstract class _C_ has a non-trivial `noSuchMethod` then each
method signature (including getters and setters) which is a member of _C_'s
interface and for which _C_ does not have a non-abstract declaration is
_noSuchMethod forwarded_. No other situations give rise to a noSuchMethod
forwarded method signature.

*This means that whenever it is stated that a class has a noSuchMethod
forwarded method signature it is guaranteed to be a non-abstract class with
a non-trivial `noSuchMethod`.*

If a class _C_ has a noSuchMethod forwarded signature then an implicit
method implementation implementing that method signature is induced in _C_.
In the case where _C_ already contains an abstract declaration with the
same name, the induced method implementation replaces the abstract
declaration.

It is a compile-time error if a non-abstract class _C_ has a non-trivial
`noSuchMethod`, and a name `m` has a set of method signatures in the
superinterfaces of _C_ where none is most specific, and there is no
declaration in _C_ which provides such a most specific method signature.

*This means that even in the situation where everything else implies that a
noSuchMethod forwarder should be induced, signature ambiguities must still
be resolved by a developer-written declaration, it cannot be a consequence
of implicitly inducing a noSuchMethod forwarder. However, that
developer-written declaration could be an abstract method in the
non-abstract class itself.*

*Note that there is no most specific method signature if there are several
method signatures which are equally specific with respect to the argument
types and return type, but an optional formal parameter in these signatures
has different default values in different signatures.*

It is a compile-time error if a class _C_ has a noSuchMethod forwarded
method signature _S_ for a method named _m_, as well as an implementation
of _m_.

*This can only happen if that implementation is inherited and satisfies
some, but not all requirements of the noSuchMethod forwarded method
signature. In the example below, a `foo(int i)` implementation is inherited
and a superinterface declares `foo([int i])`. This is a compile-time error
because `C` does not have a method implementation with signature
`foo([int])`, but if one were to be implicitly induced it would override
`A.foo` (which is capable of accepting some but not all of the argument
lists that an implementation of `foo([int])` would allow). We have made
this an error because it would be error prone to induce a forwarder in `C`
which will silently override an `A.foo` which "almost" satisfies the
requirement in the superinterface. In particular, developers are likely to
be surprised if `A.foo` is not called even when it is passed a single
`int` argument, which precisely matches the declaration of `A.foo`.*

```dart
class A {
  foo(int i) => null;
}

abstract class B {
  foo([int i]);
}

class C extends A implements B {
  noSuchMethod(Invocation i) => ...;
  // Error on `foo`: Forwarder would override `A.foo`.
}
```

*Note that this makes it a breaking change, in situations where such a
signature conflict exists in some subtype like `C`, to change an abstract
method declaration to a method implementation: If `A` had been an abstract
class and `A.foo` an abstract method which was replaced by an `A.foo`
declaration which implements the method, the error on `foo` in class `C`
would be introduced because `A.foo` was implemented. There is a reasonably
practical workaround, though: implement `C.foo` with a signature that
resolves the conflict. That implementation might invoke `A.foo` in a
superinvocation, or it might forward to `noSuchMethod`, or some times one
and some times the other, that is up to the developer who writes `C.foo`.*

*Note that it is _not_ a compile-time error if the interface of _C_ has a
noSuchMethod forwarded method signature _S_ with name _m_, and a superclass
of _C_ also has a noSuchMethod forwarded method signature named _m_, such
that the implicitly induced implementation of the former overrides the
implicitly induced implementation of the  latter. In other words, it is OK
for a generated forwarder to override another generated forwarder.*

*Note that when a class _C_ has an implicitly induced implementation of a
method, superinvocations in subclasses are allowed, just like they would
have been for a developer-written implementation.*

```dart
abstract class D { baz(); }
class E implements D {
  noSuchMethod(Invocation i) => null;
}
class F extends E { baz() { super.baz(); }} // OK
```


## Dynamic Semantics

Assume that a class _C_ has an implicitly induced implementation of a
method _m_ with positional formal parameters
_T<sub>1</sub> a<sub>1</sub>..., T<sub>k</sub> a<sub>k</sub>_
and named formal parameters
_T<sub>k+1</sub> n<sub>1</sub>..., T<sub>k+m</sub> n<sub>m</sub>_.
Said implementation will then create an instance _i_ of the predefined
class `Invocation` such that its

-   `isGetter` evaluates to true iff _m_ is a getter,
    `isSetter` evaluates to true iff _m_ is a setter,
    `isMethod` evaluates to true iff _m_ is a method.
-   `memberName` evaluates to the symbol for the name _m_.
-   `positionalArguments` evaluates to an immutable list whose
    values are _a<sub>1</sub>..., a<sub>k</sub>_.
-   `namedArguments` evaluates to an immutable map with the same keys
    and values as
    _{n<sub>1</sub>: n<sub>1</sub>..., n<sub>m</sub>: n<sub>m</sub>}_

*Note that the number of named arguments can be zero, in which case some of
the positional parameters can be optional. We do not need to mention
optional positional arguments separately, because they receive the same
treatment as required parameters (which are of course always positional).*

Finally the induced method implementation will invoke `noSuchMethod` with
_i_ as the actual argument, and return the result obtained from there.

*This determines the dynamic semantics of implicitly induced methods: The
declared return type and the formal parameters, with type annotations and
default values, are uniquely determined by the noSuchMethod forwarded
method signatures, and invocation of an implicitly induced method has the
same semantics of invocation of other methods. In particular, dynamic type
checks are performed on the actual arguments upon invocation when the
corresponding formal parameter is covariant.*

*This ensures, relying on the heap soundness and expression soundness of
Dart (which ensures that every expression of type _T_ will evaluate to an
entity of type _T_), that all statically type safe invocations will invoke
a method implementation, user-written or implicitly induced. In other
words, with statically checked calls there is no need for dynamic support
for `noSuchMethod` at all.*

For a dynamic invocation of a member _m_ on a receiver _o_ that has a
non-trivial `noSuchMethod`, the semantics is such that an attempt to invoke
_m_ with the given actual arguments (including possibly some type
arguments) is made at first. If that fails (*because _o_ has no
implementation of _m_ which can be invoked with the given argument list
shape, be it a developer-written method or an implicitly induced
implementation*) `noSuchMethod` is invoked with an actual argument which is
an `Invocation` describing the actual arguments and invocation.

*This implies that dynamic invocations on receivers having a non-trivial
`noSuchMethod` will simply invoke the forwarders whenever possible.
Similarly, it will work for dynamic invocations as well as statically
checked ones to tear off a method which is in the interface of the receiver
and implemented as a generated forwarder.*

*The only remaining situation is when a dynamic invocation invokes a method
which is not present in the static interface of the receiver, or when a
method with that name is present, but its signature does not allow for the
given invocation (e.g., because some required arguments are omitted). In
this situation, the regular instance method invocation has failed (there is
no such regular method, and no such generated forwarder). Such a dynamic
invocation will then invoke `noSuchMethod`. In this situation, a
developer-written implementation of `noSuchMethod` should also support both
method invocations and tear-offs explicitly (as it should before this
feature was added), because there is no generated forwarder to do that.*

*This approach may incur a certain performance penalty, but only for these
invocations (which are dynamic, and have already failed to invoke an
existing method, regular or generated).*

*In return, this approach enforces the following simple invariant, for both
statically checked and dynamic invocations: Whenever an instance method is
invoked, and no such method exists, `noSuchMethod` will be invoked.*

*One special case to be aware of is where a forwarder is torn off and then
invoked with an actual argument list which does not match the formal
parameter list. In that situation we will get an invocation of
`Object.noSuchMethod` rather than the `noSuchMethod` in the original
receiver, because this is an invocation of a function object (and they do
not override `noSuchMethod`):*

```dart
class A {
  dynamic noSuchMethod(Invocation i) => null;
  void foo();
}

main() {
  A a = new A();
  dynamic f = a.foo;
  // Invokes `Object.noSuchMethod`, not `A.noSuchMethod`, so it throws.
  f(42);
}
```


## Updates

*   Mar 22nd 2018, version 0.6: Added example to illustrate the case where a
    torn-off method invokes `Object.noSuchMethod`, not the one in the
    receiver, because of a non-matching actual argument list.

*   Nov 27th 2017, version 0.5: Changed terminology to use 'implicitly
    induced method implementations'. Helped achieving a major simplifaction
    of the dynamic semantics.

*   Nov 22nd 2017, version 0.4: Removed support for explicitly requesting
    generated forwarder in conflict case. Improved the clarity of many
    parts.

*   Oct 5th 2017, version 0.3: Clarified that generated forwarders must
    pass an `Invocation` to `noSuchMethod` which specifies the bindings
    of formal arguments to actual arguments. Clarified the treatment of
    default values for optional arguments.

*   Sep 20th 2017, version 0.2: Many smaller adjustments, based on review
    feedback.

*   Sep 18th 2017, version 0.1: Created the first version of this document.
