Version 2.11.0-163.0.dev
Merge commit '55496a1282e3e15356a3e2509c62f6f03f65671c' into 'dev'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index e65f60b..67b4f36 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -142,7 +142,6 @@
CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH,
CompileTimeErrorCode.COULD_NOT_INFER,
CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR,
- CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER,
CompileTimeErrorCode.DEFERRED_IMPORT_OF_EXTENSION,
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 5c08ec5..db5240f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -7,10 +7,12 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/element/display_string_builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/nullability_eliminator.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -25,10 +27,11 @@
/// Initialize a newly created element to represent a constructor, based on
/// the [declaration], and applied [substitution].
ConstructorMember(
+ TypeProviderImpl typeProvider,
ConstructorElement declaration,
MapSubstitution substitution,
bool isLegacy,
- ) : super(declaration, substitution, isLegacy,
+ ) : super(typeProvider, declaration, substitution, isLegacy,
const <TypeParameterElement>[]);
@deprecated
@@ -79,7 +82,7 @@
substitution = _substitution;
}
- return ConstructorMember(declaration, substitution, false);
+ return ConstructorMember(_typeProvider, declaration, substitution, false);
}
@override
@@ -118,6 +121,7 @@
}
return ConstructorMember(
+ constructor.library.typeProvider,
constructor,
Substitution.fromInterfaceType(definingType),
isLegacy,
@@ -141,11 +145,12 @@
/// their bounds. The [substitution] includes replacing [declaration] type
/// parameters with the provided fresh [typeParameters].
ExecutableMember(
+ TypeProviderImpl typeProvider,
ExecutableElement declaration,
MapSubstitution substitution,
bool isLegacy,
this.typeParameters,
- ) : super(declaration, substitution, isLegacy);
+ ) : super(typeProvider, declaration, substitution, isLegacy);
@deprecated
@override
@@ -185,9 +190,10 @@
List<ParameterElement> get parameters {
return declaration.parameters.map<ParameterElement>((p) {
if (p is FieldFormalParameterElement) {
- return FieldFormalParameterMember(p, _substitution, isLegacy);
+ return FieldFormalParameterMember(
+ _typeProvider, p, _substitution, isLegacy);
}
- return ParameterMember(p, _substitution, isLegacy);
+ return ParameterMember(_typeProvider, p, _substitution, isLegacy);
}).toList();
}
@@ -222,11 +228,13 @@
return null;
}
+ TypeProvider typeProvider;
var isLegacy = false;
var combined = substitution;
if (element is ExecutableMember) {
ExecutableMember member = element;
element = member.declaration;
+ typeProvider = member._typeProvider;
isLegacy = member.isLegacy;
@@ -236,6 +244,8 @@
}
map.addAll(substitution.map);
combined = Substitution.fromMap(map);
+ } else {
+ typeProvider = element.library.typeProvider;
}
if (!isLegacy && combined.map.isEmpty) {
@@ -243,11 +253,11 @@
}
if (element is ConstructorElement) {
- return ConstructorMember(element, combined, isLegacy);
+ return ConstructorMember(typeProvider, element, combined, isLegacy);
} else if (element is MethodElement) {
- return MethodMember(element, combined, isLegacy);
+ return MethodMember(typeProvider, element, combined, isLegacy);
} else if (element is PropertyAccessorElement) {
- return PropertyAccessorMember(element, combined, isLegacy);
+ return PropertyAccessorMember(typeProvider, element, combined, isLegacy);
} else {
throw UnimplementedError('(${element.runtimeType}) $element');
}
@@ -259,6 +269,7 @@
class FieldFormalParameterMember extends ParameterMember
implements FieldFormalParameterElement {
factory FieldFormalParameterMember(
+ TypeProviderImpl typeProvider,
FieldFormalParameterElement declaration,
MapSubstitution substitution,
bool isLegacy,
@@ -268,6 +279,7 @@
substitution,
);
return FieldFormalParameterMember._(
+ typeProvider,
declaration,
freshTypeParameters.substitution,
isLegacy,
@@ -276,11 +288,18 @@
}
FieldFormalParameterMember._(
+ TypeProviderImpl typeProvider,
FieldFormalParameterElement declaration,
MapSubstitution substitution,
bool isLegacy,
List<TypeParameterElement> typeParameters,
- ) : super._(declaration, substitution, isLegacy, typeParameters);
+ ) : super._(
+ typeProvider,
+ declaration,
+ substitution,
+ isLegacy,
+ typeParameters,
+ );
@override
FieldElement get field {
@@ -289,7 +308,7 @@
return null;
}
- return FieldMember(field, _substitution, isLegacy);
+ return FieldMember(_typeProvider, field, _substitution, isLegacy);
}
@override
@@ -309,10 +328,11 @@
/// Initialize a newly created element to represent a field, based on the
/// [declaration], with applied [substitution].
FieldMember(
+ TypeProviderImpl typeProvider,
FieldElement declaration,
MapSubstitution substitution,
bool isLegacy,
- ) : super(declaration, substitution, isLegacy);
+ ) : super(typeProvider, declaration, substitution, isLegacy);
@deprecated
@override
@@ -330,7 +350,8 @@
if (baseGetter == null) {
return null;
}
- return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseGetter, _substitution, isLegacy);
}
@override
@@ -354,7 +375,8 @@
if (baseSetter == null) {
return null;
}
- return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseSetter, _substitution, isLegacy);
}
@override
@@ -370,6 +392,7 @@
return field;
}
return FieldMember(
+ field.library.typeProvider,
field,
Substitution.fromInterfaceType(definingType),
false,
@@ -383,13 +406,16 @@
if (substitution.map.isEmpty) {
return element;
}
- return FieldMember(element, substitution, false);
+ var typeProvider = element.library.typeProvider;
+ return FieldMember(typeProvider, element, substitution, false);
}
}
class FunctionMember extends ExecutableMember implements FunctionElement {
- FunctionMember(FunctionElement declaration, bool isLegacy)
+ FunctionMember(
+ TypeProviderImpl typeProvider, FunctionElement declaration, bool isLegacy)
: super(
+ typeProvider,
declaration,
Substitution.empty,
isLegacy,
@@ -411,6 +437,9 @@
/// An element defined in a parameterized type where the values of the type
/// parameters are known.
abstract class Member implements Element {
+ /// A type provider (might be legacy, might be null-safe).
+ final TypeProviderImpl _typeProvider;
+
/// The element on which the parameterized element was created.
final Element _declaration;
@@ -422,7 +451,8 @@
/// Initialize a newly created element to represent a member, based on the
/// [declaration], and applied [_substitution].
- Member(this._declaration, this._substitution, this.isLegacy) {
+ Member(this._typeProvider, this._declaration, this._substitution,
+ this.isLegacy) {
if (_declaration is Member) {
throw StateError('Members must be created from a declarations.');
}
@@ -599,8 +629,7 @@
/// Otherwise, return the type unchanged.
DartType _toLegacyType(DartType type) {
if (isLegacy) {
- var typeProvider = declaration.library.typeProvider;
- return NullabilityEliminator.perform(typeProvider, type);
+ return NullabilityEliminator.perform(_typeProvider, type);
} else {
return type;
}
@@ -617,18 +646,24 @@
} else if (element is Member) {
var member = element as Member;
return ConstructorMember(
+ member._typeProvider,
member._declaration,
member._substitution,
true,
);
} else {
- return ConstructorMember(element, Substitution.empty, true);
+ var typeProvider = element.library.typeProvider;
+ return ConstructorMember(
+ typeProvider, element, Substitution.empty, true);
}
} else if (element is FunctionElement) {
if (!element.library.isNonNullableByDefault) {
return element;
} else {
- return FunctionMember(element.declaration, true);
+ var typeProvider = element is Member
+ ? (element as Member)._typeProvider
+ : element.library.typeProvider;
+ return FunctionMember(typeProvider, element.declaration, true);
}
} else if (element is MethodElement) {
if (!element.library.isNonNullableByDefault) {
@@ -636,12 +671,14 @@
} else if (element is Member) {
var member = element as Member;
return MethodMember(
+ member._typeProvider,
member._declaration,
member._substitution,
true,
);
} else {
- return MethodMember(element, Substitution.empty, true);
+ var typeProvider = element.library.typeProvider;
+ return MethodMember(typeProvider, element, Substitution.empty, true);
}
} else if (element is PropertyAccessorElement) {
if (!element.library.isNonNullableByDefault) {
@@ -649,12 +686,15 @@
} else if (element is Member) {
var member = element as Member;
return PropertyAccessorMember(
+ member._typeProvider,
member._declaration,
member._substitution,
true,
);
} else {
- return PropertyAccessorMember(element, Substitution.empty, true);
+ var typeProvider = element.library.typeProvider;
+ return PropertyAccessorMember(
+ typeProvider, element, Substitution.empty, true);
}
} else {
return element;
@@ -666,6 +706,7 @@
/// type parameters are known.
class MethodMember extends ExecutableMember implements MethodElement {
factory MethodMember(
+ TypeProviderImpl typeProvider,
MethodElement declaration,
MapSubstitution substitution,
bool isLegacy,
@@ -675,6 +716,7 @@
substitution,
);
return MethodMember._(
+ typeProvider,
declaration,
freshTypeParameters.substitution,
isLegacy,
@@ -683,11 +725,12 @@
}
MethodMember._(
+ TypeProviderImpl typeProvider,
MethodElement declaration,
MapSubstitution substitution,
bool isLegacy,
List<TypeParameterElement> typeParameters,
- ) : super(declaration, substitution, isLegacy, typeParameters);
+ ) : super(typeProvider, declaration, substitution, isLegacy, typeParameters);
@deprecated
@override
@@ -712,7 +755,9 @@
return method;
}
+ var typeProvider = method.library.typeProvider;
return MethodMember(
+ typeProvider,
method,
Substitution.fromInterfaceType(definingType),
false,
@@ -726,7 +771,8 @@
if (substitution.map.isEmpty) {
return element;
}
- return MethodMember(element, substitution, false);
+ var typeProvider = element.library.typeProvider;
+ return MethodMember(typeProvider, element, substitution, false);
}
}
@@ -739,6 +785,7 @@
final List<TypeParameterElement> typeParameters;
factory ParameterMember(
+ TypeProviderImpl typeProvider,
ParameterElement declaration,
MapSubstitution substitution,
bool isLegacy,
@@ -748,6 +795,7 @@
substitution,
);
return ParameterMember._(
+ typeProvider,
declaration,
freshTypeParameters.substitution,
isLegacy,
@@ -758,11 +806,12 @@
/// Initialize a newly created element to represent a parameter, based on the
/// [declaration], with applied [substitution].
ParameterMember._(
+ TypeProviderImpl typeProvider,
ParameterElement declaration,
MapSubstitution substitution,
bool isLegacy,
this.typeParameters,
- ) : super(declaration, substitution, isLegacy);
+ ) : super(typeProvider, declaration, substitution, isLegacy);
@deprecated
@override
@@ -828,6 +877,7 @@
class PropertyAccessorMember extends ExecutableMember
implements PropertyAccessorElement {
factory PropertyAccessorMember(
+ TypeProviderImpl typeProvider,
PropertyAccessorElement declaration,
MapSubstitution substitution,
bool isLegacy,
@@ -837,6 +887,7 @@
substitution,
);
return PropertyAccessorMember._(
+ typeProvider,
declaration,
freshTypeParameters.substitution,
isLegacy,
@@ -845,11 +896,12 @@
}
PropertyAccessorMember._(
+ TypeProviderImpl typeProvider,
PropertyAccessorElement declaration,
MapSubstitution substitution,
bool isLegacy,
List<TypeParameterElement> typeParameters,
- ) : super(declaration, substitution, isLegacy, typeParameters);
+ ) : super(typeProvider, declaration, substitution, isLegacy, typeParameters);
@deprecated
@override
@@ -861,7 +913,8 @@
if (baseGetter == null) {
return null;
}
- return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseGetter, _substitution, isLegacy);
}
@override
@@ -870,7 +923,8 @@
if (baseSetter == null) {
return null;
}
- return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseSetter, _substitution, isLegacy);
}
@override
@@ -891,9 +945,10 @@
// TODO
PropertyInducingElement variable = declaration.variable;
if (variable is FieldElement) {
- return FieldMember(variable, _substitution, isLegacy);
+ return FieldMember(_typeProvider, variable, _substitution, isLegacy);
} else if (variable is TopLevelVariableElement) {
- return TopLevelVariableMember(variable, _substitution, isLegacy);
+ return TopLevelVariableMember(
+ _typeProvider, variable, _substitution, isLegacy);
}
return variable;
}
@@ -921,7 +976,9 @@
return accessor;
}
+ var typeProvider = accessor.library.typeProvider;
return PropertyAccessorMember(
+ typeProvider,
accessor,
Substitution.fromInterfaceType(definingType),
false,
@@ -932,10 +989,11 @@
class TopLevelVariableMember extends VariableMember
implements TopLevelVariableElement {
TopLevelVariableMember(
+ TypeProviderImpl typeProvider,
VariableElement declaration,
MapSubstitution substitution,
bool isLegacy,
- ) : super(declaration, substitution, isLegacy);
+ ) : super(typeProvider, declaration, substitution, isLegacy);
@override
TopLevelVariableElement get declaration => _declaration;
@@ -946,7 +1004,8 @@
if (baseGetter == null) {
return null;
}
- return PropertyAccessorMember(baseGetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseGetter, _substitution, isLegacy);
}
@override
@@ -961,7 +1020,8 @@
if (baseSetter == null) {
return null;
}
- return PropertyAccessorMember(baseSetter, _substitution, isLegacy);
+ return PropertyAccessorMember(
+ _typeProvider, baseSetter, _substitution, isLegacy);
}
@override
@@ -978,10 +1038,11 @@
/// Initialize a newly created element to represent a variable, based on the
/// [declaration], with applied [substitution].
VariableMember(
+ TypeProviderImpl typeProvider,
VariableElement declaration,
MapSubstitution substitution,
bool isLegacy,
- ) : super(declaration, substitution, isLegacy);
+ ) : super(typeProvider, declaration, substitution, isLegacy);
@deprecated
@override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index fb65bd2..1e0761f 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -2575,9 +2575,14 @@
*/
// #### Description
//
- // The analyzer produces this diagnostic when a private class, enum, mixin,
- // typedef, top level variable, top level function, or method is declared but
- // never referenced.
+ // The analyzer produces this diagnostic when a private declaration isn't
+ // referenced in the library that contains the declaration. The following
+ // kinds of declarations are analyzed:
+ // - Private top-level declarations, such as classes, enums, mixins, typedefs,
+ // top-level variables, and top-level functions
+ // - Private static and instance methods
+ // - Optional parameters of private functions for which a value is never
+ // passed, even when the parameter doesn't have a private name
//
// #### Examples
//
@@ -2588,11 +2593,30 @@
// class [!_C!] {}
// ```
//
+ // Assuming that no code in the library passes a value for `y` in any
+ // invocation of `_m`, the following code produces this diagnostic:
+ //
+ // ```dart
+ // class C {
+ // void _m(int x, [int [!y!]]) {}
+ //
+ // void n() => _m(0);
+ // }
+ // ```
+ //
// #### Common fixes
//
- // If the declaration isn't needed, then remove it.
+ // If the declaration isn't needed, then remove it:
//
- // If the declaration was intended to be used, then add the missing code.
+ // ```dart
+ // class C {
+ // void _m(int x) {}
+ //
+ // void n() => _m(0);
+ // }
+ // ```
+ //
+ // If the declaration is intended to be used, then add the code to use it.
static const HintCode UNUSED_ELEMENT = HintCode(
'UNUSED_ELEMENT', "The declaration '{0}' isn't referenced.",
correction: "Try removing the declaration of '{0}'.",
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index b701c7d..ba5d73a 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -131,9 +131,37 @@
"Top-level declarations can't be declared to be covariant.",
correction: "Try removing the keyword 'covariant'.");
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a function type associated with
+ // a parameter includes optional parameters that have a default value. This
+ // isn't allowed because the default values of parameters aren't part of the
+ // function's type, and therefore including them doesn't provide any value.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the parameter `p` has a
+ // default value even though it's part of the type of the parameter `g`:
+ //
+ // ```dart
+ // void f(void Function([int p [!=!] 0]) g) {
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the default value from the function-type's parameter:
+ //
+ // ```dart
+ // void f(void Function([int p]) g) {
+ // }
+ // ```
static const ParserErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE = ParserErrorCode(
'DEFAULT_VALUE_IN_FUNCTION_TYPE',
- "Parameters in a function type cannot have default values",
+ "Parameters in a function type can't have default values.",
correction: "Try removing the default value.");
static const ParserErrorCode DEFERRED_AFTER_PREFIX = _DEFERRED_AFTER_PREFIX;
diff --git a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
index 489aa70..e16e7da 100644
--- a/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/binary_expression_resolver.dart
@@ -18,7 +18,6 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/type_promotion_manager.dart';
-import 'package:analyzer/src/task/strong/checker.dart';
import 'package:meta/meta.dart';
/// Helper for resolving [BinaryExpression]s.
@@ -107,26 +106,12 @@
);
}
- /// Gets the definite type of expression, which can be used in cases where
- /// the most precise type is desired, for example computing the least upper
- /// bound.
- ///
- /// See [getExpressionType] for more information. Without strong mode, this is
- /// equivalent to [_getStaticType].
- ///
- /// TODO(scheglov) this is duplicate
- DartType _getExpressionType(Expression expr, {bool read = false}) =>
- getExpressionType(expr, _typeSystem, _typeProvider, read: read);
-
/// Return the static type of the given [expression] that is to be used for
/// type analysis.
///
/// TODO(scheglov) this is duplicate
- DartType _getStaticType(Expression expression, {bool read = false}) {
- if (expression is NullLiteral) {
- return _typeProvider.nullType;
- }
- DartType type = read ? getReadType(expression) : expression.staticType;
+ DartType _getStaticType(Expression expression) {
+ DartType type = expression.staticType;
return _resolveTypeParameter(type);
}
@@ -170,7 +155,7 @@
left.accept(_resolver);
left = node.leftOperand;
- var leftType = _getExpressionType(left, read: false);
+ var leftType = left.staticType;
var rightContextType = InferenceContext.getContext(node);
if (rightContextType == null || rightContextType.isDynamic) {
@@ -183,9 +168,7 @@
right = node.rightOperand;
flow?.ifNullExpression_end();
- // TODO(scheglov) This (and above) is absolutely wrong, and convoluted.
- // This is just the status quo, until we can make types straight.
- var rightType = _getExpressionType(right, read: false);
+ var rightType = right.staticType;
if (_isNonNullableByDefault) {
var promotedLeftType = _typeSystem.promoteToNonNull(leftType);
_analyzeLeastUpperBoundTypes(node, promotedLeftType, rightType);
diff --git a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
index 75d46e2..30df9bf 100644
--- a/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/postfix_expression_resolver.dart
@@ -17,7 +17,6 @@
import 'package:analyzer/src/dart/resolver/type_property_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/task/strong/checker.dart';
import 'package:meta/meta.dart';
/// Helper for resolving [PostfixExpression]s.
@@ -228,7 +227,7 @@
operand.accept(_resolver);
operand = node.operand;
- var operandType = getReadType(operand);
+ var operandType = operand.staticType;
var type = _typeSystem.promoteToNonNull(operandType);
_inferenceHelper.recordStaticType(node, type);
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 3fa6b6d..cf508c2 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -697,14 +697,52 @@
"or removing the 'await' before the for loop.");
/**
- * nnbd/feature-specification.md
- *
- * It is an error for the initializer expression of a `late` local variable
- * to use a prefix `await` expression.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a local variable that has the
+ // 'late' modifier uses an 'await' expression in the initializer.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because an 'await' expression
+ // is used in the initializer for 'v', a local variable that is marked 'late':
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // Future<int> f() async {
+ // late v = [!await!] 42;
+ // return v;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the initializer can be rewritten to not use 'await', then rewrite it:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // Future<int> f() async {
+ // late v = 42;
+ // return v;
+ // }
+ // ```
+ //
+ // If the initializer can't be rewritten, then remove the 'late' modifier:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // Future<int> f() async {
+ // var v = await 42;
+ // return v;
+ // }
+ // ```
static const CompileTimeErrorCode AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER =
- CompileTimeErrorCode('AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER',
- "The await expression can't be used in a 'late' local variable.",
+ CompileTimeErrorCode(
+ 'AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER',
+ "The 'await' expression can't be used in a 'late' local variable's "
+ "initializer.",
correction:
"Try removing the 'late' modifier, or rewriting the initializer "
"without using the 'await' expression.");
@@ -1372,19 +1410,53 @@
"removing the keyword 'const'.");
/**
- * 10.6.3 Constant Constructors: It is a compile-time error if a constant
- * constructor is declared by a class C if any instance variable declared in C
- * is initialized with an expression that is not a constant expression.
- *
* Parameters:
* 0: the name of the field
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a constructor has the keyword
+ // `const`, but a field in the class is initialized to a non-constant value.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the field `s` is
+ // initialized to a non-constant value:
+ //
+ // ```dart
+ // class C {
+ // final String s = 3.toString();
+ // [!const!] C();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the field can be initialized to a constant value, then change the
+ // initializer to a constant expression:
+ //
+ // ```dart
+ // class C {
+ // final String s = '3';
+ // const C();
+ // }
+ // ```
+ //
+ // If the field can't be initialized to a constant value, then remove the
+ // keyword `const` from the constructor:
+ //
+ // ```dart
+ // class C {
+ // final String s = 3.toString();
+ // C();
+ // }
+ // ```
static const CompileTimeErrorCode
CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST =
CompileTimeErrorCode(
'CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST',
- "Can't define the const constructor because the field '{0}' "
- "is initialized with a non-constant value.",
+ "Can't define the 'const' constructor because the field '{0}' is "
+ "initialized with a non-constant value.",
correction: "Try initializing the field to a constant value, or "
"removing the keyword 'const' from the constructor.");
@@ -1927,15 +1999,6 @@
hasPublishedDocs: true);
/**
- * 16.12.2 Const: It is a compile-time error if <i>T</i> is not a class
- * accessible in the current scope, optionally followed by type arguments.
- *
- * 16.12.2 Const: If <i>e</i> is of the form <i>const T.id(a<sub>1</sub>,
- * …, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>, …
- * x<sub>n+k</sub>: a<sub>n+k</sub>)</i> it is a compile-time error if
- * <i>T</i> is not a class accessible in the current scope, optionally
- * followed by type arguments.
- *
* Parameters:
* 0: the name of the non-type element
*/
@@ -2037,17 +2100,6 @@
hasPublishedDocs: true);
/**
- * 6.2.1 Required Formals: By means of a function signature that names the
- * parameter and describes its type as a function type. It is a compile-time
- * error if any default values are specified in the signature of such a
- * function type.
- */
- static const CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER =
- CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER',
- "Default values aren't allowed in function typed parameters.",
- correction: "Try removing the default value.");
-
- /**
* 7.6.2 Factories: It is a compile-time error if <i>k</i> explicitly
* specifies a default value for an optional parameter.
*/
@@ -2601,6 +2653,58 @@
* Parameters:
* 0: The name of the disallowed type
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when one of the restricted classes is
+ // used in either an `extends`, `implements`, `with`, or `on` clause. The
+ // classes `bool`, `double`, `FutureOr`, `int`, `Null`, `num`, and `String`
+ // are all restricted in this way, to allow for more efficient
+ // implementations.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because `String` is used in an
+ // `extends` clause:
+ //
+ // ```dart
+ // class A extends [!String!] {}
+ // ```
+ //
+ // The following code produces this diagnostic because `String` is used in an
+ // `implements` clause:
+ //
+ // ```dart
+ // class B implements [!String!] {}
+ // ```
+ //
+ // The following code produces this diagnostic because `String` is used in a
+ // `with` clause:
+ //
+ // ```dart
+ // class C with [!String!] {}
+ // ```
+ //
+ // The following code produces this diagnostic because `String` is used in an
+ // `on` clause:
+ //
+ // ```dart
+ // mixin M on [!String!] {}
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If a different type should be specified, then replace the type:
+ //
+ // ```dart
+ // class A extends Object {}
+ // ```
+ //
+ // If there isn't a different type that would be appropriate, then remove the
+ // type, and possibly the whole clause:
+ //
+ // ```dart
+ // class B {}
+ // ```
static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
// TODO(scheglov) We might want to restore specific code with FrontEnd.
// https://github.com/dart-lang/sdk/issues/31821
@@ -3578,19 +3682,59 @@
correction: "Try changing the types so that they are compatible.");
/**
- * nnbd/feature-specification.md
- *
- * It is an error if a class has a setter and a getter with the same basename
- * where the return type of the getter is not a subtype of the argument type
- * of the setter. Note that this error specifically requires subtyping and
- * not assignability and hence makes no exception for `dynamic`.
- *
* Parameters:
* 0: the name of the getter
* 1: the type of the getter
* 2: the type of the setter
* 3: the name of the setter
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the return type of a getter
+ // isn't a subtype of the type of the parameter of a setter with the same
+ // name.
+ //
+ // The subtype relationship is a requirement whether the getter and setter are
+ // in the same class or whether one of them is in a superclass of the other.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the return type of the
+ // getter `x` is `num`, the parameter type of the setter `x` is `int`, and
+ // `num` isn't a subtype of `int`:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // class C {
+ // num get [!x!] => 0;
+ //
+ // set x(int y) {}
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the type of the getter is correct, then change the type of the setter:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // class C {
+ // num get x => 0;
+ //
+ // set x(num y) {}
+ // }
+ // ```
+ //
+ // If the type of the setter is correct, then change the type of the getter:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // class C {
+ // int get x => 0;
+ //
+ // set x(int y) {}
+ // }
+ // ```
static const CompileTimeErrorCode GETTER_NOT_SUBTYPE_SETTER_TYPES =
CompileTimeErrorCode(
'GETTER_NOT_SUBTYPE_SETTER_TYPES',
@@ -4371,11 +4515,74 @@
"-9,223,372,036,854,775,808.");
/**
- * 15 Metadata: Metadata consists of a series of annotations, each of which
- * begin with the character @, followed by a constant expression that must be
- * either a reference to a compile-time constant variable, or a call to a
- * constant constructor.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an annotation is found that is
+ // using something that is neither a variable marked as `const` or the
+ // invocation of a `const` constructor.
+ //
+ // Getters can't be used as annotations.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the variable `v` isn't
+ // a `const` variable:
+ //
+ // ```dart
+ // var v = 0;
+ //
+ // [!@v!]
+ // void f() {
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because `f` isn't a variable:
+ //
+ // ```dart
+ // [!@f!]
+ // void f() {
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because `f` isn't a
+ // constructor:
+ //
+ // ```dart
+ // [!@f()!]
+ // void f() {
+ // }
+ // ```
+ //
+ // The following code produces this diagnostic because `g` is a getter:
+ //
+ // ```dart
+ // [!@g!]
+ // int get g => 0;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the annotation is referencing a variable that isn't a `const`
+ // constructor, add the keyword `const` to the variable's declaration:
+ //
+ // ```dart
+ // const v = 0;
+ //
+ // @v
+ // void f() {
+ // }
+ // ```
+ //
+ // If the annotation isn't referencing a variable, then remove it:
+ //
+ // ```dart
+ // int v = 0;
+ //
+ // void f() {
+ // }
+ // ```
static const CompileTimeErrorCode INVALID_ANNOTATION = CompileTimeErrorCode(
'INVALID_ANNOTATION',
"Annotation must be either a const variable reference or const "
@@ -5099,11 +5306,51 @@
"correcting the name to match an existing label.");
/**
- * nnbd/feature-specification.md
- *
- * It is an error for a class with a `const` constructor to have a
- * `late final` field.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a class that has at least one
+ // `const` constructor also has a field marked both `late` and `final`.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the class `A` has a
+ // `const` constructor and the `final` field `f` is marked as `late`:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // class A {
+ // [!late!] final int f;
+ //
+ // const A();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the field doesn't need to be marked `late`, then remove the `late`
+ // modifier from the field:
+ //
+ // ```dart
+ // class A {
+ // final int f = 0;
+ //
+ // const A();
+ // }
+ // ```
+ //
+ // If the field must be marked `late`, then remove the `const` modifier from
+ // the constructors:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // class A {
+ // late final int f;
+ //
+ // A();
+ // }
+ // ```
static const CompileTimeErrorCode LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR =
CompileTimeErrorCode('LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR',
"Can't have a late final field in a class with a const constructor.",
@@ -5111,14 +5358,61 @@
"'const' constructors.");
/**
- * nnbd/feature-specification.md
- *
- * It is a compile time error to assign a value to a local variable marked
- * `late` and `final` when the variable is definitely assigned.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the analyzer can prove that a
+ // local variable marked as both `late` and `final` was already assigned a
+ // value at the point where another assignment occurs.
+ //
+ // Because `final` variables can only be assigned once, subsequent assignments
+ // are guaranteed to fail, so they're flagged.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the `final` variable
+ // `v` is assigned a value in two places:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // int f() {
+ // late final int v;
+ // v = 0;
+ // [!v!] += 1;
+ // return v;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you need to be able to reassign the variable, then remove the `final`
+ // keyword:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // int f() {
+ // late int v;
+ // v = 0;
+ // v += 1;
+ // return v;
+ // }
+ // ```
+ //
+ // If you don't need to reassign the variable, then remove all except the
+ // first of the assignments:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // int f() {
+ // late final int v;
+ // v = 0;
+ // return v;
+ // }
+ // ```
static const CompileTimeErrorCode LATE_FINAL_LOCAL_ALREADY_ASSIGNED =
CompileTimeErrorCode('LATE_FINAL_LOCAL_ALREADY_ASSIGNED',
- "The late final local variable is already definitely assigned.",
+ "The late final local variable is already assigned.",
correction: "Try removing the 'final' modifier, or don't reassign "
"the value.");
@@ -5617,7 +5911,7 @@
CompileTimeErrorCodeWithUniqueName(
'SUBTYPE_OF_DISALLOWED_TYPE',
'MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS',
- "'{0}' can't be used as a super-class constraint.",
+ "''{0}' can't be used as a superclass constraint.",
correction: "Try specifying a different super-class constraint, or "
"remove the 'on' clause.");
@@ -5692,12 +5986,50 @@
correction: "Try removing all but one of the 'super' initializers.");
/**
- * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible
- * in the current scope, optionally followed by type arguments.
- *
* Parameters:
* 0: the name of the non-type element
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an instance creation using
+ // either `new` or `const` specifies a name that isn't defined as a class.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because `f` is a function
+ // rather than a class:
+ //
+ // ```dart
+ // int f() => 0;
+ //
+ // void g() {
+ // new [!f!]();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If a class should be created, then replace the invalid name with the name
+ // of a valid class:
+ //
+ // ```dart
+ // int f() => 0;
+ //
+ // void g() {
+ // new Object();
+ // }
+ // ```
+ //
+ // If the name is the name of a function and you want that function to be
+ // invoked, then remove the `new` or `const` keyword:
+ //
+ // ```dart
+ // int f() => 0;
+ //
+ // void g() {
+ // f();
+ // }
+ // ```
static const CompileTimeErrorCode NEW_WITH_NON_TYPE =
CompileTimeErrorCodeWithUniqueName('CREATION_WITH_NON_TYPE',
'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
@@ -5820,22 +6152,64 @@
hasPublishedDocs: true);
/**
- * A method `m` of a class `C` is subject to override inference if it is
- * missing one or more component types of its signature, and one or more of
- * the direct superinterfaces of `C` has a member named `m` (*that is, `C.m`
- * overrides one or more declarations*). Each missing type is filled in with
- * the corresponding type from the combined member signature `s` of `m` in
- * the direct superinterfaces of `C`.
- *
- * A compile-time error occurs if `s` does not exist.
- *
* Parameters:
* 0: the name of the class where override error was detected
* 1: the list of candidate signatures which cannot be combined
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when there is a method declaration
+ // for which one or more types needs to be inferred, and those types can't be
+ // inferred because none of the overridden methods has a function type that is
+ // a supertype of all the other overridden methods, as specified by
+ // [override inference][].
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the method `m` declared
+ // in the class `C` is missing both the return type and the type of the
+ // parameter `a`, and neither of the missing types can be inferred for it:
+ //
+ // ```dart
+ // abstract class A {
+ // A m(String a);
+ // }
+ //
+ // abstract class B {
+ // B m(int a);
+ // }
+ //
+ // abstract class C implements A, B {
+ // [!m!](a);
+ // }
+ // ```
+ //
+ // In this example, override inference can't be performed because the
+ // overridden methods are incompatible in these ways:
+ // - Neither parameter type (`String` and `int`) is a supertype of the other.
+ // - Neither return type is a subtype of the other.
+ //
+ // #### Common fixes
+ //
+ // If possible, add types to the method in the subclass that are consistent
+ // with the types from all the overridden methods:
+ //
+ // ```dart
+ // abstract class A {
+ // A m(String a);
+ // }
+ //
+ // abstract class B {
+ // B m(int a);
+ // }
+ //
+ // abstract class C implements A, B {
+ // C m(Object a);
+ // }
+ // ```
static const CompileTimeErrorCode NO_COMBINED_SUPER_SIGNATURE =
CompileTimeErrorCode('NO_COMBINED_SUPER_SIGNATURE',
- "No valid combined signature in superinterfaces of '{0}': {1}.",
+ "Can't infer missing types in '{0}' from overridden methods: {1}.",
correction: "Try providing explicit types for this method's "
"parameters and return type.");
@@ -7485,9 +7859,44 @@
"different part.");
/**
- * 14.1 Imports: It is a compile-time error if the current library declares a
- * top-level member named <i>p</i>.
+ * Parameters:
+ * 0: The name of the prefix
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a name is used as both an import
+ // prefix and the name of a top-level declaration in the same library.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because `f` is used as both an
+ // import prefix and the name of a function:
+ //
+ // ```dart
+ // import 'dart:math' as f;
+ //
+ // int [!f!]() => f.min(0, 1);
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you want to use the name for the import prefix, then rename the
+ // top-level declaration:
+ //
+ // ```dart
+ // import 'dart:math' as f;
+ //
+ // int g() => f.min(0, 1);
+ // ```
+ //
+ // If you want to use the name for the top-level declaration, then rename the
+ // import prefix:
+ //
+ // ```dart
+ // import 'dart:math' as math;
+ //
+ // int f() => math.min(0, 1);
+ // ```
static const CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER =
CompileTimeErrorCode(
'PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER',
@@ -9679,9 +10088,9 @@
*/
// #### Description
//
- // The analyzer produces this diagnostic when an inherited member is
- // referenced using `super`, but there’s no member with that name in the
- // superclass chain.
+ // The analyzer produces this diagnostic when an inherited member (method,
+ // getter, setter, or operator) is referenced using `super`, but there’s no
+ // member with that name in the superclass chain.
//
// #### Examples
//
@@ -9715,8 +10124,8 @@
// If the member you intend to invoke is defined in the same class, then
// remove the `super.`.
//
- // If not, then either add the member to one of the superclasses or remove the
- // invocation.
+ // If the member isn’t defined, then either add the member to one of the
+ // superclasses or remove the invocation.
static const CompileTimeErrorCode UNDEFINED_SUPER_METHOD =
CompileTimeErrorCodeWithUniqueName(
'UNDEFINED_SUPER_MEMBER',
@@ -10213,19 +10622,59 @@
correction: "Try adjusting the number of type arguments.");
/**
- * It will be a static type warning if <i>m</i> is not a generic method with
- * exactly <i>n</i> type parameters.
- *
* Parameters:
* 0: the name of the method being referenced (<i>G</i>)
* 1: the number of type parameters that were declared
* 2: the number of type arguments provided
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a method or function is invoked
+ // with a different number of type arguments than the number of type
+ // parameters specified in its declaration. There must either be no type
+ // arguments or the number of arguments must match the number of parameters.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the invocation of the
+ // method `m` has two type arguments, but the declaration of `m` only has one
+ // type parameter:
+ //
+ // ```dart
+ // class C {
+ // int m<A>(A a) => 0;
+ // }
+ //
+ // int f(C c) => c.m[!<int, int>!](2);
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the type arguments are necessary, then make them match the number of
+ // type parameters by either adding or removing type arguments:
+ //
+ // ```dart
+ // class C {
+ // int m<A>(A a) => 0;
+ // }
+ //
+ // int f(C c) => c.m<int>(2);
+ // ```
+ //
+ // If the type arguments aren't necessary, then remove them:
+ //
+ // ```dart
+ // class C {
+ // int m<A>(A a) => 0;
+ // }
+ //
+ // int f(C c) => c.m(2);
+ // ```
static const CompileTimeErrorCode WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD =
CompileTimeErrorCode(
'WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD',
- "The method '{0}' is declared with {1} type parameters, "
- "but {2} type arguments were given.",
+ "The method '{0}' is declared with {1} type parameters, but {2} type "
+ "arguments are given.",
correction: "Try adjusting the number of type arguments.");
/**
@@ -10538,7 +10987,7 @@
// #### Description
//
// The analyzer produces this diagnostic when a null-aware operator (`?.`,
- // `?..`, `?[`, `?..[`, or `...?`) is used on a receiver that's known to be
+ // `?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
// non-nullable.
//
// #### Example
@@ -10560,6 +11009,26 @@
// var b = [[!...?!]a];
// ```
//
+ // The following code produces this diagnostic because `s?.length` can't
+ // return `null`:
+ //
+ // ```dart
+ // %experiments=non-nullable
+ // void f(String? s) {
+ // s?.length[!?.!]isEven;
+ // }
+ // ```
+ //
+ // The reason `s?.length` can't return `null` is because the null-aware
+ // operator following `s` short-circuits the evaluation of both `length` and
+ // `isEven` if `s` is `null`. In other words, if `s` is `null`, then neither
+ // `length` nor `isEven` will be invoked, and if `s` is non-`null`, then
+ // `length` can't return a `null` value. Either way, `isEven` can't be invoked
+ // on a `null` value, so the null-aware operator is neither necessary nor
+ // allowed. See
+ // [Understanding null safety](https://dart.dev/null-safety/understanding-null-safety#smarter-null-aware-methods)
+ // for more details.
+ //
// #### Common fixes
//
// Replace the null-aware operator with a non-null-aware equivalent; for
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4a49b97..9955b67 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -40,7 +40,6 @@
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
import 'package:analyzer/src/generated/this_access_tracker.dart';
-import 'package:analyzer/src/task/strong/checker.dart';
import 'package:meta/meta.dart';
class EnclosingExecutableContext {
@@ -319,8 +318,7 @@
_checkForArgumentTypeNotAssignableForArgument(rhs);
}
if (operatorType == TokenType.QUESTION_QUESTION_EQ) {
- _checkForDeadNullCoalesce(
- getReadType(node.leftHandSide), node.rightHandSide);
+ _checkForDeadNullCoalesce(node.readType, node.rightHandSide);
}
_checkForAssignmentToFinal(lhs);
super.visitAssignmentExpression(node);
@@ -355,8 +353,7 @@
}
if (type == TokenType.QUESTION_QUESTION) {
- _checkForDeadNullCoalesce(
- getReadType(node.leftOperand), node.rightOperand);
+ _checkForDeadNullCoalesce(node.leftOperand.staticType, node.rightOperand);
}
_checkForUseOfVoidResult(node.leftOperand);
@@ -533,7 +530,6 @@
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
_checkForInvalidAssignment(node.identifier, node.defaultValue);
- _checkForDefaultValueInFunctionTypedParameter(node);
super.visitDefaultFormalParameter(node);
}
@@ -2218,26 +2214,6 @@
}
}
- /// Verify that the given default formal [parameter] is not part of a function
- /// typed parameter.
- ///
- /// See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER].
- void _checkForDefaultValueInFunctionTypedParameter(
- DefaultFormalParameter parameter) {
- // OK, not in a function typed parameter.
- if (!_isInFunctionTypedFormalParameter) {
- return;
- }
- // OK, no default value.
- if (parameter.defaultValue == null) {
- return;
- }
-
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
- parameter);
- }
-
/// Report a diagnostic if there are any extensions in the imported library
/// that are not hidden.
void _checkForDeferredImportOfExtensions(
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index ecee766..a06752f 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -16,8 +16,6 @@
import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart';
import 'package:analyzer/src/generated/migration.dart';
import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/task/strong/checker.dart'
- show getExpressionType, getReadType;
/// Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
/// compute the static type of every expression. Second, they look for any static type errors or
@@ -344,10 +342,9 @@
/// Set the static type of [node] to be the least upper bound of the static
/// types of subexpressions [expr1] and [expr2].
void _analyzeLeastUpperBound(
- Expression node, Expression expr1, Expression expr2,
- {bool read = false}) {
- DartType staticType1 = _getExpressionType(expr1, read: read);
- DartType staticType2 = _getExpressionType(expr2, read: read);
+ Expression node, Expression expr1, Expression expr2) {
+ DartType staticType1 = expr1.staticType;
+ DartType staticType2 = expr2.staticType;
_analyzeLeastUpperBoundTypes(node, staticType1, staticType2);
}
@@ -371,20 +368,11 @@
recordStaticType(node, staticType);
}
- /// Gets the definite type of expression, which can be used in cases where
- /// the most precise type is desired, for example computing the least upper
- /// bound.
- ///
- /// See [getExpressionType] for more information. Without strong mode, this is
- /// equivalent to [_getStaticType].
- DartType _getExpressionType(Expression expr, {bool read = false}) =>
- getExpressionType(expr, _typeSystem, _typeProvider, read: read);
-
/// Return the static type of the given [expression].
DartType _getStaticType(Expression expression, {bool read = false}) {
DartType type;
if (read) {
- type = getReadType(expression);
+ type = expression.staticType;
} else {
if (expression is SimpleIdentifier && expression.inSetterContext()) {
var element = expression.staticElement;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 4e67d44..e3049ad 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -20,22 +20,9 @@
import 'package:analyzer/src/error/codes.dart'
show CompileTimeErrorCode, StrongModeCode;
import 'package:analyzer/src/summary/idl.dart';
+import 'package:meta/meta.dart';
-/// Given an [expression] and a corresponding [typeSystem] and [typeProvider],
-/// gets the known static type of the expression.
-DartType getExpressionType(
- Expression expression, TypeSystemImpl typeSystem, TypeProvider typeProvider,
- {bool read = false}) {
- DartType type;
- if (read) {
- type = getReadType(expression);
- } else {
- type = expression.staticType;
- }
- type ??= DynamicTypeImpl.instance;
- return type;
-}
-
+@Deprecated('Use CompoundAssignmentExpression.readType')
DartType getReadType(Expression expression) {
if (expression is IndexExpression) {
var aux = expression.auxiliaryElements;
@@ -148,8 +135,8 @@
}
}
- void checkAssignment(Expression expr, DartType type) {
- checkForCast(expr, type);
+ void checkAssignment(Expression expr, DartType to) {
+ checkForCast(expr, from: expr.staticType, to: to);
}
/// Analyzer checks boolean conversions, but we need to check too, because
@@ -176,20 +163,26 @@
var exprType = element.expression.staticType;
var asIterableType = exprType.asInstanceOf(typeProvider.iterableElement);
- var elementType =
- asIterableType == null ? null : asIterableType.typeArguments[0];
- // Items in the spread will then potentially be downcast to the expected
- // type.
- _checkImplicitCast(element.expression, expectedType,
- from: elementType, forSpread: true);
+
+ if (asIterableType != null) {
+ var elementType = asIterableType.typeArguments[0];
+ // Items in the spread will then potentially be downcast to the expected
+ // type.
+ _checkImplicitCast(element.expression,
+ to: expectedType, from: elementType, forSpread: true);
+ }
}
}
- void checkForCast(Expression expr, DartType type) {
+ void checkForCast(
+ Expression expr, {
+ @required DartType from,
+ @required DartType to,
+ }) {
if (expr is ParenthesizedExpression) {
- checkForCast(expr.expression, type);
+ checkForCast(expr.expression, from: from, to: to);
} else {
- _checkImplicitCast(expr, type);
+ _checkImplicitCast(expr, from: from, to: to);
}
}
@@ -214,16 +207,18 @@
var exprType = element.expression.staticType;
var asMapType = exprType.asInstanceOf(typeProvider.mapElement);
- var elementKeyType =
- asMapType == null ? null : asMapType.typeArguments[0];
- var elementValueType =
- asMapType == null ? null : asMapType.typeArguments[1];
- // Keys and values in the spread will then potentially be downcast to
- // the expected types.
- _checkImplicitCast(element.expression, expectedKeyType,
- from: elementKeyType, forSpreadKey: true);
- _checkImplicitCast(element.expression, expectedValueType,
- from: elementValueType, forSpreadValue: true);
+ if (asMapType != null) {
+ var elementKeyType = asMapType.typeArguments[0];
+ var elementValueType = asMapType.typeArguments[1];
+ // Keys and values in the spread will then potentially be downcast to
+ // the expected types.
+ _checkImplicitCast(element.expression,
+ to: expectedKeyType, from: elementKeyType, forSpreadKey: true);
+ _checkImplicitCast(element.expression,
+ to: expectedValueType,
+ from: elementValueType,
+ forSpreadValue: true);
+ }
}
}
@@ -241,16 +236,17 @@
@override
void visitAssignmentExpression(AssignmentExpression node) {
+ var left = node.leftHandSide;
+ var right = node.rightHandSide;
Token operator = node.operator;
TokenType operatorType = operator.type;
if (operatorType == TokenType.EQ ||
operatorType == TokenType.QUESTION_QUESTION_EQ) {
- DartType staticType = _getExpressionType(node.leftHandSide);
- checkAssignment(node.rightHandSide, staticType);
+ checkForCast(right, from: right.staticType, to: node.writeType);
} else if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
operatorType == TokenType.BAR_BAR_EQ) {
- checkAssignment(node.leftHandSide, typeProvider.boolType);
- checkAssignment(node.rightHandSide, typeProvider.boolType);
+ checkBoolean(left);
+ checkBoolean(right);
} else {
_checkCompoundAssignment(node);
}
@@ -457,7 +453,8 @@
@override
void visitPostfixExpression(PostfixExpression node) {
- _checkUnary(node.operand, node.operator, node.staticElement);
+ _checkUnary(node.operand, node.operator, node.staticElement,
+ readType: node.readType, writeType: node.writeType);
node.visitChildren(this);
}
@@ -466,7 +463,8 @@
if (node.operator.type == TokenType.BANG) {
checkBoolean(node.operand);
} else {
- _checkUnary(node.operand, node.operator, node.staticElement);
+ _checkUnary(node.operand, node.operator, node.staticElement,
+ readType: node.readType, writeType: node.writeType);
}
node.visitChildren(this);
}
@@ -588,7 +586,8 @@
for (VariableDeclaration variable in node.variables) {
var initializer = variable.initializer;
if (initializer != null) {
- checkForCast(initializer, type.type);
+ checkForCast(initializer,
+ from: initializer.staticType, to: type.type);
}
}
}
@@ -622,10 +621,9 @@
assert(functionType.optionalParameterTypes.isEmpty);
// Refine the return type.
- var rhsType = _getExpressionType(expr.rightHandSide);
- var lhsType = _getExpressionType(expr.leftHandSide);
+ var rhsType = expr.rightHandSide.staticType;
var returnType = rules.refineBinaryExpressionType(
- lhsType,
+ expr.readType,
op,
rhsType,
functionType.returnType,
@@ -633,7 +631,7 @@
);
// Check the argument for an implicit cast.
- _checkImplicitCast(expr.rightHandSide, paramTypes[0], from: rhsType);
+ _checkImplicitCast(expr.rightHandSide, to: paramTypes[0], from: rhsType);
// Check the return type for an implicit cast.
//
@@ -643,8 +641,8 @@
// y = /*implicit cast*/(y + 42);
// /*implicit assignment cast*/y += 42;
//
- _checkImplicitCast(expr.leftHandSide, lhsType,
- from: returnType, opAssign: true);
+ _checkImplicitCast(expr.leftHandSide,
+ to: expr.writeType, from: returnType, opAssign: true);
}
}
@@ -694,8 +692,9 @@
///
/// If [expr] does not require an implicit cast because it is not related to
/// [to] or is already a subtype of it, does nothing.
- void _checkImplicitCast(Expression expr, DartType to,
- {DartType from,
+ void _checkImplicitCast(Expression expr,
+ {@required DartType to,
+ @required DartType from,
bool opAssign = false,
bool forSpread = false,
bool forSpreadKey = false,
@@ -704,9 +703,7 @@
return;
}
- from ??= _getExpressionType(expr);
-
- if (_needsImplicitCast(expr, to, from: from) == true) {
+ if (_needsImplicitCast(expr, to: to, from: from) == true) {
_recordImplicitCast(expr, to,
from: from,
opAssign: opAssign,
@@ -730,7 +727,8 @@
if (expression != null) checkAssignment(expression, type);
}
- void _checkUnary(Expression operand, Token op, MethodElement element) {
+ void _checkUnary(Expression operand, Token op, MethodElement element,
+ {@required DartType readType, @required DartType writeType}) {
bool isIncrementAssign = op.type.isIncrementOperator;
if (op.isUserDefinableOperator || isIncrementAssign) {
if (element != null && isIncrementAssign) {
@@ -744,9 +742,8 @@
// Refine the return type.
var functionType = element.type;
var rhsType = typeProvider.intType;
- var lhsType = _getExpressionType(operand);
var returnType = rules.refineBinaryExpressionType(
- lhsType,
+ readType,
TokenType.PLUS,
rhsType,
functionType.returnType,
@@ -763,7 +760,8 @@
// y = /*implicit cast*/(y + 1);
// /*implicit assignment cast*/y++;
//
- _checkImplicitCast(operand, lhsType, from: returnType, opAssign: true);
+ _checkImplicitCast(operand,
+ to: writeType, from: returnType, opAssign: true);
}
}
}
@@ -827,9 +825,6 @@
}
}
- DartType _getExpressionType(Expression expr) =>
- getExpressionType(expr, rules, typeProvider);
-
DartType _getInstanceTypeArgument(
DartType expressionType, ClassElement instanceType) {
var asInstanceType = expressionType.asInstanceOf(instanceType);
@@ -860,9 +855,8 @@
/// downcast implicitly).
///
/// If [from] is omitted, uses the static type of [expr]
- bool _needsImplicitCast(Expression expr, DartType to, {DartType from}) {
- from ??= _getExpressionType(expr);
-
+ bool _needsImplicitCast(Expression expr,
+ {@required DartType from, @required DartType to}) {
// Void is considered Top, but may only be *explicitly* cast.
if (from.isVoid) return null;
@@ -886,8 +880,8 @@
if (to.isDartAsyncFutureOr) {
var to1 = (to as InterfaceType).typeArguments[0];
var to2 = typeProvider.futureType2(to1);
- return _needsImplicitCast(expr, to1, from: from) == true ||
- _needsImplicitCast(expr, to2, from: from) == true;
+ return _needsImplicitCast(expr, to: to1, from: from) == true ||
+ _needsImplicitCast(expr, to: to2, from: from) == true;
}
// Anything else is an illegal sideways cast.
@@ -1021,7 +1015,7 @@
var sequenceElement = awaitKeyword != null
? typeProvider.streamElement
: typeProvider.iterableElement;
- var iterableType = _getExpressionType(node.iterable);
+ var iterableType = node.iterable.staticType;
var elementType = _getInstanceTypeArgument(iterableType, sequenceElement);
// If the sequence is not an Iterable (or Stream for await for) but is a
@@ -1043,8 +1037,8 @@
if (elementType != null) {
// Insert a cast from the sequence's element type to the loop variable's
// if needed.
- _checkImplicitCast(loopVariable, loopVariableElement.type,
- from: elementType);
+ _checkImplicitCast(loopVariable,
+ to: loopVariableElement.type, from: elementType);
}
}
}
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a5956bb..c86ea47 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -1469,29 +1469,6 @@
expect(typeA.getMethod(methodName), same(methodM));
}
- void test_getMethod_parameterized_doesNotUseTypeParameter() {
- //
- // class A<E> { B m() {} }
- // class B {}
- //
- var classA = ElementFactory.classElement2("A", ["E"]);
- InterfaceType typeB = interfaceTypeStar(class_(name: 'B'));
- String methodName = "m";
- MethodElementImpl methodM =
- ElementFactory.methodElement(methodName, typeB, []);
- classA.methods = <MethodElement>[methodM];
- //
- // A<I>
- //
- InterfaceType typeI = interfaceTypeStar(class_(name: 'I'));
- InterfaceTypeImpl typeAI =
- interfaceTypeStar(classA, typeArguments: <DartType>[typeI]);
- MethodElement method = typeAI.getMethod(methodName);
- expect(method, isNotNull);
- FunctionType methodType = method.type;
- expect(methodType.typeArguments, isEmpty);
- }
-
void test_getMethod_parameterized_usesTypeParameter() {
//
// class A<E> { E m(E p) {} }
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index 0c06671..155270f 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -466,21 +466,14 @@
}
test_notLValue_postfixIncrement_compound_ifNull() async {
- await assertErrorsInCode(
- '''
+ await assertErrorsInCode('''
void f(num x, int y) {
x++ ??= y;
}
-''',
- expectedErrorsByNullability(nullable: [
- error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
- error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 33, 1),
- ], legacy: [
- error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
- ]),
- );
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
assertAssignment(
findNode.assignment('= y'),
@@ -557,21 +550,14 @@
}
test_notLValue_prefixIncrement_compound_ifNull() async {
- await assertErrorsInCode(
- '''
+ await assertErrorsInCode('''
void f(num x, int y) {
++x ??= y;
}
-''',
- expectedErrorsByNullability(nullable: [
- error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
- error(StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION, 33, 1),
- ], legacy: [
- error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
- error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
- ]),
- );
+''', [
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 25, 3),
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 25, 3),
+ ]);
assertAssignment(
findNode.assignment('= y'),
diff --git a/pkg/analyzer/test/src/diagnostics/default_value_in_function_typed_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/default_value_in_function_typed_parameter_test.dart
deleted file mode 100644
index 746f479..0000000
--- a/pkg/analyzer/test/src/diagnostics/default_value_in_function_typed_parameter_test.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/context_collection_resolution.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(DefaultValueInFunctionTypedParameterTest);
- });
-}
-
-@reflectiveTest
-class DefaultValueInFunctionTypedParameterTest
- extends PubPackageResolutionTest {
- test_named() async {
- await assertErrorsInCode('''
-f(g({p: null})) {}
-''', [
- error(
- CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, 5, 7),
- error(ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE, 6, 1),
- ]);
- }
-
- test_positional() async {
- await assertErrorsInCode('''
-f(g([p = null])) {}
-''', [
- error(
- CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, 5, 8),
- error(ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE, 7, 1),
- ]);
- }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 0711ccb..bc65f4c 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -114,8 +114,6 @@
import 'default_list_constructor_test.dart' as default_list_constructor;
import 'default_value_in_function_type_test.dart'
as default_value_in_function_type;
-import 'default_value_in_function_typed_parameter_test.dart'
- as default_value_in_function_typed_parameter;
import 'default_value_in_redirecting_factory_constructor_test.dart'
as default_value_in_redirecting_factory_constructor;
import 'default_value_on_required_parameter_test.dart'
@@ -725,7 +723,6 @@
dead_null_aware_expression.main();
default_list_constructor.main();
default_value_in_function_type.main();
- default_value_in_function_typed_parameter.main();
default_value_in_redirecting_factory_constructor.main();
default_value_on_required_parameter.main();
deferred_import_of_extension.main();
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index e0b0db5..3cb4448 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -18,6 +18,7 @@
This page uses the following terms.
[constant context]: #constant-context
+[override inference]: #override-inference
[potentially non-nullable]: #potentially-non-nullable
### Constant context
@@ -60,6 +61,64 @@
}
```
+### Override inference
+
+Override inference is the process by which any missing types in a method
+declaration are inferred based on the corresponding types from the method or
+methods that it overrides.
+
+If a candidate method (the method that's missing type information) overrides a
+single inherited method, then the corresponding types from the overridden method
+are inferred. For example, consider the following code:
+
+```dart
+class A {
+ int m(String s) => 0;
+}
+
+class B extends A {
+ @override
+ m(s) => 1;
+}
+```
+
+The declaration of `m` in `B` is a candidate because it's missing both the
+return type and the parameter type. Because it overrides a single method (the
+method `m` in `A`), the types from the overridden method will be used to infer
+the missing types and it will be as if the method in `B` had been declared as
+`int m(String s) => 1;`.
+
+If a candidate method overrides multiple methods, and the function type one of
+those overridden methods, M<sub>s</sub>, is a supertype of the function types of
+all of the other overridden methods, then M<sub>s</sub> is used to infer the
+missing types. For example, consider the following code:
+
+```dart
+class A {
+ int m(num n) => 0;
+}
+
+class B {
+ num m(int i) => 0;
+}
+
+class C implements A, B {
+ @override
+ m(n) => 1;
+}
+```
+
+The declaration of `m` in `C` is a candidate for override inference because it's
+missing both the return type and the parameter type. It overrides both `m` in
+`A` and `m` in `B`, so we need to choose one of them from which the missing
+types can be inferred. But because the function type of `m` in `A`
+(`int Function(num)`) is a supertype of the function type of `m` in `B`
+(`num Function(int)`), the function in `A` is used to infer the missing types.
+The result is the same as declaring the method in `C` as `int m(num n) => 1;`.
+
+It is an error if none of the overridden methods has a function type that is a
+supertype of all the other overridden methods.
+
### Potentially non-nullable
A type is _potentially non-nullable_ if it's either explicitly non-nullable or
@@ -576,6 +635,47 @@
Rewrite the code so that there isn't an assignment to a method.
+### await_in_late_local_variable_initializer
+
+_The 'await' expression can't be used in a 'late' local variable's initializer._
+
+#### Description
+
+The analyzer produces this diagnostic when a local variable that has the
+'late' modifier uses an 'await' expression in the initializer.
+
+#### Example
+
+The following code produces this diagnostic because an 'await' expression
+is used in the initializer for 'v', a local variable that is marked 'late':
+
+{% prettify dart tag=pre+code %}
+Future<int> f() async {
+ late v = [!await!] 42;
+ return v;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the initializer can be rewritten to not use 'await', then rewrite it:
+
+{% prettify dart tag=pre+code %}
+Future<int> f() async {
+ late v = 42;
+ return v;
+}
+{% endprettify %}
+
+If the initializer can't be rewritten, then remove the 'late' modifier:
+
+{% prettify dart tag=pre+code %}
+Future<int> f() async {
+ var v = await 42;
+ return v;
+}
+{% endprettify %}
+
### body_might_complete_normally
_The body might complete normally, causing 'null' to be returned, but the return
@@ -910,6 +1010,50 @@
}
{% endprettify %}
+### const_constructor_with_field_initialized_by_non_const
+
+_Can't define the 'const' constructor because the field '{0}' is initialized
+with a non-constant value._
+
+#### Description
+
+The analyzer produces this diagnostic when a constructor has the keyword
+`const`, but a field in the class is initialized to a non-constant value.
+
+#### Example
+
+The following code produces this diagnostic because the field `s` is
+initialized to a non-constant value:
+
+{% prettify dart tag=pre+code %}
+class C {
+ final String s = 3.toString();
+ [!const!] C();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the field can be initialized to a constant value, then change the
+initializer to a constant expression:
+
+{% prettify dart tag=pre+code %}
+class C {
+ final String s = '3';
+ const C();
+}
+{% endprettify %}
+
+If the field can't be initialized to a constant value, then remove the
+keyword `const` from the constructor:
+
+{% prettify dart tag=pre+code %}
+class C {
+ final String s = 3.toString();
+ C();
+}
+{% endprettify %}
+
### const_constructor_with_non_final_field
_Can't define a const constructor for a class with non-final fields._
@@ -1196,6 +1340,54 @@
C f(int i) => C(i);
{% endprettify %}
+### creation_with_non_type
+
+_The name '{0}' isn't a class._
+
+_The name '{0}' isn't a class._
+
+#### Description
+
+The analyzer produces this diagnostic when an instance creation using
+either `new` or `const` specifies a name that isn't defined as a class.
+
+#### Example
+
+The following code produces this diagnostic because `f` is a function
+rather than a class:
+
+{% prettify dart tag=pre+code %}
+int f() => 0;
+
+void g() {
+ new [!f!]();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If a class should be created, then replace the invalid name with the name
+of a valid class:
+
+{% prettify dart tag=pre+code %}
+int f() => 0;
+
+void g() {
+ new Object();
+}
+{% endprettify %}
+
+If the name is the name of a function and you want that function to be
+invoked, then remove the `new` or `const` keyword:
+
+{% prettify dart tag=pre+code %}
+int f() => 0;
+
+void g() {
+ f();
+}
+{% endprettify %}
+
### dead_code
_Dead code._
@@ -1468,6 +1660,36 @@
var l = List.generate(3, (i) => i);
{% endprettify %}
+### default_value_in_function_type
+
+_Parameters in a function type can't have default values._
+
+#### Description
+
+The analyzer produces this diagnostic when a function type associated with
+a parameter includes optional parameters that have a default value. This
+isn't allowed because the default values of parameters aren't part of the
+function's type, and therefore including them doesn't provide any value.
+
+#### Example
+
+The following code produces this diagnostic because the parameter `p` has a
+default value even though it's part of the type of the parameter `g`:
+
+{% prettify dart tag=pre+code %}
+void f(void Function([int p [!=!] 0]) g) {
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the default value from the function-type's parameter:
+
+{% prettify dart tag=pre+code %}
+void f(void Function([int p]) g) {
+}
+{% endprettify %}
+
### definitely_unassigned_late_local_variable
_The late local variable '{0}' is definitely unassigned at this point._
@@ -2730,6 +2952,56 @@
}
{% endprettify %}
+### getter_not_subtype_setter_types
+
+_The return type of getter '{0}' is '{1}' which isn't a subtype of the type
+'{2}' of its setter '{3}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the return type of a getter
+isn't a subtype of the type of the parameter of a setter with the same
+name.
+
+The subtype relationship is a requirement whether the getter and setter are
+in the same class or whether one of them is in a superclass of the other.
+
+#### Example
+
+The following code produces this diagnostic because the return type of the
+getter `x` is `num`, the parameter type of the setter `x` is `int`, and
+`num` isn't a subtype of `int`:
+
+{% prettify dart tag=pre+code %}
+class C {
+ num get [!x!] => 0;
+
+ set x(int y) {}
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the type of the getter is correct, then change the type of the setter:
+
+{% prettify dart tag=pre+code %}
+class C {
+ num get x => 0;
+
+ set x(num y) {}
+}
+{% endprettify %}
+
+If the type of the setter is correct, then change the type of the getter:
+
+{% prettify dart tag=pre+code %}
+class C {
+ int get x => 0;
+
+ set x(int y) {}
+}
+{% endprettify %}
+
### illegal_async_return_type
_Functions marked 'async' must have a return type assignable to 'Future'._
@@ -3232,6 +3504,80 @@
If there's a concrete subclass of the abstract class that can be used, then
create an instance of the concrete subclass.
+### invalid_annotation
+
+_Annotation must be either a const variable reference or const constructor
+invocation._
+
+_Getters can't be used as annotations._
+
+#### Description
+
+The analyzer produces this diagnostic when an annotation is found that is
+using something that is neither a variable marked as `const` or the
+invocation of a `const` constructor.
+
+Getters can't be used as annotations.
+
+#### Example
+
+The following code produces this diagnostic because the variable `v` isn't
+a `const` variable:
+
+{% prettify dart tag=pre+code %}
+var v = 0;
+
+[!@v!]
+void f() {
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `f` isn't a variable:
+
+{% prettify dart tag=pre+code %}
+[!@f!]
+void f() {
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `f` isn't a
+constructor:
+
+{% prettify dart tag=pre+code %}
+[!@f()!]
+void f() {
+}
+{% endprettify %}
+
+The following code produces this diagnostic because `g` is a getter:
+
+{% prettify dart tag=pre+code %}
+[!@g!]
+int get g => 0;
+{% endprettify %}
+
+#### Common fixes
+
+If the annotation is referencing a variable that isn't a `const`
+constructor, add the keyword `const` to the variable's declaration:
+
+{% prettify dart tag=pre+code %}
+const v = 0;
+
+@v
+void f() {
+}
+{% endprettify %}
+
+If the annotation isn't referencing a variable, then remove it:
+
+{% prettify dart tag=pre+code %}
+int v = 0;
+
+void f() {
+}
+{% endprettify %}
+
### invalid_assignment
_A value of type '{0}' can't be assigned to a variable of type '{1}'._
@@ -3453,7 +3799,7 @@
#### Description
The analyzer produces this diagnostic when a null-aware operator (`?.`,
-`?..`, `?[`, `?..[`, or `...?`) is used on a receiver that's known to be
+`?..`, `?[`, `?..[`, or `...?`) is used on a target that's known to be
non-nullable.
#### Example
@@ -3473,6 +3819,25 @@
var b = [[!...?!]a];
{% endprettify %}
+The following code produces this diagnostic because `s?.length` can't
+return `null`:
+
+{% prettify dart tag=pre+code %}
+void f(String? s) {
+ s?.length[!?.!]isEven;
+}
+{% endprettify %}
+
+The reason `s?.length` can't return `null` is because the null-aware
+operator following `s` short-circuits the evaluation of both `length` and
+`isEven` if `s` is `null`. In other words, if `s` is `null`, then neither
+`length` nor `isEven` will be invoked, and if `s` is non-`null`, then
+`length` can't return a `null` value. Either way, `isEven` can't be invoked
+on a `null` value, so the null-aware operator is neither necessary nor
+allowed. See
+[Understanding null safety](https://dart.dev/null-safety/understanding-null-safety#smarter-null-aware-methods)
+for more details.
+
#### Common fixes
Replace the null-aware operator with a non-null-aware equivalent; for
@@ -3828,6 +4193,104 @@
var y = f();
{% endprettify %}
+### late_final_field_with_const_constructor
+
+_Can't have a late final field in a class with a const constructor._
+
+#### Description
+
+The analyzer produces this diagnostic when a class that has at least one
+`const` constructor also has a field marked both `late` and `final`.
+
+#### Example
+
+The following code produces this diagnostic because the class `A` has a
+`const` constructor and the `final` field `f` is marked as `late`:
+
+{% prettify dart tag=pre+code %}
+class A {
+ [!late!] final int f;
+
+ const A();
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the field doesn't need to be marked `late`, then remove the `late`
+modifier from the field:
+
+{% prettify dart tag=pre+code %}
+class A {
+ final int f = 0;
+
+ const A();
+}
+{% endprettify %}
+
+If the field must be marked `late`, then remove the `const` modifier from
+the constructors:
+
+{% prettify dart tag=pre+code %}
+class A {
+ late final int f;
+
+ A();
+}
+{% endprettify %}
+
+### late_final_local_already_assigned
+
+_The late final local variable is already assigned._
+
+#### Description
+
+The analyzer produces this diagnostic when the analyzer can prove that a
+local variable marked as both `late` and `final` was already assigned a
+value at the point where another assignment occurs.
+
+Because `final` variables can only be assigned once, subsequent assignments
+are guaranteed to fail, so they're flagged.
+
+#### Example
+
+The following code produces this diagnostic because the `final` variable
+`v` is assigned a value in two places:
+
+{% prettify dart tag=pre+code %}
+int f() {
+ late final int v;
+ v = 0;
+ [!v!] += 1;
+ return v;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you need to be able to reassign the variable, then remove the `final`
+keyword:
+
+{% prettify dart tag=pre+code %}
+int f() {
+ late int v;
+ v = 0;
+ v += 1;
+ return v;
+}
+{% endprettify %}
+
+If you don't need to reassign the variable, then remove all except the
+first of the assignments:
+
+{% prettify dart tag=pre+code %}
+int f() {
+ late final int v;
+ v = 0;
+ return v;
+}
+{% endprettify %}
+
### list_element_type_not_assignable
_The element type '{0}' can't be assigned to the list type '{1}'._
@@ -5455,6 +5918,62 @@
var x;
{% endprettify %}
+### no_combined_super_signature
+
+_Can't infer missing types in '{0}' from overridden methods: {1}._
+
+#### Description
+
+The analyzer produces this diagnostic when there is a method declaration
+for which one or more types needs to be inferred, and those types can't be
+inferred because none of the overridden methods has a function type that is
+a supertype of all the other overridden methods, as specified by
+[override inference][].
+
+#### Example
+
+The following code produces this diagnostic because the method `m` declared
+in the class `C` is missing both the return type and the type of the
+parameter `a`, and neither of the missing types can be inferred for it:
+
+{% prettify dart tag=pre+code %}
+abstract class A {
+ A m(String a);
+}
+
+abstract class B {
+ B m(int a);
+}
+
+abstract class C implements A, B {
+ [!m!](a);
+}
+{% endprettify %}
+
+In this example, override inference can't be performed because the
+overridden methods are incompatible in these ways:
+- Neither parameter type (`String` and `int`) is a supertype of the other.
+- Neither return type is a subtype of the other.
+
+#### Common fixes
+
+If possible, add types to the method in the subclass that are consistent
+with the types from all the overridden methods:
+
+{% prettify dart tag=pre+code %}
+abstract class A {
+ A m(String a);
+}
+
+abstract class B {
+ B m(int a);
+}
+
+abstract class C implements A, B {
+ C m(Object a);
+}
+{% endprettify %}
+
### nullable_type_in_catch_clause
_A potentially nullable type can't be used in an 'on' clause because it isn't
@@ -5760,6 +6279,47 @@
import 'a.dart';
{% endprettify %}
+### prefix_collides_with_top_level_member
+
+_The name '{0}' is already used as an import prefix and can't be used to name a
+top-level element._
+
+#### Description
+
+The analyzer produces this diagnostic when a name is used as both an import
+prefix and the name of a top-level declaration in the same library.
+
+#### Example
+
+The following code produces this diagnostic because `f` is used as both an
+import prefix and the name of a function:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as f;
+
+int [!f!]() => f.min(0, 1);
+{% endprettify %}
+
+#### Common fixes
+
+If you want to use the name for the import prefix, then rename the
+top-level declaration:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as f;
+
+int g() => f.min(0, 1);
+{% endprettify %}
+
+If you want to use the name for the top-level declaration, then rename the
+import prefix:
+
+{% prettify dart tag=pre+code %}
+import 'dart:math' as math;
+
+int f() => math.min(0, 1);
+{% endprettify %}
+
### prefix_identifier_not_followed_by_dot
_The name '{0}' refers to an import prefix, so it must be followed by '.'._
@@ -6689,6 +7249,69 @@
int f(C c) => c.b;
{% endprettify %}
+### subtype_of_disallowed_type
+
+_''{0}' can't be used as a superclass constraint._
+
+_Classes and mixins can't implement '{0}'._
+
+_Classes can't extend '{0}'._
+
+_Classes can't mixin '{0}'._
+
+#### Description
+
+The analyzer produces this diagnostic when one of the restricted classes is
+used in either an `extends`, `implements`, `with`, or `on` clause. The
+classes `bool`, `double`, `FutureOr`, `int`, `Null`, `num`, and `String`
+are all restricted in this way, to allow for more efficient
+implementations.
+
+#### Example
+
+The following code produces this diagnostic because `String` is used in an
+`extends` clause:
+
+{% prettify dart tag=pre+code %}
+class A extends [!String!] {}
+{% endprettify %}
+
+The following code produces this diagnostic because `String` is used in an
+`implements` clause:
+
+{% prettify dart tag=pre+code %}
+class B implements [!String!] {}
+{% endprettify %}
+
+The following code produces this diagnostic because `String` is used in a
+`with` clause:
+
+{% prettify dart tag=pre+code %}
+class C with [!String!] {}
+{% endprettify %}
+
+The following code produces this diagnostic because `String` is used in an
+`on` clause:
+
+{% prettify dart tag=pre+code %}
+mixin M on [!String!] {}
+{% endprettify %}
+
+#### Common fixes
+
+If a different type should be specified, then replace the type:
+
+{% prettify dart tag=pre+code %}
+class A extends Object {}
+{% endprettify %}
+
+If there isn't a different type that would be appropriate, then remove the
+type, and possibly the whole clause:
+
+{% prettify dart tag=pre+code %}
+class B {}
+{% endprettify %}
+
### super_in_extension
_The 'super' keyword can't be used in an extension because an extension doesn't
@@ -7819,9 +8442,9 @@
#### Description
-The analyzer produces this diagnostic when an inherited member is
-referenced using `super`, but there’s no member with that name in the
-superclass chain.
+The analyzer produces this diagnostic when an inherited member (method,
+getter, setter, or operator) is referenced using `super`, but there’s no
+member with that name in the superclass chain.
#### Examples
@@ -7855,8 +8478,8 @@
If the member you intend to invoke is defined in the same class, then
remove the `super.`.
-If not, then either add the member to one of the superclasses or remove the
-invocation.
+If the member isn’t defined, then either add the member to one of the
+superclasses or remove the invocation.
### unnecessary_cast
@@ -8126,9 +8749,14 @@
#### Description
-The analyzer produces this diagnostic when a private class, enum, mixin,
-typedef, top level variable, top level function, or method is declared but
-never referenced.
+The analyzer produces this diagnostic when a private declaration isn't
+referenced in the library that contains the declaration. The following
+kinds of declarations are analyzed:
+- Private top-level declarations, such as classes, enums, mixins, typedefs,
+ top-level variables, and top-level functions
+- Private static and instance methods
+- Optional parameters of private functions for which a value is never
+ passed, even when the parameter doesn't have a private name
#### Examples
@@ -8139,11 +8767,30 @@
class [!_C!] {}
{% endprettify %}
+Assuming that no code in the library passes a value for `y` in any
+invocation of `_m`, the following code produces this diagnostic:
+
+{% prettify dart tag=pre+code %}
+class C {
+ void _m(int x, [int [!y!]]) {}
+
+ void n() => _m(0);
+}
+{% endprettify %}
+
#### Common fixes
-If the declaration isn't needed, then remove it.
+If the declaration isn't needed, then remove it:
-If the declaration was intended to be used, then add the missing code.
+{% prettify dart tag=pre+code %}
+class C {
+ void _m(int x) {}
+
+ void n() => _m(0);
+}
+{% endprettify %}
+
+If the declaration is intended to be used, then add the code to use it.
### unused_field
@@ -8542,6 +9189,55 @@
void f(C<int> x) {}
{% endprettify %}
+### wrong_number_of_type_arguments_method
+
+_The method '{0}' is declared with {1} type parameters, but {2} type arguments
+are given._
+
+#### Description
+
+The analyzer produces this diagnostic when a method or function is invoked
+with a different number of type arguments than the number of type
+parameters specified in its declaration. There must either be no type
+arguments or the number of arguments must match the number of parameters.
+
+#### Example
+
+The following code produces this diagnostic because the invocation of the
+method `m` has two type arguments, but the declaration of `m` only has one
+type parameter:
+
+{% prettify dart tag=pre+code %}
+class C {
+ int m<A>(A a) => 0;
+}
+
+int f(C c) => c.m[!<int, int>!](2);
+{% endprettify %}
+
+#### Common fixes
+
+If the type arguments are necessary, then make them match the number of
+type parameters by either adding or removing type arguments:
+
+{% prettify dart tag=pre+code %}
+class C {
+ int m<A>(A a) => 0;
+}
+
+int f(C c) => c.m<int>(2);
+{% endprettify %}
+
+If the type arguments aren't necessary, then remove them:
+
+{% prettify dart tag=pre+code %}
+class C {
+ int m<A>(A a) => 0;
+}
+
+int f(C c) => c.m(2);
+{% endprettify %}
+
### undefined_super_method
See [undefined_super_member](#undefined-super-member).
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 59b6c0e..7d903d9 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -403,6 +403,7 @@
This page uses the following terms.
[constant context]: #constant-context
+[override inference]: #override-inference
[potentially non-nullable]: #potentially-non-nullable
### Constant context
@@ -445,6 +446,64 @@
}
```
+### Override inference
+
+Override inference is the process by which any missing types in a method
+declaration are inferred based on the corresponding types from the method or
+methods that it overrides.
+
+If a candidate method (the method that's missing type information) overrides a
+single inherited method, then the corresponding types from the overridden method
+are inferred. For example, consider the following code:
+
+```dart
+class A {
+ int m(String s) => 0;
+}
+
+class B extends A {
+ @override
+ m(s) => 1;
+}
+```
+
+The declaration of `m` in `B` is a candidate because it's missing both the
+return type and the parameter type. Because it overrides a single method (the
+method `m` in `A`), the types from the overridden method will be used to infer
+the missing types and it will be as if the method in `B` had been declared as
+`int m(String s) => 1;`.
+
+If a candidate method overrides multiple methods, and the function type one of
+those overridden methods, M<sub>s</sub>, is a supertype of the function types of
+all of the other overridden methods, then M<sub>s</sub> is used to infer the
+missing types. For example, consider the following code:
+
+```dart
+class A {
+ int m(num n) => 0;
+}
+
+class B {
+ num m(int i) => 0;
+}
+
+class C implements A, B {
+ @override
+ m(n) => 1;
+}
+```
+
+The declaration of `m` in `C` is a candidate for override inference because it's
+missing both the return type and the parameter type. It overrides both `m` in
+`A` and `m` in `B`, so we need to choose one of them from which the missing
+types can be inferred. But because the function type of `m` in `A`
+(`int Function(num)`) is a supertype of the function type of `m` in `B`
+(`num Function(int)`), the function in `A` is used to infer the missing types.
+The result is the same as declaring the method in `C` as `int m(num n) => 1;`.
+
+It is an error if none of the overridden methods has a function type that is a
+supertype of all the other overridden methods.
+
### Potentially non-nullable
A type is _potentially non-nullable_ if it's either explicitly non-nullable or
diff --git a/tests/language/parameter/named_aggregated_test.dart b/tests/language/parameter/named_aggregated_test.dart
index 61de489f..87e6140 100644
--- a/tests/language/parameter/named_aggregated_test.dart
+++ b/tests/language/parameter/named_aggregated_test.dart
@@ -27,8 +27,6 @@
// Expect compile-time error as no default values
// are allowed in closure type.
void InstallCallback(void cb({String? msg : null})?) {
- // ^^^^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
// ^
// [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
// [cfe] Can't have a default value in a function type.
diff --git a/tests/language_2/parameter/named_aggregated_test.dart b/tests/language_2/parameter/named_aggregated_test.dart
index 82c7c8c..1b506df 100644
--- a/tests/language_2/parameter/named_aggregated_test.dart
+++ b/tests/language_2/parameter/named_aggregated_test.dart
@@ -27,8 +27,6 @@
// Expect compile-time error as no default values
// are allowed in closure type.
void InstallCallback(void cb({String msg : null})) {
- // ^^^^^^^^^^^^^^^^^
- // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
// ^
// [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
// [cfe] Can't have a default value in a function type.
diff --git a/tools/VERSION b/tools/VERSION
index 2ace34c..36662ae 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 11
PATCH 0
-PRERELEASE 162
+PRERELEASE 163
PRERELEASE_PATCH 0
\ No newline at end of file