[CFE] Special case StrongModeNNBDPackageOptOut message in IncrementalCompiler
This CL fixes the wrong message, so - when in the process of fixing
the package nnbd settings - one gets the correct message, mentioning the
right packages and no longer mentioning the fixed ones.
Change-Id: Ied26094055e56b44dfdd2e942b98eb9e1e7968fb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170423
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
index bc0393d..5d95d3b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
@@ -183,6 +183,8 @@
Code<dynamic> get code => locatedMessage.code;
+ String get codeName => code.name;
+
String get message => locatedMessage.message;
String get tip => locatedMessage.tip;
@@ -219,6 +221,7 @@
"severity": severity.index,
"uri": uri?.toString(),
"involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
+ "codeName": code.name,
};
}
@@ -242,8 +245,10 @@
final List<Uri> involvedFiles;
+ final String codeName;
+
DiagnosticMessageFromJson(this.ansiFormatted, this.plainTextFormatted,
- this.severity, this.uri, this.involvedFiles);
+ this.severity, this.uri, this.involvedFiles, this.codeName);
factory DiagnosticMessageFromJson.fromJson(String jsonString) {
Map<String, Object> decoded = json.decode(jsonString);
@@ -258,9 +263,10 @@
: new List<String>.from(decoded["involvedFiles"])
.map((e) => Uri.parse(e))
.toList();
+ String codeName = decoded["codeName"];
- return new DiagnosticMessageFromJson(
- ansiFormatted, plainTextFormatted, severity, uri, involvedFiles);
+ return new DiagnosticMessageFromJson(ansiFormatted, plainTextFormatted,
+ severity, uri, involvedFiles, codeName);
}
Map<String, Object> toJson() {
@@ -271,6 +277,7 @@
"severity": severity.index,
"uri": uri?.toString(),
"involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
+ "codeName": codeName,
};
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart b/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
index 3d83aa9..7146258 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
@@ -36,6 +36,8 @@
Severity get severity;
Iterable<Uri> get involvedFiles;
+
+ String get codeName;
}
/// This method is subject to change.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 7af91d2..906d131 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -8,6 +8,7 @@
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:front_end/src/base/nnbd_mode.dart';
import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/fasta/source/source_loader.dart';
import 'package:kernel/binary/ast_from_binary.dart'
show
BinaryBuilderWithMetadata,
@@ -1379,15 +1380,41 @@
}
// Report old problems that wasn't reported again.
- for (List<DiagnosticMessageFromJson> messages
- in remainingComponentProblems.values) {
+ Set<Uri> strongModeNNBDPackageOptOutUris;
+ for (MapEntry<Uri, List<DiagnosticMessageFromJson>> entry
+ in remainingComponentProblems.entries) {
+ List<DiagnosticMessageFromJson> messages = entry.value;
for (int i = 0; i < messages.length; i++) {
DiagnosticMessageFromJson message = messages[i];
+ if (message.codeName == "StrongModeNNBDPackageOptOut") {
+ // Special case this: Don't issue them here; instead collect them
+ // to get their uris and re-issue a new error.
+ strongModeNNBDPackageOptOutUris ??= {};
+ strongModeNNBDPackageOptOutUris.add(entry.key);
+ continue;
+ }
if (issuedProblems.add(message.toJsonString())) {
context.options.reportDiagnosticMessage(message);
}
}
}
+ if (strongModeNNBDPackageOptOutUris != null) {
+ // Get the builders for these uris; then call
+ // `SourceLoader.giveCombinedErrorForNonStrongLibraries` on them to issue
+ // a new error.
+ Set<LibraryBuilder> builders = {};
+ SourceLoader loader = userCode.loader;
+ for (LibraryBuilder builder in loader.builders.values) {
+ if (strongModeNNBDPackageOptOutUris.contains(builder.fileUri)) {
+ builders.add(builder);
+ }
+ }
+ FormattedMessage message = loader.giveCombinedErrorForNonStrongLibraries(
+ builders,
+ emitNonPackageErrors: false);
+ issuedProblems.add(message.toJsonString());
+ // The problem was issued by the call so don't re-issue it here.
+ }
// Save any new component-problems.
_addProblemsAsJsonToRemainingProblems(componentWithDill?.problemsAsJson);
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 49d78f4..e5c9010 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -355,61 +355,9 @@
// config we include each library uri in the message. For non-package
// libraries with no corresponding package config we generate a message
// per library.
- Map<String, List<LibraryBuilder>> libraryByPackage = {};
- Map<Package, Version> enableNonNullableVersionByPackage = {};
- for (LibraryBuilder libraryBuilder in _strongOptOutLibraries) {
- Package package =
- target.uriTranslator.getPackage(libraryBuilder.importUri);
-
- if (package != null &&
- package.languageVersion != null &&
- package.languageVersion is! InvalidLanguageVersion) {
- Version enableNonNullableVersion =
- enableNonNullableVersionByPackage[package] ??=
- target.getExperimentEnabledVersionInLibrary(
- ExperimentalFlag.nonNullable,
- new Uri(scheme: 'package', path: package.name));
- Version version = new Version(
- package.languageVersion.major, package.languageVersion.minor);
- if (version < enableNonNullableVersion) {
- (libraryByPackage[package?.name] ??= []).add(libraryBuilder);
- continue;
- }
- }
- if (libraryBuilder.importUri.scheme == 'package') {
- (libraryByPackage[null] ??= []).add(libraryBuilder);
- } else {
- // Emit a message that doesn't mention running 'pub'.
- addProblem(messageStrongModeNNBDButOptOut, -1, noLength,
- libraryBuilder.fileUri);
- }
- }
- if (libraryByPackage.isNotEmpty) {
- List<Uri> involvedFiles = [];
- List<String> dependencies = [];
- libraryByPackage.forEach((String name, List<LibraryBuilder> libraries) {
- if (name != null) {
- dependencies.add('package:$name');
- for (LibraryBuilder libraryBuilder in libraries) {
- involvedFiles.add(libraryBuilder.fileUri);
- }
- } else {
- for (LibraryBuilder libraryBuilder in libraries) {
- dependencies.add(libraryBuilder.importUri.toString());
- involvedFiles.add(libraryBuilder.fileUri);
- }
- }
- });
- // Emit a message that suggests to run 'pub' to check for opted in
- // versions of the packages.
- addProblem(
- templateStrongModeNNBDPackageOptOut.withArguments(dependencies),
- -1,
- -1,
- null,
- involvedFiles: involvedFiles);
- _strongOptOutLibraries = null;
- }
+ giveCombinedErrorForNonStrongLibraries(_strongOptOutLibraries,
+ emitNonPackageErrors: true);
+ _strongOptOutLibraries = null;
}
if (_nnbdMismatchLibraries != null) {
for (MapEntry<LibraryBuilder, Message> entry
@@ -420,6 +368,68 @@
}
}
+ FormattedMessage giveCombinedErrorForNonStrongLibraries(
+ Set<LibraryBuilder> libraries,
+ {bool emitNonPackageErrors}) {
+ Map<String, List<LibraryBuilder>> libraryByPackage = {};
+ Map<Package, Version> enableNonNullableVersionByPackage = {};
+ for (LibraryBuilder libraryBuilder in libraries) {
+ final Package package =
+ target.uriTranslator.getPackage(libraryBuilder.importUri);
+
+ if (package != null &&
+ package.languageVersion != null &&
+ package.languageVersion is! InvalidLanguageVersion) {
+ Version enableNonNullableVersion =
+ enableNonNullableVersionByPackage[package] ??=
+ target.getExperimentEnabledVersionInLibrary(
+ ExperimentalFlag.nonNullable,
+ new Uri(scheme: 'package', path: package.name));
+ Version version = new Version(
+ package.languageVersion.major, package.languageVersion.minor);
+ if (version < enableNonNullableVersion) {
+ (libraryByPackage[package.name] ??= []).add(libraryBuilder);
+ continue;
+ }
+ }
+ if (libraryBuilder.importUri.scheme == 'package') {
+ (libraryByPackage[null] ??= []).add(libraryBuilder);
+ } else {
+ if (emitNonPackageErrors) {
+ // Emit a message that doesn't mention running 'pub'.
+ addProblem(messageStrongModeNNBDButOptOut, -1, noLength,
+ libraryBuilder.fileUri);
+ }
+ }
+ }
+ if (libraryByPackage.isNotEmpty) {
+ List<Uri> involvedFiles = [];
+ List<String> dependencies = [];
+ libraryByPackage.forEach((String name, List<LibraryBuilder> libraries) {
+ if (name != null) {
+ dependencies.add('package:$name');
+ for (LibraryBuilder libraryBuilder in libraries) {
+ involvedFiles.add(libraryBuilder.fileUri);
+ }
+ } else {
+ for (LibraryBuilder libraryBuilder in libraries) {
+ dependencies.add(libraryBuilder.importUri.toString());
+ involvedFiles.add(libraryBuilder.fileUri);
+ }
+ }
+ });
+ // Emit a message that suggests to run 'pub' to check for opted in
+ // versions of the packages.
+ return addProblem(
+ templateStrongModeNNBDPackageOptOut.withArguments(dependencies),
+ -1,
+ -1,
+ null,
+ involvedFiles: involvedFiles);
+ }
+ return null;
+ }
+
List<int> getSource(List<int> bytes) {
// bytes is 0-terminated. We don't want that included.
if (bytes is Uint8List) {
diff --git a/pkg/front_end/test/messages_json_test.dart b/pkg/front_end/test/messages_json_test.dart
index 4e84e65..e0f5620 100644
--- a/pkg/front_end/test/messages_json_test.dart
+++ b/pkg/front_end/test/messages_json_test.dart
@@ -8,15 +8,22 @@
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:front_end/src/fasta/fasta_codes.dart'
- show DiagnosticMessageFromJson, FormattedMessage, LocatedMessage;
+ show
+ Code,
+ DiagnosticMessageFromJson,
+ FormattedMessage,
+ LocatedMessage,
+ Message;
/// Test that turning a message into json and back again retains the wanted
/// information.
main() {
for (int i = 0; i < Severity.values.length; i++) {
Severity severity = Severity.values[i];
+ Code code = new Code("MyCodeName", null);
+ Message message = new Message(code);
LocatedMessage locatedMessage1 =
- new LocatedMessage(Uri.parse("what:ever/fun_1.dart"), 117, 2, null);
+ new LocatedMessage(Uri.parse("what:ever/fun_1.dart"), 117, 2, message);
FormattedMessage formattedMessage2 = new FormattedMessage(
null, "Formatted string #2", 13, 2, Severity.error, []);
FormattedMessage formattedMessage3 = new FormattedMessage(
@@ -30,6 +37,7 @@
Uri.parse("what:ever/foo.dart"),
Uri.parse("what:ever/bar.dart")
]);
+ expect(formattedMessage1.codeName, "MyCodeName");
DiagnosticMessageFromJson diagnosticMessageFromJson =
new DiagnosticMessageFromJson.fromJson(
@@ -72,6 +80,10 @@
expect(uriList1[i], uriList2[i]);
}
}
+
+ String string1 = a.codeName;
+ String string2 = b.codeName;
+ expect(string1, string2);
}
void expect(Object actual, Object expect) {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect
index a5bd64f..caa2322 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect
@@ -5,7 +5,6 @@
// Error: This project cannot run with sound null safety, because one or more project dependencies do not
// support null safety:
//
-// - package:foo
// - package:bar
//
// Run 'pub outdated --mode=null-safety' to determine if versions of your
diff --git a/pkg/kernel/problems.md b/pkg/kernel/problems.md
index bc56e4c..073789e 100644
--- a/pkg/kernel/problems.md
+++ b/pkg/kernel/problems.md
@@ -23,6 +23,8 @@
`involvedFiles`: A possibly null list of uris involved in this message.
Normally this is null.
+`codeName`: A string identifing the specific error message.
+
These values are subject to change, but this file will be updated along with any
such changes. On the code-side these are defined in
`package:front_end/src/fasta/fasta_codes.dart`.