Fix JsonErrorFormatter to use right LineInfo for context messages.
Change-Id: Icd9e254308a54e47ea3be63220ada5fd028712e7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500660 Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
@@ -8,7 +8,6 @@ import 'package:analyzer/dart/analysis/results.dart';
|
||||
import 'package:analyzer/diagnostic/diagnostic.dart';
|
||||
import 'package:analyzer/error/error.dart';
|
||||
import 'package:analyzer/source/line_info.dart';
|
||||
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
|
||||
import 'package:analyzer_cli/src/ansi.dart';
|
||||
import 'package:analyzer_cli/src/options.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
@@ -223,6 +222,12 @@ abstract class ErrorFormatter {
|
||||
/// be filtered.
|
||||
DiagnosticSeverity? _computeSeverity(Diagnostic diagnostic) =>
|
||||
_severityProcessor(diagnostic);
|
||||
|
||||
// TODO(scheglov): We should add `LineInfo` to `DiagnosticMessage`.
|
||||
LineInfo _getLineInfo(ErrorsResult result, String filePath) {
|
||||
var fileResult = result.session.getFile(filePath) as FileResult;
|
||||
return fileResult.lineInfo;
|
||||
}
|
||||
}
|
||||
|
||||
class HumanErrorFormatter extends ErrorFormatter {
|
||||
@@ -322,23 +327,16 @@ class HumanErrorFormatter extends ErrorFormatter {
|
||||
}
|
||||
var contextMessages = <ContextMessage>[];
|
||||
for (var message in error.contextMessages) {
|
||||
// TODO(scheglov): We should add `LineInfo` to `DiagnosticMessage`.
|
||||
var session = result.session.analysisContext;
|
||||
if (session is DriverBasedAnalysisContext) {
|
||||
var fileResult = session.driver.getFileSync(message.filePath);
|
||||
if (fileResult is FileResult) {
|
||||
var lineInfo = fileResult.lineInfo;
|
||||
var location = lineInfo.getLocation(message.offset);
|
||||
contextMessages.add(
|
||||
ContextMessage(
|
||||
message.filePath,
|
||||
message.messageText(includeUrl: true),
|
||||
location.lineNumber,
|
||||
location.columnNumber,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
var lineInfo = _getLineInfo(result, message.filePath);
|
||||
var location = lineInfo.getLocation(message.offset);
|
||||
contextMessages.add(
|
||||
ContextMessage(
|
||||
message.filePath,
|
||||
message.messageText(includeUrl: true),
|
||||
location.lineNumber,
|
||||
location.columnNumber,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
batchedErrors.add(
|
||||
@@ -413,9 +411,7 @@ class JsonErrorFormatter extends ErrorFormatter {
|
||||
|
||||
var diagnostics = <Map<String, dynamic>>[];
|
||||
for (var result in results) {
|
||||
var errors = result.diagnostics;
|
||||
var lineInfo = result.lineInfo;
|
||||
for (var error in errors) {
|
||||
for (var error in result.diagnostics) {
|
||||
var severity = _computeSeverity(error);
|
||||
if (severity == null) {
|
||||
continue;
|
||||
@@ -427,7 +423,7 @@ class JsonErrorFormatter extends ErrorFormatter {
|
||||
contextMessage.filePath,
|
||||
contextMessage.offset,
|
||||
contextMessage.length,
|
||||
lineInfo,
|
||||
_getLineInfo(result, contextMessage.filePath),
|
||||
),
|
||||
'message': contextMessage.messageText(includeUrl: true),
|
||||
});
|
||||
@@ -443,7 +439,7 @@ class JsonErrorFormatter extends ErrorFormatter {
|
||||
problemMessage.filePath,
|
||||
problemMessage.offset,
|
||||
problemMessage.length,
|
||||
lineInfo,
|
||||
result.lineInfo,
|
||||
),
|
||||
'problemMessage': problemMessage.messageText(includeUrl: true),
|
||||
if (error.correctionMessage != null)
|
||||
|
||||
@@ -34,6 +34,48 @@ class ReporterTest extends PubPackageResolutionTest {
|
||||
await super.tearDown();
|
||||
}
|
||||
|
||||
Future<void> test_human_contextMessage_otherFile() async {
|
||||
var options = CommandLineOptions.parse(resourceProvider, [
|
||||
'--dart-sdk=${sdkRoot.path}',
|
||||
'--verbose',
|
||||
'test.dart',
|
||||
])!;
|
||||
var reporter = HumanErrorFormatter(out, options, stats);
|
||||
|
||||
var libFile = newFile('$testPackageRootPath/lib/lib.dart', r'''
|
||||
class C {
|
||||
final int? foo;
|
||||
C(this.foo);
|
||||
}
|
||||
''');
|
||||
|
||||
newFile(testFile.path, r'''
|
||||
import 'lib.dart';
|
||||
void f(C c) {
|
||||
if (c.foo != null) {
|
||||
c.foo.isEven;
|
||||
}
|
||||
}
|
||||
''');
|
||||
|
||||
var errorsResult = await _getErrorsResultForFile(testFile);
|
||||
await reporter.formatErrors([errorsResult]);
|
||||
reporter.flush();
|
||||
|
||||
expect(
|
||||
out.toString().trim(),
|
||||
contains(
|
||||
"error • The property 'isEven' can't be unconditionally accessed because the receiver can be 'null'. • package:test/test.dart:4:11 • unchecked_use_of_nullable_value",
|
||||
),
|
||||
);
|
||||
expect(
|
||||
out.toString().trim(),
|
||||
contains(
|
||||
" 'foo' refers to a public property so it couldn't be promoted. See http://dart.dev/go/non-promo-public-field at ${libFile.path}:2:14",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_human_error() async {
|
||||
var options = CommandLineOptions.parse(resourceProvider, [
|
||||
'--dart-sdk=${sdkRoot.path}',
|
||||
@@ -107,6 +149,73 @@ void f() {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> test_json_contextMessage_otherFile() async {
|
||||
var options = CommandLineOptions.parse(resourceProvider, [
|
||||
'--format=json',
|
||||
'--dart-sdk=${sdkRoot.path}',
|
||||
'test.dart',
|
||||
])!;
|
||||
var reporter = JsonErrorFormatter(out, options, stats);
|
||||
|
||||
var libFile = newFile('$testPackageRootPath/lib/lib.dart', r'''
|
||||
class C {
|
||||
final int? foo;
|
||||
C(this.foo);
|
||||
}
|
||||
''');
|
||||
|
||||
newFile(testFile.path, r'''
|
||||
import 'lib.dart';
|
||||
void f(C c) {
|
||||
if (c.foo != null) {
|
||||
c.foo.isEven;
|
||||
}
|
||||
}
|
||||
''');
|
||||
|
||||
var errorsResult = await _getErrorsResultForFile(testFile);
|
||||
await reporter.formatErrors([errorsResult]);
|
||||
reporter.flush();
|
||||
|
||||
var expected = {
|
||||
'version': 1,
|
||||
'diagnostics': [
|
||||
{
|
||||
'code': 'unchecked_use_of_nullable_value',
|
||||
'severity': 'ERROR',
|
||||
'type': 'COMPILE_TIME_ERROR',
|
||||
'location': {
|
||||
'file': testFile.path,
|
||||
'range': {
|
||||
'start': {'offset': 66, 'line': 4, 'column': 11},
|
||||
'end': {'offset': 72, 'line': 4, 'column': 17},
|
||||
},
|
||||
},
|
||||
'problemMessage':
|
||||
"The property 'isEven' can't be unconditionally accessed because the receiver can be 'null'.",
|
||||
'correctionMessage':
|
||||
"Try making the access conditional (using '?.') or adding a null check to the target ('!').",
|
||||
'contextMessages': [
|
||||
{
|
||||
'location': {
|
||||
'file': libFile.path,
|
||||
'range': {
|
||||
'start': {'offset': 23, 'line': 2, 'column': 14},
|
||||
'end': {'offset': 26, 'line': 2, 'column': 17},
|
||||
},
|
||||
},
|
||||
'message':
|
||||
"'foo' refers to a public property so it couldn't be promoted. See http://dart.dev/go/non-promo-public-field",
|
||||
},
|
||||
],
|
||||
'documentation':
|
||||
'https://dart.dev/diagnostics/unchecked_use_of_nullable_value',
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(json.decode(out.toString().trim()), expected);
|
||||
}
|
||||
|
||||
Future<void> test_json_error() async {
|
||||
var options = CommandLineOptions.parse(resourceProvider, [
|
||||
'--format=json',
|
||||
|
||||
Reference in New Issue
Block a user