Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
eernstg committed Jun 19, 2024
1 parent 098dedc commit bcc432b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
39 changes: 21 additions & 18 deletions working/0723-static-extensions/feature-specification-variant1.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class SortedList<X> {
}
static extension<X extends Comparable<X>> on SortedList<X> {
SortedList.ofComparable(): super((X a, X b) => a.compareTo(b));
SortedList.ofComparable(): this((X a, X b) => a.compareTo(b));
}
```

Expand Down Expand Up @@ -174,12 +174,15 @@ The grammar is modified as follows:

In a static extension of the form `static extension E on C {...}` where `C`
is an identifier or an identifier with an import prefix, we say that the
on-class of the static extension is `C`. If `C` resolves to a non-generic
class then we say that the _constructor return type_ of the static
extension is `C`.
on-class of the static extension is `C`.

*If `C` resolves to a generic class then the static extension does not have
a constructor return type.*
If `C` denotes a non-generic class, mixin, mixin class, or extension
type then we say that the _constructor return type_ of the static extension
is `C`.

If `C` denotes a generic class then `E` is treated as
`static extensionE on C<T1 .. Tk> {...}`
where `T1 .. Tk` are obtained by instantiation to bound.

In a static extension of the form `static extension E on C<T1 .. Tk> {...}`
where `C` is an identifier or prefixed identifier, we say that the on-class
Expand Down Expand Up @@ -247,8 +250,8 @@ Tools may report diagnostic messages like warnings or lints in certain
situations. This is not part of the specification, but here is one
recommended message:

A compile-time message is emitted if a static extension _D_ declares a
constructor or a static member with the same name as a constructor or a
A compile-time diagnostic is emitted if a static extension _D_ declares a
constructor or a static member with the same basename as a constructor or a
static member in the on-class of _D_.

*In other words, a static extension should not have name clashes with its
Expand Down Expand Up @@ -309,11 +312,11 @@ on-class `C` and a member named `m`.

If `C` contains such a declaration then the expression is an invocation of
that static member of `C`, with the same static analysis and dynamic
behavior as before the introduction of this feature.
semantics as before the introduction of this feature.

Otherwise, an error occurs if fewer than one or more than one declaration
named `m` was found. *They would necessarily be declared in static
extensions.*
Otherwise, an error occurs if no declarations named `m` or more than one
declaration named `m` were found. *They would necessarily be declared in
static extensions.*

Otherwise, the invocation is resolved to the given static member
declaration in a static extension named `Ej`, and the invocation is treated
Expand All @@ -327,9 +330,9 @@ parameters `X1 extends B1 .. Xs extends Bs` and an actual type argument
list `T1 .. Ts` with a type known as the _instantiated constructor return
type of_ _D_ _with type arguments_ `T1 .. Ts`.

When a static extension declaration _D_ named `E` has an on-clause which is
a non-generic class `C`, the instantiated constructor return type is `C`,
for any list of actual type arguments.
When a static extension declaration _D_ named `E` has an on-clause which
denotes a non-generic class `C`, the instantiated constructor return type
is `C`, for any list of actual type arguments.

*It is not very useful to declare a type parameter of a static extension
which isn't used in the constructor return type, because it can only be
Expand Down Expand Up @@ -417,13 +420,13 @@ henceforth treated as `E<U1 .. Us>.C<T1 .. Tm>.name(args)` (respectively
`E<U1 .. Us>.C<T1 .. Tm>(args)`).

A constructor invocation of the form `C.name(args)` (respectively
`C(args)`) where `C` resolves to a non-generic class is resolved in the
`C(args)`) where `C` denotes a non-generic class is resolved in the
same manner, with `m == 0`. *In this case, type parameters declared by `E`
will be bound to values selected by instantiation to bound.*

Consider a constructor invocation of the form `C.name(args)` (and similarly
for `C(args)`) where `C` resolves to a generic class. As usual, the
invocation is treated as in the pre-feature language when it resolves to a
for `C(args)`) where `C` denotes a generic class. As usual, the
invocation is treated as in the pre-feature language when it denotes a
constructor declared by the class `C`.

In the case where the context type schema for this invocation fully
Expand Down
46 changes: 25 additions & 21 deletions working/0723-static-extensions/feature-specification-variant2.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class SortedList<X> {
}
extension<X extends Comparable<X>> on SortedList<X> {
SortedList.ofComparable(): super((X a, X b) => a.compareTo(b));
SortedList.ofComparable(): this((X a, X b) => a.compareTo(b));
}
```

Expand Down Expand Up @@ -132,20 +132,23 @@ usual, e.g., if a redirecting factory constructor redirects to a
constructor that does not exist, or there is a redirection cycle.*

In an extension declaration of the form `extension E on C {...}` where `C`
is an identifier or an identifier with an import prefix that resolves to a
is an identifier or an identifier with an import prefix that denotes a
class, mixin, enum, or extension type declaration, we say that the
_on-class_ of the extension is `C`. If `C` resolves to a non-generic class
then we say that the _constructor return type_ of the extension is `C`.
_on-class_ of the extension is `C`. If `C` denotes a non-generic class,
mixin, mixin class, or extension type then we say that the _constructor return
type_ of the extension is `C`.

*If `C` resolves to a generic class then the extension does not have a
constructor return type.*
If `C` denotes a generic class then `E` is treated as
`extension E on C<T1 .. Tk> {...}` where `T1 .. Tk` are obtained by
instantiation to bound.

In a extension of the form `extension E on C<T1 .. Tk> {...}`
where `C` is an identifier or prefixed identifier that resolves to a class,
In an extension of the form `extension E on C<T1 .. Tk> {...}`
where `C` is an identifier or prefixed identifier that denotes a class,
mixin, enum, or extension type declaration, we say that the _on-class_
of `E` is `C`, and the _constructor return type_ of `E` is `C<T1 .. Tk>`.

In all other cases, an extension declaration does not have an on-class.
In all other cases, an extension declaration does not have an on-class nor a
constructor return type.

*For example, an extension whose on-type is a type variable does not have
an on-class, and neither does an extension whose on-type is a function
Expand All @@ -165,8 +168,8 @@ Tools may report diagnostic messages like warnings or lints in certain
situations. This is not part of the specification, but here is one
recommended message:

A compile-time message is emitted if a extension _D_ declares a
constructor or a static member with the same name as a constructor or a
A compile-time diagnostic is emitted if an extension _D_ declares a
constructor or a static member with the same basename as a constructor or a
static member in the on-class of _D_.

*In other words, an extension should not have name clashes with its
Expand Down Expand Up @@ -194,10 +197,11 @@ on-class `C` and a static member named `m`.

If `C` contains such a declaration then the expression is an invocation of
that static member of `C`, with the same static analysis and dynamic
behavior as before the introduction of this feature.
semantics as before the introduction of this feature.

Otherwise, an error occurs if fewer than one or more than one declaration
named `m` was found. *They would necessarily be declared in extensions.*
Otherwise, an error occurs if no declarations named `m` or more than one
declaration named `m` were found. *They would necessarily be declared in
extensions.*

Otherwise, the invocation is resolved to the given static member
declaration in an extension named `Ej`, and the invocation is treated
Expand All @@ -211,7 +215,7 @@ parameters `X1 extends B1 .. Xs extends Bs` and an actual type argument
list `T1 .. Ts` with a type known as the _instantiated constructor return
type of_ _D_ _with type arguments_ `T1 .. Ts`.

When an extension declaration _D_ named `E` has an on-clause which is
When an extension declaration _D_ named `E` has an on-clause which denotes
a non-generic class `C`, the instantiated constructor return type is `C`,
for any list of actual type arguments.

Expand All @@ -221,7 +225,7 @@ passed in an explicitly resolved constructor invocation, e.g.,
`E<int>.C(42)`. In all other invocations, the value of such type variables
is determined by instantiation to bound. In any case, the type parameters
are always ignored by static member declarations, they are only relevant to
constructors.*
constructors and instance members.*

When an extension declaration _D_ has no formal type parameters, and
it has an on-type `C<S1 .. Sk>`, the instantiated constructor return type
Expand Down Expand Up @@ -287,7 +291,7 @@ Otherwise, the invocation is partially resolved to a set of candidate
constructors found in extensions. Each of the candidates _kj_ is
vetted as follows:

Assume that _kj_ is a constructor declared by a extension _D_ named
Assume that _kj_ is a constructor declared by an extension _D_ named
`E` with type parameters `X1 extends B1 .. Xs extends Bs` and on-type
`C<S1 .. Sm>`. Find actual values `U1 .. Us` for `X1 .. Xs` satisfying the
bounds `B1 .. Bs`, such that `([U1/X1 .. Us/Xs]C<S1 .. Sm>) == C<T1 .. Tm>`.
Expand All @@ -300,13 +304,13 @@ henceforth treated as `E<U1 .. Us>.C<T1 .. Tm>.name(args)` (respectively
`E<U1 .. Us>.C<T1 .. Tm>(args)`).

A constructor invocation of the form `C.name(args)` (respectively
`C(args)`) where `C` resolves to a non-generic class is resolved in the
`C(args)`) where `C` denotes a non-generic class is resolved in the
same manner, with `m == 0`. *In this case, type parameters declared by `E`
will be bound to values selected by instantiation to bound.*

Consider a constructor invocation of the form `C.name(args)` (and similarly
for `C(args)`) where `C` resolves to a generic class. As usual, the
invocation is treated as in the pre-feature language when it resolves to a
for `C(args)`) where `C` denotes a generic class. As usual, the
invocation is treated as in the pre-feature language when it denotes a
constructor declared by the class `C`.

In the case where the context type schema for this invocation fully
Expand All @@ -315,7 +319,7 @@ receive said actual type arguments, `C<T1 .. Tm>.name(args)`, and treated
as described above.

In the case where the invocation resolves to exactly one constructor
`C.name` (or `C`) declared by a extension named `E`, the invocation
`C.name` (or `C`) declared by an extension named `E`, the invocation
is treated as `E.C.name(args)` (respectively `E.C(args)`).

Otherwise, when there are two or more candidates from extensions,
Expand Down

0 comments on commit bcc432b

Please sign in to comment.