From 1aa7d7321fbfcf0cb07f4d1b62fafed76ca7e5fb Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 7 May 2026 15:30:45 -0700 Subject: [PATCH] CQ. Use in-code diagnostic expectations. Add support for keeping parser diagnostic expectations in the source snippets they describe. Expectations are written as caret markers and diagnostic comments, and regenerated from the parser's actual diagnostics before comparison. This keeps parser recovery expectations close to the code under test and removes the need to maintain offset-based `assertErrors` lists by hand. The updater also removes existing expectation markers before writing the canonical form, so marked snippets can be refreshed in place. Migrate recovery parser and class parser tests to the new `assertExpectedDiagnostics` helper, including no-error cases where an unmarked snippet is the expected canonical form. Update `test_runner` to exclude `/pkg/analyzer/` from searching static error expectations. Bug: https://github.com/dart-lang/sdk/issues/63335 Change-Id: Ic9866da8cc601c6b360552ba576e8aa1646f89a5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/501340 Commit-Queue: Konstantin Shcheglov Reviewed-by: Paul Berry Reviewed-by: Bob Nystrom --- .../test/generated/recovery_parser_test.dart | 1007 ++++++++++------- .../test/src/dart/parser/class_test.dart | 350 +++--- .../src/diagnostics/parser_diagnostics.dart | 13 + .../lib/src/expected_diagnostics.dart | 425 +++++++ pkg/test_runner/lib/src/test_file.dart | 18 +- 5 files changed, 1258 insertions(+), 555 deletions(-) create mode 100644 pkg/analyzer_testing/lib/src/expected_diagnostics.dart diff --git a/pkg/analyzer/test/generated/recovery_parser_test.dart b/pkg/analyzer/test/generated/recovery_parser_test.dart index c5310733907..4b9baf2c6cf 100644 --- a/pkg/analyzer/test/generated/recovery_parser_test.dart +++ b/pkg/analyzer/test/generated/recovery_parser_test.dart @@ -2,7 +2,6 @@ // 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/diagnostic/diagnostic.dart' as diag; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../src/dart/resolution/node_text_expectations.dart'; @@ -23,8 +22,10 @@ class RecoveryParserTest extends ParserDiagnosticsTest { void test_additiveExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = + y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -39,11 +40,12 @@ BinaryExpression void test_additiveExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = +; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -58,8 +60,10 @@ BinaryExpression void test_additiveExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x +; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -74,8 +78,10 @@ BinaryExpression void test_additiveExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super +; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -90,12 +96,14 @@ BinaryExpression void test_additiveExpression_precedence_multiplicative_left() { var parseResult = parseStringWithErrors(r''' var v = * +; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -114,12 +122,14 @@ BinaryExpression void test_additiveExpression_precedence_multiplicative_right() { var parseResult = parseStringWithErrors(r''' var v = + *; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -138,11 +148,12 @@ BinaryExpression void test_additiveExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super + +; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 16, 1), - error(diag.missingIdentifier, 17, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -161,8 +172,10 @@ BinaryExpression void test_assignableSelector() { var parseResult = parseStringWithErrors(r''' var v = a.b[]; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' IndexExpression @@ -182,8 +195,10 @@ IndexExpression void test_assignmentExpression_missing_compound1() { var parseResult = parseStringWithErrors(r''' var v = = y = 0; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' AssignmentExpression @@ -202,8 +217,10 @@ AssignmentExpression void test_assignmentExpression_missing_compound2() { var parseResult = parseStringWithErrors(r''' var v = x = = 0; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' AssignmentExpression @@ -222,8 +239,10 @@ AssignmentExpression void test_assignmentExpression_missing_compound3() { var parseResult = parseStringWithErrors(r''' var v = x = y =; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' AssignmentExpression @@ -242,8 +261,10 @@ AssignmentExpression void test_assignmentExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = = 0; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' AssignmentExpression @@ -258,8 +279,10 @@ AssignmentExpression void test_assignmentExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x =; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' AssignmentExpression @@ -274,8 +297,10 @@ AssignmentExpression void test_bitwiseAndExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = & y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -290,11 +315,12 @@ BinaryExpression void test_bitwiseAndExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = &; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -309,8 +335,10 @@ BinaryExpression void test_bitwiseAndExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x &; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -325,8 +353,10 @@ BinaryExpression void test_bitwiseAndExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super &; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -341,12 +371,14 @@ BinaryExpression void test_bitwiseAndExpression_precedence_equality_left() { var parseResult = parseStringWithErrors(r''' var v = == &&; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.missingIdentifier, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -365,12 +397,14 @@ BinaryExpression void test_bitwiseAndExpression_precedence_equality_right() { var parseResult = parseStringWithErrors(r''' var v = && ==; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.missingIdentifier, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -389,11 +423,12 @@ BinaryExpression void test_bitwiseAndExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super & &; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 17, 1), - error(diag.missingIdentifier, 18, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -412,8 +447,10 @@ BinaryExpression void test_bitwiseOrExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = | y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -428,11 +465,12 @@ BinaryExpression void test_bitwiseOrExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = |; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -447,8 +485,10 @@ BinaryExpression void test_bitwiseOrExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x |; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -463,8 +503,10 @@ BinaryExpression void test_bitwiseOrExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super |; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -479,12 +521,14 @@ BinaryExpression void test_bitwiseOrExpression_precedence_xor_left() { var parseResult = parseStringWithErrors(r''' var v = ^ |; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -503,12 +547,14 @@ BinaryExpression void test_bitwiseOrExpression_precedence_xor_right() { var parseResult = parseStringWithErrors(r''' var v = | ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -527,11 +573,12 @@ BinaryExpression void test_bitwiseOrExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super | |; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 17, 1), - error(diag.missingIdentifier, 18, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -550,8 +597,10 @@ BinaryExpression void test_bitwiseXorExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = ^ y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -566,11 +615,12 @@ BinaryExpression void test_bitwiseXorExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -585,8 +635,10 @@ BinaryExpression void test_bitwiseXorExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -601,8 +653,10 @@ BinaryExpression void test_bitwiseXorExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -617,12 +671,14 @@ BinaryExpression void test_bitwiseXorExpression_precedence_and_left() { var parseResult = parseStringWithErrors(r''' var v = & ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -641,12 +697,14 @@ BinaryExpression void test_bitwiseXorExpression_precedence_and_right() { var parseResult = parseStringWithErrors(r''' var v = ^ &; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 1), - error(diag.missingIdentifier, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -665,11 +723,12 @@ BinaryExpression void test_bitwiseXorExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super ^ ^; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 17, 1), - error(diag.missingIdentifier, 18, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -689,11 +748,12 @@ BinaryExpression var parseResult = parseStringWithErrors(r''' class A {} class B = Object with A {} +// ^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 33, 1), - error(diag.expectedExecutable, 35, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -723,12 +783,13 @@ CompilationUnit void test_combinator_badIdentifier() { var parseResult = parseStringWithErrors(r''' import "/testB.dart" show @ +// ^ +// [diag.missingIdentifier] Expected an identifier. +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.missingConstFinalVarOrType][column 28][length 0] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 26, 1), - error(diag.expectedToken, 26, 1), - error(diag.missingConstFinalVarOrType, 28, 0), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -757,8 +818,10 @@ CompilationUnit void test_combinator_missingIdentifier() { var parseResult = parseStringWithErrors(r''' import "/testB.dart" show ; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 26, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -780,8 +843,10 @@ CompilationUnit void test_conditionalExpression_missingElse() { var parseResult = parseStringWithErrors(r''' var v = x ? y :; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -799,8 +864,10 @@ ConditionalExpression void test_conditionalExpression_missingThen() { var parseResult = parseStringWithErrors(r''' var v = x ? : z; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -818,8 +885,10 @@ ConditionalExpression void test_conditionalExpression_super() { var parseResult = parseStringWithErrors(r''' var v = x ? super : z; +// ^^^^^ +// [diag.missingAssignableSelector] Missing selector such as '.identifier' or '[0]'. '''); - parseResult.assertErrors([error(diag.missingAssignableSelector, 12, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -837,8 +906,10 @@ ConditionalExpression void test_conditionalExpression_super2() { var parseResult = parseStringWithErrors(r''' var v = x ? z : super; +// ^^^^^ +// [diag.missingAssignableSelector] Missing selector such as '.identifier' or '[0]'. '''); - parseResult.assertErrors([error(diag.missingAssignableSelector, 16, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -856,8 +927,10 @@ ConditionalExpression void test_declarationBeforeDirective() { var parseResult = parseStringWithErrors(r''' class foo { } import 'bar.dart'; +// ^^^^^^ +// [diag.directiveAfterDeclaration] Directives must appear before any declarations. '''); - parseResult.assertErrors([error(diag.directiveAfterDeclaration, 14, 6)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -881,8 +954,10 @@ CompilationUnit void test_dotShorthand_missing_identifier() { var parseResult = parseStringWithErrors(r''' var v = .; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 9, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' DotShorthandPropertyAccess @@ -896,8 +971,10 @@ DotShorthandPropertyAccess void test_equalityExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = == y; +// ^^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 2)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -912,11 +989,12 @@ BinaryExpression void test_equalityExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = ==; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -931,8 +1009,10 @@ BinaryExpression void test_equalityExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x ==; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -947,8 +1027,10 @@ BinaryExpression void test_equalityExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super ==; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 16, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -963,12 +1045,14 @@ BinaryExpression void test_equalityExpression_precedence_relational_right() { var parseResult = parseStringWithErrors(r''' var v = == is; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.expectedTypeName] Expected a type name. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.expectedTypeName, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -987,12 +1071,13 @@ BinaryExpression void test_equalityExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super == ==; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// [diag.equalityCannotBeEqualityOperand] A comparison expression can't be an operand of another comparison expression. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 18, 2), - error(diag.equalityCannotBeEqualityOperand, 18, 2), - error(diag.missingIdentifier, 20, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -1011,8 +1096,10 @@ BinaryExpression void test_equalityExpression_superRHS() { var parseResult = parseStringWithErrors(r''' var v = 1 == super; +// ^^^^^ +// [diag.missingAssignableSelector] Missing selector such as '.identifier' or '[0]'. '''); - parseResult.assertErrors([error(diag.missingAssignableSelector, 13, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -1027,8 +1114,10 @@ BinaryExpression void test_expressionList_multiple_end() { var parseResult = parseStringWithErrors(r''' var v = [, 2, 3, 4]; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 9, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleListLiteral; assertParsedNodeText(node, r''' ListLiteral @@ -1049,8 +1138,10 @@ ListLiteral void test_expressionList_multiple_middle() { var parseResult = parseStringWithErrors(r''' var v = [1, 2, , 4]; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleListLiteral; assertParsedNodeText(node, r''' ListLiteral @@ -1072,7 +1163,7 @@ ListLiteral var parseResult = parseStringWithErrors(r''' var v = [1, 2, 3]; '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleListLiteral; assertParsedNodeText(node, r''' ListLiteral @@ -1091,8 +1182,10 @@ ListLiteral void test_functionExpression_in_ConstructorFieldInitializer() { var parseResult = parseStringWithErrors(r''' class A { A() : a = (){}; var v; } +// ^ +// [diag.expectedClassMember] Expected a class member. '''); - parseResult.assertErrors([error(diag.expectedClassMember, 24, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1137,11 +1230,12 @@ CompilationUnit void test_functionExpression_named() { var parseResult = parseStringWithErrors(r''' var v = m(f() => 0);; +// ^ +// [diag.namedFunctionExpression] Function expressions can't be named. +// ^ +// [diag.unexpectedToken] Unexpected text ';'. '''); - parseResult.assertErrors([ - error(diag.namedFunctionExpression, 10, 1), - error(diag.unexpectedToken, 20, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' MethodInvocation @@ -1166,9 +1260,11 @@ MethodInvocation var parseResult = parseStringWithErrors(r''' void f() { if (x v) f(x); +// ^ +// [diag.expectedToken] Expected to find ')'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 19, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' IfStatement @@ -1194,8 +1290,10 @@ IfStatement void test_importDirectivePartial_as() { var parseResult = parseStringWithErrors(r''' import 'b.dart' d as b; +// ^ +// [diag.unexpectedToken] Unexpected text 'd'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 16, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1214,8 +1312,10 @@ CompilationUnit void test_importDirectivePartial_hide() { var parseResult = parseStringWithErrors(r''' import 'b.dart' d hide foo; +// ^ +// [diag.unexpectedToken] Unexpected text 'd'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 16, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1237,8 +1337,10 @@ CompilationUnit void test_importDirectivePartial_show() { var parseResult = parseStringWithErrors(r''' import 'b.dart' d show foo; +// ^ +// [diag.unexpectedToken] Unexpected text 'd'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 16, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1260,11 +1362,11 @@ CompilationUnit void test_incomplete_conditionalExpression() { var parseResult = parseStringWithErrors(r''' var v = x ? 0; +// ^ +// [diag.expectedToken] Expected to find ':'. +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 13, 1), - error(diag.missingIdentifier, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -1282,12 +1384,13 @@ ConditionalExpression void test_incomplete_constructorInitializers_empty() { var parseResult = parseStringWithErrors(r''' C() : {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.expectedExecutable, 6, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1308,12 +1411,13 @@ CompilationUnit void test_incomplete_constructorInitializers_missingEquals() { var parseResult = parseStringWithErrors(r''' C() : x(3) {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.missingIdentifier, 8, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1346,13 +1450,14 @@ CompilationUnit void test_incomplete_constructorInitializers_this() { var parseResult = parseStringWithErrors(r''' C() : this {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^^^^ +// [diag.expectedIdentifierButGotKeyword] 'this' can't be used as an identifier because it's a keyword. +// [diag.missingFunctionParameters] Functions must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.expectedIdentifierButGotKeyword, 6, 4), - error(diag.missingFunctionParameters, 6, 4), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1383,16 +1488,19 @@ CompilationUnit void test_incomplete_constructorInitializers_thisField() { var parseResult = parseStringWithErrors(r''' C() : this.g {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^^^^ +// [diag.expectedIdentifierButGotKeyword] 'this' can't be used as an identifier because it's a keyword. +// [diag.missingFunctionParameters] Functions must have an explicit list of parameters. +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.missingFunctionParameters] Functions must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.expectedIdentifierButGotKeyword, 6, 4), - error(diag.missingFunctionParameters, 6, 4), - error(diag.missingFunctionBody, 10, 1), - error(diag.expectedExecutable, 10, 1), - error(diag.missingFunctionParameters, 11, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1433,16 +1541,19 @@ CompilationUnit void test_incomplete_constructorInitializers_thisPeriod() { var parseResult = parseStringWithErrors(r''' C() : this. {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^^^^ +// [diag.expectedIdentifierButGotKeyword] 'this' can't be used as an identifier because it's a keyword. +// [diag.missingFunctionParameters] Functions must have an explicit list of parameters. +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.expectedIdentifierButGotKeyword, 6, 4), - error(diag.missingFunctionParameters, 6, 4), - error(diag.missingFunctionBody, 10, 1), - error(diag.expectedExecutable, 10, 1), - error(diag.expectedExecutable, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1473,12 +1584,13 @@ CompilationUnit void test_incomplete_constructorInitializers_variable() { var parseResult = parseStringWithErrors(r''' C() : x {} +// ^ +// [diag.missingFunctionBody] A function body must be provided. +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.missingFunctionParameters] Functions must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.missingFunctionBody, 4, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.missingFunctionParameters, 6, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1509,8 +1621,10 @@ CompilationUnit void test_incomplete_functionExpression() { var parseResult = parseStringWithErrors(r''' var v = () a => null; +// ^ +// [diag.unexpectedToken] Unexpected text 'a'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' FunctionExpression @@ -1527,8 +1641,10 @@ FunctionExpression void test_incomplete_functionExpression2() { var parseResult = parseStringWithErrors(r''' var v = () a {}; +// ^ +// [diag.unexpectedToken] Unexpected text 'a'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' FunctionExpression @@ -1545,6 +1661,9 @@ FunctionExpression void test_incomplete_returnType() { var parseResult = parseStringWithErrors(r''' Map map) { +// [diag.missingFunctionParameters][column 1][length 3] Functions must have an explicit list of parameters. +// ^^^^^^^^^^^^^^^^^^^^^^^^ +// [diag.expectedToken] Expected to find '>'. if (map == null) return null; Map result = new Map(); map.forEach((name, value) { @@ -1553,10 +1672,7 @@ Map map) { return result; } '''); - parseResult.assertErrors([ - error(diag.expectedToken, 12, 24), - error(diag.missingFunctionParameters, 0, 3), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1687,7 +1803,7 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' foo(); '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1707,8 +1823,10 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' // @dart = 3.5 foo(); +// ^ +// [diag.missingFunctionBody] A function body must be provided. '''); - parseResult.assertErrors([error(diag.missingFunctionBody, 20, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1727,11 +1845,10 @@ CompilationUnit void test_incomplete_topLevelVariable() { var parseResult = parseStringWithErrors(r''' String +// [diag.missingConstFinalVarOrType][column 1][length 6] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. +// [diag.expectedToken][column 1][length 6] Expected to find ';'. '''); - parseResult.assertErrors([ - error(diag.missingConstFinalVarOrType, 0, 6), - error(diag.expectedToken, 0, 6), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1748,11 +1865,11 @@ CompilationUnit void test_incomplete_topLevelVariable_const() { var parseResult = parseStringWithErrors(r''' const +// [diag.expectedToken][column 1][length 5] Expected to find ';'. +// ^ +// [diag.missingIdentifier][column 6][length 0] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 0, 5), - error(diag.missingIdentifier, 6, 0), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1770,11 +1887,11 @@ CompilationUnit void test_incomplete_topLevelVariable_final() { var parseResult = parseStringWithErrors(r''' final +// [diag.expectedToken][column 1][length 5] Expected to find ';'. +// ^ +// [diag.missingIdentifier][column 6][length 0] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 0, 5), - error(diag.missingIdentifier, 6, 0), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1792,11 +1909,11 @@ CompilationUnit void test_incomplete_topLevelVariable_var() { var parseResult = parseStringWithErrors(r''' var +// [diag.expectedToken][column 1][length 3] Expected to find ';'. +// ^ +// [diag.missingIdentifier][column 4][length 0] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 0, 3), - error(diag.missingIdentifier, 4, 0), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1815,12 +1932,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { const +//^^^^^ +// [diag.expectedToken] Expected to find ';'. } +// [diag.missingIdentifier][column 1][length 1] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 12, 5), - error(diag.missingIdentifier, 18, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1847,12 +1964,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { final +//^^^^^ +// [diag.expectedToken] Expected to find ';'. } +// [diag.missingIdentifier][column 1][length 1] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 12, 5), - error(diag.missingIdentifier, 18, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1879,12 +1996,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { static c +// ^ +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([ - error(diag.missingConstFinalVarOrType, 19, 1), - error(diag.expectedToken, 19, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1911,9 +2028,11 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { static c x +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 21, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1942,12 +2061,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { A +//^ +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([ - error(diag.missingConstFinalVarOrType, 12, 1), - error(diag.expectedToken, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -1973,12 +2092,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { var +//^^^ +// [diag.expectedToken] Expected to find ';'. } +// [diag.missingIdentifier][column 1][length 1] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 12, 3), - error(diag.missingIdentifier, 16, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2005,12 +2124,13 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' void f() { for (String item i) {} +// ^^^^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([ - error(diag.expectedToken, 25, 4), - error(diag.expectedToken, 30, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' ForStatement @@ -2038,12 +2158,13 @@ ForStatement var parseResult = parseStringWithErrors(r''' void f() { for (String item i) {} +// ^^^^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([ - error(diag.expectedToken, 25, 4), - error(diag.expectedToken, 30, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' ForStatement @@ -2071,12 +2192,12 @@ ForStatement var parseResult = parseStringWithErrors(r''' void f() { String v } +// ^ +// [diag.expectedToken] Expected to find ';'. } +// [diag.expectedExecutable][column 1][length 1] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 20, 1), - error(diag.expectedExecutable, 24, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2094,13 +2215,14 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' void f() { final } +//^^^^^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.missingIdentifier] Expected an identifier. } +// [diag.expectedExecutable][column 1][length 1] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 13, 5), - error(diag.missingIdentifier, 19, 1), - error(diag.expectedExecutable, 21, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2117,9 +2239,11 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' void f() { String v String v2; +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 20, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2137,9 +2261,11 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' void f() { String v if (true) {} +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 20, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2157,9 +2283,11 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' void f() { String v {} +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 20, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2177,9 +2305,11 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' void f() { List v {} +// ^ +// [diag.expectedToken] Expected to find ';'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 26, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.firstBlock.statements[0]; assertParsedNodeText(node, r''' VariableDeclarationStatement @@ -2203,9 +2333,11 @@ VariableDeclarationStatement var parseResult = parseStringWithErrors(r''' class C { final List'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 23, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2239,9 +2371,11 @@ CompilationUnit void test_incompleteTypeParameters() { var parseResult = parseStringWithErrors(r''' class C'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2265,9 +2399,11 @@ CompilationUnit void test_incompleteTypeParameters2() { var parseResult = parseStringWithErrors(r''' class C { +// ^ +// [diag.expectedToken] Expected to find '>'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 21, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2300,9 +2436,11 @@ CompilationUnit void test_incompleteTypeParameters3() { var parseResult = parseStringWithErrors(r''' class C'. } '''); - parseResult.assertErrors([error(diag.expectedToken, 20, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2335,8 +2473,10 @@ CompilationUnit void test_invalidFunctionBodyModifier() { var parseResult = parseStringWithErrors(r''' f() sync {} +// ^^^^ +// [diag.missingStarAfterSync] The modifier 'sync' must be followed by a star ('*'). '''); - parseResult.assertErrors([error(diag.missingStarAfterSync, 4, 4)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2358,8 +2498,10 @@ CompilationUnit void test_invalidMapLiteral() { var parseResult = parseStringWithErrors(r''' class C { var f = Map {}; } +// ^^^ +// [diag.literalWithClass] A map literal can't be prefixed by 'Map'. '''); - parseResult.assertErrors([error(diag.literalWithClass, 18, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2399,9 +2541,11 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { G g; +// ^^^^^^ +// [diag.expectedToken] Expected to find ','. } '''); - parseResult.assertErrors([error(diag.expectedToken, 18, 6)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2436,8 +2580,10 @@ CompilationUnit void test_invalidTypeParameters_super() { var parseResult = parseStringWithErrors(r''' class C {} +// ^ +// [diag.expectedToken] Expected to find '>'. '''); - parseResult.assertErrors([error(diag.expectedToken, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2461,13 +2607,15 @@ CompilationUnit void test_isExpression_noType() { var parseResult = parseStringWithErrors(r''' class Bar {m(x){if (x is ) return;if (x is !)}} +// ^ +// [diag.expectedTypeName] Expected a type name. +// ^ +// [diag.expectedTypeName] Expected a type name. +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.expectedTypeName, 40, 1), - error(diag.expectedTypeName, 59, 1), - error(diag.expectedToken, 59, 1), - error(diag.missingIdentifier, 60, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2535,11 +2683,12 @@ CompilationUnit void test_issue_34610_get() { var parseResult = parseStringWithErrors(r''' class C { get C.named => null; } +// ^^^ +// [diag.getterConstructor] Constructors can't be a getter. +// ^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.getterConstructor, 10, 3), - error(diag.missingMethodParameters, 14, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2571,8 +2720,10 @@ CompilationUnit void test_issue_34610_initializers() { var parseResult = parseStringWithErrors(r''' class C { C.named : super(); } +// ^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. '''); - parseResult.assertErrors([error(diag.missingMethodParameters, 10, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2608,8 +2759,10 @@ CompilationUnit void test_issue_34610_missing_param() { var parseResult = parseStringWithErrors(r''' class C { C => null; } +// ^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. '''); - parseResult.assertErrors([error(diag.missingMethodParameters, 10, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2639,8 +2792,10 @@ CompilationUnit void test_issue_34610_named_missing_param() { var parseResult = parseStringWithErrors(r''' class C { C.named => null; } +// ^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. '''); - parseResult.assertErrors([error(diag.missingMethodParameters, 10, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2672,11 +2827,12 @@ CompilationUnit void test_issue_34610_set() { var parseResult = parseStringWithErrors(r''' class C { set C.named => null; } +// ^^^ +// [diag.setterConstructor] Constructors can't be a setter. +// ^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.setterConstructor, 10, 3), - error(diag.missingMethodParameters, 14, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2708,10 +2864,9 @@ CompilationUnit void test_keywordInPlaceOfIdentifier() { var parseResult = parseStringWithErrors(r''' do() {} +// [diag.expectedIdentifierButGotKeyword][column 1][length 2] 'do' can't be used as an identifier because it's a keyword. '''); - parseResult.assertErrors([ - error(diag.expectedIdentifierButGotKeyword, 0, 2), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2732,8 +2887,10 @@ CompilationUnit void test_logicalAndExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = && y; +// ^^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 2)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2748,11 +2905,12 @@ BinaryExpression void test_logicalAndExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = &&; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2767,8 +2925,10 @@ BinaryExpression void test_logicalAndExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x &&; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2783,12 +2943,14 @@ BinaryExpression void test_logicalAndExpression_precedence_bitwiseOr_left() { var parseResult = parseStringWithErrors(r''' var v = | &&; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 2), - error(diag.missingIdentifier, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2807,12 +2969,14 @@ BinaryExpression void test_logicalAndExpression_precedence_bitwiseOr_right() { var parseResult = parseStringWithErrors(r''' var v = && |; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 1), - error(diag.missingIdentifier, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2831,8 +2995,10 @@ BinaryExpression void test_logicalOrExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = || y; +// ^^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 2)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2847,11 +3013,12 @@ BinaryExpression void test_logicalOrExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = ||; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2866,8 +3033,10 @@ BinaryExpression void test_logicalOrExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x ||; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2882,12 +3051,14 @@ BinaryExpression void test_logicalOrExpression_precedence_logicalAnd_left() { var parseResult = parseStringWithErrors(r''' var v = && ||; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.missingIdentifier, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2906,12 +3077,14 @@ BinaryExpression void test_logicalOrExpression_precedence_logicalAnd_right() { var parseResult = parseStringWithErrors(r''' var v = || &&; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.missingIdentifier, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -2930,8 +3103,10 @@ BinaryExpression void test_method_missingBody() { var parseResult = parseStringWithErrors(r''' class C { b() } +// ^ +// [diag.missingFunctionBody] A function body must be provided. '''); - parseResult.assertErrors([error(diag.missingFunctionBody, 14, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -2959,8 +3134,10 @@ CompilationUnit void test_missing_commaInArgumentList() { var parseResult = parseStringWithErrors(r''' var v = f(x: 1 y: 2); +// ^ +// [diag.expectedToken] Expected to find ','. '''); - parseResult.assertErrors([error(diag.expectedToken, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' MethodInvocation @@ -2986,15 +3163,18 @@ MethodInvocation void test_missingComma_beforeNamedArgument() { var parseResult = parseStringWithErrors(r''' (a b: c) +// [diag.expectedExecutable][column 1][length 1] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^ +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([ - error(diag.expectedExecutable, 0, 1), - error(diag.expectedToken, 3, 1), - error(diag.expectedExecutable, 4, 1), - error(diag.missingConstFinalVarOrType, 6, 1), - error(diag.expectedToken, 6, 1), - error(diag.expectedExecutable, 7, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3020,10 +3200,12 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' class C { int length {} +// ^^^^^^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. void foo() {} } '''); - parseResult.assertErrors([error(diag.missingMethodParameters, 16, 6)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3064,8 +3246,10 @@ CompilationUnit void test_missingIdentifier_afterAnnotation() { var parseResult = parseStringWithErrors(r''' @override } +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. '''); - parseResult.assertErrors([error(diag.expectedExecutable, 10, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3075,11 +3259,12 @@ CompilationUnit void test_missingSemicolon_variableDeclarationList() { var parseResult = parseStringWithErrors(r''' String n x = ""; +// ^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 7, 1), - error(diag.missingConstFinalVarOrType, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3107,8 +3292,10 @@ CompilationUnit void test_multiplicativeExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = * y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3123,11 +3310,12 @@ BinaryExpression void test_multiplicativeExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = *; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 9, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3142,8 +3330,10 @@ BinaryExpression void test_multiplicativeExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x *; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 11, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3158,8 +3348,10 @@ BinaryExpression void test_multiplicativeExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super *; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 15, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3174,8 +3366,10 @@ BinaryExpression void test_multiplicativeExpression_precedence_unary_left() { var parseResult = parseStringWithErrors(r''' var v = -x *; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3192,8 +3386,10 @@ BinaryExpression void test_multiplicativeExpression_precedence_unary_right() { var parseResult = parseStringWithErrors(r''' var v = * -y; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3210,12 +3406,13 @@ BinaryExpression void test_multiplicativeExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super == ==; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// [diag.equalityCannotBeEqualityOperand] A comparison expression can't be an operand of another comparison expression. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 18, 2), - error(diag.equalityCannotBeEqualityOperand, 18, 2), - error(diag.missingIdentifier, 20, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3234,11 +3431,12 @@ BinaryExpression void test_namedParameterOutsideGroup() { var parseResult = parseStringWithErrors(r''' class A { b(c: 0, Foo d: 0, e){} } +// ^ +// [diag.namedParameterOutsideGroup] Named parameters must be enclosed in curly braces ('{' and '}'). +// ^ +// [diag.namedParameterOutsideGroup] Named parameters must be enclosed in curly braces ('{' and '}'). '''); - parseResult.assertErrors([ - error(diag.namedParameterOutsideGroup, 13, 1), - error(diag.namedParameterOutsideGroup, 23, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3282,15 +3480,17 @@ CompilationUnit void test_nonStringLiteralUri_import() { var parseResult = parseStringWithErrors(r''' import dart:io; class C {} +// [diag.expectedToken][column 1][length 6] Expected to find ';'. +// ^^^^ +// [diag.expectedStringLiteral] Expected a string literal. +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.expectedExecutable] Expected a method, getter, setter or operator declaration. +// ^^ +// [diag.missingConstFinalVarOrType] Variables must be declared using the keywords 'const', 'final', 'var' or a type name. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 0, 6), - error(diag.expectedStringLiteral, 7, 4), - error(diag.missingConstFinalVarOrType, 7, 4), - error(diag.expectedToken, 7, 4), - error(diag.expectedExecutable, 11, 1), - error(diag.missingConstFinalVarOrType, 12, 2), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3326,8 +3526,10 @@ CompilationUnit void test_prefixExpression_missing_operand_minus() { var parseResult = parseStringWithErrors(r''' var v = -; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 9, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' PrefixExpression @@ -3340,12 +3542,13 @@ PrefixExpression void test_primaryExpression_argumentDefinitionTest() { var parseResult = parseStringWithErrors(r''' var v = ?a; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.expectedToken] Expected to find ':'. +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.expectedToken, 10, 1), - error(diag.missingIdentifier, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' ConditionalExpression @@ -3363,8 +3566,10 @@ ConditionalExpression void test_relationalExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = is y; +// ^^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 2)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' IsExpression @@ -3379,11 +3584,12 @@ IsExpression void test_relationalExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = is; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.expectedTypeName] Expected a type name. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.expectedTypeName, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' IsExpression @@ -3398,8 +3604,10 @@ IsExpression void test_relationalExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x is; +// ^ +// [diag.expectedTypeName] Expected a type name. '''); - parseResult.assertErrors([error(diag.expectedTypeName, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' IsExpression @@ -3414,12 +3622,14 @@ IsExpression void test_relationalExpression_precedence_shift_right() { var parseResult = parseStringWithErrors(r''' var v = << is; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.expectedTypeName] Expected a type name. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 2), - error(diag.expectedTypeName, 13, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' IsExpression @@ -3438,8 +3648,10 @@ IsExpression void test_shiftExpression_missing_LHS() { var parseResult = parseStringWithErrors(r''' var v = << y; +// ^^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 2)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3454,11 +3666,12 @@ BinaryExpression void test_shiftExpression_missing_LHS_RHS() { var parseResult = parseStringWithErrors(r''' var v = <<; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 10, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3473,8 +3686,10 @@ BinaryExpression void test_shiftExpression_missing_RHS() { var parseResult = parseStringWithErrors(r''' var v = x <<; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 12, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3489,8 +3704,10 @@ BinaryExpression void test_shiftExpression_missing_RHS_super() { var parseResult = parseStringWithErrors(r''' var v = super <<; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 16, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3505,12 +3722,14 @@ BinaryExpression void test_shiftExpression_precedence_unary_left() { var parseResult = parseStringWithErrors(r''' var v = + <<; +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 1), - error(diag.missingIdentifier, 10, 2), - error(diag.missingIdentifier, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3529,12 +3748,14 @@ BinaryExpression void test_shiftExpression_precedence_unary_right() { var parseResult = parseStringWithErrors(r''' var v = << +; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 8, 2), - error(diag.missingIdentifier, 11, 1), - error(diag.missingIdentifier, 12, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3553,11 +3774,12 @@ BinaryExpression void test_shiftExpression_super() { var parseResult = parseStringWithErrors(r''' var v = super << <<; +// ^^ +// [diag.missingIdentifier] Expected an identifier. +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([ - error(diag.missingIdentifier, 17, 2), - error(diag.missingIdentifier, 19, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression @@ -3576,11 +3798,12 @@ BinaryExpression void test_typedef_eof() { var parseResult = parseStringWithErrors(r''' typedef n +// ^ +// [diag.expectedToken] Expected to find ';'. +// ^ +// [diag.missingTypedefParameters][column 10][length 0] Typedefs must have an explicit list of parameters. '''); - parseResult.assertErrors([ - error(diag.expectedToken, 8, 1), - error(diag.missingTypedefParameters, 10, 0), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.unit; assertParsedNodeText(node, r''' CompilationUnit @@ -3598,8 +3821,10 @@ CompilationUnit void test_unaryPlus() { var parseResult = parseStringWithErrors(r''' var v = +2; +// ^ +// [diag.missingIdentifier] Expected an identifier. '''); - parseResult.assertErrors([error(diag.missingIdentifier, 8, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleVariableDeclaration.initializer!; assertParsedNodeText(node, r''' BinaryExpression diff --git a/pkg/analyzer/test/src/dart/parser/class_test.dart b/pkg/analyzer/test/src/dart/parser/class_test.dart index 44762905178..4f959524e84 100644 --- a/pkg/analyzer/test/src/dart/parser/class_test.dart +++ b/pkg/analyzer/test/src/dart/parser/class_test.dart @@ -2,7 +2,6 @@ // 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/diagnostic/diagnostic.dart' as diag; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../../diagnostics/parser_diagnostics.dart'; @@ -21,7 +20,7 @@ class ClassDeclarationParserTest extends ParserDiagnosticsTest { var parseResult = parseStringWithErrors(r''' augment class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -40,7 +39,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment abstract class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -58,7 +57,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment abstract base class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -77,7 +76,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment base class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -95,7 +94,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment class A extends B {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -116,7 +115,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment final class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -134,7 +133,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment class A implements B {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -156,7 +155,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment interface class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -174,7 +173,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment mixin class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -191,10 +190,9 @@ ClassDeclaration test_augment_namedMixinApplication() { var parseResult = parseStringWithErrors(r''' augment class A = B with M; +// [diag.mixinApplicationClassAugmentation][column 1][length 7] A mixin application class can't be augmented. '''); - parseResult.assertErrors([ - error(diag.mixinApplicationClassAugmentation, 0, 7), - ]); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.unit, r''' CompilationUnit declarations @@ -218,7 +216,7 @@ CompilationUnit var parseResult = parseStringWithErrors(r''' augment sealed class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -236,7 +234,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -262,7 +260,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment class A with M {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -284,7 +282,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A; '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -303,7 +301,7 @@ class A { factory named() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -326,7 +324,7 @@ class A { const factory named() = B; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -350,9 +348,11 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { factory new() {} +// ^^^ +// [diag.factoryConstructorNewName] Factory constructors can't be named 'new'. } '''); - parseResult.assertErrors([error(diag.factoryConstructorNewName, 20, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -375,7 +375,7 @@ class A { factory () {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -397,7 +397,7 @@ class A { const factory () = B; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -422,7 +422,7 @@ class A { new named(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -443,7 +443,7 @@ class A { new named() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -466,7 +466,7 @@ class A { const new named(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -488,7 +488,7 @@ class A { new named() : x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -515,9 +515,11 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { new new(); +// ^^^ +// [diag.newConstructorNewName] Constructors declared with the 'new' keyword can't be named 'new'. } '''); - parseResult.assertErrors([error(diag.newConstructorNewName, 16, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -538,7 +540,7 @@ class A { new (); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -558,7 +560,7 @@ class A { new () {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -580,7 +582,7 @@ class A { const new (); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -601,7 +603,7 @@ class A { new () : x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -629,7 +631,7 @@ class A { new (int x, {required String y}); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -660,7 +662,7 @@ augment class A { augment A.named(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -683,11 +685,11 @@ ConstructorDeclaration class A { final int f; external A([this.f = 0]); +// ^^^^ +// [diag.externalConstructorWithFieldInitializers] An external constructor can't initialize fields. } '''); - parseResult.assertErrors([ - error(diag.externalConstructorWithFieldInitializers, 39, 4), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -718,11 +720,11 @@ ConstructorDeclaration class A { final int f; external A(this.f); +// ^^^^ +// [diag.externalConstructorWithFieldInitializers] An external constructor can't initialize fields. } '''); - parseResult.assertErrors([ - error(diag.externalConstructorWithFieldInitializers, 38, 4), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -747,11 +749,11 @@ ConstructorDeclaration class A { final int f; external A() : f = 0; +// ^ +// [diag.externalConstructorWithInitializer] An external constructor can't have any initializers. } '''); - parseResult.assertErrors([ - error(diag.externalConstructorWithInitializer, 40, 1), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -781,7 +783,7 @@ class A { factory A.named() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -808,7 +810,7 @@ class A { factory A.named() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -834,7 +836,7 @@ class A { factory A() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -859,7 +861,7 @@ class A { factory A() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -884,7 +886,7 @@ class A { factory B() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -906,12 +908,12 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { A(const int a(String x)); +// ^^^^^ +// [diag.extraneousModifier] Can't have modifier 'const' here. +// [diag.functionTypedParameterVar] Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type. } '''); - parseResult.assertErrors([ - error(diag.extraneousModifier, 14, 5), - error(diag.functionTypedParameterVar, 14, 5), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -948,7 +950,7 @@ class A { ); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -982,12 +984,12 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { A(final int a(String x)); +// ^^^^^ +// [diag.functionTypedParameterVar] Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type. +// [diag.extraneousModifier] Can't have modifier 'final' here. } '''); - parseResult.assertErrors([ - error(diag.extraneousModifier, 14, 5), - error(diag.functionTypedParameterVar, 14, 5), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1019,9 +1021,11 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { A(const int a); +// ^^^^^ +// [diag.extraneousModifier] Can't have modifier 'const' here. } '''); - parseResult.assertErrors([error(diag.extraneousModifier, 14, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1050,7 +1054,7 @@ class A { ); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1076,9 +1080,11 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { A(final int a); +// ^^^^^ +// [diag.extraneousModifier] Can't have modifier 'final' here. } '''); - parseResult.assertErrors([error(diag.extraneousModifier, 14, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1104,7 +1110,7 @@ class A { A.named(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1125,9 +1131,11 @@ ConstructorDeclaration var parseResult = parseStringWithErrors(r''' class A { A.(); +// ^ +// [diag.missingIdentifier] Expected an identifier. } '''); - parseResult.assertErrors([error(diag.missingIdentifier, 14, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1150,7 +1158,7 @@ class A { A(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleConstructorDeclaration; assertParsedNodeText(node, r''' @@ -1171,7 +1179,7 @@ augment class A { augment int x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1203,7 +1211,7 @@ augment class A { augment covariant int x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1236,7 +1244,7 @@ augment class A { augment late int x; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1266,7 +1274,7 @@ augment class A { augment static int x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1299,7 +1307,7 @@ augment class A { augment static final int x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1333,7 +1341,7 @@ augment class A { augment int get foo => 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1364,7 +1372,7 @@ augment class A { augment static int get foo => 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1396,7 +1404,7 @@ class A { static int get foo; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' @@ -1412,13 +1420,15 @@ MethodDeclaration } test_getter_static_body_empty_language305() { - var parseResult = parseStringWithErrors(''' + var parseResult = parseStringWithErrors(r''' // @dart = 3.5 class A { static int get foo; +// ^ +// [diag.missingFunctionBody] A function body must be provided. } '''); - parseResult.assertErrors([error(diag.missingFunctionBody, 45, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' @@ -1439,7 +1449,7 @@ augment class A { augment void foo() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1471,9 +1481,11 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' augment class A { augment abstract void foo(); +// ^^^^^^^^ +// [diag.abstractClassMember] Members of classes can't be declared to be 'abstract'. } '''); - parseResult.assertErrors([error(diag.abstractClassMember, 28, 8)]); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1503,7 +1515,7 @@ augment class A { augment static void foo() {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1536,7 +1548,7 @@ class A { static int foo(); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' @@ -1554,13 +1566,15 @@ MethodDeclaration } test_method_static_body_empty_language305() { - var parseResult = parseStringWithErrors(''' + var parseResult = parseStringWithErrors(r''' // @dart = 3.5 class A { static int foo(); +// ^ +// [diag.missingFunctionBody] A function body must be provided. } '''); - parseResult.assertErrors([error(diag.missingFunctionBody, 43, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' @@ -1581,7 +1595,7 @@ MethodDeclaration var parseResult = parseStringWithErrors(r''' augment class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1604,7 +1618,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1630,7 +1644,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1650,7 +1664,7 @@ augment class A { augment int operator+(int other) => 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -1686,7 +1700,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class const A.named() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1719,7 +1733,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class const A() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1749,17 +1763,17 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' mixin M {} class const C = Object with M; +// ^^^^^ +// [diag.constWithoutPrimaryConstructor] 'const' can only be used together with a primary constructor declaration. '''); - parseResult.assertErrors([ - error(diag.constWithoutPrimaryConstructor, 17, 5), - ]); + parseResult.assertExpectedDiagnostics(); } test_primaryConstructor_const_noTypeParameters_named() { var parseResult = parseStringWithErrors(r''' class const A.named() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1784,7 +1798,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class const A() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1805,10 +1819,10 @@ ClassDeclaration test_primaryConstructor_const_typeName_noFormalParameters() { var parseResult = parseStringWithErrors(r''' class const A {} +// ^^^^^ +// [diag.constWithoutPrimaryConstructor] 'const' can only be used together with a primary constructor declaration. '''); - parseResult.assertErrors([ - error(diag.constWithoutPrimaryConstructor, 6, 5), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1826,8 +1840,10 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' // @dart=3.10 class const A {} +// ^^^^^ +// [diag.unexpectedToken] Unexpected text 'const'. '''); - parseResult.assertErrors([error(diag.unexpectedToken, 20, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1846,7 +1862,7 @@ ClassDeclaration class const A.named {} '''); // TODO(scheglov): this is wrong. - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1871,7 +1887,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A({final int a = 0}) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1903,7 +1919,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A({var int a = 0}) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1935,7 +1951,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A({required final int a = 0}) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -1971,7 +1987,7 @@ class A({ required final int a = 0, }) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2007,7 +2023,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A({required var int a = 0}) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2040,7 +2056,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A([final int a = 0]) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2072,7 +2088,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A([var int a = 0]) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2103,8 +2119,10 @@ ClassDeclaration test_primaryConstructor_declaringFormalParameter_functionTyped_const() { var parseResult = parseStringWithErrors(r''' class A(const int a(String x)) {} +// ^^^^^ +// [diag.extraneousModifier] Can't have modifier 'const' here. '''); - parseResult.assertErrors([error(diag.extraneousModifier, 8, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2138,7 +2156,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(final int a(String x)) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2175,7 +2193,7 @@ class A( final int a(String x) ) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2212,7 +2230,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(var int a(String x)) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2245,8 +2263,10 @@ ClassDeclaration test_primaryConstructor_declaringFormalParameter_simple_const() { var parseResult = parseStringWithErrors(r''' class A(const int a) {} +// ^^^^^ +// [diag.extraneousModifier] Can't have modifier 'const' here. '''); - parseResult.assertErrors([error(diag.extraneousModifier, 8, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2272,7 +2292,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(final int a) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2301,7 +2321,7 @@ class A( final int a ) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2330,7 +2350,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(var int a) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2356,7 +2376,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(final int this.a) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2384,7 +2404,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(var int this.a) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2411,10 +2431,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_named_keyword_required_covariant() { var parseResult = parseStringWithErrors(r''' class A({required covariant int it}) {} +// ^^^^^^^^^ +// [diag.invalidCovariantModifierInPrimaryConstructor] The 'covariant' modifier can only be used on non-final declaring parameters. '''); - parseResult.assertErrors([ - error(diag.invalidCovariantModifierInPrimaryConstructor, 18, 9), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2442,10 +2462,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_named_keyword_required_covariant_final() { var parseResult = parseStringWithErrors(r''' class A({required covariant final int it}) {} +// ^^^^^^^^^ +// [diag.invalidCovariantModifierInPrimaryConstructor] The 'covariant' modifier can only be used on non-final declaring parameters. '''); - parseResult.assertErrors([ - error(diag.invalidCovariantModifierInPrimaryConstructor, 18, 9), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2475,7 +2495,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A({required covariant var int it}) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2504,8 +2524,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_named_keyword_required_required() { var parseResult = parseStringWithErrors(r''' class A({required required int a}) {} +// ^^^^^^^^ +// [diag.duplicatedModifier] The modifier 'required' was already specified. '''); - parseResult.assertErrors([error(diag.duplicatedModifier, 18, 8)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2532,8 +2554,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_named_keyword_required_required_covariant_var() { var parseResult = parseStringWithErrors(r''' class A({required required covariant var int a}) {} +// ^^^^^^^^ +// [diag.duplicatedModifier] The modifier 'required' was already specified. '''); - parseResult.assertErrors([error(diag.duplicatedModifier, 18, 8)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2562,10 +2586,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_positional_keyword_covariant() { var parseResult = parseStringWithErrors(r''' class A(covariant int it) {} +// ^^^^^^^^^ +// [diag.invalidCovariantModifierInPrimaryConstructor] The 'covariant' modifier can only be used on non-final declaring parameters. '''); - parseResult.assertErrors([ - error(diag.invalidCovariantModifierInPrimaryConstructor, 8, 9), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2590,10 +2614,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_positional_keyword_covariant_final() { var parseResult = parseStringWithErrors(r''' class A(covariant final int it) {} +// ^^^^^^^^^ +// [diag.invalidCovariantModifierInPrimaryConstructor] The 'covariant' modifier can only be used on non-final declaring parameters. '''); - parseResult.assertErrors([ - error(diag.invalidCovariantModifierInPrimaryConstructor, 8, 9), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2620,7 +2644,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A(covariant var int it) {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2646,8 +2670,10 @@ ClassDeclaration test_primaryConstructor_formalParameters_positional_keyword_required() { var parseResult = parseStringWithErrors(r''' class A(required int a) {} +// ^^^^^^^^ +// [diag.extraneousModifier] Can't have modifier 'required' here. '''); - parseResult.assertErrors([error(diag.extraneousModifier, 8, 8)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2673,7 +2699,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A.named() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2705,7 +2731,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2734,7 +2760,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A.named() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2758,7 +2784,7 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A() {} '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2780,7 +2806,7 @@ ClassDeclaration class A(final int super.a) {} '''); // TODO(scheglov): this is wrong. - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2807,8 +2833,10 @@ ClassDeclaration test_primaryConstructor_superFormalParameter_var_namedType() { var parseResult = parseStringWithErrors(r''' class A(var int super.a) {} +// ^^^ +// [diag.extraneousModifier] Can't have modifier 'var' here. '''); - parseResult.assertErrors([error(diag.extraneousModifier, 8, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleClassDeclaration; assertParsedNodeText(node, r''' @@ -2838,7 +2866,7 @@ class A(final int x) { this : assert(x > 0); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2869,7 +2897,7 @@ class A() { } } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2895,7 +2923,7 @@ class A() { this; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2917,7 +2945,7 @@ class A() { this : x = 0; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2943,7 +2971,7 @@ class A() { this; } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2963,9 +2991,11 @@ PrimaryConstructorBody var parseResult = parseStringWithErrors(r''' class A() { const this; +//^^^^^ +// [diag.extraneousModifier] Can't have modifier 'const' here. } '''); - parseResult.assertErrors([error(diag.extraneousModifier, 14, 5)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singlePrimaryConstructorBody; assertParsedNodeText(node, r''' @@ -2982,7 +3012,7 @@ augment class A { augment set foo(int x) {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -3017,7 +3047,7 @@ augment class A { augment static set foo(int x) {} } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); assertParsedNodeText(parseResult.findNode.singleClassDeclaration, r''' ClassDeclaration augmentKeyword: augment @@ -3051,9 +3081,11 @@ ClassDeclaration var parseResult = parseStringWithErrors(r''' class A { set foo {} +// ^^^ +// [diag.missingMethodParameters] Methods must have an explicit list of parameters. } '''); - parseResult.assertErrors([error(diag.missingMethodParameters, 16, 3)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, withOffsets: true, r''' @@ -3076,11 +3108,11 @@ MethodDeclaration var parseResult = parseStringWithErrors(r''' class A { set foo({a}) {} +// ^^^ +// [diag.wrongNumberOfParametersForSetter] Setters must declare exactly one required positional parameter. } '''); - parseResult.assertErrors([ - error(diag.wrongNumberOfParametersForSetter, 16, 3), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, withOffsets: true, r''' @@ -3103,11 +3135,11 @@ MethodDeclaration var parseResult = parseStringWithErrors(r''' class A { set foo([a]) {} +// ^^^ +// [diag.wrongNumberOfParametersForSetter] Setters must declare exactly one required positional parameter. } '''); - parseResult.assertErrors([ - error(diag.wrongNumberOfParametersForSetter, 16, 3), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, withOffsets: true, r''' @@ -3130,11 +3162,11 @@ MethodDeclaration var parseResult = parseStringWithErrors(r''' class A { set foo(a, b, c) {} +// ^^^ +// [diag.wrongNumberOfParametersForSetter] Setters must declare exactly one required positional parameter. } '''); - parseResult.assertErrors([ - error(diag.wrongNumberOfParametersForSetter, 16, 3), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, withOffsets: true, r''' @@ -3157,11 +3189,11 @@ MethodDeclaration var parseResult = parseStringWithErrors(r''' class A { set foo() {} +// ^^^ +// [diag.wrongNumberOfParametersForSetter] Setters must declare exactly one required positional parameter. } '''); - parseResult.assertErrors([ - error(diag.wrongNumberOfParametersForSetter, 16, 3), - ]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, withOffsets: true, r''' @@ -3186,7 +3218,7 @@ class A { static set foo(int _); } '''); - parseResult.assertNoErrors(); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' @@ -3207,13 +3239,15 @@ MethodDeclaration } test_setter_static_body_empty_language305() { - var parseResult = parseStringWithErrors(''' + var parseResult = parseStringWithErrors(r''' // @dart = 3.5 class A { static set foo(int _); +// ^ +// [diag.missingFunctionBody] A function body must be provided. } '''); - parseResult.assertErrors([error(diag.missingFunctionBody, 48, 1)]); + parseResult.assertExpectedDiagnostics(); var node = parseResult.findNode.singleMethodDeclaration; assertParsedNodeText(node, r''' diff --git a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart index 55771c486f5..0ba3e24f287 100644 --- a/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart +++ b/pkg/analyzer/test/src/diagnostics/parser_diagnostics.dart @@ -10,6 +10,8 @@ import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/test_utilities/find_node.dart'; import 'package:analyzer_testing/src/analysis_rule/pub_package_resolution.dart'; +import 'package:analyzer_testing/src/expected_diagnostics.dart' + as expected_diagnostics; import 'package:analyzer_utilities/testing/tree_string_sink.dart'; import 'package:test/test.dart'; @@ -113,6 +115,17 @@ extension ParseStringResultExtension on ParseStringResult { diagnosticListener.assertErrors(expectedDiagnostics); } + void assertExpectedDiagnostics() { + var actual = expected_diagnostics.updateExpectedDiagnostics( + content: content, + actualDiagnostics: errors, + ); + if (actual != content) { + printPrettyDiff(content, actual); + fail('See the difference above.'); + } + } + void assertNoErrors() { assertErrors(const []); } diff --git a/pkg/analyzer_testing/lib/src/expected_diagnostics.dart b/pkg/analyzer_testing/lib/src/expected_diagnostics.dart new file mode 100644 index 00000000000..189c9940e16 --- /dev/null +++ b/pkg/analyzer_testing/lib/src/expected_diagnostics.dart @@ -0,0 +1,425 @@ +// Copyright (c) 2026, 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/diagnostic/diagnostic.dart'; +import 'package:analyzer/source/line_info.dart'; +import 'package:analyzer_testing/utilities/extensions/diagnostic_code.dart'; + +/// Returns [content] with canonical diagnostic expectation markers. +/// +/// Existing diagnostic expectation marker lines are removed before the new +/// markers are inserted, so [content] can be either unmarked or already marked. +String updateExpectedDiagnostics({ + required String content, + required List actualDiagnostics, +}) { + return _ExpectedDiagnosticsUpdater(content).update(actualDiagnostics); +} + +final class _ExpectedDiagnosticsUpdater { + final List<_Line> lines; + final LineInfo lineInfo; + final Map> markersByLine = {}; + + int nextMarkerIndex = 0; + int nextContextId = 1; + + _ExpectedDiagnosticsUpdater(String content) + : lines = _Line.parse(content), + lineInfo = LineInfo.fromContent(content); + + String update(List actualDiagnostics) { + _generateMarkers(actualDiagnostics); + return _writeContent(); + } + + void _addMarker(int lineNumber, _GeneratedMarker marker) { + markersByLine.putIfAbsent(lineNumber, () => []).add(marker); + } + + /// Builds a caret marker line for a one-based [column] and [length]. + String _caretLine(int column, int length) { + return '//${' ' * (column - 3)}${'^' * length}'; + } + + void _generateDiagnosticMarkers(Diagnostic diagnostic) { + var contextRefs = []; + for (var contextMessage in diagnostic.contextMessages) { + if (contextMessage.filePath != diagnostic.problemMessage.filePath) { + // TODO(scheglov): Support generating expectations for context + // messages in other files. + throw StateError( + 'Cannot generate a diagnostic expectation with a context message ' + 'in another file.', + ); + } + + var id = nextContextId++; + contextRefs.add(id); + var location = _markerLocation( + offset: contextMessage.offset, + length: contextMessage.length, + ); + var line = lines[location.lineNumber - 1]; + var presentation = _markerPresentation( + line, + column: location.column, + length: contextMessage.length, + ); + _addMarker( + location.lineNumber, + _GeneratedMarker.context( + offset: contextMessage.offset, + index: nextMarkerIndex++, + id: id, + column: location.column, + length: contextMessage.length, + caretLength: presentation.caretLength, + includeExplicitLocation: presentation.includeExplicitLocation, + message: contextMessage.messageText(includeUrl: false), + ), + ); + } + + var location = _markerLocation( + offset: diagnostic.offset, + length: diagnostic.length, + ); + var line = lines[location.lineNumber - 1]; + var presentation = _markerPresentation( + line, + column: location.column, + length: diagnostic.length, + ); + _addMarker( + location.lineNumber, + _GeneratedMarker.diagnostic( + offset: diagnostic.offset, + index: nextMarkerIndex++, + constantName: diagnostic.diagnosticCode.constantName, + column: location.column, + length: diagnostic.length, + caretLength: presentation.caretLength, + includeExplicitLocation: presentation.includeExplicitLocation, + contextRefs: contextRefs, + message: diagnostic.problemMessage.messageText(includeUrl: false), + ), + ); + } + + void _generateMarkers(List actualDiagnostics) { + var sortedDiagnostics = actualDiagnostics.toList() + ..sort((first, second) => first.offset.compareTo(second.offset)); + for (var diagnostic in sortedDiagnostics) { + _generateDiagnosticMarkers(diagnostic); + } + } + + /// Returns where a generated marker should be written for an actual range. + /// + /// For a normal diagnostic range, the marker belongs on the line reported by + /// [LineInfo]. For a zero-length diagnostic, the diagnostic is often an + /// insertion point rather than a source span. If the input is already + /// marked, that insertion point can be pushed into the existing marker + /// comments, or to the empty line after them, even though the marker should + /// still be attached to the preceding real source line. In that case, keep + /// the marker on the source line and express the insertion point as the + /// column after its last character. + ({int lineNumber, int column}) _markerLocation({ + required int offset, + required int length, + }) { + var location = lineInfo.getLocation(offset); + if (length == 0) { + // Only zero-length diagnostics can legitimately move onto marker-only + // text from a previous update. A non-zero range on a marker line would + // describe the marker comment itself, not an insertion point in code. + var targetLine = _targetLineForMarkerShift(location.lineNumber); + if (targetLine != null) { + return ( + lineNumber: targetLine.number, + column: targetLine.text.length + 1, + ); + } + } + return (lineNumber: location.lineNumber, column: location.columnNumber); + } + + /// Returns how [column] and [length] should be shown after [line]. + /// + /// Caret lines start with `//`, so columns 1 and 2 cannot be represented. A + /// zero-length range may still use a one-character caret as a visual anchor, + /// but must keep explicit `[column ...][length 0]` metadata. + ({int? caretLength, bool includeExplicitLocation}) _markerPresentation( + _Line line, { + required int column, + required int length, + }) { + int? caretLength; + if (column > 2) { + if (length == 0 && column <= line.text.length + 1) { + caretLength = 1; + } else if (length > 0 && column + length - 1 <= line.text.length) { + caretLength = length; + } + } + + return ( + caretLength: caretLength, + includeExplicitLocation: caretLength != length, + ); + } + + /// Finds the real source line that owns a shifted zero-length marker. + /// + /// The updater accepts both clean source and source that already contains + /// diagnostic expectation comments. Existing marker comments are removed when + /// the new content is written, but actual diagnostics are computed before + /// that removal. This matters for zero-length diagnostics near the end of a + /// line or file: after a previous update, the analyzer may report the same + /// insertion point as being on a marker line, or on the empty line + /// immediately following marker lines. + /// + /// This method recognizes only those shifted positions. If [lineNumber] + /// points at ordinary source text, or at an empty line that is not directly + /// after a marker, there is nothing to repair and `null` is returned. + /// Otherwise the search walks backward over marker lines and returns the + /// nearest preceding non-marker line, which is where the regenerated marker + /// should be attached. + _Line? _targetLineForMarkerShift(int lineNumber) { + if (lineNumber < 1 || lineNumber > lines.length) { + return null; + } + + var line = lines[lineNumber - 1]; + if (!_LineMarker.isMarker(line)) { + // A non-marker line normally owns the reported offset. The one exception + // is the synthetic empty line after existing markers, which can be where + // EOF-style zero-length diagnostics land. + var previousLine = lineNumber > 1 ? lines[lineNumber - 2] : null; + if (line.text.isNotEmpty || + previousLine == null || + !_LineMarker.isMarker(previousLine)) { + return null; + } + } + + // The reported line is either a marker line or the empty line just after + // marker lines. Walk back to the line these markers annotate. + for (var index = lineNumber - 2; index >= 0; index--) { + var previousLine = lines[index]; + if (!_LineMarker.isMarker(previousLine)) { + return previousLine; + } + } + return null; + } + + String _writeContent() { + var buffer = StringBuffer(); + var isFirstLine = true; + for (var line in lines) { + if (_LineMarker.isMarker(line)) { + continue; + } + + if (isFirstLine) { + isFirstLine = false; + } else { + buffer.writeln(); + } + buffer.write(line.text); + + var markers = markersByLine[line.number]; + if (markers != null) { + markers.sort(_GeneratedMarker.compare); + ({int column, int length})? currentCaret; + for (var marker in markers) { + if (marker.caretLength case var caretLength?) { + var markerCaret = (column: marker.column, length: caretLength); + if (markerCaret != currentCaret) { + buffer.writeln(); + buffer.write(_caretLine(marker.column, caretLength)); + currentCaret = markerCaret; + } + } + buffer.writeln(); + buffer.write(marker.expectationText); + } + } + } + return buffer.toString(); + } +} + +/// Generated expectation marker text for one diagnostic or context message. +final class _GeneratedMarker { + /// The zero-based offset of the diagnostic or context message being marked. + final int offset; + + /// The marker kind, used as a stable secondary sort key. + final _GeneratedMarkerKind kind; + + /// The order in which this marker was generated. + final int index; + + /// The one-based column of the diagnostic or context message range. + final int column; + + /// The length of the visual caret marker, or `null` if none should be shown. + /// + /// For zero-length diagnostics, a one-character caret is useful as a visual + /// anchor, but the exact `[column ...][length 0]` metadata must still be + /// emitted. + final int? caretLength; + + /// The expectation comment inserted after the target line. + final String expectationText; + + /// Creates a marker for a diagnostic context message. + factory _GeneratedMarker.context({ + required int offset, + required int index, + required int id, + required int column, + required int length, + required int? caretLength, + required bool includeExplicitLocation, + required String message, + }) { + var buffer = StringBuffer(); + buffer.write('// [context $id]'); + if (includeExplicitLocation) { + buffer.write('[column $column][length $length]'); + } + buffer.write(' $message'); + + return _GeneratedMarker._( + offset: offset, + kind: _GeneratedMarkerKind.context, + index: index, + column: column, + caretLength: caretLength, + expectationText: buffer.toString(), + ); + } + + /// Creates a marker for a diagnostic. + factory _GeneratedMarker.diagnostic({ + required int offset, + required int index, + required String constantName, + required int column, + required int length, + required int? caretLength, + required bool includeExplicitLocation, + required List contextRefs, + required String message, + }) { + var buffer = StringBuffer(); + buffer.write('// [$constantName]'); + if (includeExplicitLocation) { + buffer.write('[column $column][length $length]'); + } + for (var id in contextRefs) { + buffer.write('[context $id]'); + } + buffer.write(' $message'); + + return _GeneratedMarker._( + offset: offset, + kind: _GeneratedMarkerKind.diagnostic, + index: index, + column: column, + caretLength: caretLength, + expectationText: buffer.toString(), + ); + } + + _GeneratedMarker._({ + required this.offset, + required this.kind, + required this.index, + required this.column, + required this.caretLength, + required this.expectationText, + }); + + /// Orders generated markers in the order they should appear after a line. + static int compare(_GeneratedMarker first, _GeneratedMarker second) { + var offsetResult = first.offset.compareTo(second.offset); + if (offsetResult != 0) { + return offsetResult; + } + var kindResult = first.kind.index.compareTo(second.kind.index); + if (kindResult != 0) { + return kindResult; + } + return first.index.compareTo(second.index); + } +} + +enum _GeneratedMarkerKind { context, diagnostic } + +/// A line of text in the input content. +final class _Line { + /// The one-based line number in the input content. + final int number; + + /// The line text without the trailing newline characters. + final String text; + + _Line({required this.number, required this.text}); + + /// Splits [content] into lines while preserving each line's offset. + /// + /// Lines may end with `\r`, `\n`, or `\r\n`. The newline characters are not + /// included in [text], but they still contribute to offsets in [content]. + static List<_Line> parse(String content) { + var result = <_Line>[]; + var lineStart = 0; + var lineNumber = 1; + + for (var index = 0; index < content.length; index++) { + var codeUnit = content.codeUnitAt(index); + if (codeUnit == 0x0D || codeUnit == 0x0A) { + result.add( + _Line( + number: lineNumber++, + text: content.substring(lineStart, index), + ), + ); + + // Consume the `\n` in a `\r\n` line break. + if (codeUnit == 0x0D && + index + 1 < content.length && + content.codeUnitAt(index + 1) == 0x0A) { + index++; + } + lineStart = index + 1; + } + } + + result.add(_Line(number: lineNumber, text: content.substring(lineStart))); + return result; + } +} + +abstract final class _LineMarker { + /// Matches a caret marker line such as `// ^^^`. + static final _caretPattern = RegExp(r'^[ \t]*//[ \t]*\^+[ \t]*$'); + + /// Matches generated expectation comments for diagnostics and contexts. + /// + /// The updater only needs to recognize lines to remove before regeneration. + /// It intentionally does not validate the full marker syntax. + static final _expectationPattern = RegExp( + r'^[ \t]*//[ \t]*\[(?:diag\.[A-Za-z_][A-Za-z0-9_]*|context[ \t]+[0-9]+)\]', + ); + + static bool isMarker(_Line line) { + return _caretPattern.hasMatch(line.text) || + _expectationPattern.hasMatch(line.text); + } +} diff --git a/pkg/test_runner/lib/src/test_file.dart b/pkg/test_runner/lib/src/test_file.dart index 154150f5b94..47a4e5a99a0 100644 --- a/pkg/test_runner/lib/src/test_file.dart +++ b/pkg/test_runner/lib/src/test_file.dart @@ -345,12 +345,18 @@ class TestFile extends _TestFileBase { } var errorExpectations = []; - try { - errorExpectations.addAll(_parseExpectations(filePath)); - } on FormatException catch (error) { - throw FormatException( - "Invalid error expectation syntax in $filePath:\n$error", - ); + + // The analyzer package also uses a similar syntax for expectations, but + // we don't want the test_runner to inadvertently think files containing + // those are static error tests. + if (!filePath.replaceAll('\\', '/').contains('/pkg/analyzer/')) { + try { + errorExpectations.addAll(_parseExpectations(filePath)); + } on FormatException catch (error) { + throw FormatException( + "Invalid error expectation syntax in $filePath:\n$error", + ); + } } return TestFile._(