mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[CFE] Fix not getting rid of NNBD error in package in incremental compiler
This fixes the issue of the error not going away, but can (see added test) give a wrong error message when in the process of fixing the issues. A follow-up CL will (try to) correct the wrong error message. Change-Id: I3547fe5fb5cfd179897996029a00a4995a967e54 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170422 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
44f3881be6
commit
60a5c58196
16 changed files with 374 additions and 47 deletions
|
@ -131,9 +131,11 @@ class LocatedMessage implements Comparable<LocatedMessage> {
|
|||
}
|
||||
|
||||
FormattedMessage withFormatting(String formatted, int line, int column,
|
||||
Severity severity, List<FormattedMessage> relatedInformation) {
|
||||
Severity severity, List<FormattedMessage> relatedInformation,
|
||||
{List<Uri> involvedFiles}) {
|
||||
return new FormattedMessage(
|
||||
this, formatted, line, column, severity, relatedInformation);
|
||||
this, formatted, line, column, severity, relatedInformation,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -173,8 +175,11 @@ class FormattedMessage implements DiagnosticMessage {
|
|||
|
||||
final List<FormattedMessage> relatedInformation;
|
||||
|
||||
final List<Uri> involvedFiles;
|
||||
|
||||
const FormattedMessage(this.locatedMessage, this.formatted, this.line,
|
||||
this.column, this.severity, this.relatedInformation);
|
||||
this.column, this.severity, this.relatedInformation,
|
||||
{this.involvedFiles});
|
||||
|
||||
Code<dynamic> get code => locatedMessage.code;
|
||||
|
||||
|
@ -212,7 +217,8 @@ class FormattedMessage implements DiagnosticMessage {
|
|||
"ansiFormatted": ansiFormatted.toList(),
|
||||
"plainTextFormatted": plainTextFormatted.toList(),
|
||||
"severity": severity.index,
|
||||
"uri": uri.toString(),
|
||||
"uri": uri?.toString(),
|
||||
"involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -234,8 +240,10 @@ class DiagnosticMessageFromJson implements DiagnosticMessage {
|
|||
|
||||
final Uri uri;
|
||||
|
||||
DiagnosticMessageFromJson(
|
||||
this.ansiFormatted, this.plainTextFormatted, this.severity, this.uri);
|
||||
final List<Uri> involvedFiles;
|
||||
|
||||
DiagnosticMessageFromJson(this.ansiFormatted, this.plainTextFormatted,
|
||||
this.severity, this.uri, this.involvedFiles);
|
||||
|
||||
factory DiagnosticMessageFromJson.fromJson(String jsonString) {
|
||||
Map<String, Object> decoded = json.decode(jsonString);
|
||||
|
@ -244,10 +252,15 @@ class DiagnosticMessageFromJson implements DiagnosticMessage {
|
|||
List<String> plainTextFormatted =
|
||||
new List<String>.from(decoded["plainTextFormatted"]);
|
||||
Severity severity = Severity.values[decoded["severity"]];
|
||||
Uri uri = Uri.parse(decoded["uri"]);
|
||||
Uri uri = decoded["uri"] == null ? null : Uri.parse(decoded["uri"]);
|
||||
List<Uri> involvedFiles = decoded["involvedFiles"] == null
|
||||
? null
|
||||
: new List<String>.from(decoded["involvedFiles"])
|
||||
.map((e) => Uri.parse(e))
|
||||
.toList();
|
||||
|
||||
return new DiagnosticMessageFromJson(
|
||||
ansiFormatted, plainTextFormatted, severity, uri);
|
||||
ansiFormatted, plainTextFormatted, severity, uri, involvedFiles);
|
||||
}
|
||||
|
||||
Map<String, Object> toJson() {
|
||||
|
@ -256,7 +269,8 @@ class DiagnosticMessageFromJson implements DiagnosticMessage {
|
|||
"ansiFormatted": ansiFormatted.toList(),
|
||||
"plainTextFormatted": plainTextFormatted.toList(),
|
||||
"severity": severity.index,
|
||||
"uri": uri.toString(),
|
||||
"uri": uri?.toString(),
|
||||
"involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -34,13 +34,17 @@ abstract class DiagnosticMessage {
|
|||
Iterable<String> get plainTextFormatted;
|
||||
|
||||
Severity get severity;
|
||||
|
||||
Iterable<Uri> get involvedFiles;
|
||||
}
|
||||
|
||||
/// This method is subject to change.
|
||||
Uri getMessageUri(DiagnosticMessage message) {
|
||||
return message is FormattedMessage
|
||||
? message.uri
|
||||
: message is DiagnosticMessageFromJson ? message.uri : null;
|
||||
: message is DiagnosticMessageFromJson
|
||||
? message.uri
|
||||
: null;
|
||||
}
|
||||
|
||||
/// This method is subject to change.
|
||||
|
|
|
@ -207,7 +207,8 @@ class ProcessedOptions {
|
|||
this.ticker = new Ticker(isVerbose: options?.verbose ?? false);
|
||||
|
||||
FormattedMessage format(
|
||||
LocatedMessage message, Severity severity, List<LocatedMessage> context) {
|
||||
LocatedMessage message, Severity severity, List<LocatedMessage> context,
|
||||
{List<Uri> involvedFiles}) {
|
||||
int offset = message.charOffset;
|
||||
Uri uri = message.uri;
|
||||
Location location = offset == -1 ? null : getLocation(uri, offset);
|
||||
|
@ -221,11 +222,12 @@ class ProcessedOptions {
|
|||
}
|
||||
}
|
||||
return message.withFormatting(formatted, location?.line ?? -1,
|
||||
location?.column ?? -1, severity, formattedContext);
|
||||
location?.column ?? -1, severity, formattedContext,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
void report(LocatedMessage message, Severity severity,
|
||||
{List<LocatedMessage> context}) {
|
||||
{List<LocatedMessage> context, List<Uri> involvedFiles}) {
|
||||
if (command_line_reporting.isHidden(severity)) return;
|
||||
if (command_line_reporting.isCompileTimeError(severity)) {
|
||||
CompilerContext.current.logError(message, severity);
|
||||
|
@ -233,7 +235,8 @@ class ProcessedOptions {
|
|||
if (CompilerContext.current.options.setExitCodeOnProblem) {
|
||||
exitCode = 1;
|
||||
}
|
||||
reportDiagnosticMessage(format(message, severity, context));
|
||||
reportDiagnosticMessage(
|
||||
format(message, severity, context, involvedFiles: involvedFiles));
|
||||
if (command_line_reporting.shouldThrowOn(severity)) {
|
||||
if (fatalDiagnosticCount++ < _raw.skipForDebugging) {
|
||||
// Skip this one. The interesting one comes later.
|
||||
|
|
|
@ -65,8 +65,9 @@ class CompilerContext {
|
|||
|
||||
/// Report [message], for example, by printing it.
|
||||
void report(LocatedMessage message, Severity severity,
|
||||
{List<LocatedMessage> context}) {
|
||||
options.report(message, severity, context: context);
|
||||
{List<LocatedMessage> context, List<Uri> involvedFiles}) {
|
||||
options.report(message, severity,
|
||||
context: context, involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
/// Report [message], for example, by printing it.
|
||||
|
|
|
@ -1390,16 +1390,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
}
|
||||
|
||||
// Save any new component-problems.
|
||||
if (componentWithDill?.problemsAsJson != null) {
|
||||
for (String jsonString in componentWithDill.problemsAsJson) {
|
||||
DiagnosticMessageFromJson message =
|
||||
new DiagnosticMessageFromJson.fromJson(jsonString);
|
||||
List<DiagnosticMessageFromJson> messages =
|
||||
remainingComponentProblems[message.uri] ??=
|
||||
new List<DiagnosticMessageFromJson>();
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
_addProblemsAsJsonToRemainingProblems(componentWithDill?.problemsAsJson);
|
||||
return new List<String>.from(issuedProblems);
|
||||
}
|
||||
|
||||
|
@ -1657,14 +1648,36 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
|
||||
/// Internal method.
|
||||
void saveComponentProblems(IncrementalCompilerData data) {
|
||||
if (data.component.problemsAsJson != null) {
|
||||
for (String jsonString in data.component.problemsAsJson) {
|
||||
List<String> problemsAsJson = data.component.problemsAsJson;
|
||||
_addProblemsAsJsonToRemainingProblems(problemsAsJson);
|
||||
}
|
||||
|
||||
void _addProblemsAsJsonToRemainingProblems(List<String> problemsAsJson) {
|
||||
if (problemsAsJson != null) {
|
||||
for (String jsonString in problemsAsJson) {
|
||||
DiagnosticMessageFromJson message =
|
||||
new DiagnosticMessageFromJson.fromJson(jsonString);
|
||||
List<DiagnosticMessageFromJson> messages =
|
||||
remainingComponentProblems[message.uri] ??=
|
||||
new List<DiagnosticMessageFromJson>();
|
||||
messages.add(message);
|
||||
assert(message.uri != null ||
|
||||
(message.involvedFiles != null &&
|
||||
message.involvedFiles.isNotEmpty));
|
||||
if (message.uri != null) {
|
||||
List<DiagnosticMessageFromJson> messages =
|
||||
remainingComponentProblems[message.uri] ??=
|
||||
new List<DiagnosticMessageFromJson>();
|
||||
messages.add(message);
|
||||
}
|
||||
if (message.involvedFiles != null) {
|
||||
// This indexes the same message under several uris - this way it will
|
||||
// be issued as long as it's a problem. It will because of
|
||||
// deduplication when we re-issue these (in reissueComponentProblems)
|
||||
// only be reported once.
|
||||
for (Uri uri in message.involvedFiles) {
|
||||
List<DiagnosticMessageFromJson> messages =
|
||||
remainingComponentProblems[uri] ??=
|
||||
new List<DiagnosticMessageFromJson>();
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,11 +280,13 @@ abstract class Loader {
|
|||
{bool wasHandled: false,
|
||||
List<LocatedMessage> context,
|
||||
Severity severity,
|
||||
bool problemOnLibrary: false}) {
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri> involvedFiles}) {
|
||||
return addMessage(message, charOffset, length, fileUri, severity,
|
||||
wasHandled: wasHandled,
|
||||
context: context,
|
||||
problemOnLibrary: problemOnLibrary);
|
||||
problemOnLibrary: problemOnLibrary,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
/// All messages reported by the compiler (errors, warnings, etc.) are routed
|
||||
|
@ -302,7 +304,8 @@ abstract class Loader {
|
|||
Uri fileUri, Severity severity,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage> context,
|
||||
bool problemOnLibrary: false}) {
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri> involvedFiles}) {
|
||||
severity = target.fixSeverity(severity, message, fileUri);
|
||||
if (severity == Severity.ignored) return null;
|
||||
String trace = """
|
||||
|
@ -321,13 +324,14 @@ severity: $severity
|
|||
}
|
||||
target.context.report(
|
||||
message.withLocation(fileUri, charOffset, length), severity,
|
||||
context: context);
|
||||
context: context, involvedFiles: involvedFiles);
|
||||
if (severity == Severity.error) {
|
||||
(wasHandled ? handledErrors : unhandledErrors)
|
||||
.add(message.withLocation(fileUri, charOffset, length));
|
||||
}
|
||||
FormattedMessage formattedMessage = target.createFormattedMessage(
|
||||
message, charOffset, length, fileUri, context, severity);
|
||||
message, charOffset, length, fileUri, context, severity,
|
||||
involvedFiles: involvedFiles);
|
||||
if (!problemOnLibrary) {
|
||||
allComponentProblems.add(formattedMessage);
|
||||
}
|
||||
|
|
|
@ -385,13 +385,18 @@ class SourceLoader extends Loader {
|
|||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -401,7 +406,8 @@ class SourceLoader extends Loader {
|
|||
templateStrongModeNNBDPackageOptOut.withArguments(dependencies),
|
||||
-1,
|
||||
-1,
|
||||
null);
|
||||
null,
|
||||
involvedFiles: involvedFiles);
|
||||
_strongOptOutLibraries = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,12 +180,14 @@ abstract class TargetImplementation extends Target {
|
|||
int length,
|
||||
Uri fileUri,
|
||||
List<LocatedMessage> messageContext,
|
||||
Severity severity) {
|
||||
Severity severity,
|
||||
{List<Uri> involvedFiles}) {
|
||||
ProcessedOptions processedOptions = context.options;
|
||||
return processedOptions.format(
|
||||
message.withLocation(fileUri, charOffset, length),
|
||||
severity,
|
||||
messageContext);
|
||||
messageContext,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
Severity fixSeverity(Severity severity, Message message, Uri fileUri) {
|
||||
|
|
|
@ -23,12 +23,13 @@ main() {
|
|||
null, "Formatted string #3", 313, 32, Severity.error, []);
|
||||
|
||||
FormattedMessage formattedMessage1 = new FormattedMessage(
|
||||
locatedMessage1,
|
||||
"Formatted string",
|
||||
42,
|
||||
86,
|
||||
severity,
|
||||
[formattedMessage2, formattedMessage3]);
|
||||
locatedMessage1, "Formatted string", 42, 86, severity, [
|
||||
formattedMessage2,
|
||||
formattedMessage3
|
||||
], involvedFiles: [
|
||||
Uri.parse("what:ever/foo.dart"),
|
||||
Uri.parse("what:ever/bar.dart")
|
||||
]);
|
||||
|
||||
DiagnosticMessageFromJson diagnosticMessageFromJson =
|
||||
new DiagnosticMessageFromJson.fromJson(
|
||||
|
@ -62,6 +63,15 @@ void compareMessages(DiagnosticMessage a, DiagnosticMessage b) {
|
|||
|
||||
expect(a.severity, b.severity);
|
||||
expect(getMessageUri(a), getMessageUri(b));
|
||||
|
||||
List<Uri> uriList1 = a.involvedFiles?.toList();
|
||||
List<Uri> uriList2 = b.involvedFiles?.toList();
|
||||
expect(uriList1?.length, uriList2?.length);
|
||||
if (uriList1 != null) {
|
||||
for (int i = 0; i < uriList1.length; i++) {
|
||||
expect(uriList1[i], uriList2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void expect(Object actual, Object expect) {
|
||||
|
|
|
@ -279,6 +279,7 @@ dec
|
|||
decl
|
||||
decoupled
|
||||
decreases
|
||||
deduplication
|
||||
deemed
|
||||
deepest
|
||||
deeply
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
# Copyright (c) 2020, 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.md file.
|
||||
|
||||
# If issuing a "compiling with strong mode but [...]" error, we should be able
|
||||
# to get rid of it if the error is fixed.
|
||||
|
||||
type: newworld
|
||||
worlds:
|
||||
- entry: package:baz/main.dart
|
||||
experiments: non-nullable
|
||||
nnbdMode: strong
|
||||
errors: true
|
||||
sources:
|
||||
.dart_tool/package_config.json: |
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "foo",
|
||||
"rootUri": "../foo",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "2.8"
|
||||
},
|
||||
{
|
||||
"name": "bar",
|
||||
"rootUri": "../bar",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "2.8"
|
||||
},
|
||||
{
|
||||
"name": "baz",
|
||||
"rootUri": "../baz",
|
||||
"packageUri": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
foo/lib/foo.dart: |
|
||||
// This file is in weak mode.
|
||||
int x = null;
|
||||
bar/lib/bar.dart: |
|
||||
// This file is in weak mode.
|
||||
int y = null;
|
||||
baz/main.dart: |
|
||||
// This file wants to be strong.
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
main() {
|
||||
print(foo.x);
|
||||
print(bar.y);
|
||||
}
|
||||
expectedLibraryCount: 3
|
||||
|
||||
# Update "nothing" so we still want the error.
|
||||
- entry: package:baz/main.dart
|
||||
experiments: non-nullable
|
||||
nnbdMode: strong
|
||||
worldType: updated
|
||||
expectInitializeFromDill: false
|
||||
errors: true
|
||||
invalidate:
|
||||
- baz/main.dart
|
||||
sources:
|
||||
baz/main.dart: |
|
||||
// This file wants to be strong.
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
main() {
|
||||
print(foo.x);
|
||||
print(bar.y);
|
||||
print("done");
|
||||
}
|
||||
expectedLibraryCount: 3
|
||||
|
||||
|
||||
# Update ONE package to be strong.
|
||||
- entry: package:baz/main.dart
|
||||
experiments: non-nullable
|
||||
nnbdMode: strong
|
||||
worldType: updated
|
||||
expectInitializeFromDill: false
|
||||
errors: true
|
||||
invalidate:
|
||||
# .dart_tool/package_config.json is invalidated implicitly.
|
||||
- foo/lib/foo.dart
|
||||
sources:
|
||||
.dart_tool/package_config.json: |
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "foo",
|
||||
"rootUri": "../foo",
|
||||
"packageUri": "lib/"
|
||||
},
|
||||
{
|
||||
"name": "bar",
|
||||
"rootUri": "../bar",
|
||||
"packageUri": "lib/",
|
||||
"languageVersion": "2.8"
|
||||
},
|
||||
{
|
||||
"name": "baz",
|
||||
"rootUri": "../baz",
|
||||
"packageUri": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
foo/lib/foo.dart: |
|
||||
// This file is in strong mode.
|
||||
int x = 42;
|
||||
expectedLibraryCount: 3
|
||||
|
||||
# Update the last package to be strong.
|
||||
- entry: package:baz/main.dart
|
||||
experiments: non-nullable
|
||||
nnbdMode: strong
|
||||
worldType: updated
|
||||
expectInitializeFromDill: false
|
||||
errors: false
|
||||
invalidate:
|
||||
# .dart_tool/package_config.json is invalidated implicitly.
|
||||
- bar/lib/bar.dart
|
||||
sources:
|
||||
.dart_tool/package_config.json: |
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "foo",
|
||||
"rootUri": "../foo",
|
||||
"packageUri": "lib/"
|
||||
},
|
||||
{
|
||||
"name": "bar",
|
||||
"rootUri": "../bar",
|
||||
"packageUri": "lib/"
|
||||
},
|
||||
{
|
||||
"name": "baz",
|
||||
"rootUri": "../baz",
|
||||
"packageUri": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
bar/lib/bar.dart: |
|
||||
// This file is in strong mode.
|
||||
int y = 42;
|
||||
expectedLibraryCount: 3
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
main = main::main;
|
||||
//
|
||||
// Problems in component:
|
||||
//
|
||||
// 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
|
||||
// dependencies supporting null safety are available.
|
||||
//
|
||||
library from "package:bar/bar.dart" as bar {
|
||||
|
||||
static field dart.core::int* y = null;
|
||||
}
|
||||
library from "package:baz/main.dart" as main {
|
||||
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
|
||||
static method main() → dynamic {
|
||||
dart.core::print(foo::x);
|
||||
dart.core::print(bar::y);
|
||||
}
|
||||
}
|
||||
library from "package:foo/foo.dart" as foo {
|
||||
|
||||
static field dart.core::int* x = null;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
main = main::main;
|
||||
//
|
||||
// Problems in component:
|
||||
//
|
||||
// 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
|
||||
// dependencies supporting null safety are available.
|
||||
//
|
||||
library from "package:bar/bar.dart" as bar {
|
||||
|
||||
static field dart.core::int* y = null;
|
||||
}
|
||||
library from "package:baz/main.dart" as main {
|
||||
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
|
||||
static method main() → dynamic {
|
||||
dart.core::print(foo::x);
|
||||
dart.core::print(bar::y);
|
||||
dart.core::print("done");
|
||||
}
|
||||
}
|
||||
library from "package:foo/foo.dart" as foo {
|
||||
|
||||
static field dart.core::int* x = null;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
main = main::main;
|
||||
//
|
||||
// Problems in component:
|
||||
//
|
||||
// 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
|
||||
// dependencies supporting null safety are available.
|
||||
//
|
||||
library from "package:bar/bar.dart" as bar {
|
||||
|
||||
static field dart.core::int* y = null;
|
||||
}
|
||||
library from "package:baz/main.dart" as main {
|
||||
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
|
||||
static method main() → dynamic {
|
||||
dart.core::print(foo::x);
|
||||
dart.core::print(bar::y);
|
||||
dart.core::print("done");
|
||||
}
|
||||
}
|
||||
library from "package:foo/foo.dart" as foo {
|
||||
|
||||
static field dart.core::int x = 42;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
main = main::main;
|
||||
library from "package:bar/bar.dart" as bar {
|
||||
|
||||
static field dart.core::int y = 42;
|
||||
}
|
||||
library from "package:baz/main.dart" as main {
|
||||
|
||||
import "package:foo/foo.dart" as foo;
|
||||
import "package:bar/bar.dart" as bar;
|
||||
|
||||
static method main() → dynamic {
|
||||
dart.core::print(foo::x);
|
||||
dart.core::print(bar::y);
|
||||
dart.core::print("done");
|
||||
}
|
||||
}
|
||||
library from "package:foo/foo.dart" as foo {
|
||||
|
||||
static field dart.core::int x = 42;
|
||||
}
|
|
@ -17,7 +17,11 @@ problem-texts as reported by the compiler.
|
|||
`severity`: An integer representing severity. This should match the index in
|
||||
`package:_fe_analyzer_shared/src/messages/severity.dart`.
|
||||
|
||||
`uri`: A uri that this problems relates to.
|
||||
`uri`: A possibly null uri that this problems relates to. This is the main uri.
|
||||
Normally this is not null (but it can be).
|
||||
|
||||
`involvedFiles`: A possibly null list of uris involved in this message.
|
||||
Normally this is null.
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue