Add support for testing the context messages for diagnostics
Change-Id: I33d4abc0dcc969f3beecfdc7cbc814e8a486ad1c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107142
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 3ce5fe3..f95a185 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart' show LibraryElement;
-import 'package:analyzer/diagnostic/diagnostic.dart' as diagnostic;
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
@@ -1737,7 +1736,7 @@
errorCode,
error.message,
error.correction.isEmpty ? null : error.correction,
- contextMessages: contextMessages));
+ contextMessages: contextMessages ?? const []));
}
}
return errors;
diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
index 7b359dd..c742828 100644
--- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
+++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart
@@ -44,6 +44,6 @@
identifier.length,
CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION,
[name],
- contextMessages);
+ contextMessages ?? const []);
}
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 181575f..3057230 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -4723,7 +4723,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+ expectedMessages: [message('/test/lib/test.dart', 34, 1)]),
]);
}
@@ -4736,7 +4737,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 28, 1,
+ expectedMessages: [message('/test/lib/test.dart', 38, 1)]),
]);
}
@@ -4751,7 +4753,8 @@
}
print(x) {}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 34, 1,
+ expectedMessages: [message('/test/lib/test.dart', 48, 1)]),
]);
}
@@ -4761,7 +4764,8 @@
var v = () => v;
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 25, 1,
+ expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
]);
}
@@ -4771,7 +4775,8 @@
var v = v;
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 19, 1,
+ expectedMessages: [message('/test/lib/test.dart', 15, 1)]),
]);
}
@@ -4783,7 +4788,8 @@
print(s + String);
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+ expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
]);
}
@@ -4795,7 +4801,8 @@
print(s + String);
}
''', [
- error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6),
+ error(CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, 23, 6,
+ expectedMessages: [message('/test/lib/test.dart', 44, 6)]),
]);
}
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 25a512d..b795962 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
@@ -118,15 +119,61 @@
/// The offset of the beginning of the error's region.
final int length;
+ /// The list of context messages that are expected to be associated with the
+ /// error.
+ final List<ExpectedMessage> expectedMessages;
+
/// Initialize a newly created error description.
- ExpectedError(this.code, this.offset, this.length);
+ ExpectedError(this.code, this.offset, this.length,
+ {this.expectedMessages = const <ExpectedMessage>[]});
/// Return `true` if the [error] matches this description of what it's
/// expected to be.
bool matches(AnalysisError error) {
- return error.offset == offset &&
- error.length == length &&
- error.errorCode == code;
+ if (error.offset != offset ||
+ error.length != length ||
+ error.errorCode != code) {
+ return false;
+ }
+ List<DiagnosticMessage> contextMessages = error.contextMessages.toList();
+ contextMessages.sort((first, second) {
+ int result = first.filePath.compareTo(second.filePath);
+ if (result != 0) {
+ return result;
+ }
+ return second.offset - first.offset;
+ });
+ if (contextMessages.length != expectedMessages.length) {
+ return false;
+ }
+ for (int i = 0; i < expectedMessages.length; i++) {
+ if (!expectedMessages[i].matches(contextMessages[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+/// A description of a message that is expected to be reported with an error.
+class ExpectedMessage {
+ /// The path of the file with which the message is associated.
+ final String filePath;
+
+ /// The offset of the beginning of the error's region.
+ final int offset;
+
+ /// The offset of the beginning of the error's region.
+ final int length;
+
+ ExpectedMessage(this.filePath, this.offset, this.length);
+
+ /// Return `true` if the [message] matches this description of what it's
+ /// expected to be.
+ bool matches(DiagnosticMessage message) {
+ return message.filePath == filePath &&
+ message.offset == offset &&
+ message.length == length;
}
}
@@ -227,12 +274,30 @@
buffer.writeln();
buffer.writeln('To accept the current state, expect:');
for (AnalysisError actual in errors) {
+ List<DiagnosticMessage> contextMessages = actual.contextMessages;
buffer.write(' error(');
buffer.write(actual.errorCode);
buffer.write(', ');
buffer.write(actual.offset);
buffer.write(', ');
buffer.write(actual.length);
+ if (contextMessages.isNotEmpty) {
+ buffer.write(', expectedMessages: [');
+ for (int i = 0; i < contextMessages.length; i++) {
+ DiagnosticMessage message = contextMessages[i];
+ if (i > 0) {
+ buffer.write(', ');
+ }
+ buffer.write('message(resourceProvider.convertPath(\'');
+ buffer.write(message.filePath);
+ buffer.write('\'), ');
+ buffer.write(message.offset);
+ buffer.write(', ');
+ buffer.write(message.length);
+ buffer.write(')');
+ }
+ buffer.write(']');
+ }
buffer.writeln('),');
}
fail(buffer.toString());
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 56deafe..4040944 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -419,8 +419,10 @@
expect(node.staticType, isNull);
}
- ExpectedError error(ErrorCode code, int offset, int length) =>
- new ExpectedError(code, offset, length);
+ ExpectedError error(ErrorCode code, int offset, int length,
+ {List<ExpectedMessage> expectedMessages =
+ const <ExpectedMessage>[]}) =>
+ ExpectedError(code, offset, length, expectedMessages: expectedMessages);
Element getNodeElement(AstNode node) {
if (node is Annotation) {
@@ -450,6 +452,9 @@
}
}
+ ExpectedMessage message(String filePath, int offset, int length) =>
+ ExpectedMessage(convertPath(filePath), offset, length);
+
Future<ResolvedUnitResult> resolveFile(String path);
Future<void> resolveTestFile() async {