From 8c2f088481e90949dc04f532af8600b23138ff63 Mon Sep 17 00:00:00 2001 From: Kallen Tu Date: Tue, 22 Aug 2023 18:21:10 +0000 Subject: [PATCH] [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 Commit-Queue: Kallen Tu --- .../src/dart/constant/constant_verifier.dart | 26 +- .../lib/src/dart/constant/evaluation.dart | 256 ++++++--- pkg/analyzer/lib/src/dart/constant/value.dart | 59 +- .../src/dart/constant/evaluation_test.dart | 53 +- .../argument_type_not_assignable_test.dart | 23 +- ..._constructor_param_type_mismatch_test.dart | 103 ++++ .../const_eval_property_access_test.dart | 41 ++ .../const_eval_throws_exception_test.dart | 503 ++++-------------- .../const_eval_type_string_test.dart | 44 ++ ...field_initializer_not_assignable_test.dart | 12 +- ...ialized_by_multiple_initializers_test.dart | 12 +- ...d_in_initializer_and_declaration_test.dart | 12 +- ...zed_in_parameter_and_initializer_test.dart | 12 +- ...itializing_formal_not_assignable_test.dart | 12 +- ...d_in_declaration_and_constructor_test.dart | 12 +- .../diagnostics/invalid_constant_test.dart | 33 +- .../test/src/diagnostics/test_all.dart | 4 + .../test/verify_diagnostics_test.dart | 4 +- .../compile_time_constant/static2_test.dart | 16 +- .../compile_time_constant/static3_test.dart | 16 +- tests/language/const/constructor3_test.dart | 3 +- .../constructor_nonconst_param_test.dart | 3 +- .../const/constructor_syntax_test.dart | 2 +- tests/language/const/counter_test.dart | 2 +- .../check_const_function_typedef2_test.dart | 3 +- .../compile_time_constant/static2_test.dart | 16 +- .../compile_time_constant/static3_test.dart | 16 +- tests/language_2/const/constructor3_test.dart | 3 +- .../constructor_nonconst_param_test.dart | 3 +- .../const/constructor_syntax_test.dart | 2 +- tests/language_2/const/counter_test.dart | 2 +- .../check_const_function_typedef2_test.dart | 3 +- 32 files changed, 662 insertions(+), 649 deletions(-) create mode 100644 pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart create mode 100644 pkg/analyzer/test/src/diagnostics/const_eval_type_string_test.dart diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart index 7558f7ca6d2..806b03c10f2 100644 --- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart +++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart @@ -242,24 +242,28 @@ class ConstantVerifier extends RecursiveAstVisitor { _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 { 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, diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 92432f63c82..8b7fec65a03 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -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? typeArguments, + List 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 { // 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 { // 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 { 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 { } @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 { // 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 { /// 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 { 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 { // 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 { // 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 { 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 diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart index 578e2896038..cd0dcb14321 100644 --- a/pkg/analyzer/lib/src/dart/constant/value.dart +++ b/pkg/analyzer/lib/src/dart/constant/value.dart @@ -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 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? 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. diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart index 350d53277bb..b4c3911bea9 100644 --- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart +++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart @@ -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' 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(); ''', [ 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 '''); } + 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 { diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart index fbd8aa3434a..f3284ac291d 100644 --- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart @@ -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), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart index 8399f42fd12..9fdcd3bbac7 100644 --- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart @@ -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 { @@ -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 { + const A(T x); +} +var v = const A('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 { diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart new file mode 100644 index 00000000000..7842960568c --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/const_eval_property_access_test.dart @@ -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 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."), + ], + ), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart index 389834392ad..b69b421e32a 100644 --- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart @@ -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(); 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 { + final t; + const C(dynamic x) : t = x as T; +} + +main() { + const C(0); + const C('foo'); + const C(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 { + final t; + const C(dynamic x) : t = x as List; +} + +main() { + const C([]); + const C([]); + const C(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 { - const A(T x); -} -var v = const A('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 { - final t; - const C(dynamic x) : t = x as T; -} - -main() { - const C(0); - const C('foo'); - const C(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 { - final t; - const C(dynamic x) : t = x as List; -} - -main() { - const C([]); - const C([]); - const C(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 { - 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 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' 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('_'); diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_type_string_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_type_string_test.dart new file mode 100644 index 00000000000..3a8dfd8c304 --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/const_eval_type_string_test.dart @@ -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), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart index 4eb4f83ffa5..29f1f0faac0 100644 --- a/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/const_field_initializer_not_assignable_test.dart @@ -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), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/field_initialized_by_multiple_initializers_test.dart b/pkg/analyzer/test/src/diagnostics/field_initialized_by_multiple_initializers_test.dart index f18ff4f1b90..d766eac66ac 100644 --- a/pkg/analyzer/test/src/diagnostics/field_initialized_by_multiple_initializers_test.dart +++ b/pkg/analyzer/test/src/diagnostics/field_initialized_by_multiple_initializers_test.dart @@ -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), ]); diff --git a/pkg/analyzer/test/src/diagnostics/field_initialized_in_initializer_and_declaration_test.dart b/pkg/analyzer/test/src/diagnostics/field_initialized_in_initializer_and_declaration_test.dart index ccc96cd5c13..9bf6c157740 100644 --- a/pkg/analyzer/test/src/diagnostics/field_initialized_in_initializer_and_declaration_test.dart +++ b/pkg/analyzer/test/src/diagnostics/field_initialized_in_initializer_and_declaration_test.dart @@ -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, diff --git a/pkg/analyzer/test/src/diagnostics/field_initialized_in_parameter_and_initializer_test.dart b/pkg/analyzer/test/src/diagnostics/field_initialized_in_parameter_and_initializer_test.dart index 5eb82928c26..ced1bc95a85 100644 --- a/pkg/analyzer/test/src/diagnostics/field_initialized_in_parameter_and_initializer_test.dart +++ b/pkg/analyzer/test/src/diagnostics/field_initialized_in_parameter_and_initializer_test.dart @@ -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), ]); diff --git a/pkg/analyzer/test/src/diagnostics/field_initializing_formal_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializing_formal_not_assignable_test.dart index 14ef39deef0..7f098e36202 100644 --- a/pkg/analyzer/test/src/diagnostics/field_initializing_formal_not_assignable_test.dart +++ b/pkg/analyzer/test/src/diagnostics/field_initializing_formal_not_assignable_test.dart @@ -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), ]); diff --git a/pkg/analyzer/test/src/diagnostics/final_initialized_in_declaration_and_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/final_initialized_in_declaration_and_constructor_test.dart index 6cf7eab784b..d7a4b8e8989 100644 --- a/pkg/analyzer/test/src/diagnostics/final_initialized_in_declaration_and_constructor_test.dart +++ b/pkg/analyzer/test/src/diagnostics/final_initialized_in_declaration_and_constructor_test.dart @@ -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, diff --git a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart index be92622f737..19cf6efe0b6 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart @@ -49,6 +49,33 @@ class A { ]); } + test_constructorFieldInitializer_fromSeparateLibrary() async { + newFile('$testPackageLibPath/lib.dart', r''' +class A { + 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 { @@ -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."), ], ), ]); diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 9cefd9f80d5..8c03c6f9395 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart @@ -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(); diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart index 53b37104adc..fee9419c5d9 100644 --- a/pkg/analyzer/test/verify_diagnostics_test.dart +++ b/pkg/analyzer/test/verify_diagnostics_test.dart @@ -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', diff --git a/tests/language/compile_time_constant/static2_test.dart b/tests/language/compile_time_constant/static2_test.dart index 78ce8bed8f6..65d290b5193 100644 --- a/tests/language/compile_time_constant/static2_test.dart +++ b/tests/language/compile_time_constant/static2_test.dart @@ -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() { diff --git a/tests/language/compile_time_constant/static3_test.dart b/tests/language/compile_time_constant/static3_test.dart index a6d158e356d..29cba1976f9 100644 --- a/tests/language/compile_time_constant/static3_test.dart +++ b/tests/language/compile_time_constant/static3_test.dart @@ -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() { diff --git a/tests/language/const/constructor3_test.dart b/tests/language/const/constructor3_test.dart index fd7acda4f38..94c1fbc5cbb 100644 --- a/tests/language/const/constructor3_test.dart +++ b/tests/language/const/constructor3_test.dart @@ -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); diff --git a/tests/language/const/constructor_nonconst_param_test.dart b/tests/language/const/constructor_nonconst_param_test.dart index bca1b3e11a5..239f53ece7d 100644 --- a/tests/language/const/constructor_nonconst_param_test.dart +++ b/tests/language/const/constructor_nonconst_param_test.dart @@ -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 } diff --git a/tests/language/const/constructor_syntax_test.dart b/tests/language/const/constructor_syntax_test.dart index 898aa6ca060..06edf35884b 100644 --- a/tests/language/const/constructor_syntax_test.dart +++ b/tests/language/const/constructor_syntax_test.dart @@ -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 { diff --git a/tests/language/const/counter_test.dart b/tests/language/const/counter_test.dart index 0ca474f6a9f..702499ff4f3 100644 --- a/tests/language/const/counter_test.dart +++ b/tests/language/const/counter_test.dart @@ -23,5 +23,5 @@ class ConstCounter { main() { const ConstCounter(3); //^^^^^^^^^^^^^^^^^^^^^ -// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION +// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT } diff --git a/tests/language/type/check_const_function_typedef2_test.dart b/tests/language/type/check_const_function_typedef2_test.dart index c4ced7c6cdf..33ffd6abee9 100644 --- a/tests/language/type/check_const_function_typedef2_test.dart +++ b/tests/language/type/check_const_function_typedef2_test.dart @@ -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() { diff --git a/tests/language_2/compile_time_constant/static2_test.dart b/tests/language_2/compile_time_constant/static2_test.dart index ab56e6fc885..66760fd2c23 100644 --- a/tests/language_2/compile_time_constant/static2_test.dart +++ b/tests/language_2/compile_time_constant/static2_test.dart @@ -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() { diff --git a/tests/language_2/compile_time_constant/static3_test.dart b/tests/language_2/compile_time_constant/static3_test.dart index 98da39a09be..3cabc10c2b6 100644 --- a/tests/language_2/compile_time_constant/static3_test.dart +++ b/tests/language_2/compile_time_constant/static3_test.dart @@ -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() { diff --git a/tests/language_2/const/constructor3_test.dart b/tests/language_2/const/constructor3_test.dart index 94fe5b82602..a0dd22d6cc1 100644 --- a/tests/language_2/const/constructor3_test.dart +++ b/tests/language_2/const/constructor3_test.dart @@ -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); diff --git a/tests/language_2/const/constructor_nonconst_param_test.dart b/tests/language_2/const/constructor_nonconst_param_test.dart index fbb2d098696..50f8fd705e2 100644 --- a/tests/language_2/const/constructor_nonconst_param_test.dart +++ b/tests/language_2/const/constructor_nonconst_param_test.dart @@ -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 } diff --git a/tests/language_2/const/constructor_syntax_test.dart b/tests/language_2/const/constructor_syntax_test.dart index 585c36ef5df..61227c0026b 100644 --- a/tests/language_2/const/constructor_syntax_test.dart +++ b/tests/language_2/const/constructor_syntax_test.dart @@ -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 { diff --git a/tests/language_2/const/counter_test.dart b/tests/language_2/const/counter_test.dart index 678e6f65af6..968e4520149 100644 --- a/tests/language_2/const/counter_test.dart +++ b/tests/language_2/const/counter_test.dart @@ -25,5 +25,5 @@ class ConstCounter { main() { const ConstCounter(3); //^^^^^^^^^^^^^^^^^^^^^ -// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION +// [analyzer] COMPILE_TIME_ERROR.INVALID_CONSTANT } diff --git a/tests/language_2/type/check_const_function_typedef2_test.dart b/tests/language_2/type/check_const_function_typedef2_test.dart index 2c3e1a95288..bea07a038e6 100644 --- a/tests/language_2/type/check_const_function_typedef2_test.dart +++ b/tests/language_2/type/check_const_function_typedef2_test.dart @@ -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() {