[XL] Change in dart/sdk[main]: Add diagnostic docs for extension types

0 views
Skip to first unread message

Brian Wilkerson (Gerrit)

unread,
Aug 23, 2023, 2:15:16 PM8/23/23
to Marya Belanger, dart-analys...@google.com, rev...@dartlang.org, Brian Wilkerson

Attention is currently required from: Marya Belanger.

Brian Wilkerson would like Marya Belanger to review this change.

View Change

Add diagnostic docs for extension types

I'm fairly sure there will be other diagnostics added later, so this
isn't everything, but it covers the diagnostics that are currently
implemented in the analyzer.

Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
---
M pkg/analyzer/messages.yaml
M pkg/analyzer/tool/diagnostics/diagnostics.md
2 files changed, 1,020 insertions(+), 5 deletions(-)

diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index a6dcdd4..3f5df9e 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -1163,7 +1163,51 @@
await expression.)
AWAIT_OF_EXTENSION_TYPE_NOT_FUTURE:
problemMessage: "The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'."
- correctionMessage: Try updating the extension type to implement 'Future'.
+ correctionMessage: Try removing the `await`, or updating the extension type to implement 'Future'.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when the type of the expression in
+ an `await` expression is an extension type and the extension type isn't a
+ subclass of `Future`.
+
+ #### Example
+
+ The following code produces this diagnostic because the extension type `E`
+ isn't a subclass of `Future`:
+
+ ```dart
+ extension type E(int i) {}
+
+ void f(E e) async {
+ [!await!] e;
+ }
+ ```
+
+ #### Common fixes
+
+ If the extension type is correctly defined, then remove the `await`:
+
+ ```dart
+ extension type E(int i) {}
+
+ void f(E e) {
+ e;
+ }
+ ```
+
+ If the extension type is intended to be awaitable, then add `Future` (or a
+ subtype of `Future`) to the `implements` clause (adding an `implements`
+ clause if there isn't one already), and make the representation type
+ match:
+
+ ```dart
+ extension type E(Future<int> i) implements Future<int> {}
+
+ void f(E e) async {
+ await e;
+ }
+ ```
BASE_CLASS_IMPLEMENTED_OUTSIDE_OF_LIBRARY:
sharedName: INVALID_USE_OF_TYPE_OUTSIDE_LIBRARY
problemMessage: "The class '{0}' can't be implemented outside of its library because it's a base class."
@@ -5105,28 +5149,219 @@
problemMessage: "Extension type constructors can't declare super formal parameters."
correctionMessage: Try removing the super formal parameter declaration.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when a constructor in an extension
+ type has a super parameter. Super parameters aren't valid because
+ extension types don't have a superclass.
+
+ #### Example
+
+ The following code produces this diagnostic because the named constructor
+ `n` contains a super parameter:
+
+ ```dart
+ extension type E(int i) {
+ E.n(this.i, [!super!].foo);
+ }
+ ```
+
+ #### Common fixes
+
+ If the parameter is needed, replace the super parameter with a normal
+ parameter and make use of it:
+
+ ```dart
+ extension type E(int i) {
+ E.n(this.i, String foo);
+ }
+ ```
+
+ If the parameter isn't needed, remove the super parameter:
+
+ ```dart
+ extension type E(int i) {
+ E.n(this.i);
+ }
+ ```
EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION:
- problemMessage: "Extension type constructors can't include superinitializers."
- correctionMessage: Try removing the superconstructor invocation.
+ problemMessage: Extension type constructors can't include super initializers.
+ correctionMessage: Try removing the super constructor invocation.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when a constructor in an extension
+ type includes an invocation of a super constructor in the initializer
+ list. Because there is no superclass, there's no constructor to invoke.
+
+ #### Example
+
+ The following code produces this diagnostic because there is an invocation
+ of a super constructor in the initializer list of `E.n`:
+
+ ```dart
+ extension type E(int i) {
+ E.n() : i = 0, [!super!].n();
+ }
+ ```
+
+ #### Common fixes
+
+ Remove the invocation of the super constructor:
+
+ ```dart
+ extension type E(int i) {
+ E.n() : i = 0;
+ }
+ ```
EXTENSION_TYPE_DECLARES_INSTANCE_FIELD:
problemMessage: "Extension types can't declare instance fields."
correctionMessage: Try replacing the field with a getter.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when there's a field declaration in
+ the body of an extension type declaration.
+
+ #### Example
+
+ The following code produces this diagnostic because the extension type `E`
+ declares a field named `f`:
+
+ ```dart
+ extension type E(int i) {
+ final int [!f!] = 0;
+ }
+ ```
+
+ #### Common fixes
+
+ If you don't need the field, then remove it or replace it with a getter
+ and/or setter:
+
+ ```dart
+ extension type E(int i) {
+ int get f => 0;
+ }
+ ```
+
+ If you need the field, then convert the extension type into a class:
+
+ ```dart
+ class E {
+ final int i;
+
+ final int f = 0;
+
+ E(this.i);
+ }
+ ```
EXTENSION_TYPE_DECLARES_MEMBER_OF_OBJECT:
problemMessage: "Extension types can't declare members with the same name as a member declared by 'Object'."
correctionMessage: Try specifying a different name for the member.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when the body of an extension type
+ declaration contains a member with the same name as one of the members
+ declared by `Object`.
+
+ #### Example
+
+ The following code produces this diagnostic because the class `Object`
+ defines a member named `hashCode`:
+
+ ```dart
+ extension type E(int i) {
+ int get [!hashCode!] => 0;
+ }
+ ```
+
+ #### Common fixes
+
+ If you need a member with the implemented semantics, then rename the
+ member:
+
+ ```dart
+ extension type E(int i) {
+ int get myHashCode => 0;
+ }
+ ```
+
+ If you don't need a member with the implemented semantics, then remove the
+ member:
+
+ ```dart
+ extension type E(int i) {}
+ ```
EXTENSION_TYPE_IMPLEMENTS_DISALLOWED_TYPE:
problemMessage: "Extension types can't implement '{0}'."
correctionMessage: Try specifying a different type, or remove the type from the list.
comment: |-
Parameters:
0: the display string of the disallowed type
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when an extension type implements a
+ type that it isn't allowed to implement.
+
+ #### Example
+
+ The following code produces this diagnostic because the type `dynamic`
+ can't be implemented by an extension type:
+
+ ```dart
+ extension type A(int i) implements [!dynamic!] {}
+ ```
+
+ #### Common fixes
+
+ Remove the disallowed type from the implements clause:
+
+ ```dart
+ extension type A(int i) {}
+ ```
EXTENSION_TYPE_IMPLEMENTS_ITSELF:
problemMessage: "The extension type can't implement itself."
correctionMessage: Try removing the superinterface that references this extension type.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when an extension type implements
+ itself, either directly or indirectly.
+
+ #### Example
+
+ The following code produces this diagnostic because the extension type `A`
+ directly implements itself:
+
+ ```dart
+ extension type [!A!](int i) implements A {}
+ ```
+
+ The following code produces this diagnostic because the extension type `A`
+ indirectly implements itself (through `B`):
+
+ ```dart
+ extension type [!A!](int i) implements B {}
+ extension type [!B!](int i) implements A {}
+ ```
+
+ #### Common fixes
+
+ Break the cycle by removing a type from the implements clause of at least
+ one of the types in the cycle:
+
+ ```dart
+ extension type A(int i) implements B {}
+ extension type B(int i) {}
+ ```
EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE:
problemMessage: "'{0}' is not a supertype of '{1}', the representation type."
correctionMessage: Try specifying a different type, or remove the type from the list.
@@ -5134,6 +5369,38 @@
Parameters:
0: the implemented not extension type
1: the ultimate representation type
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when the implements clause in an
+ extension type includes a type that isn't a supertype of the
+ representation type.
+
+ #### Example
+
+ The following code produces this diagnostic because the type `String` is
+ in the implements clause, but `String` isn't a supertype of the
+ representation type `int`:
+
+ ```dart
+ extension type A(int i) implements [!String!] {}
+ ```
+
+ #### Common fixes
+
+ If the representation type is correct, then remove or replace the type in
+ the implements clause:
+
+ ```dart
+ extension type A(int i) {}
+ ```
+
+ If the representation type isn't correct, then replace it with the correct
+ type:
+
+ ```dart
+ extension type A(String s) implements String {}
+ ```
EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE:
problemMessage: "'{0}', the representation type of '{1}', is not a supertype of '{2}', the representation type of '{3}'."
correctionMessage: Try specifying a different type, or remove the type from the list.
@@ -5143,6 +5410,42 @@
1: the name of the implemented extension type
2: the representation type of the this extension type
3: the name of the this extension type
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when an extension type implements
+ another extension type, and the representation type of the implemented
+ extension type isn't a subtype of the representation type of the implementing
+ extension type.
+
+ #### Example
+
+ The following code produces this diagnostic because the extension type `B`
+ implements `A`, but the representation type of `A` (`int`) isn't a
+ subtype of the representation type of `B` (`String`):
+
+ ```dart
+ extension type A(int i) {}
+ extension type B(String s) implements [!A!] {}
+ ```
+
+ #### Common fixes
+
+ Either change the representation types of the two extension types so that
+ the representation type of the implemented type is a supertype of the
+ representation type of the implementing type:
+
+ ```dart
+ extension type A(int i) {}
+ extension type B(num n) implements A {}
+ ```
+
+ Or remove the implemented type from the implements clause:
+
+ ```dart
+ extension type A(int i) {}
+ extension type B(String s {}
+ ```
EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
problemMessage: "The extension type '{0}' has more than one distinct member named '{1}' from implemented types."
correctionMessage: Try redeclaring the corresponding member in this extension type.
@@ -5150,10 +5453,110 @@
Parameters:
0: the name of the extension type
1: the name of the conflicting member
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when an extension type implements
+ two or more other types, and at least two of those types declare a member
+ with the same name.
+
+ #### Example
+
+ The following code produces this diagnostic because the extension type `C`
+ implements both `A` and `B`, and both declare a member named `m`:
+
+ ```dart
+ class A {
+ void m() {}
+ }
+
+ extension type B(A a) {
+ void m() {}
+ }
+
+ extension type [!C!](A a) implements A, B {}
+ ```
+
+ #### Common fixes
+
+ If the extension type doesn't need to implement all of the listed types,
+ then remove all but one of the types introducing the conflicting members:
+
+ ```dart
+ class A {
+ void m() {}
+ }
+
+ extension type B(A a) {
+ void m() {}
+ }
+
+ extension type C(A a) implements A {}
+ ```
+
+ If the extension type needs to implement all of the listed types but you
+ can rename the members in those types, then rename the members to have
+ unique names:
+
+ ```dart
+ class A {
+ void m() {}
+ }
+
+ extension type B(A a) {
+ void n() {}
+ }
+
+ extension type C(A a) implements A, B {}
+ ```
EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF:
problemMessage: "The extension type representation can't depend on itself."
correctionMessage: Try specifying a different type.
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when an extension type has a
+ representation type that depends on the extension type itself, either
+ directly or indirectly.
+
+ #### Example
+
+ The following code produces this diagnostic because the representation
+ type of the extension type `A` depends on `A` directly:
+
+ ```dart
+ extension type [!A!](A a) {}
+ ```
+
+ The following code produces this diagnostic because the representation
+ type of the extension type `A` depends on `A` indirectly through the
+ extension type `B`:
+
+ ```dart
+ extension type [!A!](B b) {}
+
+ extension type [!B!](A a) {}
+ ```
+
+ The following code produces this diagnostic because the representation
+ type of the extension type `A` depends on `A` indirectly through the
+ extension type `B`:
+
+ ```dart
+ extension type [!A!](List<B> b) {}
+
+ extension type [!B!](List<A> a) {}
+ ```
+
+ #### Common fixes
+
+ Remove the dependency by choosing a different representation type for at
+ least one of the types in the cycle:
+
+ ```dart
+ extension type A(String s) {}
+ ```
EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER:
sharedName: EXTERNAL_WITH_INITIALIZER
problemMessage: External fields can't have initializers.
@@ -11063,6 +11466,30 @@
problemMessage: "An extension type parameter can't be used in a non-covariant position of its representation type."
correctionMessage: "Try removing the type parameters from function parameter types and type parameter bounds."
comment: No parameters.
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when a type parameter of an
+ extension type is used in a non-covariant position in the representation
+ type of that extension type.
+
+ #### Example
+
+ The following code produces this diagnostic because the type parameter `T`
+ is used as a parameter type in the function type `void Function(T)`, and
+ parameters are not covariant:
+
+ ```dart
+ extension type A<[!T!]>(void Function(T) f) {}
+ ```
+
+ #### Common fixes
+
+ Remove the use of the type parameter:
+
+ ```dart
+ extension type A(void Function(String) f) {}
+ ```
NON_EXHAUSTIVE_SWITCH_EXPRESSION:
problemMessage: "The type '{0}' is not exhaustively matched by the switch cases since it doesn't match '{1}'."
correctionMessage: "Try adding a wildcard pattern or cases that match '{2}'."
@@ -20886,7 +21313,7 @@
#### Common fixes

If you can rely on automatic platform detection, then omit the
- top-level `platforms` field.
+ top-level `platforms` field.

```yaml
%uri="pubspec.yaml"
@@ -24090,6 +24517,58 @@

Parameters:
0: the kind of member
+ documentation: |-
+ #### Description
+
+ The analyzer produces this diagnostic when a member of an extension type
+ is annotated with `@redeclare`, but none of the implemented interfaces
+ has a member with the same name.
+
+ #### Example
+
+ The following code produces this diagnostic because the member `n`
+ declared by the extension type `E` is annotated with `@redeclare`, but `C`
+ doesn't have a member named `n`:
+
+ ```dart
+ class C {
+ void m() {}
+ }
+
+ extension type E(C c) implements C {
+ @redeclare
+ void n() {}
+ }
+ ```
+
+ #### Common fixes
+
+ If the annotated member has the right name, then remove the annotation:
+
+ ```dart
+ class C {
+ void m() {}
+ }
+
+ extension type E(C c) implements C {
+ void n() {}
+ }
+ ```
+
+ If the annotated member is suppose to replace a member from the
+ implemented interfaces, then change the name of the annotated member to
+ match the member being replaced:
+
+ ```dart
+ class C {
+ void m() {}
+ }
+
+ extension type E(C c) implements C {
+ @redeclare
+ void m() {}
+ }
+ ```
REMOVED_LINT_USE:
problemMessage: "'{0}' was removed in Dart '{1}'"
correctionMessage: "Remove the reference to '{0}'."
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index ae53c67..83abc84 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -1472,6 +1472,55 @@
}
{% endprettify %}

+### await_of_extension_type_not_future
+
+_The 'await' expression can't be used for an expression with an extension type
+that is not a subtype of 'Future'._
+
+#### Description
+
+The analyzer produces this diagnostic when the type of the expression in
+an `await` expression is an extension type and the extension type isn't a
+subclass of `Future`.
+
+#### Example
+
+The following code produces this diagnostic because the extension type `E`
+isn't a subclass of `Future`:
+
+{% prettify dart tag=pre+code %}
+extension type E(int it) {}
+
+void f(E e) async {
+ [!await!] e;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the extension type is correctly defined, then remove the `await`:
+
+{% prettify dart tag=pre+code %}
+extension type E(int it) {}
+
+void f(E e) {
+ e;
+}
+{% endprettify %}
+
+If the extension type is intended to be awaitable, then add `Future` (or a
+subtype of `Future`) to the `implements` clause (adding an `implements`
+clause if there isn't one already), and make the representation type
+match:
+
+{% prettify dart tag=pre+code %}
+extension type E(Future<int> it) implements Future<int> {}
+
+void f(E e) async {
+ await e;
+}
+{% endprettify %}
+
### body_might_complete_normally

_The body might complete normally, causing 'null' to be returned, but the return
@@ -6136,6 +6185,408 @@
If there are multiple cascaded accesses, you'll need to duplicate the
extension override for each one.

+### extension_type_constructor_with_super_formal_parameter
+
+_Extension type constructors can't declare super formal parameters._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor in an extension
+type has a super parameter. Super parameters aren't valid because
+extension types don't have a superclass.
+
+#### Example
+
+The following code produces this diagnostic because the named constructor
+`n` contains a super parameter:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ E.n(this.i, [!super!].foo);
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the parameter is needed, replace the super parameter with a normal
+parameter and make use of it:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ E.n(this.i, String foo);
+}
+{% endprettify %}
+
+If the parameter isn't needed, remove the super parameter:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ E.n(this.i);
+}
+{% endprettify %}
+
+### extension_type_constructor_with_super_invocation
+
+_Extension type constructors can't include super initializers._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor in an extension
+type includes an invocation of a super constructor in the initializer
+list. Because there is no superclass, there's no constructor to invoke.
+
+#### Example
+
+The following code produces this diagnostic because there is an invocation
+of a super constructor in the initializer list of `E.n`:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ E.n() : i = 0, [!super!].n();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the invocation of the super constructor:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ E.n() : i = 0;
+}
+{% endprettify %}
+
+### extension_type_declares_instance_field
+
+_Extension types can't declare instance fields._
+
+#### Description
+
+The analyzer produces this diagnostic when there's a field declaration in
+the body of an extension type declaration.
+
+#### Example
+
+The following code produces this diagnostic because the extension type `E`
+declares a field named `f`:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ final int [!f!] = 0;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you don't need the field, then remove it or replace it with a getter
+and/or setter:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ int get f => 0;
+}
+{% endprettify %}
+
+If you need the field, then convert the extension type into a class:
+
+{% prettify dart tag=pre+code %}
+class E {
+ final int i;
+
+ final int f = 0;
+
+ E(this.i);
+}
+{% endprettify %}
+
+### extension_type_declares_member_of_object
+
+_Extension types can't declare members with the same name as a member declared
+by 'Object'._
+
+#### Description
+
+The analyzer produces this diagnostic when the body of an extension type
+declaration contains a member with the same name as one of the members
+declared by `Object`.
+
+#### Example
+
+The following code produces this diagnostic because the class `Object`
+defines a member named `hashCode`:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ int get [!hashCode!] => 0;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you need a member with the implemented semantics, then rename the
+member:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {
+ int get myHashCode => 0;
+}
+{% endprettify %}
+
+If you don't need a member with the implemented semantics, then remove the
+member:
+
+{% prettify dart tag=pre+code %}
+extension type E(int i) {}
+{% endprettify %}
+
+### extension_type_implements_disallowed_type
+
+_Extension types can't implement '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension type implements a
+type that it isn't allowed to implement.
+
+#### Example
+
+The following code produces this diagnostic because the type `dynamic`
+can't be implemented by an extension type:
+
+{% prettify dart tag=pre+code %}
+extension type A(int it) implements [!dynamic!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the disallowed type from the implements clause:
+
+{% prettify dart tag=pre+code %}
+extension type A(int it) {}
+{% endprettify %}
+
+### extension_type_implements_itself
+
+_The extension type can't implement itself._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension type implements
+itself, either directly or indirectly.
+
+#### Example
+
+The following code produces this diagnostic because the extension type `A`
+directly implements itself:
+
+{% prettify dart tag=pre+code %}
+extension type [!A!](int it) implements A {}
+{% endprettify %}
+
+The following code produces this diagnostic because the extension type `A`
+indirectly implements itself (through `B`):
+
+{% prettify dart tag=pre+code %}
+extension type [!A!](int it) implements B {}
+extension type [!B!](int it) implements A {}
+{% endprettify %}
+
+#### Common fixes
+
+Break the cycle by removing a type from the implements clause of at least
+one of the types in the cycle:
+
+{% prettify dart tag=pre+code %}
+extension type A(int it) implements B {}
+extension type B(int it) {}
+{% endprettify %}
+
+### extension_type_implements_not_supertype
+
+_'{0}' is not a supertype of '{1}', the representation type._
+
+#### Description
+
+The analyzer produces this diagnostic when the implements clause in an
+extension type includes a type that isn't a supertype of the
+representation type.
+
+#### Example
+
+The following code produces this diagnostic because the type `String` is
+in the implements clause, but `String` isn't a supertype of the
+representation type `int`:
+
+{% prettify dart tag=pre+code %}
+extension type A(int it) implements [!String!] {}
+{% endprettify %}
+
+#### Common fixes
+
+If the representation type is correct, then remove or replace the type in
+the implements clause:
+
+{% prettify dart tag=pre+code %}
+extension type A(int it) {}
+{% endprettify %}
+
+If the representation type isn't correct, then replace it with the correct
+type:
+
+{% prettify dart tag=pre+code %}
+extension type A(String it) implements String {}
+{% endprettify %}
+
+### extension_type_implements_representation_not_supertype
+
+_'{0}', the representation type of '{1}', is not a supertype of '{2}', the
+representation type of '{3}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension type implements
+another extension type, and the representation type of the implemented
+extension type isn't a subtype of the representation type of the implementing
+extension type.
+
+#### Example
+
+The following code produces this diagnostic because the extension type `B`
+implements `A`, but the representation type of `A` (`int`) isn't a
+subtype of the representation type of `B` (`String`):
+
+{% prettify dart tag=pre+code %}
+extension type A(int i) {}
+extension type B(String s) implements [!A!] {}
+{% endprettify %}
+
+#### Common fixes
+
+Either change the representation types of the two extension types so that
+the representation type of the implemented type is a supertype of the
+representation type of the implementing type:
+
+{% prettify dart tag=pre+code %}
+extension type A(int i) {}
+extension type B(num n) implements A {}
+{% endprettify %}
+
+Or remove the implemented type from the implements clause:
+
+{% prettify dart tag=pre+code %}
+extension type A(int i) {}
+extension type B(String s {}
+{% endprettify %}
+
+### extension_type_inherited_member_conflict
+
+_The extension type '{0}' has more than one distinct member named '{1}' from
+implemented types._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension type implements
+two or more other types, and at least two of those types declare a member
+with the same name.
+
+#### Example
+
+The following code produces this diagnostic because the extension type `C`
+implements both `A` and `B`, and both declare a member named `m`:
+
+{% prettify dart tag=pre+code %}
+class A {
+ void m() {}
+}
+
+extension type B(A a) {
+ void m() {}
+}
+
+extension type [!C!](A a) implements A, B {}
+{% endprettify %}
+
+#### Common fixes
+
+If the extension type doesn't need to implement all of the listed types,
+then remove all but one of the types introducing the conflicting members:
+
+{% prettify dart tag=pre+code %}
+class A {
+ void m() {}
+}
+
+extension type B(A a) {
+ void m() {}
+}
+
+extension type C(A a) implements A {}
+{% endprettify %}
+
+If the extension type needs to implement all of the listed types but you
+can rename the members in those types, then rename the members to have
+unique names:
+
+{% prettify dart tag=pre+code %}
+class A {
+ void m() {}
+}
+
+extension type B(A a) {
+ void n() {}
+}
+
+extension type C(A a) implements A, B {}
+{% endprettify %}
+
+### extension_type_representation_depends_on_itself
+
+_The extension type representation can't depend on itself._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension type has a
+representation type that depends on the extension type itself, either
+directly or indirectly.
+
+#### Example
+
+The following code produces this diagnostic because the representation
+type of the extension type `A` depends on `A` directly:
+
+{% prettify dart tag=pre+code %}
+extension type [!A!](A a) {}
+{% endprettify %}
+
+The following code produces this diagnostic because the representation
+type of the extension type `A` depends on `A` indirectly through the
+extension type `B`:
+
+{% prettify dart tag=pre+code %}
+extension type [!A!](B b) {}
+
+extension type [!B!](A a) {}
+{% endprettify %}
+
+The following code produces this diagnostic because the representation
+type of the extension type `A` depends on `A` indirectly through the
+extension type `B`:
+
+{% prettify dart tag=pre+code %}
+extension type [!A!](List<B> b) {}
+
+extension type [!B!](List<A> a) {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the dependency by choosing a different representation type for at
+least one of the types in the cycle:
+
+{% prettify dart tag=pre+code %}
+extension type A(String s) {}
+{% endprettify %}
+
### external_with_initializer

_External fields can't have initializers._
@@ -10188,7 +10639,7 @@
#### Common fixes

If you can rely on automatic platform detection, then omit the
-top-level `platforms` field.
+top-level `platforms` field.

{% prettify yaml tag=pre+code %}
name: example
@@ -14185,6 +14636,35 @@
}
{% endprettify %}

+### non_covariant_type_parameter_position_in_representation_type
+
+_An extension type parameter can't be used in a non-covariant position of its
+representation type._
+
+#### Description
+
+The analyzer produces this diagnostic when a type parameter of an
+extension type is used in a non-covariant position in the representation
+type of that extension type.
+
+#### Example
+
+The following code produces this diagnostic because the type parameter `T`
+is used as a parameter type in the function type `void Function(T)`, and
+parameters are not covariant:
+
+{% prettify dart tag=pre+code %}
+extension type A<[!T!]>(void Function(T) f) {}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the use of the type parameter:
+
+{% prettify dart tag=pre+code %}
+extension type A(void Function(String) f) {}
+{% endprettify %}
+
### non_exhaustive_switch_expression

_The type '{0}' is not exhaustively matched by the switch cases since it doesn't
@@ -16857,6 +17337,62 @@

Change the type hierarchy so that there's no circularity.

+### redeclare_on_non_redeclaring_member
+
+_The {0} doesn't redeclare a {0} declared in a superinterface._
+
+#### Description
+
+The analyzer produces this diagnostic when a member of an extension type
+is annotated with `@redeclare`, but none of the implemented interfaces
+has a member with the same name.
+
+#### Example
+
+The following code produces this diagnostic because the member `n`
+declared by the extension type `E` is annotated with `@redeclare`, but `C`
+doesn't have a member named `n`:
+
+{% prettify dart tag=pre+code %}
+class C {
+ void m() {}
+}
+
+extension type E(C c) implements C {
+ @redeclare
+ void n() {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the annotated member has the right name, then remove the annotation:
+
+{% prettify dart tag=pre+code %}
+class C {
+ void m() {}
+}
+
+extension type E(C c) implements C {
+ void n() {}
+}
+{% endprettify %}
+
+If the annotated member is suppose to replace a member from the
+implemented interfaces, then change the name of the annotated member to
+match the member being replaced:
+
+{% prettify dart tag=pre+code %}
+class C {
+ void m() {}
+}
+
+extension type E(C c) implements C {
+ @redeclare
+ void m() {}
+}
+{% endprettify %}
+
### redirect_generative_to_missing_constructor

_The constructor '{0}' couldn't be found in '{1}'._

To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: newchange
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
Gerrit-Change-Number: 322442
Gerrit-PatchSet: 2
Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
Gerrit-Attention: Marya Belanger <mbel...@google.com>

Brian Wilkerson (Gerrit)

unread,
Aug 23, 2023, 2:15:17 PM8/23/23
to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger

Attention is currently required from: Marya Belanger.

Patch set 2:Commit-Queue +1

View Change

2 comments:

  • File pkg/analyzer/messages.yaml:

    • Patch Set #2, Line 1180: i

      The spec (which most people won't see) uses "it" in most of its examples. I don't know whether we want to have a consistent naming convention at this point or whether we want to wait to see what the community uses. Might want to pull Bob in on the discussion.

    • Patch Set #2, Line 5311: isn't allowed to implement

      Do we want a list of disallowed types here, or will we document this somewhere? The list comes from the specification, which reads:

      A compile-time error occurs if an extension type has a non-extension superinterface whose transitive alias expansion is a type variable, a deferred type, any top type (including dynamic and void), the type Null, any function type, the type Function, any record type, the type Record, or any type of the form T? or FutureOr<T> for any type T.

To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: comment
Gerrit-Project: sdk
Gerrit-Branch: main
Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
Gerrit-Change-Number: 322442
Gerrit-PatchSet: 2
Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
Gerrit-Attention: Marya Belanger <mbel...@google.com>
Gerrit-Comment-Date: Wed, 23 Aug 2023 18:15:13 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes

CBuild (Gerrit)

unread,
Aug 23, 2023, 3:16:22 PM8/23/23
to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Commit Queue, Marya Belanger

Attention is currently required from: Brian Wilkerson, Marya Belanger.

go/dart-cbuild result: SUCCESS

Details: https://goto.google.com/dart-cbuild/find/b8999c68540eb4705ec20aeedff1d49e4664164c

View Change

    To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
    Gerrit-Change-Number: 322442
    Gerrit-PatchSet: 2
    Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
    Gerrit-Attention: Marya Belanger <mbel...@google.com>
    Gerrit-Attention: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Comment-Date: Wed, 23 Aug 2023 19:16:17 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No

    Brian Wilkerson (Gerrit)

    unread,
    Sep 27, 2023, 7:32:19 PM9/27/23
    to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, CBuild, Commit Queue, Marya Belanger

    Attention is currently required from: Marya Belanger.

    View Change

    1 comment:

    • Patchset:

      • Patch Set #4:

        Friendly ping. Not sure when you might have time to start thinking about extension types, so it's ok if it isn't now.

    To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-MessageType: comment
    Gerrit-Project: sdk
    Gerrit-Branch: main
    Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
    Gerrit-Change-Number: 322442
    Gerrit-PatchSet: 4
    Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
    Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
    Gerrit-Attention: Marya Belanger <mbel...@google.com>
    Gerrit-Comment-Date: Wed, 27 Sep 2023 23:32:14 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No

    CBuild (Gerrit)

    unread,
    Oct 2, 2023, 3:59:27 PM10/2/23
    to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Commit Queue, Marya Belanger

    Attention is currently required from: Marya Belanger.

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 4
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Attention: Marya Belanger <mbel...@google.com>
      Gerrit-Comment-Date: Mon, 02 Oct 2023 19:59:23 +0000
      Gerrit-HasComments: No
      Gerrit-Has-Labels: No

      Marya Belanger (Gerrit)

      unread,
      Nov 20, 2023, 6:46:53 PM11/20/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, CBuild, Commit Queue

      Attention is currently required from: Brian Wilkerson.

      Patch set 4:Code-Review +1

      View Change

      18 comments:

        •   The following code produces this diagnostic because the named constructor

        •       `n` contains a super parameter:

        • Is the fact that it's a named constructor part of the reason this may occur, or just an example? Just curious

        • Patch Set #4, Line 5176: If the parameter is needed

          ```suggestion
          If you need the parameter, replace the super parameter with a normal
          ```
        • Patch Set #4, Line 5177: and make use of it

          This is just referring to the fact that if you define a parameter and don't use it, that's an error too, right? If so, "and make use of it" is probably redundant with "If the parameter is needed", since if it's needed it's probably because they need to use it. In that case I would remove "and make use of it".

          If there's something specific to making use of it that solves this diagnostic, I would show that in the code example (it's not shown being made use of currently).

        • Patch Set #4, Line 5185: If the parameter isn't needed

          ```suggestion
          If you need the parameter, remove the super parameter:
          ```
        • Patch Set #4, Line 5199:

        • a constructor in an extension

        •       type

          "...when the constructor of an extension type..."?

          "a" constructor makes it sound like there could be multiple...? I don't know if that's possible; if it is, leave as is.

        • Patch Set #4, Line 5201: Because there is no superclass, there's no constructor to invoke.

          ```suggestion
          list. Because extension types don't have a superclass, there is no super constructor to invoke.

          ```

        • Patch Set #4, Line 5205:

        •       The following code produces this diagnostic because there is an invocation

        •       of a super constructor in the initializer list of `E.n`:

        • ```suggestion
          The following code produces this diagnostic because the constructor
          `E.n` invokes a super constructor in its initializer list:
          ```
        • Patch Set #4, Line 5247: and/or

          Is it "and/or" because you could replace if with both? What would replacing it with a getter and setter look like?

        • Patch Set #4, Line 5280: defines a member named `hashCode`:

          ```suggestion
          already defines a member named `hashCode`:
          ```
        • Patch Set #4, Line 5319:

        •       The following code produces this diagnostic because the type `dynamic`

        •       can't be implemented by an extension type:

        • ```suggestion
          The following code produces this diagnostic because extension types
          can't implement the type `dynamic`:
          ```
        • Patch Set #4, Line 5362:


        • Break the cycle by removing a type from the implements clause of at least

        •       one of the types in the cycle:

        • This ones a mind bender; my suggestion might incorrectly change the meaning

          ```suggestion
          Remove one of the types from at least one of the implements clauses
          causing the self-referential cycle:
          ```
        • Patch Set #4, Line 5381:

        •       The analyzer produces this diagnostic when the implements clause in an

        •       extension type includes a type that isn't a supertype of the

        •       representation type.

          Does this mean the same thing?:

          ```suggestion

        • The analyzer produces this diagnostic when an extension type
        •       The following code produces this diagnostic because the type `String` is

        •       in the implements clause, but `String` isn't a supertype of the

        •       representation type `int`:

          ```suggestion
          The following code produces this diagnostic because extension type `A`
          implements `String`, but `String` isn't a supertype of the
          representation type `int`:
          ```
        • Patch Set #4, Line 5422:

        •       The analyzer produces this diagnostic when an extension type implements

        •       another extension type, and the representation type of the implemented

        •       extension type isn't a subtype of the representation type of the implementing

        •       extension type.

          After reading the problem message, I thought this would be very confusing, but it's not at all!

        • Patch Set #4, Line 5507:

        • then rename the members to have

        •       unique names:

          ```suggestion
          can rename the members in those types, then give the conflicting
          members unique names:
          ```
        • Patch Set #4, Line 5541:

        •       The following code produces this diagnostic because the representation

        •       type of the extension type `A` depends on `A` indirectly through the

        •       extension type `B`:

          ```dart


        • extension type [!A!](B b) {}

        •       extension type [!B!](A a) {}

        •       ```



        • The following code produces this diagnostic because the representation

        •       type of the extension type `A` depends on `A` indirectly through the

        •       extension type `B`:

          ```dart


        • extension type [!A!](List<B> b) {}

        •       extension type [!B!](List<A> a) {}

        •       ```

          Is the second "indirect" example so different that it can't be extrapolated from the first? Like, if someone had code written like the `List` example, but only saw the other indirect example, would they understand their error? Genuine question because I'm not sure just how different `List<type>` is understood by the general user

        • Patch Set #4, Line 11494:

        •     The following code produces this diagnostic because the type parameter `T`

        •       is used as a parameter type in the function type `void Function(T)`, and

        •       parameters are not covariant:

          ```suggestion

        • The following code produces this diagnostic because the extension type
        •       parameter `T` is used as a parameter type in the function type
          `void Function(T)`, and parameters are not covariant:
          ```

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 4
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Attention: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Comment-Date: Mon, 20 Nov 2023 23:46:48 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes

      Brian Wilkerson (Gerrit)

      unread,
      Nov 21, 2023, 3:11:38 PM11/21/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org

      Attention is currently required from: Brian Wilkerson.

      Brian Wilkerson uploaded patch set #5 to this change.

      View Change

      Add diagnostic docs for extension types

      I'm fairly sure there will be other diagnostics added later, so this
      isn't everything, but it covers the diagnostics that are currently
      implemented in the analyzer.

      Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      ---
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/verify_diagnostics_test.dart
      M pkg/analyzer/tool/diagnostics/diagnostics.md
      3 files changed, 1,042 insertions(+), 5 deletions(-)

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: newpatchset
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 5

      Brian Wilkerson (Gerrit)

      unread,
      Nov 21, 2023, 3:12:56 PM11/21/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger, CBuild, Commit Queue

      Attention is currently required from: Marya Belanger.

      View Change

      19 comments:

      • Patchset:

        • Patch Set #5:

          There are a few unresolved comments, so I'll wait to land this until you've had a chance to respond.

      • File pkg/analyzer/messages.yaml:

        • ```suggestion […]

          Done

        • Patch Set #4, Line 5165:

            The following code produces this diagnostic because the named constructor
          `n` contains a super parameter:

        • Is the fact that it's a named constructor part of the reason this may occur, or just an example? Jus […]

          The unnamed constructor is usually defined by the representation declaration: `(int i)`. That means that any constructors in the body of the extension type will usually be named constructors. It's possible for the representation declaration to declare a named constructor, so it's possible to have an unnamed constructor in the body, but I expect it will be less common, hence the choice of making it a named constructor in the example.

          This would look like the following:
          ```
          extension type E.n(int i) {
          E(this.i, [!super!].foo);
          }
          ```

          We could add this example if you think it would be useful for completeness (and/or education).

        • ```suggestion […]

          Done

        • This is just referring to the fact that if you define a parameter and don't use it, that's an error […]

          No, it isn't an error to define a parameter and not use it (although we do have a lint to catch that case because there's no value in declaring an unused parameter).

          I've removed the phrase.

        • ```suggestion […]

          Rewritten to "If you don't need the parameter" to preserve the original meaning.

        • "...when the constructor of an extension type..."? […]

          Yes, an extension type can have multiple constructors. The example above for `EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_FORMAL_PARAMETER` shows an extension type with two constructors, but in general there can be one or more.

        • ```suggestion […]

          I replaced the first clause, but left the contraction ("there's"). If you want it changed too, let me know.

        • Patch Set #4, Line 5205:

                The following code produces this diagnostic because there is an invocation
          of a super constructor in the initializer list of `E.n`:

        • ```suggestion […]

          Done

        • Is it "and/or" because you could replace if with both? What would replacing it with a getter and set […]

          It's "and/or" because a field marked `final` or `const` induces a getter (and hence would be replaced by just a getter) while a field that isn't marked with either of those induces both a getter and a setter and would need both to preserve semantics.

          Not very well worded.

        • ```suggestion […]

          Done

        • Patch Set #4, Line 5319:

                The following code produces this diagnostic because the type `dynamic`
          can't be implemented by an extension type:

        • ```suggestion […]

          Done

        • Patch Set #4, Line 5362:


          Break the cycle by removing a type from the implements clause of at least
          one of the types in the cycle:

        • This ones a mind bender; my suggestion might incorrectly change the meaning […]

          I don't think it changes the meaning, but it doesn't quite sound right somehow. Some possible embellishments for you to consider:

          "causing" -->
          "that are causing"
          "involved in"
          "in the"
        • Patch Set #4, Line 5381:

                The analyzer produces this diagnostic when the implements clause in an
          extension type includes a type that isn't a supertype of the
          representation type.

        • Does this mean the same thing?: […]

          Yes. Change made.

        • Patch Set #4, Line 5387:

                The following code produces this diagnostic because the type `String` is
          in the implements clause, but `String` isn't a supertype of the
          representation type `int`:

        • ```suggestion […]

          Done

        • Patch Set #4, Line 5422:

                The analyzer produces this diagnostic when an extension type implements
          another extension type, and the representation type of the implemented
          extension type isn't a subtype of the representation type of the implementing
          extension type.

          After reading the problem message, I thought this would be very confusing, but it's not at all!

        • I'll try harder to be confusing next time. :-)

        • ```suggestion […]

          Done

        • Patch Set #4, Line 5541:

                The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](B b) {}

          extension type [!B!](A a) {}
          ```

          The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](List<B> b) {}

          extension type [!B!](List<A> a) {}
          ```

        • Is the second "indirect" example so different that it can't be extrapolated from the first? Like, if […]

          That's a good question. I don't know the answer. I'm happy to remove the second example if you think it's unnecessary.

          The reason I added it is because I wasn't sure that all users would understand that the dependency could be introduced in this indirect way.

        • Patch Set #4, Line 11494:

              The following code produces this diagnostic because the type parameter `T`
          is used as a parameter type in the function type `void Function(T)`, and
          parameters are not covariant:

        • ```suggestion […]

          I'm not sure that adding "extension" helps; it might even be harmful. The reason I say that is because both "extension type" and "type parameter" are meaningful phrases, but my brain doesn't know to associate "type" when it's in the middle.

          If we thought we needed to qualify a type parameter on a class we could call it a "class type parameter" (I don't think I've ever seen that, but I would understand it), but to qualify `T` we'd really want to call it an "extension type type parameter", but that's confusing.

          That said, I don't know what value there is in qualifying "type parameter" in this context.

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 5
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Attention: Marya Belanger <mbel...@google.com>
      Gerrit-Comment-Date: Tue, 21 Nov 2023 20:12:52 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Marya Belanger <mbel...@google.com>

      Marya Belanger (Gerrit)

      unread,
      Nov 22, 2023, 12:47:53 PM11/22/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, CBuild, Commit Queue

      Attention is currently required from: Brian Wilkerson.

      Patch set 5:Code-Review +1

      View Change

      9 comments:

        •   The following code produces this diagnostic because the named constructor
          `n` contains a super parameter:

        • The unnamed constructor is usually defined by the representation declaration: `(int i)`. […]

        • That makes sense, we don't need to add the unnamed example. I'll try to include how extension types lean towards named constructors in the general documentation too, so hopefully that'll support it. Thank you!

        • Rewritten to "If you don't need the parameter" to preserve the original meaning.

          Oh right, my mistake! Thanks for catching that

        • I replaced the first clause, but left the contraction ("there's"). […]

          That's fine, lgtm

        • It's "and/or" because a field marked `final` or `const` induces a getter (and hence would be replace […]

          I see. You've probably written it the best way to account for all that information without giving a whole lesson on fields, so "and/or" is fine.

        • Patch Set #4, Line 5362:


          Break the cycle by removing a type from the implements clause of at least
          one of the types in the cycle:

        • I don't think it changes the meaning, but it doesn't quite sound right somehow. […]

          Reading today with fresh eyes, the original is probably the best version, maybe with replacing "in" with "involved in":

        •       Break the cycle by removing a type from the implements clause of at least
        •       one of the types involved in the cycle:
        • Patch Set #4, Line 5422:

                The analyzer produces this diagnostic when an extension type implements
          another extension type, and the representation type of the implemented
          extension type isn't a subtype of the representation type of the implementing
          extension type.

        • I'll try harder to be confusing next time. […]

          Hahaha

        • Patch Set #4, Line 5541:

                The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](B b) {}

          extension type [!B!](A a) {}
          ```

          The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](List<B> b) {}

          extension type [!B!](List<A> a) {}
          ```

        • That's a good question. I don't know the answer. […]

          Ok, let's leave it then. Maybe there's a way to write it where you don't have to have the text repeated:


          The following two code examples produce this diagnostic because the

        • representation type of the extension type `A` depends on `A`
          indirectly through the extension type `B`:
        •       ```dart
          extension type [!A!](B b) {}
                extension type [!B!](A a) {}
          ```
        •       ```dart

        • extension type [!A!](List<B> b) {}
        •       extension type [!B!](List<A> a) {}
          ```

        • Or something like that
        • Patch Set #4, Line 11494:

              The following code produces this diagnostic because the type parameter `T`
          is used as a parameter type in the function type `void Function(T)`, and
          parameters are not covariant:

        • I'm not sure that adding "extension" helps; it might even be harmful. […]

          Oh, that's fine then! I think I was thinking that it'd help to distinguish the first `T` that occurs from the second in the statement, and thought adding "extension" would couple it to the extension type declaration more than the function. But you're right, that's unnecessarily confusing; the original is clear enough.

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 5
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Attention: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Comment-Date: Wed, 22 Nov 2023 17:47:49 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: Yes
      Comment-In-Reply-To: Marya Belanger <mbel...@google.com>
      Comment-In-Reply-To: Brian Wilkerson <brianwi...@google.com>

      Brian Wilkerson (Gerrit)

      unread,
      Nov 27, 2023, 10:46:39 PM11/27/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org

      Attention is currently required from: Brian Wilkerson.

      Brian Wilkerson uploaded patch set #6 to this change.

      View Change

      Add diagnostic docs for extension types

      I'm fairly sure there will be other diagnostics added later, so this
      isn't everything, but it covers the diagnostics that are currently
      implemented in the analyzer.

      Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      ---
      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/verify_diagnostics_test.dart
      M pkg/analyzer/tool/diagnostics/diagnostics.md
      3 files changed, 1,034 insertions(+), 5 deletions(-)

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: newpatchset
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 6

      Brian Wilkerson (Gerrit)

      unread,
      Nov 27, 2023, 10:47:48 PM11/27/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger, CBuild, Commit Queue

      Patch set 6:Code-Review +1Commit-Queue +2

      View Change

      2 comments:


        • Break the cycle by removing a type from the implements clause of at least
          one of the types in the cycle:

        • Reading today with fresh eyes, the original is probably the best version, maybe with replacing "in" […]

          Done

        • Patch Set #4, Line 5541:

                The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](B b) {}

          extension type [!B!](A a) {}
          ```

          The following code produces this diagnostic because the representation
          type of the extension type `A` depends on `A` indirectly through the
          extension type `B`:

          ```dart
          extension type [!A!](List<B> b) {}

          extension type [!B!](List<A> a) {}
          ```

        • Ok, let's leave it then. […]

          Done

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: comment
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 6
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Comment-Date: Tue, 28 Nov 2023 03:47:42 +0000

      Brian Wilkerson (Gerrit)

      unread,
      Nov 28, 2023, 12:06:59 AM11/28/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org

      Attention is currently required from: Brian Wilkerson.

      Brian Wilkerson uploaded patch set #7 to this change.

      View Change

      Add diagnostic docs for extension types

      I'm fairly sure there will be other diagnostics added later, so this
      isn't everything, but it covers the diagnostics that are currently
      implemented in the analyzer.

      Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      ---
      M pkg/analyzer/lib/src/error/codes.g.dart

      M pkg/analyzer/messages.yaml
      M pkg/analyzer/test/verify_diagnostics_test.dart
      M pkg/analyzer/tool/diagnostics/diagnostics.md
      4 files changed, 1,039 insertions(+), 8 deletions(-)

      To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-MessageType: newpatchset
      Gerrit-Project: sdk
      Gerrit-Branch: main
      Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
      Gerrit-Change-Number: 322442
      Gerrit-PatchSet: 7
      Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
      Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
      Gerrit-Attention: Brian Wilkerson <brianwi...@google.com>

      Brian Wilkerson (Gerrit)

      unread,
      Nov 28, 2023, 12:07:17 AM11/28/23
      to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger, CBuild, Commit Queue

      Patch set 7:Commit-Queue +2

      View Change

        To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: comment
        Gerrit-Project: sdk
        Gerrit-Branch: main
        Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
        Gerrit-Change-Number: 322442
        Gerrit-PatchSet: 7
        Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
        Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
        Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
        Gerrit-Comment-Date: Tue, 28 Nov 2023 05:07:13 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes

        Commit Queue (Gerrit)

        unread,
        Nov 28, 2023, 1:09:16 AM11/28/23
        to Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger, CBuild

        Commit Queue submitted this change.

        View Change



        6 is the latest approved patch-set.
        The change was submitted with unreviewed changes in the following files:

        ```
        The name of the file: pkg/analyzer/lib/src/error/codes.g.dart
        Insertions: 5, Deletions: 3.

        @@ -258,7 +258,9 @@
        'AWAIT_OF_EXTENSION_TYPE_NOT_FUTURE',

        "The 'await' expression can't be used for an expression with an extension "
                 "type that is not a subtype of 'Future'.",
        - correctionMessage: "Try updating the extension type to implement 'Future'.",
        + correctionMessage:
        + "Try removing the `await`, or updating the extension type to implement "
        + "'Future'.",
        );

        /// Parameters:
        @@ -1672,8 +1674,8 @@
        static const CompileTimeErrorCode
        EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION = CompileTimeErrorCode(
        'EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION',
        - "Extension type constructors can't include superinitializers.",
        - correctionMessage: "Try removing the superconstructor invocation.",
        + "Extension type constructors can't include super initializers.",
        + correctionMessage: "Try removing the super constructor invocation.",
        );

        /// No parameters.
        ```

        Approvals: Brian Wilkerson: Looks good to me, approved; Commit Marya Belanger: Looks good to me, approved
        Add diagnostic docs for extension types

        I'm fairly sure there will be other diagnostics added later, so this
        isn't everything, but it covers the diagnostics that are currently
        implemented in the analyzer.

        Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
        Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322442
        Reviewed-by: Marya Belanger <mbel...@google.com>
        Reviewed-by: Brian Wilkerson <brianwi...@google.com>
        Commit-Queue: Brian Wilkerson <brianwi...@google.com>

        ---
        M pkg/analyzer/lib/src/error/codes.g.dart
        M pkg/analyzer/messages.yaml
        M pkg/analyzer/test/verify_diagnostics_test.dart
        M pkg/analyzer/tool/diagnostics/diagnostics.md
        4 files changed, 1,039 insertions(+), 8 deletions(-)

        
        
        diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
        index 280326c..a672884 100644
        --- a/pkg/analyzer/lib/src/error/codes.g.dart
        +++ b/pkg/analyzer/lib/src/error/codes.g.dart
        @@ -258,7 +258,9 @@
        'AWAIT_OF_EXTENSION_TYPE_NOT_FUTURE',

        "The 'await' expression can't be used for an expression with an extension "
                 "type that is not a subtype of 'Future'.",
        - correctionMessage: "Try updating the extension type to implement 'Future'.",
        + correctionMessage:
        + "Try removing the `await`, or updating the extension type to implement "
        + "'Future'.",
        );

        /// Parameters:
        @@ -1672,8 +1674,8 @@
        static const CompileTimeErrorCode
        EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION = CompileTimeErrorCode(
        'EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION',
        - "Extension type constructors can't include superinitializers.",
        - correctionMessage: "Try removing the superconstructor invocation.",
        + "Extension type constructors can't include super initializers.",
        + correctionMessage: "Try removing the super constructor invocation.",
        );

        /// No parameters.
        diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
        index ff769bf..0e9e5f8 100644
        --- a/pkg/analyzer/messages.yaml
        +++ b/pkg/analyzer/messages.yaml
        @@ -1170,7 +1170,51 @@

        await expression.)
        AWAIT_OF_EXTENSION_TYPE_NOT_FUTURE:
        problemMessage: "The 'await' expression can't be used for an expression with an extension type that is not a subtype of 'Future'."
        - correctionMessage: Try updating the extension type to implement 'Future'.
        + correctionMessage: Try removing the `await`, or updating the extension type to implement 'Future'.
        + documentation: |-
        + #### Description
        +
        + The analyzer produces this diagnostic when the type of the expression in
        +      an `await` expression is an extension type, and the extension type isn't a
        @@ -5139,28 +5183,222 @@

        problemMessage: "Extension type constructors can't declare super formal parameters."
        correctionMessage: Try removing the super formal parameter declaration.
        comment: No parameters.
        + documentation: |-
        + #### Description
        +
        + The analyzer produces this diagnostic when a constructor in an extension
        + type has a super parameter. Super parameters aren't valid because
        + extension types don't have a superclass.
        +
        + #### Example
        +
        + The following code produces this diagnostic because the named constructor
        + `n` contains a super parameter:
        +
        + ```dart
        + extension type E(int i) {
        + E.n(this.i, [!super!].foo);
        + }
        + ```
        +
        + #### Common fixes
        +
        +      If you need the parameter, replace the super parameter with a normal
        + parameter:

        +
        + ```dart
        + extension type E(int i) {
        +        E.n(this.i, String foo);
        + }
        + ```
        +
        +      If you don't need the parameter, remove the super parameter:

        +
        + ```dart
        + extension type E(int i) {
        + E.n(this.i);
        + }
        + ```
        EXTENSION_TYPE_CONSTRUCTOR_WITH_SUPER_INVOCATION:
        - problemMessage: "Extension type constructors can't include superinitializers."
        - correctionMessage: Try removing the superconstructor invocation.
        + problemMessage: Extension type constructors can't include super initializers.
        + correctionMessage: Try removing the super constructor invocation.
        comment: No parameters.
        + documentation: |-
        + #### Description
        +
        +      The analyzer produces this diagnostic when a constructor in an extension
        + type includes an invocation of a super constructor in the initializer
        + list. Because extension types don't have a superclass, there's no
        + constructor to invoke.

        +
        + #### Example
        +
        +      The following code produces this diagnostic because the constructor `E.n`
        + invokes a super constructor in its initializer list:
        +      The following code produces this diagnostic because the class `Object`
        + already defines a member named `hashCode`:
        +      The following code produces this diagnostic because extension types can't
        + implement the type `dynamic`:
        +      Break the cycle by removing a type from the implements clause of at least
        + one of the types involved in the cycle:

        +
        + ```dart
        + extension type A(int i) implements B {}
        +
        + extension type B(int i) {}
        + ```
        EXTENSION_TYPE_IMPLEMENTS_NOT_SUPERTYPE:
        problemMessage: "'{0}' is not a supertype of '{1}', the representation type."
        correctionMessage: Try specifying a different type, or remove the type from the list.
        @@ -5168,6 +5406,37 @@

        Parameters:
        0: the implemented not extension type
        1: the ultimate representation type
        + documentation: |-
        + #### Description
        +
        +      The analyzer produces this diagnostic when an extension type implements a
        + type that isn't a supertype of the representation type.

        +
        + #### Example
        +
        +      The following code produces this diagnostic because the extension type `A`
        + implements `String`, but `String` isn't a supertype of the representation
        + type `int`:

        +
        + ```dart
        + extension type A(int i) implements [!String!] {}
        + ```
        +
        + #### Common fixes
        +
        + If the representation type is correct, then remove or replace the type in
        + the implements clause:
        +
        + ```dart
        + extension type A(int i) {}
        + ```
        +
        + If the representation type isn't correct, then replace it with the correct
        + type:
        +
        + ```dart
        + extension type A(String s) implements String {}
        + ```
        EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE:
        problemMessage: "'{0}', the representation type of '{1}', is not a supertype of '{2}', the representation type of '{3}'."
        correctionMessage: Try specifying a different type, or remove the type from the list.
        @@ -5177,6 +5446,45 @@

        1: the name of the implemented extension type
        2: the representation type of the this extension type
        3: the name of the this extension type
        + documentation: |-
        + #### Description
        +
        + The analyzer produces this diagnostic when an extension type implements
        + another extension type, and the representation type of the implemented
        + extension type isn't a subtype of the representation type of the implementing
        + extension type.
        +
        + #### Example
        +
        + The following code produces this diagnostic because the extension type `B`
        +      implements `A`, but the representation type of `A` (`num`) isn't a

        + subtype of the representation type of `B` (`String`):
        +
        + ```dart
        +      extension type A(num i) {}
        +

        + extension type B(String s) implements [!A!] {}
        + ```
        +
        + #### Common fixes
        +
        + Either change the representation types of the two extension types so that
        + the representation type of the implemented type is a supertype of the
        +      representation type of the implementing type:
        +
        + ```dart
        + extension type A(num i) {}
        +
        + extension type B(int n) implements A {}
        + ```
        +
        + Or remove the implemented type from the implements clause:
        +
        + ```dart
        + extension type A(num i) {}
        +
        + extension type B(String s) {}

        + ```
        EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT:
        problemMessage: "The extension type '{0}' has more than one distinct member named '{1}' from implemented types."
        correctionMessage: Try redeclaring the corresponding member in this extension type.
        @@ -5184,10 +5492,106 @@
        +      can rename the members in those types, then give the conflicting members
        +      The following two code examples produce this diagnostic because the
        + representation type of the extension type `A` depends on `A`
        + indirectly through the extension type `B`:
        +
        + ```dart
        + extension type [!A!](B b) {}
        +
        + extension type [!B!](A a) {}
        + ```

        +
        + ```dart
        + extension type [!A!](List<B> b) {}
        +
        + extension type [!B!](List<A> a) {}
        + ```
        +
        + #### Common fixes
        +
        + Remove the dependency by choosing a different representation type for at
        + least one of the types in the cycle:
        +
        + ```dart
        + extension type A(String s) {}
        + ```
           EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM:
        problemMessage: "The representation type can't be a bottom type."
        correctionMessage: Try specifying a different type.
        @@ -11101,6 +11505,30 @@
        @@ -20861,7 +21289,7 @@

        #### Common fixes

        If you can rely on automatic platform detection, then omit the
        - top-level `platforms` field.
        + top-level `platforms` field.

        ```yaml
        %uri="pubspec.yaml"
        @@ -24234,6 +24662,62 @@


        Parameters:
        0: the kind of member
        + documentation: |-
        + #### Description
        +
        + The analyzer produces this diagnostic when a member of an extension type
        + is annotated with `@redeclare`, but none of the implemented interfaces
        + has a member with the same name.
        +
        + #### Example
        +
        + The following code produces this diagnostic because the member `n`
        + declared by the extension type `E` is annotated with `@redeclare`, but `C`
        + doesn't have a member named `n`:
        +
        + ```dart
        +      import 'package:meta/meta.dart';
        +

        + class C {
        + void m() {}
        + }
        +
        + extension type E(C c) implements C {
        + @redeclare
        +        void [!n!]() {}

        + }
        + ```
        +
        + #### Common fixes
        +
        + If the annotated member has the right name, then remove the annotation:
        +
        + ```dart
        + class C {
        + void m() {}
        + }
        +
        + extension type E(C c) implements C {
        + void n() {}
        + }
        + ```
        +
        + If the annotated member is suppose to replace a member from the
        + implemented interfaces, then change the name of the annotated member to
        + match the member being replaced:
        +
        + ```dart
        +      import 'package:meta/meta.dart';
        +

        + class C {
        + void m() {}
        + }
        +
        + extension type E(C c) implements C {
        + @redeclare
        + void m() {}
        + }
        + ```
        REMOVED_LINT_USE:
        problemMessage: "'{0}' was removed in Dart '{1}'"
        correctionMessage: "Remove the reference to '{0}'."
        diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
        index 01bde78..51c8da5 100644
        --- a/pkg/analyzer/test/verify_diagnostics_test.dart
        +++ b/pkg/analyzer/test/verify_diagnostics_test.dart
        @@ -44,6 +44,10 @@
        'CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY',
        // Also reports CompileTimeErrorCode.SUBTYPE_OF_BASE_OR_FINAL_IS_NOT_BASE_FINAL_OR_SEALED
        'CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS',
        + // The following codes produce two diagnostics because they illustrate a
        + // cycle.
        + 'CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_ITSELF',
        + 'CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF',
        // Has code in the example section that needs to be skipped (because it's
        // part of the explanatory text not part of the example), but there's
        // currently no way to do that.
        diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
        index ab9875e..87fd16f 100644
        --- a/pkg/analyzer/tool/diagnostics/diagnostics.md
        +++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
        @@ -1473,6 +1473,55 @@

        }
        {% endprettify %}

        +### await_of_extension_type_not_future
        +
        +_The 'await' expression can't be used for an expression with an extension type
        +that is not a subtype of 'Future'._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when the type of the expression in
        +an `await` expression is an extension type, and the extension type isn't a

        +subclass of `Future`.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the extension type `E`
        +isn't a subclass of `Future`:
        +
        +{% prettify dart tag=pre+code %}
        +extension type E(int i) {}

        +
        +void f(E e) async {
        + [!await!] e;
        +}
        +{% endprettify %}
        +
        +#### Common fixes
        +
        +If the extension type is correctly defined, then remove the `await`:
        +
        +{% prettify dart tag=pre+code %}
        +extension type E(int i) {}

        +
        +void f(E e) {
        + e;
        +}
        +{% endprettify %}
        +
        +If the extension type is intended to be awaitable, then add `Future` (or a
        +subtype of `Future`) to the `implements` clause (adding an `implements`
        +clause if there isn't one already), and make the representation type
        +match:
        +
        +{% prettify dart tag=pre+code %}
        +extension type E(Future<int> i) implements Future<int> {}
        +

        +void f(E e) async {
        + await e;
        +}
        +{% endprettify %}
        +
        ### body_might_complete_normally

        _The body might complete normally, causing 'null' to be returned, but the return
        @@ -6139,6 +6188,409 @@
        +If you need the parameter, replace the super parameter with a normal
        +parameter:

        +
        +{% prettify dart tag=pre+code %}
        +extension type E(int i) {
        + E.n(this.i, String foo);
        +}
        +{% endprettify %}
        +
        +If you don't need the parameter, remove the super parameter:

        +
        +{% prettify dart tag=pre+code %}
        +extension type E(int i) {
        + E.n(this.i);
        +}
        +{% endprettify %}
        +
        +### extension_type_constructor_with_super_invocation
        +
        +_Extension type constructors can't include super initializers._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when a constructor in an extension
        +type includes an invocation of a super constructor in the initializer
        +list. Because extension types don't have a superclass, there's no
        +constructor to invoke.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the constructor `E.n`
        +invokes a super constructor in its initializer list:
        +The following code produces this diagnostic because the class `Object`
        +already defines a member named `hashCode`:
        +The following code produces this diagnostic because extension types can't
        +implement the type `dynamic`:

        +
        +{% prettify dart tag=pre+code %}
        +extension type A(int i) implements [!dynamic!] {}

        +{% endprettify %}
        +
        +#### Common fixes
        +
        +Remove the disallowed type from the implements clause:

        +
        +{% prettify dart tag=pre+code %}
        +extension type A(int i) {}
        +{% endprettify %}
        +
        +### extension_type_implements_itself
        +
        +_The extension type can't implement itself._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when an extension type implements
        +itself, either directly or indirectly.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the extension type `A`
        +directly implements itself:
        +
        +{% prettify dart tag=pre+code %}
        +extension type [!A!](int i) implements A {}

        +{% endprettify %}
        +
        +The following code produces this diagnostic because the extension type `A`
        +indirectly implements itself (through `B`):
        +
        +{% prettify dart tag=pre+code %}
        +extension type [!A!](int i) implements B {}
        +
        +extension type [!B!](int i) implements A {}

        +{% endprettify %}
        +
        +#### Common fixes
        +
        +Break the cycle by removing a type from the implements clause of at least
        +one of the types involved in the cycle:

        +
        +{% prettify dart tag=pre+code %}
        +extension type A(int i) implements B {}
        +
        +extension type B(int i) {}

        +{% endprettify %}
        +
        +### extension_type_implements_not_supertype
        +
        +_'{0}' is not a supertype of '{1}', the representation type._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when an extension type implements a
        +type that isn't a supertype of the representation type.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the extension type `A`
        +implements `String`, but `String` isn't a supertype of the representation
        +type `int`:

        +
        +{% prettify dart tag=pre+code %}
        +extension type A(int i) implements [!String!] {}

        +{% endprettify %}
        +
        +#### Common fixes
        +
        +If the representation type is correct, then remove or replace the type in
        +the implements clause:
        +
        +{% prettify dart tag=pre+code %}
        +extension type A(int i) {}

        +{% endprettify %}
        +
        +If the representation type isn't correct, then replace it with the correct
        +type:
        +
        +{% prettify dart tag=pre+code %}
        +extension type A(String s) implements String {}

        +{% endprettify %}
        +
        +### extension_type_implements_representation_not_supertype
        +
        +_'{0}', the representation type of '{1}', is not a supertype of '{2}', the
        +representation type of '{3}'._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when an extension type implements
        +another extension type, and the representation type of the implemented
        +extension type isn't a subtype of the representation type of the implementing
        +extension type.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the extension type `B`
        +implements `A`, but the representation type of `A` (`num`) isn't a

        +subtype of the representation type of `B` (`String`):
        +
        +{% prettify dart tag=pre+code %}
        +extension type A(num i) {}
        +

        +extension type B(String s) implements [!A!] {}
        +{% endprettify %}
        +
        +#### Common fixes
        +
        +Either change the representation types of the two extension types so that
        +the representation type of the implemented type is a supertype of the
        +representation type of the implementing type:
        +
        +{% prettify dart tag=pre+code %}
        +extension type A(num i) {}
        +
        +extension type B(int n) implements A {}

        +{% endprettify %}
        +
        +Or remove the implemented type from the implements clause:

        +
        +{% prettify dart tag=pre+code %}
        +extension type A(num i) {}
        +
        +extension type B(String s) {}

        +{% endprettify %}
        +
        +can rename the members in those types, then give the conflicting members
        +The following two code examples produce this diagnostic because the
        +representation type of the extension type `A` depends on `A`
        +indirectly through the extension type `B`:

        +
        +{% prettify dart tag=pre+code %}
        +extension type [!A!](B b) {}
        +
        +extension type [!B!](A a) {}
        +{% endprettify %}
        +
        +{% prettify dart tag=pre+code %}
        +extension type [!A!](List<B> b) {}
        +
        +extension type [!B!](List<A> a) {}
        +{% endprettify %}
        +
        +#### Common fixes
        +
        +Remove the dependency by choosing a different representation type for at
        +least one of the types in the cycle:
        +
        +{% prettify dart tag=pre+code %}
        +extension type A(String s) {}
        +{% endprettify %}
        +
        ### external_with_initializer

        _External fields can't have initializers._
        @@ -10186,7 +10638,7 @@

        #### Common fixes

        If you can rely on automatic platform detection, then omit the
        -top-level `platforms` field.
        +top-level `platforms` field.

        {% prettify yaml tag=pre+code %}
        name: example
        @@ -14219,6 +14671,35 @@
        @@ -16891,6 +17372,66 @@


        Change the type hierarchy so that there's no circularity.

        +### redeclare_on_non_redeclaring_member
        +
        +_The {0} doesn't redeclare a {0} declared in a superinterface._
        +
        +#### Description
        +
        +The analyzer produces this diagnostic when a member of an extension type
        +is annotated with `@redeclare`, but none of the implemented interfaces
        +has a member with the same name.
        +
        +#### Example
        +
        +The following code produces this diagnostic because the member `n`
        +declared by the extension type `E` is annotated with `@redeclare`, but `C`
        +doesn't have a member named `n`:
        +
        +{% prettify dart tag=pre+code %}
        +import 'package:meta/meta.dart';
        +

        +class C {
        + void m() {}
        +}
        +
        +extension type E(C c) implements C {
        + @redeclare
        +  void [!n!]() {}

        +}
        +{% endprettify %}
        +
        +#### Common fixes
        +
        +If the annotated member has the right name, then remove the annotation:
        +
        +{% prettify dart tag=pre+code %}
        +class C {
        + void m() {}
        +}
        +
        +extension type E(C c) implements C {
        + void n() {}
        +}
        +{% endprettify %}
        +
        +If the annotated member is suppose to replace a member from the
        +implemented interfaces, then change the name of the annotated member to
        +match the member being replaced:
        +
        +{% prettify dart tag=pre+code %}
        +import 'package:meta/meta.dart';
        +

        +class C {
        + void m() {}
        +}
        +
        +extension type E(C c) implements C {
        + @redeclare
        + void m() {}
        +}
        +{% endprettify %}
        +
        ### redirect_generative_to_missing_constructor

        _The constructor '{0}' couldn't be found in '{1}'._

        To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-MessageType: merged
        Gerrit-Project: sdk
        Gerrit-Branch: main
        Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
        Gerrit-Change-Number: 322442
        Gerrit-PatchSet: 8
        Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
        Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>

        CBuild (Gerrit)

        unread,
        Nov 28, 2023, 2:00:55 AM11/28/23
        to Commit Queue, Brian Wilkerson, dart-analys...@google.com, rev...@dartlang.org, Marya Belanger

          To view, visit change 322442. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-MessageType: comment
          Gerrit-Project: sdk
          Gerrit-Branch: main
          Gerrit-Change-Id: I27100c9a76e6db4fb2b0bf8b9bc6b0b2c326707f
          Gerrit-Change-Number: 322442
          Gerrit-PatchSet: 8
          Gerrit-Owner: Brian Wilkerson <brianwi...@google.com>
          Gerrit-Reviewer: Brian Wilkerson <brianwi...@google.com>
          Gerrit-Reviewer: Marya Belanger <mbel...@google.com>
          Gerrit-Comment-Date: Tue, 28 Nov 2023 07:00:52 +0000
          Gerrit-HasComments: No
          Gerrit-Has-Labels: No
          Reply all
          Reply to author
          Forward
          0 new messages