Skip to content

Commit

Permalink
Begin specifying type inference of selector chains.
Browse files Browse the repository at this point in the history
The bulk of the intricacies in Dart type inference occur in the
handling of selector chains, which encompasses the following
constructs (examples in parentheses):

- Static method invocations (`Foo.m()`)
- Implicit instance creation (`Foo()`)
- Implicit `this` invocation (`m()`)
- Explicit extension invocation (`Ext(...).m(...)`)
- Super invocation (`super.m(...)`)
- Method invocation (`....m(...)` or `...?.m(...)`)
- Explicit extension call invocation (`Ext(...)(...)`)
- Super call invocation (`super(...)`)
- Call invocation (`...(...)`)
- Static method tearoff (`Foo.m`)
- Constructor tearoff (`Foo.new`)
- Explicit extension tearoff or property get (`Ext(...).p`)
- Super method tearoff or property get (`super.p`)
- Method tearoff or property get (`....p` or `...?.p`)
- Implicit this method tearoff with type arguments (`m<...>`)
- Type instantiation (`Foo<...>`)
- Explicit extension index operation (`Ext(...)[...]`)
- Super index operation (`super[...]`)
- Index operation (`...[...]` or `...?[...]`)
- Null check (`...!`)

Since this is a lot of constructs, I'm going to break them up into
several PRs to simplify review. This first PR establishes the general
framework for how to differentiate among the above forms, and then it
specifies the behavior of just four of them: static method
invocations, implicit `this` invocations, non-null-aware method
invocations, and call invocations. The rest of the forms are left as
TODOs, and will be addressed in follow-up PRs.

In order to specify these four forms, it was necessary to add some
introductory material:

- Bound resolution, which converts type parameters into their
  bounds. (This concept exists in the analyzer and CFE, but I wasn't
  able to find it in the spec so I added it after the "Subtype
  constraint generation" section.)

- Argument part inference, the general process by which type inference
  is applied to the <argumentPart> portion of any invocation. Much of
  this section was adapted from the horizontal inference spec
  (https://github.com/dart-lang/language/blob/main/accepted/2.18/horizontal-inference/feature-specification.md).

- Argument partitioning, the mechanism used by horizontal inference to
  choose the order in which to type infer arguments that are function
  expressions. This was also adapted from the horizontal inference
  spec.

- Method invocation inference, which contains the common subroutines
  of type inference used for implicit `this` invocations, method
  invocations, and call invocations. In a later PR I intend to also
  use this logic to specify how user-definable operator invocations
  are type inferred.
  • Loading branch information
stereotype441 committed Jun 26, 2024
1 parent 40fecd9 commit c9db873
Showing 1 changed file with 705 additions and 0 deletions.
Loading

0 comments on commit c9db873

Please sign in to comment.