google / google/reflectable.dart

Generic function invocation and `StringInvocation` call for updates

Open
#126 0 comments 0 reactions 0 assignees View on GitHub
blocked enhancement
Dominant language
Dart
Stars
386
Forks
67
PR merge metrics
No merged PRs in 30d

Description

The class `StringInvocation` is used by reflectable in a way similar to `Invocation` (except that reflectable does not have access to symbols, so `memberName` needs to be a string). Hence, **`StringInvocation` should be updated** when `Invocation` is updated. With the addition of generic functions to Dart, this means that we must add a `List get typeArguments` member to `StringInvocation` and ensure that it gets filled in according to the given invocation.

Immediate technical consequences: `ReflectableNoSuchMethodError` needs to have `typeArguments`, and it needs to be created with the appropriate values for them, `reflectableNoSuchMethodError` needs to take an extra argument and it must be passed, and `InstanceMirror.invoke` needs to take a `typeArguments` argument as well. So the type arguments need to be passed along the whole pipeline.

However, this raises further questions about how to handle **reflective invocation of generic functions** in general, because the above will only address the situation where the invocation fails because there is no such method. In fact, we cannot directly support actual invocations of generic functions with any particular type arguments, because we cannot use values of type `Type` as actual type arguments. So there is no way to generalize reflectable such that generic function invocation is supported using the "obvious" representation, like doing `myInstanceMirror.invoke('foo', [42], {#x: 43}, [int, String])` in order to get the effect of `myReceiver.foo(42, named: 43)`.

We might be able to use _k_ different versions of `invoke`: one taking zero type arguments (like today), one taking one type argument with no bound, ..., one taking _k_ type arguments with no bound; with that, we could perform a reflective function invocation using calls like this:

```dart
var result = myInstanceMirror
.invokeWithTwoTypeArguments('foo', [42], #x: 43);
```

We would then be able to pass the given type arguments in the implementation of `invokeWithTwoTypeArguments` in the shape of actual type variables, and the invocation would (presumably) be dynamic. This might work (no implementation has been attempted), but it is unwieldy because we need many variants of each method associated with invocation, and we do not get support for actual first class management of the type arguments (e.g., we cannot store a list of actual type arguments and later reuse them).

Because of these difficulties, I'm marking this issue as **blocked**, based on primitive support.

Note that reflective invocations of generic functions with **the current approach** will go via a call site where no type argument information is available, and hence the actual type arguments will be computed using [instantiate-to-bound](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/instantiate-to-bound.md). This may be a workable solution, considering that it is likely to be difficult to select any actual type arguments which are more precise than that when an invocation is reflective.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.