Attention is currently required from: Marya Belanger.
Brian Wilkerson would like Marya Belanger to review this 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.
Attention is currently required from: Marya Belanger.
Patch set 2:Commit-Queue +1
2 comments:
File pkg/analyzer/messages.yaml:
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.
Attention is currently required from: Brian Wilkerson, Marya Belanger.
go/dart-cbuild result: SUCCESS
Details: https://goto.google.com/dart-cbuild/find/b8999c68540eb4705ec20aeedff1d49e4664164c
Attention is currently required from: Marya Belanger.
1 comment:
Patchset:
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.
Attention is currently required from: Marya Belanger.
go/dart-cbuild result: SUCCESS
Details: https://goto.google.com/dart-cbuild/find/5735ce3a7764e8e34b6975f015aed8df8abda090
Attention is currently required from: Brian Wilkerson.
Patch set 4:Code-Review +1
18 comments:
File pkg/analyzer/messages.yaml:
Patch Set #4, Line 1171: type and
```suggestion
an `await` expression is an extension type, and the extension type isn't a
```
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:
```
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.
```
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`:
```
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`:
```
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:
```
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
implements a type that isn't a supertype of the
representation 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`:
```
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!
then rename the members to have
unique names:
```suggestion
can rename the members in those types, then give the conflicting
members unique names:
```
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
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.
Attention is currently required from: Brian Wilkerson.
Brian Wilkerson uploaded patch set #5 to this 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.
Attention is currently required from: Marya Belanger.
19 comments:
Patchset:
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:
Patch Set #4, Line 1171: type and
```suggestion […]
Done
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).
Patch Set #4, Line 5176: If the parameter is needed
```suggestion […]
Done
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 […]
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.
Patch Set #4, Line 5185: If the parameter isn't needed
```suggestion […]
Rewritten to "If you don't need the parameter" to preserve the original meaning.
a constructor in an extension
type
"...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.
Patch Set #4, Line 5201: Because there is no superclass, there's no constructor to invoke.
```suggestion […]
I replaced the first clause, but left the contraction ("there's"). If you want it changed too, let me know.
The following code produces this diagnostic because there is an invocation
of a super constructor in the initializer list of `E.n`:
```suggestion […]
Done
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 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.
Patch Set #4, Line 5280: defines a member named `hashCode`:
```suggestion […]
Done
The following code produces this diagnostic because the type `dynamic`
can't be implemented by an extension type:
```suggestion […]
Done
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"
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.
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
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. :-)
then rename the members to have
unique names:
```suggestion […]
Done
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.
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.
Attention is currently required from: Brian Wilkerson.
Patch set 5:Code-Review +1
9 comments:
Patchset:
Nothing major to change; thanks for answering all my questions!
File pkg/analyzer/messages.yaml:
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!
Patch Set #4, Line 5185: If the parameter isn't needed
Rewritten to "If you don't need the parameter" to preserve the original meaning.
Oh right, my mistake! Thanks for catching that
Patch Set #4, Line 5201: Because there is no superclass, there's no constructor to invoke.
I replaced the first clause, but left the contraction ("there's"). […]
That's fine, lgtm
Patch Set #4, Line 5247: and/or
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.
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:
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
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
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.
Attention is currently required from: Brian Wilkerson.
Brian Wilkerson uploaded patch set #6 to this 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.
Patch set 6:Code-Review +1Commit-Queue +2
2 comments:
File pkg/analyzer/messages.yaml:
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
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.
Attention is currently required from: Brian Wilkerson.
Brian Wilkerson uploaded patch set #7 to this 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.
Patch set 7:Commit-Queue +2
Commit Queue submitted this 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.
```
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.
go/dart-cbuild result: SUCCESS
Details: https://goto.google.com/dart-cbuild/find/d91f3a113eba288f0f232a3df2a55e80af3c30a0