mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[analyzer] Separate exception and evaluation errors in the const evaluator.
Some errors like type checking of fields should be reported directly, so this CL separates these errors from evaluation exception errors. This reverts some changes we have before. Additionally, we move error reporting for the constructors to an outer-most method to avoid reporting multiple times. Change-Id: Ie2fde0ea7d389a633051cb106012a0738354f821 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319911 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
parent
ef4984566b
commit
8c2f088481
|
@ -242,24 +242,28 @@ class ConstantVerifier extends RecursiveAstVisitor<void> {
|
|||
_checkForConstWithTypeParameters(
|
||||
namedType, CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS);
|
||||
|
||||
node.argumentList.accept(this);
|
||||
|
||||
// We need to evaluate the constant to see if any errors occur during its
|
||||
// evaluation.
|
||||
var constructor = node.constructorName.staticElement;
|
||||
if (constructor != null) {
|
||||
ConstantVisitor constantVisitor =
|
||||
ConstantVisitor(_evaluationEngine, _currentLibrary, _errorReporter);
|
||||
_evaluationEngine.evaluateConstructorCall(
|
||||
_currentLibrary,
|
||||
node,
|
||||
constructor.returnType.typeArguments,
|
||||
node.argumentList.arguments,
|
||||
constructor,
|
||||
constantVisitor,
|
||||
_errorReporter);
|
||||
final result =
|
||||
_evaluationEngine.evaluateAndReportErrorsInConstructorCall(
|
||||
_currentLibrary,
|
||||
node,
|
||||
constructor.returnType.typeArguments,
|
||||
node.argumentList.arguments,
|
||||
constructor,
|
||||
constantVisitor,
|
||||
_errorReporter);
|
||||
if (result is! InvalidConstant) {
|
||||
// Check for further errors in individual arguments.
|
||||
node.argumentList.accept(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
node.argumentList.accept(this);
|
||||
super.visitInstanceCreationExpression(node);
|
||||
}
|
||||
}
|
||||
|
@ -579,6 +583,8 @@ class ConstantVerifier extends RecursiveAstVisitor<void> {
|
|||
dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT) ||
|
||||
identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) ||
|
||||
identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM) ||
|
||||
identical(
|
||||
dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_STRING) ||
|
||||
identical(dataErrorCode,
|
||||
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT) ||
|
||||
identical(dataErrorCode,
|
||||
|
|
|
@ -195,7 +195,7 @@ class ConstantEvaluationEngine {
|
|||
);
|
||||
ConstantVisitor constantVisitor =
|
||||
ConstantVisitor(this, library, errorReporter);
|
||||
final result = evaluateConstructorCall(
|
||||
final result = evaluateAndReportErrorsInConstructorCall(
|
||||
library,
|
||||
constNode,
|
||||
element.returnType.typeArguments,
|
||||
|
@ -342,6 +342,63 @@ class ConstantEvaluationEngine {
|
|||
}
|
||||
}
|
||||
|
||||
/// Evaluate the constructor call and report any [InvalidConstants] if found.
|
||||
Constant evaluateAndReportErrorsInConstructorCall(
|
||||
LibraryElementImpl library,
|
||||
AstNode node,
|
||||
List<DartType>? typeArguments,
|
||||
List<Expression> arguments,
|
||||
ConstructorElement constructor,
|
||||
ConstantVisitor constantVisitor,
|
||||
ErrorReporter errorReporter, {
|
||||
ConstructorInvocation? invocation,
|
||||
}) {
|
||||
var result = _InstanceCreationEvaluator.evaluate(
|
||||
this,
|
||||
_declaredVariables,
|
||||
errorReporter,
|
||||
library,
|
||||
node,
|
||||
constructor,
|
||||
typeArguments,
|
||||
arguments,
|
||||
constantVisitor,
|
||||
isNullSafe: _isNonNullableByDefault,
|
||||
invocation: invocation,
|
||||
);
|
||||
if (result is! InvalidConstant) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// If we found an evaluation exception, report a context message linking to
|
||||
// where the exception was found.
|
||||
if (result.isRuntimeException) {
|
||||
final formattedMessage =
|
||||
formatList(result.errorCode.problemMessage, result.arguments);
|
||||
final contextMessage = DiagnosticMessageImpl(
|
||||
filePath: library.source.fullName,
|
||||
length: result.entity.length,
|
||||
message: "The exception is '$formattedMessage' and occurs here.",
|
||||
offset: result.entity.offset,
|
||||
url: null,
|
||||
);
|
||||
final errorNode = configuration.errorNode(node);
|
||||
result = InvalidConstant(
|
||||
errorNode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
arguments: [],
|
||||
contextMessages: [...result.contextMessages, contextMessage]);
|
||||
}
|
||||
|
||||
errorReporter.reportErrorForOffset(
|
||||
result.errorCode,
|
||||
result.entity.offset,
|
||||
result.entity.length,
|
||||
result.arguments,
|
||||
result.contextMessages,
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
Constant evaluateConstructorCall(
|
||||
LibraryElementImpl library,
|
||||
AstNode node,
|
||||
|
@ -665,7 +722,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
|
||||
// error code.
|
||||
_error(node, null);
|
||||
return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
return InvalidConstant.genericError(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -846,7 +903,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
|
||||
// error code.
|
||||
_error(node, null);
|
||||
return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
return InvalidConstant.genericError(node);
|
||||
}
|
||||
var constructor = node.constructorName.staticElement;
|
||||
if (constructor == null) {
|
||||
|
@ -856,7 +913,9 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
}
|
||||
|
||||
return evaluationEngine.evaluateConstructorCall(
|
||||
// TODO(kallentu): Avoid reporting errors in this visitor.
|
||||
// Use [evaluationEngine.evaluateConstructorCall].
|
||||
return evaluationEngine.evaluateAndReportErrorsInConstructorCall(
|
||||
_library,
|
||||
node,
|
||||
constructor.returnType.typeArguments,
|
||||
|
@ -1032,11 +1091,11 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
}
|
||||
|
||||
@override
|
||||
Constant? visitNode(AstNode node) {
|
||||
Constant visitNode(AstNode node) {
|
||||
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
|
||||
// error code.
|
||||
_error(node, null);
|
||||
return null;
|
||||
return InvalidConstant.genericError(node);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1107,7 +1166,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
|
||||
// error code.
|
||||
_error(node, null);
|
||||
return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
return InvalidConstant.genericError(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1498,6 +1557,9 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
|
||||
/// Create an error associated with the given [node]. The error will have the
|
||||
/// given error [code].
|
||||
///
|
||||
/// TODO(kallentu): Remove once we remove the intermediary reporting in the
|
||||
/// ConstantVisitor.
|
||||
void _error(AstNode node, ErrorCode? code) {
|
||||
if (code == null) {
|
||||
var parent = node.parent;
|
||||
|
@ -1586,7 +1648,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
false)) {
|
||||
// TODO(kallentu): Don't report error here.
|
||||
_error(expression, null);
|
||||
return InvalidConstant(expression, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
return InvalidConstant.genericError(expression);
|
||||
}
|
||||
|
||||
if (variableElement is VariableElementImpl) {
|
||||
|
@ -1604,9 +1666,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
// the evaluation upstream.
|
||||
if (result == null) {
|
||||
_error(errorNode2, null);
|
||||
return InvalidConstant(
|
||||
errorNode, CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
isUnresolved: true);
|
||||
return InvalidConstant.genericError(errorNode, isUnresolved: true);
|
||||
}
|
||||
|
||||
final value = result.value;
|
||||
|
@ -1702,14 +1762,13 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
// TODO(kallentu): This error reporting retains the same behaviour as
|
||||
// before. Move this error reporting elsewhere.
|
||||
_error(errorNode2, null);
|
||||
return InvalidConstant(errorNode, CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
isUnresolved: true);
|
||||
return InvalidConstant.genericError(errorNode, isUnresolved: true);
|
||||
}
|
||||
|
||||
// TODO(https://github.com/dart-lang/sdk/issues/47061): Use a specific
|
||||
// error code.
|
||||
_error(errorNode2, null);
|
||||
return InvalidConstant(errorNode2, CompileTimeErrorCode.INVALID_CONSTANT);
|
||||
return InvalidConstant.genericError(errorNode2);
|
||||
}
|
||||
|
||||
InvalidConstant? _getDeferredLibraryError(
|
||||
|
@ -1767,7 +1826,7 @@ class ConstantVisitor extends UnifyingAstVisitor<Constant> {
|
|||
errorTarget.offset,
|
||||
errorTarget.length,
|
||||
);
|
||||
return InvalidConstant(node, errorCode);
|
||||
return InvalidConstant(errorTarget, errorCode);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -2010,7 +2069,11 @@ class DartObjectComputer {
|
|||
} on EvaluationException catch (exception) {
|
||||
// TODO(kallentu): Don't report error here.
|
||||
_errorReporter.reportErrorForNode(exception.errorCode, node);
|
||||
return InvalidConstant(node, exception.errorCode);
|
||||
return InvalidConstant(
|
||||
node,
|
||||
exception.errorCode,
|
||||
isRuntimeException: exception.isRuntimeException,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2604,11 +2667,14 @@ class _InstanceCreationEvaluator {
|
|||
continue;
|
||||
}
|
||||
// Match the value and the type.
|
||||
var fieldType = FieldMember.from(field, _constructor.returnType).type;
|
||||
final fieldType = FieldMember.from(field, _constructor.returnType).type;
|
||||
if (!typeSystem.runtimeTypeMatch(fieldValue, fieldType)) {
|
||||
return InvalidConstant(_errorNode,
|
||||
final isRuntimeException = hasTypeParameterReference(field.type);
|
||||
final errorNode = field.constantInitializer ?? _errorNode;
|
||||
return InvalidConstant(errorNode,
|
||||
CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
|
||||
arguments: [fieldValue.type, field.name, fieldType]);
|
||||
arguments: [fieldValue.type, field.name, fieldType],
|
||||
isRuntimeException: isRuntimeException);
|
||||
}
|
||||
_fieldMap[field.name] = fieldValue;
|
||||
}
|
||||
|
@ -2677,7 +2743,7 @@ class _InstanceCreationEvaluator {
|
|||
final fieldName = initializer.fieldName.name;
|
||||
if (_fieldMap.containsKey(fieldName)) {
|
||||
return _InitializersEvaluationResult(
|
||||
InvalidConstant(initializerExpression,
|
||||
InvalidConstant(_errorNode,
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION),
|
||||
evaluationIsComplete: true);
|
||||
}
|
||||
|
@ -2686,19 +2752,43 @@ class _InstanceCreationEvaluator {
|
|||
if (getter != null) {
|
||||
final field = getter.variable;
|
||||
if (!typeSystem.runtimeTypeMatch(evaluationResult, field.type)) {
|
||||
// Mark the type mismatch error as a runtime exception if the
|
||||
// initializer is statically assignable to the field.
|
||||
// TODO(kallentu): https://github.com/dart-lang/sdk/issues/53263
|
||||
final isRuntimeException = _library.typeSystem.isAssignableTo(
|
||||
initializerExpression.typeOrThrow, field.type);
|
||||
final errorNode =
|
||||
isRuntimeException ? initializerExpression : _errorNode;
|
||||
return _InitializersEvaluationResult(
|
||||
InvalidConstant(
|
||||
initializerExpression,
|
||||
errorNode,
|
||||
CompileTimeErrorCode
|
||||
.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
|
||||
arguments: [
|
||||
evaluationResult.type,
|
||||
fieldName,
|
||||
field.type
|
||||
]),
|
||||
],
|
||||
isRuntimeException: isRuntimeException),
|
||||
evaluationIsComplete: true);
|
||||
}
|
||||
}
|
||||
case InvalidConstant(isRuntimeException: false):
|
||||
// Add additional information to the error in the field initializer
|
||||
// because the error is reported at the location of [_errorNode].
|
||||
if (evaluationResult.contextMessages.isEmpty) {
|
||||
evaluationResult.contextMessages.add(DiagnosticMessageImpl(
|
||||
filePath: _constructor.source.fullName,
|
||||
length: evaluationResult.entity.length,
|
||||
message: "The error is in the field initializer of "
|
||||
"'${_constructor.displayName}', and occurs here.",
|
||||
offset: evaluationResult.entity.offset,
|
||||
url: null,
|
||||
));
|
||||
}
|
||||
return _InitializersEvaluationResult(
|
||||
InvalidConstant.forEntity(evaluationResult, _errorNode),
|
||||
evaluationIsComplete: true);
|
||||
case InvalidConstant():
|
||||
return _InitializersEvaluationResult(evaluationResult,
|
||||
evaluationIsComplete: true);
|
||||
|
@ -2731,18 +2821,35 @@ class _InstanceCreationEvaluator {
|
|||
}
|
||||
} else if (initializer is AssertInitializer) {
|
||||
final condition = initializer.condition;
|
||||
final evaluationConstant = _initializerVisitor._getConstant(condition);
|
||||
switch (evaluationConstant) {
|
||||
final evaluationResult = _initializerVisitor._getConstant(condition);
|
||||
switch (evaluationResult) {
|
||||
case DartObjectImpl():
|
||||
if (!evaluationConstant.isBool ||
|
||||
evaluationConstant.toBoolValue() == false) {
|
||||
if (!evaluationResult.isBool ||
|
||||
evaluationResult.toBoolValue() == false) {
|
||||
return _InitializersEvaluationResult(
|
||||
InvalidConstant(initializer,
|
||||
CompileTimeErrorCode.CONST_EVAL_ASSERTION_FAILURE),
|
||||
CompileTimeErrorCode.CONST_EVAL_ASSERTION_FAILURE,
|
||||
isRuntimeException: true),
|
||||
evaluationIsComplete: true);
|
||||
}
|
||||
case InvalidConstant(isRuntimeException: false):
|
||||
// Add additional information to the error in the assert initializer
|
||||
// because the error is reported at the location of [_errorNode].
|
||||
if (evaluationResult.contextMessages.isEmpty) {
|
||||
evaluationResult.contextMessages.add(DiagnosticMessageImpl(
|
||||
filePath: _constructor.source.fullName,
|
||||
length: evaluationResult.entity.length,
|
||||
message: "The error is in the assert initializer of "
|
||||
"'${_constructor.displayName}', and occurs here.",
|
||||
offset: evaluationResult.entity.offset,
|
||||
url: null,
|
||||
));
|
||||
}
|
||||
return _InitializersEvaluationResult(
|
||||
InvalidConstant.forEntity(evaluationResult, _errorNode),
|
||||
evaluationIsComplete: true);
|
||||
case InvalidConstant():
|
||||
return _InitializersEvaluationResult(evaluationConstant,
|
||||
return _InitializersEvaluationResult(evaluationResult,
|
||||
evaluationIsComplete: true);
|
||||
}
|
||||
}
|
||||
|
@ -2798,9 +2905,16 @@ class _InstanceCreationEvaluator {
|
|||
if (argumentValue != null) {
|
||||
if (!argumentValue.isInvalid &&
|
||||
!typeSystem.runtimeTypeMatch(argumentValue, parameter.type)) {
|
||||
// Mark the type mismatch error as a runtime exception if the argument
|
||||
// is statically assignable to the parameter.
|
||||
// TODO(kallentu): https://github.com/dart-lang/sdk/issues/53263
|
||||
final isEvaluationException = errorTarget is Expression &&
|
||||
_library.typeSystem
|
||||
.isAssignableTo(errorTarget.typeOrThrow, parameter.type);
|
||||
return InvalidConstant(errorTarget,
|
||||
CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
|
||||
arguments: [argumentValue.type, parameter.type]);
|
||||
arguments: [argumentValue.type, parameter.type],
|
||||
isRuntimeException: isEvaluationException);
|
||||
}
|
||||
if (baseParameter.isInitializingFormal) {
|
||||
final field = (parameter as FieldFormalParameterElement).field;
|
||||
|
@ -2869,17 +2983,27 @@ class _InstanceCreationEvaluator {
|
|||
switch (evaluationResult) {
|
||||
case DartObjectImpl():
|
||||
_fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult;
|
||||
case InvalidConstant(isRuntimeException: false):
|
||||
// Add additional information to the error in the super constructor
|
||||
// call because the error is reported at the location of
|
||||
// [_errorNode].
|
||||
if (evaluationResult.contextMessages.isEmpty) {
|
||||
evaluationResult.contextMessages.add(DiagnosticMessageImpl(
|
||||
filePath: _constructor.source.fullName,
|
||||
length: evaluationResult.entity.length,
|
||||
message: "The error is in the super constructor invocation "
|
||||
"of '${_constructor.displayName}', and occurs here.",
|
||||
offset: evaluationResult.entity.offset,
|
||||
url: null,
|
||||
));
|
||||
} else {
|
||||
evaluationResult.contextMessages.add(
|
||||
_stackTraceContextMessage(superConstructor, _constructor));
|
||||
}
|
||||
return InvalidConstant.forEntity(evaluationResult, _errorNode);
|
||||
case InvalidConstant():
|
||||
evaluationResult.contextMessages.add(DiagnosticMessageImpl(
|
||||
filePath: _constructor.source.fullName,
|
||||
length: _constructor.nameLength,
|
||||
message:
|
||||
"The evaluated constructor '${superConstructor.displayName}' "
|
||||
"is called by '${_constructor.displayName}' and "
|
||||
"'${_constructor.displayName}' is defined here.",
|
||||
offset: _constructor.nameOffset,
|
||||
url: null,
|
||||
));
|
||||
evaluationResult.contextMessages
|
||||
.add(_stackTraceContextMessage(superConstructor, _constructor));
|
||||
return evaluationResult;
|
||||
}
|
||||
}
|
||||
|
@ -2928,6 +3052,21 @@ class _InstanceCreationEvaluator {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a context message that mimics a stack trace where [superConstructor] is
|
||||
/// called by [constructor]
|
||||
DiagnosticMessageImpl _stackTraceContextMessage(
|
||||
ConstructorElement superConstructor, ConstructorElement constructor) {
|
||||
return DiagnosticMessageImpl(
|
||||
filePath: constructor.source.fullName,
|
||||
length: constructor.nameLength,
|
||||
message: "The evaluated constructor '${superConstructor.displayName}' "
|
||||
"is called by '${constructor.displayName}' and "
|
||||
"'${constructor.displayName}' is defined here.",
|
||||
offset: constructor.nameOffset,
|
||||
url: null,
|
||||
);
|
||||
}
|
||||
|
||||
/// Evaluates [node] as an instance creation expression using [constructor].
|
||||
static Constant evaluate(
|
||||
ConstantEvaluationEngine evaluationEngine,
|
||||
|
@ -2943,13 +3082,12 @@ class _InstanceCreationEvaluator {
|
|||
ConstructorInvocation? invocation,
|
||||
}) {
|
||||
if (!constructor.isConst) {
|
||||
// TODO(kallentu): Retain token error information in InvalidConstant.
|
||||
if (node is InstanceCreationExpression && node.keyword != null) {
|
||||
errorReporter.reportErrorForToken(
|
||||
CompileTimeErrorCode.CONST_WITH_NON_CONST, node.keyword!);
|
||||
} else {
|
||||
errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.CONST_WITH_NON_CONST, node);
|
||||
if (node is InstanceCreationExpression) {
|
||||
final newKeyword = node.keyword;
|
||||
if (newKeyword != null) {
|
||||
return InvalidConstant(
|
||||
newKeyword, CompileTimeErrorCode.CONST_WITH_NON_CONST);
|
||||
}
|
||||
}
|
||||
return InvalidConstant(node, CompileTimeErrorCode.CONST_WITH_NON_CONST);
|
||||
}
|
||||
|
@ -3007,12 +3145,11 @@ class _InstanceCreationEvaluator {
|
|||
);
|
||||
|
||||
constructor = _followConstantRedirectionChain(constructor);
|
||||
final errorNode = evaluationEngine.configuration.errorNode(node);
|
||||
final evaluator = _InstanceCreationEvaluator._(
|
||||
evaluationEngine,
|
||||
declaredVariables,
|
||||
library,
|
||||
errorNode,
|
||||
evaluationEngine.configuration.errorNode(node),
|
||||
constructor,
|
||||
typeArguments,
|
||||
namedNodes: namedNodes,
|
||||
|
@ -3021,34 +3158,15 @@ class _InstanceCreationEvaluator {
|
|||
invocation: invocation,
|
||||
);
|
||||
|
||||
Constant constant;
|
||||
if (constructor.isFactory) {
|
||||
// We couldn't find a non-factory constructor.
|
||||
// See if it's because we reached an external const factory constructor
|
||||
// that we can emulate.
|
||||
constant = evaluator.evaluateFactoryConstructorCall(arguments,
|
||||
return evaluator.evaluateFactoryConstructorCall(arguments,
|
||||
isNullSafe: isNullSafe);
|
||||
} else {
|
||||
constant = evaluator.evaluateGenerativeConstructorCall(arguments);
|
||||
return evaluator.evaluateGenerativeConstructorCall(arguments);
|
||||
}
|
||||
if (constant is InvalidConstant) {
|
||||
final formattedMessage =
|
||||
formatList(constant.errorCode.problemMessage, constant.arguments);
|
||||
final contextMessage = DiagnosticMessageImpl(
|
||||
filePath: library.source.fullName,
|
||||
length: constant.node.length,
|
||||
message: "The exception is '$formattedMessage' and occurs here.",
|
||||
offset: constant.node.offset,
|
||||
url: null,
|
||||
);
|
||||
errorReporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
errorNode,
|
||||
[],
|
||||
[...constant.contextMessages, contextMessage],
|
||||
);
|
||||
}
|
||||
return constant;
|
||||
}
|
||||
|
||||
/// Attempt to follow the chain of factory redirections until a constructor is
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'dart:collection';
|
|||
|
||||
import 'package:analyzer/dart/analysis/features.dart';
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/syntactic_entity.dart';
|
||||
import 'package:analyzer/dart/constant/value.dart';
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
|
@ -319,6 +320,7 @@ class DartObjectImpl implements DartObject, Constant {
|
|||
}
|
||||
|
||||
if (!typeSystem.isSubtypeOf(type, resultType)) {
|
||||
// TODO(kallentu): Make a more specific error for casting.
|
||||
throw EvaluationException(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
|
||||
}
|
||||
|
@ -1292,8 +1294,11 @@ class EvaluationException {
|
|||
/// The error code associated with the exception.
|
||||
final ErrorCode errorCode;
|
||||
|
||||
/// Returns `true` if the evaluation exception is a runtime exception.
|
||||
final bool isRuntimeException;
|
||||
|
||||
/// Initialize a newly created exception to have the given [errorCode].
|
||||
EvaluationException(this.errorCode);
|
||||
EvaluationException(this.errorCode, {this.isRuntimeException = false});
|
||||
}
|
||||
|
||||
/// The state of an object representing a function.
|
||||
|
@ -2112,7 +2117,8 @@ class IntState extends NumState {
|
|||
if (rightValue == null) {
|
||||
return UNKNOWN_VALUE;
|
||||
} else if (rightValue == 0) {
|
||||
throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
|
||||
throw EvaluationException(CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE,
|
||||
isRuntimeException: true);
|
||||
}
|
||||
return IntState(value! ~/ rightValue);
|
||||
} else if (rightOperand is DoubleState) {
|
||||
|
@ -2346,10 +2352,10 @@ class IntState extends NumState {
|
|||
|
||||
/// An invalid constant that contains diagnostic information.
|
||||
class InvalidConstant implements Constant {
|
||||
/// The node where we could not compute a valid constant.
|
||||
final AstNode node;
|
||||
/// The entity that a constant evaluator error is reported at.
|
||||
final SyntacticEntity entity;
|
||||
|
||||
/// The error code that is reported at the location of the [node].
|
||||
/// The error code that is reported at the location of the [entity].
|
||||
final ErrorCode errorCode;
|
||||
|
||||
/// The arguments required to complete the message.
|
||||
|
@ -2359,13 +2365,50 @@ class InvalidConstant implements Constant {
|
|||
/// information if the error occurs within a constructor.
|
||||
final List<DiagnosticMessage> contextMessages;
|
||||
|
||||
/// Return `true` if the error was an exception thrown during constant
|
||||
/// evaluation.
|
||||
///
|
||||
/// In [ConstantEvaluationEngine.evaluateAndReportErrorsInConstructorCall],
|
||||
/// we report this with a [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]
|
||||
/// and a context message pointing to where the exception was thrown.
|
||||
final bool isRuntimeException;
|
||||
|
||||
/// Return `true` if the constant evaluation encounters an unresolved
|
||||
/// expression.
|
||||
final bool isUnresolved;
|
||||
|
||||
InvalidConstant(this.node, this.errorCode,
|
||||
{this.arguments, this.isUnresolved = false})
|
||||
: contextMessages = [];
|
||||
InvalidConstant(this.entity, this.errorCode,
|
||||
{this.arguments,
|
||||
List<DiagnosticMessage>? contextMessages,
|
||||
this.isUnresolved = false,
|
||||
this.isRuntimeException = false})
|
||||
: contextMessages = contextMessages ?? [];
|
||||
|
||||
/// Creates a duplicate instance of [other], with a different [entity].
|
||||
factory InvalidConstant.forEntity(
|
||||
InvalidConstant other, SyntacticEntity entity) {
|
||||
return InvalidConstant(entity, other.errorCode,
|
||||
arguments: other.arguments,
|
||||
contextMessages: other.contextMessages,
|
||||
isUnresolved: other.isUnresolved,
|
||||
isRuntimeException: other.isRuntimeException);
|
||||
}
|
||||
|
||||
/// Returns a generic error depending on the [node] provided.
|
||||
factory InvalidConstant.genericError(AstNode node,
|
||||
{bool isUnresolved = false}) {
|
||||
final parent = node.parent;
|
||||
final parent2 = parent?.parent;
|
||||
if (parent is ArgumentList &&
|
||||
parent2 is InstanceCreationExpression &&
|
||||
parent2.isConst) {
|
||||
return InvalidConstant(
|
||||
node, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
|
||||
isUnresolved: isUnresolved);
|
||||
}
|
||||
return InvalidConstant(node, CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
isUnresolved: isUnresolved);
|
||||
}
|
||||
}
|
||||
|
||||
/// The state of an object representing a list.
|
||||
|
|
|
@ -1747,13 +1747,13 @@ class RequiresNonEmptyList {
|
|||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS,
|
||||
16,
|
||||
31,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 138, 14,
|
||||
text:
|
||||
"The exception is 'The property 'length' can't be accessed on the type 'List<int>' in a constant expression.' and occurs here."),
|
||||
"The error is in the assert initializer of 'RequiresNonEmptyList', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
|
@ -2871,13 +2871,13 @@ class B {
|
|||
const b = B('');
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
CompileTimeErrorCode.CONST_EVAL_EXTENSION_METHOD,
|
||||
128,
|
||||
5,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 105, 8,
|
||||
text:
|
||||
"The exception is 'Extension methods can't be used in constant expressions.' and occurs here."),
|
||||
"The error is in the field initializer of 'B', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
|
@ -2893,13 +2893,13 @@ class B {
|
|||
const y = B(x);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
CompileTimeErrorCode.CONST_EVAL_TYPE_STRING,
|
||||
70,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 47, 8,
|
||||
text:
|
||||
"The exception is 'In constant expressions, operands of this operator must be of type 'String'.' and occurs here."),
|
||||
"The error is in the field initializer of 'B', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 72, 1),
|
||||
|
@ -3463,15 +3463,17 @@ const a = const A<int>();
|
|||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_CONSTANT, 62, 1),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
77,
|
||||
14,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 62, 1,
|
||||
text:
|
||||
"The exception is 'Invalid constant value.' and occurs here."),
|
||||
"The error is in the field initializer of 'A', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 77,
|
||||
14),
|
||||
]);
|
||||
final result = _topLevelVar('a');
|
||||
_assertNull(result);
|
||||
|
@ -3504,6 +3506,8 @@ void main() {
|
|||
const Foo(bar: data);
|
||||
}
|
||||
''', [
|
||||
// TODO(kallentu): Fix [InvalidConstant.genericError] to handle
|
||||
// NamedExpressions.
|
||||
error(CompileTimeErrorCode.INVALID_CONSTANT, 148, 4),
|
||||
]);
|
||||
}
|
||||
|
@ -3525,6 +3529,39 @@ A<int>
|
|||
''');
|
||||
}
|
||||
|
||||
test_superInitializer_paramTypeMismatch_indirect() async {
|
||||
await assertErrorsInCode('''
|
||||
class C {
|
||||
final double d;
|
||||
const C(this.d);
|
||||
}
|
||||
class D extends C {
|
||||
const D(d) : super(d);
|
||||
}
|
||||
class E extends D {
|
||||
const E(e) : super(e);
|
||||
}
|
||||
const f = const E('0.0');
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
153,
|
||||
14,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 77, 1,
|
||||
text:
|
||||
"The evaluated constructor 'C' is called by 'D' and 'D' is defined here."),
|
||||
ExpectedContextMessage(testFile.path, 124, 1,
|
||||
text:
|
||||
"The evaluated constructor 'D' is called by 'E' and 'E' is defined here."),
|
||||
ExpectedContextMessage(testFile.path, 90, 1,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'double' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_superInitializer_typeParameter() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class A<T> {
|
||||
|
|
|
@ -6,7 +6,6 @@ import 'package:analyzer/src/error/codes.dart';
|
|||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -58,17 +57,8 @@ class A {
|
|||
main() {
|
||||
const A(42);
|
||||
}''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
44,
|
||||
11,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 52, 2,
|
||||
text:
|
||||
"The exception is 'A value of type 'int' can't be assigned to a parameter of type 'String' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 2),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 52, 2),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -114,16 +104,7 @@ enum E {
|
|||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 13, 1),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 13, 1,
|
||||
text:
|
||||
"The exception is 'A value of type 'int' can't be assigned to a parameter of type 'String' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 13, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,22 @@ var v = const C(const B());
|
|||
''');
|
||||
}
|
||||
|
||||
test_assignable_fieldFormal_typedef() async {
|
||||
// foo has the type dynamic -> dynamic, so it is not assignable to A.f.
|
||||
await assertErrorsInCode(r'''
|
||||
typedef String Int2String(int x);
|
||||
class A {
|
||||
final Int2String f;
|
||||
const A(this.f);
|
||||
}
|
||||
foo(x) => 1;
|
||||
var v = const A(foo);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 116, 3),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 116, 3),
|
||||
]);
|
||||
}
|
||||
|
||||
test_assignable_fieldFormal_typeSubstitution() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class A<T> {
|
||||
|
@ -173,6 +189,69 @@ const c = C();
|
|||
''');
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_optional() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
final int x;
|
||||
const A([this.x = 'foo']);
|
||||
}
|
||||
var v = const A();
|
||||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 45, 5),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 64, 9),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_supertype() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
class B extends A {
|
||||
const B();
|
||||
}
|
||||
class C {
|
||||
final B b;
|
||||
const C(this.b);
|
||||
}
|
||||
const A u = const A();
|
||||
var v = const C(u);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 143, 1),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 143, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_typedef() async {
|
||||
// foo has type String -> int, so it is not assignable to A.f
|
||||
// (A.f requires it to be int -> String).
|
||||
await assertErrorsInCode(r'''
|
||||
typedef String Int2String(int x);
|
||||
class A {
|
||||
final Int2String f;
|
||||
const A(this.f);
|
||||
}
|
||||
int foo(String x) => 1;
|
||||
var v = const A(foo);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 127, 3),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 127, 3),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_unrelated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
final int x;
|
||||
const A(this.x);
|
||||
}
|
||||
var v = const A('foo');
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 62, 5),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 62, 5),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_unresolved() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
|
@ -185,6 +264,30 @@ var v = const A('foo');
|
|||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_typeSubstitution() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A<T> {
|
||||
const A(T x);
|
||||
}
|
||||
var v = const A<int>('foo');
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 5),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 52, 5),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_unrelated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A(int x);
|
||||
}
|
||||
var v = const A('foo');
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 46, 5),
|
||||
]);
|
||||
}
|
||||
|
||||
test_superFormalParameter_explicit() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class A {
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2023, 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:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ConstEvalPropertyAccessTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ConstEvalPropertyAccessTest extends PubPackageResolutionTest {
|
||||
test_length_invalidTarget() async {
|
||||
await assertErrorsInCode('''
|
||||
void main() {
|
||||
const RequiresNonEmptyList([1]);
|
||||
}
|
||||
|
||||
class RequiresNonEmptyList {
|
||||
const RequiresNonEmptyList(List<int> numbers) : assert(numbers.length > 0);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_PROPERTY_ACCESS,
|
||||
16,
|
||||
31,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 138, 14,
|
||||
text:
|
||||
"The error is in the assert initializer of 'RequiresNonEmptyList', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ import '../dart/resolution/context_collection_resolution.dart';
|
|||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ConstConstructorFieldTypeMismatchContextTest);
|
||||
defineReflectiveTests(ConstConstructorParamTypeMismatchContextTest);
|
||||
defineReflectiveTests(ConstEvalThrowsExceptionTest);
|
||||
defineReflectiveTests(ConstEvalThrowsExceptionWithoutNullSafetyTest);
|
||||
});
|
||||
|
@ -38,7 +37,7 @@ var v = const C<String>();
|
|||
70,
|
||||
17,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 70, 17,
|
||||
ExpectedContextMessage(testFile.path, 27, 1,
|
||||
text:
|
||||
"The exception is 'In a const constructor, a value of type 'int' can't be assigned to the field 'x', which has type 'String'.' and occurs here."),
|
||||
],
|
||||
|
@ -114,28 +113,96 @@ const a = const C(null);
|
|||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ConstConstructorParamTypeMismatchContextTest
|
||||
extends PubPackageResolutionTest {
|
||||
test_assignable_fieldFormal_typedef() async {
|
||||
// foo has the type dynamic -> dynamic, so it is not assignable to A.f.
|
||||
await assertErrorsInCode(r'''
|
||||
typedef String Int2String(int x);
|
||||
class A {
|
||||
final Int2String f;
|
||||
const A(this.f);
|
||||
class ConstEvalThrowsExceptionTest extends PubPackageResolutionTest
|
||||
with ConstEvalThrowsExceptionTestCases {
|
||||
test_asExpression_typeParameter() async {
|
||||
await assertErrorsInCode('''
|
||||
class C<T> {
|
||||
final t;
|
||||
const C(dynamic x) : t = x as T;
|
||||
}
|
||||
|
||||
main() {
|
||||
const C<int>(0);
|
||||
const C<int>('foo');
|
||||
const C<int>(null);
|
||||
}
|
||||
foo(x) => 1;
|
||||
var v = const A(foo);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 116, 3),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
108,
|
||||
12,
|
||||
92,
|
||||
19,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 116, 3,
|
||||
ExpectedContextMessage(testFile.path, 51, 6,
|
||||
text:
|
||||
"The exception is 'A value of type 'dynamic Function(dynamic)' can't be assigned to a parameter of type 'String Function(int)' in a const constructor.' and occurs here."),
|
||||
"The error is in the field initializer of 'C', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
115,
|
||||
18,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 6,
|
||||
text:
|
||||
"The error is in the field initializer of 'C', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_asExpression_typeParameter_nested() async {
|
||||
await assertErrorsInCode('''
|
||||
class C<T> {
|
||||
final t;
|
||||
const C(dynamic x) : t = x as List<T>;
|
||||
}
|
||||
|
||||
main() {
|
||||
const C<int>(<int>[]);
|
||||
const C<int>(<num>[]);
|
||||
const C<int>(null);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
104,
|
||||
21,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 12,
|
||||
text:
|
||||
"The error is in the field initializer of 'C', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
129,
|
||||
18,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 12,
|
||||
text:
|
||||
"The error is in the field initializer of 'C', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_enum_constructor_initializer_asExpression() async {
|
||||
await assertErrorsInCode(r'''
|
||||
enum E {
|
||||
v();
|
||||
final int x;
|
||||
const E({int? x}) : x = x as int;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
3,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 57, 8,
|
||||
text:
|
||||
"The error is in the field initializer of 'E', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
|
@ -185,318 +252,6 @@ enum E {
|
|||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_optional() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
final int x;
|
||||
const A([this.x = 'foo']);
|
||||
}
|
||||
var v = const A();
|
||||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_ASSIGNMENT, 45, 5),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
64,
|
||||
9,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 64, 9,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'int' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_supertype() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A();
|
||||
}
|
||||
class B extends A {
|
||||
const B();
|
||||
}
|
||||
class C {
|
||||
final B b;
|
||||
const C(this.b);
|
||||
}
|
||||
const A u = const A();
|
||||
var v = const C(u);
|
||||
''', [
|
||||
// TODO(srawlins): It would be best to report only the first one.
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
135,
|
||||
10,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 143, 1,
|
||||
text:
|
||||
"The exception is 'A value of type 'A' can't be assigned to a parameter of type 'B' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 143, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_typedef() async {
|
||||
// foo has type String -> int, so it is not assignable to A.f
|
||||
// (A.f requires it to be int -> String).
|
||||
await assertErrorsInCode(r'''
|
||||
typedef String Int2String(int x);
|
||||
class A {
|
||||
final Int2String f;
|
||||
const A(this.f);
|
||||
}
|
||||
int foo(String x) => 1;
|
||||
var v = const A(foo);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 127, 3),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
119,
|
||||
12,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 127, 3,
|
||||
text:
|
||||
"The exception is 'A value of type 'int Function(String)' can't be assigned to a parameter of type 'String Function(int)' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_fieldFormal_unrelated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
final int x;
|
||||
const A(this.x);
|
||||
}
|
||||
var v = const A('foo');
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
54,
|
||||
14,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 62, 5,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'int' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 62, 5),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_typeSubstitution() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A<T> {
|
||||
const A(T x);
|
||||
}
|
||||
var v = const A<int>('foo');
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 5),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
39,
|
||||
19,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 52, 5,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'int' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_notAssignable_unrelated() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
const A(int x);
|
||||
}
|
||||
var v = const A('foo');
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
38,
|
||||
14,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 46, 5,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'int' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ConstEvalThrowsExceptionTest extends PubPackageResolutionTest
|
||||
with ConstEvalThrowsExceptionTestCases {
|
||||
test_asExpression_typeParameter() async {
|
||||
await assertErrorsInCode('''
|
||||
class C<T> {
|
||||
final t;
|
||||
const C(dynamic x) : t = x as T;
|
||||
}
|
||||
|
||||
main() {
|
||||
const C<int>(0);
|
||||
const C<int>('foo');
|
||||
const C<int>(null);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
92,
|
||||
19,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 6,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
115,
|
||||
18,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 6,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_asExpression_typeParameter_nested() async {
|
||||
await assertErrorsInCode('''
|
||||
class C<T> {
|
||||
final t;
|
||||
const C(dynamic x) : t = x as List<T>;
|
||||
}
|
||||
|
||||
main() {
|
||||
const C<int>(<int>[]);
|
||||
const C<int>(<num>[]);
|
||||
const C<int>(null);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
104,
|
||||
21,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 12,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
129,
|
||||
18,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 12,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_enum_constructor_initializer_asExpression() async {
|
||||
await assertErrorsInCode(r'''
|
||||
enum E {
|
||||
v();
|
||||
final int x;
|
||||
const E({int? x}) : x = x as int;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
3,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 57, 8,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_invalid_constructorFieldInitializer_fromSeparateLibrary() async {
|
||||
newFile('$testPackageLibPath/lib.dart', r'''
|
||||
class A<T> {
|
||||
final int f;
|
||||
const A() : f = T.foo;
|
||||
}
|
||||
''');
|
||||
await assertErrorsInCode(r'''
|
||||
import 'lib.dart';
|
||||
const a = const A();
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
29,
|
||||
9,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 46, 5,
|
||||
text:
|
||||
"The exception is 'Invalid constant value.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_property_length_invalidTarget() async {
|
||||
await assertErrorsInCode('''
|
||||
void main() {
|
||||
const RequiresNonEmptyList([1]);
|
||||
}
|
||||
|
||||
class RequiresNonEmptyList {
|
||||
const RequiresNonEmptyList(List<int> numbers) : assert(numbers.length > 0);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
16,
|
||||
31,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 138, 14,
|
||||
text:
|
||||
"The exception is 'The property 'length' can't be accessed on the type 'List<int>' in a constant expression.' and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
test_property_length_unresolvedType() async {
|
||||
await assertErrorsInCode('''
|
||||
class B {
|
||||
final l;
|
||||
const B(String o) : l = o.length;
|
||||
}
|
||||
|
||||
const y = B(x);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
70,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 47, 8,
|
||||
text:
|
||||
"The exception is 'In constant expressions, operands of this operator must be of type 'String'.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 72, 1),
|
||||
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 72, 1),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 72,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_redirectingConstructor_paramTypeMismatch() async {
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
|
@ -703,16 +458,7 @@ var x = const C();
|
|||
CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
|
||||
39,
|
||||
1),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
56,
|
||||
9,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 43, 1,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 56, 9),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -733,16 +479,7 @@ var x = const C(2);
|
|||
CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
|
||||
40,
|
||||
1),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
54,
|
||||
10,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 54, 10,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 54, 10),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -764,27 +501,9 @@ main() {
|
|||
var b1 = const bool.fromEnvironment(1);
|
||||
var b2 = const bool.fromEnvironment('x', defaultValue: 1);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
9,
|
||||
29,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 9, 29,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 9, 29),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
49,
|
||||
48,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 49, 48,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 49, 48),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 95, 1),
|
||||
]);
|
||||
}
|
||||
|
@ -796,16 +515,7 @@ var b2 = const bool.fromEnvironment('x', defaultValue: 1);
|
|||
await assertErrorsInCode('''
|
||||
var b = const bool.fromEnvironment('x', defaultValue: 1);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
8,
|
||||
48,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 8, 48,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 8, 48),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 54, 1),
|
||||
]);
|
||||
}
|
||||
|
@ -828,32 +538,14 @@ const c = [if (0 < 1) 3 else nil + 1];
|
|||
await assertErrorsInCode(r'''
|
||||
var s2 = const Symbol(3);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
9,
|
||||
15,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 9, 15,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 9, 15),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 22, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_symbolConstructor_string_digit() async {
|
||||
var expectedErrors = expectedErrorsByNullability(nullable: [], legacy: [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
8,
|
||||
17,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 8, 17,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 8, 17),
|
||||
]);
|
||||
await assertErrorsInCode(r'''
|
||||
var s = const Symbol('3');
|
||||
|
@ -862,16 +554,7 @@ var s = const Symbol('3');
|
|||
|
||||
test_symbolConstructor_string_underscore() async {
|
||||
var expectedErrors = expectedErrorsByNullability(nullable: [], legacy: [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
8,
|
||||
17,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 8, 17,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 8, 17),
|
||||
]);
|
||||
await assertErrorsInCode(r'''
|
||||
var s = const Symbol('_');
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2023, 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:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(ConstEvalTypeStringTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class ConstEvalTypeStringTest extends PubPackageResolutionTest {
|
||||
test_length_unresolvedType() async {
|
||||
await assertErrorsInCode('''
|
||||
class B {
|
||||
final l;
|
||||
const B(String o) : l = o.length;
|
||||
}
|
||||
|
||||
const y = B(x);
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_TYPE_STRING,
|
||||
70,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 47, 8,
|
||||
text:
|
||||
"The error is in the field initializer of 'B', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.UNDEFINED_IDENTIFIER, 72, 1),
|
||||
error(CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT, 72, 1),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 72,
|
||||
1),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -33,16 +32,7 @@ enum E {
|
|||
const E() : x = '';
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
1,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 47, 2,
|
||||
text:
|
||||
"The exception is 'In a const constructor, a value of type 'String' can't be assigned to the field 'x', which has type 'int'.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 11, 1),
|
||||
error(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, 47, 2),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -85,16 +84,7 @@ enum E {
|
|||
const E() : x = 0, x = 1;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
1,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 54, 1,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 11, 1),
|
||||
error(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, 50,
|
||||
1),
|
||||
]);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -39,16 +38,7 @@ enum E {
|
|||
const E() : x = 1;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
1,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 51, 1,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 11, 1),
|
||||
error(
|
||||
CompileTimeErrorCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
|
||||
47,
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -37,16 +36,7 @@ enum E {
|
|||
const E(this.x) : x = 1;
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 56, 1,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 11, 4),
|
||||
error(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
|
||||
52, 1),
|
||||
]);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -62,16 +61,7 @@ enum E {
|
|||
const E(String this.x);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
5,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 13, 2,
|
||||
text:
|
||||
"The exception is 'A value of type 'String' can't be assigned to a parameter of type 'int' in a const constructor.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 13, 2),
|
||||
error(CompileTimeErrorCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, 43,
|
||||
13),
|
||||
]);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../generated/test_support.dart';
|
||||
import '../dart/resolution/context_collection_resolution.dart';
|
||||
|
||||
main() {
|
||||
|
@ -39,16 +38,7 @@ enum E {
|
|||
const E(this.x);
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
11,
|
||||
4,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 11, 4,
|
||||
text:
|
||||
"The exception is 'Evaluation of this constant expression throws an exception.' and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 11, 4),
|
||||
error(
|
||||
CompileTimeErrorCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
|
||||
47,
|
||||
|
|
|
@ -49,6 +49,33 @@ class A {
|
|||
]);
|
||||
}
|
||||
|
||||
test_constructorFieldInitializer_fromSeparateLibrary() async {
|
||||
newFile('$testPackageLibPath/lib.dart', r'''
|
||||
class A<T> {
|
||||
final int f;
|
||||
const A() : f = T.foo;
|
||||
}
|
||||
''');
|
||||
await assertErrorsInCode(r'''
|
||||
import 'lib.dart';
|
||||
const a = const A();
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
29,
|
||||
9,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(
|
||||
convertPath('$testPackageLibPath/lib.dart'), 46, 5,
|
||||
text:
|
||||
"The error is in the field initializer of 'A', and occurs here."),
|
||||
],
|
||||
),
|
||||
error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 29,
|
||||
9),
|
||||
]);
|
||||
}
|
||||
|
||||
test_in_initializer_field_as() async {
|
||||
await assertNoErrorsInCode('''
|
||||
class C<T> {
|
||||
|
@ -178,8 +205,6 @@ class B extends A {
|
|||
}
|
||||
|
||||
test_in_initializer_instanceCreation() async {
|
||||
// TODO(scheglov): the error CONST_EVAL_THROWS_EXCEPTION is redundant and
|
||||
// ought to be suppressed. Or not?
|
||||
await assertErrorsInCode(r'''
|
||||
class A {
|
||||
A();
|
||||
|
@ -192,13 +217,13 @@ var b = const B();
|
|||
''', [
|
||||
error(CompileTimeErrorCode.INVALID_CONSTANT, 47, 7),
|
||||
error(
|
||||
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
|
||||
CompileTimeErrorCode.INVALID_CONSTANT,
|
||||
77,
|
||||
9,
|
||||
contextMessages: [
|
||||
ExpectedContextMessage(testFile.path, 47, 7,
|
||||
text:
|
||||
"The exception is 'Invalid constant value.' and occurs here."),
|
||||
"The error is in the field initializer of 'B', and occurs here."),
|
||||
],
|
||||
),
|
||||
]);
|
||||
|
|
|
@ -108,6 +108,7 @@ import 'const_deferred_class_test.dart' as const_deferred_class;
|
|||
import 'const_eval_extension_method_test.dart' as const_eval_extension_method;
|
||||
import 'const_eval_for_element_test.dart' as const_eval_for_element;
|
||||
import 'const_eval_method_invocation_test.dart' as const_eval_method_invocation;
|
||||
import 'const_eval_property_access_test.dart' as const_eval_property_access;
|
||||
import 'const_eval_throws_exception_test.dart' as const_eval_throws_exception;
|
||||
import 'const_eval_throws_idbze_test.dart' as const_eval_throws_idbze;
|
||||
import 'const_eval_type_bool_int_test.dart' as const_eval_type_bool_int;
|
||||
|
@ -115,6 +116,7 @@ import 'const_eval_type_bool_num_string_test.dart'
|
|||
as const_eval_type_bool_num_string;
|
||||
import 'const_eval_type_bool_test.dart' as const_eval_type_bool;
|
||||
import 'const_eval_type_num_test.dart' as const_eval_type_num;
|
||||
import 'const_eval_type_string_test.dart' as const_eval_type_string;
|
||||
import 'const_field_initializer_not_assignable_test.dart'
|
||||
as const_field_initializer_not_assignable;
|
||||
import 'const_initialized_with_non_constant_value_from_deferred_library_test.dart'
|
||||
|
@ -963,12 +965,14 @@ main() {
|
|||
const_eval_extension_method.main();
|
||||
const_eval_for_element.main();
|
||||
const_eval_method_invocation.main();
|
||||
const_eval_property_access.main();
|
||||
const_eval_throws_exception.main();
|
||||
const_eval_throws_idbze.main();
|
||||
const_eval_type_bool_int.main();
|
||||
const_eval_type_bool_num_string.main();
|
||||
const_eval_type_bool.main();
|
||||
const_eval_type_num.main();
|
||||
const_eval_type_string.main();
|
||||
const_field_initializer_not_assignable.main();
|
||||
const_initialized_with_non_constant_value_from_deferred_library.main();
|
||||
const_initialized_with_non_constant_value.main();
|
||||
|
|
|
@ -34,7 +34,9 @@ class DocumentationValidator {
|
|||
'CompileTimeErrorCode.AMBIGUOUS_IMPORT',
|
||||
// Produces two diagnostics when it should only produce one.
|
||||
'CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE',
|
||||
// TODO(kallentu) Now reports CONST_EVAL_THROWS_EXCEPTION instead.
|
||||
// TODO(kallentu) This is always reported with
|
||||
// `ARGUMENT_TYPE_NOT_ASSIGNABLE` or is reported as
|
||||
// `CONST_EVAL_THROWS_EXCEPTION` in const constructor evaluation.
|
||||
'CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH',
|
||||
// Produces two diagnostics when it should only produce one.
|
||||
'CompileTimeErrorCode.CONST_DEFERRED_CLASS',
|
||||
|
|
|
@ -27,27 +27,25 @@ class A {
|
|||
|
||||
const a1 = const A.a1();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
const a2 = const A.a2('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
const a3 = const A.a3();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
const a4 = const A.a4('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
const a5 = const A.a5('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
const a6 = const A.a6('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
|
||||
main() {
|
||||
|
|
|
@ -27,27 +27,25 @@ class A {
|
|||
|
||||
var a1 = const A.a1();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
var a2 = const A.a2('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
var a3 = const A.a3();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
var a4 = const A.a4('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
var a5 = const A.a5('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
var a6 = const A.a6('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
|
||||
main() {
|
||||
|
|
|
@ -14,10 +14,9 @@ class D extends C {
|
|||
const intValue = 0;
|
||||
const c = const C(0.0);
|
||||
const d = const C(intValue);
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'int' can't be assigned to the parameter type 'double'.
|
||||
const e = const D(0.0);
|
||||
const f = const D(intValue);
|
||||
|
|
|
@ -13,7 +13,6 @@ class B {
|
|||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
// [cfe] Constant evaluation error:
|
||||
// ^
|
||||
// [cfe] Constant expression expected.
|
||||
;
|
||||
}
|
||||
|
@ -21,5 +20,5 @@ class B {
|
|||
void main() {
|
||||
const B("");
|
||||
//^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ main() {
|
|||
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
var c3 = const C3();
|
||||
// ^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
||||
abstract class I0 {
|
||||
|
|
|
@ -23,5 +23,5 @@ class ConstCounter {
|
|||
main() {
|
||||
const ConstCounter(3);
|
||||
//^^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
|
|
@ -16,10 +16,9 @@ class A {
|
|||
int foo(String x) => 499;
|
||||
|
||||
const a = const A(foo);
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'int Function(String)' can't be assigned to the parameter type 'String Function(int)'.
|
||||
|
||||
main() {
|
||||
|
|
|
@ -29,27 +29,25 @@ class A {
|
|||
|
||||
const a1 = const A.a1();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
const a2 = const A.a2('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
const a3 = const A.a3();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
const a4 = const A.a4('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
const a5 = const A.a5('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
const a6 = const A.a6('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
|
||||
main() {
|
||||
|
|
|
@ -29,27 +29,25 @@ class A {
|
|||
|
||||
var a1 = const A.a1();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
var a2 = const A.a2('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
var a3 = const A.a3();
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
var a4 = const A.a4('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
var a5 = const A.a5('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
|
||||
var a6 = const A.a6('foo');
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
|
||||
|
||||
main() {
|
||||
|
|
|
@ -16,10 +16,9 @@ class D extends C {
|
|||
const intValue = 0;
|
||||
const c = const C(0.0);
|
||||
const d = const C(intValue);
|
||||
// ^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'int' can't be assigned to the parameter type 'double'.
|
||||
const e = const D(0.0);
|
||||
const f = const D(intValue);
|
||||
|
|
|
@ -15,7 +15,6 @@ class B {
|
|||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
// [cfe] Constant evaluation error:
|
||||
// ^
|
||||
// [cfe] Constant expression expected.
|
||||
;
|
||||
}
|
||||
|
@ -23,5 +22,5 @@ class B {
|
|||
void main() {
|
||||
const B("");
|
||||
//^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ main() {
|
|||
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
var c3 = const C3();
|
||||
// ^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
||||
abstract class I0 {
|
||||
|
|
|
@ -25,5 +25,5 @@ class ConstCounter {
|
|||
main() {
|
||||
const ConstCounter(3);
|
||||
//^^^^^^^^^^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT
|
||||
}
|
||||
|
|
|
@ -18,10 +18,9 @@ class A {
|
|||
int foo(String x) => 499;
|
||||
|
||||
const a = const A(foo);
|
||||
// ^^^^^^^^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.ARGUMENT_TYPE_NOT_ASSIGNABLE
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
|
||||
// [cfe] The argument type 'int Function(String)' can't be assigned to the parameter type 'String Function(int)'.
|
||||
|
||||
main() {
|
||||
|
|
Loading…
Reference in a new issue