Version 2.12.0-113.0.dev
Merge commit 'd86f0e2836d0941776f911dfc86ff444121fd29d' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 3af28cb..0bce9d2 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- 1.32.0
+ 1.32.1
</h1>
<p>
This document contains a specification of the API provided by the
@@ -235,6 +235,11 @@
the server so clients should ensure unknown values are handled gracefully, either
ignoring the item or treating it with some default/fallback handling.
</p>
+<h3>Changelog</h3>
+<h4>1.32.1</h4>
+<ul>
+ <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt></li>
+</ul>
<h3>Domains</h3>
<p>
For convenience, the API is divided into domains. Each domain is specified
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index cdccff0..7636ffc 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
-const String PROTOCOL_VERSION = '1.32.0';
+const String PROTOCOL_VERSION = '1.32.1';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 56c7ee0..145b8bf 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -74,14 +74,22 @@
RegExp(r'[$}\\]'), // Replace any of $ } \
(c) => '\\${c[0]}', // Prefix with a backslash
);
+
// Snippets syntax is documented in the LSP spec:
- // https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#snippet-syntax
+ // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
//
// $1, $2, etc. are used for tab stops and ${1:foo} inserts a placeholder of foo.
final output = [];
var offset = 0;
- var tabStopNumber = 1;
+
+ // When there's only a single tabstop, it should be ${0} as this is treated
+ // specially as the final cursor position (if we use 1, the editor will insert
+ // a 0 at the end of the string which is not what we expect).
+ // When there are multiple, start with ${1} since these are placeholders the
+ // user can tab through and the editor-inserted ${0} at the end is expected.
+ var tabStopNumber = offsetLengthPairs.length <= 2 ? 0 : 1;
+
for (var i = 0; i < offsetLengthPairs.length; i += 2) {
final pairOffset = offsetLengthPairs[i];
final pairLength = offsetLengthPairs[i + 1];
@@ -852,9 +860,11 @@
suggestion.defaultArgumentListString,
suggestion.defaultArgumentListTextRanges,
)
- : '\${1:}'; // No required params still gets a tabstop in the parens.
+ : '\${0:}'; // No required params still gets a tabstop in the parens.
insertText += '($functionCallSuffix)';
- } else if (suggestion.selectionOffset != 0) {
+ } else if (suggestion.selectionOffset != 0 &&
+ // We don't need a tabstop if the selection is the end of the string.
+ suggestion.selectionOffset != suggestion.completion.length) {
insertTextFormat = lsp.InsertTextFormat.Snippet;
insertText = buildSnippetStringWithTabStops(
suggestion.completion,
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index e1591e8..304bbbb 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -145,7 +145,7 @@
final item = res.singleWhere((c) => c.label == 'myFunction(…)');
// With no required params, there should still be parens and a tabstop inside.
expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
- expect(item.insertText, equals(r'myFunction(${1:})'));
+ expect(item.insertText, equals(r'myFunction(${0:})'));
expect(item.textEdit.newText, equals(item.insertText));
expect(
item.textEdit.range,
@@ -170,10 +170,10 @@
await openFile(mainFileUri, withoutMarkers(content));
final res = await getCompletion(mainFileUri, positionFromMarker(content));
final item = res.singleWhere((c) => c.label == 'min(…)');
- // Ensure the snippet does not include the parens/args as it doesn't
- // make sense in the show clause. There will still be a trailing tabstop.
- expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
- expect(item.insertText, equals(r'min${1:}'));
+ // The insert text should be a simple string with no parens/args and
+ // no need for snippets.
+ expect(item.insertTextFormat, isNull);
+ expect(item.insertText, equals(r'min'));
expect(item.textEdit.newText, equals(item.insertText));
}
@@ -540,7 +540,7 @@
expect(updated, contains('one: '));
}
- Future<void> test_namedArg_snippetStringSelection() async {
+ Future<void> test_namedArg_snippetStringSelection_endOfString() async {
final content = '''
class A { const A({int one}); }
@A(^)
@@ -554,11 +554,43 @@
final res = await getCompletion(mainFileUri, positionFromMarker(content));
expect(res.any((c) => c.label == 'one: '), isTrue);
final item = res.singleWhere((c) => c.label == 'one: ');
+ // As the selection is the end of the string, there's no need for a snippet
+ // here. Since the insert text is also the same as the label, it does not
+ // need to be provided.
+ expect(item.insertTextFormat, isNull);
+ expect(item.insertText, isNull);
+ expect(item.textEdit.newText, equals('one: '));
+ expect(
+ item.textEdit.range,
+ equals(Range(
+ start: positionFromMarker(content),
+ end: positionFromMarker(content))),
+ );
+ }
+
+ Future<void>
+ test_namedArgTrailing_snippetStringSelection_insideString() async {
+ final content = '''
+ main({int one, int two}) {
+ main(
+ ^
+ two: 2,
+ );
+ }
+ ''';
+
+ await initialize(
+ textDocumentCapabilities: withCompletionItemSnippetSupport(
+ emptyTextDocumentClientCapabilities));
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ expect(res.any((c) => c.label == 'one: '), isTrue);
+ final item = res.singleWhere((c) => c.label == 'one: ');
// Ensure the snippet comes through in the expected format with the expected
// placeholder.
expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
- expect(item.insertText, equals(r'one: ${1:}'));
- expect(item.textEdit.newText, equals(r'one: ${1:}'));
+ expect(item.insertText, equals(r'one: ${0:},'));
+ expect(item.textEdit.newText, equals(r'one: ${0:},'));
expect(
item.textEdit.range,
equals(Range(
diff --git a/pkg/analysis_server/test/lsp/mapping_test.dart b/pkg/analysis_server/test/lsp/mapping_test.dart
index 72bf3f6..9d88d76 100644
--- a/pkg/analysis_server/test/lsp/mapping_test.dart
+++ b/pkg/analysis_server/test/lsp/mapping_test.dart
@@ -76,7 +76,7 @@
Future<void> test_tabStopsInSnippets_contains() async {
var result = lsp.buildSnippetStringWithTabStops('a, b, c', [3, 1]);
- expect(result, equals(r'a, ${1:b}, c'));
+ expect(result, equals(r'a, ${0:b}, c'));
}
Future<void> test_tabStopsInSnippets_empty() async {
@@ -86,13 +86,13 @@
Future<void> test_tabStopsInSnippets_endsWith() async {
var result = lsp.buildSnippetStringWithTabStops('a, b', [3, 1]);
- expect(result, equals(r'a, ${1:b}'));
+ expect(result, equals(r'a, ${0:b}'));
}
Future<void> test_tabStopsInSnippets_escape() async {
var result = lsp.buildSnippetStringWithTabStops(
r'te$tstri}ng, te$tstri}ng, te$tstri}ng', [13, 11]);
- expect(result, equals(r'te\$tstri\}ng, ${1:te\$tstri\}ng}, te\$tstri\}ng'));
+ expect(result, equals(r'te\$tstri\}ng, ${0:te\$tstri\}ng}, te\$tstri\}ng'));
}
Future<void> test_tabStopsInSnippets_multiple() async {
@@ -103,6 +103,6 @@
Future<void> test_tabStopsInSnippets_startsWith() async {
var result = lsp.buildSnippetStringWithTabStops('a, b', [0, 1]);
- expect(result, equals(r'${1:a}, b'));
+ expect(result, equals(r'${0:a}, b'));
}
}
diff --git a/pkg/analysis_server/tool/code_completion/completion_metrics.dart b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
index 2e467ab..1d1665c 100644
--- a/pkg/analysis_server/tool/code_completion/completion_metrics.dart
+++ b/pkg/analysis_server/tool/code_completion/completion_metrics.dart
@@ -54,14 +54,19 @@
return io.exit(1);
}
+ var options = CompletionMetricsOptions(
+ availableSuggestions: result[AVAILABLE_SUGGESTIONS],
+ overlay: result[OVERLAY],
+ printMissedCompletionDetails: result[PRINT_MISSED_COMPLETION_DETAILS],
+ printMissedCompletionSummary: result[PRINT_MISSED_COMPLETION_SUMMARY],
+ printMissingInformation: result[PRINT_MISSING_INFORMATION],
+ printMrrByLocation: result[PRINT_MRR_BY_LOCATION],
+ printSlowestResults: result[PRINT_SLOWEST_RESULTS],
+ printWorstResults: result[PRINT_WORST_RESULTS]);
var root = result.rest[0];
print('Analyzing root: "$root"');
var stopwatch = Stopwatch()..start();
- var code = await CompletionMetricsComputer(root,
- availableSuggestions: result[AVAILABLE_SUGGESTIONS],
- overlay: result[OVERLAY],
- verbose: result[VERBOSE])
- .compute();
+ var code = await CompletionMetricsComputer(root, options).compute();
stopwatch.stop();
var duration = Duration(milliseconds: stopwatch.elapsedMilliseconds);
@@ -86,8 +91,34 @@
/// completion offset should be removed.
const String OVERLAY_REMOVE_TOKEN = 'remove-token';
-/// A flag that causes additional output to be produced.
-const String VERBOSE = 'verbose';
+/// A flag that causes detailed information to be printed every time a
+/// completion request fails to produce a suggestions matching the expected
+/// suggestion.
+const String PRINT_MISSED_COMPLETION_DETAILS =
+ 'print-missed-completion-details';
+
+/// A flag that causes summary information to be printed about the times that a
+/// completion request failed to produce a suggestions matching the expected
+/// suggestion.
+const String PRINT_MISSED_COMPLETION_SUMMARY =
+ 'print-missed-completion-summary';
+
+/// A flag that causes information to be printed about places where no
+/// completion location was computed and about information that's missing in the
+/// completion tables.
+const String PRINT_MISSING_INFORMATION = 'print-missing-information';
+
+/// A flag that causes information to be printed about the mrr score achieved at
+/// each completion location.
+const String PRINT_MRR_BY_LOCATION = 'print-mrr-by-location';
+
+/// A flag that causes information to be printed about the completion requests
+/// that were the slowest to return suggestions.
+const String PRINT_SLOWEST_RESULTS = 'print-slowest-results';
+
+/// A flag that causes information to be printed about the completion requests
+/// that had the worst mrr scores.
+const String PRINT_WORST_RESULTS = 'print-worst-results';
/// A [Counter] to track the performance of each of the completion strategies
/// that are being compared.
@@ -96,26 +127,21 @@
/// Create a parser that can be used to parse the command-line arguments.
ArgParser createArgParser() {
return ArgParser()
+ ..addFlag(AVAILABLE_SUGGESTIONS,
+ abbr: 'a',
+ help:
+ 'Use the available suggestions feature in the Analysis Server when '
+ 'computing the set of code completions. With this feature enabled, '
+ 'completion will match the support in the Dart Plugin for '
+ 'IntelliJ, without this enabled the completion support matches the '
+ 'support in LSP.',
+ defaultsTo: false,
+ negatable: false)
..addOption(
'help',
abbr: 'h',
help: 'Print this help message.',
)
- ..addFlag(
- VERBOSE,
- abbr: 'v',
- help: 'Print additional information about the analysis',
- negatable: false,
- )
- ..addFlag(AVAILABLE_SUGGESTIONS,
- abbr: 'a',
- help: 'Use the available suggestions feature in the Analysis Server '
- 'when computing the set of code completions. With this feature '
- 'enabled, completion will match the support in the Dart Plugin for '
- 'IntelliJ, without this enabled the completion support matches '
- 'the support in LSP.',
- defaultsTo: false,
- negatable: false)
..addOption(OVERLAY,
allowed: [
OVERLAY_NONE,
@@ -125,9 +151,46 @@
defaultsTo: OVERLAY_NONE,
help:
'Before attempting a completion at the location of each token, the '
- 'token can be removed, or the rest of the file can be removed to test '
- 'code completion with diverse methods. The default mode is to '
- 'complete at the start of the token without modifying the file.');
+ 'token can be removed, or the rest of the file can be removed to '
+ 'test code completion with diverse methods. The default mode is to '
+ 'complete at the start of the token without modifying the file.')
+ ..addFlag(PRINT_MISSED_COMPLETION_DETAILS,
+ defaultsTo: false,
+ help:
+ 'Print detailed information every time a completion request fails '
+ 'to produce a suggestions matching the expected suggestion.',
+ negatable: false)
+ ..addFlag(PRINT_MISSED_COMPLETION_SUMMARY,
+ defaultsTo: false,
+ help: 'Print summary information about the times that a completion '
+ 'request failed to produce a suggestions matching the expected '
+ 'suggestion.',
+ negatable: false)
+ ..addFlag(PRINT_MISSING_INFORMATION,
+ defaultsTo: false,
+ help: 'Print information about places where no completion location was '
+ 'computed and about information that is missing in the completion '
+ 'tables.',
+ negatable: false)
+ ..addFlag(PRINT_MRR_BY_LOCATION,
+ defaultsTo: false,
+ help:
+ 'Print information about the mrr score achieved at each completion '
+ 'location. This can help focus efforts to improve the overall '
+ 'score by pointing out the locations that are causing the biggest '
+ 'impact.',
+ negatable: false)
+ ..addFlag(PRINT_SLOWEST_RESULTS,
+ defaultsTo: false,
+ help: 'Print information about the completion requests that were the '
+ 'slowest to return suggestions.',
+ negatable: false)
+ ..addFlag(PRINT_WORST_RESULTS,
+ defaultsTo: false,
+ help:
+ 'Print information about the completion requests that had the worst '
+ 'mrr scores.',
+ negatable: false);
}
/// Print usage information for this tool.
@@ -446,11 +509,7 @@
class CompletionMetricsComputer {
final String rootPath;
- final bool availableSuggestions;
-
- final String overlay;
-
- final bool verbose;
+ final CompletionMetricsOptions options;
ResolvedUnitResult _resolvedUnitResult;
@@ -465,13 +524,7 @@
int overlayModificationStamp = 0;
- CompletionMetricsComputer(this.rootPath,
- {@required this.availableSuggestions,
- @required this.overlay,
- @required this.verbose})
- : assert(overlay == OVERLAY_NONE ||
- overlay == OVERLAY_REMOVE_TOKEN ||
- overlay == OVERLAY_REMOVE_REST_OF_FILE);
+ CompletionMetricsComputer(this.rootPath, this.options);
Future<int> compute() async {
resultCode = 0;
@@ -485,6 +538,7 @@
for (var context in collection.contexts) {
await _computeInContext(context.contextRoot);
}
+ printComparison();
for (var metrics in targetMetrics) {
printMetrics(metrics);
@@ -493,11 +547,15 @@
rankComparison.printCounterValues();
print('====================');
- if (verbose) {
- printWorstResults(metrics);
- printSlowestResults(metrics);
+ if (options.printMissingInformation) {
printMissingInformation(metrics);
}
+ if (options.printSlowestResults) {
+ printSlowestResults(metrics);
+ }
+ if (options.printWorstResults) {
+ printWorstResults(metrics);
+ }
}
return resultCode;
}
@@ -561,12 +619,42 @@
}
}
+ void printComparison() {
+ List<String> toRow(Iterable<MeanReciprocalRankComputer> computers) {
+ return [
+ computers.first.name,
+ for (var computer in computers) (1 / computer.mrr).toStringAsFixed(3),
+ ];
+ }
+
+ var buffer = StringBuffer();
+ var table = [
+ ['', for (var metrics in targetMetrics) metrics.name],
+ toRow(targetMetrics.map((metrics) => metrics.mrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.successfulMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.instanceMemberMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.staticMemberMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.typeRefMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.localRefMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.paramRefMrrComputer)),
+ toRow(targetMetrics.map((metrics) => metrics.topLevelMrrComputer)),
+ ];
+ for (var i = 1; i < table[0].length; i++) {
+ rightJustifyColumn(i, table);
+ }
+ buffer.writeTable(table);
+
+ print('');
+ print('Comparison of inverse mean reciprocal ranks (lower is better)');
+ print('');
+ print(buffer.toString());
+ }
+
void printMetrics(CompletionMetrics metrics) {
- print('');
- print('');
print('====================');
print('Completion metrics for ${metrics.name}:');
- if (verbose) {
+ print('');
+ if (options.printMissedCompletionSummary) {
metrics.completionMissedTokenCounter.printCounterValues();
print('');
@@ -577,31 +665,39 @@
print('');
}
- metrics.mrrComputer.printMean();
- print('');
+ List<String> toRow(MeanReciprocalRankComputer computer) {
+ return [
+ computer.name,
+ computer.mrr.toStringAsFixed(6),
+ (1 / computer.mrr).toStringAsFixed(3),
+ computer.mrr_5.toStringAsFixed(6),
+ (1 / computer.mrr_5).toStringAsFixed(3),
+ computer.count.toString(),
+ ];
+ }
- metrics.successfulMrrComputer.printMean();
- print('');
+ var buffer = StringBuffer();
+ var table = [
+ ['', 'mrr', 'inverse mrr', 'mrr_5', 'inverse mrr_5', 'count'],
+ toRow(metrics.mrrComputer),
+ toRow(metrics.successfulMrrComputer),
+ toRow(metrics.instanceMemberMrrComputer),
+ toRow(metrics.staticMemberMrrComputer),
+ toRow(metrics.typeRefMrrComputer),
+ toRow(metrics.localRefMrrComputer),
+ toRow(metrics.paramRefMrrComputer),
+ toRow(metrics.topLevelMrrComputer),
+ ];
+ rightJustifyColumn(2, table);
+ rightJustifyColumn(4, table);
+ rightJustifyColumn(5, table);
+ buffer.writeTable(table);
- metrics.instanceMemberMrrComputer.printMean();
+ print('Mean Reciprocal Rank');
print('');
+ print(buffer.toString());
- metrics.staticMemberMrrComputer.printMean();
- print('');
-
- metrics.typeRefMrrComputer.printMean();
- print('');
-
- metrics.localRefMrrComputer.printMean();
- print('');
-
- metrics.paramRefMrrComputer.printMean();
- print('');
-
- metrics.topLevelMrrComputer.printMean();
- print('');
-
- if (verbose) {
+ if (options.printMrrByLocation) {
var lines = <LocationTableLine>[];
for (var entry in metrics.locationMrrComputers.entries) {
var count = entry.value.count;
@@ -807,7 +903,7 @@
// suggestions if doComputeCompletionsFromAnalysisServer is true.
DeclarationsTracker declarationsTracker;
protocol.CompletionAvailableSuggestionsParams availableSuggestionsParams;
- if (availableSuggestions) {
+ if (options.availableSuggestions) {
declarationsTracker = DeclarationsTracker(
MemoryByteStore(), PhysicalResourceProvider.INSTANCE);
declarationsTracker.addContext(context);
@@ -852,9 +948,11 @@
// If an overlay option is being used, compute the overlay file, and
// have the context reanalyze the file
- if (overlay != OVERLAY_NONE) {
+ if (options.overlay != OVERLAY_NONE) {
var overlayContents = _getOverlayContents(
- _resolvedUnitResult.content, expectedCompletion, overlay);
+ _resolvedUnitResult.content,
+ expectedCompletion,
+ options.overlay);
_provider.setOverlay(filePath,
content: overlayContents,
@@ -921,7 +1019,7 @@
var rank = await handleExpectedCompletion(
listener: listener,
metrics: metrics,
- printMissedCompletions: verbose);
+ printMissedCompletions: options.printMissedCompletionDetails);
if (bestRank < 0 || rank < bestRank) {
bestRank = rank;
bestName = metrics.name;
@@ -932,7 +1030,7 @@
// If an overlay option is being used, remove the overlay applied
// earlier
- if (overlay != OVERLAY_NONE) {
+ if (options.overlay != OVERLAY_NONE) {
_provider.removeOverlay(filePath);
}
}
@@ -1061,6 +1159,56 @@
}
}
+/// The options specified on the command-line.
+class CompletionMetricsOptions {
+ /// A flag indicating whether available suggestions should be enabled for this
+ /// run.
+ final bool availableSuggestions;
+
+ /// The overlay mode that should be used.
+ final String overlay;
+
+ /// A flag indicating whether information should be printed every time a
+ /// completion request fails to produce a suggestions matching the expected
+ /// suggestion.
+ final bool printMissedCompletionDetails;
+
+ /// A flag indicating whether information should be printed every time a
+ /// completion request fails to produce a suggestions matching the expected
+ /// suggestion.
+ final bool printMissedCompletionSummary;
+
+ /// A flag indicating whether information should be printed about places where
+ /// no completion location was computed and about information that's missing
+ /// in the completion tables.
+ final bool printMissingInformation;
+
+ /// A flag indicating whether information should be printed about the mrr
+ /// score achieved at each completion location.
+ final bool printMrrByLocation;
+
+ /// A flag indicating whether information should be printed about the
+ /// completion requests that were the slowest to return suggestions.
+ final bool printSlowestResults;
+
+ /// A flag indicating whether information should be printed about the
+ /// completion requests that had the worst mrr scores.
+ final bool printWorstResults;
+
+ CompletionMetricsOptions(
+ {@required this.availableSuggestions,
+ @required this.overlay,
+ @required this.printMissedCompletionDetails,
+ @required this.printMissedCompletionSummary,
+ @required this.printMissingInformation,
+ @required this.printMrrByLocation,
+ @required this.printSlowestResults,
+ @required this.printWorstResults})
+ : assert(overlay == OVERLAY_NONE ||
+ overlay == OVERLAY_REMOVE_TOKEN ||
+ overlay == OVERLAY_REMOVE_REST_OF_FILE);
+}
+
/// The result of a single completion.
class CompletionResult {
final Place place;
diff --git a/pkg/analysis_server/tool/code_completion/metrics_util.dart b/pkg/analysis_server/tool/code_completion/metrics_util.dart
index cadc262..6078af8d 100644
--- a/pkg/analysis_server/tool/code_completion/metrics_util.dart
+++ b/pkg/analysis_server/tool/code_completion/metrics_util.dart
@@ -76,8 +76,13 @@
void printCounterValues() {
print('Counts for \'$name\' (total = $_totalCount):');
if (_totalCount > 0) {
- _buckets.forEach((id, count) =>
- print('[$id] $count (${printPercentage(count / _totalCount, 2)})'));
+ var entries = _buckets.entries.toList();
+ entries.sort((first, second) => second.value - first.value);
+ for (var entry in entries) {
+ var id = entry.key;
+ var count = entry.value;
+ print('[$id] $count (${printPercentage(count / _totalCount, 2)})');
+ }
} else {
print('<no counts>');
}
diff --git a/pkg/analysis_server/tool/code_completion/output_utilities.dart b/pkg/analysis_server/tool/code_completion/output_utilities.dart
index 00ed748..71660df 100644
--- a/pkg/analysis_server/tool/code_completion/output_utilities.dart
+++ b/pkg/analysis_server/tool/code_completion/output_utilities.dart
@@ -4,6 +4,26 @@
import 'dart:math' as math;
+/// Given a [table] represented as a list of rows, right justify all of the
+/// cells in the given [column], except for the first row under the assumption
+/// that the first row contains headers.
+void rightJustifyColumn(int column, List<List<String>> table) {
+ var width = 0;
+ for (var i = 0; i < table.length; i++) {
+ var row = table[i];
+ width = math.max(width, row[column].length);
+ }
+ for (var i = 1; i < table.length; i++) {
+ var row = table[i];
+ var cellValue = row[column];
+ var length = cellValue.length;
+ if (length < width) {
+ var padding = ' ' * (width - length);
+ row[column] = '$padding$cellValue';
+ }
+ }
+}
+
extension OutputUtilities on StringSink {
/// Write the given [table].
///
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 8b49fc8..57cd829 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- <version>1.32.0</version>
+ <version>1.32.1</version>
</h1>
<p>
This document contains a specification of the API provided by the
@@ -133,6 +133,11 @@
the server so clients should ensure unknown values are handled gracefully, either
ignoring the item or treating it with some default/fallback handling.
</p>
+<h3>Changelog</h3>
+<h4>1.32.1</h4>
+<ul>
+ <li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt></li>
+</ul>
<h3>Domains</h3>
<p>
For convenience, the API is divided into domains. Each domain is specified
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index cdccff0..7636ffc 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
-const String PROTOCOL_VERSION = '1.32.0';
+const String PROTOCOL_VERSION = '1.32.1';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index 2cb1bde..941812a 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -2,6 +2,8 @@
// 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 'dart:math' show max;
+
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -50,15 +52,7 @@
/// Return the interfaces that are directly implemented by this class.
List<InstantiatedClass> get interfaces {
var interfaces = element.interfaces;
-
- var result = List<InstantiatedClass>(interfaces.length);
- for (var i = 0; i < interfaces.length; i++) {
- var interface = interfaces[i];
- var substituted = _substitution.substituteType(interface);
- result[i] = InstantiatedClass.of(substituted);
- }
-
- return result;
+ return _toInstantiatedClasses(interfaces);
}
/// Return `true` if this type represents the type 'Function' defined in the
@@ -67,6 +61,12 @@
return element.name == 'Function' && element.library.isDartCore;
}
+ /// Return the mixin that are directly implemented by this class.
+ List<InstantiatedClass> get mixins {
+ var mixins = element.mixins;
+ return _toInstantiatedClasses(mixins);
+ }
+
/// Return the superclass of this type, or `null` if this type represents
/// the class 'Object'.
InstantiatedClass get superclass {
@@ -84,15 +84,7 @@
/// the type for the class `Object`.
List<InstantiatedClass> get superclassConstraints {
var constraints = element.superclassConstraints;
-
- var result = List<InstantiatedClass>(constraints.length);
- for (var i = 0; i < constraints.length; i++) {
- var constraint = constraints[i];
- var substituted = _substitution.substituteType(constraint);
- result[i] = InstantiatedClass.of(substituted);
- }
-
- return result;
+ return _toInstantiatedClasses(constraints);
}
@visibleForTesting
@@ -139,6 +131,19 @@
nullabilitySuffix: nullability,
);
}
+
+ List<InstantiatedClass> _toInstantiatedClasses(
+ List<InterfaceType> interfaces,
+ ) {
+ var result = List<InstantiatedClass>(interfaces.length);
+ for (var i = 0; i < interfaces.length; i++) {
+ var interface = interfaces[i];
+ var substituted = _substitution.substituteType(interface);
+ result[i] = InstantiatedClass.of(substituted);
+ }
+
+ return result;
+ }
}
class InterfaceLeastUpperBoundHelper {
@@ -277,11 +282,7 @@
/// Object.
@visibleForTesting
static int computeLongestInheritancePathToObject(ClassElement element) {
- return _computeLongestInheritancePathToObject(
- element,
- 0,
- <ClassElement>{},
- );
+ return _computeLongestInheritancePathToObject(element, <ClassElement>{});
}
/// Add all of the superinterfaces of the given [type] to the given [set].
@@ -295,6 +296,14 @@
}
}
+ for (var mixin in type.mixins) {
+ if (!mixin.isDartCoreFunction) {
+ if (set.add(mixin)) {
+ _addSuperinterfaces(set, mixin);
+ }
+ }
+ }
+
for (var constraint in type.superclassConstraints) {
if (!constraint.isDartCoreFunction) {
if (set.add(constraint)) {
@@ -333,47 +342,53 @@
/// is used to prevent infinite recursion in the case of a cyclic type
/// structure.
static int _computeLongestInheritancePathToObject(
- ClassElement element, int depth, Set<ClassElement> visitedElements) {
+ ClassElement element, Set<ClassElement> visitedElements) {
// Object case
if (element.isDartCoreObject || visitedElements.contains(element)) {
- return depth;
+ return 0;
}
- int longestPath = 1;
+ int longestPath = 0;
try {
visitedElements.add(element);
- int pathLength;
// loop through each of the superinterfaces recursively calling this
// method and keeping track of the longest path to return
for (InterfaceType interface in element.superclassConstraints) {
- pathLength = _computeLongestInheritancePathToObject(
- interface.element, depth + 1, visitedElements);
- if (pathLength > longestPath) {
- longestPath = pathLength;
- }
+ var pathLength = _computeLongestInheritancePathToObject(
+ interface.element, visitedElements);
+ longestPath = max(longestPath, 1 + pathLength);
}
// loop through each of the superinterfaces recursively calling this
// method and keeping track of the longest path to return
for (InterfaceType interface in element.interfaces) {
- pathLength = _computeLongestInheritancePathToObject(
- interface.element, depth + 1, visitedElements);
- if (pathLength > longestPath) {
- longestPath = pathLength;
- }
+ var pathLength = _computeLongestInheritancePathToObject(
+ interface.element, visitedElements);
+ longestPath = max(longestPath, 1 + pathLength);
}
- // finally, perform this same check on the super type
- // TODO(brianwilkerson) Does this also need to add in the number of mixin
- // classes?
- InterfaceType supertype = element.supertype;
- if (supertype != null) {
- pathLength = _computeLongestInheritancePathToObject(
- supertype.element, depth + 1, visitedElements);
- if (pathLength > longestPath) {
- longestPath = pathLength;
- }
+ var supertype = element.supertype;
+ if (supertype == null) {
+ return longestPath;
}
+
+ var superLength = _computeLongestInheritancePathToObject(
+ supertype.element, visitedElements);
+
+ var mixins = element.mixins;
+ for (var i = 0; i < mixins.length; i++) {
+ // class _X&S&M extends S implements M {}
+ // So, we choose the maximum length from S and M.
+ var mixinLength = _computeLongestInheritancePathToObject(
+ mixins[i].element,
+ visitedElements,
+ );
+ superLength = max(superLength, mixinLength);
+ // For this synthetic class representing the mixin application.
+ superLength++;
+ }
+
+ longestPath = max(longestPath, 1 + superLength);
} finally {
visitedElements.remove(element);
}
diff --git a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
index 30418ae..d99c0e8 100644
--- a/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_upper_bound_helper_test.dart
@@ -15,16 +15,104 @@
main() {
defineReflectiveSuite(() {
- defineReflectiveTests(InterfaceLeastUpperBoundHelperTest);
+ defineReflectiveTests(PathToObjectTest);
+ defineReflectiveTests(SuperinterfaceSetTest);
});
}
@reflectiveTest
-class InterfaceLeastUpperBoundHelperTest extends AbstractTypeSystemTest {
+class PathToObjectTest extends AbstractTypeSystemTest {
@override
final TestTypeProvider typeProvider = TestTypeProvider();
- void test_computeLongestInheritancePathToObject_multipleInterfacePaths() {
+ void test_class_mixins1() {
+ var M1 = mixin_(name: 'M1');
+ expect(_longestPathToObject(M1), 1);
+
+ var A = class_(name: 'A');
+ expect(_longestPathToObject(A), 1);
+
+ // class _X&A&M1 extends A implements M1 {}
+ // length: 2
+ // class X extends _X&A&M1 {}
+ // length: 3
+ var X = class_(
+ name: 'X',
+ superType: interfaceTypeNone(A),
+ mixins: [
+ interfaceTypeNone(M1),
+ ],
+ );
+
+ expect(_longestPathToObject(X), 3);
+ }
+
+ void test_class_mixins2() {
+ var M1 = mixin_(name: 'M1');
+ var M2 = mixin_(name: 'M2');
+ expect(_longestPathToObject(M1), 1);
+ expect(_longestPathToObject(M2), 1);
+
+ var A = class_(name: 'A');
+ expect(_longestPathToObject(A), 1);
+
+ // class _X&A&M1 extends A implements M1 {}
+ // length: 2
+ // class _X&A&M1&M2 extends _X&A&M1 implements M2 {}
+ // length: 3
+ // class X extends _X&A&M1&M2 {}
+ // length: 4
+ var X = class_(
+ name: 'X',
+ superType: interfaceTypeNone(A),
+ mixins: [
+ interfaceTypeNone(M1),
+ interfaceTypeNone(M2),
+ ],
+ );
+
+ expect(_longestPathToObject(X), 4);
+ }
+
+ void test_class_mixins_longerViaSecondMixin() {
+ var I1 = class_(name: 'I1');
+ var I2 = class_(name: 'I2', superType: interfaceTypeNone(I1));
+ var I3 = class_(name: 'I3', superType: interfaceTypeNone(I2));
+
+ expect(_longestPathToObject(I1), 1);
+ expect(_longestPathToObject(I2), 2);
+ expect(_longestPathToObject(I3), 3);
+
+ var M1 = mixin_(name: 'M1');
+ var M2 = mixin_(
+ name: 'M2',
+ interfaces: [interfaceTypeNone(I3)],
+ );
+ expect(_longestPathToObject(M1), 1);
+ expect(_longestPathToObject(M2), 4);
+
+ var A = class_(name: 'A'); // length: 1
+ expect(_longestPathToObject(A), 1);
+
+ // class _X&A&M1 extends A implements M1 {}
+ // length: 2
+ // class _X&A&M1&M2 extends _X&A&M1 implements M2 {}
+ // length: 5 = max(1 + _X&A&M1, 1 + M2)
+ // class X extends _X&A&M1&M2 {}
+ // length: 6
+ var X = class_(
+ name: 'X',
+ superType: interfaceTypeNone(A),
+ mixins: [
+ interfaceTypeNone(M1),
+ interfaceTypeNone(M2),
+ ],
+ );
+
+ expect(_longestPathToObject(X), 6);
+ }
+
+ void test_class_multipleInterfacePaths() {
//
// Object
// |
@@ -55,7 +143,7 @@
expect(_longestPathToObject(classE), 4);
}
- void test_computeLongestInheritancePathToObject_multipleSuperclassPaths() {
+ void test_class_multipleSuperclassPaths() {
//
// Object
// |
@@ -84,11 +172,11 @@
expect(_longestPathToObject(classE), 4);
}
- void test_computeLongestInheritancePathToObject_object() {
+ void test_class_object() {
expect(_longestPathToObject(typeProvider.objectType.element), 0);
}
- void test_computeLongestInheritancePathToObject_recursion() {
+ void test_class_recursion() {
ClassElementImpl classA = ElementFactory.classElement2("A");
ClassElementImpl classB =
ElementFactory.classElement("B", interfaceTypeStar(classA));
@@ -96,7 +184,7 @@
expect(_longestPathToObject(classA), 2);
}
- void test_computeLongestInheritancePathToObject_singleInterfacePath() {
+ void test_class_singleInterfacePath() {
//
// Object
// |
@@ -116,7 +204,7 @@
expect(_longestPathToObject(classC), 3);
}
- void test_computeLongestInheritancePathToObject_singleSuperclassPath() {
+ void test_class_singleSuperclassPath() {
//
// Object
// |
@@ -136,7 +224,138 @@
expect(_longestPathToObject(classC), 3);
}
- void test_computeSuperinterfaceSet_genericInterfacePath() {
+ void test_mixin_constraints_interfaces_allSame() {
+ var A = class_(name: 'A');
+ var B = class_(name: 'B');
+ var I = class_(name: 'I');
+ var J = class_(name: 'J');
+ expect(_longestPathToObject(A), 1);
+ expect(_longestPathToObject(B), 1);
+ expect(_longestPathToObject(I), 1);
+ expect(_longestPathToObject(J), 1);
+
+ // The interface of M is:
+ // class _M&A&A implements A, B, I, J {}
+ var M = mixin_(
+ name: 'M',
+ constraints: [
+ interfaceTypeNone(A),
+ interfaceTypeNone(B),
+ ],
+ interfaces: [
+ interfaceTypeNone(I),
+ interfaceTypeNone(J),
+ ],
+ );
+ expect(_longestPathToObject(M), 2);
+ }
+
+ void test_mixin_longerConstraint_1() {
+ var A1 = class_(name: 'A1');
+ var A = class_(
+ name: 'A',
+ superType: interfaceTypeNone(A1),
+ );
+ var B = class_(name: 'B');
+ var I = class_(name: 'I');
+ var J = class_(name: 'J');
+ expect(_longestPathToObject(A), 2);
+ expect(_longestPathToObject(B), 1);
+ expect(_longestPathToObject(I), 1);
+ expect(_longestPathToObject(J), 1);
+
+ // The interface of M is:
+ // class _M&A&A implements A, B, I, J {}
+ var M = mixin_(
+ name: 'M',
+ constraints: [
+ interfaceTypeNone(A),
+ interfaceTypeNone(B),
+ ],
+ interfaces: [
+ interfaceTypeNone(I),
+ interfaceTypeNone(J),
+ ],
+ );
+ expect(_longestPathToObject(M), 3);
+ }
+
+ void test_mixin_longerConstraint_2() {
+ var A = class_(name: 'A');
+ var B1 = class_(name: 'B1');
+ var B = class_(
+ name: 'B',
+ interfaces: [
+ interfaceTypeNone(B1),
+ ],
+ );
+ var I = class_(name: 'I');
+ var J = class_(name: 'J');
+ expect(_longestPathToObject(A), 1);
+ expect(_longestPathToObject(B), 2);
+ expect(_longestPathToObject(I), 1);
+ expect(_longestPathToObject(J), 1);
+
+ // The interface of M is:
+ // class _M&A&A implements A, B, I, J {}
+ var M = mixin_(
+ name: 'M',
+ constraints: [
+ interfaceTypeNone(A),
+ interfaceTypeNone(B),
+ ],
+ interfaces: [
+ interfaceTypeNone(I),
+ interfaceTypeNone(J),
+ ],
+ );
+ expect(_longestPathToObject(M), 3);
+ }
+
+ void test_mixin_longerInterface_1() {
+ var A = class_(name: 'A');
+ var B = class_(name: 'B');
+ var I1 = class_(name: 'I1');
+ var I = class_(
+ name: 'I',
+ interfaces: [
+ interfaceTypeNone(I1),
+ ],
+ );
+ var J = class_(name: 'J');
+ expect(_longestPathToObject(A), 1);
+ expect(_longestPathToObject(B), 1);
+ expect(_longestPathToObject(I), 2);
+ expect(_longestPathToObject(J), 1);
+
+ // The interface of M is:
+ // class _M&A&A implements A, B, I, J {}
+ var M = mixin_(
+ name: 'M',
+ constraints: [
+ interfaceTypeNone(A),
+ interfaceTypeNone(B),
+ ],
+ interfaces: [
+ interfaceTypeNone(I),
+ interfaceTypeNone(J),
+ ],
+ );
+ expect(_longestPathToObject(M), 3);
+ }
+
+ int _longestPathToObject(ClassElement element) {
+ return InterfaceLeastUpperBoundHelper.computeLongestInheritancePathToObject(
+ element);
+ }
+}
+
+@reflectiveTest
+class SuperinterfaceSetTest extends AbstractTypeSystemTest {
+ @override
+ final TestTypeProvider typeProvider = TestTypeProvider();
+
+ void test_genericInterfacePath() {
//
// A
// | implements
@@ -200,7 +419,7 @@
);
}
- void test_computeSuperinterfaceSet_genericSuperclassPath() {
+ void test_genericSuperclassPath() {
//
// A
// |
@@ -261,7 +480,7 @@
);
}
- void test_computeSuperinterfaceSet_mixin_constraints() {
+ void test_mixin_constraints() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
@@ -291,7 +510,7 @@
);
}
- void test_computeSuperinterfaceSet_mixin_constraints_object() {
+ void test_mixin_constraints_object() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var mixinM = mixin_(name: 'M');
@@ -303,7 +522,7 @@
);
}
- void test_computeSuperinterfaceSet_mixin_interfaces() {
+ void test_mixin_interfaces() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
@@ -333,7 +552,7 @@
);
}
- void test_computeSuperinterfaceSet_multipleInterfacePaths() {
+ void test_multipleInterfacePaths() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
@@ -379,7 +598,7 @@
);
}
- void test_computeSuperinterfaceSet_multipleSuperclassPaths() {
+ void test_multipleSuperclassPaths() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
@@ -425,7 +644,7 @@
);
}
- void test_computeSuperinterfaceSet_recursion() {
+ void test_recursion() {
var classA = ElementFactory.classElement3(name: 'A');
var instA = InstantiatedClass(classA, const []);
@@ -448,7 +667,7 @@
);
}
- void test_computeSuperinterfaceSet_singleInterfacePath() {
+ void test_singleInterfacePath() {
var instObject = InstantiatedClass.of(typeProvider.objectType);
var classA = ElementFactory.classElement3(name: 'A');
@@ -485,7 +704,7 @@
);
}
- void test_computeSuperinterfaceSet_singleSuperclassPath() {
+ void test_singleSuperclassPath() {
//
// A
// |
@@ -529,11 +748,6 @@
);
}
- int _longestPathToObject(ClassElement element) {
- return InterfaceLeastUpperBoundHelper.computeLongestInheritancePathToObject(
- element);
- }
-
Set<InstantiatedClass> _superInterfaces(InstantiatedClass type) {
var helper = InterfaceLeastUpperBoundHelper(typeSystem);
return helper.computeSuperinterfaceSet(type);
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index 3372610..77f2918 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -2214,6 +2214,73 @@
assertLUB(aNone, aNone, aNone);
}
+ void test_sharedMixin1() {
+ // mixin M {}
+ // class B with M {}
+ // class C with M {}
+
+ var M = mixin_(name: 'M');
+ var M_none = interfaceTypeNone(M);
+
+ var B = class_(name: 'B', mixins: [M_none]);
+ var B_none = interfaceTypeNone(B);
+
+ var C = class_(name: 'C', mixins: [M_none]);
+ var C_none = interfaceTypeNone(C);
+
+ _checkLeastUpperBound(B_none, C_none, M_none);
+ }
+
+ void test_sharedMixin2() {
+ // mixin M1 {}
+ // mixin M2 {}
+ // mixin M3 {}
+ // class A with M1, M2 {}
+ // class B with M1, M3 {}
+
+ var M1 = mixin_(name: 'M1');
+ var M1_none = interfaceTypeNone(M1);
+
+ var M2 = mixin_(name: 'M2');
+ var M2_none = interfaceTypeNone(M2);
+
+ var M3 = mixin_(name: 'M3');
+ var M3_none = interfaceTypeNone(M3);
+
+ var A = class_(name: 'A', mixins: [M1_none, M2_none]);
+ var A_none = interfaceTypeNone(A);
+
+ var B = class_(name: 'B', mixins: [M1_none, M3_none]);
+ var B_none = interfaceTypeNone(B);
+
+ _checkLeastUpperBound(A_none, B_none, M1_none);
+ }
+
+ void test_sharedMixin3() {
+ // mixin M1 {}
+ // mixin M2 {}
+ // mixin M3 {}
+ // class A with M2, M1 {}
+ // class B with M3, M1 {}
+
+ var M1 = mixin_(name: 'M1');
+ var M1_none = interfaceTypeNone(M1);
+
+ var M2 = mixin_(name: 'M2');
+ var M2_none = interfaceTypeNone(M2);
+
+ var M3 = mixin_(name: 'M3');
+ var M3_none = interfaceTypeNone(M3);
+
+ var A = class_(name: 'A', mixins: [M2_none, M1_none]);
+ var A_none = interfaceTypeNone(A);
+
+ var B = class_(name: 'B', mixins: [M3_none, M1_none]);
+ var B_none = interfaceTypeNone(B);
+
+ _checkLeastUpperBound(A_none, B_none, M1_none);
+ }
+
void test_sharedSuperclass1() {
// class A {}
// class B extends A {}
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index 8f0d5e3..2b49d2b 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -1,10 +1,10 @@
-## 0.3.1-dev
+## 0.4.0
- Deprecated the class `DartChangeBuilder` and enhanced `ChangeBuilder` to be
the replacement for it.
- Deprecated the method `ChangeBuilder.addFileEdit` and introduced
`ChangeBuilder.addDartFileEdit` and `ChangeBuilder.addGenericFileEdit` to be
the replacements for it.
-- Bump maximum supported version of the analyzer to `<0.41.0`.
+- Changed the support version range of the analyzer to `>=0.41.0 <0.42.0`.
## 0.3.0
- Removed deprecated `Plugin.getResolveResult`. Use `getResolvedUnitResult`.
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index b48c87b..2401bdb 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,6 +1,6 @@
name: analyzer_plugin
description: A framework and support code for building plugins for the analysis server.
-version: 0.3.0
+version: 0.4.0
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
@@ -8,7 +8,7 @@
sdk: '>=2.9.0 <3.0.0'
dependencies:
- analyzer: '>=0.39.12 <0.41.0'
+ analyzer: '>=0.41.0 <0.42.0'
dart_style: '^1.2.0'
meta: ^1.2.3
pub_semver: '^1.3.2'
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 85cca3c..eb037e7 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -1339,7 +1339,8 @@
createIsSetRead: () => _createFieldGet(_lateIsSetField),
createIsSetWrite: (Expression value) =>
_createFieldSet(_lateIsSetField, value),
- isSetEncoding: isSetEncoding);
+ isSetEncoding: isSetEncoding,
+ forField: true);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index c2d9461..de26ae2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5838,17 +5838,30 @@
createIsSetRead: createIsSetRead,
isSetEncoding: isSetEncoding,
forField: false)
- : late_lowering.createGetterWithInitializer(
- inferrer.coreTypes,
- fileOffset,
- node.name,
- node.type,
- node.initializer,
- createVariableRead: createVariableRead,
- createVariableWrite: createVariableWrite,
- createIsSetRead: createIsSetRead,
- createIsSetWrite: createIsSetWrite,
- isSetEncoding: isSetEncoding),
+ : (node.isFinal
+ ? late_lowering.createGetterWithInitializerWithRecheck(
+ inferrer.coreTypes,
+ fileOffset,
+ node.name,
+ node.type,
+ node.initializer,
+ createVariableRead: createVariableRead,
+ createVariableWrite: createVariableWrite,
+ createIsSetRead: createIsSetRead,
+ createIsSetWrite: createIsSetWrite,
+ isSetEncoding: isSetEncoding,
+ forField: false)
+ : late_lowering.createGetterWithInitializer(
+ inferrer.coreTypes,
+ fileOffset,
+ node.name,
+ node.type,
+ node.initializer,
+ createVariableRead: createVariableRead,
+ createVariableWrite: createVariableWrite,
+ createIsSetRead: createIsSetRead,
+ createIsSetWrite: createIsSetWrite,
+ isSetEncoding: isSetEncoding)),
returnType: node.type))
..fileOffset = fileOffset;
getVariable.type =
diff --git a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
index a2c6f50..ce8d986 100644
--- a/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/late_lowering.dart
@@ -16,13 +16,10 @@
const String lateLocalSetterSuffix = '#set';
/// Creates the body for the synthesized getter used to encode the lowering
-/// of a late non-final field with an initializer or a late local with an
-/// initializer.
+/// of a late non-final field or local with an initializer.
///
-/// Late final field needs to detect writes during initialization and therefore
-/// uses [createGetterWithInitializerWithRecheck] instead. Late final locals
-/// cannot have writes during initialization since they are not in scope in
-/// their own initializer.
+/// Late final fields and locals need to detect writes during initialization and
+/// therefore uses [createGetterWithInitializerWithRecheck] instead.
Statement createGetterWithInitializer(CoreTypes coreTypes, int fileOffset,
String name, DartType type, Expression initializer,
{Expression createVariableRead({bool needsPromotion}),
@@ -120,23 +117,23 @@
}
/// Creates the body for the synthesized getter used to encode the lowering
-/// of a late final field with an initializer.
-///
-/// A late final field needs to detect writes during initialization for
-/// which a `LateInitializationError` should be thrown. Late final locals
-/// cannot have writes during initialization since they are not in scope in
-/// their own initializer.
+/// of a late final field or local with an initializer.
Statement createGetterWithInitializerWithRecheck(CoreTypes coreTypes,
int fileOffset, String name, DartType type, Expression initializer,
{Expression createVariableRead({bool needsPromotion}),
Expression createVariableWrite(Expression value),
Expression createIsSetRead(),
Expression createIsSetWrite(Expression value),
- IsSetEncoding isSetEncoding}) {
+ IsSetEncoding isSetEncoding,
+ bool forField}) {
+ assert(forField != null);
+ Constructor constructor = forField
+ ? coreTypes.lateInitializationFieldAssignedDuringInitializationConstructor
+ : coreTypes
+ .lateInitializationLocalAssignedDuringInitializationConstructor;
Expression exception = new Throw(
new ConstructorInvocation(
- coreTypes
- .lateInitializationFieldAssignedDuringInitializationConstructor,
+ constructor,
new Arguments(
<Expression>[new StringLiteral(name)..fileOffset = fileOffset])
..fileOffset = fileOffset)
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 68fdfc8..a15a5c9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -289,7 +289,9 @@
origin: remoteContext);
}
- bool isTypeCast = localContext != null &&
+ // TODO(johnniwinther): This check wasn't called from InterfaceType and
+ // is currently very broken. Disabling for now.
+ /*bool isTypeCast = localContext != null &&
localContext is AsExpression &&
localContext.isTypeError;
// Don't check cases like foo(x as{TypeError} T). In cases where foo comes
@@ -329,7 +331,7 @@
"Found a legacy type '${node}' in an opted-in library.",
origin: remoteContext);
}
- }
+ }*/
super.defaultDartType(node);
}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart b/pkg/front_end/testcases/late_lowering/issue44372.dart
new file mode 100644
index 0000000..2550604
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart
@@ -0,0 +1,43 @@
+// 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 file.
+
+main(List<String> args) {
+ late int Function() recursiveInitLocal;
+ late final int local = recursiveInitLocal();
+
+ bool doRecursiveInitLocal = true;
+ recursiveInitLocal = () {
+ print('Executing initializer');
+ if (doRecursiveInitLocal) {
+ doRecursiveInitLocal = false;
+ print('Trigger recursive initialization');
+ int val = local;
+ print('Final local has value $val');
+ print('Returning 4 from initializer');
+ return 4;
+ }
+ print('Returning 3 from initializer');
+ return 3;
+ };
+
+ throws(() {
+ int val = local;
+ print('Final local has value $val');
+ }, "Read local");
+}
+
+expect(expected, actual) {
+ if (expected != actual) throw 'Expected $expected, actual $actual';
+}
+
+throws(f(), String message) {
+ dynamic value;
+ try {
+ value = f();
+ } on LateInitializationError catch (e) {
+ print(e);
+ return;
+ }
+ throw '$message: $value';
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect
new file mode 100644
index 0000000..cd8b66b
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.outline.expect
@@ -0,0 +1,10 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String> args) → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
+static method throws(() → dynamic f, core::String message) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect
new file mode 100644
index 0000000..016d6f4
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+ () →? core::int recursiveInitLocal;
+ function #recursiveInitLocal#get() → () → core::int
+ return let final () →? core::int #t1 = recursiveInitLocal in #t1.==(null) ?{() → core::int} throw new _in::LateError::localNI("recursiveInitLocal") : #t1{() → core::int};
+ function #recursiveInitLocal#set(() → core::int #t2) → dynamic
+ return recursiveInitLocal = #t2;
+ final core::int? local;
+ function #local#get() → core::int
+ return let final core::int? #t3 = local in #t3.==(null) ?{core::int} let final core::int #t4 = #recursiveInitLocal#get.call().call() in local.==(null) ?{core::int} local = #t4 : throw new _in::LateError::localADI("local") : #t3{core::int};
+ core::bool doRecursiveInitLocal = true;
+ #recursiveInitLocal#set.call(() → core::int {
+ core::print("Executing initializer");
+ if(doRecursiveInitLocal) {
+ doRecursiveInitLocal = false;
+ core::print("Trigger recursive initialization");
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ core::print("Returning 4 from initializer");
+ return 4;
+ }
+ core::print("Returning 3 from initializer");
+ return 3;
+ });
+ self::throws(() → Null {
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+ dynamic value;
+ try {
+ value = f.call();
+ }
+ on core::LateInitializationError catch(final core::LateInitializationError e) {
+ core::print(e);
+ return;
+ }
+ throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect
new file mode 100644
index 0000000..016d6f4
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+ () →? core::int recursiveInitLocal;
+ function #recursiveInitLocal#get() → () → core::int
+ return let final () →? core::int #t1 = recursiveInitLocal in #t1.==(null) ?{() → core::int} throw new _in::LateError::localNI("recursiveInitLocal") : #t1{() → core::int};
+ function #recursiveInitLocal#set(() → core::int #t2) → dynamic
+ return recursiveInitLocal = #t2;
+ final core::int? local;
+ function #local#get() → core::int
+ return let final core::int? #t3 = local in #t3.==(null) ?{core::int} let final core::int #t4 = #recursiveInitLocal#get.call().call() in local.==(null) ?{core::int} local = #t4 : throw new _in::LateError::localADI("local") : #t3{core::int};
+ core::bool doRecursiveInitLocal = true;
+ #recursiveInitLocal#set.call(() → core::int {
+ core::print("Executing initializer");
+ if(doRecursiveInitLocal) {
+ doRecursiveInitLocal = false;
+ core::print("Trigger recursive initialization");
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ core::print("Returning 4 from initializer");
+ return 4;
+ }
+ core::print("Returning 3 from initializer");
+ return 3;
+ });
+ self::throws(() → Null {
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+ dynamic value;
+ try {
+ value = f.call();
+ }
+ on core::LateInitializationError catch(final core::LateInitializationError e) {
+ core::print(e);
+ return;
+ }
+ throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect
new file mode 100644
index 0000000..59d6aea
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+main(List<String> args) {}
+expect(expected, actual) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..52b9bda
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@
+expect(expected, actual) {}
+main(List<String> args) {}
+throws(f(), String message) {}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect
new file mode 100644
index 0000000..515c1f2
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+ () →? core::int recursiveInitLocal;
+ core::bool #recursiveInitLocal#isSet = false;
+ function #recursiveInitLocal#get() → () → core::int
+ return #recursiveInitLocal#isSet ?{() → core::int} recursiveInitLocal{() → core::int} : throw new _in::LateError::localNI("recursiveInitLocal");
+ function #recursiveInitLocal#set(() → core::int #t1) → dynamic {
+ #recursiveInitLocal#isSet = true;
+ return recursiveInitLocal = #t1;
+ }
+ final core::int? local;
+ core::bool #local#isSet = false;
+ function #local#get() → core::int {
+ if(!#local#isSet) {
+ final core::int #t2 = #recursiveInitLocal#get.call().call();
+ if(#local#isSet)
+ throw new _in::LateError::localADI("local");
+ local = #t2;
+ #local#isSet = true;
+ }
+ return local{core::int};
+ }
+ core::bool doRecursiveInitLocal = true;
+ #recursiveInitLocal#set.call(() → core::int {
+ core::print("Executing initializer");
+ if(doRecursiveInitLocal) {
+ doRecursiveInitLocal = false;
+ core::print("Trigger recursive initialization");
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ core::print("Returning 4 from initializer");
+ return 4;
+ }
+ core::print("Returning 3 from initializer");
+ return 3;
+ });
+ self::throws(() → Null {
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+ dynamic value;
+ try {
+ value = f.call();
+ }
+ on core::LateInitializationError catch(final core::LateInitializationError e) {
+ core::print(e);
+ return;
+ }
+ throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect
new file mode 100644
index 0000000..515c1f2
--- /dev/null
+++ b/pkg/front_end/testcases/late_lowering/issue44372.dart.weak.transformed.expect
@@ -0,0 +1,60 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+static method main(core::List<core::String> args) → dynamic {
+ () →? core::int recursiveInitLocal;
+ core::bool #recursiveInitLocal#isSet = false;
+ function #recursiveInitLocal#get() → () → core::int
+ return #recursiveInitLocal#isSet ?{() → core::int} recursiveInitLocal{() → core::int} : throw new _in::LateError::localNI("recursiveInitLocal");
+ function #recursiveInitLocal#set(() → core::int #t1) → dynamic {
+ #recursiveInitLocal#isSet = true;
+ return recursiveInitLocal = #t1;
+ }
+ final core::int? local;
+ core::bool #local#isSet = false;
+ function #local#get() → core::int {
+ if(!#local#isSet) {
+ final core::int #t2 = #recursiveInitLocal#get.call().call();
+ if(#local#isSet)
+ throw new _in::LateError::localADI("local");
+ local = #t2;
+ #local#isSet = true;
+ }
+ return local{core::int};
+ }
+ core::bool doRecursiveInitLocal = true;
+ #recursiveInitLocal#set.call(() → core::int {
+ core::print("Executing initializer");
+ if(doRecursiveInitLocal) {
+ doRecursiveInitLocal = false;
+ core::print("Trigger recursive initialization");
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ core::print("Returning 4 from initializer");
+ return 4;
+ }
+ core::print("Returning 3 from initializer");
+ return 3;
+ });
+ self::throws(() → Null {
+ core::int val = #local#get.call();
+ core::print("Final local has value ${val}");
+ }, "Read local");
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual))
+ throw "Expected ${expected}, actual ${actual}";
+}
+static method throws(() → dynamic f, core::String message) → dynamic {
+ dynamic value;
+ try {
+ value = f.call();
+ }
+ on core::LateInitializationError catch(final core::LateInitializationError e) {
+ core::print(e);
+ return;
+ }
+ throw "${message}: ${value}";
+}
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
index 8a5dd62..ff4583f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -9,7 +10,7 @@
}
final core::int? lateLocal;
function #lateLocal#get() → core::int
- return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = initLateLocal.call(123) : #t1{core::int};
+ return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} let final core::int #t2 = initLateLocal.call(123) in lateLocal.==(null) ?{core::int} lateLocal = #t2 : throw new _in::LateError::localADI("lateLocal") : #t1{core::int};
self::expect(null, lateLocalInit);
self::expect(123, #lateLocal#get.call());
self::expect(123, lateLocalInit);
@@ -22,7 +23,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T% #t3 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t3;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
index 8a5dd62..ff4583f 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.strong.transformed.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -9,7 +10,7 @@
}
final core::int? lateLocal;
function #lateLocal#get() → core::int
- return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} lateLocal = initLateLocal.call(123) : #t1{core::int};
+ return let final core::int? #t1 = lateLocal in #t1.==(null) ?{core::int} let final core::int #t2 = initLateLocal.call(123) in lateLocal.==(null) ?{core::int} lateLocal = #t2 : throw new _in::LateError::localADI("lateLocal") : #t1{core::int};
self::expect(null, lateLocalInit);
self::expect(123, #lateLocal#get.call());
self::expect(123, lateLocalInit);
@@ -22,7 +23,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T% #t3 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t3;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
index 76adb10..5125e21 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal{core::int};
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T% #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
diff --git a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
index 76adb10..5125e21 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_local_with_initializer.dart.weak.transformed.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal{core::int};
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T% {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T% #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal{T%};
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
index ffb22f1..6292291 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int? #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal;
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T? #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal;
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
index ffb22f1..6292291 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.strong.transformed.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int? #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal;
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T? #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal;
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
index ffb22f1..6292291 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int? #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal;
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T? #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal;
diff --git a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
index ffb22f1..6292291 100644
--- a/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_final_nullable_local_with_initializer.dart.weak.transformed.expect
@@ -1,6 +1,7 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic {
core::int? lateLocalInit;
@@ -11,7 +12,10 @@
core::bool #lateLocal#isSet = false;
function #lateLocal#get() → core::int? {
if(!#lateLocal#isSet) {
- lateLocal = initLateLocal.call(123);
+ final core::int? #t1 = initLateLocal.call(123);
+ if(#lateLocal#isSet)
+ throw new _in::LateError::localADI("lateLocal");
+ lateLocal = #t1;
#lateLocal#isSet = true;
}
return lateLocal;
@@ -28,7 +32,10 @@
core::bool #lateGenericLocal#isSet = false;
function #lateGenericLocal#get() → T? {
if(!#lateGenericLocal#isSet) {
- lateGenericLocal = initLateGenericLocal.call(value);
+ final T? #t2 = initLateGenericLocal.call(value);
+ if(#lateGenericLocal#isSet)
+ throw new _in::LateError::localADI("lateGenericLocal");
+ lateGenericLocal = #t2;
#lateGenericLocal#isSet = true;
}
return lateGenericLocal;
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect
index b67f124..1bb57d1 100644
--- a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.expect
@@ -110,29 +110,32 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t26 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t26;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
}
final core::int? nonNullableInitializedFinalLocal;
function #nonNullableInitializedFinalLocal#get() → core::int
- return let final core::int? #t26 = nonNullableInitializedFinalLocal in #t26.==(null) ?{core::int} nonNullableInitializedFinalLocal = 0 : #t26{core::int};
+ return let final core::int? #t27 = nonNullableInitializedFinalLocal in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in nonNullableInitializedFinalLocal.==(null) ?{core::int} nonNullableInitializedFinalLocal = #t28 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t27{core::int};
}
static get uninitializedNonFinalTopLevelField() → core::int
- return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
-static set uninitializedNonFinalTopLevelField(core::int #t28) → void
- self::_#uninitializedNonFinalTopLevelField = #t28;
+ return let final core::int? #t29 = self::_#uninitializedNonFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t29{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t30) → void
+ self::_#uninitializedNonFinalTopLevelField = #t30;
static get uninitializedFinalTopLevelField() → core::int
- return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
-static set uninitializedFinalTopLevelField(core::int #t30) → void
+ return let final core::int? #t31 = self::_#uninitializedFinalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t31{core::int};
+static set uninitializedFinalTopLevelField(core::int #t32) → void
if(self::_#uninitializedFinalTopLevelField.==(null))
- self::_#uninitializedFinalTopLevelField = #t30;
+ self::_#uninitializedFinalTopLevelField = #t32;
else
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
static get initializedNonFinalTopLevelField() → core::int
- return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
-static set initializedNonFinalTopLevelField(core::int #t32) → void
- self::_#initializedNonFinalTopLevelField = #t32;
+ return let final core::int? #t33 = self::_#initializedNonFinalTopLevelField in #t33.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t33{core::int};
+static set initializedNonFinalTopLevelField(core::int #t34) → void
+ self::_#initializedNonFinalTopLevelField = #t34;
static get initializedFinalTopLevelField() → core::int
- return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
+ return let final core::int? #t35 = self::_#initializedFinalTopLevelField in #t35.==(null) ?{core::int} let final core::int #t36 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t36 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t35{core::int};
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect
index b3a9855..a71870d 100644
--- a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.strong.transformed.expect
@@ -110,36 +110,40 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t26 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t26;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
}
final core::int? nonNullableInitializedFinalLocal;
function #nonNullableInitializedFinalLocal#get() → core::int
- return let final core::int? #t26 = nonNullableInitializedFinalLocal in #t26.==(null) ?{core::int} nonNullableInitializedFinalLocal = 0 : #t26{core::int};
+ return let final core::int? #t27 = nonNullableInitializedFinalLocal in #t27.==(null) ?{core::int} let final core::int #t28 = 0 in nonNullableInitializedFinalLocal.==(null) ?{core::int} nonNullableInitializedFinalLocal = #t28 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t27{core::int};
}
static get uninitializedNonFinalTopLevelField() → core::int
- return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
-static set uninitializedNonFinalTopLevelField(core::int #t28) → void
- self::_#uninitializedNonFinalTopLevelField = #t28;
+ return let final core::int? #t29 = self::_#uninitializedNonFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t29{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t30) → void
+ self::_#uninitializedNonFinalTopLevelField = #t30;
static get uninitializedFinalTopLevelField() → core::int
- return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
-static set uninitializedFinalTopLevelField(core::int #t30) → void
+ return let final core::int? #t31 = self::_#uninitializedFinalTopLevelField in #t31.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t31{core::int};
+static set uninitializedFinalTopLevelField(core::int #t32) → void
if(self::_#uninitializedFinalTopLevelField.==(null))
- self::_#uninitializedFinalTopLevelField = #t30;
+ self::_#uninitializedFinalTopLevelField = #t32;
else
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
static get initializedNonFinalTopLevelField() → core::int
- return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
-static set initializedNonFinalTopLevelField(core::int #t32) → void
- self::_#initializedNonFinalTopLevelField = #t32;
+ return let final core::int? #t33 = self::_#initializedNonFinalTopLevelField in #t33.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t33{core::int};
+static set initializedNonFinalTopLevelField(core::int #t34) → void
+ self::_#initializedNonFinalTopLevelField = #t34;
static get initializedFinalTopLevelField() → core::int
- return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
+ return let final core::int? #t35 = self::_#initializedFinalTopLevelField in #t35.==(null) ?{core::int} let final core::int #t36 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t36 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t35{core::int};
Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:30:25 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:35:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:18:18 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///late_lowering_bitmasks.dart:24:16 -> IntConstant(0)
-Extra constant evaluation: evaluated: 224, effectively constant: 3
+Extra constant evaluation: evaluated: 235, effectively constant: 4
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect
index 0bc36f5..e5d34d1 100644
--- a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.expect
@@ -174,7 +174,10 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t23 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t23;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
@@ -183,45 +186,48 @@
core::bool #nonNullableInitializedFinalLocal#isSet = false;
function #nonNullableInitializedFinalLocal#get() → core::int {
if(!#nonNullableInitializedFinalLocal#isSet) {
- nonNullableInitializedFinalLocal = 0;
+ final core::int #t24 = 0;
+ if(#nonNullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+ nonNullableInitializedFinalLocal = #t24;
#nonNullableInitializedFinalLocal#isSet = true;
}
return nonNullableInitializedFinalLocal{core::int};
}
}
static get uninitializedNonFinalTopLevelField() → core::int
- return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
-static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
+ return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t26) → void {
self::_#uninitializedNonFinalTopLevelField#isSet = true;
- self::_#uninitializedNonFinalTopLevelField = #t24;
+ self::_#uninitializedNonFinalTopLevelField = #t26;
}
static get uninitializedFinalTopLevelField() → core::int
- return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
-static set uninitializedFinalTopLevelField(core::int #t26) → void
+ return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t28) → void
if(self::_#uninitializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
else {
self::_#uninitializedFinalTopLevelField#isSet = true;
- self::_#uninitializedFinalTopLevelField = #t26;
+ self::_#uninitializedFinalTopLevelField = #t28;
}
static get initializedNonFinalTopLevelField() → core::int {
if(!self::_#initializedNonFinalTopLevelField#isSet) {
self::_#initializedNonFinalTopLevelField = 0;
self::_#initializedNonFinalTopLevelField#isSet = true;
}
- return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
+ return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29{core::int};
}
-static set initializedNonFinalTopLevelField(core::int #t28) → void {
+static set initializedNonFinalTopLevelField(core::int #t30) → void {
self::_#initializedNonFinalTopLevelField#isSet = true;
- self::_#initializedNonFinalTopLevelField = #t28;
+ self::_#initializedNonFinalTopLevelField = #t30;
}
static get initializedFinalTopLevelField() → core::int {
if(!self::_#initializedFinalTopLevelField#isSet) {
- final core::int #t29 = 0;
+ final core::int #t31 = 0;
if(self::_#initializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
- self::_#initializedFinalTopLevelField = #t29;
+ self::_#initializedFinalTopLevelField = #t31;
self::_#initializedFinalTopLevelField#isSet = true;
}
- return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
+ return let final core::int? #t32 = self::_#initializedFinalTopLevelField in #t32{core::int};
}
diff --git a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect
index 0bc36f5..e5d34d1 100644
--- a/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/late_lowering_bitmasks.dart.weak.transformed.expect
@@ -174,7 +174,10 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t23 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t23;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
@@ -183,45 +186,48 @@
core::bool #nonNullableInitializedFinalLocal#isSet = false;
function #nonNullableInitializedFinalLocal#get() → core::int {
if(!#nonNullableInitializedFinalLocal#isSet) {
- nonNullableInitializedFinalLocal = 0;
+ final core::int #t24 = 0;
+ if(#nonNullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+ nonNullableInitializedFinalLocal = #t24;
#nonNullableInitializedFinalLocal#isSet = true;
}
return nonNullableInitializedFinalLocal{core::int};
}
}
static get uninitializedNonFinalTopLevelField() → core::int
- return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
-static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
+ return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t26) → void {
self::_#uninitializedNonFinalTopLevelField#isSet = true;
- self::_#uninitializedNonFinalTopLevelField = #t24;
+ self::_#uninitializedNonFinalTopLevelField = #t26;
}
static get uninitializedFinalTopLevelField() → core::int
- return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
-static set uninitializedFinalTopLevelField(core::int #t26) → void
+ return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t28) → void
if(self::_#uninitializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
else {
self::_#uninitializedFinalTopLevelField#isSet = true;
- self::_#uninitializedFinalTopLevelField = #t26;
+ self::_#uninitializedFinalTopLevelField = #t28;
}
static get initializedNonFinalTopLevelField() → core::int {
if(!self::_#initializedNonFinalTopLevelField#isSet) {
self::_#initializedNonFinalTopLevelField = 0;
self::_#initializedNonFinalTopLevelField#isSet = true;
}
- return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
+ return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29{core::int};
}
-static set initializedNonFinalTopLevelField(core::int #t28) → void {
+static set initializedNonFinalTopLevelField(core::int #t30) → void {
self::_#initializedNonFinalTopLevelField#isSet = true;
- self::_#initializedNonFinalTopLevelField = #t28;
+ self::_#initializedNonFinalTopLevelField = #t30;
}
static get initializedFinalTopLevelField() → core::int {
if(!self::_#initializedFinalTopLevelField#isSet) {
- final core::int #t29 = 0;
+ final core::int #t31 = 0;
if(self::_#initializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
- self::_#initializedFinalTopLevelField = #t29;
+ self::_#initializedFinalTopLevelField = #t31;
self::_#initializedFinalTopLevelField#isSet = true;
}
- return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
+ return let final core::int? #t32 = self::_#initializedFinalTopLevelField in #t32{core::int};
}
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect
index d63b6e3..df92880 100644
--- a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.expect
@@ -106,29 +106,32 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t24 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t24;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
}
final core::int? nonNullableInitializedFinalLocal;
function #nonNullableInitializedFinalLocal#get() → core::int
- return let final core::int? #t24 = nonNullableInitializedFinalLocal in #t24.==(null) ?{core::int} nonNullableInitializedFinalLocal = 0 : #t24{core::int};
+ return let final core::int? #t25 = nonNullableInitializedFinalLocal in #t25.==(null) ?{core::int} let final core::int #t26 = 0 in nonNullableInitializedFinalLocal.==(null) ?{core::int} nonNullableInitializedFinalLocal = #t26 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t25{core::int};
}
static get uninitializedNonFinalTopLevelField() → core::int
- return let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t25{core::int};
-static set uninitializedNonFinalTopLevelField(core::int #t26) → void
- self::_#uninitializedNonFinalTopLevelField = #t26;
+ return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t28) → void
+ self::_#uninitializedNonFinalTopLevelField = #t28;
static get uninitializedFinalTopLevelField() → core::int
- return let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t27{core::int};
-static set uninitializedFinalTopLevelField(core::int #t28) → void
+ return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
+static set uninitializedFinalTopLevelField(core::int #t30) → void
if(self::_#uninitializedFinalTopLevelField.==(null))
- self::_#uninitializedFinalTopLevelField = #t28;
+ self::_#uninitializedFinalTopLevelField = #t30;
else
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
static get initializedNonFinalTopLevelField() → core::int
- return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t29{core::int};
-static set initializedNonFinalTopLevelField(core::int #t30) → void
- self::_#initializedNonFinalTopLevelField = #t30;
+ return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
+static set initializedNonFinalTopLevelField(core::int #t32) → void
+ self::_#initializedNonFinalTopLevelField = #t32;
static get initializedFinalTopLevelField() → core::int
- return let final core::int? #t31 = self::_#initializedFinalTopLevelField in #t31.==(null) ?{core::int} let final core::int #t32 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t32 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t31{core::int};
+ return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect
index 23aeb4d..c2964fd 100644
--- a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.strong.transformed.expect
@@ -106,36 +106,40 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t24 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t24;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
}
final core::int? nonNullableInitializedFinalLocal;
function #nonNullableInitializedFinalLocal#get() → core::int
- return let final core::int? #t24 = nonNullableInitializedFinalLocal in #t24.==(null) ?{core::int} nonNullableInitializedFinalLocal = 0 : #t24{core::int};
+ return let final core::int? #t25 = nonNullableInitializedFinalLocal in #t25.==(null) ?{core::int} let final core::int #t26 = 0 in nonNullableInitializedFinalLocal.==(null) ?{core::int} nonNullableInitializedFinalLocal = #t26 : throw new _in::LateError::localADI("nonNullableInitializedFinalLocal") : #t25{core::int};
}
static get uninitializedNonFinalTopLevelField() → core::int
- return let final core::int? #t25 = self::_#uninitializedNonFinalTopLevelField in #t25.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t25{core::int};
-static set uninitializedNonFinalTopLevelField(core::int #t26) → void
- self::_#uninitializedNonFinalTopLevelField = #t26;
+ return let final core::int? #t27 = self::_#uninitializedNonFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField") : #t27{core::int};
+static set uninitializedNonFinalTopLevelField(core::int #t28) → void
+ self::_#uninitializedNonFinalTopLevelField = #t28;
static get uninitializedFinalTopLevelField() → core::int
- return let final core::int? #t27 = self::_#uninitializedFinalTopLevelField in #t27.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t27{core::int};
-static set uninitializedFinalTopLevelField(core::int #t28) → void
+ return let final core::int? #t29 = self::_#uninitializedFinalTopLevelField in #t29.==(null) ?{core::int} throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField") : #t29{core::int};
+static set uninitializedFinalTopLevelField(core::int #t30) → void
if(self::_#uninitializedFinalTopLevelField.==(null))
- self::_#uninitializedFinalTopLevelField = #t28;
+ self::_#uninitializedFinalTopLevelField = #t30;
else
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
static get initializedNonFinalTopLevelField() → core::int
- return let final core::int? #t29 = self::_#initializedNonFinalTopLevelField in #t29.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t29{core::int};
-static set initializedNonFinalTopLevelField(core::int #t30) → void
- self::_#initializedNonFinalTopLevelField = #t30;
+ return let final core::int? #t31 = self::_#initializedNonFinalTopLevelField in #t31.==(null) ?{core::int} self::_#initializedNonFinalTopLevelField = 0 : #t31{core::int};
+static set initializedNonFinalTopLevelField(core::int #t32) → void
+ self::_#initializedNonFinalTopLevelField = #t32;
static get initializedFinalTopLevelField() → core::int
- return let final core::int? #t31 = self::_#initializedFinalTopLevelField in #t31.==(null) ?{core::int} let final core::int #t32 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t32 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t31{core::int};
+ return let final core::int? #t33 = self::_#initializedFinalTopLevelField in #t33.==(null) ?{core::int} let final core::int #t34 = 0 in self::_#initializedFinalTopLevelField.==(null) ?{core::int} self::_#initializedFinalTopLevelField = #t34 : throw new _in::LateError::fieldADI("initializedFinalTopLevelField") : #t33{core::int};
Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:30:25 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:35:18 -> IntConstant(0)
+Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:18:18 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///main.dart:24:16 -> IntConstant(0)
-Extra constant evaluation: evaluated: 212, effectively constant: 3
+Extra constant evaluation: evaluated: 223, effectively constant: 4
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect
index 91d5d03..e3cd765 100644
--- a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.expect
@@ -167,7 +167,10 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t21 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t21;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
@@ -176,45 +179,48 @@
core::bool #nonNullableInitializedFinalLocal#isSet = false;
function #nonNullableInitializedFinalLocal#get() → core::int {
if(!#nonNullableInitializedFinalLocal#isSet) {
- nonNullableInitializedFinalLocal = 0;
+ final core::int #t22 = 0;
+ if(#nonNullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+ nonNullableInitializedFinalLocal = #t22;
#nonNullableInitializedFinalLocal#isSet = true;
}
return nonNullableInitializedFinalLocal{core::int};
}
}
static get uninitializedNonFinalTopLevelField() → core::int
- return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t21 = self::_#uninitializedNonFinalTopLevelField in #t21{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
-static set uninitializedNonFinalTopLevelField(core::int #t22) → void {
+ return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
self::_#uninitializedNonFinalTopLevelField#isSet = true;
- self::_#uninitializedNonFinalTopLevelField = #t22;
+ self::_#uninitializedNonFinalTopLevelField = #t24;
}
static get uninitializedFinalTopLevelField() → core::int
- return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
-static set uninitializedFinalTopLevelField(core::int #t24) → void
+ return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t26) → void
if(self::_#uninitializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
else {
self::_#uninitializedFinalTopLevelField#isSet = true;
- self::_#uninitializedFinalTopLevelField = #t24;
+ self::_#uninitializedFinalTopLevelField = #t26;
}
static get initializedNonFinalTopLevelField() → core::int {
if(!self::_#initializedNonFinalTopLevelField#isSet) {
self::_#initializedNonFinalTopLevelField = 0;
self::_#initializedNonFinalTopLevelField#isSet = true;
}
- return let final core::int? #t25 = self::_#initializedNonFinalTopLevelField in #t25{core::int};
+ return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
}
-static set initializedNonFinalTopLevelField(core::int #t26) → void {
+static set initializedNonFinalTopLevelField(core::int #t28) → void {
self::_#initializedNonFinalTopLevelField#isSet = true;
- self::_#initializedNonFinalTopLevelField = #t26;
+ self::_#initializedNonFinalTopLevelField = #t28;
}
static get initializedFinalTopLevelField() → core::int {
if(!self::_#initializedFinalTopLevelField#isSet) {
- final core::int #t27 = 0;
+ final core::int #t29 = 0;
if(self::_#initializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
- self::_#initializedFinalTopLevelField = #t27;
+ self::_#initializedFinalTopLevelField = #t29;
self::_#initializedFinalTopLevelField#isSet = true;
}
- return let final core::int? #t28 = self::_#initializedFinalTopLevelField in #t28{core::int};
+ return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
}
diff --git a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect
index 91d5d03..e3cd765 100644
--- a/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/skip_late_final_uninitialized_instance_fields/main.dart.weak.transformed.expect
@@ -167,7 +167,10 @@
core::bool #nullableInitializedFinalLocal#isSet = false;
function #nullableInitializedFinalLocal#get() → core::int? {
if(!#nullableInitializedFinalLocal#isSet) {
- nullableInitializedFinalLocal = 0;
+ final core::int? #t21 = 0;
+ if(#nullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nullableInitializedFinalLocal");
+ nullableInitializedFinalLocal = #t21;
#nullableInitializedFinalLocal#isSet = true;
}
return nullableInitializedFinalLocal;
@@ -176,45 +179,48 @@
core::bool #nonNullableInitializedFinalLocal#isSet = false;
function #nonNullableInitializedFinalLocal#get() → core::int {
if(!#nonNullableInitializedFinalLocal#isSet) {
- nonNullableInitializedFinalLocal = 0;
+ final core::int #t22 = 0;
+ if(#nonNullableInitializedFinalLocal#isSet)
+ throw new _in::LateError::localADI("nonNullableInitializedFinalLocal");
+ nonNullableInitializedFinalLocal = #t22;
#nonNullableInitializedFinalLocal#isSet = true;
}
return nonNullableInitializedFinalLocal{core::int};
}
}
static get uninitializedNonFinalTopLevelField() → core::int
- return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t21 = self::_#uninitializedNonFinalTopLevelField in #t21{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
-static set uninitializedNonFinalTopLevelField(core::int #t22) → void {
+ return self::_#uninitializedNonFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedNonFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedNonFinalTopLevelField");
+static set uninitializedNonFinalTopLevelField(core::int #t24) → void {
self::_#uninitializedNonFinalTopLevelField#isSet = true;
- self::_#uninitializedNonFinalTopLevelField = #t22;
+ self::_#uninitializedNonFinalTopLevelField = #t24;
}
static get uninitializedFinalTopLevelField() → core::int
- return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t23 = self::_#uninitializedFinalTopLevelField in #t23{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
-static set uninitializedFinalTopLevelField(core::int #t24) → void
+ return self::_#uninitializedFinalTopLevelField#isSet ?{core::int} let final core::int? #t25 = self::_#uninitializedFinalTopLevelField in #t25{core::int} : throw new _in::LateError::fieldNI("uninitializedFinalTopLevelField");
+static set uninitializedFinalTopLevelField(core::int #t26) → void
if(self::_#uninitializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldAI("uninitializedFinalTopLevelField");
else {
self::_#uninitializedFinalTopLevelField#isSet = true;
- self::_#uninitializedFinalTopLevelField = #t24;
+ self::_#uninitializedFinalTopLevelField = #t26;
}
static get initializedNonFinalTopLevelField() → core::int {
if(!self::_#initializedNonFinalTopLevelField#isSet) {
self::_#initializedNonFinalTopLevelField = 0;
self::_#initializedNonFinalTopLevelField#isSet = true;
}
- return let final core::int? #t25 = self::_#initializedNonFinalTopLevelField in #t25{core::int};
+ return let final core::int? #t27 = self::_#initializedNonFinalTopLevelField in #t27{core::int};
}
-static set initializedNonFinalTopLevelField(core::int #t26) → void {
+static set initializedNonFinalTopLevelField(core::int #t28) → void {
self::_#initializedNonFinalTopLevelField#isSet = true;
- self::_#initializedNonFinalTopLevelField = #t26;
+ self::_#initializedNonFinalTopLevelField = #t28;
}
static get initializedFinalTopLevelField() → core::int {
if(!self::_#initializedFinalTopLevelField#isSet) {
- final core::int #t27 = 0;
+ final core::int #t29 = 0;
if(self::_#initializedFinalTopLevelField#isSet)
throw new _in::LateError::fieldADI("initializedFinalTopLevelField");
- self::_#initializedFinalTopLevelField = #t27;
+ self::_#initializedFinalTopLevelField = #t29;
self::_#initializedFinalTopLevelField#isSet = true;
}
- return let final core::int? #t28 = self::_#initializedFinalTopLevelField in #t28{core::int};
+ return let final core::int? #t30 = self::_#initializedFinalTopLevelField in #t30{core::int};
}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
index 9f76172..9d4ef45 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.expect
@@ -42,14 +42,14 @@
throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
- return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
+ return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(nullableFinalTopLevelLocalWithInitializer) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
final core::int? nonNullableFinalTopLevelLocalWithInitializer;
function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
- return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+ return let final core::int? #t15 = nonNullableFinalTopLevelLocalWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in nonNullableFinalTopLevelLocalWithInitializer.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15{core::int};
Null neverLocal;
function #neverLocal#get() → Never
- return let final Never? #t15 = neverLocal in #t15.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t15{Never};
- function #neverLocal#set(Never #t16) → dynamic
- return neverLocal = #t16;
+ return let final Never? #t17 = neverLocal in #t17.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+ function #neverLocal#set(Never #t18) → dynamic
+ return neverLocal = #t18;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
index 9f76172..1dfd282 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.strong.transformed.expect
@@ -42,14 +42,20 @@
throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
- return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
+ return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(nullableFinalTopLevelLocalWithInitializer) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
final core::int? nonNullableFinalTopLevelLocalWithInitializer;
function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
- return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in #t14.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+ return let final core::int? #t15 = nonNullableFinalTopLevelLocalWithInitializer in #t15.==(null) ?{core::int} let final core::int #t16 = 0 in nonNullableFinalTopLevelLocalWithInitializer.==(null) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15{core::int};
Null neverLocal;
function #neverLocal#get() → Never
- return let final Never? #t15 = neverLocal in #t15.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t15{Never};
- function #neverLocal#set(Never #t16) → dynamic
- return neverLocal = #t16;
+ return let final Never? #t17 = neverLocal in #t17.==(null) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+ function #neverLocal#set(Never #t18) → dynamic
+ return neverLocal = #t18;
}
static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:12:19 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:13:18 -> IntConstant(0)
+Extra constant evaluation: evaluated: 108, effectively constant: 2
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
index c2d22e5..9a53f0d 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.expect
@@ -42,14 +42,14 @@
throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
- return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
+ return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(nullableFinalTopLevelLocalWithInitializer) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
final core::int? nonNullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
- return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t14) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+ return let final core::int #t15 = nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(nonNullableFinalTopLevelLocalWithInitializer) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15;
Null neverLocal = _in::createSentinel<Never>();
function #neverLocal#get() → Never
- return let final Never? #t15 = neverLocal in _in::isSentinel(#t15) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t15{Never};
- function #neverLocal#set(Never #t16) → dynamic
- return neverLocal = #t16;
+ return let final Never? #t17 = neverLocal in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+ function #neverLocal#set(Never #t18) → dynamic
+ return neverLocal = #t18;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
index c2d22e5..b4188db 100644
--- a/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering_sentinel/late_locals.dart.weak.transformed.expect
@@ -42,14 +42,20 @@
throw new _in::LateError::localAI("nonNullableFinalTopLevelLocal");
final core::int? nullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int?>();
function #nullableFinalTopLevelLocalWithInitializer#get() → core::int?
- return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = null : #t13{core::int?};
+ return let final core::int? #t13 = nullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t13) ?{core::int?} let final core::int? #t14 = null in _in::isSentinel(nullableFinalTopLevelLocalWithInitializer) ?{core::int?} nullableFinalTopLevelLocalWithInitializer = #t14 : throw new _in::LateError::localADI("nullableFinalTopLevelLocalWithInitializer") : #t13;
final core::int? nonNullableFinalTopLevelLocalWithInitializer = _in::createSentinel<core::int>();
function #nonNullableFinalTopLevelLocalWithInitializer#get() → core::int
- return let final core::int? #t14 = nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t14) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = 0 : #t14{core::int};
+ return let final core::int #t15 = nonNullableFinalTopLevelLocalWithInitializer in _in::isSentinel(#t15) ?{core::int} let final core::int #t16 = 0 in _in::isSentinel(nonNullableFinalTopLevelLocalWithInitializer) ?{core::int} nonNullableFinalTopLevelLocalWithInitializer = #t16 : throw new _in::LateError::localADI("nonNullableFinalTopLevelLocalWithInitializer") : #t15;
Null neverLocal = _in::createSentinel<Never>();
function #neverLocal#get() → Never
- return let final Never? #t15 = neverLocal in _in::isSentinel(#t15) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t15{Never};
- function #neverLocal#set(Never #t16) → dynamic
- return neverLocal = #t16;
+ return let final Never? #t17 = neverLocal in _in::isSentinel(#t17) ?{Never} throw new _in::LateError::localNI("neverLocal") : #t17{Never};
+ function #neverLocal#set(Never #t18) → dynamic
+ return neverLocal = #t18;
}
static method main() → dynamic {}
+
+
+Extra constant evaluation status:
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:12:19 -> NullConstant(null)
+Evaluated: VariableGet @ org-dartlang-testcase:///late_locals.dart:13:18 -> IntConstant(0)
+Extra constant evaluation: evaluated: 113, effectively constant: 2
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart
new file mode 100644
index 0000000..7980d5f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart
@@ -0,0 +1,13 @@
+// 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 file.
+
+// @dart=2.9
+
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+
+Typedef method2() => (r) => 0;
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect
new file mode 100644
index 0000000..90cf0f0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+// @dart = 2.9
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+Typedef method2() => (r) => 0;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..90cf0f0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+// @dart = 2.9
+import 'typedef_from_opt_in_lib.dart';
+
+Handler method1() => (Request r) async => new Response();
+Typedef method2() => (r) => 0;
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
new file mode 100644
index 0000000..95d0805
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "typedef_from_opt_in_lib.dart" as typ;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
+
+static method method1() → (typ::Request) →* FutureOr<typ::Response>
+ return (typ::Request* r) → asy::Future<typ::Response*>* async => new typ::Response::•();
+static method method2() → (core::int?) →* core::int
+ return (core::int* r) → core::int* => 0;
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as typ;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef Handler = (typ::Request) → FutureOr<typ::Response>;
+typedef Typedef = (core::int?) → core::int;
+class Request extends core::Object {
+ synthetic constructor •() → typ::Request
+ : super core::Object::•()
+ ;
+}
+class Response extends core::Object {
+ synthetic constructor •() → typ::Response
+ : super core::Object::•()
+ ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
new file mode 100644
index 0000000..504f220
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
@@ -0,0 +1,58 @@
+library;
+import self as self;
+import "typedef_from_opt_in_lib.dart" as typ;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
+
+static method method1() → (typ::Request) →* FutureOr<typ::Response>
+ return (typ::Request* r) → asy::Future<typ::Response*>* /* originally async */ {
+ final asy::_Future<typ::Response*>* :async_future = new asy::_Future::•<typ::Response*>();
+ core::bool* :is_sync = false;
+ FutureOr<typ::Response*>* :return_value;
+ (dynamic) →* dynamic :async_op_then;
+ (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+ core::int* :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ :return_value = new typ::Response::•();
+ break #L1;
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ };
+static method method2() → (core::int?) →* core::int
+ return (core::int* r) → core::int* => 0;
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as typ;
+import "dart:core" as core;
+
+import "dart:async";
+
+typedef Handler = (typ::Request) → FutureOr<typ::Response>;
+typedef Typedef = (core::int?) → core::int;
+class Request extends core::Object {
+ synthetic constructor •() → typ::Request
+ : super core::Object::•()
+ ;
+}
+class Response extends core::Object {
+ synthetic constructor •() → typ::Response
+ : super core::Object::•()
+ ;
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart
new file mode 100644
index 0000000..851b087
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in_lib.dart
@@ -0,0 +1,13 @@
+// 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 file.
+
+import 'dart:async';
+
+class Request {}
+
+class Response {}
+
+typedef Handler = FutureOr<Response> Function(Request request);
+
+typedef Typedef = int Function(int?);
diff --git a/pkg/frontend_server/README.md b/pkg/frontend_server/README.md
new file mode 100644
index 0000000..afebf6c
--- /dev/null
+++ b/pkg/frontend_server/README.md
@@ -0,0 +1,19 @@
+The frontend_server package is used by both the flutter command line tool and the frontend_server_client package (used by webdev and package:test).
+
+## API Stability
+
+Changes to the command line API or behavior should be tested against the follwing test suites (in addition to normal HHH testing):
+ * flutter_tools: https://github.com/flutter/flutter/tree/master/packages/flutter_tools
+ * frontend_server_client: https://github.com/dart-lang/webdev/tree/master/frontend_server_client
+
+Otherwise these changes will need to be carefully coordinated with the flutter tooling and frontend_server_client teams.
+
+This API stability does not cover any of the source code APIs.
+
+
+### Stable subset
+
+* The frontend_server kernel compilation and expression evaluation for kernel should be considered "stable".
+* The frontend_server JavaScript compilation is semi-stable, but clients should anticipate coordinated breaking changes in the future.
+* The frontend_server JavaScript expression evaluation is experimental and is expected to change significantly from Dec 2020 through the end of 2021.
+* Specific flags like the --flutter-widget-cache may be added for experimentation and should not be considered stable.
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 8dadff5..e7c5646 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -95,6 +95,7 @@
Procedure _awaitHelperProcedure;
Procedure _boolFromEnvironment;
Constructor _lateInitializationFieldAssignedDuringInitializationConstructor;
+ Constructor _lateInitializationLocalAssignedDuringInitializationConstructor;
Constructor _lateInitializationFieldNotInitializedConstructor;
Constructor _lateInitializationLocalNotInitializedConstructor;
Constructor _lateInitializationFieldAlreadyInitializedConstructor;
@@ -1220,6 +1221,12 @@
index.getMember('dart:_internal', 'LateError', 'fieldADI');
}
+ Constructor
+ get lateInitializationLocalAssignedDuringInitializationConstructor {
+ return _lateInitializationLocalAssignedDuringInitializationConstructor ??=
+ index.getMember('dart:_internal', 'LateError', 'localADI');
+ }
+
Constructor get lateInitializationFieldNotInitializedConstructor {
return _lateInitializationFieldNotInitializedConstructor ??=
index.getMember('dart:_internal', 'LateError', 'fieldNI');
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index cc2d51b..5f0d085 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -815,6 +815,7 @@
}
problem(currentParent, "Type $node references an anonymous mixin class.");
}
+ defaultDartType(node);
}
@override
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 4ebbbef..afa2668 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1148,10 +1148,9 @@
}
ErrorPtr ClassFinalizer::AllocateFinalizeClass(const Class& cls) {
+ ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
ASSERT(cls.is_finalized());
- if (cls.is_allocate_finalized()) {
- return Error::null();
- }
+ ASSERT(!cls.is_allocate_finalized());
Thread* thread = Thread::Current();
HANDLESCOPE(thread);
@@ -1200,7 +1199,10 @@
}
ErrorPtr ClassFinalizer::LoadClassMembers(const Class& cls) {
+ ASSERT(IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
ASSERT(Thread::Current()->IsMutatorThread());
+ ASSERT(!cls.is_finalized());
+
LongJumpScope jump;
if (setjmp(*jump.Set()) == 0) {
#if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 6f83c62..2b0c369 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1700,10 +1700,16 @@
// TODO(http://dartbug.com/16615): Validate isolate parameter.
Isolate* iso = reinterpret_cast<Isolate*>(isolate);
if (!Thread::EnterIsolate(iso)) {
- FATAL(
- "Unable to Enter Isolate : "
- "Multiple mutators entering an isolate / "
- "Dart VM is shutting down");
+ if (iso->IsScheduled()) {
+ FATAL(
+ "Isolate %s is already scheduled on mutator thread %p, "
+ "failed to schedule from os thread 0x%" Px "\n",
+ iso->name(), iso->scheduled_mutator_thread(),
+ OSThread::ThreadIdToIntPtr(OSThread::GetCurrentThreadId()));
+ } else {
+ FATAL("Unable to enter isolate %s as Dart VM is shutting down",
+ iso->name());
+ }
}
// A Thread structure has been associated to the thread, we do the
// safepoint transition explicitly here instead of using the
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 3a3cbf8..e88229a 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -812,7 +812,8 @@
return thread == nullptr ? nullptr : thread->isolate();
}
- bool IsScheduled() { return scheduled_mutator_thread_ != nullptr; }
+ bool IsScheduled() { return scheduled_mutator_thread() != nullptr; }
+ Thread* scheduled_mutator_thread() const { return scheduled_mutator_thread_; }
// Register a newly introduced class.
void RegisterClass(const Class& cls);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 87ca73b..803e75c 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4260,7 +4260,6 @@
// Ensure that top level parsing of the class has been done.
ErrorPtr Class::EnsureIsFinalized(Thread* thread) const {
ASSERT(!IsNull());
- // Finalized classes have already been parsed.
if (is_finalized()) {
return Error::null();
}
@@ -4290,7 +4289,6 @@
// this class is ready to be allocated.
ErrorPtr Class::EnsureIsAllocateFinalized(Thread* thread) const {
ASSERT(!IsNull());
- // Finalized classes have already been parsed.
if (is_allocate_finalized()) {
return Error::null();
}
@@ -4298,6 +4296,10 @@
Compiler::AbortBackgroundCompilation(
DeoptId::kNone, "Class allocate finalization while compiling");
}
+ SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock());
+ if (is_allocate_finalized()) {
+ return Error::null();
+ }
ASSERT(thread->IsMutatorThread());
ASSERT(thread != NULL);
Error& error = Error::Handle(thread->zone(), EnsureIsFinalized(thread));
diff --git a/sdk/lib/internal/errors.dart b/sdk/lib/internal/errors.dart
index 3fe6e40..8b93cd1 100644
--- a/sdk/lib/internal/errors.dart
+++ b/sdk/lib/internal/errors.dart
@@ -17,6 +17,10 @@
: _message =
"Field '$fieldName' has been assigned during initialization.";
+ LateError.localADI(String localName)
+ : _message =
+ "Local '$localName' has been assigned during initialization.";
+
@pragma("vm:entry-point")
LateError.fieldNI(String fieldName)
: _message = "Field '${fieldName}' has not been initialized.";
diff --git a/tests/language/type_variable/scope_test.dart b/tests/language/type_variable/scope_test.dart
index 3be94a3..2a68d15 100644
--- a/tests/language/type_variable/scope_test.dart
+++ b/tests/language/type_variable/scope_test.dart
@@ -43,6 +43,8 @@
// [cfe] Type variables can't be used in static members.
// ^
// [cfe] Verification of the generated program failed:
+ // ^
+ // [cfe] Verification of the generated program failed:
static
Foo<T>
diff --git a/tools/VERSION b/tools/VERSION
index ac2b734..5397bdc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 112
+PRERELEASE 113
PRERELEASE_PATCH 0
\ No newline at end of file