Version 2.6.0-dev.3.0
Merge commit 'cff2b10a28b2d92249ed23033fe43a8f8b5e7862' into dev
diff --git a/.packages b/.packages
index 435b8d5..281eb23 100644
--- a/.packages
+++ b/.packages
@@ -29,6 +29,7 @@
csslib:third_party/pkg/csslib/lib
dart2js_info:third_party/pkg/dart2js_info/lib
dart2js_tools:pkg/dart2js_tools/lib
+dart2native:pkg/dart2native/lib
dart_internal:pkg/dart_internal/lib
dart_style:third_party/pkg_tested/dart_style/lib
dartdoc:third_party/pkg/dartdoc/lib
diff --git a/BUILD.gn b/BUILD.gn
index 5fd2b63..1aff52e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -86,6 +86,12 @@
]
}
+group("create_sdk_nnbd") {
+ public_deps = [
+ "sdk_nnbd:create_sdk_nnbd",
+ ]
+}
+
if (defined(dart_host_sdk_toolchain) &&
dart_host_sdk_toolchain != host_toolchain) {
group("create_host_sdk") {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6efa0d..ee267aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,8 +31,10 @@
#### Linter
-The Linter was updated to `0.1.97+1`, which includes:
+The Linter was updated to `0.1.98`, which includes:
+* fixed null raw expression accesses in use_to_and_as_if_applicable
+* internal migration to using analyzer `InheritanceManager3`
* internal migration away from using analyzer `resolutionMap`
* various fixes and improvements to anticipate support for extension-methods
* new lint: `camel_case_extensions`
diff --git a/DEPS b/DEPS
index dc46d63..7d7529e 100644
--- a/DEPS
+++ b/DEPS
@@ -82,7 +82,7 @@
# and land the review.
#
# For more details, see https://github.com/dart-lang/sdk/issues/30164
- "dart_style_tag": "1.2.8", # Please see the note above before updating.
+ "dart_style_tag": "1.3.0", # Please see the note above before updating.
"dartdoc_rev" : "6934accd88c29a73cae26d0c4def3323efc2119c",
"fixnum_tag": "0.10.9",
@@ -99,7 +99,7 @@
"intl_tag": "0.15.7",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "2.0.9",
- "linter_tag": "0.1.97+1",
+ "linter_tag": "0.1.98",
"logging_tag": "0.11.3+2",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_tag": "2.0.3",
diff --git a/pkg/analysis_server/analysis_options.yaml b/pkg/analysis_server/analysis_options.yaml
index 295dd33..ed8c3c5 100644
--- a/pkg/analysis_server/analysis_options.yaml
+++ b/pkg/analysis_server/analysis_options.yaml
@@ -1,16 +1,37 @@
+include: package:pedantic/analysis_options.1.8.0.yaml
analyzer:
# This currently finds ~1,200 implicit-casts issues when enabled.
# strong-mode:
# implicit-casts: false
exclude:
- test/mock_packages/**
+ errors:
+ # Ignoring "style" lint rules from pedantic for now. There are pre-existing
+ # violations that need to be cleaned up. Each one can be cleaned up and
+ # enabled according to the value provided.
+ avoid_init_to_null: ignore
+ avoid_return_types_on_setters: ignore
+ curly_braces_in_flow_control_structures: ignore
+ empty_catches: ignore
+ prefer_iterable_wheretype: ignore
+ prefer_contains: ignore
+ # TODO(srawlins): At the time of writing, 2400 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-doc-comments`, but not worth the churn
+ # today.
+ slash_for_doc_comments: ignore
+ # TODO(srawlins): At the time of writing, 20 violations in lib/. The fix
+ # is not mechanical; each violation probably needs to be scrutinized.
+ unawaited_futures: ignore
+ # TODO(srawlins): At the time of writing, 1100 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-optional-const`, but not worth the
+ # churn today.
+ unnecessary_const: ignore
+ # TODO(srawlins): At the time of writing, 2500 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-optional-new`, but not worth the churn
+ # today.
+ unnecessary_new: ignore
linter:
rules:
- - empty_constructor_bodies # pedantic
- empty_statements
- - prefer_equal_for_default_values # pedantic
- - prefer_is_empty # pedantic
- - prefer_is_not_empty # pedantic
- unnecessary_brace_in_string_interps
- - valid_regexps # pedantic
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 5a67460..b1173da 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -6,7 +6,10 @@
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
@@ -16,6 +19,7 @@
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:path/path.dart' as path;
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';
@@ -29,6 +33,16 @@
final DartFixListener listener;
+ /// The root of the included paths.
+ ///
+ /// The included paths may contain absolute and relative paths, non-canonical
+ /// paths, and directory and file paths. The "root" is the deepest directory
+ /// which all included paths share.
+ ///
+ /// If instrumentation files are written to [outputDir], they will be written
+ /// as if in a directory structure rooted at [includedRoot].
+ final String includedRoot;
+
final String outputDir;
InstrumentationListener instrumentationListener;
@@ -40,7 +54,10 @@
/// If this occurs, then don't update any code.
bool _packageIsNNBD = true;
- NonNullableFix(this.listener, this.outputDir) {
+ NonNullableFix(this.listener, this.outputDir,
+ {List<String> included = const []})
+ : this.includedRoot =
+ _getIncludedRoot(included, listener.server.resourceProvider) {
instrumentationListener =
outputDir == null ? null : InstrumentationListener();
migration = new NullabilityMigration(
@@ -61,7 +78,7 @@
if (!outputFolder.exists) {
outputFolder.create();
}
- _generateOutput(outputFolder);
+ await _generateOutput(provider, outputFolder);
}
}
@@ -196,20 +213,58 @@
}
/// Generate output into the given [folder].
- void _generateOutput(Folder folder) {
- File main = folder.getChildAssumingFile('main.html');
- main.writeAsStringSync('''
-<html>
-<body>
-Generated output at ${DateTime.now()}.
-</body>
-</html>
-''');
+ void _generateOutput(OverlayResourceProvider provider, Folder folder) async {
+ List<LibraryInfo> libraryInfos = await InfoBuilder(listener.server)
+ .explainMigration(instrumentationListener.data, listener);
+ listener.addDetail('libraryInfos has ${libraryInfos.length} libs');
+ for (LibraryInfo info in libraryInfos) {
+ var pathContext = provider.pathContext;
+ var libraryPath =
+ pathContext.setExtension(info.units.first.path, '.html');
+ // TODO(srawlins): Choose a better scheme than the double underscores,
+ // likely with actual directories, which need to be individually created.
+ var relativePath = pathContext
+ .relative(libraryPath, from: includedRoot)
+ .replaceAll('/', '__');
+ File output = folder.getChildAssumingFile(relativePath);
+ String rendered = InstrumentationRenderer(info).render();
+ output.writeAsStringSync(rendered);
+ }
}
static void task(DartFixRegistrar registrar, DartFixListener listener,
EditDartfixParams params) {
- registrar.registerCodeTask(new NonNullableFix(listener, params.outputDir));
+ registrar.registerCodeTask(new NonNullableFix(listener, params.outputDir,
+ included: params.included));
+ }
+
+ /// Get the "root" of all [included] paths. See [includedRoot] for its
+ /// definition.
+ static String _getIncludedRoot(
+ List<String> included, OverlayResourceProvider provider) {
+ path.Context context = provider.pathContext;
+ // This step looks like it may be expensive (`getResource`, splitting up
+ // all of the paths, comparing parts, joining one path back together). In
+ // practice, this should be cheap because typically only one path is given
+ // to dartfix.
+ List<String> rootParts = included
+ .map((p) => context.absolute(context.canonicalize(p)))
+ .map((p) => provider.getResource(p) is File ? context.dirname(p) : p)
+ .map((p) => context.split(p))
+ .reduce((value, parts) {
+ List<String> shorterPath = value.length < parts.length ? value : parts;
+ int length = shorterPath.length;
+ for (int i = 0; i < length; i++) {
+ if (value[i] != parts[i]) {
+ // [value] and [parts] are the same, only up to part [i].
+ return value.sublist(0, i);
+ }
+ }
+ // [value] and [parts] are the same up to the full length of the shorter
+ // of the two, so just return that.
+ return shorterPath;
+ });
+ return context.joinAll(rootParts);
}
}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
new file mode 100644
index 0000000..acd9c24
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2019, 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 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+
+/// A builder used to build the migration information for a library.
+class InfoBuilder {
+ /// The analysis session used to get information about libraries.
+ AnalysisServer server;
+
+ /// Initialize a newly created builder.
+ InfoBuilder(this.server);
+
+ /// Return the migration information for all of the libraries that were
+ /// migrated.
+ Future<List<LibraryInfo>> explainMigration(
+ InstrumentationInformation info, DartFixListener listener) async {
+ Map<Source, SourceInformation> sourceInfo = info.sourceInformation;
+ List<LibraryInfo> libraries = [];
+ for (Source source in sourceInfo.keys) {
+ String filePath = source.fullName;
+ AnalysisSession session =
+ server.getAnalysisDriver(filePath).currentSession;
+ if (!session.getFile(filePath).isPart) {
+ ParsedLibraryResult result = await session.getParsedLibrary(filePath);
+ libraries
+ .add(_explainLibrary(result, info, sourceInfo[source], listener));
+ }
+ }
+ return libraries;
+ }
+
+ /// Return the migration information for the given library.
+ LibraryInfo _explainLibrary(
+ ParsedLibraryResult result,
+ InstrumentationInformation info,
+ SourceInformation sourceInfo,
+ DartFixListener listener) {
+ List<UnitInfo> units = [];
+ for (ParsedUnitResult unit in result.units) {
+ SourceFileEdit edit = listener.sourceChange.getFileEdit(unit.path);
+ units.add(_explainUnit(unit, edit));
+ }
+ return LibraryInfo(units);
+ }
+
+ /// Return the migration information for the given unit.
+ UnitInfo _explainUnit(ParsedUnitResult result, SourceFileEdit fileEdit) {
+ List<RegionInfo> regions = [];
+ String content = result.content;
+ // [fileEdit] is null when a file has no edits.
+ if (fileEdit == null) {
+ return UnitInfo(result.path, content, regions);
+ }
+ List<SourceEdit> edits = fileEdit.edits;
+ edits.sort((first, second) => first.offset.compareTo(second.offset));
+ // Compute the deltas for the regions that will be computed as we apply the
+ // edits. We need the deltas because the offsets to the regions are relative
+ // to the edited source, but the edits are being applied in reverse order so
+ // the offset in the pre-edited source will not match the offset in the
+ // post-edited source. The deltas compensate for that difference.
+ List<int> deltas = [];
+ int previousDelta = 0;
+ for (SourceEdit edit in edits) {
+ deltas.add(previousDelta);
+ previousDelta += (edit.replacement.length - edit.length);
+ }
+ // Apply edits in reverse order and build the regions.
+ int index = edits.length - 1;
+ for (SourceEdit edit in edits.reversed) {
+ int offset = edit.offset;
+ int length = edit.length;
+ String replacement = edit.replacement;
+ int end = offset + length;
+ int delta = deltas[index--];
+ // Insert the replacement text without deleting the replaced text.
+ content = content.replaceRange(end, end, replacement);
+ if (length > 0) {
+ // TODO(brianwilkerson) Create a sensible explanation.
+ regions.add(RegionInfo(offset + delta, length, 'removed'));
+ }
+ // TODO(brianwilkerson) Create a sensible explanation.
+ regions.add(RegionInfo(end + delta, replacement.length, 'added'));
+ }
+ regions.sort((first, second) => first.offset.compareTo(second.offset));
+ return UnitInfo(result.path, content, regions);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
index 0fec5d3..5b14508 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -14,32 +14,45 @@
int previousIndex = 0;
Map<String, dynamic> mustacheContext = {'units': <Map<String, dynamic>>[]};
for (var compilationUnit in info.units) {
- StringBuffer buffer = StringBuffer();
+ // List of Mustache context for both unmodified and modified regions:
+ //
+ // * 'modified': Whether this region represents modified source, or
+ // unmodified.
+ // * 'content': The textual content of this region.
+ // * 'explanation': The textual explanation of why the content in this
+ // region was modified. It will appear in a "tooltip" on hover.
+ // TODO(srawlins): Support some sort of HTML explanation, with
+ // hyperlinks to anchors in other source code.
+ List<Map> regions = [];
for (var region in compilationUnit.regions) {
if (region.offset > previousIndex) {
// Display a region of unmodified content.
- buffer.write(
- compilationUnit.content.substring(previousIndex, region.offset));
+ regions.add({
+ 'modified': false,
+ 'content':
+ compilationUnit.content.substring(previousIndex, region.offset)
+ });
previousIndex = region.offset + region.length;
}
- buffer.write(_regionWithTooltip(region, compilationUnit.content));
+ regions.add({
+ 'modified': true,
+ 'content': compilationUnit.content
+ .substring(region.offset, region.offset + region.length),
+ 'explanation': region.explanation,
+ });
}
if (previousIndex < compilationUnit.content.length) {
// Last region of unmodified content.
- buffer.write(compilationUnit.content.substring(previousIndex));
+ regions.add({
+ 'modified': false,
+ 'content': compilationUnit.content.substring(previousIndex)
+ });
}
mustacheContext['units']
- .add({'path': compilationUnit.path, 'content': buffer.toString()});
+ .add({'path': compilationUnit.path, 'regions': regions});
}
return _template.renderString(mustacheContext);
}
-
- String _regionWithTooltip(RegionInfo region, String content) {
- String regionContent =
- content.substring(region.offset, region.offset + region.length);
- return '<span class="region">$regionContent'
- '<span class="tooltip">${region.explanation}</span></span>';
- }
}
/// A mustache template for one library's instrumentation output.
@@ -47,35 +60,58 @@
<html>
<head>
<title>Non-nullable fix instrumentation report</title>
+ <script src="highlight.pack.js"></script>
+ <link rel="stylesheet" href="styles/androidstudio.css">
<style>
+body {
+ font-family: sans-serif;
+ padding: 1em;
+}
+
h2 {
font-size: 1em;
font-weight: bold;
}
-div.content {
+.content {
font-family: monospace;
- whitespace: pre;
+ white-space: pre;
+}
+
+.content.highlighting {
+ position: relative;
+}
+
+.regions {
+ position: absolute;
+ top: 0.5em;
+ /* The content of the regions is not visible; the user instead will see the
+ * highlighted copy of the content. */
+ visibility: hidden;
}
.region {
/* Green means this region was added. */
- color: green;
+ background-color: #ccffcc;
+ color: #003300;
+ cursor: default;
display: inline-block;
position: relative;
+ visibility: visible;
}
.region .tooltip {
background-color: #EEE;
border: solid 2px #999;
color: #333;
+ cursor: auto;
left: 50%;
- margin-left: -50px;
+ margin-left: -100px;
padding: 1px;
position: absolute;
- top: 120%;
+ top: 100%;
visibility: hidden;
- width: 100px;
+ width: 200px;
z-index: 1;
}
@@ -86,13 +122,31 @@
</head>
<body>
<h1>Non-nullable fix instrumentation report</h1>
- <p><em>Well-written introduction to this report.</em></p>
- {{# units }}
- <h2>{{ path }}</h2>
- <div class="content">
- {{{ content }}}
- </div> {{! content }}
- {{/ units }}
- </body>
-</html>
-''');
+ <p><em>Well-written introduction to this report.</em></p>'''
+ ' {{# units }}'
+ ' <h2>{{{ path }}}</h2>'
+ ' <div class="content highlighting">'
+ '{{! These regions are written out, unmodified, as they need to be found }}'
+ '{{! in one simple text string for highlight.js to hightlight them. }}'
+ '{{# regions }}'
+ '{{ content }}'
+ '{{/ regions }}'
+ ' <div class="regions">'
+ '{{! The regions are then printed again, overlaying the first copy of the }}'
+ '{{! content, to provide tooltips for modified regions. }}'
+ '{{# regions }}'
+ '{{^ modified }}{{ content }}{{/ modified }}'
+ '{{# modified }}<span class="region">{{ content }}'
+ '<span class="tooltip">{{explanation}}</span></span>{{/ modified }}'
+ '{{/ regions }}'
+ '</div></div>'
+ ' {{/ units }}'
+ ' <script lang="javascript">'
+ 'document.addEventListener("DOMContentLoaded", (event) => {'
+ ' document.querySelectorAll(".highlighting").forEach((block) => {'
+ ' hljs.highlightBlock(block);'
+ ' });'
+ '});'
+ ' </script>'
+ ' </body>'
+ '</html>');
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index f82c19c..e9a48d3 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -207,8 +207,9 @@
} else if (node is Declaration) {
if (errors.isNotEmpty) {
if (_complete_classDeclaration() ||
- _complete_functionDeclaration() ||
- _complete_variableDeclaration()) {
+ _complete_variableDeclaration() ||
+ _complete_simpleSemicolon() ||
+ _complete_functionDeclaration()) {
return completion;
}
}
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index e0b741a..ed8d65b 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -40,7 +40,7 @@
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/sdk_ext.dart';
-import 'package:path/path.dart' as pathPackage;
+import 'package:path/path.dart' as path;
final String kCustomCss = '''
.lead, .page-title+.markdown-body>p:first-child {
@@ -170,7 +170,7 @@
: super(site, 'completion', 'Code Completion',
description: 'Latency statistics for code completion.');
- pathPackage.Context get pathContext;
+ path.Context get pathContext;
List<CompletionPerformance> get performanceItems;
@@ -245,22 +245,22 @@
@override
Future<void> generateContent(Map<String, String> params) async {
- String path = params['file'];
- if (path == null) {
+ String filePath = params['file'];
+ if (filePath == null) {
p('No file path provided.');
return;
}
- AnalysisDriver driver = server.getAnalysisDriver(path);
+ AnalysisDriver driver = server.getAnalysisDriver(filePath);
if (driver == null) {
- p('The file <code>${escape(path)}</code> is not being analyzed.',
+ p('The file <code>${escape(filePath)}</code> is not being analyzed.',
raw: true);
return;
}
- ResolvedUnitResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await driver.getResult(filePath);
if (result == null) {
p(
'An AST could not be produced for the file '
- '<code>${escape(path)}</code>.',
+ '<code>${escape(filePath)}</code>.',
raw: true);
return;
}
@@ -372,7 +372,7 @@
.firstWhere((handler) => handler is CompletionDomainHandler);
@override
- pathPackage.Context get pathContext =>
+ path.Context get pathContext =>
completionDomain.server.resourceProvider.pathContext;
@override
@@ -440,7 +440,7 @@
buf.writeln(
'<a class="tabnav-tab selected">${escape(f.shortName)}</a>');
} else {
- String p = '$path?context=${Uri.encodeQueryComponent(f.path)}';
+ String p = '${this.path}?context=${Uri.encodeQueryComponent(f.path)}';
buf.writeln(
'<a href="$p" class="tabnav-tab">${escape(f.shortName)}</a>');
}
@@ -790,22 +790,22 @@
@override
Future<void> generateContent(Map<String, String> params) async {
- String path = params['file'];
- if (path == null) {
+ String filePath = params['file'];
+ if (filePath == null) {
p('No file path provided.');
return;
}
- AnalysisDriver driver = server.getAnalysisDriver(path);
+ AnalysisDriver driver = server.getAnalysisDriver(filePath);
if (driver == null) {
- p('The file <code>${escape(path)}</code> is not being analyzed.',
+ p('The file <code>${escape(filePath)}</code> is not being analyzed.',
raw: true);
return;
}
- ResolvedUnitResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await driver.getResult(filePath);
if (result == null) {
p(
'An element model could not be produced for the file '
- '<code>${escape(path)}</code>.',
+ '<code>${escape(filePath)}</code>.',
raw: true);
return;
}
@@ -994,7 +994,7 @@
LspCompletionPage(DiagnosticsSite site, this.server) : super(site);
@override
- pathPackage.Context get pathContext => server.resourceProvider.pathContext;
+ path.Context get pathContext => server.resourceProvider.pathContext;
@override
List<CompletionPerformance> get performanceItems =>
@@ -1098,7 +1098,7 @@
Map<String, List<int>> responseTimes =
PluginManager.pluginResponseTimes[plugin];
- List<String> components = pathPackage.split(id);
+ List<String> components = path.split(id);
int length = components.length;
String name;
if (length == 0) {
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 0990d68..31b2358 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -28,5 +28,6 @@
analysis_tool: any
html: any
http: any
+ pedantic: ^1.8.0
test_reflective_loader: any
test: any
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index cabaf02..261ada4 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -7,6 +7,7 @@
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:linter/src/rules.dart';
+import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -21,7 +22,6 @@
@reflectiveTest
class EditDartfixDomainHandlerTest extends AbstractAnalysisTest {
int requestId = 30;
- String libPath;
String get nextRequestId => (++requestId).toString();
@@ -78,7 +78,6 @@
void setUp() {
super.setUp();
registerLintRules();
- libPath = resourceProvider.convertPath('/project/lib');
testFile = resourceProvider.convertPath('/project/lib/fileToBeFixed.dart');
}
@@ -193,12 +192,7 @@
}
test_dartfix_nonNullable() async {
- // Add analysis options to enable non-nullable analysis
- newFile('/project/analysis_options.yaml', content: '''
-analyzer:
- enable-experiment:
- - non-nullable
-''');
+ createAnalysisOptionsFile(experiments: ['non-nullable']);
addTestFile('''
int f(int i) => 0;
int g(int i) => f(i);
@@ -293,12 +287,7 @@
}
test_dartfix_nonNullable_outputDir() async {
- // Add analysis options to enable non-nullable analysis
- newFile('/project/analysis_options.yaml', content: '''
-analyzer:
- enable-experiment:
- - non-nullable
-''');
+ createAnalysisOptionsFile(experiments: ['non-nullable']);
addTestFile('''
int f(int i) => 0;
int g(int i) => f(i);
@@ -311,7 +300,10 @@
await performFix(
includedFixes: ['non-nullable'], outputDir: outputDir.path);
expect(outputDir.exists, true);
- expect(outputDir.getChildren(), isNotEmpty);
+ // TODO(https://github.com/dart-lang/sdk/issues/38574): Fix Windows.
+ if (path.style != path.Style.windows) {
+ expect(outputDir.getChildren(), isNotEmpty);
+ }
}
test_dartfix_partFile() async {
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
index 8695f99..30e390f 100644
--- a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
+++ b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
@@ -17,18 +17,6 @@
@reflectiveTest
class InstrumentationRendererTest extends AbstractAnalysisTest {
- test_outputContainsModifiedAndUnmodifiedRegions() async {
- LibraryInfo info = LibraryInfo([
- UnitInfo('/lib/a.dart', 'int? a = null;',
- [RegionInfo(3, 1, 'null was assigned')]),
- ]);
- String output = InstrumentationRenderer(info).render();
- expect(
- output,
- contains('int<span class="region">?'
- '<span class="tooltip">null was assigned</span></span> a = null;'));
- }
-
test_outputContainsEachPath() async {
LibraryInfo info = LibraryInfo([
UnitInfo('/lib/a.dart', 'int? a = null;',
@@ -39,8 +27,40 @@
[RegionInfo(3, 1, 'null was assigned')]),
]);
String output = InstrumentationRenderer(info).render();
- expect(output, contains('<h2>/lib/a.dart</h2>'));
- expect(output, contains('<h2>/lib/part1.dart</h2>'));
- expect(output, contains('<h2>/lib/part2.dart</h2>'));
+ expect(output, contains('<h2>/lib/a.dart</h2>'));
+ expect(output, contains('<h2>/lib/part1.dart</h2>'));
+ expect(output, contains('<h2>/lib/part2.dart</h2>'));
+ }
+
+ test_outputContainsEscapedHtml() async {
+ LibraryInfo info = LibraryInfo([
+ UnitInfo('/lib/a.dart', 'List<String>? a = null;',
+ [RegionInfo(12, 1, 'null was assigned')]),
+ ]);
+ String output = InstrumentationRenderer(info).render();
+ expect(
+ output,
+ contains('List<String><span class="region">?'
+ '<span class="tooltip">null was assigned</span></span> a = null;'));
+ }
+
+ test_outputContainsEscapedHtml_ampersand() async {
+ LibraryInfo info = LibraryInfo([
+ UnitInfo('/lib/a.dart', 'bool a = true && false;', []),
+ ]);
+ String output = InstrumentationRenderer(info).render();
+ expect(output, contains('bool a = true && false;'));
+ }
+
+ test_outputContainsModifiedAndUnmodifiedRegions() async {
+ LibraryInfo info = LibraryInfo([
+ UnitInfo('/lib/a.dart', 'int? a = null;',
+ [RegionInfo(3, 1, 'null was assigned')]),
+ ]);
+ String output = InstrumentationRenderer(info).render();
+ expect(
+ output,
+ contains('int<span class="region">?'
+ '<span class="tooltip">null was assigned</span></span> a = null;'));
}
}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 083de60..7ec4aee 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -1712,6 +1712,33 @@
assertNotSuggested('x');
}
+ test_classReference_in_comment() async {
+ addTestSource(r'''
+class Abc { }
+class Abcd { }
+
+// A^
+class Foo { }
+''');
+ await computeSuggestions();
+ assertNotSuggested('Abc');
+ assertNotSuggested('Abcd');
+ }
+
+ /// see: https://github.com/dart-lang/sdk/issues/36037
+ @failingTest
+ test_classReference_in_comment_eof() async {
+ addTestSource(r'''
+class Abc { }
+class Abcd { }
+
+// A^
+''');
+ await computeSuggestions();
+ assertNotSuggested('Abc');
+ assertNotSuggested('Abcd');
+ }
+
test_Combinator_hide() async {
// SimpleIdentifier HideCombinator ImportDirective
addSource('/home/test/lib/ab.dart', '''
diff --git a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
index 7907820e..1558593 100644
--- a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
@@ -1365,6 +1365,23 @@
''');
}
+ test_expressionBody() async {
+ await _prepareCompletion(
+ '=> 1',
+ '''
+class Thing extends Object {
+ int foo() => 1
+}
+''',
+ atEnd: true);
+ _assertHasChange('Add a semicolon and newline', '''
+class Thing extends Object {
+ int foo() => 1;
+
+}
+''');
+ }
+
test_noCloseParen() async {
await _prepareCompletion(
'ing(3',
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index b06f849..b1cc002 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -124,7 +124,7 @@
''');
_createRefactoring('test');
// check conditions
- _assertInitialConditions_fatal(
+ await _assertInitialConditions_fatal(
'Only explicit getters can be converted to methods.');
}
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index d8fe817..d426b34 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -129,7 +129,7 @@
ExecutableElement element = findElement('test', ElementKind.GETTER);
_createRefactoringForElement(element);
// check conditions
- _assertInitialConditions_fatal(
+ await _assertInitialConditions_fatal(
'Only class methods or top-level functions can be converted to getters.');
}
@@ -142,7 +142,7 @@
''');
_createRefactoring('test');
// check conditions
- _assertInitialConditions_fatal(
+ await _assertInitialConditions_fatal(
'Only methods without parameters can be converted to getters.');
}
@@ -156,7 +156,7 @@
ExecutableElement element = findElementsByName(testUnit, 'test').single;
_createRefactoringForElement(element);
// check conditions
- _assertInitialConditions_fatal(
+ await _assertInitialConditions_fatal(
'Only top-level functions can be converted to getters.');
}
@@ -168,7 +168,7 @@
''');
_createRefactoring('test');
// check conditions
- _assertInitialConditions_fatal(
+ await _assertInitialConditions_fatal(
'Only class methods or top-level functions can be converted to getters.');
}
@@ -178,7 +178,8 @@
''');
_createRefactoring('test');
// check conditions
- _assertInitialConditions_fatal('Cannot convert function returning void.');
+ await _assertInitialConditions_fatal(
+ 'Cannot convert function returning void.');
}
Future _assertInitialConditions_fatal(String message) async {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 4d8e897..df07bfc 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -123,7 +123,7 @@
''');
_createRefactoringForString('abc');
// check conditions
- _assertInitialConditions_fatal_selection();
+ await _assertInitialConditions_fatal_selection();
}
test_checkInitialConditions_notPartOfFunction() async {
diff --git a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
new file mode 100644
index 0000000..8f6487f
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2019, 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 'package:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../analysis_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NonNullableFixTest);
+ });
+}
+
+@reflectiveTest
+class NonNullableFixTest extends AbstractAnalysisTest {
+ int requestId = 30;
+
+ path.Context context;
+
+ DartFixListener listener;
+
+ String get nextRequestId => (++requestId).toString();
+
+ Future<EditDartfixResult> performFix(
+ {List<String> included, String outputDir}) async {
+ final id = nextRequestId;
+ final params = EditDartfixParams(included);
+ params.includedFixes = ['non-nullable'];
+ params.outputDir = outputDir;
+ Request request = Request(id, 'edit.dartfix', params.toJson());
+ Response response = await EditDartFix(server, request).compute();
+ expect(response.id, id);
+ expect(response.error, isNull);
+ return EditDartfixResult.fromResponse(response);
+ }
+
+ @override
+ Future<void> setUp() async {
+ context = path.style == path.Style.windows
+ // On Windows, ensure that the current drive matches
+ // the drive inserted by MemoryResourceProvider.convertPath
+ // so that packages are mapped to the correct drive
+ ? path.Context(current: 'C:\\project')
+ : path.Context(current: '/project');
+ resourceProvider = MemoryResourceProvider(context: context);
+ super.setUp();
+ newFile('/project/bin/bin.dart', content: 'var x = 1;');
+ newFile('/project/lib/lib1.dart', content: 'var x = 1;');
+ newFile('/project/lib/lib2.dart', content: 'var x = 1;');
+ newFile('/project/lib/src/lib3.dart', content: 'var x = 1;');
+ newFile('/project/test/test.dart', content: 'var x = 1;');
+ newFile('/project2/bin/bin.dart', content: 'var x = 1;');
+ newFile('/project2/lib/lib1.dart', content: 'var x = 1;');
+ newFile('/project2/lib/lib2.dart', content: 'var x = 1;');
+ newFile('/project2/lib/src/lib3.dart', content: 'var x = 1;');
+ newFile('/project2/test/test.dart', content: 'var x = 1;');
+ // Compute the analysis results.
+ server.setAnalysisRoots(
+ '0', [resourceProvider.pathContext.dirname(testFile)], [], {});
+ await server
+ .getAnalysisDriver(testFile)
+ .currentSession
+ .getResolvedUnit(testFile);
+ listener = DartFixListener(server);
+ }
+
+ test_included_multipleRelativeDirectories() async {
+ NonNullableFix fix =
+ NonNullableFix(listener, '.', included: ['lib', 'test']);
+ expect(fix.includedRoot, equals(convertPath('/project')));
+ }
+
+ test_included_multipleRelativeDirectories_nonCanonical() async {
+ NonNullableFix fix = NonNullableFix(listener, '.',
+ included: ['../project2/lib', '../project2/lib/src']);
+ expect(fix.includedRoot, equals(convertPath('/project2/lib')));
+ }
+
+ test_included_multipleRelativeDirectories_nonCanonical_atFilesystemRoot() async {
+ NonNullableFix fix = NonNullableFix(listener, '.',
+ included: ['../project2/lib', '../project/lib']);
+ expect(fix.includedRoot, equals(convertPath('/')));
+ }
+
+ test_included_multipleRelativeDirectories_subAndSuperDirectories() async {
+ NonNullableFix fix = NonNullableFix(listener, '.', included: ['lib', '.']);
+ expect(fix.includedRoot, equals(convertPath('/project')));
+ }
+
+ test_included_multipleRelativeFiles() async {
+ NonNullableFix fix = NonNullableFix(listener, '.',
+ included: ['lib/lib1.dart', 'test/test.dart']);
+ expect(fix.includedRoot, equals(convertPath('/project')));
+ }
+
+ test_included_multipleRelativeFiles_sameDirectory() async {
+ NonNullableFix fix = NonNullableFix(listener, '.',
+ included: ['lib/lib1.dart', 'lib/lib2.dart']);
+ expect(fix.includedRoot, equals(convertPath('/project/lib')));
+ }
+
+ test_included_multipleRelativeFilesAndDirectories() async {
+ NonNullableFix fix = NonNullableFix(listener, '.',
+ included: ['lib/lib1.dart', 'lib/src', '../project/lib/src/lib3.dart']);
+ expect(fix.includedRoot, equals(convertPath('/project/lib')));
+ }
+
+ test_included_singleAbsoluteDirectory() async {
+ NonNullableFix fix = NonNullableFix(listener, '.', included: ['/project']);
+ expect(fix.includedRoot, equals(convertPath('/project')));
+ }
+
+ test_included_singleAbsoluteFile() async {
+ NonNullableFix fix =
+ NonNullableFix(listener, '.', included: ['/project/bin/bin.dart']);
+ expect(fix.includedRoot, equals(convertPath('/project/bin')));
+ }
+
+ test_included_singleRelativeDirectory() async {
+ NonNullableFix fix = NonNullableFix(listener, '.', included: ['.']);
+ expect(fix.includedRoot, equals(convertPath('/project')));
+ }
+
+ test_outputDirContainsFilesRootedAtProjectPath() async {
+ createProject();
+ Folder outputDir = getFolder('/outputDir');
+ await performFix(included: [projectPath], outputDir: outputDir.path);
+ expect(outputDir.exists, true);
+ expect(outputDir.getChildAssumingFile('bin__bin.html').exists, isTrue);
+ expect(outputDir.getChildAssumingFile('lib__lib1.html').exists, isTrue);
+ expect(outputDir.getChildAssumingFile('lib__lib2.html').exists, isTrue);
+ expect(
+ outputDir.getChildAssumingFile('lib__src__lib3.html').exists, isTrue);
+ expect(outputDir.getChildAssumingFile('test__test.html').exists, isTrue);
+ }
+
+ test_outputDirContainsFilesRootedInASubdirectory() async {
+ createProject();
+ Folder outputDir = getFolder('/outputDir');
+ await performFix(
+ included: [context.join(projectPath, 'lib')],
+ outputDir: outputDir.path);
+ expect(outputDir.exists, true);
+ expect(outputDir.getChildAssumingFile('lib1.html').exists, isTrue);
+ expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
+ expect(outputDir.getChildAssumingFile('src__lib3.html').exists, isTrue);
+ }
+
+ test_outputDirContainsFilesRootedInParentOfSingleFile() async {
+ createProject();
+ Folder outputDir = getFolder('/outputDir');
+ await performFix(
+ included: [context.join(projectPath, 'lib', 'lib2.dart')],
+ outputDir: outputDir.path);
+ expect(outputDir.exists, true);
+ expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
+ }
+}
diff --git a/pkg/analysis_server/test/src/edit/fix/test_all.dart b/pkg/analysis_server/test/src/edit/fix/test_all.dart
new file mode 100644
index 0000000..1bf972c
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/fix/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'non_nullable_fix_test.dart' as non_nullable_fix;
+
+main() {
+ defineReflectiveSuite(() {
+ non_nullable_fix.main();
+ }, name: 'fix');
+}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
new file mode 100644
index 0000000..f300740
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2017, 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 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../analysis_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InfoBuilderTest);
+ });
+}
+
+@reflectiveTest
+class InfoBuilderTest extends AbstractAnalysisTest {
+ /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
+ /// not yet completed.
+ List<LibraryInfo> infos;
+
+ /// Use the InfoBuilder to build information. The information will be stored
+ /// in [infos].
+ Future<void> buildInfo() async {
+ // Compute the analysis results.
+ server.setAnalysisRoots(
+ '0', [resourceProvider.pathContext.dirname(testFile)], [], {});
+ ResolvedUnitResult result = await server
+ .getAnalysisDriver(testFile)
+ .currentSession
+ .getResolvedUnit(testFile);
+ // Run the migration engine.
+ DartFixListener listener = DartFixListener(server);
+ InstrumentationListener instrumentationListener = InstrumentationListener();
+ NullabilityMigration migration = new NullabilityMigration(
+ new NullabilityMigrationAdapter(listener),
+ permissive: false,
+ instrumentation: instrumentationListener);
+ migration.prepareInput(result);
+ migration.processInput(result);
+ migration.finish();
+ // Build the migration info.
+ InfoBuilder builder = InfoBuilder(server);
+ InstrumentationInformation info = instrumentationListener.data;
+ infos = await builder.explainMigration(info, listener);
+ }
+
+ test_parameter_nullableFromInvocation() async {
+ addTestFile('''
+void f(String s) {}
+void g() {
+ f(null);
+}
+''');
+ await buildInfo();
+ expect(infos, hasLength(1));
+ List<UnitInfo> units = infos[0].units;
+ expect(units, hasLength(1));
+ UnitInfo unit = units[0];
+ expect(unit.path, testFile);
+ expect(unit.content, '''
+void f(String? s) {}
+void g() {
+ f(null);
+}
+''');
+ List<RegionInfo> regions = unit.regions;
+ expect(regions, hasLength(1));
+ RegionInfo region = regions[0];
+ expect(region.offset, 13);
+ expect(region.length, 1);
+ }
+}
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
new file mode 100644
index 0000000..b7ddf83
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'info_builder_test.dart' as info_builder;
+
+main() {
+ defineReflectiveSuite(() {
+ info_builder.main();
+ }, name: 'nnbd_migration');
+}
diff --git a/pkg/analysis_server/test/src/edit/test_all.dart b/pkg/analysis_server/test/src/edit/test_all.dart
new file mode 100644
index 0000000..9e41ed2
--- /dev/null
+++ b/pkg/analysis_server/test/src/edit/test_all.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix/test_all.dart' as fix;
+import 'nnbd_migration/test_all.dart' as nnbd_migration;
+
+main() {
+ defineReflectiveSuite(() {
+ fix.main();
+ nnbd_migration.main();
+ }, name: 'edit');
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
index d3aaded..da0dd43 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
@@ -284,7 +284,7 @@
import 'package:flutter/material.dart';
/*caret*/main() {}
''');
- assertNoAssist();
+ await assertNoAssist();
}
test_notStatelessWidget() async {
@@ -295,7 +295,7 @@
MyWidget() : super('');
}
''');
- assertNoAssist();
+ await assertNoAssist();
}
test_notWidget() async {
@@ -304,7 +304,7 @@
import 'package:flutter/material.dart';
class /*caret*/MyWidget {}
''');
- assertNoAssist();
+ await assertNoAssist();
}
test_simple() async {
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index a45add5..39637af 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -7,6 +7,7 @@
import 'computer/test_all.dart' as computer;
import 'domain_abstract_test.dart' as domain_abstract;
import 'domains/test_all.dart' as domains;
+import 'edit/test_all.dart' as edit;
import 'flutter/test_all.dart' as flutter;
import 'lsp/test_all.dart' as lsp;
import 'plugin/test_all.dart' as plugin;
@@ -22,6 +23,7 @@
computer.main();
domain_abstract.main();
domains.main();
+ edit.main();
flutter.main();
lsp.main();
plugin.main();
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 04cd0e5..274f08e 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.38.4
+* Bug fixes: #33300, #38484, #38505.
+
## 0.38.3
* Deprecated the following codes from `StaticWarningCode`. Please use the
corresponding error codes from `CompileTimeErrorCode` instead:
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 1c02e60..46298e7 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -1,13 +1,37 @@
+include: package:pedantic/analysis_options.1.8.0.yaml
analyzer:
# This currently finds ~4,500 implicit-casts issues when enabled.
# strong-mode:
# implicit-casts: false
+ errors:
+ # Ignoring "style" lint rules from pedantic for now. There are pre-existing
+ # violations that need to be cleaned up. Each one can be cleaned up and
+ # enabled according to the value provided.
+ avoid_init_to_null: ignore
+ avoid_return_types_on_setters: ignore
+ curly_braces_in_flow_control_structures: ignore
+ empty_catches: ignore
+ prefer_iterable_wheretype: ignore
+ prefer_contains: ignore
+ # TODO(srawlins): Fix existing violations!
+ no_duplicate_case_values: ignore
+ # TODO(srawlins): At the time of writing, 230 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-named-default-separator`.
+ prefer_equal_for_default_values: ignore
+ # TODO(srawlins): At the time of writing, 2600 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-doc-comments`, but not worth the churn
+ # today.
+ slash_for_doc_comments: ignore
+ # TODO(srawlins): At the time of writing, 970 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-optional-const`, but not worth the
+ # churn today.
+ unnecessary_const: ignore
+ # TODO(srawlins): At the time of writing, 3200 violations in lib/. The fix
+ # is mechanical, via `dartfmt --fix-optional-new`, but not worth the churn
+ # today.
+ unnecessary_new: ignore
linter:
rules:
- - empty_constructor_bodies # pedantic
- empty_statements
- - prefer_is_empty # pedantic
- - prefer_is_not_empty # pedantic
- unnecessary_brace_in_string_interps
- - valid_regexps # pedantic
diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart
index 575c7de..561a4db 100644
--- a/pkg/analyzer/lib/dart/analysis/features.dart
+++ b/pkg/analyzer/lib/dart/analysis/features.dart
@@ -32,6 +32,9 @@
/// Feature information for the triple-shift operator.
static const triple_shift = ExperimentalFeatures.triple_shift;
+ /// Feature information for variance.
+ static const variance = ExperimentalFeatures.variance;
+
/// If the feature may be enabled or disabled on the command line, the
/// experimental flag that may be used to enable it. Otherwise `null`.
///
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 0dfe3fa..72e7f56 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -196,6 +196,7 @@
CompileTimeErrorCode.INVALID_URI,
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION,
+ CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL,
CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
CompileTimeErrorCode.LABEL_UNDEFINED,
CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP,
@@ -303,6 +304,7 @@
CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR,
CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER,
CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
@@ -556,6 +558,7 @@
ParserErrorCode.MULTIPLE_PART_OF_DIRECTIVES,
ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS,
ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH,
+ ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS,
ParserErrorCode.MULTIPLE_WITH_CLAUSES,
ParserErrorCode.NAMED_FUNCTION_EXPRESSION,
ParserErrorCode.NAMED_FUNCTION_TYPE,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 86d5b66..6efad5a 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
import 'package:meta/meta.dart';
export 'package:analyzer/src/dart/ast/constant_evaluator.dart';
@@ -2482,1164 +2481,6 @@
}
/**
- * An object that will clone any AST structure that it visits. The cloner will
- * clone the structure, replacing the specified ASTNode with a new ASTNode,
- * mapping the old token stream to a new token stream, and preserving resolution
- * results.
- */
-@deprecated
-class IncrementalAstCloner implements AstVisitor<AstNode> {
- /**
- * The node to be replaced during the cloning process.
- */
- final AstNode _oldNode;
-
- /**
- * The replacement node used during the cloning process.
- */
- final AstNode _newNode;
-
- /**
- * A mapping of old tokens to new tokens used during the cloning process.
- */
- final TokenMap _tokenMap;
-
- /**
- * Construct a new instance that will replace the [oldNode] with the [newNode]
- * in the process of cloning an existing AST structure. The [tokenMap] is a
- * mapping of old tokens to new tokens.
- */
- IncrementalAstCloner(this._oldNode, this._newNode, this._tokenMap);
-
- @override
- AdjacentStrings visitAdjacentStrings(AdjacentStrings node) =>
- astFactory.adjacentStrings(_cloneNodeList(node.strings));
-
- @override
- Annotation visitAnnotation(Annotation node) {
- Annotation copy = astFactory.annotation(
- _mapToken(node.atSign),
- _cloneNode(node.name),
- _mapToken(node.period),
- _cloneNode(node.constructorName),
- _cloneNode(node.arguments));
- copy.element = node.element;
- return copy;
- }
-
- @override
- ArgumentList visitArgumentList(ArgumentList node) => astFactory.argumentList(
- _mapToken(node.leftParenthesis),
- _cloneNodeList(node.arguments),
- _mapToken(node.rightParenthesis));
-
- @override
- AsExpression visitAsExpression(AsExpression node) {
- AsExpression copy = astFactory.asExpression(_cloneNode(node.expression),
- _mapToken(node.asOperator), _cloneNode(node.type));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- AstNode visitAssertInitializer(AssertInitializer node) =>
- astFactory.assertInitializer(
- _mapToken(node.assertKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.condition),
- _mapToken(node.comma),
- _cloneNode(node.message),
- _mapToken(node.rightParenthesis));
-
- @override
- AstNode visitAssertStatement(AssertStatement node) =>
- astFactory.assertStatement(
- _mapToken(node.assertKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.condition),
- _mapToken(node.comma),
- _cloneNode(node.message),
- _mapToken(node.rightParenthesis),
- _mapToken(node.semicolon));
-
- @override
- AssignmentExpression visitAssignmentExpression(AssignmentExpression node) {
- AssignmentExpression copy = astFactory.assignmentExpression(
- _cloneNode(node.leftHandSide),
- _mapToken(node.operator),
- _cloneNode(node.rightHandSide));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- AwaitExpression visitAwaitExpression(AwaitExpression node) =>
- astFactory.awaitExpression(
- _mapToken(node.awaitKeyword), _cloneNode(node.expression));
-
- @override
- BinaryExpression visitBinaryExpression(BinaryExpression node) {
- BinaryExpression copy = astFactory.binaryExpression(
- _cloneNode(node.leftOperand),
- _mapToken(node.operator),
- _cloneNode(node.rightOperand));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- Block visitBlock(Block node) => astFactory.block(_mapToken(node.leftBracket),
- _cloneNodeList(node.statements), _mapToken(node.rightBracket));
-
- @override
- BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) =>
- astFactory.blockFunctionBody(_mapToken(node.keyword),
- _mapToken(node.star), _cloneNode(node.block));
-
- @override
- BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
- BooleanLiteral copy =
- astFactory.booleanLiteral(_mapToken(node.literal), node.value);
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- BreakStatement visitBreakStatement(BreakStatement node) =>
- astFactory.breakStatement(_mapToken(node.breakKeyword),
- _cloneNode(node.label), _mapToken(node.semicolon));
-
- @override
- CascadeExpression visitCascadeExpression(CascadeExpression node) {
- CascadeExpression copy = astFactory.cascadeExpression(
- _cloneNode(node.target), _cloneNodeList(node.cascadeSections));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- CatchClause visitCatchClause(CatchClause node) => astFactory.catchClause(
- _mapToken(node.onKeyword),
- _cloneNode(node.exceptionType),
- _mapToken(node.catchKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.exceptionParameter),
- _mapToken(node.comma),
- _cloneNode(node.stackTraceParameter),
- _mapToken(node.rightParenthesis),
- _cloneNode(node.body));
-
- @override
- ClassDeclaration visitClassDeclaration(ClassDeclaration node) {
- ClassDeclaration copy = astFactory.classDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.abstractKeyword),
- _mapToken(node.classKeyword),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _cloneNode(node.extendsClause),
- _cloneNode(node.withClause),
- _cloneNode(node.implementsClause),
- _mapToken(node.leftBracket),
- _cloneNodeList(node.members),
- _mapToken(node.rightBracket));
- copy.nativeClause = _cloneNode(node.nativeClause);
- return copy;
- }
-
- @override
- ClassTypeAlias visitClassTypeAlias(ClassTypeAlias node) =>
- astFactory.classTypeAlias(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.typedefKeyword),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _mapToken(node.equals),
- _mapToken(node.abstractKeyword),
- _cloneNode(node.superclass),
- _cloneNode(node.withClause),
- _cloneNode(node.implementsClause),
- _mapToken(node.semicolon));
-
- @override
- Comment visitComment(Comment node) {
- if (node.isDocumentation) {
- return astFactory.documentationComment(
- _mapTokens(node.tokens), _cloneNodeList(node.references));
- } else if (node.isBlock) {
- return astFactory.blockComment(_mapTokens(node.tokens));
- }
- return astFactory.endOfLineComment(_mapTokens(node.tokens));
- }
-
- @override
- CommentReference visitCommentReference(CommentReference node) =>
- astFactory.commentReference(
- _mapToken(node.newKeyword), _cloneNode(node.identifier));
-
- @override
- CompilationUnit visitCompilationUnit(CompilationUnit node) {
- CompilationUnitImpl copy = astFactory.compilationUnit(
- beginToken: _mapToken(node.beginToken),
- scriptTag: _cloneNode(node.scriptTag),
- directives: _cloneNodeList(node.directives),
- declarations: _cloneNodeList(node.declarations),
- endToken: _mapToken(node.endToken),
- featureSet: node.featureSet);
- copy.lineInfo = node.lineInfo;
- copy.declaredElement = node.declaredElement;
- return copy;
- }
-
- @override
- ConditionalExpression visitConditionalExpression(ConditionalExpression node) {
- ConditionalExpression copy = astFactory.conditionalExpression(
- _cloneNode(node.condition),
- _mapToken(node.question),
- _cloneNode(node.thenExpression),
- _mapToken(node.colon),
- _cloneNode(node.elseExpression));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- Configuration visitConfiguration(Configuration node) =>
- astFactory.configuration(
- _mapToken(node.ifKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.name),
- _mapToken(node.equalToken),
- _cloneNode(node.value),
- _mapToken(node.rightParenthesis),
- _cloneNode(node.uri));
-
- @override
- ConstructorDeclaration visitConstructorDeclaration(
- ConstructorDeclaration node) {
- ConstructorDeclarationImpl copy = astFactory.constructorDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.externalKeyword),
- _mapToken(node.constKeyword),
- _mapToken(node.factoryKeyword),
- _cloneNode(node.returnType),
- _mapToken(node.period),
- _cloneNode(node.name),
- _cloneNode(node.parameters),
- _mapToken(node.separator),
- _cloneNodeList(node.initializers),
- _cloneNode(node.redirectedConstructor),
- _cloneNode(node.body));
- copy.declaredElement = node.declaredElement;
- return copy;
- }
-
- @override
- ConstructorFieldInitializer visitConstructorFieldInitializer(
- ConstructorFieldInitializer node) =>
- astFactory.constructorFieldInitializer(
- _mapToken(node.thisKeyword),
- _mapToken(node.period),
- _cloneNode(node.fieldName),
- _mapToken(node.equals),
- _cloneNode(node.expression));
-
- @override
- ConstructorName visitConstructorName(ConstructorName node) {
- ConstructorName copy = astFactory.constructorName(
- _cloneNode(node.type), _mapToken(node.period), _cloneNode(node.name));
- copy.staticElement = node.staticElement;
- return copy;
- }
-
- @override
- ContinueStatement visitContinueStatement(ContinueStatement node) =>
- astFactory.continueStatement(_mapToken(node.continueKeyword),
- _cloneNode(node.label), _mapToken(node.semicolon));
-
- @override
- DeclaredIdentifier visitDeclaredIdentifier(DeclaredIdentifier node) =>
- astFactory.declaredIdentifier(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.keyword),
- _cloneNode(node.type),
- _cloneNode(node.identifier));
-
- @override
- DefaultFormalParameter visitDefaultFormalParameter(
- DefaultFormalParameter node) =>
- astFactory.defaultFormalParameter(_cloneNode(node.parameter), node.kind,
- _mapToken(node.separator), _cloneNode(node.defaultValue));
-
- @override
- DoStatement visitDoStatement(DoStatement node) => astFactory.doStatement(
- _mapToken(node.doKeyword),
- _cloneNode(node.body),
- _mapToken(node.whileKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.condition),
- _mapToken(node.rightParenthesis),
- _mapToken(node.semicolon));
-
- @override
- DottedName visitDottedName(DottedName node) =>
- astFactory.dottedName(_cloneNodeList(node.components));
-
- @override
- DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
- DoubleLiteral copy =
- astFactory.doubleLiteral(_mapToken(node.literal), node.value);
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- EmptyFunctionBody visitEmptyFunctionBody(EmptyFunctionBody node) =>
- astFactory.emptyFunctionBody(_mapToken(node.semicolon));
-
- @override
- EmptyStatement visitEmptyStatement(EmptyStatement node) =>
- astFactory.emptyStatement(_mapToken(node.semicolon));
-
- @override
- AstNode visitEnumConstantDeclaration(EnumConstantDeclaration node) =>
- astFactory.enumConstantDeclaration(_cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata), _cloneNode(node.name));
-
- @override
- AstNode visitEnumDeclaration(EnumDeclaration node) =>
- astFactory.enumDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.enumKeyword),
- _cloneNode(node.name),
- _mapToken(node.leftBracket),
- _cloneNodeList(node.constants),
- _mapToken(node.rightBracket));
-
- @override
- ExportDirective visitExportDirective(ExportDirective node) {
- ExportDirective copy = astFactory.exportDirective(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.keyword),
- _cloneNode(node.uri),
- _cloneNodeList(node.configurations),
- _cloneNodeList(node.combinators),
- _mapToken(node.semicolon));
- copy.element = node.element;
- return copy;
- }
-
- @override
- ExpressionFunctionBody visitExpressionFunctionBody(
- ExpressionFunctionBody node) =>
- astFactory.expressionFunctionBody(
- _mapToken(node.keyword),
- _mapToken(node.functionDefinition),
- _cloneNode(node.expression),
- _mapToken(node.semicolon));
-
- @override
- ExpressionStatement visitExpressionStatement(ExpressionStatement node) =>
- astFactory.expressionStatement(
- _cloneNode(node.expression), _mapToken(node.semicolon));
-
- @override
- ExtendsClause visitExtendsClause(ExtendsClause node) =>
- astFactory.extendsClause(
- _mapToken(node.extendsKeyword), _cloneNode(node.superclass));
-
- @override
- ExtensionDeclaration visitExtensionDeclaration(ExtensionDeclaration node) =>
- astFactory.extensionDeclaration(
- comment: _cloneNode(node.documentationComment),
- metadata: _cloneNodeList(node.metadata),
- extensionKeyword: _mapToken(node.extensionKeyword),
- name: _cloneNode(node.name),
- typeParameters: _cloneNode(node.typeParameters),
- onKeyword: _mapToken(node.onKeyword),
- extendedType: _cloneNode(node.extendedType),
- leftBracket: _mapToken(node.leftBracket),
- members: _cloneNodeList(node.members),
- rightBracket: _mapToken(node.rightBracket));
-
- @override
- ExtensionOverride visitExtensionOverride(ExtensionOverride node) =>
- astFactory.extensionOverride(
- extensionName: _cloneNode(node.extensionName),
- typeArguments: _cloneNode(node.typeArguments),
- argumentList: _cloneNode(node.argumentList));
-
- @override
- FieldDeclaration visitFieldDeclaration(FieldDeclaration node) =>
- astFactory.fieldDeclaration2(
- comment: _cloneNode(node.documentationComment),
- metadata: _cloneNodeList(node.metadata),
- covariantKeyword: _mapToken(node.covariantKeyword),
- staticKeyword: _mapToken(node.staticKeyword),
- fieldList: _cloneNode(node.fields),
- semicolon: _mapToken(node.semicolon));
-
- @override
- FieldFormalParameter visitFieldFormalParameter(FieldFormalParameter node) =>
- astFactory.fieldFormalParameter2(
- comment: _cloneNode(node.documentationComment),
- metadata: _cloneNodeList(node.metadata),
- covariantKeyword: _mapToken(node.covariantKeyword),
- keyword: _mapToken(node.keyword),
- type: _cloneNode(node.type),
- thisKeyword: _mapToken(node.thisKeyword),
- period: _mapToken(node.period),
- identifier: _cloneNode(node.identifier),
- typeParameters: _cloneNode(node.typeParameters),
- parameters: _cloneNode(node.parameters));
-
- @override
- ForEachPartsWithDeclaration visitForEachPartsWithDeclaration(
- ForEachPartsWithDeclaration node) =>
- astFactory.forEachPartsWithDeclaration(
- loopVariable: _cloneNode(node.loopVariable),
- inKeyword: _mapToken(node.inKeyword),
- iterable: _cloneNode(node.iterable));
-
- @override
- ForEachPartsWithIdentifier visitForEachPartsWithIdentifier(
- ForEachPartsWithIdentifier node) =>
- astFactory.forEachPartsWithIdentifier(
- identifier: _cloneNode(node.identifier),
- inKeyword: _mapToken(node.inKeyword),
- iterable: _cloneNode(node.iterable));
-
- @override
- ForElement visitForElement(ForElement node) => astFactory.forElement(
- awaitKeyword: _mapToken(node.awaitKeyword),
- forKeyword: _mapToken(node.forKeyword),
- leftParenthesis: _mapToken(node.leftParenthesis),
- forLoopParts: _cloneNode(node.forLoopParts),
- rightParenthesis: _mapToken(node.rightParenthesis),
- body: _cloneNode(node.body));
-
- @override
- FormalParameterList visitFormalParameterList(FormalParameterList node) =>
- astFactory.formalParameterList(
- _mapToken(node.leftParenthesis),
- _cloneNodeList(node.parameters),
- _mapToken(node.leftDelimiter),
- _mapToken(node.rightDelimiter),
- _mapToken(node.rightParenthesis));
-
- @override
- ForPartsWithDeclarations visitForPartsWithDeclarations(
- ForPartsWithDeclarations node) =>
- astFactory.forPartsWithDeclarations(
- variables: _cloneNode(node.variables),
- leftSeparator: _mapToken(node.leftSeparator),
- condition: _cloneNode(node.condition),
- rightSeparator: _mapToken(node.rightSeparator),
- updaters: _cloneNodeList(node.updaters));
-
- @override
- ForPartsWithExpression visitForPartsWithExpression(
- ForPartsWithExpression node) =>
- astFactory.forPartsWithExpression(
- initialization: _cloneNode(node.initialization),
- leftSeparator: _mapToken(node.leftSeparator),
- condition: _cloneNode(node.condition),
- rightSeparator: _mapToken(node.rightSeparator),
- updaters: _cloneNodeList(node.updaters));
-
- @override
- ForStatement visitForStatement(ForStatement node) => astFactory.forStatement(
- awaitKeyword: _mapToken(node.awaitKeyword),
- forKeyword: _mapToken(node.forKeyword),
- leftParenthesis: _mapToken(node.leftParenthesis),
- forLoopParts: _cloneNode(node.forLoopParts),
- rightParenthesis: _mapToken(node.rightParenthesis),
- body: _cloneNode(node.body));
-
- @override
- FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
- astFactory.functionDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.externalKeyword),
- _cloneNode(node.returnType),
- _mapToken(node.propertyKeyword),
- _cloneNode(node.name),
- _cloneNode(node.functionExpression));
-
- @override
- FunctionDeclarationStatement visitFunctionDeclarationStatement(
- FunctionDeclarationStatement node) =>
- astFactory
- .functionDeclarationStatement(_cloneNode(node.functionDeclaration));
-
- @override
- FunctionExpression visitFunctionExpression(FunctionExpression node) {
- FunctionExpressionImpl copy = astFactory.functionExpression(
- _cloneNode(node.typeParameters),
- _cloneNode(node.parameters),
- _cloneNode(node.body));
- copy.declaredElement = node.declaredElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- FunctionExpressionInvocation visitFunctionExpressionInvocation(
- FunctionExpressionInvocation node) {
- FunctionExpressionInvocation copy = astFactory.functionExpressionInvocation(
- _cloneNode(node.function),
- _cloneNode(node.typeArguments),
- _cloneNode(node.argumentList));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
- astFactory.functionTypeAlias(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.typedefKeyword),
- _cloneNode(node.returnType),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _cloneNode(node.parameters),
- _mapToken(node.semicolon));
-
- @override
- FunctionTypedFormalParameter visitFunctionTypedFormalParameter(
- FunctionTypedFormalParameter node) =>
- astFactory.functionTypedFormalParameter2(
- comment: _cloneNode(node.documentationComment),
- metadata: _cloneNodeList(node.metadata),
- covariantKeyword: _mapToken(node.covariantKeyword),
- returnType: _cloneNode(node.returnType),
- identifier: _cloneNode(node.identifier),
- typeParameters: _cloneNode(node.typeParameters),
- parameters: _cloneNode(node.parameters),
- question: _mapToken(node.question));
-
- @override
- AstNode visitGenericFunctionType(GenericFunctionType node) =>
- astFactory.genericFunctionType(
- _cloneNode(node.returnType),
- _mapToken(node.functionKeyword),
- _cloneNode(node.typeParameters),
- _cloneNode(node.parameters),
- question: _mapToken(node.question));
-
- @override
- AstNode visitGenericTypeAlias(GenericTypeAlias node) =>
- astFactory.genericTypeAlias(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.typedefKeyword),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _mapToken(node.equals),
- _cloneNode(node.functionType),
- _mapToken(node.semicolon));
-
- @override
- HideCombinator visitHideCombinator(HideCombinator node) =>
- astFactory.hideCombinator(
- _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
-
- @override
- IfElement visitIfElement(IfElement node) => astFactory.ifElement(
- ifKeyword: _mapToken(node.ifKeyword),
- leftParenthesis: _mapToken(node.leftParenthesis),
- condition: _cloneNode(node.condition),
- rightParenthesis: _mapToken(node.rightParenthesis),
- thenElement: _cloneNode(node.thenElement),
- elseKeyword: _mapToken(node.elseKeyword),
- elseElement: _cloneNode(node.elseElement));
-
- @override
- IfStatement visitIfStatement(IfStatement node) => astFactory.ifStatement(
- _mapToken(node.ifKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.condition),
- _mapToken(node.rightParenthesis),
- _cloneNode(node.thenStatement),
- _mapToken(node.elseKeyword),
- _cloneNode(node.elseStatement));
-
- @override
- ImplementsClause visitImplementsClause(ImplementsClause node) =>
- astFactory.implementsClause(
- _mapToken(node.implementsKeyword), _cloneNodeList(node.interfaces));
-
- @override
- ImportDirective visitImportDirective(ImportDirective node) {
- ImportDirective copy = astFactory.importDirective(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.keyword),
- _cloneNode(node.uri),
- _cloneNodeList(node.configurations),
- _mapToken(node.deferredKeyword),
- _mapToken(node.asKeyword),
- _cloneNode(node.prefix),
- _cloneNodeList(node.combinators),
- _mapToken(node.semicolon));
- copy.element = node.element;
- return copy;
- }
-
- @override
- IndexExpression visitIndexExpression(IndexExpression node) {
- Token period = _mapToken(node.period);
- IndexExpression copy;
- if (period == null) {
- copy = astFactory.indexExpressionForTarget(
- _cloneNode(node.target),
- _mapToken(node.leftBracket),
- _cloneNode(node.index),
- _mapToken(node.rightBracket));
- } else {
- copy = astFactory.indexExpressionForCascade(
- period,
- _mapToken(node.leftBracket),
- _cloneNode(node.index),
- _mapToken(node.rightBracket));
- }
- copy.auxiliaryElements = node.auxiliaryElements;
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- InstanceCreationExpression visitInstanceCreationExpression(
- InstanceCreationExpression node) {
- InstanceCreationExpression copy = astFactory.instanceCreationExpression(
- _mapToken(node.keyword),
- _cloneNode(node.constructorName),
- _cloneNode(node.argumentList));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- IntegerLiteral visitIntegerLiteral(IntegerLiteral node) {
- IntegerLiteral copy =
- astFactory.integerLiteral(_mapToken(node.literal), node.value);
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- InterpolationExpression visitInterpolationExpression(
- InterpolationExpression node) =>
- astFactory.interpolationExpression(_mapToken(node.leftBracket),
- _cloneNode(node.expression), _mapToken(node.rightBracket));
-
- @override
- InterpolationString visitInterpolationString(InterpolationString node) =>
- astFactory.interpolationString(_mapToken(node.contents), node.value);
-
- @override
- IsExpression visitIsExpression(IsExpression node) {
- IsExpression copy = astFactory.isExpression(
- _cloneNode(node.expression),
- _mapToken(node.isOperator),
- _mapToken(node.notOperator),
- _cloneNode(node.type));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- Label visitLabel(Label node) =>
- astFactory.label(_cloneNode(node.label), _mapToken(node.colon));
-
- @override
- LabeledStatement visitLabeledStatement(LabeledStatement node) =>
- astFactory.labeledStatement(
- _cloneNodeList(node.labels), _cloneNode(node.statement));
-
- @override
- LibraryDirective visitLibraryDirective(LibraryDirective node) {
- LibraryDirective copy = astFactory.libraryDirective(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.libraryKeyword),
- _cloneNode(node.name),
- _mapToken(node.semicolon));
- copy.element = node.element;
- return copy;
- }
-
- @override
- LibraryIdentifier visitLibraryIdentifier(LibraryIdentifier node) {
- LibraryIdentifier copy =
- astFactory.libraryIdentifier(_cloneNodeList(node.components));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- ListLiteral visitListLiteral(ListLiteral node) {
- ListLiteral copy = astFactory.listLiteral(
- _mapToken(node.constKeyword),
- _cloneNode(node.typeArguments),
- _mapToken(node.leftBracket),
- _cloneNodeList(node.elements),
- _mapToken(node.rightBracket));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
- astFactory.mapLiteralEntry(_cloneNode(node.key),
- _mapToken(node.separator), _cloneNode(node.value));
-
- @override
- MethodDeclaration visitMethodDeclaration(MethodDeclaration node) =>
- astFactory.methodDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.externalKeyword),
- _mapToken(node.modifierKeyword),
- _cloneNode(node.returnType),
- _mapToken(node.propertyKeyword),
- _mapToken(node.operatorKeyword),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _cloneNode(node.parameters),
- _cloneNode(node.body));
-
- @override
- MethodInvocation visitMethodInvocation(MethodInvocation node) {
- MethodInvocation copy = astFactory.methodInvocation(
- _cloneNode(node.target),
- _mapToken(node.operator),
- _cloneNode(node.methodName),
- _cloneNode(node.typeArguments),
- _cloneNode(node.argumentList));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- AstNode visitMixinDeclaration(MixinDeclaration node) =>
- astFactory.mixinDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.mixinKeyword),
- _cloneNode(node.name),
- _cloneNode(node.typeParameters),
- _cloneNode(node.onClause),
- _cloneNode(node.implementsClause),
- _mapToken(node.leftBracket),
- _cloneNodeList(node.members),
- _mapToken(node.rightBracket));
-
- @override
- NamedExpression visitNamedExpression(NamedExpression node) {
- NamedExpression copy = astFactory.namedExpression(
- _cloneNode(node.name), _cloneNode(node.expression));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- AstNode visitNativeClause(NativeClause node) => astFactory.nativeClause(
- _mapToken(node.nativeKeyword), _cloneNode(node.name));
-
- @override
- NativeFunctionBody visitNativeFunctionBody(NativeFunctionBody node) =>
- astFactory.nativeFunctionBody(_mapToken(node.nativeKeyword),
- _cloneNode(node.stringLiteral), _mapToken(node.semicolon));
-
- @override
- NullLiteral visitNullLiteral(NullLiteral node) {
- NullLiteral copy = astFactory.nullLiteral(_mapToken(node.literal));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- AstNode visitOnClause(OnClause node) => astFactory.onClause(
- _mapToken(node.onKeyword), _cloneNodeList(node.superclassConstraints));
-
- @override
- ParenthesizedExpression visitParenthesizedExpression(
- ParenthesizedExpression node) {
- ParenthesizedExpression copy = astFactory.parenthesizedExpression(
- _mapToken(node.leftParenthesis),
- _cloneNode(node.expression),
- _mapToken(node.rightParenthesis));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- PartDirective visitPartDirective(PartDirective node) {
- PartDirective copy = astFactory.partDirective(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.partKeyword),
- _cloneNode(node.uri),
- _mapToken(node.semicolon));
- copy.element = node.element;
- return copy;
- }
-
- @override
- PartOfDirective visitPartOfDirective(PartOfDirective node) {
- PartOfDirective copy = astFactory.partOfDirective(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _mapToken(node.partKeyword),
- _mapToken(node.ofKeyword),
- _cloneNode(node.uri),
- _cloneNode(node.libraryName),
- _mapToken(node.semicolon));
- copy.element = node.element;
- return copy;
- }
-
- @override
- PostfixExpression visitPostfixExpression(PostfixExpression node) {
- PostfixExpression copy = astFactory.postfixExpression(
- _cloneNode(node.operand), _mapToken(node.operator));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- PrefixedIdentifier visitPrefixedIdentifier(PrefixedIdentifier node) {
- PrefixedIdentifier copy = astFactory.prefixedIdentifier(
- _cloneNode(node.prefix),
- _mapToken(node.period),
- _cloneNode(node.identifier));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- PrefixExpression visitPrefixExpression(PrefixExpression node) {
- PrefixExpression copy = astFactory.prefixExpression(
- _mapToken(node.operator), _cloneNode(node.operand));
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- PropertyAccess visitPropertyAccess(PropertyAccess node) {
- PropertyAccess copy = astFactory.propertyAccess(_cloneNode(node.target),
- _mapToken(node.operator), _cloneNode(node.propertyName));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
- RedirectingConstructorInvocation node) {
- RedirectingConstructorInvocation copy =
- astFactory.redirectingConstructorInvocation(
- _mapToken(node.thisKeyword),
- _mapToken(node.period),
- _cloneNode(node.constructorName),
- _cloneNode(node.argumentList));
- copy.staticElement = node.staticElement;
- return copy;
- }
-
- @override
- RethrowExpression visitRethrowExpression(RethrowExpression node) {
- RethrowExpression copy =
- astFactory.rethrowExpression(_mapToken(node.rethrowKeyword));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- ReturnStatement visitReturnStatement(ReturnStatement node) =>
- astFactory.returnStatement(_mapToken(node.returnKeyword),
- _cloneNode(node.expression), _mapToken(node.semicolon));
-
- @override
- ScriptTag visitScriptTag(ScriptTag node) =>
- astFactory.scriptTag(_mapToken(node.scriptTag));
-
- @override
- SetOrMapLiteral visitSetOrMapLiteral(SetOrMapLiteral node) {
- SetOrMapLiteral copy = astFactory.setOrMapLiteral(
- constKeyword: _mapToken(node.constKeyword),
- typeArguments: _cloneNode(node.typeArguments),
- leftBracket: _mapToken(node.leftBracket),
- elements: _cloneNodeList(node.elements),
- rightBracket: _mapToken(node.rightBracket));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- ShowCombinator visitShowCombinator(ShowCombinator node) => astFactory
- .showCombinator(_mapToken(node.keyword), _cloneNodeList(node.shownNames));
-
- @override
- SimpleFormalParameter visitSimpleFormalParameter(
- SimpleFormalParameter node) =>
- astFactory.simpleFormalParameter2(
- comment: _cloneNode(node.documentationComment),
- metadata: _cloneNodeList(node.metadata),
- covariantKeyword: _mapToken(node.covariantKeyword),
- keyword: _mapToken(node.keyword),
- type: _cloneNode(node.type),
- identifier: _cloneNode(node.identifier));
-
- @override
- SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
- Token mappedToken = _mapToken(node.token);
- if (mappedToken == null) {
- // This only happens for SimpleIdentifiers created by the parser as part
- // of scanning documentation comments (the tokens for those identifiers
- // are not in the original token stream and hence do not get copied).
- // This extra check can be removed if the scanner is changed to scan
- // documentation comments for the parser.
- mappedToken = node.token;
- }
- SimpleIdentifier copy = astFactory.simpleIdentifier(mappedToken,
- isDeclaration: node.inDeclarationContext());
- copy.auxiliaryElements = node.auxiliaryElements;
- copy.staticElement = node.staticElement;
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- SimpleStringLiteral visitSimpleStringLiteral(SimpleStringLiteral node) {
- SimpleStringLiteral copy =
- astFactory.simpleStringLiteral(_mapToken(node.literal), node.value);
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- SpreadElement visitSpreadElement(SpreadElement node) =>
- astFactory.spreadElement(
- spreadOperator: _mapToken(node.spreadOperator),
- expression: _cloneNode(node.expression));
-
- @override
- StringInterpolation visitStringInterpolation(StringInterpolation node) {
- StringInterpolation copy =
- astFactory.stringInterpolation(_cloneNodeList(node.elements));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- SuperConstructorInvocation visitSuperConstructorInvocation(
- SuperConstructorInvocation node) {
- SuperConstructorInvocation copy = astFactory.superConstructorInvocation(
- _mapToken(node.superKeyword),
- _mapToken(node.period),
- _cloneNode(node.constructorName),
- _cloneNode(node.argumentList));
- copy.staticElement = node.staticElement;
- return copy;
- }
-
- @override
- SuperExpression visitSuperExpression(SuperExpression node) {
- SuperExpression copy =
- astFactory.superExpression(_mapToken(node.superKeyword));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- SwitchCase visitSwitchCase(SwitchCase node) => astFactory.switchCase(
- _cloneNodeList(node.labels),
- _mapToken(node.keyword),
- _cloneNode(node.expression),
- _mapToken(node.colon),
- _cloneNodeList(node.statements));
-
- @override
- SwitchDefault visitSwitchDefault(SwitchDefault node) =>
- astFactory.switchDefault(
- _cloneNodeList(node.labels),
- _mapToken(node.keyword),
- _mapToken(node.colon),
- _cloneNodeList(node.statements));
-
- @override
- SwitchStatement visitSwitchStatement(SwitchStatement node) =>
- astFactory.switchStatement(
- _mapToken(node.switchKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.expression),
- _mapToken(node.rightParenthesis),
- _mapToken(node.leftBracket),
- _cloneNodeList(node.members),
- _mapToken(node.rightBracket));
-
- @override
- AstNode visitSymbolLiteral(SymbolLiteral node) {
- SymbolLiteral copy = astFactory.symbolLiteral(
- _mapToken(node.poundSign), _mapTokens(node.components));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- ThisExpression visitThisExpression(ThisExpression node) {
- ThisExpression copy =
- astFactory.thisExpression(_mapToken(node.thisKeyword));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- ThrowExpression visitThrowExpression(ThrowExpression node) {
- ThrowExpression copy = astFactory.throwExpression(
- _mapToken(node.throwKeyword), _cloneNode(node.expression));
- copy.staticType = node.staticType;
- return copy;
- }
-
- @override
- TopLevelVariableDeclaration visitTopLevelVariableDeclaration(
- TopLevelVariableDeclaration node) =>
- astFactory.topLevelVariableDeclaration(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _cloneNode(node.variables),
- _mapToken(node.semicolon));
-
- @override
- TryStatement visitTryStatement(TryStatement node) => astFactory.tryStatement(
- _mapToken(node.tryKeyword),
- _cloneNode(node.body),
- _cloneNodeList(node.catchClauses),
- _mapToken(node.finallyKeyword),
- _cloneNode(node.finallyBlock));
-
- @override
- TypeArgumentList visitTypeArgumentList(TypeArgumentList node) =>
- astFactory.typeArgumentList(_mapToken(node.leftBracket),
- _cloneNodeList(node.arguments), _mapToken(node.rightBracket));
-
- @override
- TypeName visitTypeName(TypeName node) {
- TypeName copy = astFactory.typeName(
- _cloneNode(node.name), _cloneNode(node.typeArguments),
- question: _mapToken(node.question));
- copy.type = node.type;
- return copy;
- }
-
- @override
- TypeParameter visitTypeParameter(TypeParameter node) =>
- astFactory.typeParameter(
- _cloneNode(node.documentationComment),
- _cloneNodeList(node.metadata),
- _cloneNode(node.name),
- _mapToken(node.extendsKeyword),
- _cloneNode(node.bound));
-
- @override
- TypeParameterList visitTypeParameterList(TypeParameterList node) =>
- astFactory.typeParameterList(_mapToken(node.leftBracket),
- _cloneNodeList(node.typeParameters), _mapToken(node.rightBracket));
-
- @override
- VariableDeclaration visitVariableDeclaration(VariableDeclaration node) =>
- astFactory.variableDeclaration(_cloneNode(node.name),
- _mapToken(node.equals), _cloneNode(node.initializer));
-
- @override
- VariableDeclarationList visitVariableDeclarationList(
- VariableDeclarationList node) =>
- astFactory.variableDeclarationList(
- null,
- _cloneNodeList(node.metadata),
- _mapToken(node.keyword),
- _cloneNode(node.type),
- _cloneNodeList(node.variables));
-
- @override
- VariableDeclarationStatement visitVariableDeclarationStatement(
- VariableDeclarationStatement node) =>
- astFactory.variableDeclarationStatement(
- _cloneNode(node.variables), _mapToken(node.semicolon));
-
- @override
- WhileStatement visitWhileStatement(WhileStatement node) =>
- astFactory.whileStatement(
- _mapToken(node.whileKeyword),
- _mapToken(node.leftParenthesis),
- _cloneNode(node.condition),
- _mapToken(node.rightParenthesis),
- _cloneNode(node.body));
-
- @override
- WithClause visitWithClause(WithClause node) => astFactory.withClause(
- _mapToken(node.withKeyword), _cloneNodeList(node.mixinTypes));
-
- @override
- YieldStatement visitYieldStatement(YieldStatement node) =>
- astFactory.yieldStatement(
- _mapToken(node.yieldKeyword),
- _mapToken(node.star),
- _cloneNode(node.expression),
- _mapToken(node.semicolon));
-
- E _cloneNode<E extends AstNode>(E node) {
- if (node == null) {
- return null;
- }
- if (identical(node, _oldNode)) {
- return _newNode as E;
- }
- return node.accept(this) as E;
- }
-
- List<E> _cloneNodeList<E extends AstNode>(NodeList<E> nodes) {
- List<E> clonedNodes = new List<E>();
- for (E node in nodes) {
- clonedNodes.add(_cloneNode(node));
- }
- return clonedNodes;
- }
-
- Token _mapToken(Token oldToken) {
- if (oldToken == null) {
- return null;
- }
- return _tokenMap.get(oldToken);
- }
-
- List<Token> _mapTokens(List<Token> oldTokens) {
- List<Token> newTokens = new List<Token>(oldTokens.length);
- for (int index = 0; index < newTokens.length; index++) {
- newTokens[index] = _mapToken(oldTokens[index]);
- }
- return newTokens;
- }
-}
-
-/**
* An object used to locate the [AstNode] associated with a source range, given
* the AST structure built from the source. More specifically, they will return
* the [AstNode] with the shortest length whose source range completely
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index ca2c1e5..f5b08f4 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -514,7 +514,7 @@
if (formalCount == 0 && !force) return original;
// Allocate fresh type variables
- var typeVars = <DartType>[];
+ var typeVars = <TypeParameterElement>[];
var freshTypeVars = <DartType>[];
var freshVarElements = <TypeParameterElement>[];
for (int i = 0; i < formalCount; i++) {
@@ -524,7 +524,7 @@
new TypeParameterElementImpl.synthetic(typeParamElement.name);
var freshTypeVar = new TypeParameterTypeImpl(freshElement);
- typeVars.add(typeParamElement.type);
+ typeVars.add(typeParamElement);
freshTypeVars.add(freshTypeVar);
freshVarElements.add(freshElement);
}
@@ -535,7 +535,8 @@
var bound = typeParamElement.bound;
if (bound != null) {
var freshElement = freshVarElements[i] as TypeParameterElementImpl;
- freshElement.bound = bound.substitute2(freshTypeVars, typeVars);
+ freshElement.bound = Substitution.fromPairs(typeVars, freshTypeVars)
+ .substituteType(bound);
}
}
@@ -747,7 +748,7 @@
}
List<DartType> instantiateTypeArgs = <DartType>[];
- List<DartType> variables = <DartType>[];
+ List<TypeParameterElement> variables = <TypeParameterElement>[];
typeParametersBuffer.write('<');
for (TypeParameterElement e in typeFormals) {
if (e != typeFormals[0]) {
@@ -769,11 +770,12 @@
t.appendTo(typeParametersBuffer, visitedTypes,
withNullability: withNullability);
instantiateTypeArgs.add(t);
- variables.add(e.type);
+ variables.add(e);
if (e.bound != null) {
typeParametersBuffer.write(' extends ');
TypeImpl renamed =
- e.bound.substitute2(instantiateTypeArgs, variables);
+ Substitution.fromPairs(variables, instantiateTypeArgs)
+ .substituteType(e.bound);
renamed.appendTo(typeParametersBuffer, visitedTypes);
}
}
@@ -1173,8 +1175,8 @@
// We build up a substitution matching up the type parameters
// from the two types, {variablesFresh/variables1} and
// {variablesFresh/variables2}
- List<DartType> variables1 = <DartType>[];
- List<DartType> variables2 = <DartType>[];
+ List<TypeParameterElement> variables1 = <TypeParameterElement>[];
+ List<TypeParameterElement> variables2 = <TypeParameterElement>[];
List<DartType> variablesFresh = <DartType>[];
for (int i = 0; i < count; i++) {
TypeParameterElement p1 = params1[i];
@@ -1182,18 +1184,18 @@
TypeParameterElementImpl pFresh =
new TypeParameterElementImpl.synthetic(p2.name);
- DartType variable1 = p1.type;
- DartType variable2 = p2.type;
DartType variableFresh = new TypeParameterTypeImpl(pFresh);
- variables1.add(variable1);
- variables2.add(variable2);
+ variables1.add(p1);
+ variables2.add(p2);
variablesFresh.add(variableFresh);
DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
- bound1 = bound1.substitute2(variablesFresh, variables1);
- bound2 = bound2.substitute2(variablesFresh, variables2);
+ bound1 = Substitution.fromPairs(variables1, variablesFresh)
+ .substituteType(bound1);
+ bound2 = Substitution.fromPairs(variables2, variablesFresh)
+ .substituteType(bound2);
if (!relation(bound2, bound1, p2, p1)) {
return null;
}
@@ -1706,8 +1708,8 @@
bool isDirectSupertypeOf(InterfaceType type) {
InterfaceType i = this;
InterfaceType j = type;
+ var substitution = Substitution.fromInterfaceType(j);
ClassElement jElement = j.element;
- InterfaceType supertype = jElement.supertype;
//
// If J is Object, then it has no direct supertypes.
//
@@ -1717,10 +1719,9 @@
//
// I is listed in the extends clause of J.
//
- List<DartType> jArgs = j.typeArguments;
- List<DartType> jVars = jElement.type.typeArguments;
+ InterfaceType supertype = jElement.supertype;
if (supertype != null) {
- supertype = supertype.substitute2(jArgs, jVars);
+ supertype = substitution.substituteType(supertype);
if (supertype == i) {
return true;
}
@@ -1729,7 +1730,7 @@
// I is listed in the on clause of J.
//
for (InterfaceType interfaceType in jElement.superclassConstraints) {
- interfaceType = interfaceType.substitute2(jArgs, jVars);
+ interfaceType = substitution.substituteType(interfaceType);
if (interfaceType == i) {
return true;
}
@@ -1738,7 +1739,7 @@
// I is listed in the implements clause of J.
//
for (InterfaceType interfaceType in jElement.interfaces) {
- interfaceType = interfaceType.substitute2(jArgs, jVars);
+ interfaceType = substitution.substituteType(interfaceType);
if (interfaceType == i) {
return true;
}
@@ -1747,7 +1748,7 @@
// I is listed in the with clause of J.
//
for (InterfaceType mixinType in jElement.mixins) {
- mixinType = mixinType.substitute2(jArgs, jVars);
+ mixinType = substitution.substituteType(mixinType);
if (mixinType == i) {
return true;
}
@@ -2855,8 +2856,6 @@
class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
static bool _comparingBounds = false;
- static bool _appendingBounds = false;
-
@override
final NullabilitySuffix nullabilitySuffix;
@@ -2898,29 +2897,6 @@
return false;
}
- /**
- * Append a textual representation of this type to the given [buffer]. The set
- * of [visitedTypes] is used to prevent infinite recursion.
- */
- void appendTo(StringBuffer buffer, Set<TypeImpl> visitedTypes,
- {bool withNullability = false}) {
- super.appendTo(buffer, visitedTypes, withNullability: withNullability);
- TypeParameterElement e = element;
- if (e is TypeParameterMember &&
- e.bound != e.baseElement.bound &&
- !_appendingBounds) {
- buffer.write(' extends ');
- // If we're appending bounds already, we don't want to do it recursively.
- _appendingBounds = true;
- try {
- (e.bound as TypeImpl)
- .appendTo(buffer, visitedTypes, withNullability: withNullability);
- } finally {
- _appendingBounds = false;
- }
- }
- }
-
@override
bool isMoreSpecificThan(DartType s,
[bool withDynamic = false, Set<Element> visitedElements]) {
@@ -3580,10 +3556,12 @@
if (argumentTypes.isEmpty) {
return this;
}
- var parameterTypes = typeFormals.map((p) => p.type).toList();
+
+ var substitution = Substitution.fromPairs(typeFormals, argumentTypes);
+
ParameterElement transformParameter(ParameterElement p) {
var type = p.type;
- var newType = type.substitute2(argumentTypes, parameterTypes);
+ var newType = substitution.substituteType(type);
if (identical(newType, type)) return p;
return new ParameterElementImpl.synthetic(
p.name,
@@ -3594,7 +3572,7 @@
}
return new _FunctionTypeImplStrict._(
- returnType.substitute2(argumentTypes, parameterTypes),
+ substitution.substituteType(returnType),
const [],
_transformOrShare(parameters, transformParameter),
nullabilitySuffix: nullabilitySuffix);
@@ -3612,56 +3590,12 @@
"argumentTypes.length (${argumentTypes.length}) != "
"parameterTypes.length (${parameterTypes.length})");
}
- TypeParameterElement transformTypeFormal(TypeParameterElement p) {
- var bound = p.bound;
- var newBound = bound?.substitute2(argumentTypes, parameterTypes);
- if (identical(bound, newBound)) return p;
- var element = new TypeParameterElementImpl.synthetic(p.name);
- element.bound = newBound;
- return element;
- }
- var newTypeFormals = _transformOrShare(typeFormals, transformTypeFormal);
- List<DartType> typeFormalsArgumentTypes;
- List<DartType> typeFormalsParameterTypes;
- if (!identical(typeFormals, newTypeFormals)) {
- typeFormalsArgumentTypes = newTypeFormals.map((p) => p.type).toList();
- typeFormalsParameterTypes = typeFormals.map((p) => p.type).toList();
- }
- DartType transformType(DartType t) {
- t = t.substitute2(argumentTypes, parameterTypes);
- if (typeFormalsArgumentTypes != null) {
- t = t.substitute2(typeFormalsArgumentTypes, typeFormalsParameterTypes);
- }
- return t;
- }
-
- ParameterElement transformParameter(ParameterElement p) {
- var type = p.type;
- var newType = transformType(type);
- if (identical(newType, type)) return p;
- return new ParameterElementImpl.synthetic(
- p.name,
- newType,
- // ignore: deprecated_member_use_from_same_package
- p.parameterKind);
- }
-
- var newReturnType = transformType(returnType);
- var newParameters = _transformOrShare(parameters, transformParameter);
- if (identical(returnType, newReturnType) &&
- identical(typeFormals, newTypeFormals) &&
- identical(parameters, newParameters)) {
- return this;
- }
-
- var typeArguments = this.typeArguments.map(transformType).toList();
-
- return new _FunctionTypeImplStrict._(
- newReturnType, newTypeFormals, newParameters,
- element: element,
- typeArguments: typeArguments,
- nullabilitySuffix: nullabilitySuffix);
+ var substitution = Substitution.fromPairs(
+ parameterTypes.map<TypeParameterElement>((t) => t.element).toList(),
+ argumentTypes,
+ );
+ return substitution.substituteType(this);
}
@override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index bc9e976..9a60696 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_visitor.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -448,7 +449,7 @@
}
@override
- DartType visitNamedType(NamedTypeBuilder type) {
+ DartType visitNamedTypeBuilder(NamedTypeBuilder type) {
if (type.arguments.isEmpty) {
return type;
}
@@ -472,6 +473,9 @@
}
@override
+ DartType visitUnknownInferredType(UnknownInferredType type) => type;
+
+ @override
DartType visitVoidType(VoidType type) => type;
static ParameterElementImpl _parameterElement(
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
index 08b8de6..fe8a706 100644
--- a/pkg/analyzer/lib/src/dart/element/type_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/summary2/function_type_builder.dart';
import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -22,10 +23,12 @@
R visitInterfaceType(InterfaceType type) => defaultDartType(type);
- R visitNamedType(NamedTypeBuilder type) => defaultDartType(type);
+ R visitNamedTypeBuilder(NamedTypeBuilder type) => defaultDartType(type);
R visitTypeParameterType(TypeParameterType type) => defaultDartType(type);
+ R visitUnknownInferredType(UnknownInferredType type) => defaultDartType(type);
+
R visitVoidType(VoidType type) => defaultDartType(type);
static R visit<R>(DartType type, DartTypeVisitor<R> visitor) {
@@ -45,11 +48,14 @@
return visitor.visitInterfaceType(type);
}
if (type is NamedTypeBuilder) {
- return visitor.visitNamedType(type);
+ return visitor.visitNamedTypeBuilder(type);
}
if (type is TypeParameterType) {
return visitor.visitTypeParameterType(type);
}
+ if (type is UnknownInferredType) {
+ return visitor.visitUnknownInferredType(type);
+ }
if (type is VoidType) {
return visitor.visitVoidType(type);
}
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index dbcc657..89c7e91 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -650,6 +650,9 @@
correction:
"Try moving all but one of the declarations inside the loop body.");
+ static const ParserErrorCode MULTIPLE_VARIANCE_MODIFIERS =
+ _MULTIPLE_VARIANCE_MODIFIERS;
+
static const ParserErrorCode MULTIPLE_WITH_CLAUSES = _MULTIPLE_WITH_CLAUSES;
static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode(
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 9653453..8a12c18 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -104,6 +104,7 @@
_EXTENSION_DECLARES_ABSTRACT_MEMBER,
_MIXIN_DECLARES_CONSTRUCTOR,
_NULL_AWARE_CASCADE_OUT_OF_ORDER,
+ _MULTIPLE_VARIANCE_MODIFIERS,
];
const ParserErrorCode _ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
@@ -471,6 +472,11 @@
r"Only one part-of directive may be declared in a file.",
correction: "Try removing all but one of the part-of directives.");
+const ParserErrorCode _MULTIPLE_VARIANCE_MODIFIERS = const ParserErrorCode(
+ 'MULTIPLE_VARIANCE_MODIFIERS',
+ r"Each type parameter can have at most one variance modifier.",
+ correction: "Use at most one of the 'in', 'out', or 'inout' modifiers.");
+
const ParserErrorCode _MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
'MULTIPLE_WITH_CLAUSES',
r"Each class definition can have at most one with clause.",
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index 2e6c7f7..a41d8f6 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -69,34 +69,38 @@
return ResolutionResult.ambiguous;
}
- /// Return the member with the [name] (without `=`).
+ /// Resolve the [name] (without `=`) to the corresponding getter and setter
+ /// members of the extension [node].
///
/// The [node] is fully resolved, and its type arguments are set.
- ExecutableElement getOverrideMember(
- ExtensionOverride node,
- String name, {
- bool setter = false,
- }) {
+ ResolutionResult getOverrideMember(ExtensionOverride node, String name) {
ExtensionElement element = node.extensionName.staticElement;
- ExecutableElement member;
- if (setter) {
- member = element.getSetter(name);
+ ExecutableElement getter;
+ ExecutableElement setter;
+ if (name == '[]') {
+ getter = element.getMethod('[]');
+ setter = element.getMethod('[]=');
} else {
- member = element.getGetter(name) ?? element.getMethod(name);
+ getter = element.getGetter(name) ?? element.getMethod(name);
+ setter = element.getSetter(name);
}
- if (member == null) {
- return null;
+ if (getter == null && setter == null) {
+ return ResolutionResult.none;
}
- return ExecutableMember.from2(
- member,
- Substitution.fromPairs(
- element.typeParameters,
- node.typeArgumentTypes,
- ),
+ var substitution = Substitution.fromPairs(
+ element.typeParameters,
+ node.typeArgumentTypes,
);
+
+ var getterMember =
+ getter != null ? ExecutableMember.from2(getter, substitution) : null;
+ var setterMember =
+ setter != null ? ExecutableMember.from2(setter, substitution) : null;
+
+ return ResolutionResult(getter: getterMember, setter: setterMember);
}
/// Perform upward inference for the override.
@@ -291,17 +295,38 @@
for (var field in extension.fields) {
if (field.name == name) {
candidates.add(
- _CandidateExtension(extension, field: field),
+ _CandidateExtension(
+ extension,
+ getter: field.getter,
+ setter: field.setter,
+ ),
);
return;
}
}
- for (var method in extension.methods) {
- if (method.name == name) {
+ if (name == '[]') {
+ ExecutableElement getter;
+ ExecutableElement setter;
+ for (var method in extension.methods) {
+ if (method.name == '[]') {
+ getter = method;
+ } else if (method.name == '[]=') {
+ setter = method;
+ }
+ }
+ if (getter != null || setter != null) {
candidates.add(
- _CandidateExtension(extension, method: method),
+ _CandidateExtension(extension, getter: getter, setter: setter),
);
- return;
+ }
+ } else {
+ for (var method in extension.methods) {
+ if (method.name == name) {
+ candidates.add(
+ _CandidateExtension(extension, getter: method),
+ );
+ return;
+ }
}
}
}
@@ -429,11 +454,11 @@
class _CandidateExtension {
final ExtensionElement extension;
- final FieldElement field;
- final MethodElement method;
+ final ExecutableElement getter;
+ final ExecutableElement setter;
- _CandidateExtension(this.extension, {this.field, this.method})
- : assert(field != null || method != null);
+ _CandidateExtension(this.extension, {this.getter, this.setter})
+ : assert(getter != null || setter != null);
}
class _InstantiatedExtension {
@@ -444,22 +469,22 @@
_InstantiatedExtension(this.candidate, this.substitution, this.extendedType);
ResolutionResult get asResolutionResult {
- return ResolutionResult(function: method, property: field);
+ return ResolutionResult(getter: getter, setter: setter);
}
ExtensionElement get extension => candidate.extension;
- FieldElement get field {
- if (candidate.field == null) {
+ ExecutableElement get getter {
+ if (candidate.getter == null) {
return null;
}
- return FieldMember.from2(candidate.field, substitution);
+ return ExecutableMember.from2(candidate.getter, substitution);
}
- MethodElement get method {
- if (candidate.method == null) {
+ ExecutableElement get setter {
+ if (candidate.setter == null) {
return null;
}
- return MethodMember.from2(candidate.method, substitution);
+ return ExecutableMember.from2(candidate.setter, substitution);
}
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 9244efd..4ac8a57 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -390,7 +390,8 @@
void _resolveExtensionOverride(MethodInvocation node,
ExtensionOverride override, SimpleIdentifier nameNode, String name) {
- var member = _extensionResolver.getOverrideMember(override, name);
+ var result = _extensionResolver.getOverrideMember(override, name);
+ var member = result.getter;
if (member == null) {
_setDynamicResolution(node);
@@ -747,7 +748,7 @@
var result = _extensionResolver.findExtension(
type, _nameCall.name, node.methodName);
if (result.isSingle) {
- call = result.function;
+ call = result.getter;
} else if (result.isAmbiguous) {
return;
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
index d3b7288..f87810c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_result.dart
@@ -4,7 +4,7 @@
import 'package:analyzer/dart/element/element.dart';
-/// The result of attempting to resolve an identifier to a element.
+/// The result of attempting to resolve an identifier to elements.
class ResolutionResult {
/// An instance that can be used anywhere that no element was found.
static const ResolutionResult none =
@@ -17,27 +17,22 @@
/// The state of the result.
final _ResolutionResultState state;
- /// The function that was found, or `null` if the [state] is not
- /// [_ResolutionResultState.single], or a [property] was found.
- final ExecutableElement function;
+ /// Return the element that is invoked for reading.
+ final ExecutableElement getter;
- /// The property that was found, or `null` if the [state] is not
- /// [_ResolutionResultState.single], or a [function] was found.
- final PropertyInducingElement property;
+ /// Return the element that is invoked for writing.
+ final ExecutableElement setter;
- /// Initialize a newly created result to represent resolving to a single
- /// [function] or [property].
- ResolutionResult({this.function, this.property})
- : assert(function != null || property != null),
+ /// Initialize a newly created result to represent resolving a single
+ /// reading and / or writing result.
+ ResolutionResult({this.getter, this.setter})
+ : assert(getter != null || setter != null),
state = _ResolutionResultState.single;
- /// Initialize a newly created result with no element and the given [state].
+ /// Initialize a newly created result with no elements and the given [state].
const ResolutionResult._(this.state)
- : function = null,
- property = null;
-
- /// Return the getter of the [property], or the [function].
- ExecutableElement get getter => function ?? property?.getter;
+ : getter = null,
+ setter = null;
/// Return `true` if this result represents the case where multiple ambiguous
/// elements were found.
@@ -55,12 +50,8 @@
/// If this is a function, return `true` is the function is static.
/// Otherwise return `false`.
bool get isStatic {
- return function?.isStatic ?? property?.isStatic ?? false;
+ return getter?.isStatic ?? setter?.isStatic ?? false;
}
-
- /// Return the setter of the [property], or `null` if this is not a property,
- /// or the property does not have a setter.
- ExecutableElement get setter => property?.setter;
}
/// The state of a [ResolutionResult].
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 3f75ebc..6bf0d08 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -621,8 +621,7 @@
for (File librariesFile in _libraryMapLocations) {
try {
String contents = librariesFile.readAsStringSync();
- return new SdkLibrariesReader(useDart2jsPaths)
- .readFromFile(librariesFile, contents);
+ return new SdkLibrariesReader().readFromFile(librariesFile, contents);
} catch (exception, stackTrace) {
searchedPaths.add(librariesFile.path);
lastException = exception;
@@ -873,17 +872,7 @@
* };
*/
class SdkLibrariesReader {
- /**
- * A flag indicating whether the dart2js path should be used when it is
- * available.
- */
- final bool _useDart2jsPaths;
-
- /**
- * Initialize a newly created library reader to use the dart2js path if
- * [_useDart2jsPaths] is `true`.
- */
- SdkLibrariesReader(this._useDart2jsPaths);
+ SdkLibrariesReader([@deprecated bool useDart2jsPaths]);
/**
* Return the library map read from the given [file], given that the content
@@ -907,7 +896,7 @@
Parser parser = new Parser(source, errorListener, featureSet: featureSet);
CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
SdkLibrariesReader_LibraryBuilder libraryBuilder =
- new SdkLibrariesReader_LibraryBuilder(_useDart2jsPaths);
+ new SdkLibrariesReader_LibraryBuilder(true);
// If any syntactic errors were found then don't try to visit the AST
// structure.
if (!errorListener.errorReported) {
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 11e27cf..d7f00f5 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -106,14 +106,35 @@
*/
class CompileTimeErrorCode extends AnalyzerErrorCode {
/**
- * Member lookups ignore abstract declarations, which means that there will
- * be a compile-time error if the targeted member `m` is abstract, as well as
- * when it does not exist at all.
- *
* Parameters:
* 0: the display name for the kind of the found abstract member
* 1: the name of the member
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an inherited member is
+ // referenced using `super`, but there is no concrete implementation of the
+ // member in the superclass chain. Abstract members can't be invoked.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // abstract class A {
+ // int get a;
+ // }
+ // class B extends A {
+ // int get a => super.[!a!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the invocation of the abstract member, possibly replacing it with an
+ // invocation of a concrete member.
+ // TODO(brianwilkerson) This either needs to be generalized (use 'member'
+ // rather than '{0}') or split into multiple codes.
static const CompileTimeErrorCode ABSTRACT_SUPER_MEMBER_REFERENCE =
const CompileTimeErrorCode('ABSTRACT_SUPER_MEMBER_REFERENCE',
"The {0} '{1}' is always abstract in the supertype.");
@@ -410,12 +431,25 @@
"Try marking the function body with either 'async' or 'async*'.");
/**
- * It is a compile-time error if a built-in identifier is used as the declared
- * name of an extension.
- *
* Parameters:
* 0: the built-in identifier that is being used
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the name of an extension is a
+ // built-in identifier. Built-in identifiers can’t be used as extension names.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension [!mixin!] on int {}
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Choose a different name for the extension.
static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME =
const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_EXTENSION_NAME',
"The built-in identifier '{0}' can't be used as an extension name.",
@@ -917,10 +951,62 @@
correction: "Try using a different value for the element, or "
"removing the keyword 'const' from the set.");
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the expression of a spread
+ // operator in a constant list or set evaluates to something other than a list
+ // or a set.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // const List<int> list1 = null;
+ // const List<int> list2 = [...[!list1!]];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Change the expression to something that evaluates to either a constant list
+ // or a constant set:
+ //
+ // ```dart
+ // const List<int> list1 = [];
+ // const List<int> list2 = [...list1];
+ // ```
static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_LIST_OR_SET =
const CompileTimeErrorCode('CONST_SPREAD_EXPECTED_LIST_OR_SET',
"A list or a set is expected in this spread.");
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the expression of a spread
+ // operator in a constant map evaluates to something other than a map.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // const Map<String, int> map1 = null;
+ // const Map<String, int> map2 = {...[!map1!]};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Change the expression to something that evaluates to a constant map:
+ //
+ // ```dart
+ // const Map<String, int> map1 = {};
+ // const Map<String, int> map2 = {...map1};
+ // ```
static const CompileTimeErrorCode CONST_SPREAD_EXPECTED_MAP =
const CompileTimeErrorCode(
'CONST_SPREAD_EXPECTED_MAP', "A map is expected in this spread.");
@@ -960,10 +1046,37 @@
correction: "Try using 'new' to call the constructor.");
/**
- * 16.12.2 Const: In all of the above cases, it is a compile-time error if
- * <i>a<sub>i</sub>, 1 <= i <= n + k</i>, is not a compile-time constant
- * expression.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a const constructor is invoked
+ // with an argument that isn't a constant expression.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // class C {
+ // final int i;
+ // const C(this.i);
+ // }
+ // C f(int i) => const C([!i!]);
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Either make all of the arguments constant expressions, or remove the
+ // `const` keyword to use the non-constant form of the constructor:
+ //
+ // ```dart
+ // class C {
+ // final int i;
+ // const C(this.i);
+ // }
+ // C f(int i) => C(i);
+ // ```
static const CompileTimeErrorCode CONST_WITH_NON_CONSTANT_ARGUMENT =
const CompileTimeErrorCode('CONST_WITH_NON_CONSTANT_ARGUMENT',
"Arguments of a constant creation must be constant expressions.",
@@ -1126,18 +1239,31 @@
correction: "Try renaming one of the constructors.");
/**
- * 3.1 Scoping: It is a compile-time error if there is more than one entity
- * with the same name declared in the same scope.
- *
- * 7 Classes: It is a compile-time error if a class declares two members of
- * the same name.
- *
- * 7 Classes: It is a compile-time error if a class has an instance member and
- * a static member with the same name.
- *
* Parameters:
* 0: the name of the duplicate entity
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a name is declared, and there is
+ // a previous declaration with the same name in the same scope.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // int x = 0;
+ // int [!x!] = 1;
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Choose a different name for one of the declarations.
+ //
+ // ```dart
+ // int x = 0;
+ // int y = 1;
+ // ```
static const CompileTimeErrorCode DUPLICATE_DEFINITION =
const CompileTimeErrorCode(
'DUPLICATE_DEFINITION', "The name '{0}' is already defined.",
@@ -1172,9 +1298,33 @@
"parameter.");
/**
- * 16.11 Sets: It is a compile-time error if two elements of a constant set
- * literal are equal according to their `==` operator (16.27).
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when two elements in a constant set
+ // literal have the same value. The set can only contain each value once,
+ // which means that one of the values is unnecessary.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // const Set<String> set = {'a', [!'a'!]};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove one of the duplicate values:
+ //
+ // ```dart
+ // const Set<String> set = {'a'};
+ // ```
+ //
+ // Note that literal sets preserve the order of their elements, so the choice
+ // of which element to remove might affect the order in which elements are
+ // returned by an iterator.
static const CompileTimeErrorCode EQUAL_ELEMENTS_IN_CONST_SET =
const CompileTimeErrorCode('EQUAL_ELEMENTS_IN_CONST_SET',
"Two values in a constant set can't be equal.");
@@ -1199,17 +1349,23 @@
//
// #### Common fixes
//
- // If one of the keys was supposed to be different, then replace it:
+ // If both entries should be included in the map, then change one of the keys
+ // to be different:
//
// ```dart
// const map = <int, String>{1: 'a', 2: 'b', 3: 'c', 4: 'd'};
// ```
//
- // Otherwise, remove the key/value pair that isn't intended to be in the map:
+ // If only one of the entries is needed, then remove the one that isn't
+ // needed:
//
// ```dart
// const map = <int, String>{1: 'a', 2: 'b', 4: 'd'};
// ```
+ //
+ // Note that literal maps preserve the order of their entries, so the choice
+ // of which entry to remove might affect the order in which keys and values
+ // are returned by an iterator.
static const CompileTimeErrorCode EQUAL_KEYS_IN_CONST_MAP =
const CompileTimeErrorCode('EQUAL_KEYS_IN_CONST_MAP',
"Two keys in a constant map literal can't be equal.",
@@ -1339,6 +1495,36 @@
* Parameters:
* 0: the name of the extension
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the name of an extension is used
+ // in an expression other than in an extension override or to qualify an
+ // access to a static member of the extension.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on int {
+ // static String m() => '';
+ // }
+ //
+ // var x = [!E!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Replace the name of the extension with a name that can be referenced, such
+ // as a static member defined on the extension:
+ //
+ // ```dart
+ // extension E on int {
+ // static String m() => '';
+ // }
+ //
+ // var x = E.m();
+ // ```
static const CompileTimeErrorCode EXTENSION_AS_EXPRESSION =
const CompileTimeErrorCode('EXTENSION_AS_EXPRESSION',
"Extension '{0}' can't be used as an expression.",
@@ -1518,6 +1704,39 @@
/**
* No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an extension override is used as
+ // the target of a cascade expression.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // extension E on int {
+ // void m() {}
+ // }
+ // f() {
+ // E(3)[!..!]m();
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Use '.' rather than '..':
+ //
+ // ```dart
+ // extension E on int {
+ // void m() {}
+ // }
+ // f() {
+ // E(3).m();
+ // }
+ // ```
+ //
+ // If there are multiple cascaded accesses, you'll need to duplicate the
+ // extension override for each one.
static const CompileTimeErrorCode EXTENSION_OVERRIDE_WITH_CASCADE =
const CompileTimeErrorCode(
'EXTENSION_OVERRIDE_WITH_CASCADE',
@@ -1581,32 +1800,84 @@
correction: 'Consider adding an access to an instance member.');
/**
- * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m <
- * h</i> or if <i>m > n</i>.
- *
- * 16.12.2 Const: It is a compile-time error if evaluation of a constant
- * object results in an uncaught exception being thrown.
- *
* Parameters:
* 0: the maximum number of positional arguments
* 1: the actual number of positional arguments given
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a method or function invocation
+ // has more positional arguments than the method or function allows.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f(int a, int b) {}
+ // void g() {
+ // f[!(1, 2, 3)!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Remove the arguments that don't correspond to parameters:
+ //
+ // ```dart
+ // void f(int a, int b) {}
+ // void g() {
+ // f(1, 2);
+ // }
+ // ```
static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS =
const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS',
"Too many positional arguments: {0} expected, but {1} found.",
correction: "Try removing the extra arguments.");
/**
- * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m <
- * h</i> or if <i>m > n</i>.
- *
- * 16.12.2 Const: It is a compile-time error if evaluation of a constant
- * object results in an uncaught exception being thrown.
- *
* Parameters:
* 0: the maximum number of positional arguments
* 1: the actual number of positional arguments given
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a method or function invocation
+ // has more positional arguments than the method or function allows, but the
+ // method or function defines named parameters.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f(int a, int b, {int c}) {}
+ // void g() {
+ // f[!(1, 2, 3)!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If some of the arguments should be values for named parameters, then add
+ // the names before the arguments:
+ //
+ // ```dart
+ // void f(int a, int b, {int c}) {}
+ // void g() {
+ // f(1, 2, c: 3);
+ // }
+ // ```
+ //
+ // Otherwise, remove the arguments that don't correspond to positional
+ // parameters:
+ //
+ // ```dart
+ // void f(int a, int b, {int c}) {}
+ // void g() {
+ // f(1, 2);
+ // }
+ // ```
static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED =
const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
"Too many positional arguments: {0} expected, but {1} found.",
@@ -1785,13 +2056,37 @@
"remove the class from the list.");
/**
- * 7.10 Superinterfaces: It is a compile-time error if the implements clause
- * of a class <i>C</i> includes a type expression that does not denote a class
- * available in the lexical scope of <i>C</i>.
- *
* Parameters:
* 0: the name of the interface that was not found
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a name used in the implements
+ // clause of a class or mixin declaration is defined to be something other
+ // than a class or mixin.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // var x;
+ // class C implements [!x!] {}
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the name is the name of an existing class or mixin that's already being
+ // imported, then add a prefix to the import so that the local definition of
+ // the name doesn't shadow the imported name.
+ //
+ // If the name is the name of an existing class or mixin that isn't being
+ // imported, then add an import, with a prefix, for the library in which it’s
+ // declared.
+ //
+ // Otherwise, either replace the name in the implements clause with the name
+ // of an existing class or mixin, or remove the name from the implements
+ // clause.
static const CompileTimeErrorCode IMPLEMENTS_NON_CLASS =
const CompileTimeErrorCode('IMPLEMENTS_NON_CLASS',
"Classes and mixins can only implement other classes and mixins.",
@@ -2334,6 +2629,16 @@
const CompileTimeErrorCode('INVALID_URI', "Invalid URI syntax: '{0}'.");
/**
+ * Parameters:
+ * 0: the name of the extension
+ */
+ static const CompileTimeErrorCode INVOCATION_OF_EXTENSION_WITHOUT_CALL =
+ const CompileTimeErrorCode(
+ 'INVOCATION_OF_EXTENSION_WITHOUT_CALL',
+ "The extension '{0}' does not define a 'call' method so the override "
+ "can't be used in an invocation.");
+
+ /**
* 13.13 Break: It is a compile-time error if no such statement
* <i>s<sub>E</sub></i> exists within the innermost function in which
* <i>s<sub>b</sub></i> occurs.
@@ -2367,6 +2672,42 @@
correction: "Try defining the label, or "
"correcting the name to match an existing label.");
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a map entry (a key/value pair)
+ // is found in a set literal.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // const collection = <String>{[!'a' : 'b'!]};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you intended for the collection to be a map, then change the code so
+ // that it is a map. In the previous example, you could do this by adding
+ // another type argument:
+ //
+ // ```dart
+ // const collection = <String, String>{'a' : 'b'};
+ // ```
+ //
+ // In other cases, you might need to change the explicit type from `Set` to
+ // `Map`.
+ //
+ // If you intended for the collection to be a set, then remove the map entry,
+ // possibly by replacing the colon with a comma if both values should be
+ // included in the set:
+ //
+ // ```dart
+ // const collection = <String>{'a', 'b'};
+ // ```
static const CompileTimeErrorCode MAP_ENTRY_NOT_IN_MAP =
const CompileTimeErrorCode('MAP_ENTRY_NOT_IN_MAP',
"Map entries can only be used in a map literal.",
@@ -2772,16 +3113,39 @@
"used as an expression statement.");
/**
- * 13.9 Switch: Given a switch statement of the form <i>switch (e) {
- * label<sub>11</sub> … label<sub>1j1</sub> case e<sub>1</sub>:
- * s<sub>1</sub> … label<sub>n1</sub> … label<sub>njn</sub> case
- * e<sub>n</sub>: s<sub>n</sub> default: s<sub>n+1</sub>}</i> or the form
- * <i>switch (e) { label<sub>11</sub> … label<sub>1j1</sub> case
- * e<sub>1</sub>: s<sub>1</sub> … label<sub>n1</sub> …
- * label<sub>njn</sub> case e<sub>n</sub>: s<sub>n</sub>}</i>, it is a
- * compile-time error if the expressions <i>e<sub>k</sub></i> are not
- * compile-time constants, for all <i>1 <= k <= n</i>.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the expression in a case clause
+ // isn't a constant expression.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f(int i, int j) {
+ // switch (i) {
+ // case [!j!]:
+ // // ...
+ // break;
+ // }
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Either make the expression a constant expression, or rewrite the switch
+ // statement as a sequence of if statements:
+ //
+ // ```dart
+ // void f(int i, int j) {
+ // if (i == j) {
+ // // ...
+ // }
+ // }
+ // ```
static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION =
const CompileTimeErrorCode(
'NON_CONSTANT_CASE_EXPRESSION', "Case expressions must be constant.");
@@ -2898,9 +3262,38 @@
"Try removing the keyword 'const' from the list literal.");
/**
- * 12.7 Maps: It is a compile time error if either a key or a value of an
- * entry in a constant map literal is not a compile-time constant.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a key in a constant map literal
+ // isn't a constant value.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // var a = 'a';
+ // var m = const {[!a!]: 0};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the map needs to be a constant map, then make the key a constant:
+ //
+ // ```dart
+ // const a = 'a';
+ // var m = const {a: 0};
+ // ```
+ //
+ // If the map doesn't need to be a constant map, then remove the `const`
+ // keyword:
+ //
+ // ```dart
+ // var a = 'a';
+ // var m = {a: 0};
+ // ```
static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY =
const CompileTimeErrorCode('NON_CONSTANT_MAP_KEY',
"The keys in a const map literal must be constant.",
@@ -2921,18 +3314,87 @@
correction: "Try removing the keyword 'const' from the map literal.");
/**
- * 12.7 Maps: It is a compile time error if either a key or a value of an
- * entry in a constant map literal is not a compile-time constant.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a value in a constant map
+ // literal isn't a constant value.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // var a = 'a';
+ // var m = const {0: [!a!]};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the map needs to be a constant map, then make the key a constant:
+ //
+ // ```dart
+ // const a = 'a';
+ // var m = const {0: a};
+ // ```
+ //
+ // If the map doesn't need to be a constant map, then remove the `const`
+ // keyword:
+ //
+ // ```dart
+ // var a = 'a';
+ // var m = {0: a};
+ // ```
static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE =
const CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE',
"The values in a const map literal must be constant.",
correction: "Try removing the keyword 'const' from the map literal.");
/**
- * 12.7 Maps: It is a compile time error if an element of a constant map
- * literal is not a compile-time constant.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an if element or a spread
+ // element in a constant map isn't a constant element.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because it is attempting to
+ // spread a non-constant map:
+ //
+ // ```dart
+ // var notConst = <int, int>{};
+ // var map = const <int, int>{...[!notConst!]};
+ // ```
+ //
+ // Similarly, the following code produces this diagnostic because the
+ // condition in the if element isn't a constant expression:
+ //
+ // ```dart
+ // bool notConst = true;
+ // var map = const <int, int>{if ([!notConst!]) 1 : 2};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the map needs to be a constant map, then make the elements constants.
+ // In the spread example, you might do that by making the collection being
+ // spread a constant:
+ //
+ // ```dart
+ // const notConst = <int, int>{};
+ // var map = const <int, int>{...notConst};
+ // ```
+ //
+ // If the map doesn't need to be a constant map, then remove the `const`
+ // keyword:
+ //
+ // ```dart
+ // bool notConst = true;
+ // var map = <int, int>{if (notConst) 1 : 2};
+ // ```
static const CompileTimeErrorCode NON_CONSTANT_MAP_ELEMENT =
const CompileTimeErrorCode('NON_CONSTANT_MAP_ELEMENT',
"The elements in a const map literal must be constant.",
@@ -3022,6 +3484,33 @@
* 0: the expected number of required arguments
* 1: the actual number of positional arguments given
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a method or function invocation
+ // has fewer positional arguments than the number of required positional
+ // parameters.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f(int a, int b) {}
+ // void g() {
+ // f[!(0)!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Add arguments corresponding to the remaining parameters:
+ //
+ // ```dart
+ // void f(int a, int b) {}
+ // void g() {
+ // f(0, 1);
+ // }
+ // ```
static const CompileTimeErrorCode NOT_ENOUGH_POSITIONAL_ARGUMENTS =
const CompileTimeErrorCode('NOT_ENOUGH_POSITIONAL_ARGUMENTS',
"{0} positional argument(s) expected, but {1} found.",
@@ -3112,6 +3601,33 @@
"Spread elements in list or set literals must implement 'Iterable'.",
hasPublishedDocs: true);
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the static type of the
+ // expression of a spread element that appears in a map literal doesn't
+ // implement the type `Map`.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // var l = <String>['a', 'b'];
+ // var m = <int, String>{...[!l!]};
+ // ```
+ //
+ // #### Common fixes
+ //
+ // The most common fix is to replace the expression with one that produces a
+ // map:
+ //
+ // ```dart
+ // var l = <String>['a', 'b'];
+ // var m = <int, String>{...l.asMap()};
+ // ```
static const CompileTimeErrorCode NOT_MAP_SPREAD = const CompileTimeErrorCode(
'NOT_MAP_SPREAD',
"Spread elements in map literals must implement 'Map'.");
@@ -3484,10 +4000,52 @@
correction: "Try redirecting to a different constructor.");
/**
- * 5 Variables: A local variable may only be referenced at a source code
- * location that is after its initializer, if any, is complete, or a
- * compile-time error occurs.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a variable is referenced before
+ // it’s declared. In Dart, variables are visible everywhere in the block in
+ // which they are declared, but can only be referenced after they are
+ // declared.
+ //
+ // The analyzer also produces a context message that indicates where the
+ // declaration is located.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f() {
+ // print([!i!]);
+ // int i = 5;
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you intended to reference the local variable, move the declaration
+ // before the first reference:
+ //
+ // ```dart
+ // void f() {
+ // int i = 5;
+ // print(i);
+ // }
+ // ```
+ //
+ // If you intended to reference a name from an outer scope, such as a
+ // parameter, instance field or top-level variable, then rename the local
+ // declaration so that it doesn't hide the outer variable.
+ //
+ // ```dart
+ // void f(int i) {
+ // print(i);
+ // int x = 5;
+ // print(x);
+ // }
+ // ```
static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION =
const CompileTimeErrorCode('REFERENCED_BEFORE_DECLARATION',
"Local variable '{0}' can't be referenced before it is declared.",
@@ -3670,11 +4228,42 @@
correction: "Try removing the type parameters.");
/**
- * 15 Metadata: Metadata consists of a series of annotations, each of which
- * begin with the character @, followed by a constant expression that must be
- * either a reference to a compile-time constant variable, or a call to a
- * constant constructor.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a name that isn't defined is
+ // used as an annotation.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // [!@undefined!]
+ // void f() {}
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the name is correct, but it isn’t declared yet, then declare the name as
+ // a constant value:
+ //
+ // ```dart
+ // const undefined = 'undefined';
+ //
+ // @undefined
+ // void f() {}
+ // ```
+ //
+ // If the name is wrong, replace the name with the name of a valid constant:
+ //
+ // ```dart
+ // @deprecated
+ // void f() {}
+ // ```
+ //
+ // Otherwise, remove the annotation.
static const CompileTimeErrorCode UNDEFINED_ANNOTATION =
const CompileTimeErrorCode(
'UNDEFINED_ANNOTATION', "Undefined name '{0}' used as an annotation.",
@@ -3960,6 +4549,16 @@
/**
* Parameters:
+ * 0: the name of the operator that is undefined
+ * 1: the name of the extension that was explicitly specified
+ */
+ static const CompileTimeErrorCode UNDEFINED_EXTENSION_OPERATOR =
+ const CompileTimeErrorCode('UNDEFINED_EXTENSION_OPERATOR',
+ "The operator '{0}' isn't defined for the extension '{1}'.",
+ correction: "Try defining the operator '{0}'.");
+
+ /**
+ * Parameters:
* 0: the name of the setter that is undefined
* 1: the name of the extension that was explicitly specified
*/
@@ -4139,12 +4738,67 @@
* Parameters:
* 0: the name of the defining type
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an undefined name is found, and
+ // the name is the same as a static member of the extended type or one of its
+ // superclasses.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // class C {
+ // static void m() {}
+ // }
+ //
+ // extension E on C {
+ // void f() {
+ // [!m!]();
+ // }
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If you're trying to reference a static member that's declared outside the
+ // extension, then add the name of the class or extension before the reference
+ // to the member:
+ //
+ // ```dart
+ // class C {
+ // static void m() {}
+ // }
+ //
+ // extension E on C {
+ // void f() {
+ // C.m();
+ // }
+ // }
+ // ```
+ //
+ // If you're referencing a member that isn't declared yet, add a declaration:
+ //
+ // ```dart
+ // class C {
+ // static void m() {}
+ // }
+ //
+ // extension E on C {
+ // void f() {
+ // m();
+ // }
+ //
+ // void m() {}
+ // }
+ // ```
static const CompileTimeErrorCode
UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE =
const CompileTimeErrorCode(
'UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE',
- "Static members from the extended type or one of its superclasses must "
- "be qualified by the name of the defining type.",
+ "Static members from the extended type or one of its superclasses "
+ "must be qualified by the name of the defining type.",
correction: "Try adding '{0}.' before the name.");
/**
@@ -4432,22 +5086,47 @@
correction: "Try using the class '{2}' to access the {1}.");
/**
- * 12.18 Assignment: It is a static type warning if the static type of
- * <i>e</i> may not be assigned to the static type of <i>v</i>. The static
- * type of the expression <i>v = e</i> is the static type of <i>e</i>.
- *
- * 12.18 Assignment: It is a static type warning if the static type of
- * <i>e</i> may not be assigned to the static type of <i>C.v</i>. The static
- * type of the expression <i>C.v = e</i> is the static type of <i>e</i>.
- *
- * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>.
- * It is a static type warning if the static type of <i>e<sub>2</sub></i> may
- * not be assigned to <i>T</i>.
- *
* Parameters:
* 0: the name of the right hand side type
* 1: the name of the left hand side type
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the static type of an expression
+ // that is assigned to a variable isn't assignable to the type of the
+ // variable.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic because the type of the
+ // initializer (`int`) isn't assignable to the type of the variable
+ // (`String`):
+ //
+ // ```dart
+ // int i = 0;
+ // String s = [!i!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the value being assigned is always assignable at runtime, even though
+ // the static types don't reflect that, then add an explicit cast.
+ //
+ // Otherwise, change the value being assigned so that it has the expected
+ // type. In the previous example, this might look like:
+ //
+ // ```dart
+ // int i = 0;
+ // String s = i.toString();
+ // ```
+ //
+ // If you can’t change the value, then change the type of the variable to be
+ // compatible with the type of the value being assigned:
+ //
+ // ```dart
+ // int i = 0;
+ // int s = i;
+ // ```
static const StaticTypeWarningCode INVALID_ASSIGNMENT =
const StaticTypeWarningCode(
'INVALID_ASSIGNMENT',
@@ -4800,6 +5479,34 @@
"The operator '{0}' isn't defined for the class '{1}'.",
correction: "Try defining the operator '{0}'.");
+ /**
+ * No parameters.
+ */
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a prefixed identifier is found
+ // where the prefix is valid, but the identifier isn't declared in any of the
+ // libraries imported using that prefix.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // import 'dart:core' as p;
+ //
+ // void f() {
+ // p.[!a!];
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the library in which the name is declared isn't imported yet, add an
+ // import for the library.
+ //
+ // If the name is wrong, then change it to one of the names that's declared in
+ // the imported libraries.
static const StaticTypeWarningCode UNDEFINED_PREFIXED_NAME =
const StaticTypeWarningCode(
'UNDEFINED_PREFIXED_NAME',
@@ -4871,16 +5578,38 @@
"defining a getter or field named '{0}' in a superclass.");
/**
- * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
- * <i>super.m(a<sub>1</sub>, …, a<sub>n</sub>, x<sub>n+1</sub>:
- * a<sub>n+1</sub>, … x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a
- * static type warning if <i>S</i> does not have an accessible instance member
- * named <i>m</i>.
- *
* Parameters:
* 0: the name of the method that is undefined
* 1: the resolved type name that the method lookup is happening on
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when an inherited method is
+ // referenced using `super`, but there’s no method with that name in the
+ // superclass chain.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // class C {
+ // void m() {
+ // super.[!n!]();
+ // }
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // If the inherited method you intend to invoke has a different name, then
+ // make the name of the invoked method match the inherited method.
+ //
+ // If the method you intend to invoke is defined in the same class, then
+ // remove the `super.`.
+ //
+ // If not, then either add the method to one of the superclasses or remove the
+ // invocation.
static const StaticTypeWarningCode UNDEFINED_SUPER_METHOD =
const StaticTypeWarningCode('UNDEFINED_SUPER_METHOD',
"The method '{0}' isn't defined in a superclass of '{1}'.",
@@ -5243,9 +5972,30 @@
correction: "Try adding one of the required statements.");
/**
- * 12.32 Type Cast: It is a static warning if <i>T</i> does not denote a type
- * available in the current lexical scope.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the name following the `as` in a
+ // cast expression is defined to be something other than a type.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // num x = 0;
+ // int y = x as [!x!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Replace the name with the name of a type:
+ //
+ // ```dart
+ // num x = 0;
+ // int y = x as int;
+ // ```
static const StaticWarningCode CAST_TO_NON_TYPE = const StaticWarningCode(
'CAST_TO_NON_TYPE',
"The name '{0}' isn't a type, so it can't be used in an 'as' expression.",
@@ -5370,13 +6120,50 @@
"changing the field's type.");
/**
- * 5 Variables: It is a static warning if a library, static or local variable
- * <i>v</i> is final and <i>v</i> is not initialized at its point of
- * declaration.
- *
* Parameters:
* 0: the name of the uninitialized final variable
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when a final field or variable isn't
+ // initialized.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // final [!x!];
+ // ```
+ //
+ // #### Common fixes
+ //
+ // For variables and static fields, you can add an initializer:
+ //
+ // ```dart
+ // final x = 0;
+ // ```
+ //
+ // For instance fields, you can add an initializer as shown in the previous
+ // example, or you can initialize the field in every constructor. You can
+ // initialize the field by using a field formal parameter:
+ //
+ // ```dart
+ // class C {
+ // final int x;
+ // C(this.x);
+ // }
+ // ```
+ //
+ // You can also initialize the field by using an initializer in the
+ // constructor:
+ //
+ // ```dart
+ // class C {
+ // final int x;
+ // C(int y) : x = y * 2;
+ // }
+ // ```
static const StaticWarningCode FINAL_NOT_INITIALIZED =
const StaticWarningCode('FINAL_NOT_INITIALIZED',
"The final variable '{0}' must be initialized.",
@@ -6005,9 +6792,36 @@
correction: "Try correcting the name to match an existing type.");
/**
- * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type
- * available in the current lexical scope.
+ * No parameters.
*/
+ // #### Description
+ //
+ // The analyzer produces this diagnostic when the name following the `is` in a
+ // type test expression isn't defined.
+ //
+ // #### Example
+ //
+ // The following code produces this diagnostic:
+ //
+ // ```dart
+ // void f(Object o) {
+ // if (o is [!Srting!]) {
+ // // ...
+ // }
+ // }
+ // ```
+ //
+ // #### Common fixes
+ //
+ // Replace the name with the name of a type:
+ //
+ // ```dart
+ // void f(Object o) {
+ // if (o is String) {
+ // // ...
+ // }
+ // }
+ // ```
static const StaticWarningCode TYPE_TEST_WITH_UNDEFINED_NAME =
const StaticWarningCode(
'TYPE_TEST_WITH_UNDEFINED_NAME',
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 5d94e1b..078a9da 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -121,6 +121,9 @@
/// `true` if triple-shift behavior is enabled
final bool enableTripleShift;
+ /// `true` if variance behavior is enabled
+ final bool enableVariance;
+
final FeatureSet _featureSet;
AstBuilder(ErrorReporter errorReporter, this.fileUri, this.isFullAst,
@@ -133,6 +136,7 @@
this.enableControlFlowCollections =
_featureSet.isEnabled(Feature.control_flow_collections),
this.enableTripleShift = _featureSet.isEnabled(Feature.triple_shift),
+ this.enableVariance = _featureSet.isEnabled(Feature.variance),
uri = uri ?? fileUri;
NodeList<ClassMember> get currentDeclarationMembers {
@@ -3338,6 +3342,14 @@
}
@override
+ void handleVarianceModifier(Token variance) {
+ debugEvent('VarianceModifier');
+ if (!enableVariance) {
+ reportVarianceModifierNotEnabled(variance);
+ }
+ }
+
+ @override
void handleVoidKeyword(Token voidKeyword) {
assert(optional('void', voidKeyword));
debugEvent("VoidKeyword");
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 25b6dcc..b2d006f 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/builder.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart';
/// A visitor that resolves declarations in an AST structure to already built
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 6e95ad6..fd7e626 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,7 +19,9 @@
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
+import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
import 'package:analyzer/src/dart/resolver/resolution_result.dart';
@@ -173,9 +175,9 @@
String methodName = operatorType.lexeme;
// TODO(brianwilkerson) Change the [methodNameNode] from the left hand
// side to the operator.
- var result = _newPropertyResolver().resolveOperator(
- leftHandSide, staticType, methodName, leftHandSide);
- node.staticElement = result.function;
+ var result = _newPropertyResolver()
+ .resolve(leftHandSide, staticType, methodName, leftHandSide);
+ node.staticElement = result.getter;
if (_shouldReportInvalidMember(staticType, result)) {
_recordUndefinedToken(
staticType.element,
@@ -266,10 +268,9 @@
}
if (node.newKeyword == null) {
if (element is ClassElement) {
- var propertyResolver = _newPropertyResolver();
- propertyResolver.resolve(prefix, element.type, name.name, name);
- name.staticElement = propertyResolver.getterResult.getter ??
- propertyResolver.setterResult.setter ??
+ name.staticElement = element.getMethod(name.name) ??
+ element.getGetter(name.name) ??
+ element.getSetter(name.name) ??
element.getNamedConstructor(name.name);
} else {
// TODO(brianwilkerson) Report this error.
@@ -396,14 +397,23 @@
Expression function = node.function;
DartType functionType;
if (function is ExtensionOverride) {
- var member = _extensionResolver.getOverrideMember(function, 'call');
- if (member != null && member.isStatic) {
+ var result = _extensionResolver.getOverrideMember(function, 'call');
+ var member = result.getter;
+ if (member == null) {
_resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
- node.argumentList);
+ CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL,
+ function,
+ [function.extensionName.name]);
+ functionType = _resolver.typeProvider.dynamicType;
+ } else {
+ if (member.isStatic) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER,
+ node.argumentList);
+ }
+ node.staticElement = member;
+ functionType = member.type;
}
- node.staticElement = member;
- functionType = member.type;
} else {
functionType = function.staticType;
}
@@ -466,47 +476,36 @@
void visitIndexExpression(IndexExpression node) {
Expression target = node.realTarget;
DartType staticType = _getStaticType(target);
+
String getterMethodName = TokenType.INDEX.lexeme;
String setterMethodName = TokenType.INDEX_EQ.lexeme;
+
+ ResolutionResult result;
+ if (target is ExtensionOverride) {
+ result = _extensionResolver.getOverrideMember(target, getterMethodName);
+ } else {
+ result = _newPropertyResolver()
+ .resolve(target, staticType, getterMethodName, target);
+ }
+
bool isInGetterContext = node.inGetterContext();
bool isInSetterContext = node.inSetterContext();
if (isInGetterContext && isInSetterContext) {
- // lookup setter
- ResolutionResult setterResult = _newPropertyResolver()
- .resolveOperator(target, staticType, setterMethodName, target);
- // set setter element
- node.staticElement = setterResult.function;
- // generate undefined method warning
- _checkForUndefinedIndexOperator(
- node, target, setterMethodName, setterResult, staticType);
- // lookup getter method
- ResolutionResult getterResult = _newPropertyResolver()
- .resolveOperator(target, staticType, getterMethodName, target);
- // set getter element
- AuxiliaryElements auxiliaryElements =
- new AuxiliaryElements(getterResult.function, null);
- node.auxiliaryElements = auxiliaryElements;
- // generate undefined method warning
- _checkForUndefinedIndexOperator(
- node, target, getterMethodName, getterResult, staticType);
+ node.staticElement = result.setter;
+ node.auxiliaryElements = AuxiliaryElements(result.getter, null);
} else if (isInGetterContext) {
- // lookup getter method
- ResolutionResult methodResult = _newPropertyResolver()
- .resolveOperator(target, staticType, getterMethodName, target);
- // set getter element
- node.staticElement = methodResult.function;
- // generate undefined method warning
- _checkForUndefinedIndexOperator(
- node, target, getterMethodName, methodResult, staticType);
+ node.staticElement = result.getter;
} else if (isInSetterContext) {
- // lookup setter method
- ResolutionResult methodResult = _newPropertyResolver()
- .resolveOperator(target, staticType, setterMethodName, target);
- // set setter element
- node.staticElement = methodResult.function;
- // generate undefined method warning
+ node.staticElement = result.setter;
+ }
+
+ if (isInGetterContext) {
_checkForUndefinedIndexOperator(
- node, target, setterMethodName, methodResult, staticType);
+ node, target, getterMethodName, result, result.getter, staticType);
+ }
+ if (isInSetterContext) {
+ _checkForUndefinedIndexOperator(
+ node, target, setterMethodName, result, result.setter, staticType);
}
}
@@ -558,8 +557,8 @@
String methodName = _getPostfixOperator(node);
DartType staticType = _getStaticType(operand);
var result = _newPropertyResolver()
- .resolveOperator(operand, staticType, methodName, operand);
- node.staticElement = result.function;
+ .resolve(operand, staticType, methodName, operand);
+ node.staticElement = result.getter;
if (_shouldReportInvalidMember(staticType, result)) {
if (operand is SuperExpression) {
_recordUndefinedToken(
@@ -665,8 +664,8 @@
String methodName = _getPrefixOperator(node);
DartType staticType = _getStaticType(operand, read: true);
var result = _newPropertyResolver()
- .resolveOperator(operand, staticType, methodName, operand);
- node.staticElement = result.function;
+ .resolve(operand, staticType, methodName, operand);
+ node.staticElement = result.getter;
if (_shouldReportInvalidMember(staticType, result)) {
if (operand is SuperExpression) {
_recordUndefinedToken(
@@ -702,12 +701,9 @@
SimpleIdentifier propertyName = node.propertyName;
String memberName = propertyName.name;
ExecutableElement member;
+ var result = _extensionResolver.getOverrideMember(target, memberName);
if (propertyName.inSetterContext()) {
- member = _extensionResolver.getOverrideMember(
- target,
- memberName,
- setter: true,
- );
+ member = result.setter;
if (member == null) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER,
@@ -715,8 +711,7 @@
[memberName, element.name]);
}
if (propertyName.inGetterContext()) {
- PropertyAccessorElement getter =
- _extensionResolver.getOverrideMember(target, memberName);
+ PropertyAccessorElement getter = result.getter;
if (getter == null) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -726,7 +721,7 @@
propertyName.auxiliaryElements = AuxiliaryElements(getter, null);
}
} else if (propertyName.inGetterContext()) {
- member = _extensionResolver.getOverrideMember(target, memberName);
+ member = result.getter;
if (member == null) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -867,7 +862,7 @@
var propertyResolver = _newPropertyResolver();
propertyResolver.resolve(null, enclosingType, node.name, node);
node.auxiliaryElements = AuxiliaryElements(
- propertyResolver.getterResult.getter,
+ propertyResolver.result.getter,
null,
);
}
@@ -979,37 +974,57 @@
* the target of the expression. The [methodName] is the name of the operator
* associated with the context of using of the given index expression.
*/
- bool _checkForUndefinedIndexOperator(
+ void _checkForUndefinedIndexOperator(
IndexExpression expression,
Expression target,
String methodName,
ResolutionResult result,
+ ExecutableElement element,
DartType staticType) {
- if (_shouldReportInvalidMember(staticType, result)) {
- Token leftBracket = expression.leftBracket;
- Token rightBracket = expression.rightBracket;
- ErrorCode errorCode;
- var errorArguments = [methodName, staticType.displayName];
- if (target is SuperExpression) {
- errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR;
- } else if (staticType != null && staticType.isVoid) {
- errorCode = StaticWarningCode.USE_OF_VOID_RESULT;
- errorArguments = [];
- } else {
- errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR;
- }
- if (leftBracket == null || rightBracket == null) {
- _recordUndefinedNode(
- staticType.element, errorCode, expression, errorArguments);
- } else {
- int offset = leftBracket.offset;
- int length = rightBracket.offset - offset + 1;
- _recordUndefinedOffset(
- staticType.element, errorCode, offset, length, errorArguments);
- }
- return true;
+ if (result.isAmbiguous) {
+ return;
}
- return false;
+ if (element != null) {
+ return;
+ }
+ if (target is! ExtensionOverride) {
+ if (staticType == null || staticType.isDynamic) {
+ return;
+ }
+ }
+
+ var leftBracket = expression.leftBracket;
+ var rightBracket = expression.rightBracket;
+ var offset = leftBracket.offset;
+ var length = rightBracket.end - offset;
+ if (target is ExtensionOverride) {
+ _resolver.errorReporter.reportErrorForOffset(
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR,
+ offset,
+ length,
+ [methodName, target.staticElement.name],
+ );
+ } else if (target is SuperExpression) {
+ _resolver.errorReporter.reportErrorForOffset(
+ StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+ offset,
+ length,
+ [methodName, staticType.displayName],
+ );
+ } else if (staticType.isVoid) {
+ _resolver.errorReporter.reportErrorForOffset(
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ offset,
+ length,
+ );
+ } else {
+ _resolver.errorReporter.reportErrorForOffset(
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ offset,
+ length,
+ [methodName, staticType.displayName],
+ );
+ }
}
/**
@@ -1100,7 +1115,7 @@
var propertyResolver = _newPropertyResolver();
propertyResolver.resolve(null, invokeType,
FunctionElement.CALL_METHOD_NAME, invocation.function);
- MethodElement callMethod = propertyResolver.getterResult.function;
+ ExecutableElement callMethod = propertyResolver.result.getter;
invocation.staticElement = callMethod;
parameterizableType = callMethod?.type;
parameters = (parameterizableType as FunctionType)?.typeFormals;
@@ -1227,20 +1242,6 @@
}
/**
- * Record that the given [offset]/[length] is undefined, causing an error to
- * be reported if appropriate. The [declaringElement] is the element inside
- * which no declaration was found. If this element is a proxy, no error will
- * be reported. If null, then an error will always be reported. The
- * [errorCode] is the error code to report. The [arguments] are arguments to
- * the error message.
- */
- void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode,
- int offset, int length, List<Object> arguments) {
- _resolver.errorReporter
- .reportErrorForOffset(errorCode, offset, length, arguments);
- }
-
- /**
* Record that the given [token] is undefined, causing an error to be reported
* if appropriate. The [declaringElement] is the element inside which no
* declaration was found. If this element is a proxy, no error will be
@@ -1253,6 +1254,44 @@
_resolver.errorReporter.reportErrorForToken(errorCode, token, arguments);
}
+ /// Resolve the [constructorName] to the constructor in the class [element].
+ /// Perform inference using [argumentList].
+ ConstructorElement _resolveAnnotationConstructor(
+ ClassElement element,
+ String constructorName,
+ ArgumentList argumentList,
+ ) {
+ var constructor = constructorName != null
+ ? element.getNamedConstructor(constructorName)
+ : element.unnamedConstructor;
+ if (constructor == null) {
+ return null;
+ }
+ if (!constructor.isAccessibleIn(_definingLibrary)) {
+ return null;
+ }
+
+ var typeParameters = element.typeParameters;
+ if (typeParameters.isEmpty) {
+ return constructor;
+ }
+
+ var typeArgs = _resolver.typeSystem.inferGenericFunctionOrType(
+ typeParameters: typeParameters,
+ parameters: constructor.parameters,
+ declaredReturnType: null,
+ argumentTypes: argumentList.arguments.map((a) => a.staticType).toList(),
+ contextReturnType: null,
+ isConst: true,
+ errorReporter: _resolver.errorReporter,
+ errorNode: argumentList,
+ );
+ return ExecutableMember.from2(
+ constructor,
+ Substitution.fromPairs(typeParameters, typeArgs),
+ );
+ }
+
void _resolveAnnotationConstructorInvocationArguments(
Annotation annotation, ConstructorElement constructor) {
ArgumentList argumentList = annotation.arguments;
@@ -1299,7 +1338,11 @@
}
// Class(args)
if (element1 is ClassElement) {
- constructor = element1.type.lookUpConstructor(null, _definingLibrary);
+ constructor = _resolveAnnotationConstructor(
+ element1,
+ null,
+ annotation.arguments,
+ );
} else if (element1 == null) {
undefined = true;
}
@@ -1327,8 +1370,11 @@
}
// Class.constructor(args)
if (element1 is ClassElement) {
- constructor =
- element1.type.lookUpConstructor(nameNode2.name, _definingLibrary);
+ constructor = _resolveAnnotationConstructor(
+ element1,
+ nameNode2.name,
+ annotation.arguments,
+ );
nameNode2.staticElement = constructor;
}
if (element1 == null && element2 == null) {
@@ -1353,7 +1399,11 @@
return;
}
// prefix.Class.constructor(args)
- constructor = element2.type.lookUpConstructor(name3, _definingLibrary);
+ constructor = _resolveAnnotationConstructor(
+ element2,
+ name3,
+ annotation.arguments,
+ );
nameNode3.staticElement = constructor;
} else if (element2 == null) {
undefined = true;
@@ -1437,7 +1487,7 @@
MethodElement member = element.getMethod(methodName);
if (member == null) {
_resolver.errorReporter.reportErrorForToken(
- CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD,
+ CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR,
node.operator,
[methodName, element.name]);
}
@@ -1446,10 +1496,10 @@
}
DartType leftType = _getStaticType(leftOperand);
ResolutionResult result = _newPropertyResolver()
- .resolveOperator(leftOperand, leftType, methodName, node);
+ .resolve(leftOperand, leftType, methodName, node);
- node.staticElement = result.function;
- node.staticInvokeType = result.function?.type;
+ node.staticElement = result.getter;
+ node.staticInvokeType = result.getter?.type;
if (_shouldReportInvalidMember(leftType, result)) {
if (leftOperand is SuperExpression) {
_recordUndefinedToken(
@@ -1722,15 +1772,19 @@
return;
}
- var propertyResolver = _newPropertyResolver();
- propertyResolver.resolve(
- target, staticType, propertyName.name, propertyName);
+ var result = _newPropertyResolver()
+ .resolve(target, staticType, propertyName.name, propertyName);
if (propertyName.inGetterContext()) {
- var getterResult = propertyResolver.getterResult;
- if (getterResult.isSingle) {
- propertyName.staticElement = getterResult.getter;
- } else if (getterResult.isNone) {
+ var shouldReportUndefinedGetter = false;
+ if (result.isSingle) {
+ var getter = result.getter;
+ if (getter != null) {
+ propertyName.staticElement = getter;
+ } else {
+ shouldReportUndefinedGetter = true;
+ }
+ } else if (result.isNone) {
if (staticType is FunctionType &&
propertyName.name == FunctionElement.CALL_METHOD_NAME) {
// Referencing `.call` on a `Function` type is OK.
@@ -1739,31 +1793,34 @@
propertyName.name == FunctionElement.CALL_METHOD_NAME) {
// Referencing `.call` on a `Function` type is OK.
} else {
- _resolver.errorReporter.reportErrorForNode(
- StaticTypeWarningCode.UNDEFINED_GETTER,
- propertyName,
- [propertyName.name, staticType.displayName],
- );
+ shouldReportUndefinedGetter = true;
}
}
+ if (shouldReportUndefinedGetter) {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_GETTER,
+ propertyName,
+ [propertyName.name, staticType.displayName],
+ );
+ }
}
if (propertyName.inSetterContext()) {
- var setterResult = propertyResolver.setterResult;
- if (setterResult.isSingle) {
- propertyName.staticElement = setterResult.setter;
- } else if (setterResult.isNone) {
- var getter = propertyResolver.getterResult.getter;
- if (getter != null) {
+ if (result.isSingle) {
+ var setter = result.setter;
+ if (setter != null) {
+ propertyName.staticElement = setter;
+ } else {
+ var getter = result.getter;
propertyName.staticElement = getter;
// A more specific error will be reported in ErrorVerifier.
- } else {
- _resolver.errorReporter.reportErrorForNode(
- StaticTypeWarningCode.UNDEFINED_SETTER,
- propertyName,
- [propertyName.name, staticType.displayName],
- );
}
+ } else if (result.isNone) {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SETTER,
+ propertyName,
+ [propertyName.name, staticType.displayName],
+ );
}
}
}
@@ -1790,7 +1847,7 @@
var propertyResolver = _newPropertyResolver();
propertyResolver.resolve(
null, enclosingClass.thisType, identifier.name, identifier);
- setter = propertyResolver.setterResult.setter;
+ setter = propertyResolver.result.setter;
}
}
if (setter != null) {
@@ -1830,9 +1887,9 @@
null, enclosingType, identifier.name, identifier);
if (identifier.inSetterContext() ||
identifier.parent is CommentReference) {
- element = propertyResolver.setterResult.setter;
+ element = propertyResolver.result.setter;
}
- element ??= propertyResolver.getterResult.getter;
+ element ??= propertyResolver.result.getter;
}
}
return element;
@@ -1994,8 +2051,7 @@
final LibraryElement _definingLibrary;
final ExtensionMemberResolver _extensionResolver;
- ResolutionResult getterResult = ResolutionResult.none;
- ResolutionResult setterResult = ResolutionResult.none;
+ ResolutionResult result = ResolutionResult.none;
_PropertyResolver(
this._typeProvider,
@@ -2005,13 +2061,11 @@
);
/// Look up the getter and the setter with the given [name] in the [type].
- /// Set results into [getterResult] or [setterResult] correspondingly.
- /// Methods are considered getters for this purpose.
///
/// The [target] is optional, and used to identify `super`.
///
/// The [errorNode] is used to report the ambiguous extension issue.
- void resolve(
+ ResolutionResult resolve(
Expression target,
DartType type,
String name,
@@ -2019,21 +2073,28 @@
) {
type = _resolveTypeParameter(type);
- PropertyAccessorElement typeGetter;
- PropertyAccessorElement typeSetter;
- ExecutableElement typeMethod;
+ ExecutableElement typeGetter;
+ ExecutableElement typeSetter;
void lookupIn(InterfaceType type) {
var isSuper = target is SuperExpression;
- typeGetter = type.lookUpInheritedGetter(name,
- library: _definingLibrary, thisType: !isSuper);
+ if (name == '[]') {
+ typeGetter = type.lookUpInheritedMethod('[]',
+ library: _definingLibrary, thisType: !isSuper);
- typeSetter = type.lookUpInheritedSetter(name,
- library: _definingLibrary, thisType: !isSuper);
+ typeSetter = type.lookUpInheritedMethod('[]=',
+ library: _definingLibrary, thisType: !isSuper);
+ } else {
+ typeGetter = type.lookUpInheritedGetter(name,
+ library: _definingLibrary, thisType: !isSuper);
- typeMethod = type.lookUpInheritedMethod(name,
- library: _definingLibrary, thisType: !isSuper);
+ typeGetter ??= type.lookUpInheritedMethod(name,
+ library: _definingLibrary, thisType: !isSuper);
+
+ typeSetter = type.lookUpInheritedSetter(name,
+ library: _definingLibrary, thisType: !isSuper);
+ }
}
if (type is InterfaceType) {
@@ -2041,38 +2102,18 @@
} else if (type is FunctionType) {
lookupIn(_typeProvider.functionType);
} else {
- return;
+ return ResolutionResult.none;
}
- if (typeGetter != null) {
- getterResult = ResolutionResult(property: typeGetter.variable);
- } else if (typeMethod != null) {
- getterResult = ResolutionResult(function: typeMethod);
- }
- if (typeSetter != null) {
- setterResult = ResolutionResult(property: typeSetter.variable);
+ if (typeGetter != null || typeSetter != null) {
+ result = ResolutionResult(getter: typeGetter, setter: typeSetter);
}
- if (getterResult.isNone && setterResult.isNone) {
- var result = _extensionResolver.findExtension(type, name, errorNode);
- if (result.isSingle) {
- if (result.getter != null) {
- getterResult = result;
- }
- if (result.setter != null) {
- setterResult = result;
- }
- } else if (result.isAmbiguous) {
- getterResult = ResolutionResult.ambiguous;
- setterResult = ResolutionResult.ambiguous;
- }
+ if (result.isNone) {
+ result = _extensionResolver.findExtension(type, name, errorNode);
}
- }
- ResolutionResult resolveOperator(
- Expression target, DartType type, String name, Expression nameNode) {
- resolve(target, type, name, nameNode);
- return getterResult;
+ return result;
}
/// If the given [type] is a type parameter, replace it with its bound.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 2f1a57f..66c7f6c 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -272,6 +272,7 @@
}
}
}
+ _checkStrictInferenceInParameters(node.parameters);
super.visitConstructorDeclaration(node);
}
@@ -316,6 +317,7 @@
if (node.parent is CompilationUnit) {
_checkStrictInferenceReturnType(node.returnType, node, node.name.name);
}
+ _checkStrictInferenceInParameters(node.functionExpression.parameters);
super.visitFunctionDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
@@ -334,6 +336,10 @@
if (node.parent is! FunctionDeclaration) {
_checkForMissingReturn(null, node.body, node.declaredElement, node);
}
+ DartType functionType = InferenceContext.getContext(node);
+ if (functionType is! FunctionType) {
+ _checkStrictInferenceInParameters(node.parameters);
+ }
super.visitFunctionExpression(node);
}
@@ -341,6 +347,7 @@
void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
_checkStrictInferenceReturnType(
node.returnType, node, node.identifier.name);
+ _checkStrictInferenceInParameters(node.parameters);
super.visitFunctionTypedFormalParameter(node);
}
@@ -386,6 +393,7 @@
_checkForMissingReturn(node.returnType, node.body, element, node);
_checkForUnnecessaryNoSuchMethod(node);
_checkStrictInferenceReturnType(node.returnType, node, node.name.name);
+ _checkStrictInferenceInParameters(node.parameters);
super.visitMethodDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
@@ -1136,7 +1144,35 @@
}
}
- /// In "strict-inference" mode, check that [returnNode]'s return type is specified.
+ /// In "strict-inference" mode, check that each of the [parameters]' type is
+ /// specified.
+ _checkStrictInferenceInParameters(FormalParameterList parameters) {
+ void checkParameterTypeIsKnown(SimpleFormalParameter parameter) {
+ if (parameter.type == null) {
+ ParameterElement element = parameter.declaredElement;
+ _errorReporter.reportTypeErrorForNode(
+ HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER,
+ parameter,
+ [element.displayName],
+ );
+ }
+ }
+
+ if (_strictInference && parameters != null) {
+ for (FormalParameter parameter in parameters.parameters) {
+ if (parameter is SimpleFormalParameter) {
+ checkParameterTypeIsKnown(parameter);
+ } else if (parameter is DefaultFormalParameter) {
+ if (parameter.parameter is SimpleFormalParameter) {
+ checkParameterTypeIsKnown(parameter.parameter);
+ }
+ }
+ }
+ }
+ }
+
+ /// In "strict-inference" mode, check that [returnNode]'s return type is
+ /// specified.
void _checkStrictInferenceReturnType(
AstNode returnType, AstNode reportNode, String displayName) {
if (!_strictInference) {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 91b6336..1263674 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -117,8 +117,7 @@
/**
* Given a formal parameter list and a function type use the function type
* to infer types for any of the parameters which have implicit (missing)
- * types. Only infers types in strong mode. Returns true if inference
- * has occurred.
+ * types. Returns true if inference has occurred.
*/
bool inferFormalParameterList(
FormalParameterList node, DartType functionType) {
@@ -525,34 +524,6 @@
_resolver.extensionResolver.resolveOverride(node);
}
- /// No inference is performed here; just static checking for the
- /// "strict-inference" static analysis mode.
- @override
- void visitFormalParameterList(FormalParameterList node) {
- void checkParameterTypeIsKnown(SimpleFormalParameter parameter) {
- ParameterElement element = parameter.declaredElement;
- if (parameter.type == null) {
- _resolver.errorReporter.reportTypeErrorForNode(
- HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER,
- parameter,
- [element.displayName],
- );
- }
- }
-
- if (_strictInference) {
- for (FormalParameter parameter in node.parameters) {
- if (parameter is SimpleFormalParameter) {
- checkParameterTypeIsKnown(parameter);
- } else if (parameter is DefaultFormalParameter) {
- if (parameter.parameter is SimpleFormalParameter) {
- checkParameterTypeIsKnown(parameter.parameter);
- }
- }
- }
- }
- }
-
@override
void visitFunctionDeclaration(FunctionDeclaration node) {
FunctionExpression function = node.functionExpression;
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 75ab704..7ed3c90 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,9 +2,6 @@
// 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:collection';
-
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/generated/java_core.dart';
/**
@@ -80,261 +77,3 @@
}
}
}
-
-/**
- * The interface `MapIterator` defines the behavior of objects that iterate over the entries
- * in a map.
- *
- * This interface defines the concept of a current entry and provides methods to access the key and
- * value in the current entry. When an iterator is first created it will be positioned before the
- * first entry and there is no current entry until [moveNext] is invoked. When all of the
- * entries have been accessed there will also be no current entry.
- *
- * There is no guarantee made about the order in which the entries are accessible.
- */
-abstract class MapIterator<K, V> {
- /**
- * Return the key associated with the current element.
- *
- * @return the key associated with the current element
- * @throws NoSuchElementException if there is no current element
- */
- K get key;
-
- /**
- * Return the value associated with the current element.
- *
- * @return the value associated with the current element
- * @throws NoSuchElementException if there is no current element
- */
- V get value;
-
- /**
- * Set the value associated with the current element to the given value.
- *
- * @param newValue the new value to be associated with the current element
- * @throws NoSuchElementException if there is no current element
- */
- void set value(V newValue);
-
- /**
- * Advance to the next entry in the map. Return `true` if there is a current element that
- * can be accessed after this method returns. It is safe to invoke this method even if the
- * previous invocation returned `false`.
- *
- * @return `true` if there is a current element that can be accessed
- */
- bool moveNext();
-}
-
-/**
- * Instances of the class `MultipleMapIterator` implement an iterator that can be used to
- * sequentially access the entries in multiple maps.
- */
-class MultipleMapIterator<K, V> implements MapIterator<K, V> {
- /**
- * The iterators used to access the entries.
- */
- List<MapIterator<K, V>> _iterators;
-
- /**
- * The index of the iterator currently being used to access the entries.
- */
- int _iteratorIndex = -1;
-
- /**
- * The current iterator, or `null` if there is no current iterator.
- */
- MapIterator<K, V> _currentIterator;
-
- /**
- * Initialize a newly created iterator to return the entries from the given maps.
- *
- * @param maps the maps containing the entries to be iterated
- */
- MultipleMapIterator(List<Map<K, V>> maps) {
- int count = maps.length;
- _iterators = new List<MapIterator<K, V>>(count);
- for (int i = 0; i < count; i++) {
- _iterators[i] = new SingleMapIterator<K, V>(maps[i]);
- }
- }
-
- @override
- K get key {
- if (_currentIterator == null) {
- throw new StateError('No element');
- }
- return _currentIterator.key;
- }
-
- @override
- V get value {
- if (_currentIterator == null) {
- throw new StateError('No element');
- }
- return _currentIterator.value;
- }
-
- @override
- void set value(V newValue) {
- if (_currentIterator == null) {
- throw new StateError('No element');
- }
- _currentIterator.value = newValue;
- }
-
- @override
- bool moveNext() {
- if (_iteratorIndex < 0) {
- if (_iterators.isEmpty) {
- _currentIterator = null;
- return false;
- }
- if (_advanceToNextIterator()) {
- return true;
- } else {
- _currentIterator = null;
- return false;
- }
- }
- if (_currentIterator.moveNext()) {
- return true;
- } else if (_advanceToNextIterator()) {
- return true;
- } else {
- _currentIterator = null;
- return false;
- }
- }
-
- /**
- * Under the assumption that there are no more entries that can be returned using the current
- * iterator, advance to the next iterator that has entries.
- *
- * @return `true` if there is a current iterator that has entries
- */
- bool _advanceToNextIterator() {
- _iteratorIndex++;
- while (_iteratorIndex < _iterators.length) {
- MapIterator<K, V> iterator = _iterators[_iteratorIndex];
- if (iterator.moveNext()) {
- _currentIterator = iterator;
- return true;
- }
- _iteratorIndex++;
- }
- return false;
- }
-}
-
-/**
- * Instances of the class `SingleMapIterator` implement an iterator that can be used to access
- * the entries in a single map.
- */
-class SingleMapIterator<K, V> implements MapIterator<K, V> {
- /**
- * The [Map] containing the entries to be iterated over.
- */
- final Map<K, V> _map;
-
- /**
- * The iterator used to access the entries.
- */
- Iterator<K> _keyIterator;
-
- /**
- * The current key, or `null` if there is no current key.
- */
- K _currentKey;
-
- /**
- * The current value.
- */
- V _currentValue;
-
- /**
- * Initialize a newly created iterator to return the entries from the given map.
- *
- * @param map the map containing the entries to be iterated over
- */
- SingleMapIterator(this._map) {
- this._keyIterator = _map.keys.iterator;
- }
-
- @override
- K get key {
- if (_currentKey == null) {
- throw new StateError('No element');
- }
- return _currentKey;
- }
-
- @override
- V get value {
- if (_currentKey == null) {
- throw new StateError('No element');
- }
- if (_currentValue == null) {
- _currentValue = _map[_currentKey];
- }
- return _currentValue;
- }
-
- @override
- void set value(V newValue) {
- if (_currentKey == null) {
- throw new StateError('No element');
- }
- _currentValue = newValue;
- _map[_currentKey] = newValue;
- }
-
- @override
- bool moveNext() {
- if (_keyIterator.moveNext()) {
- _currentKey = _keyIterator.current;
- _currentValue = null;
- return true;
- } else {
- _currentKey = null;
- return false;
- }
- }
-
- /**
- * Returns a new [SingleMapIterator] instance for the given [Map].
- */
- static SingleMapIterator forMap(Map map) => new SingleMapIterator(map);
-}
-
-/**
- * Instances of the class `TokenMap` map one set of tokens to another set of tokens.
- */
-class TokenMap {
- /**
- * A table mapping tokens to tokens. This should be replaced by a more performant implementation.
- * One possibility is a pair of parallel arrays, with keys being sorted by their offset and a
- * cursor indicating where to start searching.
- */
- Map<Token, Token> _map = new HashMap<Token, Token>();
-
- /**
- * Return the token that is mapped to the given token, or `null` if there is no token
- * corresponding to the given token.
- *
- * @param key the token being mapped to another token
- * @return the token that is mapped to the given token
- */
- Token get(Token key) => _map[key];
-
- /**
- * Map the key to the value.
- *
- * @param key the token being mapped to the value
- * @param value the token to which the key will be mapped
- */
- void put(Token key, Token value) {
- _map[key] = value;
- }
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 25e5b7f..bb96dd0 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -289,7 +289,10 @@
var libraryContext = elementFactory.libraryMap[uriStr];
if (libraryContext == null) {
- throw ArgumentError('Missing library: $uriStr');
+ throw ArgumentError(
+ 'Missing library: $uriStr\n'
+ 'Available libraries: ${elementFactory.libraryMap.keys.toList()}',
+ );
}
var libraryNode = libraryContext.node;
var hasName = libraryNode.name.isNotEmpty;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index ddf6cf8..3a196922 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -900,11 +900,18 @@
// The member may be from a superclass, so we need to ensure the type
// parameters are properly substituted.
- var classType = targetType.element.type;
- var classLowerBound = classType.instantiate(new List.filled(
- classType.typeParameters.length, BottomTypeImpl.instance));
+ var classElement = targetType.element;
+ var classLowerBound = classElement.instantiate(
+ typeArguments: List.filled(
+ classElement.typeParameters.length,
+ BottomTypeImpl.instance,
+ ),
+ nullabilitySuffix: NullabilitySuffix.none,
+ );
var memberLowerBound = inheritance.getMember(
- classLowerBound, Name(element.librarySource.uri, element.name));
+ classLowerBound,
+ Name(element.librarySource.uri, element.name),
+ );
if (memberLowerBound == null &&
element.enclosingElement is ExtensionElement) {
return;
@@ -1465,11 +1472,11 @@
// Find all generic interfaces that could be used to call into members of
// this class. This will help us identify which parameters need checks
// for soundness.
- var allCovariant = _findAllGenericInterfaces(element.type);
+ var allCovariant = _findAllGenericInterfaces(element);
if (allCovariant.isEmpty) return;
var seenConcreteMembers = new HashSet<String>();
- var members = _getConcreteMembers(element.type, seenConcreteMembers);
+ var members = _getConcreteMembers(element.thisType, seenConcreteMembers);
// For members on this class, check them against all generic interfaces.
var checks = _findCovariantChecks(members, allCovariant);
@@ -1646,7 +1653,7 @@
void visitImmediateSuper(InterfaceType type) {
// For members of mixins/supertypes, check them against new interfaces,
// and also record any existing checks they already had.
- var oldCovariant = _findAllGenericInterfaces(type);
+ var oldCovariant = _findAllGenericInterfaces(type.element);
var newCovariant = allCovariant.difference(oldCovariant);
if (newCovariant.isEmpty) return;
@@ -1688,32 +1695,40 @@
return x == y;
}
- /// Find all generic interfaces that are implemented by [type], including
- /// [type] itself if it is generic.
+ /// Find all generic interfaces that are implemented by [element], including
+ /// [element] itself if it is generic.
///
/// This represents the complete set of unsafe covariant interfaces that could
- /// be used to call members of [type].
+ /// be used to call members of [element].
///
/// Because we're going to instantiate these to their upper bound, we don't
/// have to track type parameters.
- static Set<ClassElement> _findAllGenericInterfaces(InterfaceType type) {
- var visited = new HashSet<ClassElement>();
- var genericSupertypes = new Set<ClassElement>();
+ static Set<ClassElement> _findAllGenericInterfaces(ClassElement element) {
+ var visited = <ClassElement>{};
+ var genericSupertypes = <ClassElement>{};
- void visitTypeAndSupertypes(InterfaceType type) {
- var element = type.element;
+ void visitClassAndSupertypes(ClassElement element) {
if (visited.add(element)) {
if (element.typeParameters.isNotEmpty) {
genericSupertypes.add(element);
}
+
var supertype = element.supertype;
- if (supertype != null) visitTypeAndSupertypes(supertype);
- element.mixins.forEach(visitTypeAndSupertypes);
- element.interfaces.forEach(visitTypeAndSupertypes);
+ if (supertype != null) {
+ visitClassAndSupertypes(supertype.element);
+ }
+
+ for (var interface in element.mixins) {
+ visitClassAndSupertypes(interface.element);
+ }
+
+ for (var interface in element.interfaces) {
+ visitClassAndSupertypes(interface.element);
+ }
}
}
- visitTypeAndSupertypes(type);
+ visitClassAndSupertypes(element);
return genericSupertypes;
}
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index acef919..7e9a9ed 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -151,6 +151,10 @@
return _node(search, (n) => n is IntegerLiteral);
}
+ Label label(String search) {
+ return _node(search, (n) => n is Label);
+ }
+
LibraryDirective library(String search) {
return _node(search, (n) => n is LibraryDirective);
}
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 176212d..da08116 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -344,6 +344,7 @@
void add(E value) {}
void addAll(Iterable<E> iterable) {}
+ Map<int, E> asMap() {}
void clear() {}
int indexOf(Object element);
E removeLast() {}
@@ -499,7 +500,7 @@
'dart:html',
'$sdkRoot/lib/html/dart2js/html_dart2js.dart',
'''
-library dart.html;
+library dart.dom.html;
import 'dart:async';
class Event {}
@@ -566,6 +567,10 @@
bool autofocus;
}
+class EmbedElement extends HtmlEment {
+ String src;
+}
+
class HeadingElement extends HtmlElement {
factory HeadingElement._() { throw new UnsupportedError("Not supported"); }
factory HeadingElement.h1() => document.createElement("h1");
@@ -592,6 +597,10 @@
String src;
}
+class ImageElement extends HtmlEment {
+ String src;
+}
+
class OptionElement extends HtmlElement {
factory OptionElement({String data: '', String value : '', bool selected: false}) {
}
@@ -600,6 +609,11 @@
}
}
+class ScriptElement extends HtmlElement {
+ String src;
+ String type;
+}
+
class TableSectionElement extends HtmlElement {
List<TableRowElement> get rows => null;
@@ -652,7 +666,7 @@
'dart:html',
'$sdkRoot/lib/html/dartium/html_dartium.dart',
'''
-library dart.html;
+library dart.dom.html;
import 'dart:async';
class Event {}
@@ -719,6 +733,10 @@
bool autofocus;
}
+class EmbedElement extends HtmlEment {
+ String src;
+}
+
class HeadingElement extends HtmlElement {
factory HeadingElement._() { throw new UnsupportedError("Not supported"); }
factory HeadingElement.h1() => document.createElement("h1");
@@ -745,6 +763,10 @@
String src;
}
+class ImageElement extends HtmlEment {
+ String src;
+}
+
class OptionElement extends HtmlElement {
factory OptionElement({String data: '', String value : '', bool selected: false}) {
}
@@ -753,6 +775,11 @@
}
}
+class ScriptElement extends HtmlElement {
+ String src;
+ String type;
+}
+
class TableSectionElement extends HtmlElement {
List<TableRowElement> get rows => null;
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 67ae027..a1a5220 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.38.3
+version: 0.38.4
author: Dart Team <misc@dartlang.org>
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -13,10 +13,10 @@
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.25
+ front_end: 0.1.26
glob: ^1.0.3
html: '>=0.13.4+1 <0.15.0'
- kernel: 0.3.25
+ kernel: 0.3.26
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
@@ -27,5 +27,6 @@
dev_dependencies:
analysis_tool:
path: ../analysis_tool
+ pedantic: ^1.8.0
test: ^1.0.0
test_reflective_loader: ^0.1.8
diff --git a/pkg/analyzer/test/dart/analysis/declared_variables_test.dart b/pkg/analyzer/test/dart/analysis/declared_variables_test.dart
index 2460423..4563f45 100644
--- a/pkg/analyzer/test/dart/analysis/declared_variables_test.dart
+++ b/pkg/analyzer/test/dart/analysis/declared_variables_test.dart
@@ -9,8 +9,6 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../generated/test_support.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DeclaredVariablesTest);
@@ -18,7 +16,7 @@
}
@reflectiveTest
-class DeclaredVariablesTest extends EngineTestCase {
+class DeclaredVariablesTest {
void test_getBool_false() {
TestTypeProvider typeProvider = new TestTypeProvider();
String variableName = "var";
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 163cb6c..61d45e6 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -133,7 +133,7 @@
}
@reflectiveTest
-class ConstructorDeclarationTest extends EngineTestCase {
+class ConstructorDeclarationTest {
void test_firstTokenAfterCommentAndMetadata_all_inverted() {
Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
externalKeyword.offset = 14;
@@ -205,7 +205,7 @@
}
@reflectiveTest
-class FieldFormalParameterTest extends EngineTestCase {
+class FieldFormalParameterTest {
void test_endToken_noParameters() {
FieldFormalParameter parameter =
AstTestFactory.fieldFormalParameter2('field');
@@ -220,7 +220,7 @@
}
@reflectiveTest
-class IndexExpressionTest extends EngineTestCase {
+class IndexExpressionTest {
void test_inGetterContext_assignment_compound_left() {
IndexExpression expression = AstTestFactory.indexExpression(
AstTestFactory.identifier3("a"), AstTestFactory.identifier3("b"));
@@ -343,7 +343,7 @@
}
@reflectiveTest
-class MethodDeclarationTest extends EngineTestCase {
+class MethodDeclarationTest {
void test_firstTokenAfterCommentAndMetadata_external() {
MethodDeclaration declaration =
AstTestFactory.methodDeclaration4(external: true, name: 'm');
@@ -406,7 +406,7 @@
}
@reflectiveTest
-class NodeListTest extends EngineTestCase {
+class NodeListTest {
void test_add() {
AstNode parent = AstTestFactory.argumentList();
AstNode firstNode = AstTestFactory.booleanLiteral(true);
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index 92d475a..fc77013 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -19,6 +19,7 @@
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/generated/testing/node_search.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -222,8 +223,8 @@
void test_metadata_localVariableDeclaration() {
var code = 'f() { @a int x, y; }';
buildElementsForText(code);
- var x = findLocalVariable(code, 'x, ');
- var y = findLocalVariable(code, 'x, ');
+ var x = findLocalVariable('x, ');
+ var y = findLocalVariable('x, ');
checkMetadata(x);
checkMetadata(y);
expect(x.metadata, same(y.metadata));
@@ -232,15 +233,15 @@
void test_metadata_visitDeclaredIdentifier() {
var code = 'f() { for (@a var x in y) {} }';
buildElementsForText(code);
- var x = findLocalVariable(code, 'x in');
+ var x = findLocalVariable('x in');
checkMetadata(x);
}
void test_visitCatchClause() {
var code = 'f() { try {} catch (e, s) {} }';
buildElementsForText(code);
- var e = findLocalVariable(code, 'e, ');
- var s = findLocalVariable(code, 's) {}');
+ var e = findLocalVariable('e, ');
+ var s = findLocalVariable('s) {}');
expect(e, isNotNull);
expect(e.name, 'e');
@@ -263,7 +264,7 @@
void test_visitCatchClause_withType() {
var code = 'f() { try {} on E catch (e) {} }';
buildElementsForText(code);
- var e = findLocalVariable(code, 'e) {}');
+ var e = findLocalVariable('e) {}');
expect(e, isNotNull);
expect(e.name, 'e');
expect(e.hasImplicitType, isFalse);
@@ -292,7 +293,7 @@
void test_visitDeclaredIdentifier_noType() {
var code = 'f() { for (var i in []) {} }';
buildElementsForText(code);
- var variable = findLocalVariable(code, 'i in');
+ var variable = findLocalVariable('i in');
assertHasCodeRange(variable, 11, 5);
expect(variable, isNotNull);
expect(variable.hasImplicitType, isTrue);
@@ -309,7 +310,7 @@
void test_visitDeclaredIdentifier_type() {
var code = 'f() { for (int i in []) {} }';
buildElementsForText(code);
- var variable = findLocalVariable(code, 'i in');
+ var variable = findLocalVariable('i in');
assertHasCodeRange(variable, 11, 5);
expect(variable.hasImplicitType, isFalse);
expect(variable.isConst, isFalse);
@@ -522,7 +523,7 @@
void test_visitLabeledStatement() {
String code = 'f() { l: print(42); }';
buildElementsForText(code);
- LabelElement label = findLabel(code, 'l:');
+ LabelElement label = findLabel('l:');
expect(label, isNotNull);
expect(label.name, 'l');
expect(label.isSynthetic, isFalse);
@@ -548,13 +549,13 @@
expect(parameter, isNotNull);
expect(parameter.name, parameterName);
- var v = findLocalVariable(code, 'v;');
+ var v = findLocalVariable('v;');
expect(v.name, 'v');
- var e = findLocalVariable(code, 'e) {}');
+ var e = findLocalVariable('e) {}');
expect(e.name, 'e');
- LabelElement label = findLabel(code, 'l:');
+ LabelElement label = findLabel('l:');
expect(label, isNotNull);
expect(label.name, labelName);
}
@@ -750,7 +751,7 @@
void test_visitVariableDeclaration_inConstructor() {
var code = 'class C { C() { var v = 1; } }';
buildElementsForText(code);
- var v = findLocalVariable(code, 'v =');
+ var v = findLocalVariable('v =');
assertHasCodeRange(v, 16, 9);
expect(v.hasImplicitType, isTrue);
expect(v.name, 'v');
@@ -1063,11 +1064,12 @@
main.encloseElements(holder.functions);
main.encloseElements(holder.localVariables);
- var f1 = findLocalFunction(code, 'f1() {');
- var f2 = findLocalFunction(code, 'f2() {');
- var v1 = findLocalVariable(code, 'v1;');
- var v2 = findLocalVariable(code, 'v2;');
- var v3 = findLocalVariable(code, 'v3;');
+ findNode = FindNode(code, _compilationUnit);
+ var f1 = findLocalFunction('f1() {');
+ var f2 = findLocalFunction('f2() {');
+ var v1 = findLocalVariable('v1;');
+ var v2 = findLocalVariable('v2;');
+ var v3 = findLocalVariable('v3;');
expect(v1.enclosingElement, main);
{
@@ -1198,7 +1200,7 @@
void test_visitVariableDeclaration_local() {
var code = 'class C { m() { T v = null; } }';
buildElementsForText(code);
- LocalVariableElement element = findIdentifier(code, 'v =').staticElement;
+ LocalVariableElement element = findNode.simple('v =').staticElement;
expect(element.hasImplicitType, isFalse);
expect(element.name, 'v');
expect(element.initializer, isNotNull);
@@ -2607,6 +2609,7 @@
abstract class _BaseTest extends ParserTestCase {
CompilationUnitElement compilationUnitElement;
CompilationUnit _compilationUnit;
+ FindNode findNode;
CompilationUnit get compilationUnit => _compilationUnit;
@@ -2667,20 +2670,16 @@
AstVisitor createElementBuilder(ElementHolder holder);
- SimpleIdentifier findIdentifier(String code, String prefix) {
- return EngineTestCase.findSimpleIdentifier(compilationUnit, code, prefix);
+ LabelElement findLabel(String prefix) {
+ return findNode.simple(prefix).staticElement;
}
- LabelElement findLabel(String code, String prefix) {
- return findIdentifier(code, prefix).staticElement;
+ FunctionElement findLocalFunction(String search) {
+ return findNode.functionDeclaration(search).declaredElement;
}
- FunctionElement findLocalFunction(String code, String prefix) {
- return findIdentifier(code, prefix).staticElement;
- }
-
- LocalVariableElement findLocalVariable(String code, String prefix) {
- return findIdentifier(code, prefix).staticElement;
+ LocalVariableElement findLocalVariable(String search) {
+ return findNode.simple(search).staticElement;
}
void setUp() {
@@ -2702,6 +2701,7 @@
AnalysisEngine.instance.logger = logger;
try {
_compilationUnit = parseCompilationUnit(code);
+ findNode = FindNode(code, _compilationUnit);
compilationUnit.accept(visitor);
} finally {
expect(logger.log, hasLength(0));
diff --git a/pkg/analyzer/test/dart/element/element_test.dart b/pkg/analyzer/test/dart/element/element_test.dart
index bfab82b..9ad4872 100644
--- a/pkg/analyzer/test/dart/element/element_test.dart
+++ b/pkg/analyzer/test/dart/element/element_test.dart
@@ -7,8 +7,6 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../generated/test_support.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ElementKindTest);
@@ -16,7 +14,7 @@
}
@reflectiveTest
-class ElementKindTest extends EngineTestCase {
+class ElementKindTest {
void test_of_nonNull() {
expect(ElementKind.of(ElementFactory.classElement2("A")),
same(ElementKind.CLASS));
diff --git a/pkg/analyzer/test/error/error_reporter_test.dart b/pkg/analyzer/test/error/error_reporter_test.dart
index a796291..1b84665 100644
--- a/pkg/analyzer/test/error/error_reporter_test.dart
+++ b/pkg/analyzer/test/error/error_reporter_test.dart
@@ -28,9 +28,7 @@
}
test_reportErrorForElement_named() async {
- addTestFile('class A {}');
- await resolveTestFile();
-
+ await resolveTestCode('class A {}');
var element = findElement.class_('A');
var reporter = ErrorReporter(listener, element.source);
reporter.reportErrorForElement(
@@ -44,12 +42,10 @@
}
test_reportErrorForElement_unnamed() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async';
import 'dart:math';
''');
- await resolveTestFile();
-
var element = findElement.import('dart:math');
var reporter = ErrorReporter(listener, element.source);
@@ -94,7 +90,7 @@
test_reportTypeErrorForNode_differentNames() async {
newFile('/test/lib/a.dart', content: 'class A {}');
newFile('/test/lib/b.dart', content: 'class B {}');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'package:test/a.dart';
import 'package:test/b.dart';
@@ -102,8 +98,6 @@
x;
}
''');
- await resolveTestFile();
-
var aImport = findElement.importFind('package:test/a.dart');
var bImport = findElement.importFind('package:test/b.dart');
@@ -131,7 +125,7 @@
test_reportTypeErrorForNode_sameName() async {
newFile('/test/lib/a.dart', content: 'class A {}');
newFile('/test/lib/b.dart', content: 'class A {}');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'package:test/a.dart';
import 'package:test/b.dart';
@@ -139,8 +133,6 @@
x;
}
''');
- await resolveTestFile();
-
var aImport = findElement.importFind('package:test/a.dart');
var bImport = findElement.importFind('package:test/b.dart');
@@ -167,7 +159,7 @@
test_reportTypeErrorForNode_sameName_functionType() async {
newFile('/test/lib/a.dart', content: 'class A{}');
newFile('/test/lib/b.dart', content: 'class A{}');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as a;
import 'b.dart' as b;
@@ -178,8 +170,6 @@
x;
}
''');
- await resolveTestFile();
-
var fa = findNode.topLevelVariableDeclaration('fa');
var fb = findNode.topLevelVariableDeclaration('fb');
@@ -199,7 +189,7 @@
test_reportTypeErrorForNode_sameName_nested() async {
newFile('/test/lib/a.dart', content: 'class A{}');
newFile('/test/lib/b.dart', content: 'class A{}');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as a;
import 'b.dart' as b;
@@ -211,8 +201,6 @@
x;
}
''');
- await resolveTestFile();
-
var ba = findNode.topLevelVariableDeclaration('ba');
var bb = findNode.topLevelVariableDeclaration('bb');
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a0153b8..c7b52204 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -134,7 +134,7 @@
}
@reflectiveTest
-class ErrorSeverityTest extends EngineTestCase {
+class ErrorSeverityTest {
test_max_error_error() async {
expect(ErrorSeverity.ERROR.max(ErrorSeverity.ERROR),
same(ErrorSeverity.ERROR));
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 7d8db75..accf42d 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -487,18 +487,15 @@
Future<EvaluationResult> _getExpressionValue(String expressionCode,
{String context: ''}) async {
- var path = convertPath('/test/lib/test.dart');
-
- var file = newFile(path, content: '''
+ await resolveTestCode('''
var x = $expressionCode;
$context
''');
- await resolveTestFile();
-
var expression = findNode.variableDeclaration('x =').initializer;
+ var file = getFile(result.path);
var evaluator = ConstantEvaluator(
file.createSource(result.uri),
result.typeProvider,
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index db29c01..e223c2f 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -6,7 +6,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/declaration_resolver.dart';
@@ -17,7 +16,6 @@
import '../src/dart/resolution/driver_resolution.dart';
import '../util/element_type_matchers.dart';
-import 'test_support.dart';
main() {
defineReflectiveSuite(() {
@@ -54,9 +52,7 @@
Future<void> setupCode(String code) async {
this.code = code;
- addTestFile(code + ' const a = null;');
- await resolveTestFile();
-
+ await resolveTestCode(code + ' const a = null;');
unit = result.unit;
unit2 = _cloneResolveUnit(unit);
}
@@ -103,7 +99,7 @@
}
test_exportDirective_resynthesized() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
@a
export "dart:async";
@@ -113,7 +109,6 @@
const a = null;
const b = null;
''');
- await resolveTestFile();
unit = result.unit;
expect(unit.directives[0].metadata.single.name.name, 'a');
@@ -186,7 +181,7 @@
}
test_importDirective_resynthesized() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
@a
import "dart:async";
@@ -196,7 +191,6 @@
const a = null;
const b = null;
''');
- await resolveTestFile();
unit = result.unit;
expect(unit.directives[0].metadata.single.name.name, 'a');
@@ -223,8 +217,7 @@
}
test_libraryDirective_resynthesized() async {
- addTestFile('@a library L; const a = null;');
- await resolveTestFile();
+ await resolveTestCode('@a library L; const a = null;');
unit = result.unit;
expect(unit.directives.single.metadata.single.name.name, 'a');
@@ -245,9 +238,8 @@
await setupCode('f() { @a g() {} }');
// Note: metadata on local function declarations is ignored by the
// analyzer. TODO(paulberry): is this a bug?
- FunctionDeclaration node = EngineTestCase.findNode(
- unit, code, 'g', (AstNode n) => n is FunctionDeclaration);
- NodeList<Annotation> metadata = (node as FunctionDeclarationImpl).metadata;
+ var node = FindNode(code, unit).functionDeclaration('g()');
+ NodeList<Annotation> metadata = node.metadata;
if (Parser.useFasta) {
expect(metadata, hasLength(1));
} else {
@@ -285,7 +277,7 @@
newFile('/test/lib/part_a.dart', content: 'part of L;');
newFile('/test/lib/part_b.dart', content: 'part of L;');
- addTestFile(r'''
+ await resolveTestCode(r'''
library L;
@a
@@ -297,7 +289,6 @@
const a = null;
const b = null;
''');
- await resolveTestFile();
unit = result.unit;
expect(unit.directives[1].metadata.single.name.name, 'a');
@@ -354,8 +345,7 @@
}
NodeList<Annotation> _findMetadata(CompilationUnit unit, String search) {
- AstNode node =
- EngineTestCase.findNode(unit, code, search, (AstNode _) => true);
+ var node = FindNode(code, unit).any(search);
while (node != null) {
if (node is AnnotatedNode && node.metadata.isNotEmpty) {
return node.metadata;
@@ -372,7 +362,7 @@
@reflectiveTest
class DeclarationResolverTest extends DriverResolutionTest {
test_closure_inside_catch_block() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
try {
} catch (e) {
@@ -380,14 +370,13 @@
}
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_closure_inside_labeled_statement() async {
- addTestFile('''
+ await resolveTestCode('''
f(b) {
foo: while (true) {
if (b) {
@@ -397,14 +386,13 @@
}
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_closure_inside_switch_case() async {
- addTestFile('''
+ await resolveTestCode('''
void f(k, m) {
switch (k) {
case 0:
@@ -413,14 +401,13 @@
}
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_closure_inside_switch_default() async {
- addTestFile('''
+ await resolveTestCode('''
void f(k, m) {
switch (k) {
default:
@@ -429,18 +416,15 @@
}
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_functionDeclaration_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int get zzz => 42;
''');
- await resolveTestFile();
-
var getterElement = findElement.topGet('zzz');
expect(getterElement.isGetter, isTrue);
@@ -451,11 +435,9 @@
}
test_functionDeclaration_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void set zzz(_) {}
''');
- await resolveTestFile();
-
var setterElement = findElement.topSet('zzz');
expect(setterElement.isSetter, isTrue);
@@ -466,92 +448,83 @@
}
test_genericFunction_asFunctionReturnType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
Function(int, String) f() => null;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asGenericFunctionReturnType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef F<T> = int Function(T t, S s) Function<S>(int);
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asMethodReturnType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
Function(int, String) m() => null;
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asParameterReturnType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
f(Function(int, String) p) => null;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asTopLevelVariableType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int Function(int, String) v;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asTypeArgument() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
List<Function(int)> v;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asTypeArgument_lessNodes() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
Map<Function<int>> v;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asTypeArgument_moreNodes() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
List<Function<int>, Function<String>> v;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_genericFunction_asTypeArgument_noNodes() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
List v;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
@@ -561,34 +534,29 @@
String code = r'''
var v = <Function(int)>[];
''';
- addTestFile(code);
- await resolveTestFile();
-
+ await resolveTestCode(code);
var newUnit = _cloneResolveUnit(result.unit);
var initializer = FindNode(result.content, newUnit).listLiteral('>[]');
expect(initializer.typeArguments.arguments[0].type, isNotNull);
}
test_genericFunction_invalid_missingParameterName() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef F = Function({int});
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_invalid_functionDeclaration_getter_inFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
var v = (() {
main() {
int get zzz => 42;
}
});
''');
- await resolveTestFile();
-
// re-resolve
var unit2 = _cloneResolveUnit(result.unit);
var getterName = FindNode(result.content, unit2).simple('zzz =>');
@@ -598,15 +566,13 @@
}
test_invalid_functionDeclaration_setter_inFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
var v = (() {
main() {
set zzz(x) {}
}
});
''');
- await resolveTestFile();
-
// re-resolve
var unit2 = _cloneResolveUnit(result.unit);
var setterName = FindNode(result.content, unit2).simple('zzz(x)');
@@ -616,96 +582,86 @@
}
test_visitExportDirective_notExistingSource() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
export 'foo.dart';
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitExportDirective_unresolvedUri() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
export 'package:foo/bar.dart';
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitFunctionExpression() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main(List<String> items) {
items.forEach((item) {});
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitGenericTypeAlias_0() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef F<T> = Function<S>(List<S> list, Function<A>(A), T);
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitGenericTypeAlias_1() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef F = Function({int});
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitGenericTypeAlias_2() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef F = int;
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitImportDirective_notExistingSource() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'foo.dart';
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitImportDirective_unresolvedUri() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'package:foo/bar.dart';
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitMethodDeclaration_getter_duplicate() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int get zzz => 1;
String get zzz => null;
}
''');
- await resolveTestFile();
-
var firstElement = findNode.simple('zzz => 1').staticElement;
var secondElement = findNode.simple('zzz => null').staticElement;
expect(firstElement, isNot(same(secondElement)));
@@ -720,15 +676,13 @@
}
test_visitMethodDeclaration_getterSetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int _field = 0;
int get field => _field;
void set field(value) {_field = value;}
}
''');
- await resolveTestFile();
-
var getterElement = findElement.getter('field');
var setterElement = findElement.setter('field');
@@ -742,14 +696,12 @@
}
test_visitMethodDeclaration_method_duplicate() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void zzz(x) {}
void zzz(y) {}
}
''');
- await resolveTestFile();
-
MethodElement firstElement = findNode.simple('zzz(x)').staticElement;
MethodElement secondElement = findNode.simple('zzz(y)').staticElement;
expect(firstElement, isNot(same(secondElement)));
@@ -765,14 +717,12 @@
test_visitMethodDeclaration_setter_duplicate() async {
// https://github.com/dart-lang/sdk/issues/25601
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
set zzz(x) {}
set zzz(y) {}
}
''');
- await resolveTestFile();
-
PropertyAccessorElement firstElement =
findNode.simple('zzz(x)').staticElement;
PropertyAccessorElement secondElement =
@@ -789,23 +739,21 @@
}
test_visitMethodDeclaration_unaryMinus() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C operator -() => null;
C operator -(C other) => null;
}
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
}
test_visitPartDirective_notExistingSource() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
part 'foo.bar';
''');
- await resolveTestFile();
// re-resolve
_cloneResolveUnit(result.unit);
// no other validations than built into DeclarationResolver
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index a03c601..6a4c187 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -275,13 +275,11 @@
String annotationText,
validator(SimpleIdentifier name1, SimpleIdentifier name2,
SimpleIdentifier name3, Element annotationElement)) async {
- addTestFile('''
+ await resolveTestCode('''
import 'a.dart' $annotationPrefix;
$annotationText
class C {}
''');
- await resolveTestFile();
-
var clazz = findNode.classDeclaration('C');
Annotation annotation = clazz.metadata.single;
Identifier name = annotation.name;
@@ -298,8 +296,7 @@
}
@reflectiveTest
-class ElementResolverTest extends EngineTestCase
- with ResourceProviderMixin, ElementsTypesMixin {
+class ElementResolverTest with ResourceProviderMixin, ElementsTypesMixin {
/**
* The error listener to which errors will be reported.
*/
@@ -376,9 +373,7 @@
_listener.assertNoErrors();
}
- @override
void setUp() {
- super.setUp();
_listener = new GatheringErrorListener();
_createResolver();
}
@@ -427,7 +422,7 @@
leftHandSide, TokenType.PLUS_EQ, AstTestFactory.integer(1));
_resolveNode(assignment);
expect(
- assignment.staticElement, same(getMethod(_typeProvider.numType, "+")));
+ assignment.staticElement, same(_typeProvider.numType.getMethod('+')));
_listener.assertNoErrors();
}
@@ -488,7 +483,7 @@
BinaryExpression expression = AstTestFactory.binaryExpression(
left, TokenType.PLUS, AstTestFactory.identifier3("j"));
_resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
+ expect(expression.staticElement, numType.getMethod('+'));
_listener.assertNoErrors();
}
@@ -793,7 +788,7 @@
AstTestFactory.methodInvocation(left, methodName);
_resolveNode(invocation);
expect(invocation.methodName.staticElement,
- same(getMethod(numType, methodName)));
+ same(numType.getMethod(methodName)));
_listener.assertNoErrors();
}
@@ -804,7 +799,7 @@
PostfixExpression expression =
AstTestFactory.postfixExpression(operand, TokenType.PLUS_PLUS);
_resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
+ expect(expression.staticElement, numType.getMethod('+'));
_listener.assertNoErrors();
}
@@ -830,8 +825,10 @@
AstTestFactory.postfixExpression(operand, TokenType.BANG);
_resolveNode(expression);
// TODO(danrubel): fails with Unsupported operation
- expect(expression.staticElement, getMethod(numType, "!"));
+ expect(expression.staticElement, numType.getMethod('!'));
_listener.assertNoErrors();
+ // TODO(scheglov) This is wrong: `expr!` should not be resolved to `num.!`.
+ fail('Expectations are wrong.');
}
test_visitPrefixedIdentifier_dynamic() async {
@@ -942,7 +939,7 @@
PrefixExpression expression =
AstTestFactory.prefixExpression(TokenType.PLUS_PLUS, operand);
_resolveNode(expression);
- expect(expression.staticElement, getMethod(numType, "+"));
+ expect(expression.staticElement, numType.getMethod('+'));
_listener.assertNoErrors();
}
@@ -1012,7 +1009,7 @@
String fieldName = 'nan';
SimpleIdentifier node = AstTestFactory.identifier3(fieldName);
_resolveInClass(node, doubleType.element);
- expect(node.staticElement, getGetter(doubleType, fieldName));
+ expect(node.staticElement, doubleType.getGetter(fieldName));
_listener.assertNoErrors();
}
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index 165a105..6659778 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -223,8 +223,7 @@
}
Future<void> _assertCanBeAnalyzed(String text) async {
- addTestFile(text);
- await resolveTestFile();
+ await resolveTestCode(text);
assertHasTestErrors();
}
}
@@ -271,8 +270,7 @@
}
Future<void> _assertCanBeAnalyzed(String text) async {
- addTestFile(text);
- await resolveTestFile();
+ await resolveTestCode(text);
assertHasTestErrors();
}
}
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 805d5c7..1a16278 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -46,6 +46,7 @@
defineReflectiveTests(SimpleParserTest_Fasta);
defineReflectiveTests(StatementParserTest_Fasta);
defineReflectiveTests(TopLevelParserTest_Fasta);
+ defineReflectiveTests(VarianceParserTest_Fasta);
});
}
@@ -1801,6 +1802,133 @@
}
}
+@reflectiveTest
+class VarianceParserTest_Fasta extends FastaParserTestCase {
+ @override
+ CompilationUnit parseCompilationUnit(String content,
+ {List<ErrorCode> codes,
+ List<ExpectedError> errors,
+ FeatureSet featureSet}) {
+ return super.parseCompilationUnit(content,
+ codes: codes,
+ errors: errors,
+ featureSet: featureSet ??
+ FeatureSet.forTesting(
+ sdkVersion: '2.5.0',
+ additionalFeatures: [Feature.variance],
+ ));
+ }
+
+ void test_class_enabled_single() {
+ var unit = parseCompilationUnit('class A<in T> { }');
+ expect(unit.declarations, hasLength(1));
+ var classDecl = unit.declarations[0] as ClassDeclaration;
+ expect(classDecl.name.name, 'A');
+ expect(classDecl.typeParameters.typeParameters, hasLength(1));
+ expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+ }
+
+ void test_class_enabled_multipleVariances() {
+ var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
+ expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
+ expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
+ ]);
+ expect(unit.declarations, hasLength(1));
+ var classDecl = unit.declarations[0] as ClassDeclaration;
+ expect(classDecl.name.name, 'A');
+ expect(classDecl.typeParameters.typeParameters, hasLength(1));
+ expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+ }
+
+ void test_class_disabled_single() {
+ parseCompilationUnit('class A<out T> { }',
+ errors: [
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_class_disabled_multiple() {
+ parseCompilationUnit('class A<in T, inout U, out V> { }',
+ errors: [
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_mixin_enabled_single() {
+ var unit = parseCompilationUnit('mixin A<inout T> { }');
+ expect(unit.declarations, hasLength(1));
+ var mixinDecl = unit.declarations[0] as MixinDeclaration;
+ expect(mixinDecl.name.name, 'A');
+ expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
+ expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
+ }
+
+ void test_mixin_disabled_single() {
+ parseCompilationUnit('mixin A<inout T> { }',
+ errors: [
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_mixin_disabled_multiple() {
+ parseCompilationUnit('mixin A<inout T, out U> { }',
+ errors: [
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_typedef_enabled() {
+ parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+ ]);
+ }
+
+ void test_typedef_disabled() {
+ parseCompilationUnit('typedef A<inout X> = X Function(X);',
+ errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_list_enabled() {
+ parseCompilationUnit('List<out String> stringList = [];', errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+ ]);
+ }
+
+ void test_list_disabled() {
+ parseCompilationUnit('List<out String> stringList = [];',
+ errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+
+ void test_function_enabled() {
+ parseCompilationUnit('void A(in int value) {}', errors: [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+ ]);
+ }
+
+ void test_function_disabled() {
+ parseCompilationUnit('void A(in int value) {}',
+ errors: [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+ ],
+ featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+ }
+}
+
/**
* Implementation of [AbstractParserTestCase] specialized for testing the
* Fasta parser.
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 584d201..ed1b914 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -9412,9 +9412,7 @@
* Implementation of [AbstractParserTestCase] specialized for testing the
* analyzer parser.
*/
-class ParserTestCase extends EngineTestCase
- with ParserTestHelpers
- implements AbstractParserTestCase {
+class ParserTestCase with ParserTestHelpers implements AbstractParserTestCase {
/**
* A flag indicating whether parser is to parse function bodies.
*/
@@ -10046,9 +10044,7 @@
}
}
- @override
void setUp() {
- super.setUp();
parseFunctionBodies = true;
}
}
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 691b596..c49393b 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2,7 +2,6 @@
// 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';
import 'dart:collection';
import 'package:analyzer/dart/analysis/features.dart';
@@ -61,7 +60,7 @@
}
@reflectiveTest
-class ChangeSetTest extends EngineTestCase {
+class ChangeSetTest {
void test_changedContent() {
TestSource source = new TestSource();
String content = "";
@@ -157,13 +156,12 @@
}
test_enclosingElement_invalidLocalFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C() {
int get x => 0;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
ParserErrorCode.EXPECTED_TOKEN
@@ -189,7 +187,7 @@
// therefore discard the propagated type.
//
// So this test does not use strong mode.
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
abstract class Iter {
List<S> map<S>(S f(x));
}
@@ -867,7 +865,7 @@
}
@reflectiveTest
-class TypePropagationTest extends ResolverTestCase {
+class TypePropagationTest extends DriverResolutionTest {
test_assignment_null() async {
String code = r'''
main() {
@@ -875,144 +873,73 @@
v = null;
return v; // return
}''';
- CompilationUnit unit;
- {
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- unit = analysisResult.unit;
- }
- {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit, code, "v; // declare", (node) => node is SimpleIdentifier);
- expect(identifier.staticType, typeProvider.intType);
- }
- {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit, code, "v = null;", (node) => node is SimpleIdentifier);
- expect(identifier.staticType, typeProvider.intType);
- }
- {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit, code, "v; // return", (node) => node is SimpleIdentifier);
- expect(identifier.staticType, typeProvider.intType);
- }
+ await resolveTestCode(code);
+ assertType(findNode.simple('v; // declare'), 'int');
+ assertType(findNode.simple('v = null;'), 'int');
+ assertType(findNode.simple('v; // return'), 'int');
}
test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A {
m(void f(int i)) {}
}
x() {
A a = new A();
a.m(() => 0);
-}''';
- Source source = addSource(code);
- CompilationUnit unit = await _computeResolvedUnit(source, noErrors: false);
- assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- // () => 0
- FunctionExpression functionExpression = EngineTestCase.findNode(
- unit, code, "() => 0)", (node) => node is FunctionExpression);
- expect((functionExpression.staticType as FunctionType).parameters.length,
- same(0));
+}''', [
+ error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 63, 7),
+ ]);
+ assertType(findNode.functionExpression('() => 0'), 'int Function()');
}
test_initializer_hasStaticType() async {
- Source source = addSource(r'''
+ await resolveTestCode(r'''
f() {
int v = 0;
return v;
}''');
- CompilationUnit unit = await _computeResolvedUnit(source);
- FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
- BlockFunctionBody body =
- function.functionExpression.body as BlockFunctionBody;
- NodeList<Statement> statements = body.block.statements;
- // Type of 'v' in declaration.
- {
- VariableDeclarationStatement statement =
- statements[0] as VariableDeclarationStatement;
- SimpleIdentifier variableName = statement.variables.variables[0].name;
- expect(variableName.staticType, typeProvider.intType);
- }
- // Type of 'v' in reference.
- {
- ReturnStatement statement = statements[1] as ReturnStatement;
- SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
- expect(variableName.staticType, typeProvider.intType);
- }
+ assertType(findNode.simple('v = 0;'), 'int');
+ assertType(findNode.simple('v;'), 'int');
}
test_initializer_hasStaticType_parameterized() async {
- Source source = addSource(r'''
+ await resolveTestCode(r'''
f() {
List<int> v = <int>[];
return v;
}''');
- CompilationUnit unit = await _computeResolvedUnit(source);
- FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
- BlockFunctionBody body =
- function.functionExpression.body as BlockFunctionBody;
- NodeList<Statement> statements = body.block.statements;
- // Type of 'v' in declaration.
- {
- VariableDeclarationStatement statement =
- statements[0] as VariableDeclarationStatement;
- SimpleIdentifier variableName = statement.variables.variables[0].name;
- expect(variableName.staticType, isNotNull);
- }
- // Type of 'v' in reference.
- {
- ReturnStatement statement = statements[1] as ReturnStatement;
- SimpleIdentifier variableName = statement.expression as SimpleIdentifier;
- expect(variableName.staticType, isNotNull);
- }
+ assertType(findNode.simple('v ='), 'List<int>');
+ assertType(findNode.simple('v;'), 'List<int>');
}
test_initializer_null() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
int v = null;
- return v; // marker
-}''';
- CompilationUnit unit;
- {
- Source source = addSource(code);
- unit = await _computeResolvedUnit(source);
- }
- {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit, code, "v = null;", (node) => node is SimpleIdentifier);
- expect(identifier.staticType, typeProvider.intType);
- }
- {
- SimpleIdentifier identifier = EngineTestCase.findNode(
- unit, code, "v; // marker", (node) => node is SimpleIdentifier);
- expect(identifier.staticType, typeProvider.intType);
- }
+ return v;
+}''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v;'), 'int');
}
test_invocation_target_prefixed() async {
- addNamedSource('/helper.dart', '''
-library helper;
+ newFile('/test/lib/a.dart', content: r'''
int max(int x, int y) => 0;
''');
- String code = '''
-import 'helper.dart' as helper;
+ await resolveTestCode('''
+import 'a.dart' as helper;
main() {
helper.max(10, 10); // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- SimpleIdentifier methodName =
- findMarkedIdentifier(code, unit, "(10, 10); // marker");
- MethodInvocation methodInvoke = methodName.parent;
- expect(methodInvoke.methodName.staticElement, isNotNull);
+}''');
+ assertElement(
+ findNode.simple('max(10, 10)'),
+ findElement.importFind('package:test/a.dart').topFunction('max'),
+ );
}
test_is_subclass() async {
- Source source = addSource(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
B m() => this;
@@ -1023,20 +950,15 @@
}
return p;
}''');
- CompilationUnit unit = await _computeResolvedUnit(source);
- FunctionDeclaration function = unit.declarations[2] as FunctionDeclaration;
- BlockFunctionBody body =
- function.functionExpression.body as BlockFunctionBody;
- IfStatement ifStatement = body.block.statements[0] as IfStatement;
- ReturnStatement statement =
- (ifStatement.thenStatement as Block).statements[0] as ReturnStatement;
- MethodInvocation invocation = statement.expression as MethodInvocation;
- expect(invocation.methodName.staticElement, isNotNull);
+ assertElement(
+ findNode.methodInvocation('p.m()'),
+ findElement.method('m', of: 'B'),
+ );
}
test_mutatedOutsideScope() async {
// https://code.google.com/p/dart/issues/detail?id=22732
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
class Base {
}
@@ -1061,104 +983,59 @@
}
x = null;
}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
}
test_objectAccessInference_disabled_for_library_prefix() async {
- String name = 'hashCode';
- addNamedSource('/helper.dart', '''
-library helper;
-dynamic get $name => 42;
+ newFile('/test/lib/a.dart', content: '''
+dynamic get hashCode => 42;
''');
- String code = '''
-import 'helper.dart' as helper;
+ await assertNoErrorsInCode('''
+import 'a.dart' as helper;
main() {
- helper.$name; // marker
-}''';
-
- CompilationUnit unit = await resolveSource(code);
- SimpleIdentifier id = findMarkedIdentifier(code, unit, "; // marker");
- PrefixedIdentifier prefixedId = id.parent;
- expect(id.staticType, typeProvider.dynamicType);
- expect(prefixedId.staticType, typeProvider.dynamicType);
+ helper.hashCode;
+}''');
+ assertTypeDynamic(findNode.prefixed('helper.hashCode'));
}
test_objectAccessInference_disabled_for_local_getter() async {
- String name = 'hashCode';
- String code = '''
-dynamic get $name => null;
+ await assertNoErrorsInCode('''
+dynamic get hashCode => null;
main() {
- $name; // marker
-}''';
-
- CompilationUnit unit = await resolveSource(code);
- SimpleIdentifier getter = findMarkedIdentifier(code, unit, "; // marker");
- expect(getter.staticType, typeProvider.dynamicType);
+ hashCode; // marker
+}''');
+ assertTypeDynamic(findNode.simple('hashCode; // marker'));
}
test_objectMethodInference_disabled_for_library_prefix() async {
- String name = 'toString';
- addNamedSource('/helper.dart', '''
-library helper;
+ newFile('/test/lib/a.dart', content: '''
dynamic toString = (int x) => x + 42;
''');
- String code = '''
-import 'helper.dart' as helper;
+ await assertNoErrorsInCode('''
+import 'a.dart' as helper;
main() {
- helper.$name(); // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- SimpleIdentifier methodName =
- findMarkedIdentifier(code, unit, "(); // marker");
- MethodInvocation methodInvoke = methodName.parent;
- expect(methodName.staticType, typeProvider.dynamicType);
- expect(methodInvoke.staticType, typeProvider.dynamicType);
+ helper.toString();
+}''');
+ assertTypeDynamic(findNode.methodInvocation('helper.toString()'));
}
test_objectMethodInference_disabled_for_local_function() async {
- String name = 'toString';
- String code = '''
+ await resolveTestCode('''
main() {
- dynamic $name = () => null;
- $name(); // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
-
- SimpleIdentifier identifier = findMarkedIdentifier(code, unit, "$name = ");
- expect(identifier.staticType, typeProvider.dynamicType);
-
- SimpleIdentifier methodName =
- findMarkedIdentifier(code, unit, "(); // marker");
- MethodInvocation methodInvoke = methodName.parent;
- expect(methodName.staticType, typeProvider.dynamicType);
- expect(methodInvoke.staticType, typeProvider.dynamicType);
+ dynamic toString = () => null;
+ toString(); // marker
+}''');
+ assertTypeDynamic(findNode.simple('toString ='));
+ assertTypeDynamic(findNode.simple('toString(); // marker'));
}
@failingTest
test_propagatedReturnType_functionExpression() async {
// TODO(scheglov) disabled because we don't resolve function expression
- String code = r'''
+ await resolveTestCode(r'''
main() {
var v = (() {return 42;})();
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.dynamicType);
- }
-
- /**
- * Return the resolved unit for the given [source].
- *
- * If [noErrors] is not specified or is not `true`, [assertNoErrors].
- */
- Future<CompilationUnit> _computeResolvedUnit(Source source,
- {bool noErrors: true}) async {
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- if (noErrors) {
- assertNoErrors(source);
- verify([source]);
- }
- return analysisResult.unit;
+}''');
+ assertTypeDynamic(findNode.simple('v = '));
}
}
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index aa995d1..cc089a6 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -32,6 +32,7 @@
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
+import '../src/dart/resolution/driver_resolution.dart';
import 'test_analysis_context.dart';
import 'test_support.dart';
@@ -308,7 +309,7 @@
}
}
-class ResolverTestCase extends EngineTestCase with ResourceProviderMixin {
+class ResolverTestCase with ResourceProviderMixin {
/**
* Specifies if [assertErrors] should check for [HintCode.UNUSED_ELEMENT] and
* [HintCode.UNUSED_FIELD].
@@ -384,16 +385,6 @@
addNamedSource(_defaultSourceName, contents);
/**
- * The [code] that assigns the value to the variable "v", no matter how. We
- * check that "v" has expected static type.
- */
- void assertAssignedType(
- String code, CompilationUnit unit, DartType expectedStaticType) {
- SimpleIdentifier identifier = findMarkedIdentifier(code, unit, "v = ");
- expect(identifier.staticType, expectedStaticType);
- }
-
- /**
* Assert that the number of errors reported against the given
* [source] matches the number of errors that are given and that they have
* the expected error codes. The order in which the errors were gathered is
@@ -474,26 +465,6 @@
verify([source]);
}
- /**
- * The [code] that iterates using variable "v". We check that "v" has expected
- * static type.
- */
- void assertPropagatedIterationType(
- String code, CompilationUnit unit, DartType expectedStaticType) {
- SimpleIdentifier identifier = findMarkedIdentifier(code, unit, "v in ");
- expect(identifier.staticType, expectedStaticType);
- }
-
- /**
- * Check the static type of the expression marked with "; // marker" comment.
- */
- void assertTypeOfMarkedExpression(
- String code, CompilationUnit unit, DartType expectedStaticType) {
- SimpleIdentifier identifier =
- findMarkedIdentifier(code, unit, "; // marker");
- expect(identifier.staticType, expectedStaticType);
- }
-
Future<TestAnalysisResult> computeAnalysisResult(Source source) async {
TestAnalysisResult analysisResult;
ResolvedUnitResult result = await driver.getResult(source.fullName);
@@ -573,16 +544,6 @@
return library;
}
- /**
- * Return the [SimpleIdentifier] from [unit] marked by [marker] in [code].
- * The source code must have no errors and be verifiable.
- */
- SimpleIdentifier findMarkedIdentifier(
- String code, CompilationUnit unit, String marker) {
- return EngineTestCase.findNode(
- unit, code, marker, (node) => node is SimpleIdentifier);
- }
-
Expression findTopLevelConstantExpression(
CompilationUnit compilationUnit, String name) =>
findTopLevelDeclaration(compilationUnit, name).initializer;
@@ -706,17 +667,13 @@
verify([source]);
}
- @override
void setUp() {
ElementFactory.flushStaticState();
- super.setUp();
reset();
}
- @override
void tearDown() {
AnalysisEngine.instance.clearCaches();
- super.tearDown();
}
/**
@@ -738,11 +695,7 @@
* Shared infrastructure for [StaticTypeAnalyzer2Test] and
* [StrongModeStaticTypeAnalyzer2Test].
*/
-class StaticTypeAnalyzer2TestShared extends ResolverTestCase {
- String testCode;
- Source testSource;
- CompilationUnit testUnit;
-
+class StaticTypeAnalyzer2TestShared extends DriverResolutionTest {
/**
* Find the expression that starts at the offset of [search] and validate its
* that its static type matches the given [type].
@@ -752,7 +705,7 @@
* to match the type.
*/
void expectExpressionType(String search, type) {
- Expression expression = findExpression(search);
+ Expression expression = findNode.expression(search);
_expectType(expression.staticType, type);
}
@@ -778,7 +731,7 @@
fail('Wrong element type: ${element.runtimeType}');
}
- SimpleIdentifier identifier = findIdentifier(name);
+ SimpleIdentifier identifier = findNode.simple(name);
// Element is either ExecutableElement or ParameterElement.
var element = identifier.staticElement;
FunctionTypeImpl functionType = (element as dynamic).type;
@@ -797,7 +750,7 @@
* output.
*/
FunctionTypeImpl expectFunctionType2(String name, String type) {
- SimpleIdentifier identifier = findIdentifier(name);
+ SimpleIdentifier identifier = findNode.simple(name);
FunctionTypeImpl functionType = identifier.staticType;
expect('$functionType', type);
return functionType;
@@ -811,7 +764,7 @@
* to match the type.
*/
void expectIdentifierType(String name, type) {
- SimpleIdentifier identifier = findIdentifier(name);
+ SimpleIdentifier identifier = findNode.simple(name);
_expectType(identifier.staticType, type);
}
@@ -824,34 +777,13 @@
* to match the type.
*/
void expectInitializerType(String name, type) {
- SimpleIdentifier identifier = findIdentifier(name);
+ SimpleIdentifier identifier = findNode.simple(name);
VariableDeclaration declaration =
identifier.thisOrAncestorOfType<VariableDeclaration>();
Expression initializer = declaration.initializer;
_expectType(initializer.staticType, type);
}
- Expression findExpression(String search) {
- return EngineTestCase.findNode(
- testUnit, testCode, search, (node) => node is Expression);
- }
-
- SimpleIdentifier findIdentifier(String search) {
- return EngineTestCase.findNode(
- testUnit, testCode, search, (node) => node is SimpleIdentifier);
- }
-
- Future<void> resolveTestUnit(String code, {bool noErrors: true}) async {
- testCode = code;
- testSource = addSource(testCode);
- TestAnalysisResult analysisResult = await computeAnalysisResult(testSource);
- if (noErrors) {
- assertNoErrors(testSource);
- }
- verify([testSource]);
- testUnit = analysisResult.unit;
- }
-
/**
* Validates that [type] matches [expected].
*
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 5470859..1ff1558 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -21,7 +21,7 @@
});
}
-class CharacterRangeReaderTest extends EngineTestCase {
+class CharacterRangeReaderTest {
void test_advance() {
CharSequenceReader baseReader = new CharSequenceReader("xyzzy");
CharacterRangeReader reader = new CharacterRangeReader(baseReader, 1, 4);
@@ -78,7 +78,7 @@
}
@reflectiveTest
-class LineInfoTest extends EngineTestCase {
+class LineInfoTest {
final featureSet = FeatureSet.forTesting(sdkVersion: '2.2.2');
void test_lineInfo_multilineComment() {
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
index 6dae63b..e62602f 100644
--- a/pkg/analyzer/test/generated/sdk_test.dart
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -9,8 +9,6 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'test_support.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DartSdkManagerTest);
@@ -19,7 +17,7 @@
}
@reflectiveTest
-class DartSdkManagerTest extends EngineTestCase with ResourceProviderMixin {
+class DartSdkManagerTest with ResourceProviderMixin {
void test_anySdk() {
DartSdkManager manager = new DartSdkManager('/a/b/c', false);
expect(manager.anySdk, isNull);
@@ -63,7 +61,7 @@
}
@reflectiveTest
-class SdkDescriptionTest extends EngineTestCase {
+class SdkDescriptionTest {
void test_equals_differentPaths_nested() {
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription left = new SdkDescription(<String>['/a/b/c'], options);
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index de35b72..7df3a66 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -20,7 +20,7 @@
@reflectiveTest
class SimpleResolverTest extends DriverResolutionTest {
test_argumentResolution_required_matching() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2, 3);
@@ -31,7 +31,7 @@
}
test_argumentResolution_required_tooFew() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2);
@@ -42,7 +42,7 @@
}
test_argumentResolution_required_tooMany() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2, 3);
@@ -53,7 +53,7 @@
}
test_argumentResolution_requiredAndNamed_extra() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void f() {
g(1, 2, c: 3, d: 4);
@@ -64,7 +64,7 @@
}
test_argumentResolution_requiredAndNamed_matching() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2, c: 3);
@@ -75,7 +75,7 @@
}
test_argumentResolution_requiredAndNamed_missing() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void f() {
g(1, 2, d: 3);
@@ -86,7 +86,7 @@
}
test_argumentResolution_requiredAndPositional_fewer() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void f() {
g(1, 2, 3);
@@ -97,7 +97,7 @@
}
test_argumentResolution_requiredAndPositional_matching() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2, 3, 4);
@@ -108,7 +108,7 @@
}
test_argumentResolution_requiredAndPositional_more() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void f() {
g(1, 2, 3, 4);
@@ -119,7 +119,7 @@
}
test_argumentResolution_setter_propagated() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var a = new A();
a.sss = 0;
@@ -127,8 +127,6 @@
class A {
set sss(x) {}
}''');
- await resolveTestFile();
-
var rhs = findNode.assignment(' = 0;').rightHandSide;
expect(
rhs.staticParameterElement,
@@ -137,7 +135,7 @@
}
test_argumentResolution_setter_propagated_propertyAccess() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var a = new A();
a.b.sss = 0;
@@ -148,8 +146,6 @@
class B {
set sss(x) {}
}''');
- await resolveTestFile();
-
var rhs = findNode.assignment(' = 0;').rightHandSide;
expect(
rhs.staticParameterElement,
@@ -158,7 +154,7 @@
}
test_argumentResolution_setter_static() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
A a = new A();
a.sss = 0;
@@ -166,8 +162,6 @@
class A {
set sss(x) {}
}''');
- await resolveTestFile();
-
var rhs = findNode.assignment(' = 0;').rightHandSide;
expect(
rhs.staticParameterElement,
@@ -176,7 +170,7 @@
}
test_argumentResolution_setter_static_propertyAccess() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
A a = new A();
a.b.sss = 0;
@@ -187,8 +181,6 @@
class B {
set sss(x) {}
}''');
- await resolveTestFile();
-
var rhs = findNode.assignment(' = 0;').rightHandSide;
expect(
rhs.staticParameterElement,
@@ -199,7 +191,7 @@
test_breakTarget_labeled() async {
// Verify that the target of the label is correctly found and is recorded
// as the unlabeled portion of the statement.
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
loop1: while (true) {
loop2: for (int i = 0; i < 10; i++) {
@@ -209,8 +201,6 @@
}
}
''');
- await resolveTestFile();
-
var break1 = findNode.breakStatement('break loop1;');
var whileStatement = findNode.whileStatement('while (');
expect(break1.target, same(whileStatement));
@@ -221,52 +211,46 @@
}
test_breakTarget_unlabeledBreakFromDo() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
do {
break;
} while (true);
}
''');
- await resolveTestFile();
-
var doStatement = findNode.doStatement('do {');
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, same(doStatement));
}
test_breakTarget_unlabeledBreakFromFor() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
for (int i = 0; i < 10; i++) {
break;
}
}
''');
- await resolveTestFile();
-
var forStatement = findNode.forStatement('for (');
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, same(forStatement));
}
test_breakTarget_unlabeledBreakFromForEach() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
for (x in []) {
break;
}
}
''');
- await resolveTestFile();
-
var forStatement = findNode.forStatement('for (');
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, same(forStatement));
}
test_breakTarget_unlabeledBreakFromSwitch() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
switch (0) {
@@ -276,23 +260,19 @@
}
}
''');
- await resolveTestFile();
-
var switchStatement = findNode.switchStatement('switch (');
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, same(switchStatement));
}
test_breakTarget_unlabeledBreakFromWhile() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
break;
}
}
''');
- await resolveTestFile();
-
var whileStatement = findNode.whileStatement('while (');
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, same(whileStatement));
@@ -301,7 +281,7 @@
test_breakTarget_unlabeledBreakToOuterFunction() async {
// Verify that unlabeled break statements can't resolve to loops in an
// outer function.
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
void g() {
@@ -310,8 +290,6 @@
}
}
''');
- await resolveTestFile();
-
var breakStatement = findNode.breakStatement('break;');
expect(breakStatement.target, isNull);
}
@@ -336,7 +314,7 @@
test_continueTarget_labeled() async {
// Verify that the target of the label is correctly found and is recorded
// as the unlabeled portion of the statement.
- addTestFile('''
+ await resolveTestCode('''
void f() {
loop1: while (true) {
loop2: for (int i = 0; i < 10; i++) {
@@ -346,8 +324,6 @@
}
}
''');
- await resolveTestFile();
-
var continue1 = findNode.continueStatement('continue loop1');
var whileStatement = findNode.whileStatement('while (');
expect(continue1.target, same(whileStatement));
@@ -358,67 +334,59 @@
}
test_continueTarget_unlabeledContinueFromDo() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
do {
continue;
} while (true);
}
''');
- await resolveTestFile();
-
var doStatement = findNode.doStatement('do {');
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, same(doStatement));
}
test_continueTarget_unlabeledContinueFromFor() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
for (int i = 0; i < 10; i++) {
continue;
}
}
''');
- await resolveTestFile();
-
var forStatement = findNode.forStatement('for (');
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, same(forStatement));
}
test_continueTarget_unlabeledContinueFromForEach() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
for (x in []) {
continue;
}
}
''');
- await resolveTestFile();
-
var forStatement = findNode.forStatement('for (');
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, same(forStatement));
}
test_continueTarget_unlabeledContinueFromWhile() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
continue;
}
}
''');
- await resolveTestFile();
-
var whileStatement = findNode.whileStatement('while (');
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, same(whileStatement));
}
test_continueTarget_unlabeledContinueSkipsSwitch() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
switch (0) {
@@ -428,8 +396,6 @@
}
}
''');
- await resolveTestFile();
-
var whileStatement = findNode.whileStatement('while (');
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, same(whileStatement));
@@ -438,7 +404,7 @@
test_continueTarget_unlabeledContinueToOuterFunction() async {
// Verify that unlabeled continue statements can't resolve to loops in an
// outer function.
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {
while (true) {
void g() {
@@ -447,15 +413,12 @@
}
}
''');
- await resolveTestFile();
-
var continueStatement = findNode.continueStatement('continue;');
expect(continueStatement.target, isNull);
}
test_empty() async {
- addTestFile('');
- await resolveTestFile();
+ await resolveTestCode('');
assertNoTestErrors();
}
@@ -464,10 +427,9 @@
main() {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
export 'a.dart';
''');
- await resolveTestFile();
assertNoTestErrors();
var library = result.libraryElement;
@@ -478,10 +440,9 @@
}
test_entryPoint_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {}
''');
- await resolveTestFile();
assertNoTestErrors();
var library = result.libraryElement;
@@ -492,8 +453,7 @@
}
test_entryPoint_none() async {
- addTestFile('');
- await resolveTestFile();
+ await resolveTestCode('');
assertNoTestErrors();
var library = result.libraryElement;
@@ -504,12 +464,11 @@
newFile('/test/lib/a.dart', content: r'''
enum EEE {A, B, C}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
void f(EEE e) {}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
@@ -527,13 +486,12 @@
}
test_fieldFormalParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int x;
int y;
A(this.x) : y = x {}
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -583,7 +541,7 @@
}
test_getter_and_setter_fromMixins_bare_identifier() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
get x => null;
@@ -599,7 +557,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -621,7 +578,7 @@
// TODO(paulberry): it appears that auxiliaryElements isn't properly set on
// a SimpleIdentifier that's inside a property access. This bug should be
// fixed.
- addTestFile(r'''
+ await resolveTestCode(r'''
class B {}
class M1 {
get x => null;
@@ -653,7 +610,7 @@
}
test_getter_fromMixins_bare_identifier() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
get x => null;
@@ -667,7 +624,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -680,7 +636,7 @@
}
test_getter_fromMixins_property_access() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
get x => null;
@@ -693,7 +649,6 @@
var y = new C().x;
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -706,7 +661,7 @@
}
test_getterAndSetterWithDifferentTypes() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get f => 0;
void set f(String s) {}
@@ -714,17 +669,15 @@
g (A a) {
a.f = a.f.toString();
}''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
verifyTestResolved();
}
test_hasReferenceToSuper() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B {toString() => super.toString();}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -743,7 +696,7 @@
newFile('/test/lib/lib2.dart', content: r'''
set foo(value) {}''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'lib1.dart' hide foo;
import 'lib2.dart';
@@ -751,7 +704,6 @@
foo = 0;
}
A a;''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
@@ -762,12 +714,11 @@
return x * x;
}''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as _a;
main() {
_a.f(0);
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
@@ -778,7 +729,7 @@
// single error generated when the only problem is that an imported file
// does not exist.
//
- addTestFile('''
+ await resolveTestCode('''
import 'missing.dart' as p;
int a = p.q + p.r.s;
String b = p.t(a) + p.u(v: 0);
@@ -795,7 +746,6 @@
H(int i) : super(i);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
verifyTestResolved();
}
@@ -806,7 +756,7 @@
// single error generated when the only problem is that an imported file
// does not exist.
//
- addTestFile('''
+ await resolveTestCode('''
import 'missing.dart' show q, r, t, u, T, U, V, W;
int a = q + r.s;
String b = t(a) + u(v: 0);
@@ -823,7 +773,6 @@
H(int i) : super(i);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
verifyTestResolved();
}
@@ -857,12 +806,11 @@
}
test_indexExpression_typeParameters_invalidAssignmentWarning() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
f() {
List<List<int>> b;
b[0][0] = 'hi';
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verifyTestResolved();
}
@@ -899,11 +847,10 @@
}
test_isValidMixin_badSuperclass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A extends B {}
class B {}
class C = Object with A;''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
verifyTestResolved();
@@ -913,12 +860,11 @@
}
test_isValidMixin_constructor() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A() {}
}
class C = Object with A;''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
);
@@ -929,12 +875,11 @@
}
test_isValidMixin_factoryConstructor() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
factory A() => null;
}
class C = Object with A;''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -943,14 +888,13 @@
}
test_isValidMixin_super() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
toString() {
return super.toString();
}
}
class C = Object with A;''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
verifyTestResolved();
@@ -984,23 +928,20 @@
}
test_localVariable_types_invoked() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
main() {
var myVar = (int p) => 'foo';
myVar(42);
}''');
- await resolveTestFile();
-
var node = findNode.simple('myVar(42)');
assertType(node, 'String Function(int)');
}
test_metadata_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
@A class C<A> {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1015,12 +956,11 @@
}
test_metadata_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
class C {
@A int f;
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1029,13 +969,12 @@
}
test_metadata_fieldFormalParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
class C {
int f;
C(@A this.f);
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1044,10 +983,9 @@
}
test_metadata_function() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
@A f() {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1056,10 +994,9 @@
}
test_metadata_functionTypedParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
f(@A int p(int x)) {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1068,10 +1005,9 @@
}
test_metadata_libraryDirective() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
@A library lib;
const A = null;''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1080,12 +1016,11 @@
}
test_metadata_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
class C {
@A void m() {}
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1094,10 +1029,9 @@
}
test_metadata_namedParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
f({@A int p : 0}) {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1106,10 +1040,9 @@
}
test_metadata_positionalParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
f([@A int p = 0]) {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1118,10 +1051,9 @@
}
test_metadata_simpleParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
f(@A p1, @A int p2) {}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1130,10 +1062,9 @@
}
test_metadata_typedef() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const A = null;
@A typedef F<A>();''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1147,7 +1078,7 @@
}
test_method_fromMixin() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class B {
bar() => 1;
}
@@ -1159,13 +1090,12 @@
bar() => super.bar();
foo() => super.foo();
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_method_fromMixins() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
void f() {}
@@ -1178,7 +1108,6 @@
new C().f();
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1189,7 +1118,7 @@
}
test_method_fromMixins_bare_identifier() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
void f() {}
@@ -1203,7 +1132,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1214,7 +1142,7 @@
}
test_method_fromMixins_invoked_from_outside_class() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
void f() {}
@@ -1227,7 +1155,6 @@
new C().f();
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1238,7 +1165,7 @@
}
test_method_fromSuperclassMixin() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void m1() {}
}
@@ -1249,13 +1176,12 @@
f(C c) {
c.m1();
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_methodCascades() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void m1() {}
void m2() {}
@@ -1265,13 +1191,12 @@
..m2();
}
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_methodCascades_withSetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
String name;
void m1() {}
@@ -1283,23 +1208,21 @@
..m2();
}
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_resolveAgainstNull() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
f(var p) {
return null == p;
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_setter_fromMixins_bare_identifier() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
set x(value) {}
@@ -1313,7 +1236,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1324,7 +1246,7 @@
}
test_setter_fromMixins_property_access() async {
- addTestFile('''
+ await resolveTestCode('''
class B {}
class M1 {
set x(value) {}
@@ -1337,7 +1259,6 @@
new C().x = 1;
}
''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
@@ -1348,7 +1269,7 @@
}
test_setter_inherited() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get x => 0;
set x(int p) {}
@@ -1357,20 +1278,18 @@
int get x => super.x == null ? 0 : super.x;
int f() => x = 1;
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
test_setter_static() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
set s(x) {
}
main() {
s = 123;
}''');
- await resolveTestFile();
assertNoTestErrors();
verifyTestResolved();
}
@@ -1404,8 +1323,6 @@
* valid
*/
Future<void> _validateArgumentResolution(List<int> indices) async {
- await resolveTestFile();
-
var g = findElement.method('g');
var parameters = g.parameters;
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index c9246a0..abfd5fc 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -53,14 +53,13 @@
@reflectiveTest
class SetLiteralsTest extends StaticTypeAnalyzer2TestShared {
test_emptySetLiteral_parameter_typed() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
useSet({});
}
void useSet(Set<int> s) {
}
-''';
- await resolveTestUnit(code);
+''');
expectExpressionType('{}', 'Set<int>');
}
}
@@ -71,90 +70,83 @@
@reflectiveTest
class StaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
test_FunctionExpressionInvocation_block() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
var foo = (() { return 1; })();
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
test_FunctionExpressionInvocation_curried() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
typedef int F();
F f() => null;
main() {
var foo = f()();
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
test_FunctionExpressionInvocation_expression() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
var foo = (() => 1)();
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
test_MethodInvocation_nameType_localVariable() async {
- String code = r"""
+ await assertNoErrorsInCode(r"""
typedef Foo();
main() {
Foo foo;
foo();
}
-""";
- await resolveTestUnit(code);
+""");
// "foo" should be resolved to the "Foo" type
expectIdentifierType("foo();", new TypeMatcher<FunctionType>());
}
test_MethodInvocation_nameType_parameter_FunctionTypeAlias() async {
- String code = r"""
+ await assertNoErrorsInCode(r"""
typedef Foo();
main(Foo foo) {
foo();
}
-""";
- await resolveTestUnit(code);
+""");
// "foo" should be resolved to the "Foo" type
expectIdentifierType("foo();", new TypeMatcher<FunctionType>());
}
test_MethodInvocation_nameType_parameter_propagatedType() async {
- String code = r"""
+ await assertNoErrorsInCode(r"""
typedef Foo();
main(p) {
if (p is Foo) {
p();
}
}
-""";
- await resolveTestUnit(code);
+""");
expectIdentifierType("p()", 'dynamic Function()');
}
test_staticMethods_classTypeParameters() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
static void m() => null;
}
main() {
print(C.m);
}
-''';
- await resolveTestUnit(code);
+''');
expectFunctionType('m);', 'void Function()');
}
test_staticMethods_classTypeParameters_genericMethod() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
static void m<S>(S s) {
void f<U>(S s, U u) {}
@@ -164,8 +156,7 @@
main() {
print(C.m);
}
-''';
- await resolveTestUnit(code);
+''');
// C - m
TypeParameterType typeS;
{
@@ -208,31 +199,28 @@
@reflectiveTest
class StaticTypeAnalyzer3Test extends StaticTypeAnalyzer2TestShared {
test_emptyMapLiteral_initializer_var() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
var v = {};
}
-''';
- await resolveTestUnit(code);
+''');
expectExpressionType('{}', 'Map<dynamic, dynamic>');
}
test_emptyMapLiteral_parameter_typed() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
useMap({});
}
void useMap(Map<int, int> m) {
}
-''';
- await resolveTestUnit(code);
+''');
expectExpressionType('{}', 'Map<int, int>');
}
}
@reflectiveTest
-class StaticTypeAnalyzerTest extends EngineTestCase
- with ResourceProviderMixin, ElementsTypesMixin {
+class StaticTypeAnalyzerTest with ResourceProviderMixin, ElementsTypesMixin {
/**
* The error listener to which errors will be reported.
*/
@@ -275,9 +263,7 @@
_listener.assertNoErrors();
}
- @override
void setUp() {
- super.setUp();
_listener = new GatheringErrorListener();
_analyzer = _createAnalyzer();
}
@@ -519,7 +505,7 @@
// 1 + 2.0
BinaryExpression node = AstTestFactory.binaryExpression(
_resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "+");
+ node.staticElement = _typeProvider.numType.getMethod('+');
expect(_analyze(node), same(_typeProvider.doubleType));
_listener.assertNoErrors();
}
@@ -528,7 +514,7 @@
// 1 + 2
BinaryExpression node = AstTestFactory.binaryExpression(
_resolvedInteger(1), TokenType.PLUS, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "+");
+ node.staticElement = _typeProvider.numType.getMethod('+');
expect(_analyze(node), same(_typeProvider.intType));
_listener.assertNoErrors();
}
@@ -537,7 +523,7 @@
// 2 / 2
BinaryExpressionImpl node = AstTestFactory.binaryExpression(
_resolvedInteger(2), TokenType.SLASH, _resolvedInteger(2));
- node.staticElement = getMethod(_typeProvider.numType, "/");
+ node.staticElement = _typeProvider.numType.getMethod('/');
node.staticInvokeType = node.staticElement.type;
expect(_analyze(node), _typeProvider.doubleType);
_listener.assertNoErrors();
@@ -570,7 +556,7 @@
// 1 * 2.0
BinaryExpression node = AstTestFactory.binaryExpression(
_resolvedInteger(1), TokenType.PLUS, _resolvedDouble(2.0));
- node.staticElement = getMethod(_typeProvider.numType, "*");
+ node.staticElement = _typeProvider.numType.getMethod('*');
expect(_analyze(node), same(_typeProvider.doubleType));
_listener.assertNoErrors();
}
@@ -1122,7 +1108,7 @@
// -0
PrefixExpression node =
AstTestFactory.prefixExpression(TokenType.MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
+ MethodElement minusMethod = _typeProvider.numType.getMethod('-');
node.staticElement = minusMethod;
expect(_analyze(node), _typeProvider.numType);
_listener.assertNoErrors();
@@ -1132,7 +1118,7 @@
// --0
PrefixExpression node = AstTestFactory.prefixExpression(
TokenType.MINUS_MINUS, _resolvedInteger(0));
- MethodElement minusMethod = getMethod(_typeProvider.numType, "-");
+ MethodElement minusMethod = _typeProvider.numType.getMethod('-');
node.staticElement = minusMethod;
expect(_analyze(node), same(_typeProvider.intType));
_listener.assertNoErrors();
@@ -1150,7 +1136,7 @@
// ++0
PrefixExpression node = AstTestFactory.prefixExpression(
TokenType.PLUS_PLUS, _resolvedInteger(0));
- MethodElement plusMethod = getMethod(_typeProvider.numType, "+");
+ MethodElement plusMethod = _typeProvider.numType.getMethod('+');
node.staticElement = plusMethod;
expect(_analyze(node), same(_typeProvider.intType));
_listener.assertNoErrors();
@@ -1160,7 +1146,7 @@
// ~0
PrefixExpression node =
AstTestFactory.prefixExpression(TokenType.TILDE, _resolvedInteger(0));
- MethodElement tildeMethod = getMethod(_typeProvider.intType, "~");
+ MethodElement tildeMethod = _typeProvider.intType.getMethod('~');
node.staticElement = tildeMethod;
expect(_analyze(node), _typeProvider.intType);
_listener.assertNoErrors();
@@ -1490,20 +1476,19 @@
class StaticTypeAnalyzerWithSetLiteralsTest
extends StaticTypeAnalyzer2TestShared {
test_emptySetLiteral_inferredFromLinkedHashSet() async {
- String code = r'''
+ await assertErrorsInCode(r'''
import 'dart:collection';
LinkedHashSet<int> test4() => {};
-''';
- await resolveTestUnit(code, noErrors: false);
+''', [
+ error(StrongModeCode.INVALID_CAST_LITERAL_SET, 56, 2),
+ ]);
expectExpressionType('{}', 'Set<dynamic>');
- await assertErrorsInCode(code, [StrongModeCode.INVALID_CAST_LITERAL_SET]);
}
test_emptySetLiteral_initializer_typed_nested() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
Set<Set<int>> ints = {{}};
-''';
- await resolveTestUnit(code);
+''');
expectExpressionType('{}', 'Set<int>');
expectExpressionType('{{}}', 'Set<Set<int>>');
}
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index bac33e6..8557eb0 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -20,6 +20,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../src/dart/resolution/driver_resolution.dart';
import '../utils.dart';
import 'resolver_test_case.dart';
@@ -4134,16 +4135,10 @@
@reflectiveTest
class StrongModeStaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
void expectStaticInvokeType(String search, String type) {
- var invocation = findIdentifier(search).parent as MethodInvocation;
+ var invocation = findNode.simple(search).parent as MethodInvocation;
expect(invocation.staticInvokeType.toString(), type);
}
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- resetWith(options: options);
- }
-
test_dynamicObjectGetter_hashCode() async {
String code = r'''
main() {
@@ -4151,7 +4146,7 @@
var foo = a.hashCode;
}
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
expectInitializerType('foo', 'int');
}
@@ -4161,7 +4156,7 @@
import "dart:async";
dynamic test(FutureOr<int> x) => (x is int) && (x.abs() == 0);
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
}
test_futureOr_promotion2() async {
@@ -4172,7 +4167,7 @@
dynamic test(FutureOr<int> x) => (x is Future<int>) &&
(x.then((x) => x) == null);
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
}
test_futureOr_promotion3() async {
@@ -4183,7 +4178,7 @@
dynamic test<T extends num>(FutureOr<T> x) => (x is T) &&
(x.abs() == 0);
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
}
test_futureOr_promotion4() async {
@@ -4194,32 +4189,30 @@
dynamic test<T extends num>(FutureOr<T> x) => (x is Future<T>) &&
(x.then((x) => x) == null);
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
}
test_generalizedVoid_assignToVoidOk() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
void main() {
void x;
x = 42;
}
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
}
test_genericFunction() async {
- await resolveTestUnit(r'T f<T>(T x) => null;');
+ await assertNoErrorsInCode(r'T f<T>(T x) => null;');
expectFunctionType('f', 'T Function<T>(T)',
elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = findIdentifier('f');
+ SimpleIdentifier f = findNode.simple('f');
FunctionElementImpl e = f.staticElement;
FunctionType ft = e.type.instantiate([typeProvider.stringType]);
expect(ft.toString(), 'String Function(String)');
}
test_genericFunction_bounds() async {
- await resolveTestUnit(r'T f<T extends num>(T x) => null;');
+ await assertNoErrorsInCode(r'T f<T extends num>(T x) => null;');
expectFunctionType('f', 'T Function<T extends num>(T)',
elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
}
@@ -4228,7 +4221,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void g(T f<T>(T x)) {}
''');
var type = expectFunctionType2('f', 'T Function<T>(T)');
@@ -4237,14 +4230,14 @@
}
test_genericFunction_static() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
static T f<T>(T x) => null;
}
''');
expectFunctionType('f', 'T Function<T>(T)',
elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = findIdentifier('f');
+ SimpleIdentifier f = findNode.simple('f');
MethodElementImpl e = f.staticElement;
FunctionType ft = e.type.instantiate([typeProvider.stringType]);
expect(ft.toString(), 'String Function(String)');
@@ -4258,7 +4251,7 @@
class C {
static F f1;
F f2;
- void g(F f3) {
+ void g(F f3) { // C
F f4;
f0(3);
f1(3);
@@ -4271,7 +4264,7 @@
class D<S> {
static F f1;
F f2;
- void g(F f3) {
+ void g(F f3) { // D
F f4;
f0(3);
f1(3);
@@ -4281,11 +4274,10 @@
}
}
''';
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
checkBody(String className) {
- List<Statement> statements =
- AstFinder.getStatementsInMethod(testUnit, className, "g");
+ var statements = findNode.block('{ // $className').statements;
for (int i = 1; i <= 5; i++) {
Expression exp = (statements[i] as ExpressionStatement).expression;
@@ -4299,13 +4291,13 @@
test_genericFunction_upwardsAndDownwards() async {
// Regression tests for https://github.com/dart-lang/sdk/issues/27586.
- await resolveTestUnit(r'List<num> x = [1, 2];');
+ await assertNoErrorsInCode(r'List<num> x = [1, 2];');
expectInitializerType('x', 'List<num>');
}
test_genericFunction_upwardsAndDownwards_Object() async {
// Regression tests for https://github.com/dart-lang/sdk/issues/27625.
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
List<Object> aaa = [];
List<Object> bbb = [1, 2, 3];
List<Object> ccc = [null];
@@ -4320,7 +4312,7 @@
}
test_genericMethod() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
List<T> f<T>(E e) => null;
}
@@ -4328,12 +4320,12 @@
C<String> cOfString;
}
''');
- expectFunctionType('f', 'List<T> Function<T>(E)',
+ expectFunctionType('f<T>', 'List<T> Function<T>(E)',
elementTypeParams: '[T]',
typeParams: '[E]',
typeArgs: '[E]',
typeFormals: '[T]');
- SimpleIdentifier c = findIdentifier('cOfString');
+ SimpleIdentifier c = findNode.simple('cOfString');
FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
expect(ft.toString(), 'List<T> Function<T>(String)');
ft = ft.instantiate([typeProvider.intType]);
@@ -4341,7 +4333,7 @@
}
test_genericMethod_explicitTypeParams() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
List<T> f<T>(E e) => null;
}
@@ -4350,16 +4342,16 @@
var x = cOfString.f<int>('hi');
}
''');
- MethodInvocation f = findIdentifier('f<int>').parent;
+ MethodInvocation f = findNode.simple('f<int>').parent;
FunctionType ft = f.staticInvokeType;
expect(ft.toString(), 'List<int> Function(String)');
- SimpleIdentifier x = findIdentifier('x');
+ SimpleIdentifier x = findNode.simple('x');
expect(x.staticType, typeProvider.listType2(typeProvider.intType));
}
test_genericMethod_functionExpressionInvocation_explicit() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(T e) => null;
static T g<T>(T e) => null;
@@ -4396,7 +4388,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void test<S>(T pf<T>(T e)) {
var paramCall = (pf)<int>(3);
}
@@ -4408,7 +4400,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void test<S>(T pf<T>(T e)) {
var paramCall = (pf)(3);
}
@@ -4420,7 +4412,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(T e) => null;
static T g<T>(T e) => null;
@@ -4454,7 +4446,7 @@
}
test_genericMethod_functionInvocation_explicit() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(T e) => null;
static T g<T>(T e) => null;
@@ -4488,7 +4480,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void test<S>(T pf<T>(T e)) {
var paramCall = pf<int>(3);
}
@@ -4500,7 +4492,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void test<S>(T pf<T>(T e)) {
var paramCall = pf(3);
}
@@ -4509,7 +4501,7 @@
}
test_genericMethod_functionInvocation_inferred() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(T e) => null;
static T g<T>(T e) => null;
@@ -4540,7 +4532,7 @@
}
test_genericMethod_functionTypedParameter() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
List<T> f<T>(T f(E e)) => null;
}
@@ -4548,13 +4540,13 @@
C<String> cOfString;
}
''');
- expectFunctionType('f', 'List<T> Function<T>(T Function(E))',
+ expectFunctionType('f<T>', 'List<T> Function<T>(T Function(E))',
elementTypeParams: '[T]',
typeParams: '[E]',
typeArgs: '[E]',
typeFormals: '[T]');
- SimpleIdentifier c = findIdentifier('cOfString');
+ SimpleIdentifier c = findNode.simple('cOfString');
FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
expect(ft.toString(), 'List<T> Function<T>(T Function(String))');
ft = ft.instantiate([typeProvider.intType]);
@@ -4565,7 +4557,7 @@
// TODO(paulberry): remove when dartbug.com/28515 fixed.
if (!AnalysisDriver.useSummary2) return;
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
void test<S>(T pf<T>(T e)) {
var paramTearOff = pf;
}
@@ -4577,7 +4569,7 @@
// Regression test for:
// https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
// These should not cause any hints or warnings.
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class List<E> {
T map<T>(T f(E e)) => null;
}
@@ -4591,83 +4583,77 @@
expectIdentifierType(
'map((e) => 3);', 'T Function<T>(T Function(dynamic))');
- MethodInvocation m1 = findIdentifier('map((e) => e);').parent;
+ MethodInvocation m1 = findNode.methodInvocation('map((e) => e);');
expect(m1.staticInvokeType.toString(),
'dynamic Function(dynamic Function(dynamic))');
- MethodInvocation m2 = findIdentifier('map((e) => 3);').parent;
+ MethodInvocation m2 = findNode.methodInvocation('map((e) => 3);');
expect(
m2.staticInvokeType.toString(), 'int Function(int Function(dynamic))');
}
test_genericMethod_max_doubleDouble() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:math';
main() {
var foo = max(1.0, 2.0);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'double');
}
test_genericMethod_max_doubleDouble_prefixed() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:math' as math;
main() {
var foo = math.max(1.0, 2.0);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'double');
}
test_genericMethod_max_doubleInt() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:math';
main() {
var foo = max(1.0, 2);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'num');
}
test_genericMethod_max_intDouble() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:math';
main() {
var foo = max(1, 2.0);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'num');
}
test_genericMethod_max_intInt() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:math';
main() {
var foo = max(1, 2);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
test_genericMethod_nestedBound() async {
- String code = r'''
+ // Just validate that there is no warning on the call to `.abs()`.
+ await assertNoErrorsInCode(r'''
class Foo<T extends num> {
void method<U extends T>(U u) {
u.abs();
}
}
-''';
- // Just validate that there is no warning on the call to `.abs()`.
- await resolveTestUnit(code);
+''');
}
test_genericMethod_nestedCapture() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
T f<S>(S x) {
new C<S>().f<int>(3);
@@ -4676,7 +4662,7 @@
}
}
''');
- MethodInvocation f = findIdentifier('f<int>(3);').parent;
+ MethodInvocation f = findNode.methodInvocation('f<int>(3);');
expect(f.staticInvokeType.toString(), 'S Function(int)');
expectIdentifierType('f;', 'S Function<S₀>(S₀)');
@@ -4684,7 +4670,7 @@
@FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/30236')
test_genericMethod_nestedCaptureBounds() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
T f<S extends T>(S x) {
new C<S>().f<int>(3);
@@ -4693,7 +4679,7 @@
}
}
''');
- MethodInvocation f = findIdentifier('f<int>(3);').parent;
+ MethodInvocation f = findNode.methodInvocation('f<int>(3);');
expect(f.staticInvokeType.toString(), 'S Function(int)');
FunctionType ft = f.staticInvokeType;
expect('${ft.typeArguments}/${ft.typeParameters}',
@@ -4703,18 +4689,18 @@
}
test_genericMethod_nestedFunctions() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
S f<S>(S x) {
g<S>(S x) => f;
return null;
}
''');
- expectIdentifierType('f', 'S Function<S>(S)');
- expectIdentifierType('g', 'S Function<S>(S) Function<S>(S)');
+ expectIdentifierType('f<S>', 'S Function<S>(S)');
+ expectIdentifierType('g<S>', 'S Function<S>(S) Function<S>(S)');
}
test_genericMethod_override() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C {
T f<T>(T x) => null;
}
@@ -4724,14 +4710,14 @@
''');
expectFunctionType('f<T>(T x) => null; // from D', 'T Function<T>(T)',
elementTypeParams: '[T]', typeFormals: '[T]');
- SimpleIdentifier f = findIdentifier('f<T>(T x) => null; // from D');
+ SimpleIdentifier f = findNode.simple('f<T>(T x) => null; // from D');
MethodElementImpl e = f.staticElement;
FunctionType ft = e.type.instantiate([typeProvider.stringType]);
expect(ft.toString(), 'String Function(String)');
}
test_genericMethod_override_bounds() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class A {}
class B {
T f<T extends A>(T x) => null;
@@ -4748,7 +4734,7 @@
}
test_genericMethod_override_covariant_field() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
abstract class A {
num get x;
set x(covariant num _);
@@ -4758,13 +4744,10 @@
int x;
}
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
}
test_genericMethod_override_differentContextsSameBounds() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
class GenericMethodBounds<T> {
Type get t => T;
GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
@@ -4778,13 +4761,10 @@
new GenericMethodBounds<E>();
}
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
}
test_genericMethod_override_invalidContravariantTypeParamBounds() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class A {}
class B extends A {}
class C {
@@ -4792,14 +4772,13 @@
}
class D extends C {
T f<T extends B>(T x) => null;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- verify([source]);
+}''', [
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 101, 1),
+ ]);
}
test_genericMethod_override_invalidCovariantTypeParamBounds() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class A {}
class B extends A {}
class C {
@@ -4807,36 +4786,33 @@
}
class D extends C {
T f<T extends A>(T x) => null;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- verify([source]);
+}''', [
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 101, 1),
+ ]);
}
test_genericMethod_override_invalidReturnType() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class C {
Iterable<T> f<T>(T x) => null;
}
class D extends C {
String f<S>(S x) => null;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- verify([source]);
+}''', [
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 74, 1),
+ ]);
}
test_genericMethod_override_invalidTypeParamCount() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class C {
T f<T>(T x) => null;
}
class D extends C {
S f<T, S>(T x) => null;
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- verify([source]);
+}''', [
+ error(CompileTimeErrorCode.INVALID_OVERRIDE, 59, 1),
+ ]);
}
test_genericMethod_propagatedType_promotion() async {
@@ -4847,7 +4823,7 @@
// example won't work, as we now compute a static type and therefore discard
// the propagated type. So a new test was created that doesn't run under
// strong mode.
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
abstract class Iter {
List<S> map<S>(S f(x));
}
@@ -4862,7 +4838,7 @@
}
test_genericMethod_tearoff() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(E e) => null;
static T g<T>(T e) => null;
@@ -4894,7 +4870,7 @@
@failingTest
test_genericMethod_tearoff_instantiated() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
T f<T>(E e) => null;
static T g<T>(T e) => null;
@@ -4925,42 +4901,42 @@
}
test_genericMethod_then() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:async';
String toString(int x) => x.toString();
main() {
Future<int> bar = null;
var foo = bar.then(toString);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'Future<String>');
}
test_genericMethod_then_prefixed() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
import 'dart:async' as async;
String toString(int x) => x.toString();
main() {
async.Future<int> bar = null;
var foo = bar.then(toString);
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'Future<String>');
}
test_genericMethod_then_propagatedType() async {
// Regression test for https://github.com/dart-lang/sdk/issues/25482.
- String code = r'''
+ await assertErrorsInCode(r'''
import 'dart:async';
void main() {
Future<String> p;
var foo = p.then((r) => new Future<String>.value(3));
}
-''';
- await resolveTestUnit(code, noErrors: false);
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 61, 3),
+ error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 106, 1),
+ ]);
// Note: this correctly reports the error
// StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE when run with the driver;
// when run without the driver, it reports no errors. So we don't bother
@@ -4969,7 +4945,7 @@
}
test_genericMethod_toplevel_field_staticTearoff() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
static T g<T>(T e) => null;
static T Function<T>(T) h = null;
@@ -4983,7 +4959,7 @@
}
test_implicitBounds() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T> {}
class B<T extends num> {}
@@ -4999,8 +4975,7 @@
var bb = new B();
var cc = new C();
}
-''';
- await resolveTestUnit(code);
+''');
expectIdentifierType('ai', "A<dynamic>");
expectIdentifierType('bi', "B<num>");
expectIdentifierType('ci', "C<int, B<int>, A<dynamic>>");
@@ -5009,154 +4984,119 @@
expectIdentifierType('cc', "C<int, B<int>, A<dynamic>>");
}
- test_inferClosureType_parameters() async {
- Source source = addSource(r'''
-typedef F({bool p});
-foo(callback(F f)) {}
-main() {
- foo((f) {
- f(p: false);
- });
-}
-''');
- var result = await computeAnalysisResult(source);
- var main = result.unit.declarations[2] as FunctionDeclaration;
- var body = main.functionExpression.body as BlockFunctionBody;
- var statement = body.block.statements[0] as ExpressionStatement;
- var invocation = statement.expression as MethodInvocation;
- var closure = invocation.argumentList.arguments[0] as FunctionExpression;
- var closureType = closure.staticType as FunctionType;
- var fType = closureType.parameters[0].type as FunctionType;
- // The inferred type of "f" in "foo()" invocation must own its parameters.
- ParameterElement p = fType.parameters[0];
- expect(p.name, 'p');
- expect(p.enclosingElement, same(fType.element));
- }
-
test_instantiateToBounds_class_error_extension_malbounded() async {
// Test that superclasses are strictly checked for malbounded default
// types
- String code = r'''
+ await assertErrorsInCode(r'''
class C<T0 extends List<T1>, T1 extends List<T0>> {}
class D extends C {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(
- testSource, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+''', [
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 69, 1),
+ ]);
}
test_instantiateToBounds_class_error_instantiation_malbounded() async {
// Test that instance creations are strictly checked for malbounded default
// types
- String code = r'''
+ await assertErrorsInCode(r'''
class C<T0 extends List<T1>, T1 extends List<T0>> {}
void test() {
var c = new C();
}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.COULD_NOT_INFER,
- CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 73, 1),
+ error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 81, 1),
+ error(StrongModeCode.COULD_NOT_INFER, 81, 1),
]);
expectIdentifierType('c =', 'C<List<dynamic>, List<List<dynamic>>>');
}
test_instantiateToBounds_class_error_recursion() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C<T0 extends List<T1>, T1 extends List<T0>> {}
C c;
-''';
- await resolveTestUnit(code, noErrors: false);
- assertNoErrors(testSource);
+''', []);
+
expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>');
}
test_instantiateToBounds_class_error_recursion_self() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C<T extends C<T>> {}
C c;
-''';
- await resolveTestUnit(code, noErrors: false);
- assertNoErrors(testSource);
+''', []);
+
expectIdentifierType('c;', 'C<C<dynamic>>');
}
test_instantiateToBounds_class_error_recursion_self2() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<E> {}
class C<T extends A<T>> {}
C c;
-''';
- await resolveTestUnit(code, noErrors: false);
- assertNoErrors(testSource);
+''', []);
+
expectIdentifierType('c;', 'C<A<dynamic>>');
}
test_instantiateToBounds_class_error_typedef() async {
- String code = r'''
+ await assertErrorsInCode(r'''
typedef T F<T>(T x);
class C<T extends F<T>> {}
C c;
-''';
- await resolveTestUnit(code, noErrors: false);
- assertNoErrors(testSource);
+''', []);
+
expectIdentifierType('c;', 'C<dynamic Function(dynamic)>');
}
test_instantiateToBounds_class_ok_implicitDynamic_multi() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T0 extends Map<T1, T2>, T1 extends List, T2 extends int> {}
C c;
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType(
'c;', 'C<Map<List<dynamic>, int>, List<dynamic>, int>');
}
test_instantiateToBounds_class_ok_referenceOther_after() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T0 extends T1, T1 extends int> {}
C c;
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType('c;', 'C<int, int>');
}
test_instantiateToBounds_class_ok_referenceOther_after2() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T0 extends Map<T1, T1>, T1 extends int> {}
C c;
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType('c;', 'C<Map<int, int>, int>');
}
test_instantiateToBounds_class_ok_referenceOther_before() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T0 extends int, T1 extends T0> {}
C c;
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType('c;', 'C<int, int>');
}
test_instantiateToBounds_class_ok_referenceOther_multi() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T0 extends Map<T1, T2>, T1 extends List<T2>, T2 extends int> {}
C c;
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType('c;', 'C<Map<List<int>, int>, List<int>, int>');
}
test_instantiateToBounds_class_ok_simpleBounds() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T> {}
class B<T extends num> {}
class C<T extends List<int>> {}
@@ -5167,9 +5107,8 @@
C c;
D d;
}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectIdentifierType('a;', 'A<dynamic>');
expectIdentifierType('b;', 'B<num>');
expectIdentifierType('c;', 'C<List<int>>');
@@ -5179,21 +5118,22 @@
test_instantiateToBounds_generic_function_error_malbounded() async {
// Test that generic methods are strictly checked for malbounded default
// types
- String code = r'''
+ await assertErrorsInCode(r'''
T0 f<T0 extends List<T1>, T1 extends List<T0>>() {}
void g() {
var c = f();
return;
}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(
- testSource, [HintCode.MISSING_RETURN, StrongModeCode.COULD_NOT_INFER]);
+''', [
+ error(HintCode.MISSING_RETURN, 0, 2),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 69, 1),
+ error(StrongModeCode.COULD_NOT_INFER, 73, 1),
+ ]);
expectIdentifierType('c =', 'List<dynamic>');
}
test_instantiateToBounds_method_ok_referenceOther_before() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
void m<S0 extends T, S1 extends List<S0>>(S0 p0, S1 p1) {}
@@ -5201,14 +5141,13 @@
m(null, null);
}
}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectStaticInvokeType('m(null', 'void Function(Null, Null)');
}
test_instantiateToBounds_method_ok_referenceOther_before2() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
Map<S0, S1> m<S0 extends T, S1 extends List<S0>>() => null;
@@ -5216,14 +5155,13 @@
m();
}
}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectStaticInvokeType('m();', 'Map<T, List<T>> Function()');
}
test_instantiateToBounds_method_ok_simpleBounds() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
void m<S extends T>(S p0) {}
@@ -5231,14 +5169,13 @@
m(null);
}
}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectStaticInvokeType('m(null)', 'void Function(Null)');
}
test_instantiateToBounds_method_ok_simpleBounds2() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T> {
S m<S extends T>() => null;
@@ -5246,14 +5183,13 @@
m();
}
}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
+
expectStaticInvokeType('m();', 'T Function()');
}
test_issue32396() async {
- await resolveTestUnit(r'''
+ await assertNoErrorsInCode(r'''
class C<E> {
static T g<T>(T e) => null;
static final h = g;
@@ -5262,190 +5198,169 @@
}
test_notInstantiatedBound_class_error_recursion() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<T extends B> {} // points to a
class B<T extends A> {} // points to b
class C<T extends A> {} // points to a cyclical type
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND,
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 18, 1),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 57, 1),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 96, 1),
]);
}
test_notInstantiatedBound_class_error_recursion_less_direct() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<T extends B<A>> {}
class B<T extends A<B>> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND,
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 20, 1),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 47, 1),
]);
}
test_notInstantiatedBound_class_error_recursion_typedef() async {
- String code = r'''
+ await assertErrorsInCode(r'''
typedef F(C value);
class C<T extends F> {}
class D<T extends C> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+''', [
+ error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 19),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 38, 1),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 62, 1),
]);
}
test_notInstantiatedBound_error_class_argument() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends List<K>> {}
class C<T extends A> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 51, 1),
+ ]);
}
test_notInstantiatedBound_error_class_argument2() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends List<List<K>>> {}
class C<T extends A> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 57, 1),
+ ]);
}
test_notInstantiatedBound_error_class_direct() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends K> {}
class C<T extends A> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 45, 1),
+ ]);
}
test_notInstantiatedBound_error_class_indirect() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends K> {}
class C<T extends List<A>> {}
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 50, 1),
+ ]);
}
test_notInstantiatedBound_error_functionType() async {
- await resolveTestUnit(r'''
+ await assertErrorsInCode(r'''
class A<T extends Function(T)> {}
class B<T extends T Function()> {}
class C<T extends A> {}
class D<T extends B> {}
-''', noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 87, 1),
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 111, 1),
]);
}
test_notInstantiatedBound_error_typedef_argument() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends List<K>> {}
typedef void F<T extends A>();
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 58, 1),
+ ]);
}
test_notInstantiatedBound_error_typedef_argument2() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends List<List<K>>> {}
typedef void F<T extends A>();
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 64, 1),
+ ]);
}
test_notInstantiatedBound_error_typedef_direct() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class A<K, V extends K> {}
typedef void F<T extends A>();
-''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+''', [
+ error(StrongModeCode.NOT_INSTANTIATED_BOUND, 52, 1),
+ ]);
}
test_notInstantiatedBound_ok_class() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T extends int> {}
class C1<T extends A> {}
class C2<T extends List<A>> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_class_class2() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T> {}
class C<T extends A<int>> {}
class D<T extends C> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_class_class3() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T> {}
class B<T extends int> {}
class C<T extends A<B>> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_class_class4() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<K, V> {}
class B<T extends int> {}
class C<T extends A<B, B>> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_class_function() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class A<T extends void Function()> {}
class B<T extends A> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_class_typedef() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
typedef void F<T extends int>();
class C<T extends F> {}
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_notInstantiatedBound_ok_typedef_class() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C<T extends int> {}
typedef void F<T extends C>();
-''';
- await resolveTestUnit(code);
- assertNoErrors(testSource);
+''');
}
test_objectMethodOnFunctions_Anonymous() async {
- String code = r'''
+ await _objectMethodOnFunctions_helper2(r'''
void main() {
var f = (x) => 3;
// No errors, correct type
@@ -5467,12 +5382,11 @@
(f)..toString();
(f)..toString;
(f)..hashCode;
-}''';
- await _objectMethodOnFunctions_helper2(code);
+}''');
}
test_objectMethodOnFunctions_Function() async {
- String code = r'''
+ await _objectMethodOnFunctions_helper2(r'''
void main() {
Function f;
// No errors, correct type
@@ -5494,12 +5408,11 @@
(f)..toString();
(f)..toString;
(f)..hashCode;
-}''';
- await _objectMethodOnFunctions_helper2(code);
+}''');
}
test_objectMethodOnFunctions_Static() async {
- String code = r'''
+ await _objectMethodOnFunctions_helper2(r'''
int f(int x) => null;
void main() {
// No errors, correct type
@@ -5521,12 +5434,11 @@
(f)..toString();
(f)..toString;
(f)..hashCode;
-}''';
- await _objectMethodOnFunctions_helper2(code);
+}''');
}
test_objectMethodOnFunctions_Typedef() async {
- String code = r'''
+ await _objectMethodOnFunctions_helper2(r'''
typedef bool Predicate<T>(T object);
void main() {
@@ -5550,110 +5462,93 @@
(f)..toString();
(f)..toString;
(f)..hashCode;
-}''';
- await _objectMethodOnFunctions_helper2(code);
+}''');
}
test_returnOfInvalidType_object_void() async {
await assertErrorsInCode(
- "Object f() { void voidFn() => null; return voidFn(); }",
- [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+ "Object f() { void voidFn() => null; return voidFn(); }", [
+ error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 43, 8),
+ ]);
}
test_setterWithDynamicTypeIsError() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class A {
dynamic set f(String s) => null;
}
dynamic set g(int x) => null;
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+''', [
+ error(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, 12, 7),
+ error(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, 47, 7),
]);
- verify([source]);
}
test_setterWithExplicitVoidType_returningVoid() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
void returnsVoid() {}
class A {
void set f(String s) => returnsVoid();
}
void set g(int x) => returnsVoid();
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
}
test_setterWithNoVoidType() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class A {
set f(String s) {
return '42';
}
}
set g(int x) => 42;
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+''', [
+ error(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, 41, 4),
]);
- verify([source]);
}
test_setterWithNoVoidType_returningVoid() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
void returnsVoid() {}
class A {
set f(String s) => returnsVoid();
}
set g(int x) => returnsVoid();
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
}
test_setterWithOtherTypeIsError() async {
- Source source = addSource(r'''
+ await assertErrorsInCode(r'''
class A {
String set f(String s) => null;
}
Object set g(x) => null;
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
- StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+''', [
+ error(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, 12, 6),
+ error(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, 46, 6),
]);
- verify([source]);
}
test_ternaryOperator_null_left() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
var foo = (true) ? null : 3;
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
test_ternaryOperator_null_right() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
main() {
var foo = (true) ? 3 : null;
}
-''';
- await resolveTestUnit(code);
+''');
expectInitializerType('foo', 'int');
}
Future<void> _objectMethodOnFunctions_helper2(String code) async {
- await resolveTestUnit(code);
+ await assertNoErrorsInCode(code);
expectIdentifierType('t0', "String");
expectIdentifierType('t1', "String Function()");
expectIdentifierType('t2', "int");
@@ -5664,83 +5559,71 @@
}
@reflectiveTest
-class StrongModeTypePropagationTest extends ResolverTestCase {
- @override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- resetWith(options: options);
- }
-
+class StrongModeTypePropagationTest extends DriverResolutionTest {
test_foreachInference_dynamic_disabled() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var list = <int>[];
for (dynamic v in list) {
v; // marker
}
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+}''');
+ assertTypeDynamic(findNode.simple('v in'));
+ assertTypeDynamic(findNode.simple('v; // marker'));
}
test_foreachInference_reusedVar_disabled() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var list = <int>[];
var v;
for (v in list) {
v; // marker
}
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+}''');
+ assertTypeDynamic(findNode.simple('v in'));
+ assertTypeDynamic(findNode.simple('v; // marker'));
}
test_foreachInference_var() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var list = <int>[];
for (var v in list) {
v; // marker
}
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertPropagatedIterationType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v in'), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_foreachInference_var_iterable() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
Iterable<int> list = <int>[];
for (var v in list) {
v; // marker
}
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertPropagatedIterationType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v in'), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_foreachInference_var_stream() async {
- String code = r'''
+ await resolveTestCode(r'''
import 'dart:async';
main() async {
Stream<int> stream = null;
await for (var v in stream) {
v; // marker
}
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertPropagatedIterationType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v in'), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_inconsistentMethodInheritance_inferFunctionTypeFromTypedef() async {
- Source source = addSource(r'''
+ await assertNoErrorsInCode(r'''
typedef bool F<E>(E argument);
abstract class Base {
@@ -5756,58 +5639,51 @@
class C extends Override implements Base {}
''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
}
test_localVariableInference_bottom_disabled() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var v = null;
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.dynamicType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+}''');
+ assertTypeDynamic(findNode.simple('v ='));
+ assertTypeDynamic(findNode.simple('v; // marker'));
}
test_localVariableInference_constant() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var v = 3;
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_declaredType_disabled() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
dynamic v = 3;
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.dynamicType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+}''');
+ assertTypeDynamic(findNode.simple('v ='));
+ assertTypeDynamic(findNode.simple('v; // marker'));
}
test_localVariableInference_noInitializer_disabled() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var v;
v = 3;
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.dynamicType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+}''');
+ assertTypeDynamic(findNode.simple('v ='));
+ assertTypeDynamic(findNode.simple('v; // marker'));
}
test_localVariableInference_transitive_field_inferred_lexical() async {
- String code = r'''
+ await resolveTestCode(r'''
class A {
final x = 3;
f() {
@@ -5817,14 +5693,13 @@
}
main() {
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_field_inferred_reversed() async {
- String code = r'''
+ await resolveTestCode(r'''
class A {
f() {
var v = x;
@@ -5834,14 +5709,13 @@
}
main() {
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_field_lexical() async {
- String code = r'''
+ await resolveTestCode(r'''
class A {
int x = 3;
f() {
@@ -5851,14 +5725,13 @@
}
main() {
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_field_reversed() async {
- String code = r'''
+ await resolveTestCode(r'''
class A {
f() {
var v = x;
@@ -5868,85 +5741,78 @@
}
main() {
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_list_local() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var x = <int>[3];
var v = x[0];
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_local() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var x = 3;
var v = x;
v; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+}''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
- test_localVariableInference_transitive_toplevel_inferred_lexical() async {
- String code = r'''
+ test_localVariableInference_transitive_topLevel_inferred_lexical() async {
+ await resolveTestCode(r'''
final x = 3;
main() {
var v = x;
v; // marker
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
test_localVariableInference_transitive_toplevel_inferred_reversed() async {
- String code = r'''
+ await resolveTestCode(r'''
main() {
var v = x;
v; // marker
}
final x = 3;
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
- test_localVariableInference_transitive_toplevel_lexical() async {
- String code = r'''
+ test_localVariableInference_transitive_topLevel_lexical() async {
+ await resolveTestCode(r'''
int x = 3;
main() {
var v = x;
v; // marker
}
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
- test_localVariableInference_transitive_toplevel_reversed() async {
- String code = r'''
+ test_localVariableInference_transitive_topLevel_reversed() async {
+ await resolveTestCode(r'''
main() {
var v = x;
v; // marker
}
int x = 3;
-''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.intType);
- assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+''');
+ assertType(findNode.simple('v ='), 'int');
+ assertType(findNode.simple('v; // marker'), 'int');
}
}
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index f85b302..4b73b9c 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -2,107 +2,16 @@
// 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 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier;
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
-import 'test_analysis_context.dart';
-
-/// The class `EngineTestCase` defines utility methods for making assertions.
-class EngineTestCase {
- /// Return `true` if the fasta parser is being used.
- bool get usingFastaParser => Parser.useFasta;
-
- /// Assert that the given collection of [elements] has the same number of
- /// elements as the number of specified [names], and that for each specified
- /// name, a corresponding element can be found in the given collection with
- /// that name.
- void assertNamedElements(List<Element> elements, List<String> names) {
- for (String elemName in names) {
- bool found = false;
- for (Element elem in elements) {
- if (elem.name == elemName) {
- found = true;
- break;
- }
- }
- if (!found) {
- StringBuffer buffer = new StringBuffer();
- buffer.write("Expected element named: ");
- buffer.write(elemName);
- buffer.write("\n but found: ");
- for (Element elem in elements) {
- buffer.write(elem.name);
- buffer.write(", ");
- }
- fail(buffer.toString());
- }
- }
- expect(elements, hasLength(names.length));
- }
-
- AnalysisContext createAnalysisContext() {
- return TestAnalysisContext();
- }
-
- /// Return the getter in the given [type] with the given [name]. Inherited
- /// getters are ignored.
- PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
- for (PropertyAccessorElement accessor in type.element.accessors) {
- if (accessor.isGetter && accessor.name == getterName) {
- return accessor;
- }
- }
- fail("Could not find getter named $getterName in ${type.displayName}");
- }
-
- /// Return the method in the given [type] with the given [name]. Inherited
- /// methods are ignored.
- MethodElement getMethod(InterfaceType type, String methodName) {
- for (MethodElement method in type.element.methods) {
- if (method.name == methodName) {
- return method;
- }
- }
- fail("Could not find method named $methodName in ${type.displayName}");
- }
-
- void setUp() {}
-
- void tearDown() {}
-
- /// Return the [AstNode] with requested type at offset of the [prefix].
- static AstNode findNode(
- AstNode root, String code, String prefix, Predicate<AstNode> predicate) {
- int offset = code.indexOf(prefix);
- if (offset == -1) {
- throw new ArgumentError("Not found '$prefix'.");
- }
- AstNode node = new NodeLocator(offset).searchWithin(root);
- return node.thisOrAncestorMatching(predicate);
- }
-
- /// Find the [SimpleIdentifier] with at offset of the [prefix].
- static SimpleIdentifier findSimpleIdentifier(
- AstNode root, String code, String prefix) {
- int offset = code.indexOf(prefix);
- if (offset == -1) {
- throw new ArgumentError("Not found '$prefix'.");
- }
- return new NodeLocator(offset).searchWithin(root);
- }
-}
-
/// A description of an error that is expected to be reported.
class ExpectedError {
/// An empty array of error descriptors used when no errors are expected.
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 858c95e..d5f31a8 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,8 +2,6 @@
// 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:collection';
-
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
@@ -18,7 +16,6 @@
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -31,12 +28,9 @@
defineReflectiveTests(BooleanArrayTest);
defineReflectiveTests(ExceptionHandlingDelegatingAstVisitorTest);
defineReflectiveTests(LineInfoTest);
- defineReflectiveTests(MultipleMapIteratorTest);
defineReflectiveTests(NodeReplacerTest);
- defineReflectiveTests(SingleMapIteratorTest);
defineReflectiveTests(SourceRangeTest);
defineReflectiveTests(StringUtilitiesTest);
- defineReflectiveTests(TokenMapTest);
});
}
@@ -69,7 +63,7 @@
}
@reflectiveTest
-class AstClonerTest extends EngineTestCase {
+class AstClonerTest {
void test_visitAdjacentStrings() {
_assertCloneExpression("'a' 'b'");
}
@@ -1337,7 +1331,7 @@
}
@reflectiveTest
-class ExceptionHandlingDelegatingAstVisitorTest extends EngineTestCase {
+class ExceptionHandlingDelegatingAstVisitorTest {
void test_handlerIsCalled() {
AstVisitor exceptionThrowingVisitor = new _ExceptionThrowingVisitor();
bool handlerInvoked = false;
@@ -2608,113 +2602,7 @@
}
@reflectiveTest
-class MultipleMapIteratorTest extends EngineTestCase {
- void test_multipleMaps_firstEmpty() {
- Map<String, String> map1 = new HashMap<String, String>();
- Map<String, String> map2 = new HashMap<String, String>();
- map2["k2"] = "v2";
- Map<String, String> map3 = new HashMap<String, String>();
- map3["k3"] = "v3";
- MultipleMapIterator<String, String> iterator =
- _iterator([map1, map2, map3]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_multipleMaps_lastEmpty() {
- Map<String, String> map1 = new HashMap<String, String>();
- map1["k1"] = "v1";
- Map<String, String> map2 = new HashMap<String, String>();
- map2["k2"] = "v2";
- Map<String, String> map3 = new HashMap<String, String>();
- MultipleMapIterator<String, String> iterator =
- _iterator([map1, map2, map3]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_multipleMaps_middleEmpty() {
- Map<String, String> map1 = new HashMap<String, String>();
- map1["k1"] = "v1";
- Map<String, String> map2 = new HashMap<String, String>();
- Map<String, String> map3 = new HashMap<String, String>();
- map3["k3"] = "v3";
- MultipleMapIterator<String, String> iterator =
- _iterator([map1, map2, map3]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_multipleMaps_nonEmpty() {
- Map<String, String> map1 = new HashMap<String, String>();
- map1["k1"] = "v1";
- Map<String, String> map2 = new HashMap<String, String>();
- map2["k2"] = "v2";
- Map<String, String> map3 = new HashMap<String, String>();
- map3["k3"] = "v3";
- MultipleMapIterator<String, String> iterator =
- _iterator([map1, map2, map3]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_noMap() {
- MultipleMapIterator<String, String> iterator = _iterator([]);
- expect(iterator.moveNext(), isFalse);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_singleMap_empty() {
- Map<String, String> map = new HashMap<String, String>();
- MultipleMapIterator<String, String> iterator = _iterator([map]);
- expect(iterator.moveNext(), isFalse);
- expect(() => iterator.key, throwsStateError);
- expect(() => iterator.value, throwsStateError);
- expect(() {
- iterator.value = 'x';
- }, throwsStateError);
- }
-
- void test_singleMap_multiple() {
- Map<String, String> map = new HashMap<String, String>();
- map["k1"] = "v1";
- map["k2"] = "v2";
- map["k3"] = "v3";
- MultipleMapIterator<String, String> iterator = _iterator([map]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_singleMap_single() {
- String key = "key";
- String value = "value";
- Map<String, String> map = new HashMap<String, String>();
- map[key] = value;
- MultipleMapIterator<String, String> iterator = _iterator([map]);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.key, same(key));
- expect(iterator.value, same(value));
- String newValue = "newValue";
- iterator.value = newValue;
- expect(iterator.value, same(newValue));
- expect(iterator.moveNext(), isFalse);
- }
-
- MultipleMapIterator<String, String> _iterator(
- List<Map<String, String>> maps) {
- return new MultipleMapIterator<String, String>(maps);
- }
-}
-
-@reflectiveTest
-class NodeReplacerTest extends EngineTestCase {
+class NodeReplacerTest {
/**
* An empty list of tokens.
*/
@@ -3700,51 +3588,6 @@
}
@reflectiveTest
-class SingleMapIteratorTest extends EngineTestCase {
- void test_empty() {
- Map<String, String> map = new HashMap<String, String>();
- SingleMapIterator<String, String> iterator =
- new SingleMapIterator<String, String>(map);
- expect(iterator.moveNext(), isFalse);
- expect(() => iterator.key, throwsStateError);
- expect(() => iterator.value, throwsStateError);
- expect(() {
- iterator.value = 'x';
- }, throwsStateError);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_multiple() {
- Map<String, String> map = new HashMap<String, String>();
- map["k1"] = "v1";
- map["k2"] = "v2";
- map["k3"] = "v3";
- SingleMapIterator<String, String> iterator =
- new SingleMapIterator<String, String>(map);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.moveNext(), isFalse);
- }
-
- void test_single() {
- String key = "key";
- String value = "value";
- Map<String, String> map = new HashMap<String, String>();
- map[key] = value;
- SingleMapIterator<String, String> iterator =
- new SingleMapIterator<String, String>(map);
- expect(iterator.moveNext(), isTrue);
- expect(iterator.key, same(key));
- expect(iterator.value, same(value));
- String newValue = "newValue";
- iterator.value = newValue;
- expect(iterator.value, same(newValue));
- expect(iterator.moveNext(), isFalse);
- }
-}
-
-@reflectiveTest
class SourceRangeTest {
void test_access() {
SourceRange r = new SourceRange(10, 1);
@@ -4148,26 +3991,6 @@
}
}
-@reflectiveTest
-class TokenMapTest {
- void test_creation() {
- expect(new TokenMap(), isNotNull);
- }
-
- void test_get_absent() {
- TokenMap tokenMap = new TokenMap();
- expect(tokenMap.get(TokenFactory.tokenFromType(TokenType.AT)), isNull);
- }
-
- void test_get_added() {
- TokenMap tokenMap = new TokenMap();
- Token key = TokenFactory.tokenFromType(TokenType.AT);
- Token value = TokenFactory.tokenFromType(TokenType.AT);
- tokenMap.put(key, value);
- expect(tokenMap.get(key), same(value));
- }
-}
-
class _ExceptionThrowingVisitor extends SimpleAstVisitor {
visitNullLiteral(NullLiteral node) {
throw new ArgumentError('');
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index cc22d22..03fb7a6 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -31,7 +31,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../embedder_tests.dart';
-import '../../generated/test_support.dart';
main() {
defineReflectiveSuite(() {
@@ -41,7 +40,7 @@
}
@reflectiveTest
-class ContextBuilderTest extends EngineTestCase with ResourceProviderMixin {
+class ContextBuilderTest with ResourceProviderMixin {
/**
* The SDK manager used by the tests;
*/
@@ -93,7 +92,6 @@
options: builderOptions);
}
- @override
void setUp() {
new MockSdk(resourceProvider: resourceProvider);
sdkManager = new DartSdkManager(convertPath('/sdk'), false);
@@ -533,6 +531,68 @@
expect(packageSource.fullName, join(packageA, 'a.dart'));
}
+ void test_createWorkspace_hasPackagesFile_hasDartToolAndPubspec() {
+ newFile('/workspace/.packages');
+ newFolder('/workspace/.dart_tool/build/generated/project/lib');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<PackageBuildWorkspace>());
+ }
+
+ void test_createWorkspace_hasPackagesFile_hasPubspec() {
+ newFile('/workspace/.packages');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<PubWorkspace>());
+ }
+
+ void test_createWorkspace_hasPackagesFile_noMarkerFiles() {
+ newFile('/workspace/.packages');
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<BasicWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasBazelMarkerFiles() {
+ newFile('/workspace/WORKSPACE');
+ newFolder('/workspace/bazel-genfiles');
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<BazelWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasDartToolAndPubspec() {
+ newFolder('/workspace/.dart_tool/build/generated/project/lib');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<PackageBuildWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasGnMarkerFiles() {
+ newFolder('/workspace/.jiri_root');
+ newFile(
+ '/workspace/out/debug-x87_128/dartlang/gen/project/lib/lib.packages');
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<GnWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasPubspec() {
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<PubWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_noMarkerFiles() {
+ Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+ convertPath('/workspace/project/lib/lib.dart'), builder);
+ expect(workspace, TypeMatcher<BasicWorkspace>());
+ }
+
void test_declareVariables_emptyMap() {
AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
Iterable<String> expected = context.declaredVariables.variableNames;
@@ -857,68 +917,6 @@
expect(result.path, filePath);
}
- void test_createWorkspace_hasPackagesFile_hasDartToolAndPubspec() {
- newFile('/workspace/.packages');
- newFolder('/workspace/.dart_tool/build/generated/project/lib');
- newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<PackageBuildWorkspace>());
- }
-
- void test_createWorkspace_hasPackagesFile_hasPubspec() {
- newFile('/workspace/.packages');
- newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<PubWorkspace>());
- }
-
- void test_createWorkspace_hasPackagesFile_noMarkerFiles() {
- newFile('/workspace/.packages');
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<BasicWorkspace>());
- }
-
- void test_createWorkspace_noPackagesFile_hasDartToolAndPubspec() {
- newFolder('/workspace/.dart_tool/build/generated/project/lib');
- newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<PackageBuildWorkspace>());
- }
-
- void test_createWorkspace_noPackagesFile_hasPubspec() {
- newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<PubWorkspace>());
- }
-
- void test_createWorkspace_noPackagesFile_noMarkerFiles() {
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<BasicWorkspace>());
- }
-
- void test_createWorkspace_noPackagesFile_hasGnMarkerFiles() {
- newFolder('/workspace/.jiri_root');
- newFile(
- '/workspace/out/debug-x87_128/dartlang/gen/project/lib/lib.packages');
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<GnWorkspace>());
- }
-
- void test_createWorkspace_noPackagesFile_hasBazelMarkerFiles() {
- newFile('/workspace/WORKSPACE');
- newFolder('/workspace/bazel-genfiles');
- Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
- convertPath('/workspace/project/lib/lib.dart'), builder);
- expect(workspace, TypeMatcher<BazelWorkspace>());
- }
-
_defineMockLintRules() {
_mockLintRule = new _MockLintRule('mock_lint_rule');
Registry.ruleRegistry.register(_mockLintRule);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index dc8f58b..ef0509e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -293,6 +293,8 @@
Monitor idleStatusMonitor = new Monitor();
List<AnalysisStatus> allStatuses = [];
+ // awaiting times out.
+ // ignore: unawaited_futures
scheduler.status.forEach((status) {
allStatuses.add(status);
if (status.isIdle) {
@@ -322,6 +324,8 @@
Monitor idleStatusMonitor = new Monitor();
List<AnalysisStatus> allStatuses = [];
+ // awaiting times out.
+ // ignore: unawaited_futures
scheduler.status.forEach((status) {
allStatuses.add(status);
if (status.isIdle) {
@@ -2300,7 +2304,7 @@
expect(driver.hasFilesToAnalyze, isFalse);
// Request of referenced names is not analysis of a file.
- driver.getFilesReferencingName('X');
+ await driver.getFilesReferencingName('X');
expect(driver.hasFilesToAnalyze, isFalse);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/results_test.dart b/pkg/analyzer/test/src/dart/analysis/results_test.dart
index 030194c..9d9c4ed 100644
--- a/pkg/analyzer/test/src/dart/analysis/results_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/results_test.dart
@@ -30,11 +30,9 @@
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
test_extension() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
extension E on int {}
''');
- await resolveTestFile();
-
var element = findNode.extensionDeclaration('E').declaredElement;
var result = await getElementDeclaration(element);
ExtensionDeclaration node = result.node;
@@ -46,11 +44,9 @@
Future<ElementDeclarationResult> getElementDeclaration(Element element);
test_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
''');
- await resolveTestFile();
-
var element = findNode.classDeclaration('A').declaredElement;
var result = await getElementDeclaration(element);
ClassDeclaration node = result.node;
@@ -58,12 +54,10 @@
}
test_class_duplicate() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {} // 1
class A {} // 2
''');
- await resolveTestFile();
-
{
var element = findNode.classDeclaration('A {} // 1').declaredElement;
var result = await getElementDeclaration(element);
@@ -92,11 +86,9 @@
part of 'test.dart';
class A {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
part 'a.dart';
''');
- await resolveTestFile();
-
var library = this.result.unit.declaredElement.library;
var element = library.getType('A');
var result = await getElementDeclaration(element);
@@ -105,11 +97,9 @@
}
test_class_missingName() async {
- addTestFile('''
+ await resolveTestCode('''
class {}
''');
- await resolveTestFile();
-
var element = findNode.classDeclaration('class {}').declaredElement;
var result = await getElementDeclaration(element);
ClassDeclaration node = result.node;
@@ -118,13 +108,11 @@
}
test_classTypeAlias() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
mixin M {}
class A {}
class B = A with M;
''');
- await resolveTestFile();
-
var element = findElement.class_('B');
var result = await getElementDeclaration(element);
ClassTypeAlias node = result.node;
@@ -132,14 +120,12 @@
}
test_constructor() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A();
A.named();
}
''');
- await resolveTestFile();
-
{
var unnamed = findNode.constructor('A();').declaredElement;
var result = await getElementDeclaration(unnamed);
@@ -156,14 +142,12 @@
}
test_constructor_duplicate_named() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A.named(); // 1
A.named(); // 2
}
''');
- await resolveTestFile();
-
{
var element = findNode.constructor('A.named(); // 1').declaredElement;
var result = await getElementDeclaration(element);
@@ -188,14 +172,12 @@
}
test_constructor_duplicate_unnamed() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A(); // 1
A(); // 2
}
''');
- await resolveTestFile();
-
{
var element = findNode.constructor('A(); // 1').declaredElement;
var result = await getElementDeclaration(element);
@@ -220,11 +202,9 @@
}
test_constructor_synthetic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
''');
- await resolveTestFile();
-
var element = findElement.class_('A').unnamedConstructor;
expect(element.isSynthetic, isTrue);
@@ -233,11 +213,9 @@
}
test_enum() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum MyEnum {a, b, c}
''');
- await resolveTestFile();
-
var element = findElement.enum_('MyEnum');
var result = await getElementDeclaration(element);
EnumDeclaration node = result.node;
@@ -245,11 +223,9 @@
}
test_enum_constant() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum MyEnum {a, b, c}
''');
- await resolveTestFile();
-
var element = findElement.field('a');
var result = await getElementDeclaration(element);
EnumConstantDeclaration node = result.node;
@@ -257,13 +233,11 @@
}
test_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int foo;
}
''');
- await resolveTestFile();
-
var element = findElement.field('foo');
var result = await getElementDeclaration(element);
@@ -272,13 +246,11 @@
}
test_functionDeclaration_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo() {}
}
''');
- await resolveTestFile();
-
var element = findElement.localFunction('foo');
var result = await getElementDeclaration(element);
@@ -287,11 +259,9 @@
}
test_functionDeclaration_top() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo() {}
''');
- await resolveTestFile();
-
var element = findElement.topFunction('foo');
var result = await getElementDeclaration(element);
@@ -300,13 +270,11 @@
}
test_getter_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get x => 0;
}
''');
- await resolveTestFile();
-
var element = findElement.getter('x');
var result = await getElementDeclaration(element);
MethodDeclaration node = result.node;
@@ -315,11 +283,9 @@
}
test_getter_top() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int get x => 0;
''');
- await resolveTestFile();
-
var element = findElement.topGet('x');
var result = await getElementDeclaration(element);
FunctionDeclaration node = result.node;
@@ -328,13 +294,11 @@
}
test_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int foo;
}
''');
- await resolveTestFile();
-
var element = findElement.localVar('foo');
var result = await getElementDeclaration(element);
@@ -343,13 +307,11 @@
}
test_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void foo() {}
}
''');
- await resolveTestFile();
-
var element = findElement.method('foo');
var result = await getElementDeclaration(element);
@@ -358,11 +320,9 @@
}
test_mixin() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
mixin M {}
''');
- await resolveTestFile();
-
var element = findElement.mixin('M');
var result = await getElementDeclaration(element);
MixinDeclaration node = result.node;
@@ -370,11 +330,9 @@
}
test_parameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f(int a) {}
''');
- await resolveTestFile();
-
var element = findElement.parameter('a');
var result = await getElementDeclaration(element);
@@ -383,11 +341,9 @@
}
test_parameter_missingName_named() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f({@a}) {}
''');
- await resolveTestFile();
-
var f = findElement.topFunction('f');
var element = f.parameters.single;
expect(element.name, '');
@@ -399,11 +355,9 @@
}
test_parameter_missingName_required() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f(@a) {}
''');
- await resolveTestFile();
-
var f = findElement.topFunction('f');
var element = f.parameters.single;
expect(element.name, '');
@@ -415,13 +369,11 @@
}
test_setter_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
set x(_) {}
}
''');
- await resolveTestFile();
-
var element = findElement.setter('x');
var result = await getElementDeclaration(element);
MethodDeclaration node = result.node;
@@ -430,11 +382,9 @@
}
test_setter_top() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
set x(_) {}
''');
- await resolveTestFile();
-
var element = findElement.topSet('x');
var result = await getElementDeclaration(element);
FunctionDeclaration node = result.node;
@@ -443,11 +393,9 @@
}
test_topLevelVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int foo;
''');
- await resolveTestFile();
-
var element = findElement.topVar('foo');
var result = await getElementDeclaration(element);
@@ -456,11 +404,9 @@
}
test_topLevelVariable_synthetic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int get foo => 0;
''');
- await resolveTestFile();
-
var element = findElement.topVar('foo');
var result = await getElementDeclaration(element);
diff --git a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
index 7316c24..2a39d97 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
@@ -76,11 +76,9 @@
}
test_getElementDeclaration_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
''');
- await resolveTestFile();
-
var element = findElement.class_('A');
var result = await helper.getElementDeclaration(element);
ClassDeclaration node = result.node;
@@ -88,12 +86,10 @@
}
test_getResolvedUnitByElement() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B {}
''');
- await resolveTestFile();
-
var element = findNode.classDeclaration('A').declaredElement;
var resolvedUnit = await helper.getResolvedUnitByElement(element);
expect(resolvedUnit.unit.declarations, hasLength(2));
diff --git a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
index e7e1ac1..f63cc86 100644
--- a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
@@ -2,8 +2,6 @@
// 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';
-
import 'package:analyzer/src/dart/ast/element_locator.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test/test.dart';
@@ -26,7 +24,7 @@
}
test_locate_AssignmentExpression() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
int x = 0;
void main() {
x += 1;
@@ -38,21 +36,21 @@
}
test_locate_BinaryExpression() async {
- await _resolveTestCode('var x = 3 + 4');
+ await resolveTestCode('var x = 3 + 4');
var node = findNode.binary('+');
var element = ElementLocator.locate(node);
expect(element, isMethodElement);
}
test_locate_ClassDeclaration() async {
- await _resolveTestCode('class A {}');
+ await resolveTestCode('class A {}');
var node = findNode.classDeclaration('class');
var element = ElementLocator.locate(node);
expect(element, isClassElement);
}
test_locate_CompilationUnit() async {
- await _resolveTestCode('// only comment');
+ await resolveTestCode('// only comment');
var unitElement = result.unit.declaredElement;
expect(unitElement, isNotNull);
@@ -62,7 +60,7 @@
}
test_locate_ConstructorDeclaration() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {
A.foo();
}
@@ -73,21 +71,21 @@
}
test_locate_ExportDirective() async {
- await _resolveTestCode("export 'dart:code';");
+ await resolveTestCode("export 'dart:code';");
var node = findNode.export('export');
var element = ElementLocator.locate(node);
expect(element, isExportElement);
}
test_locate_FunctionDeclaration() async {
- await _resolveTestCode('int f() => 3;');
+ await resolveTestCode('int f() => 3;');
var node = findNode.functionDeclaration('f');
var element = ElementLocator.locate(node);
expect(element, isFunctionElement);
}
test_locate_Identifier_annotationClass_namedConstructor() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class Class {
const Class.name();
}
@@ -99,7 +97,7 @@
}
test_locate_Identifier_annotationClass_unnamedConstructor() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class Class {
const Class();
}
@@ -111,14 +109,14 @@
}
test_locate_Identifier_className() async {
- await _resolveTestCode('class A {}');
+ await resolveTestCode('class A {}');
var node = findNode.simple('A');
var element = ElementLocator.locate(node);
expect(element, isClassElement);
}
test_locate_Identifier_constructor_named() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {
A.bar();
}
@@ -129,7 +127,7 @@
}
test_locate_Identifier_constructor_unnamed() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {
A();
}
@@ -140,7 +138,7 @@
}
test_locate_Identifier_fieldName() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
class A {
var x;
}
@@ -151,14 +149,14 @@
}
test_locate_Identifier_libraryDirective() async {
- await _resolveTestCode('library foo.bar;');
+ await resolveTestCode('library foo.bar;');
var node = findNode.simple('foo');
var element = ElementLocator.locate(node);
expect(element, isLibraryElement);
}
test_locate_Identifier_propertyAccess() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
void main() {
int x = 'foo'.length;
}
@@ -169,14 +167,14 @@
}
test_locate_ImportDirective() async {
- await _resolveTestCode("import 'dart:core';");
+ await resolveTestCode("import 'dart:core';");
var node = findNode.import('import');
var element = ElementLocator.locate(node);
expect(element, isImportElement);
}
test_locate_IndexExpression() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
void main() {
var x = [1, 2];
var y = x[0];
@@ -188,7 +186,7 @@
}
test_locate_InstanceCreationExpression() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {}
void main() {
@@ -204,7 +202,7 @@
newFile('/test/lib/a.dart', content: r'''
class A {}
''');
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
import 'a.dart' as pref;
void main() {
@@ -219,7 +217,7 @@
test_locate_InstanceCreationExpression_type_simpleIdentifier() async {
newFile('/test/lib/a.dart', content: r'''
''');
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {}
void main() {
@@ -232,14 +230,14 @@
}
test_locate_LibraryDirective() async {
- await _resolveTestCode('library foo;');
+ await resolveTestCode('library foo;');
var node = findNode.library('library');
var element = ElementLocator.locate(node);
expect(element, isLibraryElement);
}
test_locate_MethodDeclaration() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {
void foo() {}
}
@@ -250,7 +248,7 @@
}
test_locate_MethodInvocation_method() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
class A {
void foo() {}
}
@@ -265,7 +263,7 @@
}
test_locate_MethodInvocation_topLevel() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
foo(x) {}
void main() {
@@ -289,21 +287,21 @@
driver.addFile(libPath);
driver.addFile(partPath);
- await _resolveTestCode('part of my.lib;');
+ await resolveTestCode('part of my.lib;');
var node = findNode.partOf('part of');
var element = ElementLocator.locate(node);
expect(element, isLibraryElement);
}
test_locate_PostfixExpression() async {
- await _resolveTestCode('int addOne(int x) => x++;');
+ await resolveTestCode('int addOne(int x) => x++;');
var node = findNode.postfix('x++');
var element = ElementLocator.locate(node);
expect(element, isMethodElement);
}
test_locate_PrefixedIdentifier() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
import 'dart:core' as core;
core.int value;
''');
@@ -313,7 +311,7 @@
}
test_locate_PrefixExpression() async {
- await _resolveTestCode('int addOne(int x) => ++x;');
+ await resolveTestCode('int addOne(int x) => ++x;');
var node = findNode.prefix('++x');
var element = ElementLocator.locate(node);
expect(element, isMethodElement);
@@ -321,14 +319,14 @@
test_locate_StringLiteral_exportUri() async {
newFile("/test/lib/foo.dart", content: '');
- await _resolveTestCode("export 'foo.dart';");
+ await resolveTestCode("export 'foo.dart';");
var node = findNode.stringLiteral('foo.dart');
var element = ElementLocator.locate(node);
expect(element, isLibraryElement);
}
test_locate_StringLiteral_expression() async {
- await _resolveTestCode("var x = 'abc';");
+ await resolveTestCode("var x = 'abc';");
var node = findNode.stringLiteral('abc');
var element = ElementLocator.locate(node);
expect(element, isNull);
@@ -336,7 +334,7 @@
test_locate_StringLiteral_importUri() async {
newFile("/test/lib/foo.dart", content: '');
- await _resolveTestCode("import 'foo.dart';");
+ await resolveTestCode("import 'foo.dart';");
var node = findNode.stringLiteral('foo.dart');
var element = ElementLocator.locate(node);
expect(element, isLibraryElement);
@@ -344,7 +342,7 @@
test_locate_StringLiteral_partUri() async {
newFile("/test/lib/foo.dart", content: 'part of lib;');
- await _resolveTestCode('''
+ await resolveTestCode('''
library lib;
part 'foo.dart';
@@ -355,14 +353,9 @@
}
test_locate_VariableDeclaration() async {
- await _resolveTestCode('var x = 42;');
+ await resolveTestCode('var x = 42;');
var node = findNode.variableDeclaration('x =');
var element = ElementLocator.locate(node);
expect(element, isTopLevelVariableElement);
}
-
- Future<void> _resolveTestCode(String code) async {
- addTestFile(code);
- await resolveTestFile();
- }
}
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 88f8e7a..676ada5 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -21,7 +21,6 @@
import '../../../generated/elements_types_mixin.dart';
import '../../../generated/parser_test.dart' show ParserTestCase;
-import '../../../generated/test_support.dart';
import '../../../util/ast_type_matchers.dart';
main() {
@@ -922,7 +921,7 @@
}
@reflectiveTest
-class ToSourceVisitor2Test extends EngineTestCase {
+class ToSourceVisitor2Test {
void test_visitAdjacentStrings() {
_assertSource(
"'a' 'b'",
@@ -3738,7 +3737,7 @@
@deprecated
@reflectiveTest
-class ToSourceVisitorTest extends EngineTestCase {
+class ToSourceVisitorTest {
void test_visitAdjacentStrings() {
_assertSource(
"'a' 'b'",
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 8d0b13e..2abcaba 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
@@ -28,7 +27,7 @@
@reflectiveTest
class ConstantVisitorTest extends ConstantVisitorTestSupport {
test_visitBinaryExpression_questionQuestion_eager_notNull_notNull() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 'a' ?? 'b';
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -37,7 +36,7 @@
}
test_visitBinaryExpression_questionQuestion_eager_null_notNull() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ?? 'b';
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -46,7 +45,7 @@
}
test_visitBinaryExpression_questionQuestion_eager_null_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ?? null;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -54,7 +53,7 @@
}
test_visitConditionalExpression_eager_false_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false ? 1 : 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -63,7 +62,7 @@
}
test_visitConditionalExpression_eager_invalid_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ? 1 : 0;
''');
DartObjectImpl result = _evaluateConstant(
@@ -74,7 +73,7 @@
}
test_visitConditionalExpression_eager_true_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? 1 : 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -83,7 +82,7 @@
}
test_visitConditionalExpression_eager_true_int_invalid() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? 1 : x;
''');
DartObjectImpl result = _evaluateConstant(
@@ -98,7 +97,7 @@
}
test_visitConditionalExpression_eager_true_invalid_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? x : 0;
''');
DartObjectImpl result = _evaluateConstant(
@@ -109,7 +108,7 @@
}
test_visitIntegerLiteral() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const double d = 3;
''');
DartObjectImpl result = _evaluateConstant('d');
@@ -118,7 +117,7 @@
}
test_visitSimpleIdentifier_className() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = C;
class C {}
''');
@@ -128,7 +127,7 @@
}
test_visitSimpleIdentifier_dynamic() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = dynamic;
''');
DartObjectImpl result = _evaluateConstant('a');
@@ -137,7 +136,7 @@
}
test_visitSimpleIdentifier_inEnvironment() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
const a = b;
const b = 3;''');
var environment = <String, DartObjectImpl>{
@@ -149,7 +148,7 @@
}
test_visitSimpleIdentifier_notInEnvironment() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
const a = b;
const b = 3;''');
var environment = <String, DartObjectImpl>{
@@ -161,7 +160,7 @@
}
test_visitSimpleIdentifier_withoutEnvironment() async {
- await _resolveTestCode(r'''
+ await resolveTestCode(r'''
const a = b;
const b = 3;''');
var result = _evaluateConstant('a');
@@ -202,12 +201,6 @@
}
return result;
}
-
- Future<CompilationUnit> _resolveTestCode(String code) async {
- addTestFile(code);
- await resolveTestFile();
- return result.unit;
- }
}
@reflectiveTest
@@ -221,7 +214,7 @@
];
test_visitAsExpression_instanceOfSameClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a as A;
class A {
@@ -234,7 +227,7 @@
}
test_visitAsExpression_instanceOfSubclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const B();
const b = a as A;
class A {
@@ -250,7 +243,7 @@
}
test_visitAsExpression_instanceOfSuperclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a as B;
class A {
@@ -266,7 +259,7 @@
}
test_visitAsExpression_instanceOfUnrelatedClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a as B;
class A {
@@ -282,7 +275,7 @@
}
test_visitAsExpression_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a as A;
class A {}
@@ -305,7 +298,7 @@
}
test_visitBinaryExpression_and_bool_known_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false & true;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -313,7 +306,7 @@
}
test_visitBinaryExpression_and_bool_known_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const b = bool.fromEnvironment('y');
const c = false & b;
''');
@@ -322,7 +315,7 @@
}
test_visitBinaryExpression_and_bool_unknown_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const c = a & true;
''');
@@ -331,7 +324,7 @@
}
test_visitBinaryExpression_and_bool_unknown_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const b = bool.fromEnvironment('y');
const c = a & b;
@@ -341,7 +334,7 @@
}
test_visitBinaryExpression_and_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 & 5;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -349,7 +342,7 @@
}
test_visitBinaryExpression_and_mixed() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 & false;
''');
_evaluateConstant('c',
@@ -357,7 +350,7 @@
}
test_visitBinaryExpression_gtGtGt_negative_fewerBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFFFFFFFF >>> 8;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -366,7 +359,7 @@
}
test_visitBinaryExpression_gtGtGt_negative_moreBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFFFFFFFF >>> 33;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -375,7 +368,7 @@
}
test_visitBinaryExpression_gtGtGt_negative_moreThan64Bits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFFFFFFFF >>> 65;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -384,7 +377,7 @@
}
test_visitBinaryExpression_gtGtGt_negative_negativeBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFFFFFFFF >>> -2;
''');
_evaluateConstant('c',
@@ -392,7 +385,7 @@
}
test_visitBinaryExpression_gtGtGt_negative_zeroBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFFFFFFFF >>> 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -401,7 +394,7 @@
}
test_visitBinaryExpression_gtGtGt_positive_fewerBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFF >>> 3;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -410,7 +403,7 @@
}
test_visitBinaryExpression_gtGtGt_positive_moreBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFF >>> 9;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -419,7 +412,7 @@
}
test_visitBinaryExpression_gtGtGt_positive_moreThan64Bits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFF >>> 65;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -428,7 +421,7 @@
}
test_visitBinaryExpression_gtGtGt_positive_negativeBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFF >>> -2;
''');
_evaluateConstant('c',
@@ -436,7 +429,7 @@
}
test_visitBinaryExpression_gtGtGt_positive_zeroBits() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 0xFF >>> 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -445,7 +438,7 @@
}
test_visitBinaryExpression_or_bool_known_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false | true;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -453,7 +446,7 @@
}
test_visitBinaryExpression_or_bool_known_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const b = bool.fromEnvironment('y');
const c = false | b;
''');
@@ -462,7 +455,7 @@
}
test_visitBinaryExpression_or_bool_unknown_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const c = a | true;
''');
@@ -471,7 +464,7 @@
}
test_visitBinaryExpression_or_bool_unknown_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const b = bool.fromEnvironment('y');
const c = a | b;
@@ -481,7 +474,7 @@
}
test_visitBinaryExpression_or_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 | 5;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -489,7 +482,7 @@
}
test_visitBinaryExpression_or_mixed() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 | false;
''');
_evaluateConstant('c',
@@ -497,7 +490,7 @@
}
test_visitBinaryExpression_questionQuestion_lazy_notNull_invalid() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 'a' ?? new C();
class C {}
''');
@@ -507,7 +500,7 @@
}
test_visitBinaryExpression_questionQuestion_lazy_notNull_notNull() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 'a' ?? 'b';
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -516,7 +509,7 @@
}
test_visitBinaryExpression_questionQuestion_lazy_null_invalid() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ?? new C();
class C {}
''');
@@ -524,7 +517,7 @@
}
test_visitBinaryExpression_questionQuestion_lazy_null_notNull() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ?? 'b';
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -533,7 +526,7 @@
}
test_visitBinaryExpression_questionQuestion_lazy_null_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = null ?? null;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -541,7 +534,7 @@
}
test_visitBinaryExpression_xor_bool_known_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false ^ true;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -549,7 +542,7 @@
}
test_visitBinaryExpression_xor_bool_known_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const b = bool.fromEnvironment('y');
const c = false ^ b;
''');
@@ -558,7 +551,7 @@
}
test_visitBinaryExpression_xor_bool_unknown_known() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const c = a ^ true;
''');
@@ -567,7 +560,7 @@
}
test_visitBinaryExpression_xor_bool_unknown_unknown() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = bool.fromEnvironment('x');
const b = bool.fromEnvironment('y');
const c = a ^ b;
@@ -577,7 +570,7 @@
}
test_visitBinaryExpression_xor_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 ^ 5;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -585,7 +578,7 @@
}
test_visitBinaryExpression_xor_mixed() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 ^ false;
''');
_evaluateConstant('c',
@@ -593,7 +586,7 @@
}
test_visitConditionalExpression_lazy_false_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false ? 1 : 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -602,14 +595,14 @@
}
test_visitConditionalExpression_lazy_false_int_invalid() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false ? 1 : new C();
''');
_evaluateConstant('c', errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT]);
}
test_visitConditionalExpression_lazy_false_invalid_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = false ? new C() : 0;
''');
DartObjectImpl result = _evaluateConstant('c',
@@ -619,7 +612,7 @@
}
test_visitConditionalExpression_lazy_invalid_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = 3 ? 1 : 0;
''');
_evaluateConstant('c',
@@ -627,7 +620,7 @@
}
test_visitConditionalExpression_lazy_true_int_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? 1 : 0;
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -636,7 +629,7 @@
}
test_visitConditionalExpression_lazy_true_int_invalid() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? 1: new C();
''');
DartObjectImpl result = _evaluateConstant('c',
@@ -646,7 +639,7 @@
}
test_visitConditionalExpression_lazy_true_invalid_int() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = true ? new C() : 0;
class C {}
''');
@@ -654,7 +647,7 @@
}
test_visitIsExpression_is_instanceOfSameClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is A;
class A {
@@ -667,7 +660,7 @@
}
test_visitIsExpression_is_instanceOfSubclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const B();
const b = a is A;
class A {
@@ -683,7 +676,7 @@
}
test_visitIsExpression_is_instanceOfSuperclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is B;
class A {
@@ -699,7 +692,7 @@
}
test_visitIsExpression_is_instanceOfUnrelatedClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is B;
class A {
@@ -715,7 +708,7 @@
}
test_visitIsExpression_is_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a is A;
class A {}
@@ -726,7 +719,7 @@
}
test_visitIsExpression_is_null_dynamic() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a is dynamic;
class A {}
@@ -737,7 +730,7 @@
}
test_visitIsExpression_is_null_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a is Null;
class A {}
@@ -748,7 +741,7 @@
}
test_visitIsExpression_is_null_object() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a is Object;
class A {}
@@ -759,7 +752,7 @@
}
test_visitIsExpression_isNot_instanceOfSameClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is! A;
class A {
@@ -772,7 +765,7 @@
}
test_visitIsExpression_isNot_instanceOfSubclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const B();
const b = a is! A;
class A {
@@ -788,7 +781,7 @@
}
test_visitIsExpression_isNot_instanceOfSuperclass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is! B;
class A {
@@ -804,7 +797,7 @@
}
test_visitIsExpression_isNot_instanceOfUnrelatedClass() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = const A();
const b = a is! B;
class A {
@@ -820,7 +813,7 @@
}
test_visitIsExpression_isNot_null() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const a = null;
const b = a is! A;
class A {}
@@ -835,7 +828,7 @@
class ConstantVisitorWithFlowControlAndSpreadCollectionsTest
extends ConstantVisitorTestSupport {
test_listLiteral_ifElement_false_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, if (1 < 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -844,7 +837,7 @@
}
test_listLiteral_ifElement_false_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, if (1 < 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -853,7 +846,7 @@
}
test_listLiteral_ifElement_true_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, if (1 > 0) 2 else 3, 4];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -862,7 +855,7 @@
}
test_listLiteral_ifElement_true_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, if (1 > 0) 2, 3];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -871,7 +864,7 @@
}
test_listLiteral_nested() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, if (1 > 0) if (2 > 1) 2, 3];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -882,7 +875,7 @@
}
test_listLiteral_spreadElement() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = [1, ...[2, 3], 4];
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -891,7 +884,7 @@
}
test_mapLiteral_ifElement_false_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, if (1 < 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -904,7 +897,7 @@
}
test_mapLiteral_ifElement_false_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, if (1 < 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -917,7 +910,7 @@
}
test_mapLiteral_ifElement_true_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, if (1 > 0) 'b' : 2 else 'c' : 3, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -930,7 +923,7 @@
}
test_mapLiteral_ifElement_true_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, if (1 > 0) 'b' : 2, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -945,7 +938,7 @@
@failingTest
test_mapLiteral_nested() async {
// Fails because we're not yet parsing nested elements.
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, if (1 > 0) if (2 > 1) {'b' : 2}, 'c' : 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -958,7 +951,7 @@
}
test_mapLiteral_spreadElement() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {'a' : 1, ...{'b' : 2, 'c' : 3}, 'd' : 4};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -972,7 +965,7 @@
}
test_setLiteral_ifElement_false_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, if (1 < 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -981,7 +974,7 @@
}
test_setLiteral_ifElement_false_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, if (1 < 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -990,7 +983,7 @@
}
test_setLiteral_ifElement_true_withElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, if (1 > 0) 2 else 3, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -999,7 +992,7 @@
}
test_setLiteral_ifElement_true_withoutElse() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, if (1 > 0) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -1008,7 +1001,7 @@
}
test_setLiteral_nested() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, if (1 > 0) if (2 > 1) 2, 3};
''');
DartObjectImpl result = _evaluateConstant('c');
@@ -1017,7 +1010,7 @@
}
test_setLiteral_spreadElement() async {
- await _resolveTestCode('''
+ await resolveTestCode('''
const c = {1, ...{2, 3}, 4};
''');
DartObjectImpl result = _evaluateConstant('c');
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index a18956a..b2431e5 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -119,17 +119,13 @@
}
Future<void> _assertConst(String code) async {
- addTestFile(code);
- await resolveTestFile();
-
+ await resolveTestCode(code);
var type = findNode.variableDeclarationList('x;').type;
expect(isConstantTypeExpression(type), isTrue);
}
Future<void> _assertNotConst(String code) async {
- addTestFile(code);
- await resolveTestFile();
-
+ await resolveTestCode(code);
var type = findNode.variableDeclarationList('x;').type;
expect(isConstantTypeExpression(type), isFalse);
}
@@ -847,9 +843,7 @@
}
_assertConst(String code, AstNode Function() getNode) async {
- addTestFile(code);
- await resolveTestFile();
-
+ await resolveTestCode(code);
var node = getNode();
var notConstList = getNotPotentiallyConstants(node);
expect(notConstList, isEmpty);
@@ -857,9 +851,7 @@
_assertNotConst(String code, AstNode Function() getNode,
List<AstNode> Function() getNotConstList) async {
- addTestFile(code);
- await resolveTestFile();
-
+ await resolveTestCode(code);
var node = getNode();
var notConstList = getNotPotentiallyConstants(node);
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index f337c05..d26101c 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -9,8 +9,6 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../generated/test_support.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DartObjectImplTest);
@@ -23,7 +21,7 @@
throwsA(new TypeMatcher<EvaluationException>());
@reflectiveTest
-class DartObjectImplTest extends EngineTestCase {
+class DartObjectImplTest {
TypeProvider _typeProvider = new TestTypeProvider();
void test_add_knownDouble_knownDouble() {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a3d5a04..f0489be 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -20,7 +20,6 @@
import '../../../generated/elements_types_mixin.dart';
import '../../../generated/test_analysis_context.dart';
-import '../../../generated/test_support.dart';
import '../resolution/driver_resolution.dart';
main() {
@@ -869,7 +868,7 @@
}
@reflectiveTest
-class CompilationUnitElementImplTest extends EngineTestCase {
+class CompilationUnitElementImplTest {
void test_getEnum_declared() {
TestTypeProvider typeProvider = new TestTypeProvider();
CompilationUnitElementImpl unit =
@@ -921,14 +920,12 @@
}
void f(@A('x') int p) {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
main() {
f(3);
}
''');
- await resolveTestFile();
-
var argument = findNode.integerLiteral('3');
ParameterElement parameter = argument.staticParameterElement;
@@ -1049,7 +1046,7 @@
}
@reflectiveTest
-class ElementLocationImplTest extends EngineTestCase {
+class ElementLocationImplTest {
void test_create_encoding() {
String encoding = "a;b;c";
ElementLocationImpl location = new ElementLocationImpl.con2(encoding);
@@ -1116,11 +1113,9 @@
@reflectiveTest
class FieldElementImplTest extends DriverResolutionTest {
test_isEnumConstant() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum B {B1, B2, B3}
''');
- await resolveTestFile();
-
var B = findElement.enum_('B');
FieldElement b2Element = B.getField('B2');
@@ -3434,16 +3429,16 @@
}
@reflectiveTest
-class LibraryElementImplTest extends EngineTestCase {
+class LibraryElementImplTest {
void test_creation() {
expect(
- new LibraryElementImpl.forNode(createAnalysisContext(), null,
+ new LibraryElementImpl.forNode(TestAnalysisContext(), null,
AstTestFactory.libraryIdentifier2(["l"]), true),
isNotNull);
}
void test_getImportedLibraries() {
- AnalysisContext context = createAnalysisContext();
+ AnalysisContext context = TestAnalysisContext();
LibraryElementImpl library1 = ElementFactory.library(context, "l1");
LibraryElementImpl library2 = ElementFactory.library(context, "l2");
LibraryElementImpl library3 = ElementFactory.library(context, "l3");
@@ -3467,7 +3462,7 @@
}
void test_getPrefixes() {
- AnalysisContext context = createAnalysisContext();
+ AnalysisContext context = TestAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "l1");
PrefixElement prefixA =
new PrefixElementImpl.forNode(AstTestFactory.identifier3("a"));
@@ -3492,7 +3487,7 @@
}
void test_getUnits() {
- AnalysisContext context = createAnalysisContext();
+ AnalysisContext context = TestAnalysisContext();
LibraryElementImpl library = ElementFactory.library(context, "test");
CompilationUnitElement unitLib = library.definingCompilationUnit;
CompilationUnitElementImpl unitA =
@@ -3505,7 +3500,7 @@
}
void test_setImports() {
- AnalysisContext context = createAnalysisContext();
+ AnalysisContext context = TestAnalysisContext();
LibraryElementImpl library = new LibraryElementImpl.forNode(
context, null, AstTestFactory.libraryIdentifier2(["l1"]), true);
List<ImportElementImpl> expectedImports = [
@@ -3522,7 +3517,7 @@
}
@reflectiveTest
-class PropertyAccessorElementImplTest extends EngineTestCase {
+class PropertyAccessorElementImplTest {
void test_matchesHandle_getter() {
CompilationUnitElementImpl compilationUnitElement =
ElementFactory.compilationUnit('foo.dart');
@@ -3572,14 +3567,12 @@
newFile('/test/lib/a.dart', content: r'''
const int C = 42;
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
main() {
print(C);
}
''');
- await resolveTestFile();
-
SimpleIdentifier argument = findNode.simple('C);');
PropertyAccessorElementImpl getter = argument.staticElement;
TopLevelVariableElement constant = getter.variable;
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 6b6aa60..0b79a60 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -36,7 +36,6 @@
@reflectiveTest
class FunctionTypeTest with ElementsTypesMixin {
static const bug_33294_fixed = false;
- static const bug_33300_fixed = false;
static const bug_33301_fixed = false;
static const bug_33302_fixed = false;
@@ -592,64 +591,6 @@
throwsA(new TypeMatcher<ArgumentError>()));
}
- test_synthetic_substitute_share_returnType_and_parameters() {
- // int Function<U extends T>(int x)
- var t = typeParameter('T');
- var u = typeParameter('U', bound: typeParameterType(t));
- var x = requiredParameter('x', type: intType);
- FunctionType f = new FunctionTypeImpl.synthetic(intType, [u], [x]);
- FunctionType substituted =
- f.substitute2([objectType], [typeParameterType(t)]);
- basicChecks(substituted,
- element: isNull,
- displayName: 'int Function<U extends Object>(int)',
- returnType: same(f.returnType),
- typeFormals: hasLength(1),
- normalParameterNames: ['x'],
- normalParameterTypes: [same(intType)],
- parameters: same(f.parameters));
- expect(substituted.typeFormals[0].name, 'U');
- expect(substituted.typeFormals[0].bound, same(objectType));
- }
-
- test_synthetic_substitute_share_returnType_and_typeFormals() {
- // int Function<U>(T x, U y)
- var t = typeParameter('T');
- var u = typeParameter('U');
- var x = requiredParameter('x', type: typeParameterType(t));
- var y = requiredParameter('y', type: typeParameterType(u));
- FunctionType f = new FunctionTypeImpl.synthetic(intType, [u], [x, y]);
- FunctionType substituted =
- f.substitute2([objectType], [typeParameterType(t)]);
- basicChecks(substituted,
- element: isNull,
- displayName: 'int Function<U>(Object, U)',
- returnType: same(f.returnType),
- typeFormals: same(f.typeFormals),
- normalParameterNames: ['x', 'y'],
- normalParameterTypes: [same(objectType), typeParameterType(u)],
- parameters: hasLength(2));
- }
-
- test_synthetic_substitute_share_typeFormals_and_parameters() {
- // T Function<U>(U x)
- var t = typeParameter('T');
- var u = typeParameter('U');
- var x = requiredParameter('x', type: typeParameterType(u));
- FunctionType f =
- new FunctionTypeImpl.synthetic(typeParameterType(t), [u], [x]);
- FunctionType substituted =
- f.substitute2([objectType], [typeParameterType(t)]);
- basicChecks(substituted,
- element: isNull,
- displayName: 'Object Function<U>(U)',
- returnType: same(objectType),
- typeFormals: same(f.typeFormals),
- normalParameterNames: ['x'],
- normalParameterTypes: [typeParameterType(u)],
- parameters: same(f.parameters));
- }
-
test_synthetic_substitute_unchanged() {
// dynamic Function<U>(U x)
var t = typeParameter('T');
@@ -877,13 +818,8 @@
typeFormals: hasLength(3),
typeParameters: [same(u)],
typeArguments: [same(objectType)]);
- if (bug_33300_fixed) {
- expect(substituted.displayName,
- 'Map<S, V> Function<S extends T,T extends Object,V extends T>()');
- } else {
- expect(substituted.displayName,
- 'Map<S, V> Function<S extends T extends Object,T extends Object,V extends T>()');
- }
+ expect(substituted.displayName,
+ 'Map<S, V> Function<S extends T,T extends Object,V extends T>()');
var s2 = substituted.typeFormals[0];
var t2 = substituted.typeFormals[1];
var v2 = substituted.typeFormals[2];
@@ -933,13 +869,8 @@
typeFormals: hasLength(3),
typeParameters: [same(u)],
typeArguments: [same(objectType)]);
- if (bug_33300_fixed) {
- expect(substituted.displayName,
- 'void Function<S extends T,T extends Object,V extends T>(S, V)');
- } else {
- expect(substituted.displayName,
- 'void Function<S extends T extends Object,T extends Object,V extends T>(S, V)');
- }
+ expect(substituted.displayName,
+ 'void Function<S extends T,T extends Object,V extends T>(S, V)');
var s2 = substituted.typeFormals[0];
var t2 = substituted.typeFormals[1];
var v2 = substituted.typeFormals[2];
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
index 71b0757..b2da098 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
@@ -30,7 +30,7 @@
}
test_getInherited_closestSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -43,8 +43,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -53,7 +51,7 @@
}
test_getInherited_interfaces() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo();
}
@@ -66,8 +64,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -76,7 +72,7 @@
}
test_getInherited_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -89,8 +85,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -99,7 +93,7 @@
}
test_getInherited_preferImplemented() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -112,8 +106,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -122,85 +114,75 @@
}
test_getInheritedConcreteMap_accessor_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedConcreteMap_accessor_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
abstract class B implements A {}
''');
- await resolveTestFile();
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_accessor_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int get foo => 0;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedConcreteMap_implicitExtends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
''');
- await resolveTestFile();
_assertInheritedConcreteMap('A', '');
}
test_getInheritedConcreteMap_method_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedConcreteMap_method_extends_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_method_extends_invalidForImplements() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo(int x, {int y});
void bar(String s);
@@ -212,43 +194,37 @@
class C extends A implements I {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('C', r'''
A.foo: void Function(int)
''');
}
test_getInheritedConcreteMap_method_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_method_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedConcreteMap_method_with2() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
@@ -259,8 +235,6 @@
class C extends Object with A, B {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('C', r'''
A.foo: void Function()
B.bar: void Function()
@@ -268,52 +242,46 @@
}
test_getInheritedMap_accessor_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_accessor_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_accessor_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int get foo => 0;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_closestSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -324,23 +292,19 @@
class X extends B {}
''');
- await resolveTestFile();
-
_assertInheritedMap('X', r'''
B.foo: void Function()
''');
}
test_getInheritedMap_field_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -348,15 +312,13 @@
}
test_getInheritedMap_field_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo;
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -364,15 +326,13 @@
}
test_getInheritedMap_field_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int foo;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -380,61 +340,53 @@
}
test_getInheritedMap_implicitExtendsObject() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', '');
}
test_getInheritedMap_method_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_method_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_method_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_preferImplemented() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -447,15 +399,13 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertInheritedMap('X', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_union_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int foo();
void bar();
@@ -468,15 +418,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.bar: void Function()
''');
}
test_getInheritedMap_union_differentNames() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int foo();
}
@@ -487,8 +435,6 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I.foo: int Function()
J.bar: double Function()
@@ -496,7 +442,7 @@
}
test_getInheritedMap_union_multipleSubtypes_2_getters() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int get foo;
}
@@ -507,15 +453,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.foo: int Function()
''');
}
test_getInheritedMap_union_multipleSubtypes_2_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo();
}
@@ -526,15 +470,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.foo: void Function()
''');
}
test_getInheritedMap_union_multipleSubtypes_2_setters() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void set foo(num _);
}
@@ -546,8 +488,6 @@
abstract class A implements I, J {}
abstract class B implements J, I {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I.foo=: void Function(num)
''');
@@ -558,7 +498,7 @@
}
test_getInheritedMap_union_multipleSubtypes_3_getters() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -578,8 +518,6 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I3.foo: C Function()
''');
@@ -590,7 +528,7 @@
}
test_getInheritedMap_union_multipleSubtypes_3_methods() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -610,15 +548,13 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I1.foo: void Function(A)
''');
}
test_getInheritedMap_union_multipleSubtypes_3_setters() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -638,8 +574,6 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I1.foo=: void Function(A)
''');
@@ -650,7 +584,7 @@
}
test_getInheritedMap_union_oneSubtype_2_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
int foo();
}
@@ -662,8 +596,6 @@
abstract class A implements I1, I2 {}
abstract class B implements I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I2.foo: int Function([int])
''');
@@ -674,7 +606,7 @@
}
test_getInheritedMap_union_oneSubtype_3_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
int foo();
}
@@ -690,8 +622,6 @@
abstract class A implements I1, I2, I3 {}
abstract class B implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I3.foo: int Function([int, int])
''');
@@ -702,7 +632,7 @@
}
test_getMember() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
void f(int i);
}
@@ -713,8 +643,6 @@
abstract class C implements I1, I2 {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'C',
name: 'f',
@@ -723,13 +651,11 @@
}
test_getMember_concrete() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -739,13 +665,11 @@
}
test_getMember_concrete_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -754,15 +678,13 @@
}
test_getMember_concrete_fromMixedClass() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class X with A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -772,7 +694,7 @@
}
test_getMember_concrete_fromMixedClass2() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -781,8 +703,6 @@
class X with B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -792,7 +712,7 @@
}
test_getMember_concrete_fromMixedClass_skipObject() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
String toString() => 'A';
}
@@ -801,8 +721,6 @@
class X extends A with B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'toString',
@@ -812,15 +730,13 @@
}
test_getMember_concrete_fromMixin() async {
- addTestFile('''
+ await resolveTestCode('''
mixin M {
void foo() {}
}
class X with M {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -830,7 +746,7 @@
}
test_getMember_concrete_fromSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -839,8 +755,6 @@
abstract class C extends B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -857,11 +771,9 @@
}
test_getMember_concrete_missing() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -870,7 +782,7 @@
}
test_getMember_concrete_noSuchMethod() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -881,8 +793,6 @@
abstract class C extends B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -899,7 +809,7 @@
}
test_getMember_concrete_noSuchMethod_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo();
@@ -908,9 +818,7 @@
abstract class B extends Object with A {}
''');
- await resolveTestFile();
-
- // noSuchMethod forwarders are not mixed-in.
+// noSuchMethod forwarders are not mixed-in.
// https://github.com/dart-lang/sdk/issues/33553#issuecomment-424638320
_assertGetMember(
className: 'B',
@@ -920,7 +828,7 @@
}
test_getMember_concrete_noSuchMethod_moreSpecificSignature() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -933,8 +841,6 @@
void foo([int a]);
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'C',
name: 'foo',
@@ -944,7 +850,7 @@
}
test_getMember_preferLatest_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -963,8 +869,6 @@
class X extends A with M1, M2 implements I {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -973,7 +877,7 @@
}
test_getMember_preferLatest_superclass() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -988,8 +892,6 @@
class X extends B implements I {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -998,7 +900,7 @@
}
test_getMember_preferLatest_this() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -1011,8 +913,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -1021,7 +921,7 @@
}
test_getMember_super_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
@@ -1030,8 +930,6 @@
noSuchMethod(_) {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1040,15 +938,13 @@
}
test_getMember_super_forMixin_interface() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
mixin M implements A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'M',
name: 'foo',
@@ -1057,15 +953,13 @@
}
test_getMember_super_forMixin_superclassConstraint() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
mixin M on A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'M',
name: 'foo',
@@ -1075,7 +969,7 @@
}
test_getMember_super_fromMixin() async {
- addTestFile('''
+ await resolveTestCode('''
mixin M {
void foo() {}
}
@@ -1084,8 +978,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -1095,7 +987,7 @@
}
test_getMember_super_fromSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -1104,8 +996,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1115,13 +1005,11 @@
}
test_getMember_super_missing() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1130,7 +1018,7 @@
}
test_getMember_super_noSuchMember() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo();
noSuchMethod(_) {}
@@ -1140,8 +1028,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
index 3a5221c..f8901a3 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager3_test.dart
@@ -31,7 +31,7 @@
}
test_getInherited_closestSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -44,8 +44,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -54,7 +52,7 @@
}
test_getInherited_interfaces() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo();
}
@@ -67,8 +65,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -77,7 +73,7 @@
}
test_getInherited_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -90,8 +86,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -100,7 +94,7 @@
}
test_getInherited_preferImplemented() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -113,8 +107,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetInherited(
className: 'X',
name: 'foo',
@@ -123,85 +115,75 @@
}
test_getInheritedConcreteMap_accessor_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedConcreteMap_accessor_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
abstract class B implements A {}
''');
- await resolveTestFile();
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_accessor_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int get foo => 0;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedConcreteMap_implicitExtends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
''');
- await resolveTestFile();
_assertInheritedConcreteMap('A', '');
}
test_getInheritedConcreteMap_method_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedConcreteMap_method_extends_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_method_extends_invalidForImplements() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo(int x, {int y});
void bar(String s);
@@ -213,43 +195,37 @@
class C extends A implements I {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('C', r'''
A.foo: void Function(int)
''');
}
test_getInheritedConcreteMap_method_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', '');
}
test_getInheritedConcreteMap_method_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedConcreteMap_method_with2() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
@@ -260,8 +236,6 @@
class C extends Object with A, B {}
''');
- await resolveTestFile();
-
_assertInheritedConcreteMap('C', r'''
A.foo: void Function()
B.bar: void Function()
@@ -269,52 +243,46 @@
}
test_getInheritedMap_accessor_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_accessor_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo => 0;
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_accessor_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int get foo => 0;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
''');
}
test_getInheritedMap_closestSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -325,23 +293,19 @@
class X extends B {}
''');
- await resolveTestFile();
-
_assertInheritedMap('X', r'''
B.foo: void Function()
''');
}
test_getInheritedMap_field_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo;
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -349,15 +313,13 @@
}
test_getInheritedMap_field_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo;
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -365,15 +327,13 @@
}
test_getInheritedMap_field_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
int foo;
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: int Function()
A.foo=: void Function(int)
@@ -381,61 +341,53 @@
}
test_getInheritedMap_implicitExtendsObject() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', '');
}
test_getInheritedMap_method_extends() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class B extends A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_method_implements() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
abstract class B implements A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_method_with() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A {
void foo() {}
}
class B extends Object with A {}
''');
- await resolveTestFile();
-
_assertInheritedMap('B', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_preferImplemented() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -448,15 +400,13 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertInheritedMap('X', r'''
A.foo: void Function()
''');
}
test_getInheritedMap_union_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int foo();
void bar();
@@ -469,15 +419,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.bar: void Function()
''');
}
test_getInheritedMap_union_differentNames() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int foo();
}
@@ -488,8 +436,6 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I.foo: int Function()
J.bar: double Function()
@@ -497,7 +443,7 @@
}
test_getInheritedMap_union_multipleSubtypes_2_getters() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
int get foo;
}
@@ -508,15 +454,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.foo: int Function()
''');
}
test_getInheritedMap_union_multipleSubtypes_2_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void foo();
}
@@ -527,15 +471,13 @@
abstract class A implements I, J {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
J.foo: void Function()
''');
}
test_getInheritedMap_union_multipleSubtypes_2_setters() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I {
void set foo(num _);
}
@@ -547,8 +489,6 @@
abstract class A implements I, J {}
abstract class B implements J, I {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I.foo=: void Function(num)
''');
@@ -559,7 +499,7 @@
}
test_getInheritedMap_union_multipleSubtypes_3_getters() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -579,8 +519,6 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I3.foo: C Function()
''');
@@ -591,7 +529,7 @@
}
test_getInheritedMap_union_multipleSubtypes_3_methods() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -611,15 +549,13 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I1.foo: void Function(A)
''');
}
test_getInheritedMap_union_multipleSubtypes_3_setters() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
class C extends B {}
@@ -639,8 +575,6 @@
abstract class D implements I1, I2, I3 {}
abstract class E implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('D', r'''
I1.foo=: void Function(A)
''');
@@ -651,7 +585,7 @@
}
test_getInheritedMap_union_oneSubtype_2_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
int foo();
}
@@ -663,8 +597,6 @@
abstract class A implements I1, I2 {}
abstract class B implements I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I2.foo: int Function([int])
''');
@@ -675,7 +607,7 @@
}
test_getInheritedMap_union_oneSubtype_3_methods() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
int foo();
}
@@ -691,8 +623,6 @@
abstract class A implements I1, I2, I3 {}
abstract class B implements I3, I2, I1 {}
''');
- await resolveTestFile();
-
_assertInheritedMap('A', r'''
I3.foo: int Function([int, int])
''');
@@ -703,7 +633,7 @@
}
test_getMember() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class I1 {
void f(int i);
}
@@ -714,8 +644,6 @@
abstract class C implements I1, I2 {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'C',
name: 'f',
@@ -724,13 +652,11 @@
}
test_getMember_concrete() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -740,13 +666,11 @@
}
test_getMember_concrete_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -755,15 +679,13 @@
}
test_getMember_concrete_fromMixedClass() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
class X with A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -773,7 +695,7 @@
}
test_getMember_concrete_fromMixedClass2() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -782,8 +704,6 @@
class X with B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -793,7 +713,7 @@
}
test_getMember_concrete_fromMixedClass_skipObject() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
String toString() => 'A';
}
@@ -802,8 +722,6 @@
class X extends A with B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'toString',
@@ -813,15 +731,13 @@
}
test_getMember_concrete_fromMixin() async {
- addTestFile('''
+ await resolveTestCode('''
mixin M {
void foo() {}
}
class X with M {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -831,7 +747,7 @@
}
test_getMember_concrete_fromSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -840,8 +756,6 @@
abstract class C extends B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -858,11 +772,9 @@
}
test_getMember_concrete_missing() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'A',
name: 'foo',
@@ -871,7 +783,7 @@
}
test_getMember_concrete_noSuchMethod() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -882,8 +794,6 @@
abstract class C extends B {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -900,7 +810,7 @@
}
test_getMember_concrete_noSuchMethod_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo();
@@ -909,9 +819,7 @@
abstract class B extends Object with A {}
''');
- await resolveTestFile();
-
- // noSuchMethod forwarders are not mixed-in.
+// noSuchMethod forwarders are not mixed-in.
// https://github.com/dart-lang/sdk/issues/33553#issuecomment-424638320
_assertGetMember(
className: 'B',
@@ -921,7 +829,7 @@
}
test_getMember_concrete_noSuchMethod_moreSpecificSignature() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -934,8 +842,6 @@
void foo([int a]);
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'C',
name: 'foo',
@@ -945,7 +851,7 @@
}
test_getMember_preferLatest_mixin() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -964,8 +870,6 @@
class X extends A with M1, M2 implements I {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -974,7 +878,7 @@
}
test_getMember_preferLatest_superclass() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -989,8 +893,6 @@
class X extends B implements I {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -999,7 +901,7 @@
}
test_getMember_preferLatest_this() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -1012,8 +914,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -1022,7 +922,7 @@
}
test_getMember_super_abstract() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
@@ -1031,8 +931,6 @@
noSuchMethod(_) {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1041,15 +939,13 @@
}
test_getMember_super_forMixin_interface() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
mixin M implements A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'M',
name: 'foo',
@@ -1058,15 +954,13 @@
}
test_getMember_super_forMixin_superclassConstraint() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo();
}
mixin M on A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'M',
name: 'foo',
@@ -1076,7 +970,7 @@
}
test_getMember_super_fromMixin() async {
- addTestFile('''
+ await resolveTestCode('''
mixin M {
void foo() {}
}
@@ -1085,8 +979,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'X',
name: 'foo',
@@ -1096,7 +988,7 @@
}
test_getMember_super_fromSuper() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -1105,8 +997,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1116,13 +1006,11 @@
}
test_getMember_super_missing() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B extends A {}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
@@ -1131,7 +1019,7 @@
}
test_getMember_super_noSuchMember() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo();
noSuchMethod(_) {}
@@ -1141,8 +1029,6 @@
void foo() {}
}
''');
- await resolveTestFile();
-
_assertGetMember(
className: 'B',
name: 'foo',
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
index 93095da..17352e4 100644
--- a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/type_system.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -256,6 +257,11 @@
_assertIdenticalType(type, {U: doubleType});
}
+ test_unknownInferredType() async {
+ var T = typeParameter('T');
+ _assertIdenticalType(UnknownInferredType.instance, {T: intType});
+ }
+
test_void() async {
var T = typeParameter('T');
_assertIdenticalType(typeProvider.voidType, {T: intType});
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index e556a7f..ea4bd89 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -19,14 +19,12 @@
@reflectiveTest
class AssignmentDriverResolutionTest extends DriverResolutionTest {
test_compound_indexExpression() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var x = <num>[1, 2, 3];
x[0] += 4;
}
''');
- await resolveTestFile();
-
AssignmentExpression assignment = findNode.assignment('+= 4');
assertElement(assignment, numElement.getMethod('+'));
assertType(assignment, 'num'); // num + int = num
@@ -47,14 +45,12 @@
}
test_compound_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
num v = 0;
v += 3;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('v += 3');
assertElement(assignment, numElement.getMethod('+'));
assertType(assignment, 'num'); // num + int = num
@@ -68,7 +64,7 @@
}
test_compound_prefixedIdentifier() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var c = new C();
c.f += 2;
@@ -77,8 +73,6 @@
num f;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('c.f += 2');
assertElement(assignment, numElement.getMethod('+'));
assertType(assignment, 'num'); // num + int = num
@@ -99,7 +93,7 @@
}
test_compound_propertyAccess() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
new C().f += 2;
}
@@ -107,8 +101,6 @@
num f;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f += 2');
assertElement(assignment, numElement.getMethod('+'));
assertType(assignment, 'num'); // num + int = num
@@ -186,12 +178,11 @@
}
test_in_const_context() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
const [x = y];
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x =');
@@ -204,13 +195,11 @@
}
test_indexExpression_cascade() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
<int, double>{}..[1] = 2.0;
}
''');
- await resolveTestFile();
-
var cascade = findNode.cascade('<int, double>');
assertType(cascade, 'Map<int, double>');
@@ -233,14 +222,13 @@
}
test_notLValue_parenthesized() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int a, b;
double c = 0.0;
main() {
(a + b) = c;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var parenthesized = findNode.parenthesized('(a + b)');
@@ -256,14 +244,12 @@
}
test_nullAware_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
String v;
v ??= 'test';
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('v ??=');
assertElementNull(assignment);
assertType(assignment, 'String');
@@ -277,7 +263,7 @@
}
test_propertyAccess_forwardingStub() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int f;
}
@@ -289,8 +275,6 @@
new B().f = 1;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f = 1');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -311,14 +295,12 @@
}
test_simple_indexExpression() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var x = <int>[1, 2, 3];
x[0] = 4;
}
''');
- await resolveTestFile();
-
AssignmentExpression assignment = findNode.assignment('= 4');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -339,7 +321,7 @@
}
test_simple_instanceField_unqualified() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
num f = 0;
foo() {
@@ -347,8 +329,6 @@
}
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f = 2;');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -362,14 +342,12 @@
}
test_simple_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
num v = 0;
v = 2;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('v = 2;');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -383,7 +361,7 @@
}
test_simple_prefixedIdentifier() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var c = new C();
c.f = 2;
@@ -392,8 +370,6 @@
num f;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('c.f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -414,7 +390,7 @@
}
test_simple_prefixedIdentifier_staticField() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
C.f = 2;
}
@@ -423,8 +399,6 @@
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('C.f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -446,7 +420,7 @@
}
test_simple_propertyAccess() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
new C().f = 2;
}
@@ -454,8 +428,6 @@
num f;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -476,7 +448,7 @@
}
test_simple_propertyAccess_chained() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var a = new A();
a.b.f = 2;
@@ -488,8 +460,6 @@
num f;
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('a.b.f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -517,7 +487,7 @@
}
test_simple_propertyAccess_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
new C().f = 2;
}
@@ -525,8 +495,6 @@
void set f(num _) {}
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -547,7 +515,7 @@
}
test_simple_staticField_unqualified() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static num f = 0;
foo() {
@@ -555,8 +523,6 @@
}
}
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('f = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -570,14 +536,12 @@
}
test_simple_topLevelVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
v = 2;
}
num v = 0;
''');
- await resolveTestFile();
-
var assignment = findNode.assignment('v = 2');
assertElementNull(assignment);
assertType(assignment, 'int');
@@ -591,13 +555,12 @@
}
test_to_class() async {
- addTestFile('''
+ await resolveTestCode('''
class C {}
void f(int x) {
C = x;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var cRef = findNode.simple('C =');
@@ -612,14 +575,13 @@
test_to_class_ambiguous() async {
newFile('/test/lib/a.dart', content: 'class C {}');
newFile('/test/lib/b.dart', content: 'class C {}');
- addTestFile('''
+ await resolveTestCode('''
import 'a.dart';
import 'b.dart';
void f(int x) {
C = x;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x;');
@@ -628,12 +590,11 @@
}
test_to_final_parameter() async {
- addTestFile('''
+ await resolveTestCode('''
f(final int x) {
x += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -642,13 +603,12 @@
}
test_to_final_variable_local() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
final x = 1;
x += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -657,7 +617,7 @@
}
test_to_getter_instance_direct() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
int get x => 0;
}
@@ -665,7 +625,6 @@
c.x += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -674,7 +633,7 @@
}
test_to_getter_instance_via_implicit_this() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
int get x => 0;
f() {
@@ -682,7 +641,6 @@
}
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -691,7 +649,7 @@
}
test_to_getter_static_direct() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
static int get x => 0;
}
@@ -699,7 +657,6 @@
C.x += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -708,7 +665,7 @@
}
test_to_getter_static_via_scope() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
static int get x => 0;
f() {
@@ -716,7 +673,6 @@
}
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -725,13 +681,12 @@
}
test_to_getter_top_level() async {
- addTestFile('''
+ await resolveTestCode('''
int get x => 0;
main() {
x += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -740,12 +695,11 @@
}
test_to_non_lvalue() async {
- addTestFile('''
+ await resolveTestCode('''
void f(int x, double y, String z) {
x + y = z;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +');
@@ -762,12 +716,11 @@
}
test_to_postfix_increment() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
x++ = y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x++');
@@ -780,12 +733,11 @@
}
test_to_postfix_increment_compound() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
x++ += y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x++');
@@ -798,12 +750,11 @@
}
test_to_postfix_increment_null_aware() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
x++ ??= y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x++');
@@ -819,13 +770,12 @@
newFile('/test/lib/a.dart', content: '''
var x = 0;
''');
- addTestFile('''
+ await resolveTestCode('''
import 'a.dart' as p;
main() {
p += 2;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var pRef = findNode.simple('p +=');
@@ -834,12 +784,11 @@
}
test_to_prefix_increment() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
++x = y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x =');
@@ -852,12 +801,11 @@
}
test_to_prefix_increment_compound() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
++x += y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x +=');
@@ -870,12 +818,11 @@
}
test_to_prefix_increment_null_aware() async {
- addTestFile('''
+ await resolveTestCode('''
void f(num x, int y) {
++x ??= y;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x ??=');
@@ -888,14 +835,13 @@
}
test_types_local() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int a;
bool b;
main() {
a = b;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a = b');
@@ -907,11 +853,10 @@
}
test_types_top() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int a = 0;
bool b = a;
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var bDeclaration = findNode.variableDeclaration('b =');
@@ -926,11 +871,10 @@
}
test_types_top_const() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
const int a = 0;
const bool b = a;
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var bDeclaration = findNode.variableDeclaration('b =');
@@ -945,13 +889,12 @@
}
test_unresolved_left_identifier_compound() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int b;
main() {
a += b;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a += b');
@@ -966,13 +909,12 @@
}
test_unresolved_left_identifier_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int b;
main() {
a = b;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a = b');
@@ -987,13 +929,12 @@
}
test_unresolved_left_indexed1_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int c;
main() {
a[b] = c;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a[b] = c');
@@ -1015,7 +956,7 @@
}
test_unresolved_left_indexed2_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
A a;
int c;
main() {
@@ -1023,7 +964,6 @@
}
class A {}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a[b] = c');
@@ -1045,7 +985,7 @@
}
test_unresolved_left_indexed3_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
A a;
int c;
main() {
@@ -1055,7 +995,6 @@
operator[]=(double b) {}
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a[b] = c');
@@ -1077,14 +1016,13 @@
}
test_unresolved_left_indexed4_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
double b;
int c;
main() {
a[b] = c;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a[b] = c');
@@ -1106,13 +1044,12 @@
}
test_unresolved_left_prefixed1_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int c;
main() {
a.b = c;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a.b = c');
@@ -1134,7 +1071,7 @@
}
test_unresolved_left_prefixed2_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
A a;
int c;
@@ -1142,7 +1079,6 @@
a.b = c;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a.b = c');
@@ -1164,13 +1100,12 @@
}
test_unresolved_left_property1_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int d;
main() {
a.b.c = d;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a.b.c = d');
@@ -1198,7 +1133,7 @@
}
test_unresolved_left_property2_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
A a;
int d;
main() {
@@ -1206,7 +1141,6 @@
}
class A {}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var assignment = findNode.assignment('a.b.c = d');
@@ -1234,7 +1168,7 @@
}
test_unresolved_left_property3_simple() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
A a;
int d;
main() {
@@ -1243,7 +1177,6 @@
class A { B b; }
class B {}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var bElement = findElement.field('b');
@@ -1272,12 +1205,11 @@
}
test_with_synthetic_lhs() async {
- addTestFile('''
+ await resolveTestCode('''
void f(int x) {
= x;
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x;');
@@ -1286,14 +1218,13 @@
}
test_with_synthetic_lhs_in_method() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
void f(int x) {
= x;
}
}
''');
- await resolveTestFile();
expect(result.errors, isNotEmpty);
var xRef = findNode.simple('x;');
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index 1cb1ed5..689444f 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -15,25 +15,23 @@
@reflectiveTest
class ClassAliasDriverResolutionTest extends DriverResolutionTest {
test_defaultConstructor() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class M {}
class X = A with M;
''');
- await resolveTestFile();
assertNoTestErrors();
assertConstructors(findElement.class_('X'), ['X X()']);
}
test_element() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B {}
class C {}
class X = A with B implements C;
''');
- await resolveTestFile();
assertNoTestErrors();
var x = findElement.class_('X');
@@ -49,7 +47,7 @@
@failingTest
test_implicitConstructors_const() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
const A();
}
@@ -60,13 +58,12 @@
const x = const C();
''');
- await resolveTestFile();
assertNoTestErrors();
// TODO(scheglov) add also negative test with fields
}
test_implicitConstructors_dependencies() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A(int i);
}
@@ -76,7 +73,6 @@
class C2 = C1 with M2;
class C1 = A with M1;
''');
- await resolveTestFile();
assertNoTestErrors();
assertConstructors(findElement.class_('C1'), ['C1 C1(int i)']);
@@ -84,7 +80,7 @@
}
test_implicitConstructors_optionalParameters() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
A.c1(int a);
A.c2(int a, [int b, int c]);
@@ -95,7 +91,6 @@
class C = A with M;
''');
- await resolveTestFile();
assertNoTestErrors();
assertConstructors(
@@ -109,7 +104,7 @@
}
test_implicitConstructors_requiredParameters() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A<T extends num> {
A(T x, T y);
}
@@ -118,7 +113,6 @@
class B<E extends num> = A<E> with M;
''');
- await resolveTestFile();
assertNoTestErrors();
assertConstructors(findElement.class_('B'), ['B<E> B(E x, E y)']);
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index aaa8176..752cb6f 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -19,7 +19,7 @@
class ClassDriverResolutionTest extends DriverResolutionTest
with ElementsTypesMixin {
test_abstractSuperMemberReference_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
get foo;
}
@@ -29,14 +29,13 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo; // ref'), findElement.getter('foo'));
}
test_abstractSuperMemberReference_getter2() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class Foo {
String get foo;
}
@@ -48,7 +47,6 @@
String get foo => super.foo; // ref
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(
@@ -58,7 +56,7 @@
}
test_abstractSuperMemberReference_method_reference() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
foo();
}
@@ -68,14 +66,13 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo; // ref'), findElement.method('foo'));
}
test_abstractSuperMemberReference_OK_superHasConcrete_mixinHasAbstract_method() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {}
}
@@ -90,7 +87,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertElement(
findNode.simple('foo(); // ref'),
@@ -99,7 +95,7 @@
}
test_abstractSuperMemberReference_OK_superSuperHasConcrete_getter() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
int get foo => 0;
}
@@ -112,7 +108,6 @@
int get bar => super.foo; // ref
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertElement(
findNode.simple('foo; // ref'),
@@ -121,7 +116,7 @@
}
test_abstractSuperMemberReference_OK_superSuperHasConcrete_setter() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void set foo(_) {}
}
@@ -136,7 +131,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertElement(
findNode.simple('foo = 0;'),
@@ -145,7 +139,7 @@
}
test_abstractSuperMemberReference_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
set foo(_);
}
@@ -155,38 +149,35 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(findNode.simple('foo = 0;'), findElement.setter('foo'));
}
test_conflictingGenericInterfaces_simple() async {
- addTestFile('''
+ await resolveTestCode('''
class I<T> {}
class A implements I<int> {}
class B implements I<String> {}
class C extends A implements B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
}
test_conflictingGenericInterfaces_viaMixin() async {
- addTestFile('''
+ await resolveTestCode('''
class I<T> {}
class A implements I<int> {}
class B implements I<String> {}
class C extends A with B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
}
test_element_allSupertypes() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B {}
class C {}
@@ -199,7 +190,6 @@
class X4 extends A with B implements C {}
class X5 extends A with B, C implements D, E {}
''');
- await resolveTestFile();
assertNoTestErrors();
var a = findElement.class_('A');
@@ -237,7 +227,7 @@
}
test_element_allSupertypes_generic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A<T> {}
class B<T, U> {}
class C<T> extends B<int, T> {}
@@ -246,7 +236,6 @@
class X2 extends B<String, List<int>> {}
class X3 extends C<double> {}
''');
- await resolveTestFile();
assertNoTestErrors();
var a = findElement.class_('A');
@@ -280,14 +269,13 @@
}
test_element_allSupertypes_recursive() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A extends B {}
class B extends C {}
class C extends A {}
class X extends A {}
''');
- await resolveTestFile();
assertHasTestErrors();
var a = findElement.class_('A');
@@ -300,33 +288,31 @@
}
test_error_conflictingConstructorAndStaticField_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
static int foo;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
test_error_conflictingConstructorAndStaticField_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
static int get foo => 0;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
test_error_conflictingConstructorAndStaticField_OK_notSameClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
static int foo;
}
@@ -334,49 +320,45 @@
B.foo();
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_error_conflictingConstructorAndStaticField_OK_notStatic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
int foo;
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_error_conflictingConstructorAndStaticField_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
static void set foo(_) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD,
]);
}
test_error_conflictingConstructorAndStaticMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
static void foo() {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
]);
}
test_error_conflictingConstructorAndStaticMethod_OK_notSameClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
static void foo() {}
}
@@ -384,23 +366,21 @@
B.foo();
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_error_conflictingConstructorAndStaticMethod_OK_notStatic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
void foo() {}
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_error_conflictingFieldAndMethod_inSuper_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
foo() {}
}
@@ -408,13 +388,12 @@
int foo;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingFieldAndMethod_inSuper_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
foo() {}
}
@@ -422,13 +401,12 @@
get foo => 0;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingFieldAndMethod_inSuper_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
foo() {}
}
@@ -436,13 +414,12 @@
set foo(_) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD]);
}
test_error_conflictingMethodAndField_inSuper_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int foo;
}
@@ -450,13 +427,12 @@
foo() {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_conflictingMethodAndField_inSuper_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
get foo => 0;
}
@@ -464,13 +440,12 @@
foo() {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_conflictingMethodAndField_inSuper_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
set foo(_) {}
}
@@ -478,42 +453,38 @@
foo() {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD]);
}
test_error_duplicateConstructorDefault() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C();
C();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT,
]);
}
test_error_duplicateConstructorName() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
C.foo();
C.foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME,
]);
}
test_error_extendsNonClass_dynamic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A extends dynamic {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -523,11 +494,10 @@
}
test_error_extendsNonClass_enum() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum E { ONE }
class A extends E {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -540,11 +510,10 @@
}
test_error_extendsNonClass_mixin() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
mixin M {}
class A extends M {} // ref
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -557,11 +526,10 @@
}
test_error_extendsNonClass_variable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
int v;
class A extends v {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.EXTENDS_NON_CLASS,
]);
@@ -571,11 +539,10 @@
}
test_error_implementsRepeated() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B implements A, A {} // ref
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.IMPLEMENTS_REPEATED]);
var a = findElement.class_('A');
@@ -584,10 +551,9 @@
}
test_error_implementsRepeated_3times() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {} class C{}
class B implements A, A, A, A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
CompileTimeErrorCode.IMPLEMENTS_REPEATED,
@@ -596,22 +562,20 @@
}
test_error_memberWithClassName_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int get C => null;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_getter_static() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static int get C => null;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
var method = findNode.methodDeclaration('C =>');
@@ -621,22 +585,20 @@
}
test_error_memberWithClassName_setter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
set C(_) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
}
test_error_memberWithClassName_setter_static() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static set C(_) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
var method = findNode.methodDeclaration('C(_)');
@@ -645,20 +607,19 @@
}
test_error_mismatchedGetterAndSetterTypes_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int get foo => 0;
set foo(String _) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
test_error_mismatchedGetterAndSetterTypes_interfaces() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get foo {
return 0;
@@ -671,7 +632,6 @@
abstract class X implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
@@ -683,14 +643,13 @@
int get _foo => 0;
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
class B extends A {
set _foo(String _) {}
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
@@ -705,13 +664,12 @@
set _foo(String _) {}
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
import 'b.dart';
class X implements A, B {}
''');
- await resolveTestFile();
assertNoTestErrors();
}
@@ -725,12 +683,11 @@
set _foo(String _) {}
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
class X implements A, B {}
''');
- await resolveTestFile();
assertNoTestErrors();
}
@@ -740,45 +697,42 @@
set _foo(String _) {}
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
class B extends A {
int get _foo => 0;
}
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_error_mismatchedGetterAndSetterTypes_OK_setterParameter_0() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int get foo => 0;
set foo() {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
]);
}
test_error_mismatchedGetterAndSetterTypes_OK_setterParameter_2() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
int get foo => 0;
set foo(String p1, String p2) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
]);
}
test_error_mismatchedGetterAndSetterTypes_superGetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get foo => 0;
}
@@ -787,14 +741,13 @@
set foo(String _) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
test_error_mismatchedGetterAndSetterTypes_superSetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
set foo(String _) {}
}
@@ -803,14 +756,13 @@
int get foo => 0;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES,
]);
}
test_inconsistentInheritance_parameterType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
x(int i);
}
@@ -819,14 +771,13 @@
}
abstract class C implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
test_inconsistentInheritance_requiredParameters() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
x();
}
@@ -835,14 +786,13 @@
}
abstract class C implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
test_inconsistentInheritance_returnType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
int x();
}
@@ -851,14 +801,13 @@
}
abstract class C implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
]);
}
test_inconsistentInheritanceGetterAndMethod_getter_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
int get x;
}
@@ -867,14 +816,13 @@
}
abstract class C implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_inconsistentInheritanceGetterAndMethod_method_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
int x();
}
@@ -883,14 +831,13 @@
}
abstract class C implements A, B {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
]);
}
test_issue32815() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A<T> extends B<T> {}
class B<T> extends A<T> {}
class C<T> extends B<T> implements I<T> {}
@@ -901,15 +848,13 @@
Iterable<I<int>> x = [new C()];
}
''');
- await resolveTestFile();
assertHasTestErrors();
}
test_recursiveInterfaceInheritance_extends() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A extends B {}
class B extends A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -917,10 +862,9 @@
}
test_recursiveInterfaceInheritance_extends_implements() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A extends B {}
class B implements A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -928,10 +872,9 @@
}
test_recursiveInterfaceInheritance_implements() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A implements B {}
class B implements A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -939,10 +882,9 @@
}
test_recursiveInterfaceInheritance_mixin() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class M1 = Object with M2;
class M2 = Object with M1;''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -952,12 +894,11 @@
test_recursiveInterfaceInheritance_mixin_superclass() async {
// Make sure we don't get CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS in
// addition--that would just be confusing.
- addTestFile('''
+ await resolveTestCode('''
class C = D with M;
class D = C with M;
class M {}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
@@ -965,20 +906,18 @@
}
test_recursiveInterfaceInheritance_tail() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A implements A {}
class B implements A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
test_recursiveInterfaceInheritance_tail2() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A implements B {}
abstract class B implements A {}
class C implements A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
@@ -986,12 +925,11 @@
}
test_recursiveInterfaceInheritance_tail3() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A implements B {}
abstract class B implements C {}
abstract class C implements A {}
class D implements A {}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
@@ -1000,95 +938,86 @@
}
test_recursiveInterfaceInheritanceExtends() async {
- addTestFile("class A extends A {}");
- await resolveTestFile();
+ await resolveTestCode("class A extends A {}");
assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS]);
}
test_recursiveInterfaceInheritanceExtends_abstract() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C extends C {
var bar = 0;
m();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_EXTENDS,
]);
}
test_recursiveInterfaceInheritanceImplements() async {
- addTestFile("class A implements A {}");
- await resolveTestFile();
+ await resolveTestCode("class A implements A {}");
assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
test_recursiveInterfaceInheritanceImplements_typeAlias() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class M {}
class B = A with M implements B;''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_IMPLEMENTS]);
}
test_recursiveInterfaceInheritanceWith() async {
- addTestFile("class M = Object with M;");
- await resolveTestFile();
+ await resolveTestCode("class M = Object with M;");
assertTestErrorsWithCodes([
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_WITH,
]);
}
test_undefinedSuperGetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
get g {
return super.g;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_GETTER]);
}
test_undefinedSuperMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
m() {
return super.m();
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_METHOD]);
}
test_undefinedSuperOperator_binaryExpression() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
operator +(value) {
return super + value;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperOperator_indexBoth() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
operator [](index) {
return super[index]++;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
@@ -1096,38 +1025,35 @@
}
test_undefinedSuperOperator_indexGetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
operator [](index) {
return super[index + 1];
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperOperator_indexSetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
operator []=(index, value) {
super[index] = 0;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
}
test_undefinedSuperSetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
f() {
super.m = 0;
}
}''');
- await resolveTestFile();
assertTestErrorsWithCodes([StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index fec0505..d09efd3 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -24,11 +24,10 @@
const A({int p});
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
const a = const A();
''');
- await resolveTestFile();
assertNoTestErrors();
var aLib = findElement.import('package:test/a.dart').importedLibrary;
@@ -42,7 +41,7 @@
}
test_constFactoryRedirection_super() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class I {
const factory I(int f) = B;
}
@@ -60,7 +59,6 @@
@I(42)
main() {}
''');
- await resolveTestFile();
assertNoTestErrors();
var node = findNode.annotation('@I');
@@ -69,7 +67,7 @@
}
test_constNotInitialized() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class B {
const B(_);
}
@@ -79,7 +77,6 @@
const C() : super(a);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
@@ -95,12 +92,11 @@
const C();
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
const v = a;
''');
- await resolveTestFile();
assertNoTestErrors();
var v = findElement.topVar('v') as ConstVariableElement;
diff --git a/pkg/analyzer/test/src/dart/resolution/constructor_test.dart b/pkg/analyzer/test/src/dart/resolution/constructor_test.dart
index b91fbda..db7428a 100644
--- a/pkg/analyzer/test/src/dart/resolution/constructor_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constructor_test.dart
@@ -15,24 +15,22 @@
@reflectiveTest
class ConstructorResolutionTest extends DriverResolutionTest {
test_initializer_field_functionExpression_expressionBody() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
final int x;
C(int a) : x = (() => a + 1)();
}
''');
- await resolveTestFile();
assertElement(findNode.simple('a + 1'), findElement.parameter('a'));
}
test_initializer_field_functionExpression_blockBody() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
var x;
C(int a) : x = (() {return a + 1;})();
}
''');
- await resolveTestFile();
assertElement(findNode.simple('a + 1'), findElement.parameter('a'));
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index f204d72..3354370 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -16,13 +16,12 @@
@reflectiveTest
class EnumDriverResolutionTest extends DriverResolutionTest {
test_inference_listLiteral() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum E1 {a, b}
enum E2 {a, b}
var v = [E1.a, E2.b];
''');
- await resolveTestFile();
assertNoTestErrors();
var v = findElement.topVar('v');
@@ -30,12 +29,11 @@
}
test_isConstantEvaluated() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
enum E {
aaa, bbb
}
''');
- await resolveTestFile();
assertNoTestErrors();
expect(findElement.field('aaa').isConstantEvaluated, isTrue);
diff --git a/pkg/analyzer/test/src/dart/resolution/export_test.dart b/pkg/analyzer/test/src/dart/resolution/export_test.dart
index 565f72d..5a4455a 100644
--- a/pkg/analyzer/test/src/dart/resolution/export_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/export_test.dart
@@ -21,10 +21,9 @@
get f => null;
set f(_) {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
export 'a.dart';
''');
- await resolveTestFile();
var exportNamespace = result.libraryElement.exportNamespace;
expect(exportNamespace.get('f'), isNotNull);
expect(exportNamespace.get('f='), isNotNull);
diff --git a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
index 54f31ff..b8b7e2a 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_element_test.dart
@@ -16,13 +16,12 @@
@reflectiveTest
class ForEachElementTest extends DriverResolutionTest {
test_declaredIdentifierScope() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
<int>[for (var i in [1, 2, 3]) i]; // 1
<double>[for (var i in [1.1, 2.2, 3.3]) i]; // 2
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertElement(
@@ -39,13 +38,12 @@
@reflectiveTest
class ForLoopElementTest extends DriverResolutionTest {
test_declaredVariableScope() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
<int>[for (var i = 1; i < 10; i += 3) i]; // 1
<double>[for (var i = 1.1; i < 10; i += 5) i]; // 2
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertElement(
diff --git a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
index 5b83f62..a32bf70 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
@@ -18,14 +18,13 @@
test_importPrefix_asIterable() async {
// TODO(scheglov) Remove this test (already tested as import prefix).
// TODO(scheglov) Move other for-in tests here.
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async' as p;
main() {
for (var x in p) {}
}
''');
- await resolveTestFile();
assertHasTestErrors();
var xRef = findNode.simple('x in');
diff --git a/pkg/analyzer/test/src/dart/resolution/function_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/function_type_alias_test.dart
index c233a3d..3d89872 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_type_alias_test.dart
@@ -17,13 +17,11 @@
@reflectiveTest
class FunctionTypeAliasResolutionTest extends DriverResolutionTest {
test_type_element() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
G<int> g;
typedef T G<T>();
''');
- await resolveTestFile();
-
FunctionType type = findElement.topVar('g').type;
assertElementTypeString(type, 'int Function()');
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index 5dde449..e88a6bc 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -18,61 +18,57 @@
@reflectiveTest
class GenericTypeAliasDriverResolutionTest extends DriverResolutionTest {
test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T> {}
typedef G = Function<S>();
C<G> x;
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T> {}
C<Function<S>()> x;
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
T f<T>(T) => null;
main() {
f<Function<S>()>(null);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
T Function<T>(T) f;
main() {
f<Function<S>()>(null);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
T f<T>(T) => null;
}
@@ -81,54 +77,48 @@
new C().f<Function<S>()>(null);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef T F<T>(T t);
F<Function<S>()> x;
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
);
}
test_genericFunctionTypeCannotBeTypeArgument_OK_def_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T> {}
typedef G = Function();
C<G> x;
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_genericFunctionTypeCannotBeTypeArgument_OK_literal_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T> {}
C<Function()> x;
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_type_element() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
G<int> g;
typedef G<T> = T Function(double);
''');
- await resolveTestFile();
-
FunctionType type = findElement.topVar('g').type;
assertElementTypeString(type, 'int Function(double)');
@@ -142,15 +132,13 @@
}
test_typeParameters() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B {}
typedef F<T extends A> = B<T> Function<U extends B>(T a, U b);
''');
- await resolveTestFile();
-
var f = findElement.genericTypeAlias('F');
expect(f.typeParameters, hasLength(1));
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index c514779..44a4dce 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -17,14 +17,13 @@
@reflectiveTest
class ImportPrefixDriverResolutionTest extends DriverResolutionTest {
test_asExpression_expressionStatement() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async' as p;
main() {
p; // use
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -35,14 +34,13 @@
}
test_asExpression_forIn_iterable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async' as p;
main() {
for (var x in p) {}
}
''');
- await resolveTestFile();
assertHasTestErrors();
var xRef = findNode.simple('x in');
@@ -54,7 +52,7 @@
}
test_asExpression_instanceCreation_argument() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async' as p;
class C<T> {
@@ -65,7 +63,6 @@
var x = new C(p);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -76,14 +73,13 @@
}
test_asPrefix_methodInvocation() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' as p;
main() {
p.max(0, 0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var pRef = findNode.simple('p.max');
@@ -92,14 +88,13 @@
}
test_asPrefix_prefixedIdentifier() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:async' as p;
main() {
p.Future;
}
''');
- await resolveTestFile();
assertNoTestErrors();
var pRef = findNode.simple('p.Future');
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 962eb5d..3fdea94 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -16,10 +16,9 @@
@reflectiveTest
class InstanceCreationDriverResolutionTest extends DriverResolutionTest {
test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
final foo = Map<int>();
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
]);
@@ -35,7 +34,7 @@
}
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class Foo<X> {
Foo.bar();
}
@@ -44,7 +43,6 @@
new Foo.bar<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -66,14 +64,13 @@
Foo.bar();
}
''');
- addTestFile('''
+ await resolveTestCode('''
import 'a.dart' as p;
main() {
new p.Foo.bar<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -92,7 +89,7 @@
}
test_error_wrongNumberOfTypeArgumentsConstructor_implicitNew() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class Foo<X> {
Foo.bar();
}
@@ -101,7 +98,6 @@
Foo.bar<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
@@ -127,14 +123,13 @@
Foo.bar();
}
''');
- addTestFile('''
+ await resolveTestCode('''
import 'a.dart' as p;
main() {
p.Foo.bar<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
]);
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
index 44c13fe..1de534c 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -16,16 +16,15 @@
class InstanceMemberInferenceClassDriverResolutionTest
extends DriverResolutionTest {
test_invalid_inheritanceCycle() async {
- addTestFile('''
+ await resolveTestCode('''
class A extends C {}
class B extends A {}
class C extends B {}
''');
- await resolveTestFile();
}
test_method_parameter_multiple_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo(int p) => 0;
}
@@ -36,14 +35,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_named_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -54,14 +51,12 @@
foo({p}) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_named_same() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -72,14 +67,12 @@
foo({p}) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeString(p.type, 'int');
}
test_method_parameter_multiple_namedAndRequired() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -90,14 +83,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_optionalAndRequired() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo(int p) => 0;
}
@@ -108,14 +99,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeString(p.type, 'int');
}
test_method_parameter_single_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
foo(E p) => 0;
}
@@ -123,14 +112,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'C').parameters[0];
assertElementTypeString(p.type, 'T');
}
test_method_return_multiple_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -141,14 +128,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_different_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => null;
}
@@ -159,14 +144,12 @@
foo() => null;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_different_void() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -177,14 +160,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -195,14 +176,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_same_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => 0;
}
@@ -213,14 +192,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeString(foo.returnType, 'T');
}
test_method_return_multiple_same_nonVoid() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -231,14 +208,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeString(foo.returnType, 'int');
}
test_method_return_multiple_same_void() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {};
}
@@ -249,14 +224,12 @@
foo() {};
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'C');
assertElementTypeString(foo.returnType, 'void');
}
test_method_return_single() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -264,14 +237,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'B');
assertElementTypeString(foo.returnType, 'int');
}
test_method_return_single_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => 0;
}
@@ -279,8 +250,6 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'B');
assertElementTypeString(foo.returnType, 'T');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
index 0368dd9..9d188eb 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -16,16 +16,15 @@
class InstanceMemberInferenceMixinDriverResolutionTest
extends DriverResolutionTest {
test_invalid_inheritanceCycle() async {
- addTestFile('''
+ await resolveTestCode('''
mixin A on C {}
mixin B on A {}
mixin C on B {}
''');
- await resolveTestFile();
}
test_method_parameter_multiple_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo(int p) => 0;
}
@@ -36,14 +35,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_named_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -54,14 +51,12 @@
foo({p}) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_named_same() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -72,14 +67,12 @@
foo({p}) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeString(p.type, 'int');
}
test_method_parameter_multiple_namedAndRequired() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo({int p}) => 0;
}
@@ -90,14 +83,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeDynamic(p.type);
}
test_method_parameter_multiple_optionalAndRequired() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
foo(int p) => 0;
}
@@ -108,14 +99,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeString(p.type, 'int');
}
test_method_parameter_single_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
foo(E p) => 0;
}
@@ -123,14 +112,12 @@
foo(p) => 0;
}
''');
- await resolveTestFile();
-
var p = findElement.method('foo', of: 'M').parameters[0];
assertElementTypeString(p.type, 'T');
}
test_method_return_multiple_different() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -141,14 +128,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_different_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => null;
}
@@ -159,14 +144,12 @@
foo() => null;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_different_void() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -177,14 +160,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -195,14 +176,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeDynamic(foo.returnType);
}
test_method_return_multiple_same_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => 0;
}
@@ -213,14 +192,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeString(foo.returnType, 'T');
}
test_method_return_multiple_same_nonVoid() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -231,14 +208,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeString(foo.returnType, 'int');
}
test_method_return_multiple_same_void() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
void foo() {};
}
@@ -249,14 +224,12 @@
foo() {};
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeString(foo.returnType, 'void');
}
test_method_return_single() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo() => 0;
}
@@ -264,14 +237,12 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeString(foo.returnType, 'int');
}
test_method_return_single_generic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E> {
E foo() => 0;
}
@@ -279,8 +250,6 @@
foo() => 0;
}
''');
- await resolveTestFile();
-
var foo = findElement.method('foo', of: 'M');
assertElementTypeString(foo.returnType, 'T');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 14dc87d..c2520f8 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -15,7 +15,7 @@
@reflectiveTest
class MetadataResolutionTest extends DriverResolutionTest {
- test_constructor_named() async {
+ test_otherLibrary_constructor_named() async {
newFile('/test/lib/a.dart', content: r'''
class A {
final int f;
@@ -30,22 +30,21 @@
class B {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'b.dart';
B b;
''');
- await resolveTestFile();
assertNoTestErrors();
var classB = findNode.typeName('B b;').name.staticElement;
var annotation = classB.metadata.single;
var value = annotation.computeConstantValue();
- expect(value, isNotNull);
+ assertElementTypeString(value.type, 'A');
expect(value.getField('f').toIntValue(), 42);
}
- test_constructor_unnamed() async {
+ test_otherLibrary_constructor_unnamed() async {
newFile('/test/lib/a.dart', content: r'''
class A {
final int f;
@@ -60,22 +59,21 @@
class B {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'b.dart';
B b;
''');
- await resolveTestFile();
assertNoTestErrors();
var classB = findNode.typeName('B b;').name.staticElement;
var annotation = classB.metadata.single;
var value = annotation.computeConstantValue();
- expect(value, isNotNull);
+ assertElementTypeString(value.type, 'A');
expect(value.getField('f').toIntValue(), 42);
}
- test_implicitConst() async {
+ test_otherLibrary_implicitConst() async {
newFile('/test/lib/a.dart', content: r'''
class A {
final int f;
@@ -91,18 +89,33 @@
class C {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
C c;
''');
- await resolveTestFile();
assertNoTestErrors();
var classC = findNode.typeName('C c;').name.staticElement;
var annotation = classC.metadata.single;
var value = annotation.computeConstantValue();
- expect(value, isNotNull);
+ assertElementTypeString(value.type, 'B');
expect(value.getField('a').getField('f').toIntValue(), 42);
}
+
+ test_sameLibrary_genericClass_constructor_unnamed() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ final T f;
+ const A(this.f);
+}
+
+@A(42)
+class B {}
+''');
+ var annotation = findElement.class_('B').metadata.single;
+ var value = annotation.computeConstantValue();
+ assertElementTypeString(value.type, 'A<int>');
+ expect(value.getField('f').toIntValue(), 42);
+ }
}
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index c31ff84..f600ea3 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -18,7 +18,7 @@
@reflectiveTest
class MethodInvocationResolutionTest extends DriverResolutionTest {
test_error_abstractSuperMemberReference() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class A {
void foo(int _);
}
@@ -30,7 +30,6 @@
void foo(int _) {} // does not matter
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
@@ -44,7 +43,7 @@
}
test_error_abstractSuperMemberReference_mixin_implements() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void foo(int _) {}
}
@@ -55,7 +54,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
@@ -69,7 +67,7 @@
}
test_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int foo();
noSuchMethod(im) => 42;
@@ -80,7 +78,6 @@
noSuchMethod(im) => 87;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
@@ -94,7 +91,7 @@
}
test_error_abstractSuperMemberReference_OK_mixinHasConcrete() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class M {
@@ -109,7 +106,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -122,7 +118,7 @@
}
test_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int foo();
noSuchMethod(im) => 42;
@@ -133,7 +129,6 @@
noSuchMethod(im) => 87;
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('super.foo(); // ref');
@@ -146,7 +141,7 @@
}
test_error_abstractSuperMemberReference_OK_superSuperHasConcrete() async {
- addTestFile('''
+ await resolveTestCode('''
abstract class A {
void foo(int _) {}
}
@@ -161,7 +156,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -181,7 +175,7 @@
void foo(int _) {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
import 'b.dart';
@@ -189,7 +183,6 @@
foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.AMBIGUOUS_IMPORT,
]);
@@ -207,7 +200,7 @@
void foo(int _) {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as p;
import 'b.dart' as p;
@@ -215,7 +208,6 @@
p.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.AMBIGUOUS_IMPORT,
]);
@@ -226,7 +218,7 @@
}
test_error_instanceAccessToStaticMember_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
static void foo(int _) {}
}
@@ -235,7 +227,6 @@
a.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
]);
@@ -247,7 +238,7 @@
}
test_error_invocationOfNonFunction_interface_hasCall_field() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void Function() call;
}
@@ -256,7 +247,6 @@
c();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
@@ -267,13 +257,12 @@
}
test_error_invocationOfNonFunction_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
Object foo;
foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
@@ -285,19 +274,18 @@
}
test_error_invocationOfNonFunction_OK_dynamic_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var foo;
foo();
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation('foo();', findElement.localVar('foo'));
}
test_error_invocationOfNonFunction_OK_dynamicGetter_instance() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
var foo;
}
@@ -306,7 +294,6 @@
c.foo();
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation(
'c.foo();',
@@ -316,7 +303,7 @@
}
test_error_invocationOfNonFunction_OK_dynamicGetter_superClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
var foo;
}
@@ -327,7 +314,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation(
'foo();',
@@ -337,7 +323,7 @@
}
test_error_invocationOfNonFunction_OK_dynamicGetter_thisClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
var foo;
@@ -346,7 +332,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation(
'foo();',
@@ -356,18 +341,17 @@
}
test_error_invocationOfNonFunction_OK_Function() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
f(Function foo) {
foo(1, 2);
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation('foo(1, 2);', findElement.parameter('foo'));
}
test_error_invocationOfNonFunction_OK_functionTypeTypeParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
typedef MyFunction = double Function(int _);
class C<T extends MyFunction> {
@@ -378,7 +362,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertMethodInvocation(
findNode.methodInvocation('foo(0)'),
@@ -389,7 +372,7 @@
}
test_error_invocationOfNonFunction_static_hasTarget() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static int foo;
}
@@ -398,7 +381,6 @@
C.foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
@@ -410,7 +392,7 @@
}
test_error_invocationOfNonFunction_static_noTarget() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static int foo;
@@ -419,7 +401,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
@@ -431,7 +412,7 @@
}
test_error_invocationOfNonFunction_super_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get foo => 0;
}
@@ -442,7 +423,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
]);
@@ -458,14 +438,13 @@
void foo() {}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as prefix;
main() {
prefix?.foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -482,14 +461,13 @@
}
test_error_prefixIdentifierNotFollowedByDot_deferred() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' deferred as math;
main() {
math?.loadLibrary();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -506,14 +484,13 @@
}
test_error_prefixIdentifierNotFollowedByDot_invoke() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' as foo;
main() {
foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -525,12 +502,11 @@
}
test_error_undefinedFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_FUNCTION,
]);
@@ -538,14 +514,13 @@
}
test_error_undefinedFunction_hasTarget_importPrefix() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' as math;
main() {
math.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_FUNCTION,
]);
@@ -553,12 +528,11 @@
}
test_error_undefinedIdentifier_target() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
bar.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.UNDEFINED_IDENTIFIER,
]);
@@ -566,13 +540,12 @@
}
test_error_undefinedMethod_hasTarget_class() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {}
main() {
C.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -580,7 +553,7 @@
}
test_error_undefinedMethod_hasTarget_class_arguments() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {}
int x;
@@ -588,7 +561,6 @@
C.foo(x);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -598,7 +570,7 @@
}
test_error_undefinedMethod_hasTarget_class_inSuperclass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class S {
static void foo(int _) {}
}
@@ -609,7 +581,6 @@
C.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -617,14 +588,13 @@
}
test_error_undefinedMethod_hasTarget_class_typeArguments() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {}
main() {
C.foo<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -637,12 +607,11 @@
}
test_error_undefinedMethod_hasTarget_class_typeParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T> {
static main() => C.T();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -650,12 +619,11 @@
}
test_error_undefinedMethod_hasTarget_instance() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
42.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -663,13 +631,12 @@
}
test_error_undefinedMethod_hasTarget_localVariable_function() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var v = () {};
v.foo(0);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -677,14 +644,13 @@
}
test_error_undefinedMethod_noTarget() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
main() {
foo(0);
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -692,24 +658,22 @@
}
test_error_undefinedMethod_object_call() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main(Object o) {
o.call();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
}
test_error_undefinedMethod_OK_null() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
null.foo();
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertUnresolvedMethodInvocation('foo();');
}
@@ -720,7 +684,7 @@
void _foo(int _) {}
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart';
class B extends A {
@@ -729,7 +693,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -737,7 +700,7 @@
}
test_error_undefinedMethod_typeLiteral_cascadeTarget() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static void foo() {}
}
@@ -746,7 +709,6 @@
C..foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
@@ -755,20 +717,19 @@
test_error_undefinedMethod_typeLiteral_conditional() async {
// When applied to a type literal, the conditional access operator '?.'
// cannot be used to access instance methods of Type.
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
main() {
A?.toString();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_METHOD,
]);
}
test_error_undefinedSuperMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {}
class B extends A {
@@ -777,7 +738,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
]);
@@ -786,7 +746,7 @@
}
test_error_unqualifiedReferenceToNonLocalStaticMember_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
static void foo() {}
}
@@ -797,7 +757,6 @@
}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
]);
@@ -813,7 +772,7 @@
/// single error generated when the only problem is that an imported file
/// does not exist.
test_error_uriDoesNotExist_prefixed() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'missing.dart' as p;
main() {
@@ -821,7 +780,6 @@
p.bar(2);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
]);
@@ -833,7 +791,7 @@
/// single error generated when the only problem is that an imported file
/// does not exist.
test_error_uriDoesNotExist_show() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'missing.dart' show foo, bar;
main() {
@@ -841,7 +799,6 @@
bar(2);
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.URI_DOES_NOT_EXIST,
]);
@@ -850,7 +807,7 @@
}
test_error_useOfVoidResult_name_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C<T>{
T foo;
}
@@ -859,7 +816,6 @@
c.foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -872,13 +828,12 @@
}
test_error_useOfVoidResult_name_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo;
foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -890,14 +845,13 @@
}
test_error_useOfVoidResult_name_topFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo() {}
main() {
foo()();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -909,14 +863,13 @@
}
test_error_useOfVoidResult_name_topVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo;
main() {
foo();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -929,13 +882,12 @@
}
test_error_useOfVoidResult_receiver() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo;
foo.toString();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -948,13 +900,12 @@
}
test_error_useOfVoidResult_receiver_cascade() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo;
foo..toString();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -967,13 +918,12 @@
}
test_error_useOfVoidResult_receiver_withNull() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo;
foo?.toString();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticWarningCode.USE_OF_VOID_RESULT,
]);
@@ -986,14 +936,13 @@
}
test_error_wrongNumberOfTypeArgumentsMethod_01() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo() {}
main() {
foo<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
]);
@@ -1006,14 +955,13 @@
}
test_error_wrongNumberOfTypeArgumentsMethod_21() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
Map<T, U> foo<T extends num, U>() => null;
main() {
foo<int>();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
]);
@@ -1027,7 +975,7 @@
}
test_hasReceiver_class_staticGetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static double Function(int) get foo => null;
}
@@ -1036,7 +984,6 @@
C.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1050,7 +997,7 @@
}
test_hasReceiver_class_staticMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
static void foo(int _) {}
}
@@ -1059,7 +1006,6 @@
C.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1072,14 +1018,13 @@
}
test_hasReceiver_deferredImportPrefix_loadLibrary() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' deferred as math;
main() {
math.loadLibrary();
}
''');
- await resolveTestFile();
assertNoTestErrors();
var import = findElement.importFind('dart:math');
@@ -1094,14 +1039,13 @@
}
test_hasReceiver_functionTyped_call() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo(int _) {}
main() {
foo.call(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('call(0)');
@@ -1119,14 +1063,13 @@
T foo<T extends num>(T a, T b) => a;
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as prefix;
main() {
prefix.foo(1, 2);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var import = findElement.importFind('package:test/a.dart');
@@ -1146,14 +1089,13 @@
T Function<T>(T a, T b) get foo => null;
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as prefix;
main() {
prefix.foo(1, 2);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var import = findElement.importFind('package:test/a.dart');
@@ -1170,33 +1112,31 @@
}
test_hasReceiver_instance_Function_call_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void main() {
Function foo;
foo.call(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation('call(0)', null);
}
test_hasReceiver_instance_Function_call_topVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
Function foo;
void main() {
foo.call(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertInvalidInvocation('call(0)', null);
}
test_hasReceiver_instance_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
double Function(int) get foo => null;
}
@@ -1205,7 +1145,6 @@
c.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1218,7 +1157,7 @@
}
test_hasReceiver_instance_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void foo(int _) {}
}
@@ -1227,7 +1166,6 @@
c.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1241,7 +1179,7 @@
}
test_hasReceiver_instance_method_generic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
T foo<T>(T a) {
return a;
@@ -1252,7 +1190,6 @@
c.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1267,7 +1204,7 @@
}
test_hasReceiver_instance_method_issue30552() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
abstract class I1 {
void foo(int i);
}
@@ -1286,7 +1223,6 @@
c.foo('hi');
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation("foo('hi')");
@@ -1298,7 +1234,7 @@
}
test_hasReceiver_instance_typeParameter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void foo(int _) {}
}
@@ -1311,7 +1247,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1329,14 +1264,13 @@
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as prefix;
main() {
prefix.C.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var import = findElement.importFind('package:test/a.dart');
@@ -1361,14 +1295,13 @@
}
''');
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'a.dart' as prefix;
main() {
prefix.C.foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var import = findElement.importFind('package:test/a.dart');
@@ -1386,7 +1319,7 @@
}
test_hasReceiver_super_getter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
double Function(int) get foo => null;
}
@@ -1397,7 +1330,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1411,7 +1343,7 @@
}
test_hasReceiver_super_method() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void foo(int _) {}
}
@@ -1422,7 +1354,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0);');
@@ -1435,14 +1366,13 @@
}
test_namedArgument() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo({int a, bool b}) {}
main() {
foo(b: false, a: 0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(b:');
@@ -1456,7 +1386,7 @@
}
test_noReceiver_getter_superClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
double Function(int) get foo => null;
}
@@ -1467,7 +1397,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1480,7 +1409,7 @@
}
test_noReceiver_getter_thisClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
double Function(int) get foo => null;
@@ -1489,7 +1418,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1502,14 +1430,13 @@
}
test_noReceiver_importPrefix() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'dart:math' as math;
main() {
math();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([
CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
]);
@@ -1517,14 +1444,13 @@
}
test_noReceiver_localFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void foo(int _) {}
foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1536,14 +1462,13 @@
}
test_noReceiver_localVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
void Function(int) foo;
foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1555,7 +1480,7 @@
}
test_noReceiver_localVariable_call() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void call(int _) {}
}
@@ -1564,7 +1489,6 @@
c(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('c(0);');
@@ -1576,7 +1500,7 @@
}
test_noReceiver_localVariable_promoted() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var foo;
if (foo is void Function(int)) {
@@ -1584,7 +1508,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1596,7 +1519,7 @@
}
test_noReceiver_method_superClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
void foo(int _) {}
}
@@ -1607,7 +1530,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1619,7 +1541,7 @@
}
test_noReceiver_method_thisClass() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class C {
void foo(int _) {}
@@ -1628,7 +1550,6 @@
}
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1640,14 +1561,13 @@
}
test_noReceiver_topFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo(int _) {}
main() {
foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1660,14 +1580,13 @@
}
test_noReceiver_topGetter() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
double Function(int) get foo => null;
main() {
foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1680,14 +1599,13 @@
}
test_noReceiver_topVariable() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void Function(int) foo;
main() {
foo(0);
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('foo(0)');
@@ -1700,26 +1618,24 @@
}
test_objectMethodOnDynamic() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
var v;
v.toString(42);
}
''');
- await resolveTestFile();
assertNoTestErrors();
_assertUnresolvedMethodInvocation('toString(42);');
}
test_objectMethodOnFunction() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void f() {}
main() {
f.toString();
}
''');
- await resolveTestFile();
assertNoTestErrors();
var invocation = findNode.methodInvocation('toString();');
@@ -1757,29 +1673,25 @@
}
test_typeArgumentTypes_generic_typeArguments_notBounds() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo<T extends num>() {}
main() {
foo<bool>();
}
''');
- await resolveTestFile();
-
var invocation = findNode.methodInvocation('foo<bool>();');
assertTypeArgumentTypes(invocation, ['bool']);
}
test_typeArgumentTypes_generic_typeArguments_wrongNumber() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
void foo<T>() {}
main() {
foo<int, double>();
}
''');
- await resolveTestFile();
-
var invocation = findNode.methodInvocation('foo<int, double>();');
assertTypeArgumentTypes(invocation, ['dynamic']);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 8ebd753..b69b39a 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -857,14 +857,13 @@
}
test_error_mixinInstantiate_default() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
mixin M {}
main() {
new M();
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([CompileTimeErrorCode.MIXIN_INSTANTIATE]);
var creation = findNode.instanceCreation('M();');
diff --git a/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart b/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
index 35f6532..68665ba 100644
--- a/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/non_nullable_test.dart
@@ -27,14 +27,13 @@
bool get typeToStringWithNullability => true;
test_class_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class X1 extends A {} // 1
class X2 implements A {} // 2
class X3 with A {} // 3
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A {} // 1'), 'A');
@@ -43,14 +42,13 @@
}
test_classTypeAlias_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B {}
class C {}
class X = A with B implements C;
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A with'), 'A');
@@ -59,26 +57,24 @@
}
test_local_getterNullAwareAccess_interfaceType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int? x;
return x?.isEven;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.propertyAccess('x?.isEven'), 'bool?');
}
test_local_interfaceType() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
int? a = 0;
int b = 0;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('int? a'), 'int?');
@@ -86,7 +82,7 @@
}
test_local_interfaceType_generic() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
List<int?>? a = [];
List<int>? b = [];
@@ -94,7 +90,6 @@
List<int> d = [];
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('List<int?>? a'), 'List<int?>?');
@@ -104,7 +99,7 @@
}
test_local_methodNullAwareCall_interfaceType() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
class C {
bool x() => true;
}
@@ -115,69 +110,63 @@
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.methodInvocation('c?.x()'), 'bool?');
}
test_local_nullCoalesce_nullableInt_int() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int? x;
int y = 0;
x ?? y;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.binary('x ?? y'), 'int');
}
test_local_nullCoalesce_nullableInt_nullableInt() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int? x;
x ?? x;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.binary('x ?? x'), 'int?');
}
test_local_nullCoalesceAssign_nullableInt_int() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int? x;
int y = 0;
x ??= y;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.assignment('x ??= y'), 'int');
}
test_local_nullCoalesceAssign_nullableInt_nullableInt() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main() {
int? x;
x ??= x;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.assignment('x ??= x'), 'int?');
}
test_local_typeParameter() async {
- addTestFile('''
+ await resolveTestCode('''
main<T>(T a) {
T x = a;
T? y;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('T x'), 'T');
@@ -186,12 +175,11 @@
@failingTest
test_local_variable_genericFunctionType() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
int? Function(bool, String?)? a;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(
@@ -201,12 +189,11 @@
}
test_localFunction_parameter_interfaceType() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
f(int? a, int b) {}
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('int? a'), 'int?');
@@ -214,13 +201,12 @@
}
test_localFunction_returnType_interfaceType() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
int? f() => 0;
int g() => 0;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('int? f'), 'int?');
@@ -228,25 +214,23 @@
}
test_member_potentiallyNullable_called() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
m<T extends Function>() {
List<T?> x;
x.first();
}
''');
- await resolveTestFile();
- // Do not assert no test errors. Deliberately invokes nullable type.
+// Do not assert no test errors. Deliberately invokes nullable type.
assertType(findNode.methodInvocation('first').methodName, 'Function?');
}
test_mixin_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
mixin X1 on A {} // 1
mixin X2 implements A {} // 2
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A {} // 1'), 'A');
@@ -254,36 +238,33 @@
}
test_null_assertion_operator_changes_null_to_never() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
Null x = null;
x!;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.postfix('x!'), 'Never');
}
test_null_assertion_operator_removes_nullability() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
Object? x = null;
x!;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.postfix('x!'), 'Object');
}
@failingTest
test_parameter_genericFunctionType() async {
- addTestFile('''
+ await resolveTestCode('''
main(int? Function(bool, String?)? a) {
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(
@@ -293,23 +274,21 @@
}
test_parameter_getterNullAwareAccess_interfaceType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
main(int? x) {
return x?.isEven;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.propertyAccess('x?.isEven'), 'bool?');
}
test_parameter_interfaceType() async {
- addTestFile('''
+ await resolveTestCode('''
main(int? a, int b) {
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('int? a'), 'int?');
@@ -317,11 +296,10 @@
}
test_parameter_interfaceType_generic() async {
- addTestFile('''
+ await resolveTestCode('''
main(List<int?>? a, List<int>? b, List<int?> c, List<int> d) {
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('List<int?>? a'), 'List<int?>?');
@@ -331,7 +309,7 @@
}
test_parameter_methodNullAwareCall_interfaceType() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
class C {
bool x() => true;
}
@@ -341,61 +319,55 @@
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.methodInvocation('c?.x()'), 'bool?');
}
test_parameter_nullCoalesce_nullableInt_int() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main(int? x, int y) {
x ?? y;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.binary('x ?? y'), 'int');
}
test_parameter_nullCoalesce_nullableInt_nullableInt() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main(int? x) {
x ?? x;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.binary('x ?? x'), 'int?');
}
test_parameter_nullCoalesceAssign_nullableInt_int() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main(int? x, int y) {
x ??= y;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.assignment('x ??= y'), 'int');
}
test_parameter_nullCoalesceAssign_nullableInt_nullableInt() async {
- await addTestFile(r'''
+ await resolveTestCode(r'''
main(int? x) {
x ??= x;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.assignment('x ??= x'), 'int?');
}
test_parameter_typeParameter() async {
- addTestFile('''
+ await resolveTestCode('''
main<T>(T a, T? b) {
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('T a'), 'T');
@@ -403,14 +375,13 @@
}
test_typedef_classic() async {
- addTestFile('''
+ await resolveTestCode('''
typedef int? F(bool a, String? b);
main() {
F? a;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('F? a'), 'int? Function(bool, String?)?');
@@ -418,14 +389,13 @@
@failingTest
test_typedef_function() async {
- addTestFile('''
+ await resolveTestCode('''
typedef F<T> = int? Function(bool, T, T?);
main() {
F<String>? a;
}
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(
@@ -441,14 +411,13 @@
bool get typeToStringWithNullability => true;
test_class_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class X1 extends A {} // 1
class X2 implements A {} // 2
class X3 with A {} // 3
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A {} // 1'), 'A*');
@@ -457,14 +426,13 @@
}
test_classTypeAlias_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
class B {}
class C {}
class X = A with B implements C;
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A with'), 'A*');
@@ -473,13 +441,12 @@
}
test_local_variable_interfaceType_notMigrated() async {
- addTestFile('''
+ await resolveTestCode('''
main() {
int? a = 0;
int b = 0;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes([ParserErrorCode.EXPERIMENT_NOT_ENABLED]);
assertType(findNode.typeName('int? a'), 'int*');
@@ -487,13 +454,12 @@
}
test_mixin_hierarchy() async {
- addTestFile('''
+ await resolveTestCode('''
class A {}
mixin X1 on A {} // 1
mixin X2 implements A {} // 2
''');
- await resolveTestFile();
assertNoTestErrors();
assertType(findNode.typeName('A {} // 1'), 'A*');
diff --git a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
index 287b10c..5fbe1d7 100644
--- a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
@@ -197,11 +197,10 @@
''');
}
- addTestFile(r'''
+ await resolveTestCode(r'''
import 'b.dart';
var v = a;
''');
- await resolveTestFile();
_fillLibraries();
PropertyAccessorElement vg = findNode.simple('a;').staticElement;
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
index dcc2d69..ab9db42 100644
--- a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -16,7 +16,7 @@
@reflectiveTest
class PropertyAccessResolutionTest extends DriverResolutionTest {
test_get_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
int get foo;
noSuchMethod(im) => 1;
@@ -27,7 +27,6 @@
noSuchMethod(im) => 2;
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
@@ -37,7 +36,7 @@
}
test_get_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
int get foo;
noSuchMethod(im) => 1;
@@ -48,7 +47,6 @@
noSuchMethod(im) => 2;
}
''');
- await resolveTestFile();
assertNoTestErrors();
var access = findNode.propertyAccess('super.foo; // ref');
@@ -57,7 +55,7 @@
}
test_set_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
- addTestFile('''
+ await resolveTestCode('''
class A {
set foo(int a);
noSuchMethod(im) {}
@@ -68,7 +66,6 @@
noSuchMethod(im) {}
}
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
@@ -82,7 +79,7 @@
}
test_set_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
set foo(int a);
noSuchMethod(im) => 1;
@@ -93,7 +90,6 @@
noSuchMethod(im) => 2;
}
''');
- await resolveTestFile();
assertNoTestErrors();
var access = findNode.propertyAccess('foo = v; // ref');
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 332bcca..aa18ac4 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -169,14 +169,6 @@
expect(element.enclosingElement, expectedEnclosing);
}
- @Deprecated('Use assertErrorsInCode')
- Future<void> assertErrorCodesInCode(
- String code, List<ErrorCode> errors) async {
- addTestFile(code);
- await resolveTestFile();
- assertTestErrorsWithCodes(errors);
- }
-
Future<void> assertErrorsInCode(
String code, List<ExpectedError> expectedErrors) async {
addTestFile(code);
@@ -513,6 +505,12 @@
Future<ResolvedUnitResult> resolveFile(String path);
+ /// Put the [code] into the test file, and resolve it.
+ Future<void> resolveTestCode(String code) async {
+ addTestFile(code);
+ await resolveTestFile();
+ }
+
Future<void> resolveTestFile() async {
var path = convertPath('/test/lib/test.dart');
result = await resolveFile(path);
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 5e56cac..9233974 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -16,13 +16,12 @@
@reflectiveTest
class TopTypeInferenceDriverResolutionTest extends DriverResolutionTest {
test_referenceInstanceVariable_withDeclaredType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
final int a = b + 1;
}
final b = new A().a;
''');
- await resolveTestFile();
assertNoTestErrors();
assertElementTypeString(findElement.field('a').type, 'int');
@@ -30,13 +29,12 @@
}
test_referenceInstanceVariable_withoutDeclaredType() async {
- addTestFile(r'''
+ await resolveTestCode(r'''
class A {
final a = b + 1;
}
final b = new A().a;
''');
- await resolveTestFile();
assertTestErrorsWithCodes([StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
assertElementTypeDynamic(findElement.field('a').type);
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart
index 0b07098..ed4f95f 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/collection_elements_test.dart
@@ -28,204 +28,189 @@
@failingTest
test_list_awaitForIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int>[await for (var e in a()) e];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Stream<dynamic> Function()');
}
@failingTest
test_list_awaitForIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int>[await for (int e in a()) e];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'Stream<int> Function()');
}
@failingTest
test_list_for_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>[for (int i = 0; a(); i++) i];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_list_forIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>[for (var e in a()) e];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<dynamic> Function()');
}
@failingTest
test_list_forIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>[for (int e in a()) e];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
@failingTest
test_map_awaitForIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int, int>{await for (var e in a()) e : e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Stream<dynamic> Function()');
}
@failingTest
test_map_awaitForIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int, int>{await for (int e in a()) e : e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'Stream<int> Function()');
}
@failingTest
test_map_for_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int, int>{for (int i = 0; a(); i++) i : i};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_map_forIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int, int>{for (var e in a()) e : e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<dynamic> Function()');
}
@failingTest
test_map_forIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int, int>{for (int e in a()) e : e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
@failingTest
test_set_awaitForIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int>{await for (var e in a()) e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Stream<dynamic> Function()');
}
@failingTest
test_set_awaitForIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
var b = <int>{await for (int e in a()) e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'Stream<int> Function()');
}
@failingTest
test_set_for_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>{for (int i = 0; a(); i++) i};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_set_forIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>{for (var e in a()) e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<dynamic> Function()');
}
@failingTest
test_set_forIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>{for (int e in a()) e};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
@@ -243,40 +228,37 @@
@failingTest
test_list_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>[if (a()) 1];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_map_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <String, int>{if (a()) 'a' : 1};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_set_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>{if (a()) 1};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
@@ -293,42 +275,39 @@
@failingTest
test_list_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>[...a()];
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
@failingTest
test_map_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <String, int>{...a()};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Map<String, int> Function()');
}
@failingTest
test_set_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
var b = <int>{...a()};
print(b);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
index 72ebc03..ec7660c 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/conditional_expression_test.dart
@@ -18,13 +18,12 @@
@reflectiveTest
class ConditionalExpressionTest extends DriverResolutionTest {
test_upward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(bool a, int b, int c) {
var d = a ? b : c;
print(d);
}
''');
- await resolveTestFile();
assertType(findNode.simple('d)'), 'int');
}
}
@@ -41,14 +40,13 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(int b, int c) {
var d = a() ? b : c;
print(d);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('d)'), 'bool Function()');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart
index d0bf2ff..9997f16 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/equality_expressions_test.dart
@@ -20,13 +20,12 @@
@reflectiveTest
class EqualTest extends DriverResolutionTest {
test_simple() async {
- addTestFile('''
+ await resolveTestCode('''
void f(Object a, Object b) {
var c = a == b;
print(c);
}
''');
- await resolveTestFile();
assertType(findNode.simple('c)'), 'bool');
}
}
@@ -45,13 +44,12 @@
@reflectiveTest
class NotEqualTest extends DriverResolutionTest {
test_simple() async {
- addTestFile('''
+ await resolveTestCode('''
void f(Object a, Object b) {
var c = a != b;
print(c);
}
''');
- await resolveTestFile();
assertType(findNode.simple('c)'), 'bool');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index daf22e8..a2f10f6 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -15,62 +15,55 @@
@reflectiveTest
class ListLiteralTest extends DriverResolutionTest {
test_context_noTypeArgs_expression_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> a = ['a'];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_context_noTypeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> a = [1];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_context_noTypeArgs_noElements() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = [];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
test_context_noTypeArgs_noElements_typeParameter() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends List<int>> {
E a = [];
}
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<dynamic>');
}
test_context_noTypeArgs_noElements_typeParameter_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends List<dynamic>> {
E a = [];
}
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<dynamic>');
}
test_context_typeArgs_expression_conflictingContext() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <int>[0];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_context_typeArgs_expression_conflictingExpression() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <String>[0];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
@@ -78,242 +71,215 @@
test_context_typeArgs_expression_conflictingTypeArgs() async {
// Context type and element types both suggest `String`, so this should
// override the explicit type argument.
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <int>['a'];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
test_context_typeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <String>['a'];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
test_context_typeArgs_noElements_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <int>[];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_context_typeArgs_noElements_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
List<String> a = <String>[];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
test_noContext_noTypeArgs_expressions_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
var a = [1, 2, 3];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_noContext_noTypeArgs_expressions_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
var a = [1, 2.3, 4];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<num>');
}
test_noContext_noTypeArgs_expressions_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
var a = [1, '2', 3];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<Object>');
}
test_noContext_noTypeArgs_forEachWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
var a = [for (int e in c) e * 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[for'), 'List<int>');
}
test_noContext_noTypeArgs_forEachWithIdentifier() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
int b;
var a = [for (b in c) b * 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[for'), 'List<int>');
}
test_noContext_noTypeArgs_forWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
var a = [for (var i = 0; i < 2; i++) i * 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[for'), 'List<int>');
}
test_noContext_noTypeArgs_forWithExpression() async {
- addTestFile('''
+ await resolveTestCode('''
int i;
var a = [for (i = 0; i < 2; i++) i * 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[for'), 'List<int>');
}
test_noContext_noTypeArgs_if() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = [if (c) 1];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_noContext_noTypeArgs_ifElse_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = [if (c) 1 else 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_noContext_noTypeArgs_ifElse_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = [if (c) 1 else 2.3];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<num>');
}
test_noContext_noTypeArgs_ifElse_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = [if (c) 1 else '2'];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<Object>');
}
test_noContext_noTypeArgs_noElements() async {
- addTestFile('''
+ await resolveTestCode('''
var a = [];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<dynamic>');
}
test_noContext_noTypeArgs_spread() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
var a = [...c];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[...'), 'List<int>');
}
test_noContext_noTypeArgs_spread_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<int> b;
var a = [...b, ...c];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[...'), 'List<int>');
}
test_noContext_noTypeArgs_spread_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<double> b;
var a = [...b, ...c];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[...'), 'List<num>');
}
test_noContext_noTypeArgs_spread_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<String> b;
var a = [...b, ...c];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('[...'), 'List<Object>');
}
test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
dynamic d;
var a = [if (0 < 1) ...c else ...d];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<dynamic>');
}
test_noContext_noTypeArgs_spread_nullAware_nullAndNotNull() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
var futureNull = Future.value(null);
var a = [1, ...?await futureNull, 2];
}
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<dynamic>');
}
test_noContext_noTypeArgs_spread_nullAware_onlyNull() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
var futureNull = Future.value(null);
var a = [...?await futureNull];
}
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<Null>');
}
test_noContext_typeArgs_expression_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <String>[1];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<String>');
}
test_noContext_typeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int>[1];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
@failingTest
test_noContext_typeArgs_expressions_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int, String>[1, 2];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<int>');
}
test_noContext_typeArgs_noElements() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <num>[];
''');
- await resolveTestFile();
assertType(findNode.listLiteral('['), 'List<num>');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart
index bf31077..764822a 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/logical_boolean_expressions_test.dart
@@ -20,13 +20,12 @@
@reflectiveTest
class LogicalAndTest extends DriverResolutionTest {
test_upward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(bool a, bool b) {
var c = a && b;
print(c);
}
''');
- await resolveTestFile();
assertType(findNode.simple('c)'), 'bool');
}
}
@@ -43,7 +42,7 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(b) {
var c = a() && b();
print(c);
@@ -51,7 +50,6 @@
T a<T>() => throw '';
T b<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
assertInvokeType(findNode.methodInvocation('b('), 'bool Function()');
}
@@ -60,13 +58,12 @@
@reflectiveTest
class LogicalOrTest extends DriverResolutionTest {
test_upward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(bool a, bool b) {
var c = a || b;
print(c);
}
''');
- await resolveTestFile();
assertType(findNode.simple('c)'), 'bool');
}
}
@@ -83,7 +80,7 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(b) {
var c = a() || b();
print(c);
@@ -91,7 +88,6 @@
T a<T>() => throw '';
T b<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
assertInvokeType(findNode.methodInvocation('b('), 'bool Function()');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
index d09d57f..9ed2abc 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/map_literal_test.dart
@@ -18,346 +18,307 @@
AstNode setOrMapLiteral(String search) => findNode.setOrMapLiteral(search);
test_context_noTypeArgs_entry_conflictingKey() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> a = {'a' : 1};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_context_noTypeArgs_entry_conflictingValue() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> a = {1 : 'a'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_context_noTypeArgs_entry_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> a = {1 : 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_context_noTypeArgs_noEntries() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = {};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, String>');
}
test_context_noTypeArgs_noEntries_typeParameters() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends Map<int, String>> {
E a = {};
}
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{}'), 'Map<dynamic, dynamic>');
}
test_context_noTypeArgs_noEntries_typeParameters_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends Map<dynamic, dynamic>> {
E a = {};
}
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{}'), 'Map<dynamic, dynamic>');
}
test_context_typeArgs_entry_conflictingKey() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = <String, String>{0 : 'a'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, String>');
}
test_context_typeArgs_entry_conflictingValue() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = <String, String>{'a' : 1};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, String>');
}
test_context_typeArgs_entry_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = <String, String>{'a' : 'b'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, String>');
}
test_context_typeArgs_noEntries_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = <int, int>{};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_context_typeArgs_noEntries_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, String> a = <String, String>{};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, String>');
}
test_default_constructor_param_typed() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
const C({x = const <String, int>{}});
}
''');
- await resolveTestFile();
}
test_default_constructor_param_untyped() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
const C({x = const {}});
}
''');
- await resolveTestFile();
}
test_noContext_noTypeArgs_expressions_lubOfIntAndString() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1 : 'a', 2 : 'b', 3 : 'c'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, String>');
}
test_noContext_noTypeArgs_expressions_lubOfNumAndNum() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1 : 2, 3.0 : 4, 5 : 6.0};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<num, num>');
}
test_noContext_noTypeArgs_expressions_lubOfObjectAndObject() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1 : '1', '2' : 2, 3 : '3'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<Object, Object>');
}
test_noContext_noTypeArgs_forEachWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
var a = {for (int e in c) e : e * 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{for'), 'Map<int, int>');
}
test_noContext_noTypeArgs_forEachWithIdentifier() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
int b;
var a = {for (b in c) b * 2 : b};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{for'), 'Map<int, int>');
}
test_noContext_noTypeArgs_forWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {for (var i = 0; i < 2; i++) i : i * 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{for'), 'Map<int, int>');
}
test_noContext_noTypeArgs_forWithExpression() async {
- addTestFile('''
+ await resolveTestCode('''
int i;
var a = {for (i = 0; i < 2; i++) i * 2 : i};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{for'), 'Map<int, int>');
}
test_noContext_noTypeArgs_if() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 : 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_noContext_noTypeArgs_ifElse_lubOfIntAndInt() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 : 3 else 2 : 4};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_noContext_noTypeArgs_ifElse_lubOfNumAndNum() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1.0 : 3 else 2 : 4.0};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<num, num>');
}
test_noContext_noTypeArgs_ifElse_lubOfObjectAndObject() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 : '1' else '2': 2 };
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<Object, Object>');
}
test_noContext_noTypeArgs_noEntries() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<dynamic, dynamic>');
}
test_noContext_noTypeArgs_spread() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> c;
var a = {...c};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'Map<int, int>');
}
test_noContext_noTypeArgs_spread_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
var c = {};
var a = {...c};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'Map<dynamic, dynamic>');
}
test_noContext_noTypeArgs_spread_lubOfIntAndInt() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> c;
Map<int, int> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'Map<int, int>');
}
test_noContext_noTypeArgs_spread_lubOfNumAndNum() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, double> c;
Map<double, int> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'Map<num, num>');
}
test_noContext_noTypeArgs_spread_lubOfObjectObject() async {
- addTestFile('''
+ await resolveTestCode('''
Map<int, int> c;
Map<String, String> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'Map<Object, Object>');
}
test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
- addTestFile('''
+ await resolveTestCode('''
Map<String, int> c;
dynamic d;
var a = {if (0 < 1) ...c else ...d};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<dynamic, dynamic>');
}
@failingTest
test_noContext_noTypeArgs_spread_nullAware_nullAndNotNull() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
var futureNull = Future.value(null);
var a = {1 : 'a', ...?await futureNull, 2 : 'b'};
}
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{1'), 'Map<int, String>');
}
test_noContext_noTypeArgs_spread_nullAware_onlyNull() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
var futureNull = Future.value(null);
var a = {...?await futureNull};
}
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{...'), 'dynamic');
}
test_noContext_typeArgs_entry_conflictingKey() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <String, int>{1 : 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, int>');
}
test_noContext_typeArgs_entry_conflictingValue() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <String, int>{'a' : 'b'};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<String, int>');
}
test_noContext_typeArgs_entry_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int, int>{1 : 2};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_noContext_typeArgs_expression_conflictingElement() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int, String>{1};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, String>');
}
@failingTest
test_noContext_typeArgs_expressions_conflictingTypeArgs() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int>{1 : 2, 3 : 4};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<int, int>');
}
test_noContext_typeArgs_noEntries() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <num, String>{};
''');
- await resolveTestFile();
assertType(setOrMapLiteral('{'), 'Map<num, String>');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart
index 60335c4..93067e4 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/prefix_expressions_test.dart
@@ -18,13 +18,12 @@
@reflectiveTest
class NotTest extends DriverResolutionTest {
test_upward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(bool a) {
var b = !a;
print(b);
}
''');
- await resolveTestFile();
assertType(findNode.simple('b)'), 'bool');
}
}
@@ -41,14 +40,13 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f(b) {
var c = !a();
print(c);
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
index a6a6664..a880513 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/set_literal_test.dart
@@ -18,277 +18,246 @@
AstNode setLiteral(String search) => findNode.setOrMapLiteral(search);
test_context_noTypeArgs_expression_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
Set<int> a = {'a'};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_context_noTypeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Set<int> a = {1};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_context_noTypeArgs_noElements() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = {};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
test_context_noTypeArgs_noElements_typeParameter() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends Set<int>> {
E a = {};
}
''');
- await resolveTestFile();
assertType(setLiteral('{}'), 'Set<dynamic>');
}
test_context_noTypeArgs_noElements_typeParameter_dynamic() async {
- addTestFile('''
+ await resolveTestCode('''
class A<E extends Set<dynamic>> {
E a = {};
}
''');
- await resolveTestFile();
assertType(setLiteral('{}'), 'Set<dynamic>');
}
test_context_typeArgs_expression_conflictingExpression() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = <String>{0};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
@failingTest
test_context_typeArgs_expression_conflictingTypeArgs() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = <int>{'a'};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
test_context_typeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = <String>{'a'};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
test_context_typeArgs_noElements_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = <int>{};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_context_typeArgs_noElements_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
Set<String> a = <String>{};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
test_noContext_noTypeArgs_expressions_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1, 2, 3};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_noContext_noTypeArgs_expressions_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1, 2.3, 4};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<num>');
}
test_noContext_noTypeArgs_expressions_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {1, '2', 3};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<Object>');
}
test_noContext_noTypeArgs_forEachWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
var a = {for (int e in c) e * 2};
''');
- await resolveTestFile();
assertType(setLiteral('{for'), 'Set<int>');
}
test_noContext_noTypeArgs_forEachWithIdentifier() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
int b;
var a = {for (b in c) b * 2};
''');
- await resolveTestFile();
assertType(setLiteral('{for'), 'Set<int>');
}
test_noContext_noTypeArgs_forWithDeclaration() async {
- addTestFile('''
+ await resolveTestCode('''
var a = {for (var i = 0; i < 2; i++) i * 2};
''');
- await resolveTestFile();
assertType(setLiteral('{for'), 'Set<int>');
}
test_noContext_noTypeArgs_forWithExpression() async {
- addTestFile('''
+ await resolveTestCode('''
int i;
var a = {for (i = 0; i < 2; i++) i * 2};
''');
- await resolveTestFile();
assertType(setLiteral('{for'), 'Set<int>');
}
test_noContext_noTypeArgs_if() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_noContext_noTypeArgs_ifElse_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 else 2};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_noContext_noTypeArgs_ifElse_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 else 2.3};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<num>');
}
test_noContext_noTypeArgs_ifElse_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
bool c = true;
var a = {if (c) 1 else '2'};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<Object>');
}
test_noContext_noTypeArgs_spread() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
var a = {...c};
''');
- await resolveTestFile();
assertType(setLiteral('{...'), 'Set<int>');
}
test_noContext_noTypeArgs_spread_lubOfInt() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<int> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setLiteral('{...'), 'Set<int>');
}
test_noContext_noTypeArgs_spread_lubOfNum() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<double> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setLiteral('{...'), 'Set<num>');
}
test_noContext_noTypeArgs_spread_lubOfObject() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
List<String> b;
var a = {...b, ...c};
''');
- await resolveTestFile();
assertType(setLiteral('{...'), 'Set<Object>');
}
test_noContext_noTypeArgs_spread_nestedInIf_oneAmbiguous() async {
- addTestFile('''
+ await resolveTestCode('''
List<int> c;
dynamic d;
var a = {if (0 < 1) ...c else ...d};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<dynamic>');
}
@failingTest
test_noContext_noTypeArgs_spread_nullAware_nullAndNotNull() async {
- addTestFile('''
+ await resolveTestCode('''
f() {
var futureNull = Future.value(null);
var a = {1, ...?await futureNull, 2};
}
''');
- await resolveTestFile();
assertType(setLiteral('{1'), 'Set<int>');
}
test_noContext_typeArgs_expression_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <String>{1};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<String>');
}
test_noContext_typeArgs_expression_noConflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int>{1};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
@failingTest
test_noContext_typeArgs_expressions_conflict() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <int, String>{1, 2};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<int>');
}
test_noContext_typeArgs_noElements() async {
- addTestFile('''
+ await resolveTestCode('''
var a = <num>{};
''');
- await resolveTestFile();
assertType(setLiteral('{'), 'Set<num>');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/statements_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/statements_test.dart
index 6137756..cab7d7b 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/statements_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/statements_test.dart
@@ -30,13 +30,12 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
assert(a());
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
@@ -53,13 +52,12 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
do {} while(a())
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
@@ -76,63 +74,58 @@
@failingTest
test_awaitForIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
await for (var e in a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Stream<dynamic> Function()');
}
@failingTest
test_awaitForIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() async {
await for (int e in a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'Stream<int> Function()');
}
@failingTest
test_for_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
for (int i = 0; a(); i++) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
@failingTest
test_forIn_dynamic_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
for (var e in a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<dynamic> Function()');
}
@failingTest
test_forIn_int_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
for (int e in a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(
findNode.methodInvocation('a('), 'Iterable<int> Function()');
}
@@ -150,13 +143,12 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
if (a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
@@ -173,13 +165,12 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
while (a()) {}
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'bool Function()');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart
index 8cdfe3a..60e9a36 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/throw_test.dart
@@ -26,13 +26,12 @@
@failingTest
test_downward() async {
- addTestFile('''
+ await resolveTestCode('''
void f() {
throw a();
}
T a<T>() => throw '';
''');
- await resolveTestFile();
assertInvokeType(findNode.methodInvocation('a('), 'dynamic Function()');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart
index 9dd6039..641ffb6 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/type_test_expressions_test.dart
@@ -20,13 +20,12 @@
@reflectiveTest
class IsNotTest extends DriverResolutionTest {
test_simple() async {
- addTestFile('''
+ await resolveTestCode('''
void f(Object a) {
var b = a is! String;
print(b);
}
''');
- await resolveTestFile();
assertType(findNode.simple('b)'), 'bool');
}
}
@@ -45,13 +44,12 @@
@reflectiveTest
class IsTest extends DriverResolutionTest {
test_simple() async {
- addTestFile('''
+ await resolveTestCode('''
void f(Object a) {
var b = a is String;
print(b);
}
''');
- await resolveTestFile();
assertType(findNode.simple('b)'), 'bool');
}
}
diff --git a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
index 457e913..43bfb89 100644
--- a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
@@ -15,7 +15,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../embedder_tests.dart';
-import '../../../generated/test_support.dart';
import '../../../resource_utils.dart';
main() {
@@ -164,8 +163,8 @@
void test_fromFile_library_firstExact() {
FolderBasedDartSdk sdk = _createDartSdk();
Folder dirHtml = sdk.libraryDirectory.getChildAssumingFolder("html");
- Folder dirDartium = dirHtml.getChildAssumingFolder("dartium");
- File file = dirDartium.getChildAssumingFile("html_dartium.dart");
+ Folder dirDartium = dirHtml.getChildAssumingFolder("dart2js");
+ File file = dirDartium.getChildAssumingFile("html_dart2js.dart");
Source source = sdk.fromFileUri(file.toUri());
expect(source, isNotNull);
expect(source.isInSystemLibrary, isTrue);
@@ -180,7 +179,7 @@
Source source = sdk.fromFileUri(file.toUri());
expect(source, isNotNull);
expect(source.isInSystemLibrary, isTrue);
- expect(source.uri.toString(), "dart:html_common/html_common_dart2js.dart");
+ expect(source.uri.toString(), "dart:html_common");
}
void test_fromFile_part() {
@@ -264,9 +263,11 @@
_createFile(sdkDirectory, ['lib', 'async', 'async.dart']);
_createFile(sdkDirectory, ['lib', 'core', 'core.dart']);
_createFile(sdkDirectory, ['lib', 'core', 'num.dart']);
+ _createFile(
+ sdkDirectory, ['lib', 'html', 'html_common', 'html_common.dart']);
_createFile(sdkDirectory,
['lib', 'html', 'html_common', 'html_common_dart2js.dart']);
- _createFile(sdkDirectory, ['lib', 'html', 'dartium', 'html_dartium.dart']);
+ _createFile(sdkDirectory, ['lib', 'html', 'dart2js', 'html_dart2js.dart']);
_createFile(
sdkDirectory, ['bin', (OSUtilities.isWindows() ? 'pub.bat' : 'pub')]);
return new FolderBasedDartSdk(resourceProvider, sdkDirectory);
@@ -298,10 +299,9 @@
dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
"html": const LibraryInfo(
- "html/dartium/html_dartium.dart",
+ "html/dart2js/html_dart2js.dart",
categories: "Client",
- maturity: Maturity.WEB_STABLE,
- dart2jsPath: "html/dart2js/html_dart2js.dart"),
+ maturity: Maturity.WEB_STABLE),
"html_common": const LibraryInfo(
"html/html_common/html_common.dart",
@@ -356,41 +356,17 @@
}
@reflectiveTest
-class SdkLibrariesReaderTest extends EngineTestCase with ResourceProviderMixin {
- void test_readFrom_dart2js() {
- LibraryMap libraryMap =
- new SdkLibrariesReader(true).readFromFile(getFile("/libs.dart"), r'''
-final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
- 'first' : const LibraryInfo(
- 'first/first.dart',
- categories: 'Client',
- documented: true,
- platforms: VM_PLATFORM,
- dart2jsPath: 'first/first_dart2js.dart'),
-};''');
- expect(libraryMap, isNotNull);
- expect(libraryMap.size(), 1);
- SdkLibrary first = libraryMap.getLibrary("dart:first");
- expect(first, isNotNull);
- expect(first.category, "Client");
- expect(first.path, "first/first_dart2js.dart");
- expect(first.shortName, "dart:first");
- expect(first.isDart2JsLibrary, false);
- expect(first.isDocumented, true);
- expect(first.isImplementation, false);
- expect(first.isVmLibrary, true);
- }
-
+class SdkLibrariesReaderTest with ResourceProviderMixin {
void test_readFrom_empty() {
LibraryMap libraryMap =
- new SdkLibrariesReader(false).readFromFile(getFile("/libs.dart"), "");
+ new SdkLibrariesReader().readFromFile(getFile("/libs.dart"), "");
expect(libraryMap, isNotNull);
expect(libraryMap.size(), 0);
}
void test_readFrom_normal() {
LibraryMap libraryMap =
- new SdkLibrariesReader(false).readFromFile(getFile("/libs.dart"), r'''
+ new SdkLibrariesReader().readFromFile(getFile("/libs.dart"), r'''
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
'first' : const LibraryInfo(
'first/first.dart',
diff --git a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
index a6894c5..e9b7c6c 100644
--- a/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/ambiguous_extension_member_access_test.dart
@@ -168,7 +168,7 @@
]);
}
- test_operator_index() async {
+ test_operator_index_index() async {
await assertErrorsInCode('''
class A {}
@@ -186,6 +186,24 @@
]);
}
+ test_operator_index_indexEq() async {
+ await assertErrorsInCode('''
+extension E1 on int {
+ int operator[](int index) => 0;
+}
+
+extension E2 on int {
+ void operator[]=(int index, int value) {}
+}
+
+f() {
+ 0[1] += 2;
+}
+''', [
+ error(CompileTimeErrorCode.AMBIGUOUS_EXTENSION_MEMBER_ACCESS, 136, 1),
+ ]);
+ }
+
test_operator_unary() async {
await assertErrorsInCode('''
class A {}
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
index 1c179be..b6f90a5 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
@@ -18,13 +18,6 @@
@reflectiveTest
class ConstConstructorParamTypeMismatchTest extends DriverResolutionTest {
test_int_to_double_reference_from_other_library_other_file_after() async {
- addTestFile('''
-class C {
- final double d;
- const C(this.d);
-}
-const C constant = const C(0);
-''');
newFile('/test/lib/other.dart', content: '''
import 'test.dart';
class D {
@@ -33,7 +26,13 @@
}
const D constant2 = const D(constant);
''');
- await resolveTestFile();
+ await resolveTestCode('''
+class C {
+ final double d;
+ const C(this.d);
+}
+const C constant = const C(0);
+''');
assertNoTestErrors();
var otherFileResult =
await resolveFile(convertPath('/test/lib/other.dart'));
@@ -41,7 +40,7 @@
}
test_int_to_double_reference_from_other_library_other_file_before() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
final double d;
const C(this.d);
@@ -59,37 +58,34 @@
var otherFileResult =
await resolveFile(convertPath('/test/lib/other.dart'));
expect(otherFileResult.errors, isEmpty);
- await resolveTestFile();
assertNoTestErrors();
}
test_int_to_double_single_library() async {
- addTestFile('''
+ await resolveTestCode('''
class C {
final double d;
const C(this.d);
}
const C constant = const C(0);
''');
- await resolveTestFile();
assertNoTestErrors();
}
test_int_to_double_via_default_value_other_file_after() async {
- addTestFile('''
-import 'other.dart';
-
-void main() {
- const c = C();
-}
-''');
newFile('/test/lib/other.dart', content: '''
class C {
final double x;
const C([this.x = 0]);
}
''');
- await resolveTestFile();
+ await resolveTestCode('''
+import 'other.dart';
+
+void main() {
+ const c = C();
+}
+''');
assertNoTestErrors();
var otherFileResult =
await resolveFile(convertPath('/test/lib/other.dart'));
@@ -97,13 +93,6 @@
}
test_int_to_double_via_default_value_other_file_before() async {
- addTestFile('''
-import 'other.dart';
-
-void main() {
- const c = C();
-}
-''');
newFile('/test/lib/other.dart', content: '''
class C {
final double x;
@@ -113,7 +102,14 @@
var otherFileResult =
await resolveFile(convertPath('/test/lib/other.dart'));
expect(otherFileResult.errors, isEmpty);
- await resolveTestFile();
+
+ await resolveTestCode('''
+import 'other.dart';
+
+void main() {
+ const c = C();
+}
+''');
assertNoTestErrors();
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
index 0bcdf0a..263cebb 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_function_return_type_test.dart
@@ -26,7 +26,7 @@
..strictInference = true;
test_extensionMethod() async {
- assertErrorsInCode(r'''
+ await assertErrorsInCode(r'''
extension E on List {
e() {
return 7;
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
index 736554b..846fd9c 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_uninitialized_variable_test.dart
@@ -20,111 +20,21 @@
class InferenceFailureOnUninitializedVariableTest
extends StaticTypeAnalyzer2TestShared {
@override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strictInference = true;
- resetWith(options: options);
- }
-
- test_localVariable() async {
- String code = r'''
-void f() {
- var a;
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE]);
- }
-
- test_localVariable_withInitializer() async {
- String code = r'''
-void f() {
- var a = 7;
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_localVariable_withType() async {
- String code = r'''
-void f() {
- int a;
- dynamic b;
- Object c;
- Null d;
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_topLevelVariable() async {
- String code = r'''
-var a;
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE]);
- }
-
- test_topLevelVariable_withInitializer() async {
- String code = r'''
-var a = 7;
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_topLevelVariable_withType() async {
- String code = r'''
-int a;
-dynamic b;
-Object c;
-Null d;
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..strictInference = true;
test_field() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C {
var a;
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE]);
- }
-
- test_finalField() async {
- String code = r'''
-class C {
- final a;
- C(this.a);
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE]);
- }
-
- test_staticField() async {
- String code = r'''
-class C {
- static var a;
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE]);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE, 16, 1),
+ ]);
}
test_field_withInitializer() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C {
static var c = 3;
static final d = 5;
@@ -132,13 +42,11 @@
var a = 7;
final b = 9;
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
}
test_field_withType() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C {
static int c;
static final int d = 5;
@@ -148,8 +56,87 @@
C(this.b);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
+ }
+
+ test_finalField() async {
+ await assertErrorsInCode(r'''
+class C {
+ final a;
+ C(this.a);
+}
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE, 18, 1),
+ ]);
+ }
+
+ test_localVariable() async {
+ await assertErrorsInCode(r'''
+void f() {
+ var a;
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE, 17, 1),
+ ]);
+ }
+
+ test_localVariable_withInitializer() async {
+ await assertErrorsInCode(r'''
+void f() {
+ var a = 7;
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+ ]);
+ }
+
+ test_localVariable_withType() async {
+ await assertErrorsInCode(r'''
+void f() {
+ int a;
+ dynamic b;
+ Object c;
+ Null d;
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 30, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 42, 1),
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 52, 1),
+ ]);
+ }
+
+ test_staticField() async {
+ await assertErrorsInCode(r'''
+class C {
+ static var a;
+}
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE, 23, 1),
+ ]);
+ }
+
+ test_topLevelVariable() async {
+ await assertErrorsInCode(r'''
+var a;
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNINITIALIZED_VARIABLE, 4, 1),
+ ]);
+ }
+
+ test_topLevelVariable_withInitializer() async {
+ await assertNoErrorsInCode(r'''
+var a = 7;
+''');
+ }
+
+ test_topLevelVariable_withType() async {
+ await assertNoErrorsInCode(r'''
+int a;
+dynamic b;
+Object c;
+Null d;
+''');
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart b/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
index e1cf255..5428deb 100644
--- a/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inference_failure_on_untyped_parameter_test.dart
@@ -20,104 +20,135 @@
class InferenceFailureOnUntypedParameterTest
extends StaticTypeAnalyzer2TestShared {
@override
- void setUp() {
- super.setUp();
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strictInference = true;
- resetWith(options: options);
+ AnalysisOptionsImpl get analysisOptions =>
+ AnalysisOptionsImpl()..strictInference = true;
+
+ test_fieldParameter() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ int a;
+ C(this.a) {}
+}
+''');
}
- test_parameter() async {
- String code = r'''
-void fn(a) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
+ test_functionTypedFormalParameter_withType() async {
+ await assertNoErrorsInCode(r'''
+void fn(String cb(int x)) => print(cb(7));
+''');
}
- test_parameter_withVar() async {
- String code = r'''
-void fn(var a) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
-
- test_parameter_withType() async {
- String code = r'''
-void fn(int a) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_parameter_inGenericFunction_withType() async {
- String code = r'''
-void fn<T>(T a) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_parameter_withVarAndDefault() async {
- String code = r'''
-void fn([var a = 7]) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
-
- test_parameter_withTypeAndDefault() async {
- String code = r'''
-void fn([int a = 7]) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_namedParameter_withVar() async {
- String code = r'''
-void fn({var a}) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
+ test_functionTypedFormalParameter_withVar() async {
+ await assertErrorsInCode(r'''
+void fn(String cb(var x)) => print(cb(7));
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 18, 5),
+ ]);
}
test_namedParameter_withType() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
void fn({int a}) => print(a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
+ }
+
+ test_namedParameter_withVar() async {
+ await assertErrorsInCode(r'''
+void fn({var a}) => print(a);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 9, 5),
+ ]);
+ }
+
+ test_parameter() async {
+ await assertErrorsInCode(r'''
+void fn(a) => print(a);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 8, 1),
+ ]);
+ }
+
+ test_parameter_inConstructor() async {
+ await assertErrorsInCode(r'''
+class C {
+ C(var a) {}
+}
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 14, 5),
+ ]);
+ }
+
+ test_parameter_inConstructor_withType() async {
+ await assertNoErrorsInCode(r'''
+class C {
+ C(int a) {}
+}
+''');
+ }
+
+ test_parameter_inFunctionLiteral() async {
+ await assertErrorsInCode(r'''
+void fn() {
+ var f = (var a) {};
+}
+''', [
+ error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 1),
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 23, 5),
+ ]);
+ }
+
+ test_parameter_inFunctionLiteral_inferredType() async {
+ await assertNoErrorsInCode(r'''
+void fn() {
+ g((a, b) => print('$a$b'));
+}
+
+void g(void cb(int a, dynamic b)) => cb(7, "x");
+''');
+ }
+
+ test_parameter_inFunctionLiteral_inferredType_viaReturn() async {
+ await assertNoErrorsInCode(r'''
+void Function(int, dynamic) fn() {
+ return (a, b) => print('$a$b');
+}
+''');
+ }
+
+ test_parameter_inFunctionLiteral_withType() async {
+ await assertNoErrorsInCode(r'''
+void fn() {
+ var f = (int a) {};
+}
+''');
+ }
+
+ test_parameter_inGenericFunction_withType() async {
+ await assertNoErrorsInCode(r'''
+void fn<T>(T a) => print(a);
+''');
}
test_parameter_inMethod() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C {
void fn(var a) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 20, 5),
+ ]);
}
test_parameter_inMethod_withType() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C {
void fn(String a) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
}
test_parameter_inOverridingMethod() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C {
void fn(int a) => print(a);
}
@@ -126,29 +157,13 @@
@override
void fn(var a) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
-
- test_parameter_inOverridingMethod_withType() async {
- String code = r'''
-class C {
- void fn(int a) => print(a);
-}
-
-class D extends C {
- @override
- void fn(num a) => print(a);
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 85, 5),
+ ]);
}
test_parameter_inOverridingMethod_withDefault() async {
- String code = r'''
+ await assertErrorsInCode(r'''
class C {
void fn([int a = 7]) => print(a);
}
@@ -157,14 +172,13 @@
@override
void fn([var a = 7]) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 92, 5),
+ ]);
}
test_parameter_inOverridingMethod_withDefaultAndType() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
class C {
void fn([int a = 7]) => print(a);
}
@@ -173,86 +187,61 @@
@override
void fn([num a = 7]) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
}
- test_parameter_inConstructor() async {
- String code = r'''
+ test_parameter_inOverridingMethod_withType() async {
+ await assertNoErrorsInCode(r'''
class C {
- C(var a) {}
+ void fn(int a) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
- test_parameter_inConstructor_withType() async {
- String code = r'''
-class C {
- C(int a) {}
+class D extends C {
+ @override
+ void fn(num a) => print(a);
}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_fieldParameter() async {
- String code = r'''
-class C {
- int a;
- C(this.a) {}
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_parameter_inFunctionLiteral() async {
- String code = r'''
-void fn() {
- var f = (var a) {};
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
-
- test_parameter_inFunctionLiteral_withType() async {
- String code = r'''
-void fn() {
- var f = (int a) {};
-}
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
- }
-
- test_functionTypeParameter_withVar() async {
- String code = r'''
-void fn(String cb(var x)) => print(cb(7));
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertErrorsInCode(
- code, [HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER]);
- }
-
- test_functionTypeParameter_withType() async {
- String code = r'''
-void fn(String cb(int x)) => print(cb(7));
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
}
test_parameter_inTypedef_withType() async {
- String code = r'''
+ await assertNoErrorsInCode(r'''
typedef cb = void Function(int a);
-''';
- await resolveTestUnit(code, noErrors: false);
- await assertNoErrorsInCode(code);
+''');
+ }
+
+ test_parameter_withoutKeyword() async {
+ await assertErrorsInCode(r'''
+void fn(a) => print(a);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 8, 1),
+ ]);
+ }
+
+ test_parameter_withType() async {
+ await assertNoErrorsInCode(r'''
+void fn(int a) => print(a);
+''');
+ }
+
+ test_parameter_withTypeAndDefault() async {
+ await assertNoErrorsInCode(r'''
+void fn([int a = 7]) => print(a);
+''');
+ }
+
+ test_parameter_withVar() async {
+ await assertErrorsInCode(r'''
+void fn(var a) => print(a);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 8, 5),
+ ]);
+ }
+
+ test_parameter_withVarAndDefault() async {
+ await assertErrorsInCode(r'''
+void fn([var a = 7]) => print(a);
+''', [
+ error(HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER, 9, 5),
+ ]);
}
}
diff --git a/pkg/analyzer/test/src/diagnostics/invocation_of_extension_without_call_test.dart b/pkg/analyzer/test/src/diagnostics/invocation_of_extension_without_call_test.dart
new file mode 100644
index 0000000..8708381
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invocation_of_extension_without_call_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InvocationOfExtensionWithoutCallTest);
+ });
+}
+
+@reflectiveTest
+class InvocationOfExtensionWithoutCallTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_instance_differentKind() async {
+ await assertErrorsInCode('''
+extension E on Object {}
+f() {
+ E(null)();
+}
+''', [
+ error(CompileTimeErrorCode.INVOCATION_OF_EXTENSION_WITHOUT_CALL, 33, 7),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart b/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
index b9b0063..f117889 100644
--- a/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/static_access_to_instance_member_test.dart
@@ -88,7 +88,7 @@
sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
test_getter() async {
- assertErrorsInCode('''
+ await assertErrorsInCode('''
extension E on int {
int get g => 0;
}
@@ -101,7 +101,7 @@
}
test_method() async {
- assertErrorsInCode('''
+ await assertErrorsInCode('''
extension E on int {
void m() {}
}
@@ -114,7 +114,7 @@
}
test_setter() async {
- assertErrorsInCode('''
+ await assertErrorsInCode('''
extension E on int {
void set s(int i) {}
}
diff --git a/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart b/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart
index 3a50c22..90f4c84 100644
--- a/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/strict_raw_type_test.dart
@@ -27,20 +27,20 @@
..strictRawTypes = true;
test_typeOnExtendedType_anonymous_missing() async {
- assertErrorsInCode(r'''
+ await assertErrorsInCode(r'''
extension on List {}
''', [error(HintCode.STRICT_RAW_TYPE, 13, 4)]);
}
test_typeOnExtendedType_missing() async {
- assertErrorsInCode(r'''
+ await assertErrorsInCode(r'''
extension E on List {}
''', [error(HintCode.STRICT_RAW_TYPE, 15, 4)]);
}
test_typeOnExtendedType_optionalTypeArgs() async {
addMetaPackage();
- assertNoErrorsInCode(r'''
+ await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
class C<T> {}
@@ -50,7 +50,7 @@
}
test_typeOnExtendedType_present() async {
- assertNoErrorsInCode(r'''
+ await assertNoErrorsInCode(r'''
extension E<T> on List<T> {}
extension F on List<int> {}
''');
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 5dbd49a..fd2ef4e 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -149,6 +149,8 @@
as invalid_use_of_visible_for_testing_member;
import 'invalid_visibility_annotation_test.dart'
as invalid_visibility_annotation;
+import 'invocation_of_extension_without_call_test.dart'
+ as invocation_of_extension_without_call;
import 'is_double_test.dart' as is_double;
import 'is_int_test.dart' as is_int;
import 'is_not_double_test.dart' as is_not_double;
@@ -293,6 +295,7 @@
import 'undefined_class_test.dart' as undefined_class;
import 'undefined_extension_getter_test.dart' as undefined_extension_getter;
import 'undefined_extension_method_test.dart' as undefined_extension_method;
+import 'undefined_extension_operator_test.dart' as undefined_extension_operator;
import 'undefined_extension_setter_test.dart' as undefined_extension_setter;
import 'undefined_getter_test.dart' as undefined_getter;
import 'undefined_hidden_name_test.dart' as undefined_hidden_name;
@@ -427,6 +430,7 @@
invalid_use_of_visible_for_template_member.main();
invalid_use_of_visible_for_testing_member.main();
invalid_visibility_annotation.main();
+ invocation_of_extension_without_call.main();
is_double.main();
is_int.main();
is_not_double.main();
@@ -527,6 +531,7 @@
undefined_class.main();
undefined_extension_getter.main();
undefined_extension_method.main();
+ undefined_extension_operator.main();
undefined_extension_setter.main();
undefined_getter.main();
undefined_hidden_name.main();
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
index 38ea384..4ac7029 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_method_test.dart
@@ -51,32 +51,6 @@
);
}
- test_operator_defined() async {
- await assertNoErrorsInCode('''
-extension E on String {
- void operator +(int offset) {}
-}
-f() {
- E('a') + 1;
-}
-''');
- }
-
- test_operator_undefined() async {
- await assertErrorsInCode('''
-extension E on String {}
-f() {
- E('a') + 1;
-}
-''', [
- error(CompileTimeErrorCode.UNDEFINED_EXTENSION_METHOD, 40, 1),
- ]);
- var binaryExpression = findNode.binary('+ 1');
- assertElementNull(binaryExpression);
- assertInvokeTypeNull(binaryExpression);
- assertTypeDynamic(binaryExpression);
- }
-
test_static_withInference() async {
await assertErrorsInCode('''
extension E on Object {}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_extension_operator_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_extension_operator_test.dart
new file mode 100644
index 0000000..36fe2ea
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_extension_operator_test.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2019, 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 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UndefinedExtensionMethodTest);
+ });
+}
+
+@reflectiveTest
+class UndefinedExtensionMethodTest extends DriverResolutionTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_binary_defined() async {
+ await assertNoErrorsInCode('''
+extension E on String {
+ void operator +(int offset) {}
+}
+f() {
+ E('a') + 1;
+}
+''');
+ }
+
+ test_binary_undefined() async {
+ await assertErrorsInCode('''
+extension E on String {}
+f() {
+ E('a') + 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 40, 1),
+ ]);
+ var binaryExpression = findNode.binary('+ 1');
+ assertElementNull(binaryExpression);
+ assertInvokeTypeNull(binaryExpression);
+ assertTypeDynamic(binaryExpression);
+ }
+
+ test_index_get_hasGetter() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ int operator[](int index) => 0;
+}
+
+f(A a) {
+ E(a)[0];
+}
+''');
+ }
+
+ test_index_get_hasNone() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {}
+
+f(A a) {
+ E(a)[0];
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 48, 3),
+ ]);
+ }
+
+ test_index_get_hasSetter() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ E(a)[0];
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 93, 3),
+ ]);
+ }
+
+ test_index_getSet_hasBoth() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ int operator[](int index) => 0;
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ E(a)[0] += 1;
+}
+''');
+ }
+
+ test_index_getSet_hasGetter() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ int operator[](int index) => 0;
+}
+
+f(A a) {
+ E(a)[0] += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 83, 3),
+ ]);
+ }
+
+ test_index_getSet_hasNone() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {}
+
+f(A a) {
+ E(a)[0] += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 48, 3),
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 48, 3),
+ ]);
+ }
+
+ test_index_getSet_hasSetter() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ E(a)[0] += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 93, 3),
+ ]);
+ }
+
+ test_index_set_hasGetter() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ int operator[](int index) => 0;
+}
+
+f(A a) {
+ E(a)[0] = 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 83, 3),
+ ]);
+ }
+
+ test_index_set_hasNone() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+extension E on A {}
+
+f(A a) {
+ E(a)[0] = 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_EXTENSION_OPERATOR, 48, 3),
+ ]);
+ }
+
+ test_index_set_hasSetter() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ E(a)[0] = 1;
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
index ee6452d..188e474 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
@@ -2,7 +2,9 @@
// 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 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
@@ -10,6 +12,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(UndefinedOperatorTest);
+ defineReflectiveTests(UndefinedOperatorTestWithExtensionMethodsTest);
});
}
@@ -44,103 +47,50 @@
]);
}
+ test_index_both() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+f(A a) {
+ a[0]++;
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 3),
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 3),
+ ]);
+ }
+
+ test_index_getter() async {
+ await assertErrorsInCode(r'''
+class A {}
+
+f(A a) {
+ a[0];
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 3),
+ ]);
+ }
+
test_index_null() async {
await assertErrorsInCode(r'''
-m() {
- Null x;
+f(Null x) {
x[0];
}
''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 19, 3),
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 15, 3),
]);
}
- test_indexBoth() async {
+ test_index_setter() async {
await assertErrorsInCode(r'''
class A {}
-f(var a) {
- if (a is A) {
- a[0]++;
- }
-}
-''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 43, 3),
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 43, 3),
- ]);
- }
- test_indexBoth_inSubtype() async {
- await assertErrorsInCode(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if (a is A) {
- a[0]++;
- }
+f(A a) {
+ a[0] = 1;
}
''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 93, 3),
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 93, 3),
- ]);
- }
-
- test_indexGetter() async {
- await assertErrorsInCode(r'''
-class A {}
-f(var a) {
- if (a is A) {
- a[0];
- }
-}
-''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 43, 3),
- ]);
- }
-
- test_indexGetter_inSubtype() async {
- await assertErrorsInCode(r'''
-class A {}
-class B extends A {
- operator [](int index) {}
-}
-f(var a) {
- if (a is A) {
- a[0];
- }
-}
-''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 93, 3),
- ]);
- }
-
- test_indexSetter() async {
- await assertErrorsInCode(r'''
-class A {}
-f(var a) {
- if (a is A) {
- a[0] = 1;
- }
-}
-''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 43, 3),
- ]);
- }
-
- test_indexSetter_inSubtype() async {
- await assertErrorsInCode(r'''
-class A {}
-class B extends A {
- operator []=(i, v) {}
-}
-f(var a) {
- if (a is A) {
- a[0] = 1;
- }
-}
-''', [
- error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 89, 3),
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 24, 3),
]);
}
@@ -300,3 +250,76 @@
]);
}
}
+
+@reflectiveTest
+class UndefinedOperatorTestWithExtensionMethodsTest
+ extends UndefinedOperatorTest {
+ @override
+ AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+ ..contextFeatures = new FeatureSet.forTesting(
+ sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods]);
+
+ test_index_get_extendedHasNone_extensionHasGetter() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ int operator[](int index) => 0;
+}
+
+f(A a) {
+ a[0];
+}
+''');
+ }
+
+ test_index_get_extendedHasSetter_extensionHasGetter() async {
+ await assertErrorsInCode(r'''
+class A {
+ void operator[]=(int index, int value) {}
+}
+
+extension E on A {
+ int operator[](int index) => 0;
+}
+
+f(A a) {
+ a[0];
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 125, 3),
+ ]);
+ }
+
+ test_index_set_extendedHasGetter_extensionHasSetter() async {
+ await assertErrorsInCode(r'''
+class A {
+ int operator[](int index) => 0;
+}
+
+extension E on A {
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ a[0] = 1;
+}
+''', [
+ error(StaticTypeWarningCode.UNDEFINED_OPERATOR, 125, 3),
+ ]);
+ }
+
+ test_index_set_extendedHasNone_extensionHasSetter() async {
+ await assertNoErrorsInCode(r'''
+class A {}
+
+extension E on A {
+ void operator[]=(int index, int value) {}
+}
+
+f(A a) {
+ a[0] = 1;
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
index e366f23..1cd6641 100644
--- a/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/variable_type_mismatch_test.dart
@@ -22,11 +22,10 @@
// Note: in the following code, the declaration of `y` should produce an
// error because we should only promote literal ints to doubles; we
// shouldn't promote the reference to the variable `x`.
- addTestFile('''
+ await resolveTestCode('''
const Object x = 0;
const double y = x;
''');
- await resolveTestFile();
assertTestErrorsWithCodes(
[CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
}
diff --git a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
index deb16fa..e189d2c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
@@ -2,6 +2,7 @@
// 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 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test/test.dart';
@@ -16,6 +17,7 @@
defineReflectiveTests(ModifiersTest);
defineReflectiveTests(MultipleTypeTest);
defineReflectiveTests(PunctuationTest);
+ defineReflectiveTests(VarianceModifierTest);
});
}
@@ -307,3 +309,21 @@
''');
}
}
+
+/**
+ * Test how well the parser recovers when there is extra variance modifiers.
+ */
+@reflectiveTest
+class VarianceModifierTest extends AbstractRecoveryTest {
+ void test_extraModifier_inClass() {
+ testRecovery('''
+class A<in out X> {}
+''', [ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS], '''
+class A<in X> {}
+''',
+ featureSet: FeatureSet.forTesting(
+ sdkVersion: '2.5.0',
+ additionalFeatures: [Feature.variance],
+ ));
+ }
+}
diff --git a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
index 2d07417..06b49c5 100644
--- a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
+++ b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
@@ -23,9 +23,7 @@
LinterContextImpl context;
Future<void> resolve(String content) async {
- addTestFile(content);
- await resolveTestFile();
-
+ await resolveTestCode(content);
var contextUnit = LinterContextUnit(result.content, result.unit);
context = new LinterContextImpl(
[contextUnit],
diff --git a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
index 2ec431a6..275c530 100644
--- a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
+++ b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
@@ -4,15 +4,13 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../generated/resolver_test_case.dart';
-import '../../../generated/test_support.dart';
+import '../../dart/resolution/driver_resolution.dart';
void main() {
defineReflectiveSuite(() {
@@ -24,42 +22,35 @@
///
/// https://github.com/dart-lang/sdk/issues/31638
@reflectiveTest
-class Dart2InferenceTest extends ResolverTestCase {
- @override
- AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
-
+class Dart2InferenceTest extends DriverResolutionTest {
test_bool_assert() async {
var code = r'''
-T f<T>() => null;
+T f<T>(int _) => null;
main() {
- assert(f()); // 1
- assert(f(), f()); // 2
+ assert(f(1));
+ assert(f(2), f(3));
}
class C {
- C() : assert(f()), // 3
- assert(f(), f()); // 4
+ C() : assert(f(4)),
+ assert(f(5), f(6));
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- String getType(String prefix) {
- var invocation = _findMethodInvocation(unit, code, prefix);
- return invocation.staticInvokeType.toString();
+ await resolveTestCode(code);
+ MethodInvocation invocation(String search) {
+ return findNode.methodInvocation(search);
}
- expect(getType('f()); // 1'), 'bool Function()');
+ assertInvokeType(invocation('f(1));'), 'bool Function(int)');
- expect(getType('f(), '), 'bool Function()');
- expect(getType('f()); // 2'), 'dynamic Function()');
+ assertInvokeType(invocation('f(2)'), 'bool Function(int)');
+ assertInvokeType(invocation('f(3)'), 'dynamic Function(int)');
- expect(getType('f()), // 3'), 'bool Function()');
+ assertInvokeType(invocation('f(4)'), 'bool Function(int)');
- expect(getType('f(), '), 'bool Function()');
- expect(getType('f()); // 4'), 'dynamic Function()');
+ assertInvokeType(invocation('f(5)'), 'bool Function(int)');
+ assertInvokeType(invocation('f(6)'), 'dynamic Function(int)');
}
test_bool_logical() async {
@@ -74,12 +65,9 @@
var v2 = f() && f(); // 4
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
+ await resolveTestCode(code);
void assertType(String prefix) {
- var invocation = _findMethodInvocation(unit, code, prefix);
+ var invocation = findNode.methodInvocation(prefix);
expect(invocation.staticInvokeType.toString(), 'bool Function()');
}
@@ -105,12 +93,9 @@
for (; f(); ) {} // 4
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
+ await resolveTestCode(code);
void assertType(String prefix) {
- var invocation = _findMethodInvocation(unit, code, prefix);
+ var invocation = findNode.methodInvocation(prefix);
expect(invocation.staticInvokeType.toString(), 'bool Function()');
}
@@ -127,11 +112,8 @@
g = () => 42;
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- Expression closure = _findExpression(unit, code, '() => 42');
+ await resolveTestCode(code);
+ Expression closure = findNode.expression('() => 42');
expect(closure.staticType.toString(), 'List<int> Function()');
}
@@ -144,16 +126,13 @@
};
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- Expression closure = _findExpression(unit, code, '() { // mark');
+ await resolveTestCode(code);
+ Expression closure = findNode.expression('() { // mark');
expect(closure.staticType.toString(), 'List<int> Function()');
}
test_compoundAssignment_index() async {
- var code = r'''
+ await resolveTestCode(r'''
int getInt() => 0;
num getNum() => 0;
double getDouble() => 0.0;
@@ -273,15 +252,12 @@
var /*@type=double*/ v10 = ++t['x'];
var /*@type=double*/ v11 = t['x']++;
}
-''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
- _assertTypeAnnotations(code, unit);
+''');
+ _assertTypeAnnotations();
}
test_compoundAssignment_prefixedIdentifier() async {
- var code = r'''
+ await assertNoErrorsInCode(r'''
int getInt() => 0;
num getNum() => 0;
double getDouble() => 0.0;
@@ -355,13 +331,8 @@
var /*@type=double*/ v10 = ++t.x;
var /*@type=double*/ v11 = t.x++;
}
-''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
-
- var unit = analysisResult.unit;
- _assertTypeAnnotations(code, unit);
+''');
+ _assertTypeAnnotations();
}
test_compoundAssignment_propertyAccess() async {
@@ -370,7 +341,7 @@
var t5 = 'new Test<num, num>()';
var t8 = 'new Test<double, num>()';
var t9 = 'new Test<double, double>()';
- var code = '''
+ await assertNoErrorsInCode('''
int getInt() => 0;
num getNum() => 0;
double getDouble() => 0.0;
@@ -444,17 +415,12 @@
var /*@type=double*/ v10 = ++$t9.x;
var /*@type=double*/ v11 = $t9.x++;
}
-''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
-
- var unit = analysisResult.unit;
- _assertTypeAnnotations(code, unit);
+''');
+ _assertTypeAnnotations();
}
test_compoundAssignment_simpleIdentifier() async {
- var code = r'''
+ await assertNoErrorsInCode(r'''
int getInt() => 0;
num getNum() => 0;
double getDouble() => 0.0;
@@ -538,17 +504,12 @@
var /*@type=double*/ v11 = x++;
}
}
-''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
-
- var unit = analysisResult.unit;
- _assertTypeAnnotations(code, unit);
+''');
+ _assertTypeAnnotations();
}
test_compoundAssignment_simpleIdentifier_topLevel() async {
- var code = r'''
+ await assertNoErrorsInCode(r'''
class A {}
class B extends A {
@@ -562,13 +523,8 @@
main() {
var /*@type=B*/ v = topLevel += 1;
}
-''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
-
- var unit = analysisResult.unit;
- _assertTypeAnnotations(code, unit);
+''');
+ _assertTypeAnnotations();
}
test_forIn_identifier() async {
@@ -592,12 +548,9 @@
for (aTopLevelSetter in f()) {} // top setter
}
}''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
+ await resolveTestCode(code);
void assertType(String prefix) {
- var invocation = _findMethodInvocation(unit, code, prefix);
+ var invocation = findNode.methodInvocation(prefix);
expect(invocation.staticType.toString(), 'Iterable<A>');
}
@@ -618,35 +571,32 @@
for (num y in f()) {} // 3
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
+ await resolveTestCode(code);
{
- var node = EngineTestCase.findSimpleIdentifier(unit, code, 'w in');
+ var node = findNode.simple('w in');
VariableElement element = node.staticElement;
expect(node.staticType, typeProvider.dynamicType);
expect(element.type, typeProvider.dynamicType);
- var invocation = _findMethodInvocation(unit, code, 'f()) {} // 1');
+ var invocation = findNode.methodInvocation('f()) {} // 1');
expect(invocation.staticType.toString(), 'Iterable<dynamic>');
}
{
- var node = EngineTestCase.findSimpleIdentifier(unit, code, 'x in');
+ var node = findNode.simple('x in');
VariableElement element = node.staticElement;
expect(node.staticType, typeProvider.numType);
expect(element.type, typeProvider.numType);
}
{
- var node = EngineTestCase.findSimpleIdentifier(unit, code, 'y in');
+ var node = findNode.simple('y in');
VariableElement element = node.staticElement;
expect(node.staticType, typeProvider.numType);
expect(element.type, typeProvider.numType);
- var invocation = _findMethodInvocation(unit, code, 'f()) {} // 3');
+ var invocation = findNode.methodInvocation('f()) {} // 3');
expect(invocation.staticType.toString(), 'Iterable<num>');
}
}
@@ -666,16 +616,13 @@
for (B b3 in f(listB)) {} // 5
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
+ await resolveTestCode(code);
void assertTypes(
String vSearch, String vType, String fSearch, String fType) {
- var node = EngineTestCase.findSimpleIdentifier(unit, code, vSearch);
+ var node = findNode.simple(vSearch);
expect(node.staticType.toString(), vType);
- var invocation = _findMethodInvocation(unit, code, fSearch);
+ var invocation = findNode.methodInvocation(fSearch);
expect(invocation.staticType.toString(), fType);
}
@@ -693,11 +640,8 @@
operator []=(int index, double value) => null;
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- ClassElement c = unit.declaredElement.getType('C');
+ await resolveTestCode(code);
+ ClassElement c = findElement.class_('C');
PropertyAccessorElement x = c.accessors[0];
expect(x.returnType, VoidTypeImpl.instance);
@@ -717,11 +661,8 @@
set x(_) {}
operator[]=(int x, int y) {}
}''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- ClassElement c = unit.declaredElement.getType('Derived');
+ await resolveTestCode(code);
+ ClassElement c = findElement.class_('Derived');
PropertyAccessorElement x = c.accessors[0];
expect(x.returnType, VoidTypeImpl.instance);
@@ -738,10 +679,8 @@
f((x) {});
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
- var xNode = EngineTestCase.findSimpleIdentifier(unit, code, 'x) {}');
+ await resolveTestCode(code);
+ var xNode = findNode.simple('x) {}');
VariableElement xElement = xNode.staticElement;
expect(xNode.staticType, typeProvider.objectType);
expect(xElement.type, typeProvider.objectType);
@@ -752,14 +691,11 @@
var x = [];
var y = {};
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- SimpleIdentifier x = _findExpression(unit, code, 'x = ');
+ await resolveTestCode(code);
+ SimpleIdentifier x = findNode.expression('x = ');
expect(x.staticType.toString(), 'List<dynamic>');
- SimpleIdentifier y = _findExpression(unit, code, 'y = ');
+ SimpleIdentifier y = findNode.expression('y = ');
expect(y.staticType.toString(), 'Map<dynamic, dynamic>');
}
@@ -768,14 +704,11 @@
var x = [null];
var y = {null: null};
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- SimpleIdentifier x = _findExpression(unit, code, 'x = ');
+ await resolveTestCode(code);
+ SimpleIdentifier x = findNode.expression('x = ');
expect(x.staticType.toString(), 'List<Null>');
- SimpleIdentifier y = _findExpression(unit, code, 'y = ');
+ SimpleIdentifier y = findNode.expression('y = ');
expect(y.staticType.toString(), 'Map<Null, Null>');
}
@@ -793,11 +726,8 @@
break;
}
}''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- var node = _findInstanceCreation(unit, code, 'const C():');
+ await resolveTestCode(code);
+ var node = findNode.instanceCreation('const C():');
expect(node.staticType.toString(), 'C<int>');
}
@@ -811,14 +741,11 @@
var y = new C().m();
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- SimpleIdentifier x = _findExpression(unit, code, 'x = ');
+ await resolveTestCode(code);
+ SimpleIdentifier x = findNode.expression('x = ');
expect(x.staticType, VoidTypeImpl.instance);
- SimpleIdentifier y = _findExpression(unit, code, 'y = ');
+ SimpleIdentifier y = findNode.expression('y = ');
expect(y.staticType, VoidTypeImpl.instance);
}
@@ -830,18 +757,18 @@
var y = f();
}
''';
- var source = addSource(code);
- var analysisResult = await computeAnalysisResult(source);
- var unit = analysisResult.unit;
-
- SimpleIdentifier x = _findExpression(unit, code, 'x = ');
+ await resolveTestCode(code);
+ SimpleIdentifier x = findNode.expression('x = ');
expect(x.staticType, VoidTypeImpl.instance);
- SimpleIdentifier y = _findExpression(unit, code, 'y = ');
+ SimpleIdentifier y = findNode.expression('y = ');
expect(y.staticType, VoidTypeImpl.instance);
}
- void _assertTypeAnnotations(String code, CompilationUnit unit) {
+ void _assertTypeAnnotations() {
+ var code = result.content;
+ var unit = result.unit;
+
var types = <int, String>{};
{
int lastIndex = 0;
@@ -858,43 +785,18 @@
lastIndex = closeIndex;
}
}
- unit.accept(new _TypeAnnotationsValidator(types));
- }
- Expression _findExpression(AstNode root, String code, String prefix) {
- return EngineTestCase.findNode(root, code, prefix, (n) {
- return n is Expression;
- });
- }
-
- InstanceCreationExpression _findInstanceCreation(
- AstNode root, String code, String prefix) {
- return EngineTestCase.findNode(root, code, prefix, (n) {
- return n is InstanceCreationExpression;
- });
- }
-
- MethodInvocation _findMethodInvocation(
- AstNode root, String code, String prefix) {
- return EngineTestCase.findNode(root, code, prefix, (n) {
- return n is MethodInvocation;
- });
- }
-}
-
-class _TypeAnnotationsValidator extends RecursiveAstVisitor {
- final Map<int, String> types;
-
- _TypeAnnotationsValidator(this.types);
-
- void visitSimpleIdentifier(SimpleIdentifier node) {
- Token comment = node.token.precedingComments;
- if (comment != null) {
- String expectedType = types[comment.offset];
- if (expectedType != null) {
- String actualType = node.staticType.toString();
- expect(actualType, expectedType, reason: '@${comment.offset}');
- }
- }
+ unit.accept(FunctionAstVisitor(
+ simpleIdentifier: (node) {
+ Token comment = node.token.precedingComments;
+ if (comment != null) {
+ String expectedType = types[comment.offset];
+ if (expectedType != null) {
+ String actualType = node.staticType.toString();
+ expect(actualType, expectedType, reason: '@${comment.offset}');
+ }
+ }
+ },
+ ));
}
}
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index 1340172..b881193 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -14,38 +14,15 @@
import 'package:path/path.dart';
import 'package:pub_semver/src/version_constraint.dart';
import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../tool/diagnostics/generate.dart';
import 'src/dart/resolution/driver_resolution.dart';
-/// Validate the documentation associated with the declarations of the error
-/// codes.
-void main() async {
- Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
- List<CodePath> codePaths = computeCodePaths();
- //
- // Validate that the input to the generator is correct.
- //
- DocumentationValidator validator = DocumentationValidator(codePaths);
- await validator.validate();
- //
- // Validate that the generator has been run.
- //
- if (pathContext.style != Style.windows) {
- String actualContent = PhysicalResourceProvider.INSTANCE
- .getFile(computeOutputPath())
- .readAsStringSync();
-
- StringBuffer sink = StringBuffer();
- DocumentationGenerator generator = DocumentationGenerator(codePaths);
- generator.writeDocumentation(sink);
- String expectedContent = sink.toString();
-
- if (actualContent != expectedContent) {
- fail('The diagnostic documentation needs to be regenerated.\n'
- 'Please run tool/diagnostics/generate.dart.');
- }
- }
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(VerifyDiagnosticsTest);
+ });
}
/// A class used to validate diagnostic documentation.
@@ -313,6 +290,39 @@
}
}
+/// Validate the documentation associated with the declarations of the error
+/// codes.
+@reflectiveTest
+class VerifyDiagnosticsTest {
+ test_diagnostics() async {
+ Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ List<CodePath> codePaths = computeCodePaths();
+ //
+ // Validate that the input to the generator is correct.
+ //
+ DocumentationValidator validator = DocumentationValidator(codePaths);
+ await validator.validate();
+ //
+ // Validate that the generator has been run.
+ //
+ if (pathContext.style != Style.windows) {
+ String actualContent = PhysicalResourceProvider.INSTANCE
+ .getFile(computeOutputPath())
+ .readAsStringSync();
+
+ StringBuffer sink = StringBuffer();
+ DocumentationGenerator generator = DocumentationGenerator(codePaths);
+ generator.writeDocumentation(sink);
+ String expectedContent = sink.toString();
+
+ if (actualContent != expectedContent) {
+ fail('The diagnostic documentation needs to be regenerated.\n'
+ 'Please run tool/diagnostics/generate.dart.');
+ }
+ }
+ }
+}
+
/// A data holder used to return multiple values when extracting an error range
/// from a snippet.
class _SnippetData {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 46b5264..daa7d2a 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -62,6 +62,34 @@
doesn't conform to the language specification or
that might work in unexpected ways.
+### abstract_super_member_reference
+
+_The {0} '{1}' is always abstract in the supertype._
+
+#### Description
+
+The analyzer produces this diagnostic when an inherited member is
+referenced using `super`, but there is no concrete implementation of the
+member in the superclass chain. Abstract members can't be invoked.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+abstract class A {
+ int get a;
+}
+class B extends A {
+ int get a => super.[!a!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the invocation of the abstract member, possibly replacing it with an
+invocation of a concrete member.
+
### ambiguous_extension_member_access
_A member named '{0}' is defined in extensions '{1}' and '{2}' and neither is
@@ -302,6 +330,54 @@
String g(num y) => f(y as String);
{% endprettify %}
+### built_in_identifier_as_extension_name
+
+_The built-in identifier '{0}' can't be used as an extension name._
+
+#### Description
+
+The analyzer produces this diagnostic when the name of an extension is a
+built-in identifier. Built-in identifiers can’t be used as extension names.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension [!mixin!] on int {}
+{% endprettify %}
+
+#### Common fixes
+
+Choose a different name for the extension.
+
+### cast_to_non_type
+
+_The name '{0}' isn't a type, so it can't be used in an 'as' expression._
+
+#### Description
+
+The analyzer produces this diagnostic when the name following the `as` in a
+cast expression is defined to be something other than a type.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+num x = 0;
+int y = x as [!x!];
+{% endprettify %}
+
+#### Common fixes
+
+Replace the name with the name of a type:
+
+{% prettify dart %}
+num x = 0;
+int y = x as int;
+{% endprettify %}
+
### const_initialized_with_non_constant_value
_Const variables must be initialized with a constant value._
@@ -340,6 +416,96 @@
final y = x;
{% endprettify %}
+### const_spread_expected_list_or_set
+
+_A list or a set is expected in this spread._
+
+#### Description
+
+The analyzer produces this diagnostic when the expression of a spread
+operator in a constant list or set evaluates to something other than a list
+or a set.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+const List<int> list1 = null;
+const List<int> list2 = [...[!list1!]];
+{% endprettify %}
+
+#### Common fixes
+
+Change the expression to something that evaluates to either a constant list
+or a constant set:
+
+{% prettify dart %}
+const List<int> list1 = [];
+const List<int> list2 = [...list1];
+{% endprettify %}
+
+### const_spread_expected_map
+
+_A map is expected in this spread._
+
+#### Description
+
+The analyzer produces this diagnostic when the expression of a spread
+operator in a constant map evaluates to something other than a map.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+const Map<String, int> map1 = null;
+const Map<String, int> map2 = {...[!map1!]};
+{% endprettify %}
+
+#### Common fixes
+
+Change the expression to something that evaluates to a constant map:
+
+{% prettify dart %}
+const Map<String, int> map1 = {};
+const Map<String, int> map2 = {...map1};
+{% endprettify %}
+
+### const_with_non_constant_argument
+
+_Arguments of a constant creation must be constant expressions._
+
+#### Description
+
+The analyzer produces this diagnostic when a const constructor is invoked
+with an argument that isn't a constant expression.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+class C {
+ final int i;
+ const C(this.i);
+}
+C f(int i) => const C([!i!]);
+{% endprettify %}
+
+#### Common fixes
+
+Either make all of the arguments constant expressions, or remove the
+`const` keyword to use the non-constant form of the constructor:
+
+{% prettify dart %}
+class C {
+ final int i;
+ const C(this.i);
+}
+C f(int i) => C(i);
+{% endprettify %}
+
### deprecated_member_use
_'{0}' is deprecated and shouldn't be used._
@@ -390,6 +556,63 @@
documentation for deprecated declarations should indicate what code to use
in place of the deprecated code.
+### duplicate_definition
+
+_The name '{0}' is already defined._
+
+#### Description
+
+The analyzer produces this diagnostic when a name is declared, and there is
+a previous declaration with the same name in the same scope.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+int x = 0;
+int [!x!] = 1;
+{% endprettify %}
+
+#### Common fixes
+
+Choose a different name for one of the declarations.
+
+{% prettify dart %}
+int x = 0;
+int y = 1;
+{% endprettify %}
+
+### equal_elements_in_const_set
+
+_Two values in a constant set can't be equal._
+
+#### Description
+
+The analyzer produces this diagnostic when two elements in a constant set
+literal have the same value. The set can only contain each value once,
+which means that one of the values is unnecessary.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+const Set<String> set = {'a', [!'a'!]};
+{% endprettify %}
+
+#### Common fixes
+
+Remove one of the duplicate values:
+
+{% prettify dart %}
+const Set<String> set = {'a'};
+{% endprettify %}
+
+Note that literal sets preserve the order of their elements, so the choice
+of which element to remove might affect the order in which elements are
+returned by an iterator.
+
### equal_keys_in_const_map
_Two keys in a constant map literal can't be equal._
@@ -411,18 +634,24 @@
#### Common fixes
-If one of the keys was supposed to be different, then replace it:
+If both entries should be included in the map, then change one of the keys
+to be different:
{% prettify dart %}
const map = <int, String>{1: 'a', 2: 'b', 3: 'c', 4: 'd'};
{% endprettify %}
-Otherwise, remove the key/value pair that isn't intended to be in the map:
+If only one of the entries is needed, then remove the one that isn't
+needed:
{% prettify dart %}
const map = <int, String>{1: 'a', 2: 'b', 4: 'd'};
{% endprettify %}
+Note that literal maps preserve the order of their entries, so the choice
+of which entry to remove might affect the order in which keys and values
+are returned by an iterator.
+
### expression_in_map
_Expressions can't be used in a map literal._
@@ -450,6 +679,41 @@
var map = <String, int>{'a': 0, 'b': 1, 'c': 2};
{% endprettify %}
+### extension_as_expression
+
+_Extension '{0}' can't be used as an expression._
+
+#### Description
+
+The analyzer produces this diagnostic when the name of an extension is used
+in an expression other than in an extension override or to qualify an
+access to a static member of the extension.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on int {
+ static String m() => '';
+}
+
+var x = [!E!];
+{% endprettify %}
+
+#### Common fixes
+
+Replace the name of the extension with a name that can be referenced, such
+as a static member defined on the extension:
+
+{% prettify dart %}
+extension E on int {
+ static String m() => '';
+}
+
+var x = E.m();
+{% endprettify %}
+
### extension_conflicting_static_and_instance
_Extension '{0}' can't define static member '{1}' and an instance member with
@@ -726,6 +990,240 @@
}
{% endprettify %}
+### extension_override_with_cascade
+
+_Extension overrides have no value so they can't be used as the target of a
+cascade expression._
+
+#### Description
+
+The analyzer produces this diagnostic when an extension override is used as
+the target of a cascade expression.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+extension E on int {
+ void m() {}
+}
+f() {
+ E(3)[!..!]m();
+}
+{% endprettify %}
+
+#### Common fixes
+
+Use '.' rather than '..':
+
+{% prettify dart %}
+extension E on int {
+ void m() {}
+}
+f() {
+ E(3).m();
+}
+{% endprettify %}
+
+If there are multiple cascaded accesses, you'll need to duplicate the
+extension override for each one.
+
+### extra_positional_arguments
+
+_Too many positional arguments: {0} expected, but {1} found._
+
+#### Description
+
+The analyzer produces this diagnostic when a method or function invocation
+has more positional arguments than the method or function allows.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f(int a, int b) {}
+void g() {
+ f[!(1, 2, 3)!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Remove the arguments that don't correspond to parameters:
+
+{% prettify dart %}
+void f(int a, int b) {}
+void g() {
+ f(1, 2);
+}
+{% endprettify %}
+
+### extra_positional_arguments_could_be_named
+
+_Too many positional arguments: {0} expected, but {1} found._
+
+#### Description
+
+The analyzer produces this diagnostic when a method or function invocation
+has more positional arguments than the method or function allows, but the
+method or function defines named parameters.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f(int a, int b, {int c}) {}
+void g() {
+ f[!(1, 2, 3)!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+If some of the arguments should be values for named parameters, then add
+the names before the arguments:
+
+{% prettify dart %}
+void f(int a, int b, {int c}) {}
+void g() {
+ f(1, 2, c: 3);
+}
+{% endprettify %}
+
+Otherwise, remove the arguments that don't correspond to positional
+parameters:
+
+{% prettify dart %}
+void f(int a, int b, {int c}) {}
+void g() {
+ f(1, 2);
+}
+{% endprettify %}
+
+### final_not_initialized
+
+_The final variable '{0}' must be initialized._
+
+#### Description
+
+The analyzer produces this diagnostic when a final field or variable isn't
+initialized.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+final [!x!];
+{% endprettify %}
+
+#### Common fixes
+
+For variables and static fields, you can add an initializer:
+
+{% prettify dart %}
+final x = 0;
+{% endprettify %}
+
+For instance fields, you can add an initializer as shown in the previous
+example, or you can initialize the field in every constructor. You can
+initialize the field by using a field formal parameter:
+
+{% prettify dart %}
+class C {
+ final int x;
+ C(this.x);
+}
+{% endprettify %}
+
+You can also initialize the field by using an initializer in the
+constructor:
+
+{% prettify dart %}
+class C {
+ final int x;
+ C(int y) : x = y * 2;
+}
+{% endprettify %}
+
+### implements_non_class
+
+_Classes and mixins can only implement other classes and mixins._
+
+#### Description
+
+The analyzer produces this diagnostic when a name used in the implements
+clause of a class or mixin declaration is defined to be something other
+than a class or mixin.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+var x;
+class C implements [!x!] {}
+{% endprettify %}
+
+#### Common fixes
+
+If the name is the name of an existing class or mixin that's already being
+imported, then add a prefix to the import so that the local definition of
+the name doesn't shadow the imported name.
+
+If the name is the name of an existing class or mixin that isn't being
+imported, then add an import, with a prefix, for the library in which it’s
+declared.
+
+Otherwise, either replace the name in the implements clause with the name
+of an existing class or mixin, or remove the name from the implements
+clause.
+
+### invalid_assignment
+
+_A value of type '{0}' can't be assigned to a variable of type '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when the static type of an expression
+that is assigned to a variable isn't assignable to the type of the
+variable.
+
+#### Example
+
+The following code produces this diagnostic because the type of the
+initializer (`int`) isn't assignable to the type of the variable
+(`String`):
+
+{% prettify dart %}
+int i = 0;
+String s = [!i!];
+{% endprettify %}
+
+#### Common fixes
+
+If the value being assigned is always assignable at runtime, even though
+the static types don't reflect that, then add an explicit cast.
+
+Otherwise, change the value being assigned so that it has the expected
+type. In the previous example, this might look like:
+
+{% prettify dart %}
+int i = 0;
+String s = i.toString();
+{% endprettify %}
+
+If you can’t change the value, then change the type of the variable to be
+compatible with the type of the value being assigned:
+
+{% prettify dart %}
+int i = 0;
+int s = i;
+{% endprettify %}
+
### invalid_extension_argument_count
_Extension overrides must have exactly one argument: the value of 'this' in the
@@ -864,6 +1362,44 @@
Replace the name with the name of a function.
+### map_entry_not_in_map
+
+_Map entries can only be used in a map literal._
+
+#### Description
+
+The analyzer produces this diagnostic when a map entry (a key/value pair)
+is found in a set literal.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+const collection = <String>{[!'a' : 'b'!]};
+{% endprettify %}
+
+#### Common fixes
+
+If you intended for the collection to be a map, then change the code so
+that it is a map. In the previous example, you could do this by adding
+another type argument:
+
+{% prettify dart %}
+const collection = <String, String>{'a' : 'b'};
+{% endprettify %}
+
+In other cases, you might need to change the explicit type from `Set` to
+`Map`.
+
+If you intended for the collection to be a set, then remove the map entry,
+possibly by replacing the colon with a comma if both values should be
+included in the set:
+
+{% prettify dart %}
+const collection = <String>{'a', 'b'};
+{% endprettify %}
+
### missing_return
_This function has a return type of '{0}', but doesn't end with a return
@@ -892,6 +1428,42 @@
Add a return statement that makes the return value explicit, even if `null`
is the appropriate value.
+### non_constant_case_expression
+
+_Case expressions must be constant._
+
+#### Description
+
+The analyzer produces this diagnostic when the expression in a case clause
+isn't a constant expression.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f(int i, int j) {
+ switch (i) {
+ case [!j!]:
+ // ...
+ break;
+ }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Either make the expression a constant expression, or rewrite the switch
+statement as a sequence of if statements:
+
+{% prettify dart %}
+void f(int i, int j) {
+ if (i == j) {
+ // ...
+ }
+}
+{% endprettify %}
+
### non_constant_list_element
_The values in a const list literal must be constants._
@@ -934,6 +1506,122 @@
var y = <int>[0, 1, x];
{% endprettify %}
+### non_constant_map_element
+
+_The elements in a const map literal must be constant._
+
+#### Description
+
+The analyzer produces this diagnostic when an if element or a spread
+element in a constant map isn't a constant element.
+
+#### Example
+
+The following code produces this diagnostic because it is attempting to
+spread a non-constant map:
+
+{% prettify dart %}
+var notConst = <int, int>{};
+var map = const <int, int>{...[!notConst!]};
+{% endprettify %}
+
+Similarly, the following code produces this diagnostic because the
+condition in the if element isn't a constant expression:
+
+{% prettify dart %}
+bool notConst = true;
+var map = const <int, int>{if ([!notConst!]) 1 : 2};
+{% endprettify %}
+
+#### Common fixes
+
+If the map needs to be a constant map, then make the elements constants.
+In the spread example, you might do that by making the collection being
+spread a constant:
+
+{% prettify dart %}
+const notConst = <int, int>{};
+var map = const <int, int>{...notConst};
+{% endprettify %}
+
+If the map doesn't need to be a constant map, then remove the `const`
+keyword:
+
+{% prettify dart %}
+bool notConst = true;
+var map = <int, int>{if (notConst) 1 : 2};
+{% endprettify %}
+
+### non_constant_map_key
+
+_The keys in a const map literal must be constant._
+
+#### Description
+
+The analyzer produces this diagnostic when a key in a constant map literal
+isn't a constant value.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+var a = 'a';
+var m = const {[!a!]: 0};
+{% endprettify %}
+
+#### Common fixes
+
+If the map needs to be a constant map, then make the key a constant:
+
+{% prettify dart %}
+const a = 'a';
+var m = const {a: 0};
+{% endprettify %}
+
+If the map doesn't need to be a constant map, then remove the `const`
+keyword:
+
+{% prettify dart %}
+var a = 'a';
+var m = {a: 0};
+{% endprettify %}
+
+### non_constant_map_value
+
+_The values in a const map literal must be constant._
+
+#### Description
+
+The analyzer produces this diagnostic when a value in a constant map
+literal isn't a constant value.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+var a = 'a';
+var m = const {0: [!a!]};
+{% endprettify %}
+
+#### Common fixes
+
+If the map needs to be a constant map, then make the key a constant:
+
+{% prettify dart %}
+const a = 'a';
+var m = const {0: a};
+{% endprettify %}
+
+If the map doesn't need to be a constant map, then remove the `const`
+keyword:
+
+{% prettify dart %}
+var a = 'a';
+var m = {0: a};
+{% endprettify %}
+
### non_type_as_type_argument
_The name '{0}' isn't a type so it can't be used as a type argument._
@@ -984,6 +1672,38 @@
Replace the name with the name of a type.
+### not_enough_positional_arguments
+
+_{0} positional argument(s) expected, but {1} found._
+
+#### Description
+
+The analyzer produces this diagnostic when a method or function invocation
+has fewer positional arguments than the number of required positional
+parameters.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f(int a, int b) {}
+void g() {
+ f[!(0)!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+Add arguments corresponding to the remaining parameters:
+
+{% prettify dart %}
+void f(int a, int b) {}
+void g() {
+ f(0, 1);
+}
+{% endprettify %}
+
### not_iterable_spread
_Spread elements in list or set literals must implement 'Iterable'._
@@ -1013,6 +1733,35 @@
var s = <String>{...m.keys};
{% endprettify %}
+### not_map_spread
+
+_Spread elements in map literals must implement 'Map'._
+
+#### Description
+
+The analyzer produces this diagnostic when the static type of the
+expression of a spread element that appears in a map literal doesn't
+implement the type `Map`.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+var l = <String>['a', 'b'];
+var m = <int, String>{...[!l!]};
+{% endprettify %}
+
+#### Common fixes
+
+The most common fix is to replace the expression with one that produces a
+map:
+
+{% prettify dart %}
+var l = <String>['a', 'b'];
+var m = <int, String>{...l.asMap()};
+{% endprettify %}
+
### redirect_to_non_class
_The name '{0}' isn't a type and can't be used in a redirected constructor._
@@ -1055,6 +1804,55 @@
}
{% endprettify %}
+### referenced_before_declaration
+
+_Local variable '{0}' can't be referenced before it is declared._
+
+#### Description
+
+The analyzer produces this diagnostic when a variable is referenced before
+it’s declared. In Dart, variables are visible everywhere in the block in
+which they are declared, but can only be referenced after they are
+declared.
+
+The analyzer also produces a context message that indicates where the
+declaration is located.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f() {
+ print([!i!]);
+ int i = 5;
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you intended to reference the local variable, move the declaration
+before the first reference:
+
+{% prettify dart %}
+void f() {
+ int i = 5;
+ print(i);
+}
+{% endprettify %}
+
+If you intended to reference a name from an outer scope, such as a
+parameter, instance field or top-level variable, then rename the local
+declaration so that it doesn't hide the outer variable.
+
+{% prettify dart %}
+void f(int i) {
+ print(i);
+ int x = 5;
+ print(x);
+}
+{% endprettify %}
+
### sdk_version_async_exported_from_core
_The class '{0}' wasn't exported from 'dart:core' until version 2.1, but this
@@ -1589,6 +2387,78 @@
var a = A<int>();
{% endprettify %}
+### type_test_with_undefined_name
+
+_The name '{0}' isn't defined, so it can't be used in an 'is' expression._
+
+#### Description
+
+The analyzer produces this diagnostic when the name following the `is` in a
+type test expression isn't defined.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+void f(Object o) {
+ if (o is [!Srting!]) {
+ // ...
+ }
+}
+{% endprettify %}
+
+#### Common fixes
+
+Replace the name with the name of a type:
+
+{% prettify dart %}
+void f(Object o) {
+ if (o is String) {
+ // ...
+ }
+}
+{% endprettify %}
+
+### undefined_annotation
+
+_Undefined name '{0}' used as an annotation._
+
+#### Description
+
+The analyzer produces this diagnostic when a name that isn't defined is
+used as an annotation.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+[!@undefined!]
+void f() {}
+{% endprettify %}
+
+#### Common fixes
+
+If the name is correct, but it isn’t declared yet, then declare the name as
+a constant value:
+
+{% prettify dart %}
+const undefined = 'undefined';
+
+@undefined
+void f() {}
+{% endprettify %}
+
+If the name is wrong, replace the name with the name of a valid constant:
+
+{% prettify dart %}
+@deprecated
+void f() {}
+{% endprettify %}
+
+Otherwise, remove the annotation.
+
### undefined_class
_Undefined class '{0}'._
@@ -2099,6 +2969,37 @@
}
{% endprettify %}
+### undefined_prefixed_name
+
+_The name '{0}' is being referenced through the prefix '{1}', but it isn't
+defined in any of the libraries imported using that prefix._
+
+#### Description
+
+The analyzer produces this diagnostic when a prefixed identifier is found
+where the prefix is valid, but the identifier isn't declared in any of the
+libraries imported using that prefix.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+import 'dart:core' as p;
+
+void f() {
+ p.[!a!];
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the library in which the name is declared isn't imported yet, add an
+import for the library.
+
+If the name is wrong, then change it to one of the names that's declared in
+the imported libraries.
+
### undefined_setter
_The setter '{0}' isn't defined for the class '{1}'._
@@ -2137,6 +3038,100 @@
}
{% endprettify %}
+### undefined_super_method
+
+_The method '{0}' isn't defined in a superclass of '{1}'._
+
+#### Description
+
+The analyzer produces this diagnostic when an inherited method is
+referenced using `super`, but there’s no method with that name in the
+superclass chain.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+class C {
+ void m() {
+ super.[!n!]();
+ }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If the inherited method you intend to invoke has a different name, then
+make the name of the invoked method match the inherited method.
+
+If the method you intend to invoke is defined in the same class, then
+remove the `super.`.
+
+If not, then either add the method to one of the superclasses or remove the
+invocation.
+
+### unqualified_reference_to_static_member_of_extended_type
+
+_Static members from the extended type or one of its superclasses must be
+qualified by the name of the defining type._
+
+#### Description
+
+The analyzer produces this diagnostic when an undefined name is found, and
+the name is the same as a static member of the extended type or one of its
+superclasses.
+
+#### Example
+
+The following code produces this diagnostic:
+
+{% prettify dart %}
+class C {
+ static void m() {}
+}
+
+extension E on C {
+ void f() {
+ [!m!]();
+ }
+}
+{% endprettify %}
+
+#### Common fixes
+
+If you're trying to reference a static member that's declared outside the
+extension, then add the name of the class or extension before the reference
+to the member:
+
+{% prettify dart %}
+class C {
+ static void m() {}
+}
+
+extension E on C {
+ void f() {
+ C.m();
+ }
+}
+{% endprettify %}
+
+If you're referencing a member that isn't declared yet, add a declaration:
+
+{% prettify dart %}
+class C {
+ static void m() {}
+}
+
+extension E on C {
+ void f() {
+ m();
+ }
+
+ void m() {}
+}
+{% endprettify %}
+
### unused_element
_The declaration '{0}' isn't referenced._
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index 41d5c6a..9e16b8f 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -130,7 +130,7 @@
: CompletionSuggestionKind.INVOCATION;
if (!skipChildClass) {
- _addSuggestionsForType(classElement.type, optype,
+ _addSuggestionsForType(classElement.thisType, optype,
isFunctionalArgument: isFunctionalArgument);
}
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index e118229..8e9c085 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -2253,6 +2253,10 @@
/// where all types arguments are `dynamic`.
InterfaceType getRawType(ClassEntity cls);
+ /// Returns the 'JS-interop type' of [cls]; that is, the instantiation of
+ /// [cls] where all type arguments are 'any'.
+ InterfaceType getJsInteropType(ClassEntity cls);
+
/// Returns the 'this type' of [cls]. That is, the instantiation of [cls]
/// where the type arguments are the type variables of [cls].
InterfaceType getThisType(ClassEntity cls);
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 69425c5..df92e42 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -174,7 +174,8 @@
final ClassEntity element;
final List<DartType> typeArguments;
- InterfaceType(this.element, this.typeArguments);
+ InterfaceType(this.element, this.typeArguments)
+ : assert(typeArguments.every((e) => e != null));
@override
bool get isInterfaceType => true;
@@ -942,7 +943,7 @@
}
/// A visitor that by default visits the substructure of the type until some
-/// visit returns`true`. The default handers return `false` which will search
+/// visit returns `true`. The default handers return `false` which will search
/// the whole structure unless overridden.
abstract class DartTypeStructuralPredicateVisitor
extends DartTypeVisitor<bool, List<FunctionTypeVariable>> {
@@ -1528,11 +1529,12 @@
}
}
-// TODO(fishythefish): Support 'any'.
abstract class MoreSpecificVisitor<T extends DartType>
extends AbstractTypeRelation<T> {
bool isMoreSpecific(T t, T s) {
if (identical(t, s) ||
+ t.isAny ||
+ s.isAny ||
s.treatAsDynamic ||
s.isVoid ||
s == commonElements.objectType ||
@@ -1582,10 +1584,10 @@
}
/// Type visitor that determines the subtype relation two types.
-// TODO(fishythefish): Support 'any'.
abstract class SubtypeVisitor<T extends DartType>
extends MoreSpecificVisitor<T> {
bool isSubtype(DartType t, DartType s) {
+ if (t.isAny || s.isAny) return true;
if (s.isFutureOr) {
FutureOrType sFutureOr = s;
if (isSubtype(t, sFutureOr.typeArgument)) {
@@ -1644,13 +1646,13 @@
/// Type visitor that determines one type could a subtype of another given the
/// right type variable substitution. The computation is approximate and returns
/// `false` only if we are sure no such substitution exists.
-// TODO(fishythefish): Support 'any'.
abstract class PotentialSubtypeVisitor<T extends DartType>
extends SubtypeVisitor<T> {
bool _assumeInstantiations = true;
@override
bool isSubtype(DartType t, DartType s) {
+ if (t.isAny || s.isAny) return true;
if (t is TypeVariableType || s is TypeVariableType) {
return true;
}
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index 5bc26a3..f8d5341 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -42,6 +42,11 @@
[CallStructure callStructure]) {
MemberDefinition definition = elementMap.getMemberDefinition(member);
switch (definition.kind) {
+ case MemberKind.regular:
+ ir.Member node = definition.node;
+ if (node.isExtensionMember) return _findExtensionMemberName(node);
+ return computeElementNameForSourceMaps(member, callStructure);
+
case MemberKind.closureCall:
ir.TreeNode node = definition.node;
String name;
@@ -70,6 +75,32 @@
}
}
+/// Extract a simple readable name for an extension member.
+String _findExtensionMemberName(ir.Member member) {
+ assert(member.isExtensionMember);
+ for (ir.Extension extension in member.enclosingLibrary.extensions) {
+ for (ir.ExtensionMemberDescriptor descriptor in extension.members) {
+ if (descriptor.member == member.reference) {
+ String extensionName;
+ // Anonymous extensions contain a # on their synthetic name.
+ if (extension.name.contains('#')) {
+ ir.DartType type = extension.onType;
+ if (type is ir.InterfaceType) {
+ extensionName = "${type.classNode.name}.<anonymous extension>";
+ } else {
+ extensionName = "<anonymous extension>";
+ }
+ } else {
+ extensionName = extension.name;
+ }
+ String memberName = descriptor.name.name;
+ return '$extensionName.$memberName';
+ }
+ }
+ }
+ throw StateError('No original name found for extension member $member.');
+}
+
/// [SourceInformationBuilder] that generates [PositionSourceInformation] from
/// Kernel nodes.
class KernelSourceInformationBuilder implements SourceInformationBuilder {
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 0ec782d..084ffd0 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -220,9 +220,9 @@
// Treat the properties of Object specially.
String nameString = node.name.name;
if (nameString == 'hashCode') {
- return typeEnvironment.intType;
+ return typeEnvironment.coreTypes.intLegacyRawType;
} else if (nameString == 'runtimeType') {
- return typeEnvironment.typeType;
+ return typeEnvironment.coreTypes.typeLegacyRawType;
}
return const ir.DynamicType();
}
@@ -382,7 +382,7 @@
ir.Procedure _objectEquals;
ir.Procedure get objectEquals =>
- _objectEquals ??= _getMember(typeEnvironment.objectType.classNode, '==');
+ _objectEquals ??= _getMember(typeEnvironment.coreTypes.objectClass, '==');
/// Returns [receiverType] narrowed to enclosing class of [interfaceTarget].
///
@@ -434,7 +434,7 @@
/// [type].
bool isTypeApplicable(ir.DartType type) {
if (type is ir.DynamicType) return true;
- if (type == typeEnvironment.rawFunctionType) return true;
+ if (type == typeEnvironment.coreTypes.functionLegacyRawType) return true;
if (type is ir.FunctionType) {
return isFunctionTypeApplicable(
type.typeParameters.length,
@@ -636,7 +636,7 @@
}
if (node.name.name == '==') {
// We use this special case to simplify generation of '==' checks.
- return typeEnvironment.boolType;
+ return typeEnvironment.coreTypes.boolLegacyRawType;
}
return const ir.DynamicType();
}
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 2da7c24..c544cb0 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -98,34 +98,36 @@
}
@override
- ir.DartType visitBoolLiteral(ir.BoolLiteral node) => typeEnvironment.boolType;
+ ir.DartType visitBoolLiteral(ir.BoolLiteral node) =>
+ typeEnvironment.coreTypes.boolLegacyRawType;
@override
ir.DartType visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded node) =>
- typeEnvironment.objectType;
+ typeEnvironment.coreTypes.objectLegacyRawType;
@override
ir.DartType visitStringLiteral(ir.StringLiteral node) =>
- typeEnvironment.stringType;
+ typeEnvironment.coreTypes.stringLegacyRawType;
@override
ir.DartType visitStringConcatenation(ir.StringConcatenation node) {
- return typeEnvironment.stringType;
+ return typeEnvironment.coreTypes.stringLegacyRawType;
}
@override
ir.DartType visitNullLiteral(ir.NullLiteral node) => typeEnvironment.nullType;
@override
- ir.DartType visitIntLiteral(ir.IntLiteral node) => typeEnvironment.intType;
+ ir.DartType visitIntLiteral(ir.IntLiteral node) =>
+ typeEnvironment.coreTypes.intLegacyRawType;
@override
ir.DartType visitDoubleLiteral(ir.DoubleLiteral node) =>
- typeEnvironment.doubleType;
+ typeEnvironment.coreTypes.doubleLegacyRawType;
@override
ir.DartType visitSymbolLiteral(ir.SymbolLiteral node) =>
- typeEnvironment.symbolType;
+ typeEnvironment.coreTypes.symbolLegacyRawType;
@override
ir.DartType visitListLiteral(ir.ListLiteral node) {
@@ -181,11 +183,11 @@
@override
ir.DartType visitLogicalExpression(ir.LogicalExpression node) =>
- typeEnvironment.boolType;
+ typeEnvironment.coreTypes.boolLegacyRawType;
@override
ir.DartType visitNot(ir.Not node) {
- return typeEnvironment.boolType;
+ return typeEnvironment.coreTypes.boolLegacyRawType;
}
@override
@@ -195,11 +197,12 @@
@override
ir.DartType visitIsExpression(ir.IsExpression node) {
- return typeEnvironment.boolType;
+ return typeEnvironment.coreTypes.boolLegacyRawType;
}
@override
- ir.DartType visitTypeLiteral(ir.TypeLiteral node) => typeEnvironment.typeType;
+ ir.DartType visitTypeLiteral(ir.TypeLiteral node) =>
+ typeEnvironment.coreTypes.typeLegacyRawType;
@override
ir.DartType visitFunctionExpression(ir.FunctionExpression node) {
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index 0dfdaf9..ecb9b52 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -473,26 +473,29 @@
world.extractTypeArgumentsInterfacesNewRti.contains(cls);
class _RulesetEntry {
- final InterfaceType _targetType;
- List<InterfaceType> _supertypes;
- Map<TypeVariableType, DartType> _typeVariables;
+ Set<InterfaceType> _supertypes = {};
+ Map<TypeVariableType, DartType> _typeVariables = {};
- _RulesetEntry(
- this._targetType, Iterable<InterfaceType> supertypes, this._typeVariables)
- : _supertypes = supertypes.toList();
+ void addAll(Iterable<InterfaceType> supertypes,
+ Map<TypeVariableType, DartType> typeVariables) {
+ _supertypes.addAll(supertypes);
+ _typeVariables.addAll(typeVariables);
+ }
bool get isEmpty => _supertypes.isEmpty && _typeVariables.isEmpty;
}
class Ruleset {
- List<_RulesetEntry> _entries;
+ Map<InterfaceType, _RulesetEntry> _entries;
Ruleset(this._entries);
- Ruleset.empty() : this([]);
+ Ruleset.empty() : this({});
void add(InterfaceType targetType, Iterable<InterfaceType> supertypes,
- Map<TypeVariableType, DartType> typeVariables) =>
- _entries.add(_RulesetEntry(targetType, supertypes, typeVariables));
+ Map<TypeVariableType, DartType> typeVariables) {
+ _RulesetEntry entry = _entries[targetType] ??= _RulesetEntry();
+ entry.addAll(supertypes, typeVariables);
+ }
}
class RulesetEncoder {
@@ -515,16 +518,17 @@
bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
- void _preprocessEntry(_RulesetEntry entry) {
+ void _preprocessEntry(InterfaceType targetType, _RulesetEntry entry) {
entry._supertypes.removeWhere((InterfaceType supertype) =>
- _isObject(supertype) || identical(entry._targetType, supertype));
+ _isObject(supertype) ||
+ identical(targetType.element, supertype.element));
}
void _preprocessRuleset(Ruleset ruleset) {
ruleset._entries
- .removeWhere((_RulesetEntry entry) => _isObject(entry._targetType));
+ .removeWhere((InterfaceType targetType, _) => _isObject(targetType));
ruleset._entries.forEach(_preprocessEntry);
- ruleset._entries.removeWhere((_RulesetEntry entry) => entry.isEmpty);
+ ruleset._entries.removeWhere((_, _RulesetEntry entry) => entry.isEmpty);
}
// TODO(fishythefish): Common substring elimination.
@@ -539,21 +543,22 @@
js.concatenateStrings([
_quote,
_leftBrace,
- ...js.joinLiterals(ruleset._entries.map(_encodeEntry), _comma),
+ ...js.joinLiterals(ruleset._entries.entries.map(_encodeEntry), _comma),
_rightBrace,
_quote,
]);
- jsAst.StringConcatenation _encodeEntry(_RulesetEntry entry) =>
+ jsAst.StringConcatenation _encodeEntry(
+ MapEntry<InterfaceType, _RulesetEntry> entry) =>
js.concatenateStrings([
- js.quoteName(_emitter.typeAccessNewRti(entry._targetType.element)),
+ js.quoteName(_emitter.typeAccessNewRti(entry.key.element)),
_colon,
_leftBrace,
...js.joinLiterals([
- ...entry._supertypes.map((InterfaceType supertype) =>
- _encodeSupertype(entry._targetType, supertype)),
- ...entry._typeVariables.entries.map((mapEntry) => _encodeTypeVariable(
- entry._targetType, mapEntry.key, mapEntry.value))
+ ...entry.value._supertypes.map((InterfaceType supertype) =>
+ _encodeSupertype(entry.key, supertype)),
+ ...entry.value._typeVariables.entries.map((mapEntry) =>
+ _encodeTypeVariable(entry.key, mapEntry.key, mapEntry.value))
], _comma),
_rightBrace,
]);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index adf8d1c..17d454c 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -589,9 +589,12 @@
RecipeEncoder _recipeEncoder;
RulesetEncoder _rulesetEncoder;
+ ClassHierarchy get _classHierarchy => _closedWorld.classHierarchy;
+ CommonElements get _commonElements => _closedWorld.commonElements;
DartTypes get _dartTypes => _closedWorld.dartTypes;
JElementEnvironment get _elementEnvironment =>
_closedWorld.elementEnvironment;
+ NativeData get _nativeData => _closedWorld.nativeData;
js.Name _call0Name, _call1Name, _call2Name;
js.Name get call0Name =>
@@ -1948,17 +1951,35 @@
classes.forEach((Class cls) {
if (cls.classChecksNewRti == null) return;
InterfaceType targetType = _elementEnvironment.getThisType(cls.element);
- Iterable<InterfaceType> supertypes = cls.classChecksNewRti.checks.map(
- (TypeCheck check) => _dartTypes.asInstanceOf(targetType, check.cls));
+ bool isInterop = _nativeData.isJsInteropClass(cls.element);
+
+ Iterable<TypeCheck> checks = cls.classChecksNewRti.checks;
+ Iterable<InterfaceType> supertypes = isInterop
+ ? checks
+ .map((check) => _elementEnvironment.getJsInteropType(check.cls))
+ : checks
+ .map((check) => _dartTypes.asInstanceOf(targetType, check.cls));
+
Map<TypeVariableType, DartType> typeVariables = {};
for (TypeVariableType typeVariable in cls.namedTypeVariablesNewRti) {
TypeVariableEntity element = typeVariable.element;
- InterfaceType supertype =
- _dartTypes.asInstanceOf(targetType, element.typeDeclaration);
+ InterfaceType supertype = isInterop
+ ? _elementEnvironment.getJsInteropType(element.typeDeclaration)
+ : _dartTypes.asInstanceOf(targetType, element.typeDeclaration);
List<DartType> supertypeArguments = supertype.typeArguments;
typeVariables[typeVariable] = supertypeArguments[element.index];
}
- ruleset.add(targetType, supertypes, typeVariables);
+
+ if (isInterop) {
+ _classHierarchy
+ .subtypesOf(_commonElements.jsJavaScriptObjectClass)
+ .forEach((ClassEntity interceptor) {
+ ruleset.add(_elementEnvironment.getThisType(interceptor), supertypes,
+ typeVariables);
+ });
+ } else {
+ ruleset.add(targetType, supertypes, typeVariables);
+ }
});
FunctionEntity method = _closedWorld.commonElements.rtiAddRulesMethod;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index ef075cd..0a78680 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -49,11 +49,13 @@
import '../../js_backend/js_backend.dart'
show Namer, ConstantEmitter, StringBackedName;
import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
+import '../../js_backend/native_data.dart' show NativeData;
import '../../js_backend/runtime_types.dart';
import '../../js_backend/runtime_types_codegen.dart';
import '../../js_backend/runtime_types_new.dart'
show RecipeEncoder, RecipeEncoderImpl, Ruleset, RulesetEncoder;
import '../../options.dart';
+import '../../universe/class_hierarchy.dart' show ClassHierarchy;
import '../../universe/codegen_world_builder.dart' show CodegenWorld;
import '../../world.dart';
import '../code_emitter_task.dart';
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index e0ebc2f..4c87632 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -888,6 +888,9 @@
InterfaceType get mixedInType => null;
@override
+ InterfaceType get jsInteropType => thisType;
+
+ @override
InterfaceType get rawType => thisType;
}
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 43985c5..6b99f16 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -714,6 +714,20 @@
}
}
+ void _ensureJsInteropType(ClassEntity cls, JClassData data) {
+ assert(checkFamily(cls));
+ if (data is JClassDataImpl && data.jsInteropType == null) {
+ ir.Class node = data.cls;
+ if (node.typeParameters.isEmpty) {
+ _ensureThisAndRawType(cls, data);
+ data.jsInteropType = data.thisType;
+ } else {
+ data.jsInteropType = InterfaceType(cls,
+ List<DartType>.filled(node.typeParameters.length, const AnyType()));
+ }
+ }
+ }
+
@override
TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
getTypeVariableInternal(node);
@@ -993,6 +1007,13 @@
return data.thisType;
}
+ InterfaceType _getJsInteropType(IndexedClass cls) {
+ assert(checkFamily(cls));
+ JClassData data = classes.getData(cls);
+ _ensureJsInteropType(cls, data);
+ return data.jsInteropType;
+ }
+
InterfaceType _getRawType(IndexedClass cls) {
assert(checkFamily(cls));
JClassData data = classes.getData(cls);
@@ -2181,6 +2202,11 @@
}
@override
+ InterfaceType getJsInteropType(ClassEntity cls) {
+ return elementMap._getJsInteropType(cls);
+ }
+
+ @override
InterfaceType getRawType(ClassEntity cls) {
return elementMap._getRawType(cls);
}
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index ac096b1..527a27b 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -440,6 +440,7 @@
ClassDefinition get definition;
InterfaceType get thisType;
+ InterfaceType get jsInteropType;
InterfaceType get rawType;
InterfaceType get supertype;
InterfaceType get mixedInType;
@@ -466,6 +467,8 @@
@override
InterfaceType thisType;
@override
+ InterfaceType jsInteropType;
+ @override
InterfaceType rawType;
@override
InterfaceType supertype;
diff --git a/pkg/compiler/lib/src/js_model/type_recipe.dart b/pkg/compiler/lib/src/js_model/type_recipe.dart
index ed1543c..9e17421 100644
--- a/pkg/compiler/lib/src/js_model/type_recipe.dart
+++ b/pkg/compiler/lib/src/js_model/type_recipe.dart
@@ -4,7 +4,77 @@
library dart2js.js_model.type_recipe;
+import '../elements/entities.dart' show ClassEntity;
import '../elements/types.dart';
+import '../diagnostics/invariant.dart';
+import '../diagnostics/spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
+
+abstract class TypeRecipeDomain {
+ /// Detect if a recipe evaluates to its input environment.
+ ///
+ /// Returns `true` if [recipe] evaluates in an environment with [structure] to
+ /// the environment. This is typically a recipe that selects the entire input.
+ bool isIdentity(TypeRecipe recipe, TypeEnvironmentStructure structure);
+
+ /// Detect if a recipe evaluates to its input environment.
+ ///
+ /// Returns `true` if [recipe] evaluates in an environment with
+ /// [environmentStructure] to the environment, where the environment is known
+ /// to be an instance type of exactly the class [classEntity].
+ ///
+ /// This is a special case of [isIdentity] where we have additional
+ /// information about the input environment that is not encoded in the
+ /// environment structure.
+ // TODO(sra): Consider extending TypeEnvironmentStructure to encode when the
+ // classType is an exact type. Then the [classEntity] parameter would not be
+ // needed.
+ bool isReconstruction(ClassEntity classEntity,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
+
+ /// Tries to evaluate [recipe] against a fixed environment [environmentRecipe]
+ /// having structure [environmentStructure].
+ ///
+ /// May return `null` if the evaluation is too complex.
+ TypeRecipe foldLoadEval(TypeRecipe environmentRecipe,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
+
+ /// Partial constant folding of a type expression when the environment is
+ /// created by binding a ground term.
+ ///
+ /// An 'original' environment is extended with [bindArgument] to produce an
+ /// intermediate environment with structure [environmentStructure]. [recipe]
+ /// is evaluated against this intermediate environment to produce a result.
+ ///
+ /// Returns the structure of the 'original' environment and a recipe that
+ /// evaluates against that structure to produce the same result.
+ ///
+ /// [bindArgument] must be a ground term, i.e. have no type variables.
+ TypeRecipeAndEnvironmentStructure foldBindLoadEval(
+ TypeRecipe bindArgument,
+ TypeEnvironmentStructure environmentStructure,
+ TypeRecipe recipe,
+ );
+
+ /// Combines [recipe1] and [recipe2] into a single recipe that can be
+ /// evaluated against [environmentStructure1]. ([recipe1] produces an
+ /// intermediate type or environment value that conforms to the layout
+ /// described by [environmentStructure2].)
+ TypeRecipeAndEnvironmentStructure foldEvalEval(
+ TypeEnvironmentStructure environmentStructure1,
+ TypeRecipe recipe1,
+ TypeEnvironmentStructure environmentStructure2,
+ TypeRecipe recipe2,
+ );
+}
+
+/// A type recipe and the structure of the type environment against which it is
+/// evaluated.
+class TypeRecipeAndEnvironmentStructure {
+ final TypeRecipe recipe;
+ final TypeEnvironmentStructure environmentStructure;
+
+ TypeRecipeAndEnvironmentStructure(this.recipe, this.environmentStructure);
+}
/// A TypeEnvironmentStructure describes the shape or layout of a reified type
/// environment.
@@ -79,17 +149,6 @@
// yield the same type, e.g. `List<X> @X` and `List<Y> @Y`.
return false;
}
-
- /// Returns `true` if [recipe] evaluates in an environment with [structure] to
- /// the environment.
- static bool isIdentity(
- TypeRecipe recipe, TypeEnvironmentStructure structure) {
- if (structure is SingletonTypeEnvironmentStructure &&
- recipe is TypeExpressionRecipe) {
- if (structure.variable == recipe.type) return true;
- }
- return false;
- }
}
/// A recipe that yields a reified type.
@@ -161,3 +220,243 @@
@override
String toString() => 'FullTypeEnvironmentRecipe($classType, $types)';
}
+
+class TypeRecipeDomainImpl implements TypeRecipeDomain {
+ @override
+ bool isIdentity(TypeRecipe recipe, TypeEnvironmentStructure structure) {
+ if (structure is SingletonTypeEnvironmentStructure &&
+ recipe is TypeExpressionRecipe) {
+ if (structure.variable == recipe.type) return true;
+ }
+ return false;
+ }
+
+ @override
+ bool isReconstruction(ClassEntity classEntity,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
+ if (environmentStructure is FullTypeEnvironmentStructure &&
+ environmentStructure.bindings.isEmpty) {
+ InterfaceType classType = environmentStructure.classType;
+ if (classType.element == classEntity) {
+ if (recipe is TypeExpressionRecipe && recipe.type == classType) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @override
+ TypeRecipe foldLoadEval(TypeRecipe environmentRecipe,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
+ if (environmentStructure is SingletonTypeEnvironmentStructure) {
+ if (environmentRecipe is TypeExpressionRecipe) {
+ List<TypeVariableType> variables = [environmentStructure.variable];
+ List<DartType> replacements = [environmentRecipe.type];
+ return _Substitution(null, null, variables, replacements)
+ .substituteRecipe(recipe);
+ }
+ failedAt(CURRENT_ELEMENT_SPANNABLE,
+ 'Expected a TypeExpressionRecipe: $environmentRecipe');
+ return null;
+ }
+
+ if (environmentStructure is FullTypeEnvironmentStructure) {
+ if (environmentStructure.classType != null) {
+ if (environmentRecipe is TypeExpressionRecipe) {
+ assert(environmentStructure.bindings.isEmpty);
+ return _Substitution(environmentStructure.classType,
+ environmentRecipe.type, null, null)
+ .substituteRecipe(recipe);
+ }
+ return null;
+ }
+ if (environmentRecipe is TypeExpressionRecipe) {
+ // Is this possible?
+ return null;
+ }
+ if (environmentRecipe is FullTypeEnvironmentRecipe) {
+ return _Substitution(
+ environmentStructure.classType,
+ environmentRecipe.classType,
+ environmentStructure.bindings,
+ environmentRecipe.types)
+ .substituteRecipe(recipe);
+ }
+ return null;
+ }
+
+ failedAt(CURRENT_ELEMENT_SPANNABLE,
+ 'Unknown environmentStructure: $environmentStructure');
+ return null;
+ }
+
+ @override
+ TypeRecipeAndEnvironmentStructure foldBindLoadEval(TypeRecipe bindArgument,
+ TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
+ // 'Bind' adds variables to the environment. We fold 'bind' of a ground type
+ // by removing the added variables and replacing them in the recipe with the
+ // constant type values.
+
+ if (environmentStructure is FullTypeEnvironmentStructure) {
+ List<DartType> replacements;
+ if (bindArgument is TypeExpressionRecipe) {
+ // Bind call adds a single binding.
+ replacements = [bindArgument.type];
+ } else if (bindArgument is FullTypeEnvironmentRecipe) {
+ replacements = bindArgument.types;
+ } else {
+ failedAt(CURRENT_ELEMENT_SPANNABLE,
+ 'Unexpected bindArgument: $bindArgument');
+ }
+ List<TypeVariableType> bindings = environmentStructure.bindings;
+ int index = bindings.length - replacements.length;
+ List<TypeVariableType> replacedVariables = bindings.sublist(index);
+ List<TypeVariableType> remainingVariables = bindings.sublist(0, index);
+ TypeRecipe newRecipe =
+ _Substitution(null, null, replacedVariables, replacements)
+ .substituteRecipe(recipe);
+ if (newRecipe == null) return null;
+ TypeEnvironmentStructure newEnvironmentStructure =
+ FullTypeEnvironmentStructure(
+ classType: environmentStructure.classType,
+ bindings: remainingVariables);
+ return TypeRecipeAndEnvironmentStructure(
+ newRecipe, newEnvironmentStructure);
+ }
+
+ failedAt(CURRENT_ELEMENT_SPANNABLE,
+ 'unexpected bind on environment with structure $environmentStructure');
+ return null;
+ }
+
+ @override
+ TypeRecipeAndEnvironmentStructure foldEvalEval(
+ TypeEnvironmentStructure environmentStructure1,
+ TypeRecipe recipe1,
+ TypeEnvironmentStructure environmentStructure2,
+ TypeRecipe recipe2) {
+ if (environmentStructure2 is SingletonTypeEnvironmentStructure &&
+ recipe1 is TypeExpressionRecipe) {
+ TypeRecipe newRecipe = _Substitution(
+ null, null, [environmentStructure2.variable], [recipe1.type])
+ .substituteRecipe(recipe2);
+ if (newRecipe == null) return null;
+ return TypeRecipeAndEnvironmentStructure(
+ newRecipe, environmentStructure1);
+ }
+
+ if (environmentStructure2 is FullTypeEnvironmentStructure &&
+ recipe1 is TypeExpressionRecipe) {
+ assert(environmentStructure2.bindings.isEmpty);
+ TypeRecipe newRecipe = _Substitution(
+ environmentStructure2.classType, recipe1.type, null, null)
+ .substituteRecipe(recipe2);
+ if (newRecipe == null) return null;
+ return TypeRecipeAndEnvironmentStructure(
+ newRecipe, environmentStructure1);
+ }
+
+ if (environmentStructure2 is FullTypeEnvironmentStructure &&
+ recipe1 is FullTypeEnvironmentRecipe) {
+ TypeRecipe newRecipe = _Substitution(environmentStructure2.classType,
+ recipe1.classType, environmentStructure2.bindings, recipe1.types)
+ .substituteRecipe(recipe2);
+ if (newRecipe == null) return null;
+ return TypeRecipeAndEnvironmentStructure(
+ newRecipe, environmentStructure1);
+ }
+
+ return null;
+ }
+}
+
+/// Substitution algorithm for transforming a TypeRecipe by substitution of
+/// bindings of a type environment.
+///
+/// Since the general case of a type environment has class type variables (bound
+/// by a class instance type) and method type variable bindings, both are
+/// provided. The class type variables can be implicit (e.g. CodeUnits defines
+/// ListMixin.E), whereas the method type variables are always bound explicitly.
+///
+/// A [_Substitution] contains the bindings and the state required to perform
+/// a single substitution.
+class _Substitution extends DartTypeSubstitutionVisitor<Null> {
+ final Map<DartType, DartType> _lookupCache = {};
+ final Map<DartType, int> _counts = {};
+ bool _failed = false;
+
+ final InterfaceType _classEnvironment;
+ final InterfaceType _classValue;
+ final List<TypeVariableType> _variables;
+ final List<DartType> _replacements;
+
+ _Substitution(this._classEnvironment, this._classValue, this._variables,
+ this._replacements)
+ : assert(_variables?.length == _replacements?.length);
+
+ // Returns `null` if declined.
+ TypeRecipe substituteRecipe(TypeRecipe recipe) {
+ if (recipe is TypeExpressionRecipe) {
+ DartType result = _substituteType(recipe.type);
+ if (_failed) return null;
+ return TypeExpressionRecipe(result);
+ }
+ if (recipe is FullTypeEnvironmentRecipe) {
+ DartType newClass = _substitutePossiblyNullType(recipe.classType);
+ List<DartType> newTypes = recipe.types.map(_substituteType).toList();
+ if (_failed) return null;
+ return FullTypeEnvironmentRecipe(classType: newClass, types: newTypes);
+ }
+
+ failedAt(CURRENT_ELEMENT_SPANNABLE, 'Unexpected recipe: $recipe');
+ return null;
+ }
+
+ DartType _substituteType(DartType type) => visit(type, null);
+
+ DartType _substitutePossiblyNullType(DartType type) =>
+ type == null ? null : visit(type, null);
+
+ // Returns `null` if not bound.
+ DartType _lookupTypeVariableType(TypeVariableType type) {
+ if (_variables != null) {
+ int index = _variables.indexOf(type);
+ if (index >= 0) return _replacements[index];
+ }
+ if (_classEnvironment == null) return null;
+
+ if (_classEnvironment.element == _classValue.element) {
+ int index = _classEnvironment.typeArguments.indexOf(type);
+ if (index >= 0) return _classValue.typeArguments[index];
+ return null;
+ }
+ // TODO(sra): Lookup type variable of supertype (e.g. ListMixin.E of
+ // CodeUnits).
+ _failed = true;
+ return null;
+ }
+
+ @override
+ DartType substituteTypeVariableType(
+ TypeVariableType variable, Null argument, bool freshReference) {
+ DartType replacement =
+ _lookupCache[variable] ??= _lookupTypeVariableType(variable);
+ if (replacement == null) return variable; // not substituted.
+ if (!freshReference) return replacement;
+ int count = _counts[variable] = (_counts[variable] ?? 0) + 1;
+ if (count > 1) {
+ // If the replacement is 'big', duplicating it can grow the term, perhaps
+ // exponentially given a sufficently pathological input.
+ // TODO(sra): Fix exponential terms by encoding a DAG in recipes to avoid
+ // linearization.
+ if (replacement is FunctionType ||
+ replacement is InterfaceType &&
+ replacement.typeArguments.isNotEmpty ||
+ replacement is FutureOrType) {
+ _failed = true;
+ }
+ }
+ return replacement;
+ }
+}
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 5818ce3..1c3701c 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -285,6 +285,20 @@
}
}
+ void _ensureJsInteropType(ClassEntity cls, KClassData data) {
+ assert(checkFamily(cls));
+ if (data is KClassDataImpl && data.jsInteropType == null) {
+ ir.Class node = data.node;
+ if (node.typeParameters.isEmpty) {
+ _ensureThisAndRawType(cls, data);
+ data.jsInteropType = data.thisType;
+ } else {
+ data.jsInteropType = InterfaceType(cls,
+ List<DartType>.filled(node.typeParameters.length, const AnyType()));
+ }
+ }
+ }
+
@override
TypeVariableEntity getTypeVariable(ir.TypeParameter node) =>
getTypeVariableInternal(node);
@@ -567,6 +581,13 @@
return data.thisType;
}
+ InterfaceType _getJsInteropType(IndexedClass cls) {
+ assert(checkFamily(cls));
+ KClassData data = classes.getData(cls);
+ _ensureJsInteropType(cls, data);
+ return data.jsInteropType;
+ }
+
InterfaceType _getRawType(IndexedClass cls) {
assert(checkFamily(cls));
KClassData data = classes.getData(cls);
@@ -1645,6 +1666,11 @@
}
@override
+ InterfaceType getJsInteropType(ClassEntity cls) {
+ return elementMap._getJsInteropType(cls);
+ }
+
+ @override
InterfaceType getRawType(ClassEntity cls) {
return elementMap._getRawType(cls);
}
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 1b22344..8dd1973 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -612,6 +612,7 @@
ir.Class get node;
InterfaceType get thisType;
+ InterfaceType get jsInteropType;
InterfaceType get rawType;
InterfaceType get supertype;
InterfaceType get mixedInType;
@@ -638,6 +639,8 @@
@override
InterfaceType thisType;
@override
+ InterfaceType jsInteropType;
+ @override
InterfaceType rawType;
@override
InterfaceType supertype;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 2e65567..b23b29c 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4698,8 +4698,9 @@
InterfaceType(_commonElements.jsArrayClass, [DynamicType()]);
SourceInformation sourceInformation =
_sourceInformationBuilder.buildCall(invocation, invocation);
- HInstruction rti = HLoadType(interopType, _abstractValueDomain.dynamicType)
- ..sourceInformation = sourceInformation;
+ HInstruction rti =
+ HLoadType.type(interopType, _abstractValueDomain.dynamicType)
+ ..sourceInformation = sourceInformation;
push(rti);
}
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 1197751..158413d 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -31,7 +31,6 @@
show RecipeEncoder, RecipeEncoding;
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
import '../js_model/elements.dart' show JGeneratorBody;
-import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
import '../native/behavior.dart';
import '../options.dart';
import '../tracer.dart';
@@ -3400,8 +3399,8 @@
FunctionEntity helperElement = _commonElements.findType;
_registry.registerStaticUse(
new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
- js.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
- _emitter, TypeExpressionRecipe(node.typeExpression));
+ js.Expression recipe =
+ _rtiRecipeEncoder.encodeGroundRecipe(_emitter, node.typeExpression);
js.Expression helper = _emitter.staticFunctionAccess(helperElement);
push(js.js(r'#(#)', [helper, recipe]).withSourceInformation(
node.sourceInformation));
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 495f629..068ae28 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -14,7 +14,8 @@
import '../inferrer/abstract_value_domain.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
-import '../js_model/type_recipe.dart' show TypeEnvironmentStructure, TypeRecipe;
+import '../js_model/type_recipe.dart'
+ show TypeEnvironmentStructure, TypeRecipe, TypeExpressionRecipe;
import '../native/behavior.dart';
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
@@ -4518,12 +4519,16 @@
/// Evaluates an Rti type recipe in the global environment.
class HLoadType extends HRtiInstruction {
- DartType typeExpression; // TODO(sra): Allow a type environment expression.
+ TypeRecipe typeExpression;
- HLoadType(this.typeExpression, AbstractValue type) : super([], type) {
+ HLoadType(this.typeExpression, AbstractValue instructionType)
+ : super([], instructionType) {
setUseGvn();
}
+ HLoadType.type(DartType dartType, AbstractValue instructionType)
+ : this(TypeExpressionRecipe(dartType), instructionType);
+
@override
accept(HVisitor visitor) => visitor.visitLoadType(this);
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 8eb2043..d7d7140 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -18,7 +18,13 @@
import '../js_backend/backend.dart' show CodegenInputs;
import '../js_backend/native_data.dart' show NativeData;
import '../js_backend/runtime_types_codegen.dart';
-import '../js_model/type_recipe.dart' show TypeRecipe;
+import '../js_model/type_recipe.dart'
+ show
+ TypeRecipe,
+ TypeExpressionRecipe,
+ TypeRecipeAndEnvironmentStructure,
+ TypeRecipeDomain,
+ TypeRecipeDomainImpl;
import '../js_backend/specialized_checks.dart';
import '../native/behavior.dart';
import '../options.dart';
@@ -70,6 +76,8 @@
SsaCodeMotion codeMotion;
SsaLoadElimination loadElimination;
+ TypeRecipeDomain typeRecipeDomain = TypeRecipeDomainImpl();
+
OptimizationTestLog log;
if (retainDataForTesting) {
loggersForTesting ??= {};
@@ -80,8 +88,14 @@
List<OptimizationPhase> phases = <OptimizationPhase>[
// Run trivial instruction simplification first to optimize
// some patterns useful for type conversion.
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
new SsaTypeConversionInserter(closedWorld),
new SsaRedundantPhiEliminator(),
new SsaDeadPhiEliminator(),
@@ -89,11 +103,23 @@
closedWorld.commonElements, closedWorld, log),
// After type propagation, more instructions can be
// simplified.
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
new SsaTypePropagator(globalInferenceResults,
closedWorld.commonElements, closedWorld, log),
@@ -118,8 +144,14 @@
new SsaValueRangeAnalyzer(closedWorld, this),
// Previous optimizations may have generated new
// opportunities for instruction simplification.
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
];
phases.forEach(runPhase);
@@ -133,6 +165,7 @@
runPhase(dce);
if (codeMotion.movedCode ||
dce.eliminatedSideEffects ||
+ dce.newGvnCandidates ||
loadElimination.newGvnCandidates) {
phases = <OptimizationPhase>[
new SsaTypePropagator(globalInferenceResults,
@@ -140,8 +173,14 @@
new SsaGlobalValueNumberer(closedWorld.abstractValueDomain),
new SsaCodeMotion(closedWorld.abstractValueDomain),
new SsaValueRangeAnalyzer(closedWorld, this),
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
new SsaSimplifyInterceptors(closedWorld, member.enclosingClass),
new SsaDeadCodeEliminator(closedWorld, this),
@@ -152,8 +191,14 @@
closedWorld.commonElements, closedWorld, log),
// Run the simplifier to remove unneeded type checks inserted by
// type propagation.
- new SsaInstructionSimplifier(globalInferenceResults, _options,
- codegen.rtiSubstitutions, closedWorld, registry, log),
+ new SsaInstructionSimplifier(
+ globalInferenceResults,
+ _options,
+ codegen.rtiSubstitutions,
+ closedWorld,
+ typeRecipeDomain,
+ registry,
+ log),
];
}
phases.forEach(runPhase);
@@ -196,12 +241,19 @@
final CompilerOptions _options;
final RuntimeTypesSubstitutions _rtiSubstitutions;
final JClosedWorld _closedWorld;
+ final TypeRecipeDomain _typeRecipeDomain;
final CodegenRegistry _registry;
final OptimizationTestLog _log;
HGraph _graph;
- SsaInstructionSimplifier(this._globalInferenceResults, this._options,
- this._rtiSubstitutions, this._closedWorld, this._registry, this._log);
+ SsaInstructionSimplifier(
+ this._globalInferenceResults,
+ this._options,
+ this._rtiSubstitutions,
+ this._closedWorld,
+ this._typeRecipeDomain,
+ this._registry,
+ this._log);
JCommonElements get commonElements => _closedWorld.commonElements;
@@ -638,7 +690,7 @@
HInstruction typeInfo;
if (_options.experimentNewRti) {
- typeInfo = HLoadType(
+ typeInfo = HLoadType.type(
_closedWorld.elementEnvironment.createInterfaceType(
commonElements.jsArrayClass, [commonElements.stringType]),
_abstractValueDomain.dynamicType);
@@ -1884,9 +1936,77 @@
@override
HInstruction visitTypeEval(HTypeEval node) {
- if (TypeRecipe.isIdentity(node.typeExpression, node.envStructure)) {
- return node.inputs.single;
+ HInstruction environment = node.inputs.single;
+ if (_typeRecipeDomain.isIdentity(node.typeExpression, node.envStructure)) {
+ return environment;
}
+
+ if (environment is HLoadType) {
+ TypeRecipe result = _typeRecipeDomain.foldLoadEval(
+ environment.typeExpression, node.envStructure, node.typeExpression);
+ if (result != null) return HLoadType(result, node.instructionType);
+ return node;
+ }
+
+ if (environment is HTypeBind) {
+ HInstruction bindings = environment.inputs.last;
+ if (bindings is HLoadType) {
+ // env.bind(LoadType(T)).eval(...1...) --> env.eval(...T...)
+ TypeRecipeAndEnvironmentStructure result =
+ _typeRecipeDomain.foldBindLoadEval(bindings.typeExpression,
+ node.envStructure, node.typeExpression);
+ if (result != null) {
+ HInstruction previousEnvironment = environment.inputs.first;
+ return HTypeEval(previousEnvironment, result.environmentStructure,
+ result.recipe, node.instructionType);
+ }
+ }
+ // TODO(sra): LoadType(T).bind(E).eval(...1...) --> E.eval(...0...)
+ return node;
+ }
+
+ if (environment is HTypeEval) {
+ TypeRecipeAndEnvironmentStructure result = _typeRecipeDomain.foldEvalEval(
+ environment.envStructure,
+ environment.typeExpression,
+ node.envStructure,
+ node.typeExpression);
+ if (result != null) {
+ HInstruction previousEnvironment = environment.inputs.first;
+ return HTypeEval(previousEnvironment, result.environmentStructure,
+ result.recipe, node.instructionType);
+ }
+ return node;
+ }
+
+ if (environment is HInstanceEnvironment) {
+ HInstruction instance = environment.inputs.single;
+ AbstractValue instanceAbstractValue = instance.instructionType;
+ ClassEntity instanceClass =
+ _abstractValueDomain.getExactClass(instanceAbstractValue);
+ if (instanceClass == null) {
+ // All the subclasses of JSArray are JSArray at runtime.
+ ClassEntity jsArrayClass = _closedWorld.commonElements.jsArrayClass;
+ if (_abstractValueDomain
+ .isInstanceOf(instanceAbstractValue, jsArrayClass)
+ .isDefinitelyTrue) {
+ instanceClass = jsArrayClass;
+ }
+ }
+ if (instanceClass != null) {
+ if (_typeRecipeDomain.isReconstruction(
+ instanceClass, node.envStructure, node.typeExpression)) {
+ return environment;
+ }
+ }
+ }
+
+ return node;
+ }
+
+ @override
+ HInstruction visitTypeBind(HTypeBind node) {
+ // TODO(sra): env1.eval(X).bind(env1.eval(Y)) --> env1.eval(...X...Y...)
return node;
}
@@ -1897,7 +2017,8 @@
// See if this check can be lowered to a simple one.
HInstruction typeInput = node.typeInput;
if (typeInput is HLoadType) {
- DartType dartType = typeInput.typeExpression;
+ TypeExpressionRecipe recipe = typeInput.typeExpression;
+ DartType dartType = recipe.type;
MemberEntity specializedCheck = SpecializedChecks.findAsCheck(
dartType, node.isTypeError, _closedWorld.commonElements);
if (specializedCheck != null) {
@@ -1906,6 +2027,9 @@
return HAsCheckSimple(node.checkedInput, dartType, checkedType,
node.isTypeError, specializedCheck, node.instructionType);
}
+ if (dartType is DynamicType) {
+ return node.checkedInput;
+ }
}
return node;
}
@@ -1957,7 +2081,13 @@
if (instance is HCreate) {
if (instance.hasRtiInput) {
instance.instantiatedTypes?.forEach(_registry.registerInstantiation);
- return instance.inputs.last;
+ return instance.rtiInput;
+ }
+ InterfaceType instanceType =
+ _closedWorld.elementEnvironment.getThisType(instance.element);
+ if (instanceType.typeArguments.length == 0) {
+ instance.instantiatedTypes?.forEach(_registry.registerInstantiation);
+ return HLoadType.type(instanceType, instance.instructionType);
}
return node;
}
@@ -1966,7 +2096,7 @@
ConstantValue constantValue = instance.constant;
if (constantValue is ConstructedConstantValue) {
_registry.registerInstantiation(constantValue.type);
- return HLoadType(constantValue.type, instance.instructionType);
+ return HLoadType.type(constantValue.type, instance.instructionType);
}
return node;
}
@@ -2081,6 +2211,7 @@
Map<HInstruction, bool> trivialDeadStoreReceivers =
new Maplet<HInstruction, bool>();
bool eliminatedSideEffects = false;
+ bool newGvnCandidates = false;
SsaDeadCodeEliminator(this.closedWorld, this.optimizer);
@@ -2321,6 +2452,9 @@
while (!instruction.isControlFlow()) {
HInstruction next = instruction.next;
if (instruction is HTypeKnown && instruction.isPinned) break;
+ // It might be worth re-running GVN optimizations if we hoisted a
+ // GVN-able instructions from [target] into [block].
+ newGvnCandidates = newGvnCandidates || instruction.useGvn();
instruction.block.detach(instruction);
block.moveAtExit(instruction);
instruction = next;
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index aac509a..0b77dbd 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -288,8 +288,9 @@
argument = argument.unaliased;
if (!argument.containsTypeVariables) {
- HInstruction rti = HLoadType(argument, _abstractValueDomain.dynamicType)
- ..sourceInformation = sourceInformation;
+ HInstruction rti =
+ HLoadType.type(argument, _abstractValueDomain.dynamicType)
+ ..sourceInformation = sourceInformation;
builder.add(rti);
return rti;
}
diff --git a/pkg/compiler/testing.json b/pkg/compiler/testing.json
index 498a45c..dcac855 100644
--- a/pkg/compiler/testing.json
+++ b/pkg/compiler/testing.json
@@ -16,7 +16,8 @@
"exclude": [
"^tests/compiler/dart2js/.*/data/.*",
"^tests/compiler/dart2js/.*/model_data/.*",
- "^tests/compiler/dart2js/deferred_loading/libs/.*"
+ "^tests/compiler/dart2js/deferred_loading/libs/.*",
+ "^tests/compiler/dart2js/sourcemaps/stacktrace/extension_method.dart"
]
}
}
diff --git a/pkg/dart2native/bin/dart2aot.dart b/pkg/dart2native/bin/dart2aot.dart
deleted file mode 100644
index b406184..0000000
--- a/pkg/dart2native/bin/dart2aot.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2019, 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:io';
-import 'package:args/args.dart';
-import 'package:path/path.dart';
-
-const clearLine = '\r\x1b[2K';
-
-void aot(String sourceFile, String snapshotFile, bool enableAsserts,
- bool buildElf, bool tfa, bool noTfa, String packages, List<String> ds) {
- if (!FileSystemEntity.isFileSync(sourceFile)) {
- print('Error: $sourceFile is not a file');
- return;
- }
-
- String genSnapshotOption = buildElf
- ? '--snapshot-kind=app-aot-assembly'
- : '--snapshot-kind=app-aot-blobs';
- String genSnapshotFilename = buildElf
- ? '--assembly=$snapshotFile.S'
- : '--blobs_container_filename=$snapshotFile';
-
- String snapDir = dirname(Platform.script.path);
- String binDir = canonicalize(join(snapDir, '..'));
- String sdkDir = canonicalize(join(binDir, '..'));
- String dartCommand = join(binDir, 'dart');
- String snapshot = join(snapDir, 'gen_kernel.dart.snapshot');
-
- stdout.write('${clearLine}Generating AOT snapshot');
- List<String> dartArgs = <String>[
- snapshot,
- '--platform',
- '${sdkDir}//lib/_internal/vm_platform_strong.dill',
- '--aot',
- '-Ddart.vm.product=true',
- if (tfa) '--tfa',
- if (noTfa) '--no-tfa',
- ...ds,
- if (packages != null) ...['--packages', packages],
- '-o',
- '$snapshotFile.dill',
- sourceFile
- ];
-
- var cmdResult = Process.runSync(dartCommand, dartArgs);
- if (cmdResult.exitCode != 0) {
- print('\nGenerating AOT snapshot failed\n');
- print(cmdResult.stdout);
- print(cmdResult.stderr);
- return;
- }
-
- stdout.write("${clearLine}Generating AOT .dill");
- String genSnapshotCommand = join(binDir, 'utils', 'gen_snapshot');
- List<String> genSnapshotArgs = [
- genSnapshotOption,
- genSnapshotFilename,
- if (enableAsserts) '--enable-asserts',
- '$snapshotFile.dill'
- ];
- cmdResult = Process.runSync(genSnapshotCommand, genSnapshotArgs);
- if (cmdResult.exitCode != 0) {
- print('\nGenerating AOT .dill failed\n');
- print(cmdResult.stdout);
- print(cmdResult.stderr);
- return;
- }
- stdout.write("${clearLine}Done.\n");
- stdout.flush();
-}
-
-void setupAOTArgs(ArgParser parser) {
- parser.addFlag('build-elf');
- parser.addFlag('enable-asserts');
- parser.addFlag('tfa');
- parser.addFlag('no-tfa');
- parser.addOption('packages');
-}
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index ac9cf35..f15d5d2 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -3,68 +3,171 @@
// 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:io';
+
import 'package:args/args.dart';
-import 'dart2aot.dart';
+import 'package:dart2native/dart2native.dart';
+import 'package:path/path.dart' as path;
-typedef void Command(ArgResults args, List<String> ds);
+final String executableSuffix = Platform.isWindows ? '.exe' : '';
+final String snapshotDir = path.dirname(Platform.script.toFilePath());
+final String binDir = path.canonicalize(path.join(snapshotDir, '..'));
+final String sdkDir = path.canonicalize(path.join(binDir, '..'));
+final String dart = path.join(binDir, 'dart${executableSuffix}');
+final String genKernel = path.join(snapshotDir, 'gen_kernel.dart.snapshot');
+final String dartaotruntime =
+ path.join(binDir, 'dartaotruntime${executableSuffix}');
+final String genSnapshot =
+ path.join(binDir, 'utils', 'gen_snapshot${executableSuffix}');
+final String platformDill =
+ path.join(sdkDir, 'lib', '_internal', 'vm_platform_strong.dill');
-void main(List<String> args) {
- Map<String, Command> commands = <String, Command>{};
- commands['aot'] = callAOT;
-
- // Read -D args that the ArgParser can't handle.
- List<String> ds = [];
- args = filterDArgs(args, ds);
-
- ArgParser parser = ArgParser();
- parser.addFlag('help');
- ArgParser aotParser = parser.addCommand('aot');
- setupAOTArgs(aotParser);
-
- ArgResults result = null;
+Future<void> generateNative(
+ Kind kind,
+ String sourceFile,
+ String outputFile,
+ String packages,
+ List<String> defines,
+ bool enableAsserts,
+ bool verbose) async {
+ final Directory tempDir = Directory.systemTemp.createTempSync();
try {
- result = parser.parse(args);
- } catch (ArgParserException) {
- // We handle this case as result == null below.
- }
+ final String kernelFile = path.join(tempDir.path, 'kernel.dill');
+ final String snapshotFile = (kind == Kind.aot
+ ? outputFile
+ : path.join(tempDir.path, 'snapshot.aot'));
- if (result == null || result.command == null || result['help']) {
- print('dart2native <command> <args>\n');
- print(' command: ');
- print(' aot - Compile script into one ahead of time dart snapshot');
- return;
- }
-
- if (commands.containsKey(result.command.name)) {
- commands[result.command.name](result.command, ds);
- return;
- }
-}
-
-void callAOT(ArgResults args, List<String> ds) {
- List<String> rest = args.rest;
- if (rest.length != 2) {
- print(
- 'Usage: dart2native aot [options] <dart-source-file> <dart-aot-file>\n');
- print(
- 'Dart AOT (ahead-of-time) compile Dart source code into native machine code.');
- return;
- }
-
- aot(rest[0], rest[1], args['build-elf'], args['enable-asserts'], args['tfa'],
- args['no-tfa'], args['packages'], ds);
-}
-
-List<String> filterDArgs(List<String> args, List<String> ds) {
- List<String> result = <String>[];
-
- args.forEach((String arg) {
- if (!arg.startsWith('-D')) {
- result.add(arg);
- } else {
- ds.add(arg);
+ if (verbose) {
+ print('Generating AOT kernel dill.');
}
- });
+ final kernelResult = await generateAotKernel(dart, genKernel, platformDill,
+ sourceFile, kernelFile, packages, defines);
+ if (kernelResult.exitCode != 0) {
+ stderr.writeln(kernelResult.stdout);
+ stderr.writeln(kernelResult.stderr);
+ await stderr.flush();
+ throw 'Generating AOT kernel dill failed!';
+ }
- return result;
+ if (verbose) {
+ print('Generating AOT snapshot.');
+ }
+ final snapshotResult = await generateAotSnapshot(
+ genSnapshot, kernelFile, snapshotFile, enableAsserts);
+ if (snapshotResult.exitCode != 0) {
+ stderr.writeln(snapshotResult.stdout);
+ stderr.writeln(snapshotResult.stderr);
+ await stderr.flush();
+ throw 'Generating AOT snapshot failed!';
+ }
+
+ if (kind == Kind.exe) {
+ if (verbose) {
+ print('Generating executable.');
+ }
+ await writeAppendedExecutable(dartaotruntime, snapshotFile, outputFile);
+
+ if (Platform.isLinux || Platform.isMacOS) {
+ if (verbose) {
+ print('Marking binary executable.');
+ }
+ await markExecutable(outputFile);
+ }
+ }
+
+ print('Generated: ${outputFile}');
+ } finally {
+ tempDir.deleteSync(recursive: true);
+ }
+}
+
+void printUsage(final ArgParser parser) {
+ print('''
+Usage: dart2native <main-dart-file> [<options>]
+
+Generates an executable or an AOT snapshot from <main-dart-file>.
+''');
+ print(parser.usage);
+}
+
+Future<void> main(List<String> args) async {
+ final ArgParser parser = ArgParser()
+ ..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
+Set values of environment variables.
+To specify multiple variables, use multiple flags or use commas to separate pairs.
+Example:
+dart2native -Da=1,b=2 -Dc=3 --define=d=4 main.dart''')
+ ..addFlag('enable-asserts',
+ negatable: false, help: 'Enable assert statements.')
+ ..addFlag('help',
+ abbr: 'h', negatable: false, help: 'Displays this help message.')
+ ..addOption('output',
+ abbr: 'o', valueHelp: 'path', help: 'Put the output in file <path>.')
+ ..addOption('output-kind',
+ abbr: 'k',
+ allowed: ['exe', 'aot'],
+ defaultsTo: 'exe',
+ valueHelp: 'exe|aot',
+ help: 'Generate a standalone executable or an AOT snapshot.')
+ ..addOption('packages',
+ abbr: 'p', valueHelp: 'path', help: 'Use the .packages file at <path>.')
+ ..addFlag('verbose',
+ abbr: 'v', negatable: false, help: 'Show verbose output.');
+
+ ArgResults parsedArgs;
+ try {
+ parsedArgs = parser.parse(args);
+ } on FormatException catch (e) {
+ stderr.writeln('Error: ${e.message}');
+ await stderr.flush();
+ printUsage(parser);
+ exit(1);
+ }
+
+ if (parsedArgs['help']) {
+ printUsage(parser);
+ exit(0);
+ }
+
+ if (parsedArgs.rest.length != 1) {
+ printUsage(parser);
+ exit(1);
+ }
+
+ final Kind kind = {
+ 'aot': Kind.aot,
+ 'exe': Kind.exe,
+ }[parsedArgs['output-kind']];
+
+ final sourcePath = path.canonicalize(path.normalize(parsedArgs.rest[0]));
+ final outputPath =
+ path.canonicalize(path.normalize(parsedArgs['output'] != null
+ ? parsedArgs['output']
+ : {
+ Kind.aot: '${sourcePath}.aot',
+ Kind.exe: '${sourcePath}.exe',
+ }[kind]));
+
+ if (!FileSystemEntity.isFileSync(sourcePath)) {
+ stderr.writeln(
+ '"${sourcePath}" is not a file. See \'--help\' for more information.');
+ await stderr.flush();
+ exit(1);
+ }
+
+ try {
+ await generateNative(
+ kind,
+ sourcePath,
+ outputPath,
+ parsedArgs['packages'],
+ parsedArgs['define'],
+ parsedArgs['enable-asserts'],
+ parsedArgs['verbose']);
+ } catch (e) {
+ stderr.writeln('Failed to generate native files:');
+ stderr.writeln(e);
+ await stderr.flush();
+ exit(1);
+ }
}
diff --git a/pkg/dart2native/lib/dart2native.dart b/pkg/dart2native/lib/dart2native.dart
new file mode 100644
index 0000000..754fec9
--- /dev/null
+++ b/pkg/dart2native/lib/dart2native.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2019, 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:io';
+import 'dart:typed_data';
+
+import 'package:path/path.dart' as path;
+
+const appSnapshotPageSize = 4096;
+const appjitMagicNumber = <int>[0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0];
+
+enum Kind { aot, exe }
+
+Future writeAppendedExecutable(
+ String dartaotruntimePath, String payloadPath, String outputPath) async {
+ final dartaotruntime = File(dartaotruntimePath);
+ final int dartaotruntimeLength = dartaotruntime.lengthSync();
+
+ final padding =
+ ((appSnapshotPageSize - dartaotruntimeLength) % appSnapshotPageSize);
+ final padBytes = Uint8List(padding);
+ final offset = dartaotruntimeLength + padding;
+
+ // Note: The offset is always Little Endian regardless of host.
+ final offsetBytes = new ByteData(8) // 64 bit in bytes.
+ ..setUint64(0, offset, Endian.little);
+
+ final outputFile = File(outputPath).openWrite();
+ outputFile.add(dartaotruntime.readAsBytesSync());
+ outputFile.add(padBytes);
+ outputFile.add(File(payloadPath).readAsBytesSync());
+ outputFile.add(offsetBytes.buffer.asUint8List());
+ outputFile.add(appjitMagicNumber);
+ await outputFile.close();
+}
+
+Future markExecutable(String outputFile) {
+ return Process.run('chmod', ['+x', outputFile]);
+}
+
+Future generateAotKernel(
+ String dart,
+ String genKernel,
+ String platformDill,
+ String sourceFile,
+ String kernelFile,
+ String packages,
+ List<String> defines) {
+ return Process.run(dart, [
+ genKernel,
+ '--platform',
+ platformDill,
+ '--aot',
+ '-Ddart.vm.product=true',
+ ...(defines.map((d) => '-D${d}')),
+ if (packages != null) ...['--packages', packages],
+ '-o',
+ kernelFile,
+ sourceFile
+ ]);
+}
+
+Future generateAotSnapshot(String genSnapshot, String kernelFile,
+ String snapshotFile, bool enableAsserts) {
+ return Process.run(genSnapshot, [
+ '--snapshot-kind=app-aot-blobs',
+ '--blobs_container_filename=${snapshotFile}',
+ if (enableAsserts) '--enable-asserts',
+ kernelFile
+ ]);
+}
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index e521784..4fe742b 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
@@ -198,8 +199,8 @@
this.options, this._extensionTypes, this.errors)
: rules = Dart2TypeSystem(types),
declaredVariables = driver.declaredVariables,
- _asyncStreamIterator =
- driver.getClass('dart:async', 'StreamIterator').type,
+ _asyncStreamIterator = getLegacyRawClassType(
+ driver.getClass('dart:async', 'StreamIterator')),
_coreIdentical = driver
.getLibrary('dart:core')
.publicNamespace
@@ -218,18 +219,18 @@
internalSymbolClass = driver.getClass('dart:_internal', 'Symbol'),
privateSymbolClass =
driver.getClass('dart:_js_helper', 'PrivateSymbol'),
- linkedHashMapImplType =
- driver.getClass('dart:_js_helper', 'LinkedMap').type,
- identityHashMapImplType =
- driver.getClass('dart:_js_helper', 'IdentityMap').type,
- linkedHashSetImplType =
- driver.getClass('dart:collection', '_HashSet').type,
- identityHashSetImplType =
- driver.getClass('dart:collection', '_IdentityHashSet').type,
- syncIterableType =
- driver.getClass('dart:_js_helper', 'SyncIterable').type,
- asyncStarImplType =
- driver.getClass('dart:async', '_AsyncStarImpl').type,
+ linkedHashMapImplType = getLegacyRawClassType(
+ driver.getClass('dart:_js_helper', 'LinkedMap')),
+ identityHashMapImplType = getLegacyRawClassType(
+ driver.getClass('dart:_js_helper', 'IdentityMap')),
+ linkedHashSetImplType = getLegacyRawClassType(
+ driver.getClass('dart:collection', '_HashSet')),
+ identityHashSetImplType = getLegacyRawClassType(
+ driver.getClass('dart:collection', '_IdentityHashSet')),
+ syncIterableType = getLegacyRawClassType(
+ driver.getClass('dart:_js_helper', 'SyncIterable')),
+ asyncStarImplType = getLegacyRawClassType(
+ driver.getClass('dart:async', '_AsyncStarImpl')),
dartJSLibrary = driver.getLibrary('dart:js') {
jsTypeRep = JSTypeRep(rules, driver);
}
@@ -244,10 +245,12 @@
FunctionBody get currentFunction => _currentFunction;
@override
- InterfaceType get privateSymbolType => privateSymbolClass.type;
+ InterfaceType get privateSymbolType =>
+ getLegacyRawClassType(privateSymbolClass);
@override
- InterfaceType get internalSymbolType => internalSymbolClass.type;
+ InterfaceType get internalSymbolType =>
+ getLegacyRawClassType(internalSymbolClass);
CompilationUnitElement get _currentCompilationUnit {
for (var e = _currentElement;; e = e.enclosingElement) {
@@ -1004,7 +1007,8 @@
}
if (classElem.library.isDartAsync) {
if (classElem == types.futureOrElement) {
- var typeParamT = classElem.typeParameters[0].type;
+ var typeParamT =
+ getLegacyTypeParameterType(classElem.typeParameters[0]);
var typeT = _emitType(typeParamT);
var futureOfT = _emitType(types.futureType2(typeParamT));
body.add(js.statement('''
@@ -1249,7 +1253,7 @@
}
getBaseClass(int count) {
- var base = emitDeferredType(classElem.type);
+ var base = emitDeferredType(getLegacyRawClassType(classElem));
while (--count >= 0) {
base = js.call('#.__proto__', [base]);
}
@@ -1416,7 +1420,7 @@
List<js_ast.Method> _emitClassMethods(
ClassElement classElem, List<ClassMember> memberNodes) {
- var type = classElem.type;
+ var type = getLegacyRawClassType(classElem);
var virtualFields = _classProperties.virtualFields;
var jsMethods = <js_ast.Method>[];
@@ -1838,7 +1842,7 @@
void _registerExtensionType(
ClassElement classElem, String jsPeerName, List<js_ast.Statement> body) {
var className = _emitTopLevelName(classElem);
- if (jsTypeRep.isPrimitive(classElem.type)) {
+ if (jsTypeRep.isPrimitive(getLegacyRawClassType(classElem))) {
body.add(runtimeStatement(
'definePrimitiveHashCode(#.prototype)', [className]));
}
@@ -1954,7 +1958,7 @@
Map<Element, Declaration> members, List<js_ast.Statement> body) {
if (classElem.isEnum) {
// Emit enum static fields
- var type = classElem.type;
+ var type = getLegacyRawClassType(classElem);
void addField(FieldElement e, js_ast.Expression value) {
body.add(defineValueOnClass(classElem, _emitStaticClassName(e),
_declareMemberName(e.getter), value)
@@ -2004,7 +2008,7 @@
/// Ensure `dartx.` symbols we will use are present.
void _initExtensionSymbols(ClassElement classElem) {
- if (_extensionTypes.hasNativeSubtype(classElem.type) ||
+ if (_extensionTypes.hasNativeSubtype(getLegacyRawClassType(classElem)) ||
classElem.isDartCoreObject) {
for (var members in [classElem.methods, classElem.accessors]) {
for (var m in members) {
@@ -2083,8 +2087,8 @@
var name = method.name;
var reifiedType = _getMemberRuntimeType(method);
- var memberOverride =
- classElem.type.lookUpMethodInSuperclass(name, currentLibrary);
+ var memberOverride = getLegacyRawClassType(classElem)
+ .lookUpMethodInSuperclass(name, currentLibrary);
// Don't add redundant signatures for inherited methods whose signature
// did not change. If we are not overriding, or if the thing we are
// overriding has a different reified type from ourselves, we must
@@ -2140,8 +2144,10 @@
var name = accessor.name;
var isGetter = accessor.isGetter;
var memberOverride = isGetter
- ? classElem.type.lookUpGetterInSuperclass(name, currentLibrary)
- : classElem.type.lookUpSetterInSuperclass(name, currentLibrary);
+ ? getLegacyRawClassType(classElem)
+ .lookUpGetterInSuperclass(name, currentLibrary)
+ : getLegacyRawClassType(classElem)
+ .lookUpSetterInSuperclass(name, currentLibrary);
var reifiedType = accessor.type;
// Don't add redundant signatures for inherited methods whose signature
@@ -2258,7 +2264,7 @@
var parameters = element.parameters
.map((p) => ParameterElementImpl.synthetic(
p.name,
- _isCovariant(p) ? objectClass.type : p.type,
+ _isCovariant(p) ? getLegacyRawClassType(objectClass) : p.type,
// ignore: deprecated_member_use
p.parameterKind))
.toList();
@@ -2861,8 +2867,11 @@
for (var t in typeFormals) {
t = covariantParams.lookup(t) as TypeParameterElement;
if (t != null) {
- body.add(runtimeStatement('checkTypeBound(#, #, #)',
- [_emitType(t.type), _emitType(t.bound), propertyName(t.name)]));
+ body.add(runtimeStatement('checkTypeBound(#, #, #)', [
+ _emitType(getLegacyTypeParameterType(t)),
+ _emitType(t.bound),
+ propertyName(t.name)
+ ]));
}
}
}
@@ -3096,7 +3105,7 @@
ClassMemberElement element, Element accessor, Expression node) {
bool isStatic = element.isStatic;
var classElem = element.enclosingElement as ClassElement;
- var type = classElem.type;
+ var type = getLegacyRawClassType(classElem);
var member = _emitMemberName(element.name,
isStatic: isStatic, type: type, element: accessor);
@@ -3259,7 +3268,8 @@
// If any explicit bounds were passed, emit them.
if (typeFormals.any((t) => t.bound != null)) {
var bounds = typeFormals
- .map((t) => _emitType(t.type.bound, cacheType: cacheType))
+ .map((t) => _emitType(getLegacyTypeParameterType(t).bound,
+ cacheType: cacheType))
.toList();
typeParts.add(addTypeFormalsAsParameters(bounds));
}
@@ -3586,7 +3596,9 @@
var classElem = field.enclosingElement as ClassElement;
var isStatic = field.isStatic;
var member = _emitMemberName(field.name,
- isStatic: isStatic, type: classElem.type, element: field.setter);
+ isStatic: isStatic,
+ type: getLegacyRawClassType(classElem),
+ element: field.setter);
jsTarget = isStatic
? (js_ast.PropertyAccess(_emitStaticClassName(field), member)
..sourceInformation = _nodeSpan(id))
@@ -3653,7 +3665,7 @@
if (e.name == 'getGenericClass' && firstArg is SimpleIdentifier) {
var typeElem = firstArg.staticElement;
if (typeElem is TypeDefiningElement &&
- typeElem.type is ParameterizedType) {
+ getLegacyElementType(typeElem) is ParameterizedType) {
return _emitTopLevelNameNoInterop(typeElem, suffix: '\$');
}
}
@@ -3686,7 +3698,8 @@
Expression target, Element member, bool isStatic) {
if (isStatic) {
if (member is ConstructorElement) {
- return emitConstructorAccess(member.enclosingElement.type)
+ return emitConstructorAccess(
+ getLegacyRawClassType(member.enclosingElement))
..sourceInformation = _nodeSpan(target);
}
if (member is PropertyAccessorElement) {
@@ -4533,8 +4546,11 @@
if (typeNode is NamedType && typeNode.typeArguments != null) {
var e = typeNode.name.staticElement;
if (e is ClassElement) {
- return e.type.instantiate(
- typeNode.typeArguments.arguments.map(getType).toList());
+ return e.instantiate(
+ typeArguments:
+ typeNode.typeArguments.arguments.map(getType).toList(),
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
} else if (e is FunctionTypedElement) {
return e.type.instantiate(
typeNode.typeArguments.arguments.map(getType).toList());
@@ -5652,7 +5668,9 @@
// This applies regardless in an int or double context.
var valueInJS = BigInt.from(value.toDouble());
if (value != valueInJS) {
- assert(node.staticType == intClass.type || options.unsafeForceCompile,
+ assert(
+ node.staticType == getLegacyRawClassType(intClass) ||
+ options.unsafeForceCompile,
'int literals in double contexts should be checked by Analyzer.');
var lexeme = node.literal.lexeme;
@@ -5721,7 +5739,7 @@
if (itemType.isDynamic) return list;
// Call `new JSArray<E>.of(list)`
- var arrayType = _jsArray.type.instantiate([itemType]);
+ var arrayType = getLegacyRawClassType(_jsArray).instantiate([itemType]);
return js.call('#.of(#)', [_emitType(arrayType), list]);
}
@@ -5878,7 +5896,8 @@
if (_isUiAsCodeElement(node)) {
// Create a temporary variable to build a new collection from.
var previousCollectionVariable = _currentCollectionVariable;
- var arrayType = _jsArray.type.instantiate([elementType]);
+ var arrayType =
+ getLegacyRawClassType(_jsArray).instantiate([elementType]);
var temporaryIdentifier = _createTemporary('items', arrayType);
_currentCollectionVariable = _emitSimpleIdentifier(temporaryIdentifier);
var items = js.statement('let # = #',
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index a306bfb..5723e17 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart'
show DartType, InterfaceType, FunctionType;
import 'package:analyzer/dart/element/type.dart';
@@ -15,6 +16,8 @@
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/type_system.dart' show Dart2TypeSystem;
+import 'type_utilities.dart';
+
class Tuple2<T0, T1> {
final T0 e0;
final T1 e1;
@@ -29,9 +32,12 @@
/// [instantiateElementTypeToBounds] should be used instead.
InterfaceType fillDynamicTypeArgsForClass(InterfaceType t) {
if (t.typeArguments.isNotEmpty) {
- var rawT = t.element.type;
- var dyn = List.filled(rawT.typeArguments.length, DynamicTypeImpl.instance);
- return rawT.substitute2(dyn, rawT.typeArguments);
+ var dyn =
+ List.filled(t.element.typeParameters.length, DynamicTypeImpl.instance);
+ return t.element.instantiate(
+ typeArguments: dyn,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
}
return t;
}
@@ -63,14 +69,14 @@
} else if (e is FunctionTypedElement) {
type = e.type;
} else if (e is ClassElement) {
- type = e.type;
+ type = getLegacyRawClassType(e);
}
var bounds = rules.instantiateTypeFormalsToBounds(e.typeParameters);
if (bounds == null) return type;
return type.substitute2(
bounds, TypeParameterTypeImpl.getTypes(e.typeParameters));
}
- return element.type;
+ return getLegacyElementType(element);
}
/// Given an [element] and a [test] function, returns the first matching
@@ -253,7 +259,8 @@
// * `dynamic d; d();` without a declared `call` method is handled by dcall.
// * for `class C implements Callable { noSuchMethod(i) { ... } }` we find
// the `call` method on the `Callable` interface.
- var callMethod = c.type.lookUpInheritedGetterOrMethod('call');
+ var callMethod =
+ getLegacyRawClassType(c).lookUpInheritedGetterOrMethod('call');
return callMethod is PropertyAccessorElement
? callMethod.returnType is FunctionType
: callMethod != null;
diff --git a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
index 833a968..0175913 100644
--- a/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/extension_types.dart
@@ -10,7 +10,9 @@
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
+
import 'element_helpers.dart' show getAnnotationName, isBuiltinAnnotation;
+import 'type_utilities.dart';
/// Contains information about native JS types (those types provided by the
/// implementation) that are also provided by the Dart SDK.
@@ -79,7 +81,7 @@
void _visitClass(ClassElement element) {
if (_isNative(element)) {
- _addExtensionType(element.type, true);
+ _addExtensionType(getLegacyRawClassType(element), true);
}
}
@@ -114,7 +116,7 @@
void _addExtensionTypesForLibrary(String libraryUri, List<String> typeNames) {
var library = _getLibraryByUri(libraryUri);
for (var typeName in typeNames) {
- _addExtensionType(library.getType(typeName).type);
+ _addExtensionType(getLegacyRawClassType(library.getType(typeName)));
}
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/js_typerep.dart b/pkg/dev_compiler/lib/src/analyzer/js_typerep.dart
index 851d47b..c24e5f5 100644
--- a/pkg/dev_compiler/lib/src/analyzer/js_typerep.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/js_typerep.dart
@@ -2,12 +2,14 @@
// 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 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/element.dart' show ClassElement;
+import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/type_system.dart' show Dart2TypeSystem;
+
import '../compiler/js_typerep.dart';
import 'driver.dart';
+import 'type_utilities.dart';
class JSTypeRep extends SharedJSTypeRep<DartType> {
final Dart2TypeSystem rules;
@@ -54,9 +56,9 @@
InterfaceType getImplementationType(DartType t) {
var rep = typeFor(t);
// Number, String, and Bool are final
- if (rep == JSType.jsNumber) return _jsNumber.type;
- if (rep == JSType.jsBoolean) return _jsBool.type;
- if (rep == JSType.jsString) return _jsString.type;
+ if (rep == JSType.jsNumber) return getLegacyRawClassType(_jsNumber);
+ if (rep == JSType.jsBoolean) return getLegacyRawClassType(_jsBool);
+ if (rep == JSType.jsString) return getLegacyRawClassType(_jsString);
return null;
}
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
index 4aa976d..40f5f7c 100644
--- a/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/nullable_type_inference.dart
@@ -14,6 +14,7 @@
import 'js_interop.dart' show isNotNullAnnotation, isNullCheckAnnotation;
import 'js_typerep.dart';
import 'property_model.dart';
+import 'type_utilities.dart';
/// An inference engine for nullable types.
///
@@ -86,7 +87,7 @@
if (e is MethodElement) {
Element container = e.enclosingElement;
if (container is ClassElement) {
- DartType targetType = container.type;
+ DartType targetType = getLegacyRawClassType(container);
InterfaceType implType = jsTypeRep.getImplementationType(targetType);
if (implType != null) {
MethodElement method = implType.lookUpMethod(e.name, coreLibrary);
@@ -110,7 +111,7 @@
// type.
Element container = element.enclosingElement;
if (container is ClassElement) {
- var targetType = container.type;
+ var targetType = getLegacyRawClassType(container);
var implType = jsTypeRep.getImplementationType(targetType);
if (implType != null) {
var getter = implType.lookUpGetter(name, coreLibrary);
diff --git a/pkg/dev_compiler/lib/src/analyzer/property_model.dart b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
index 227afa7..74d3484 100644
--- a/pkg/dev_compiler/lib/src/analyzer/property_model.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
@@ -11,6 +11,7 @@
import '../compiler/js_names.dart' as js_ast;
import 'element_helpers.dart';
import 'extension_types.dart';
+import 'type_utilities.dart';
/// Dart allows all fields to be overridden.
///
@@ -220,7 +221,7 @@
}
}
- _collectMockMembers(classElem.type);
+ _collectMockMembers(getLegacyRawClassType(classElem));
_collectExtensionMembers(classElem);
var virtualAccessorNames = HashSet<String>()
@@ -311,12 +312,13 @@
// this class. This will help us identify which parameters need checks
// for soundness.
var allNatives = HashSet<String>();
- _collectNativeMembers(element.type, allNatives);
+ _collectNativeMembers(getLegacyRawClassType(element), allNatives);
if (allNatives.isEmpty) return;
// For members on this class, check them against all generic interfaces.
var seenConcreteMembers = HashSet<String>();
- _findExtensionMembers(element.type, seenConcreteMembers, allNatives);
+ _findExtensionMembers(
+ getLegacyRawClassType(element), seenConcreteMembers, allNatives);
// Add mock members. These are compiler-generated concrete members that
// forward to `noSuchMethod`.
for (var m in mockMembers.values) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
index 789197d..3b24cf0 100644
--- a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
@@ -5,14 +5,50 @@
import 'dart:collection';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
import '../analyzer/element_helpers.dart';
import '../compiler/js_names.dart' as js_ast;
import '../js_ast/js_ast.dart' as js_ast;
import '../js_ast/js_ast.dart' show js;
+/// Return the [InterfaceType] that itself has the legacy nullability, and for
+/// every type parameter a [TypeParameterType] instance with the legacy
+/// nullability is used as the corresponding type argument.
+InterfaceType getLegacyRawClassType(ClassElement element) {
+ var typeParameters = element.typeParameters;
+ var typeArguments = typeParameters.map(getLegacyTypeParameterType).toList();
+ return element.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: NullabilitySuffix.star,
+ );
+}
+
+/// Return the [TypeParameterType] with the legacy nullability for the given
+/// type parameter [element].
+TypeParameterType getLegacyTypeParameterType(TypeParameterElement element) {
+ return element.instantiate(nullabilitySuffix: NullabilitySuffix.star);
+}
+
+/// Return the raw type (i.e. the type where type parameters are replaced with
+/// the corresponding [TypeParameterType]) for the given [element]. The type
+/// returned, and every [TypeParameterType] instance will have the legacy
+/// nullability suffix.
+DartType getLegacyElementType(TypeDefiningElement element) {
+ if (element is ClassElement) {
+ return getLegacyRawClassType(element);
+ } else if (element is DynamicElementImpl) {
+ return element.type;
+ } else if (element is TypeParameterElement) {
+ return getLegacyTypeParameterType(element);
+ } else {
+ throw StateError('Unsupported element: (${element.runtimeType}) $element');
+ }
+}
+
Set<TypeParameterElement> freeTypeParameters(DartType t) {
var result = Set<TypeParameterElement>();
void find(DartType t) {
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 01d77e4..645dd90 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -263,7 +263,8 @@
return privateNames.putIfAbsent(name, initPrivateNameSymbol);
}
- /// Emits a private name JS Symbol for [name] unique to a Dart class [cls].
+ /// Emits a private name JS Symbol for [memberName] unique to a Dart
+ /// class [className].
///
/// This is now required for fields of constant objects that may be
/// overridden within the same library.
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index 4f1d80b..7b9408a 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -2,8 +2,9 @@
// 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:core' hide MapEntry;
import 'dart:collection';
+import 'dart:core' hide MapEntry;
+
import 'package:analyzer/dart/element/element.dart' as a;
import 'package:analyzer/dart/element/type.dart' as a;
import 'package:analyzer/file_system/physical_file_system.dart' as a;
@@ -13,18 +14,19 @@
import 'package:analyzer/src/dart/element/type.dart' as a;
import 'package:analyzer/src/generated/constant.dart' as a;
import 'package:analyzer/src/generated/engine.dart' as a;
+import 'package:analyzer/src/generated/resolver.dart' as a
+ show NamespaceBuilder, TypeProvider;
import 'package:analyzer/src/generated/source.dart' as a;
import 'package:analyzer/src/generated/type_system.dart' as a;
import 'package:analyzer/src/summary/idl.dart' as a;
import 'package:analyzer/src/summary/package_bundle_reader.dart' as a;
import 'package:analyzer/src/summary/summary_sdk.dart' as a;
-import 'package:analyzer/src/generated/resolver.dart' as a
- show NamespaceBuilder, TypeProvider;
import 'package:front_end/src/api_unstable/ddc.dart'
show RedirectingFactoryBody;
import 'package:kernel/kernel.dart';
import 'package:kernel/type_algebra.dart';
+import '../analyzer/type_utilities.dart' hide freeTypeParameters;
import 'type_table.dart';
/// Converts an Analyzer summary file to a Kernel [Component].
@@ -471,7 +473,8 @@
if (typeParams.isNotEmpty) {
// Skip past the type formals, we'll add them back below, so these
// type parameter names will end up in scope in the generated JS.
- type = type.instantiate(typeParams.map((f) => f.type).toList());
+ type = type.instantiate(
+ typeParams.map((f) => getLegacyTypeParameterType(f)).toList());
}
}
t.typeParameters.addAll(typeParams.map(visitTypeParameterElement));
@@ -732,7 +735,8 @@
}
bool _isGenericCovariant(a.ClassElement c, a.DartType type) {
- var classUpperBound = rules.instantiateToBounds(c.type) as a.InterfaceType;
+ var classUpperBound =
+ rules.instantiateToBounds(getLegacyRawClassType(c)) as a.InterfaceType;
var typeUpperBound = type.substitute2(classUpperBound.typeArguments,
a.TypeParameterTypeImpl.getTypes(classUpperBound.typeParameters));
// Is it safe to assign the upper bound of the field/parameter to it?
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 396b0ae..2539d4a 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1194,7 +1194,6 @@
js_ast.Expression className, List<js_ast.Statement> body) {
void emitExtensions(String helperName, Iterable<String> extensions) {
if (extensions.isEmpty) return;
-
var names = extensions
.map((e) => propertyName(js_ast.memberNameForDartMember(e)))
.toList();
@@ -2267,8 +2266,7 @@
}
useExtension ??= _isSymbolizedMember(memberClass, name);
- name = js_ast.memberNameForDartMember(
- name, member is Procedure && member.isExternal);
+ name = js_ast.memberNameForDartMember(name, _isExternal(member));
if (useExtension) {
return getExtensionSymbolInternal(name);
}
@@ -2292,7 +2290,7 @@
// Fields on a native class are implicitly native.
// Methods/getters/setters are marked external/native.
- if (member is Field || member is Procedure && member.isExternal) {
+ if (member is Field || _isExternal(member)) {
var jsName = _annotationName(member, isJSName);
return jsName != null && jsName != name;
} else {
@@ -2384,6 +2382,46 @@
return propertyName(name + suffix);
}
+ bool _isExternal(Member m) {
+ // Corresponds to the names in memberNameForDartMember in
+ // compiler/js_names.dart.
+ const renamedJsMembers = ["prototype", "constructor"];
+ if (m is Procedure) {
+ if (m.isExternal) return true;
+ if (m.isNoSuchMethodForwarder) {
+ if (renamedJsMembers.contains(m.name.name)) {
+ return _hasExternalProcedure(m.enclosingClass, m.name.name);
+ }
+ }
+ }
+ return false;
+ }
+
+ /// Returns true if anything up the class hierarchy externally defines a
+ /// procedure with name = [name].
+ ///
+ /// Used to determine when we should alias Dart-JS reserved members
+ /// (e.g., 'prototype' and 'constructor').
+ bool _hasExternalProcedure(Class c, String name) {
+ var classes = Queue<Class>()..add(c);
+
+ while (classes.isNotEmpty) {
+ var c = classes.removeFirst();
+ var classesToCheck = [
+ if (c.supertype != null) c.supertype.classNode,
+ for (var t in c.implementedTypes) if (t.classNode != null) t.classNode,
+ ];
+ classes.addAll(classesToCheck);
+ for (var procedure in c.procedures) {
+ if (procedure.name.name == name && !procedure.isNoSuchMethodForwarder) {
+ return procedure.isExternal;
+ }
+ }
+ }
+
+ return false;
+ }
+
String _getJSNameWithoutGlobal(NamedNode n) {
if (!usesJSInterop(n)) return null;
var libraryJSName = _annotationName(getLibrary(n), isPublicJSAnnotation);
@@ -2651,7 +2689,8 @@
/// Kernel represents `<T>` as `<T extends Object = dynamic>`. We can find
/// explicit bounds by looking for anything *except* that.
typeParameterHasExplicitBound(TypeParameter t) =>
- t.bound != _types.objectType || t.defaultType != const DynamicType();
+ t.bound != _types.coreTypes.objectLegacyRawType ||
+ t.defaultType != const DynamicType();
// If any explicit bounds were passed, emit them.
if (typeFormals.any(typeParameterHasExplicitBound)) {
@@ -3147,7 +3186,7 @@
}
if (node is AsExpression && node.isTypeError) {
- assert(node.getStaticType(_types) == _types.boolType);
+ assert(node.getStaticType(_types) == _types.coreTypes.boolLegacyRawType);
return runtimeCall('dtest(#)', [_visitExpression(node.operand)]);
}
@@ -4317,7 +4356,7 @@
var rightType = right.getStaticType(_types);
if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
- leftType == _types.stringType && op == '+') {
+ leftType == _types.coreTypes.stringLegacyRawType && op == '+') {
// Inline operations on primitive types where possible.
// TODO(jmesserly): inline these from dart:core instead of hardcoding
// the implementation details here.
@@ -4629,7 +4668,7 @@
// A static native element should just forward directly to the JS type's
// member, for example `Css.supports(...)` in dart:html should be replaced
// by a direct call to the DOM API: `global.CSS.supports`.
- if (target is Procedure && target.isStatic && target.isExternal) {
+ if (_isExternal(target) && (target as Procedure).isStatic) {
var nativeName = _extensionTypes.getNativePeers(c);
if (nativeName.isNotEmpty) {
var memberName = _annotationName(target, isJSName) ??
@@ -4894,6 +4933,11 @@
}
@override
+ js_ast.Expression visitNullCheck(NullCheck node) {
+ throw UnimplementedError('Unimplemented null check expression: $node');
+ }
+
+ @override
js_ast.Expression visitLogicalExpression(LogicalExpression node) {
// The operands of logical boolean operators are subject to boolean
// conversion.
@@ -4918,9 +4962,11 @@
if (jsExpr is js_ast.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
continue;
}
- parts.add(e.getStaticType(_types) == _types.stringType && !isNullable(e)
- ? jsExpr
- : runtimeCall('str(#)', [jsExpr]));
+ parts.add(
+ e.getStaticType(_types) == _types.coreTypes.stringLegacyRawType &&
+ !isNullable(e)
+ ? jsExpr
+ : runtimeCall('str(#)', [jsExpr]));
}
if (parts.isEmpty) return js.string('');
return js_ast.Expression.binary(parts, '+');
@@ -4966,7 +5012,7 @@
var lhs = _visitExpression(operand);
var typeofName = _typeRep.typeFor(type).primitiveTypeOf;
// Inline primitives other than int (which requires a Math.floor check).
- if (typeofName != null && type != _types.intType) {
+ if (typeofName != null && type != _types.coreTypes.intLegacyRawType) {
return js.call('typeof # == #', [lhs, js.string(typeofName, "'")]);
} else {
return js.call('#.is(#)', [_emitType(type), lhs]);
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index f1ced92..fe3e379 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -147,11 +147,6 @@
// Enums are not extensible.
return false;
}
- var libraryUri = class_.enclosingLibrary.importUri;
- if (libraryUri.scheme == 'dart' && libraryUri.path.startsWith('_')) {
- // There should be no extensible fields in private SDK libraries.
- return false;
- }
if (!field.name.isPrivate) {
// Public fields in public classes (or extensible private classes)
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
index 3d75a07..f537492 100644
--- a/pkg/dev_compiler/test/modular_ddc_suite.dart
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -19,6 +19,7 @@
String _test_package = 'ddc_modular_test';
Uri sdkRoot = Platform.script.resolve("../../../");
+bool _nnbd = false;
Options _options;
String _dartdevcScript;
String _buildSdkScript;
@@ -68,8 +69,8 @@
ProcessResult result;
- bool nnbd = flags.contains('non-nullable');
- bool allowErrors = nnbd && _nnbdOptOut.contains(module.name);
+ _nnbd = flags.contains('non-nullable');
+ bool allowErrors = _nnbd && _nnbdOptOut.contains(module.name);
if (module.isSdk) {
assert(transitiveDependencies.isEmpty);
@@ -82,7 +83,7 @@
sdkRoot.toFilePath(),
_sdkDevRuntime,
'patched_sdk',
- if (nnbd) 'sdk_nnbd'
+ if (_nnbd) 'sdk_nnbd'
],
root.toFilePath());
_checkExitCode(result, this, module);
@@ -309,5 +310,8 @@
'pkg/dev_compiler/bin/dartdevc.dart', 'snapshots/dartdevc.dart.snapshot');
_buildSdkScript = await resolve('pkg/dev_compiler/tool/build_sdk.dart');
_patchSdkScript = await resolve('pkg/dev_compiler/tool/patch_sdk.dart');
- _sdkDevRuntime = await resolve('sdk/lib/_internal/js_dev_runtime');
+ _sdkDevRuntime = await resolve(_nnbd
+ ? 'sdk_nnbd'
+ : 'sdk'
+ '/lib/_internal/js_dev_runtime');
}
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 2a73fd9..9b07711 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -62,7 +62,13 @@
..addOption('mode',
help: 'Option to (compile|run|all). Default is all (compile and run).',
allowed: ['compile', 'run', 'all'],
- defaultsTo: 'all');
+ defaultsTo: 'all')
+ ..addOption('compile-vm-options',
+ help: 'DART_VM_OPTIONS for the compilation VM.')
+ ..addOption('packages',
+ help: 'Where to find a package spec file.')
+ ..addOption('out',
+ help: 'Output file.');
var options = parser.parse(args);
if (options['help'] as bool) {
@@ -90,6 +96,7 @@
var run = mode == 'run' || mode == 'all';
var entry = p.canonicalize(options.rest.first);
+ var out = (options['out'] as String) ?? p.setExtension(entry, '.js');
var libRoot = p.dirname(entry);
var basename = p.basenameWithoutExtension(entry);
var libname = kernel
@@ -135,8 +142,12 @@
// Use built snapshot.
command = p.join(dartSdk, 'bin', command);
}
- var process =
- await Process.start(command, args, mode: ProcessStartMode.inheritStdio);
+ var process = await Process.start(command, args,
+ mode: ProcessStartMode.inheritStdio,
+ environment: <String, String>{
+ if (options['compile-vm-options'] != null)
+ 'DART_VM_OPTIONS': options['compile-vm-options']
+ });
if (await process.exitCode != 0) exit(await process.exitCode);
}
@@ -185,8 +196,9 @@
'--library-root=$libRoot',
for (var summary in summaries) '--summary=$summary',
for (var experiment in experiments) '--enable-experiment=$experiment',
+ if (options['packages'] != null) '--packages=${options['packages']}',
'-o',
- p.setExtension(entry, '.js'),
+ out,
entry
];
@@ -226,7 +238,7 @@
});
</script>
''';
- var htmlFile = p.setExtension(entry, '.html');
+ var htmlFile = p.setExtension(out, '.html');
File(htmlFile).writeAsStringSync(html);
var tmp = p.join(Directory.systemTemp.path, 'ddc');
@@ -262,7 +274,7 @@
process.exit(1);
}
''';
- var nodeFile = p.setExtension(entry, '.run.js');
+ var nodeFile = p.setExtension(out, '.run.js');
File(nodeFile).writeAsStringSync(runjs);
var nodeBinary = binary ?? 'node';
var process = await Process.start(
@@ -274,7 +286,7 @@
// Fix SDK import. `d8` doesn't let us set paths, so we need a full path
// to the SDK.
- var jsFile = File(p.setExtension(entry, '.js'));
+ var jsFile = File(out);
var jsContents = jsFile.readAsStringSync();
jsContents = jsContents.replaceFirst(
"from 'dart_sdk.js'", "from '$sdkJsPath/dart_sdk.js'");
@@ -291,7 +303,7 @@
console.error(e);
}
''';
- var d8File = p.setExtension(entry, '.d8.js');
+ var d8File = p.setExtension(out, '.d8.js');
File(d8File).writeAsStringSync(runjs);
var d8Binary = binary ?? p.join(dartCheckoutPath, _d8executable);
var process = await Process.start(d8Binary, ['--module', d8File],
diff --git a/pkg/dev_compiler/web/source_map_stack_trace.dart b/pkg/dev_compiler/web/source_map_stack_trace.dart
index 9dce84a..57a4016 100644
--- a/pkg/dev_compiler/web/source_map_stack_trace.dart
+++ b/pkg/dev_compiler/web/source_map_stack_trace.dart
@@ -58,7 +58,7 @@
if (!sourceUrl.startsWith('dart:') &&
!sourceUrl.startsWith('package:') &&
- sourceUrl.contains('dart_sdk.js')) {
+ sourceUrl.contains('dart_sdk')) {
// This compresses the long dart_sdk URLs if SDK source maps are missing.
// It's no longer linkable, but neither are the properly mapped ones
// above.
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 68939cd..6c6b5a4 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -77,6 +77,9 @@
WorkerInputComponent cachedSdkInput;
Map<Uri, WorkerInputComponent> workerInputCache =
oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+ Map<Uri, Uri> workerInputCacheLibs =
+ oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
+
bool startOver = false;
Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
parseExperimentalArguments(experiments),
@@ -92,6 +95,7 @@
// We'll load a new sdk, anything loaded already will have a wrong root.
workerInputCache.clear();
+ workerInputCacheLibs.clear();
} else {
// We do have a previous state.
cachedSdkInput = workerInputCache[sdkSummary];
@@ -101,6 +105,7 @@
startOver = true;
// We'll load a new sdk, anything loaded already will have a wrong root.
workerInputCache.clear();
+ workerInputCacheLibs.clear();
}
}
@@ -120,6 +125,12 @@
cachedSdkInput = new WorkerInputComponent(
sdkDigest, await processedOpts.loadSdkSummary(null));
workerInputCache[sdkSummary] = cachedSdkInput;
+ for (Library lib in cachedSdkInput.component.libraries) {
+ if (workerInputCacheLibs.containsKey(lib.importUri)) {
+ throw new StateError("Duplicate sources in sdk.");
+ }
+ workerInputCacheLibs[lib.importUri] = sdkSummary;
+ }
incrementalCompiler = new IncrementalCompiler.fromComponent(
new CompilerContext(processedOpts),
@@ -166,7 +177,9 @@
libraryToInputDill = new Map<Uri, Uri>();
}
List<Uri> loadFromDill = new List<Uri>();
+ Set<Uri> inputSummariesSet = new Set<Uri>();
for (Uri summary in summaryInputs) {
+ inputSummariesSet.add(summary);
WorkerInputComponent cachedInput = workerInputCache[summary];
List<int> summaryDigest = workerInputDigests[summary];
if (summaryDigest == null) {
@@ -175,6 +188,14 @@
if (cachedInput == null ||
cachedInput.component.root != nameRoot ||
!digestsEqual(cachedInput.digest, summaryDigest)) {
+ // Remove any old libraries from workerInputCacheLibs.
+ Component component = cachedInput?.component;
+ if (component != null) {
+ for (Library lib in component.libraries) {
+ workerInputCacheLibs.remove(lib.importUri);
+ }
+ }
+
loadFromDill.add(summary);
} else {
// Need to reset cached components so they are usable again.
@@ -202,8 +223,24 @@
alwaysCreateNewNamedNodes: true));
workerInputCache[summary] = cachedInput;
inputSummaries.add(cachedInput.component);
- if (trackNeededDillLibraries) {
- for (Library lib in cachedInput.component.libraries) {
+ for (Library lib in cachedInput.component.libraries) {
+ if (workerInputCacheLibs.containsKey(lib.importUri)) {
+ Uri fromSummary = workerInputCacheLibs[lib.importUri];
+ if (inputSummariesSet.contains(fromSummary)) {
+ throw new StateError(
+ "Asked to load several summaries that contain the same library.");
+ } else {
+ // Library contained in old cached component. Flush that cache.
+ Component component = workerInputCache.remove(fromSummary).component;
+ for (Library lib in component.libraries) {
+ workerInputCacheLibs.remove(lib.importUri);
+ }
+ }
+ } else {
+ workerInputCacheLibs[lib.importUri] = summary;
+ }
+
+ if (trackNeededDillLibraries) {
libraryToInputDill[lib.importUri] = summary;
}
}
@@ -213,6 +250,7 @@
return new InitializedCompilerState(options, processedOpts,
workerInputCache: workerInputCache,
+ workerInputCacheLibs: workerInputCacheLibs,
incrementalCompiler: incrementalCompiler,
tags: tags,
libraryToInputDill: libraryToInputDill);
diff --git a/pkg/front_end/lib/src/api_unstable/compiler_state.dart b/pkg/front_end/lib/src/api_unstable/compiler_state.dart
index 0852c60..06998b7 100644
--- a/pkg/front_end/lib/src/api_unstable/compiler_state.dart
+++ b/pkg/front_end/lib/src/api_unstable/compiler_state.dart
@@ -15,12 +15,17 @@
final CompilerOptions options;
final ProcessedOptions processedOpts;
final Map<Uri, WorkerInputComponent> workerInputCache;
+
+ /// A map from library import uri to dill uri, i.e. where a library came from,
+ /// for all cached libraries.
+ final Map<Uri, Uri> workerInputCacheLibs;
final IncrementalCompiler incrementalCompiler;
final Set<String> tags;
final Map<Uri, Uri> libraryToInputDill;
InitializedCompilerState(this.options, this.processedOpts,
{this.workerInputCache,
+ this.workerInputCacheLibs,
this.incrementalCompiler,
this.tags,
this.libraryToInputDill});
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 585c738..8885e67 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -157,6 +157,9 @@
Map<Uri, WorkerInputComponent> workerInputCache =
oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+ Map<Uri, Uri> workerInputCacheLibs =
+ oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
+
final List<int> sdkDigest = workerInputDigests[sdkSummary];
if (sdkDigest == null) {
throw new StateError("Expected to get sdk digest at $sdkSummary");
@@ -187,12 +190,20 @@
// We'll load a new sdk, anything loaded already will have a wrong root.
workerInputCache.clear();
+ workerInputCacheLibs.clear();
processedOpts = new ProcessedOptions(options: options);
cachedSdkInput = new WorkerInputComponent(
sdkDigest, await processedOpts.loadSdkSummary(null));
workerInputCache[sdkSummary] = cachedSdkInput;
+ for (Library lib in cachedSdkInput.component.libraries) {
+ if (workerInputCacheLibs.containsKey(lib.importUri)) {
+ throw new StateError("Duplicate sources in sdk.");
+ }
+ workerInputCacheLibs[lib.importUri] = sdkSummary;
+ }
+
incrementalCompiler = new IncrementalCompiler.fromComponent(
new CompilerContext(processedOpts), cachedSdkInput.component);
incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
@@ -234,8 +245,10 @@
if (doneInputSummaries.length != inputSummaries.length) {
throw new ArgumentError("Invalid length.");
}
+ Set<Uri> inputSummariesSet = new Set<Uri>();
for (int i = 0; i < inputSummaries.length; i++) {
Uri inputSummary = inputSummaries[i];
+ inputSummariesSet.add(inputSummary);
WorkerInputComponent cachedInput = workerInputCache[inputSummary];
List<int> digest = workerInputDigests[inputSummary];
if (digest == null) {
@@ -244,6 +257,14 @@
if (cachedInput == null ||
cachedInput.component.root != nameRoot ||
!digestsEqual(digest, cachedInput.digest)) {
+ // Remove any old libraries from workerInputCacheLibs.
+ Component component = cachedInput?.component;
+ if (component != null) {
+ for (Library lib in component.libraries) {
+ workerInputCacheLibs.remove(lib.importUri);
+ }
+ }
+
loadFromDillIndexes.add(i);
} else {
// Need to reset cached components so they are usable again.
@@ -273,8 +294,24 @@
.loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
workerInputCache[summary] = cachedInput;
doneInputSummaries[index] = cachedInput.component;
- if (trackNeededDillLibraries) {
- for (Library lib in cachedInput.component.libraries) {
+ for (Library lib in cachedInput.component.libraries) {
+ if (workerInputCacheLibs.containsKey(lib.importUri)) {
+ Uri fromSummary = workerInputCacheLibs[lib.importUri];
+ if (inputSummariesSet.contains(fromSummary)) {
+ throw new StateError(
+ "Asked to load several summaries that contain the same library.");
+ } else {
+ // Library contained in old cached component. Flush that cache.
+ Component component = workerInputCache.remove(fromSummary).component;
+ for (Library lib in component.libraries) {
+ workerInputCacheLibs.remove(lib.importUri);
+ }
+ }
+ } else {
+ workerInputCacheLibs[lib.importUri] = summary;
+ }
+
+ if (trackNeededDillLibraries) {
libraryToInputDill[lib.importUri] = summary;
}
}
@@ -284,6 +321,7 @@
return new InitializedCompilerState(options, processedOpts,
workerInputCache: workerInputCache,
+ workerInputCacheLibs: workerInputCacheLibs,
incrementalCompiler: incrementalCompiler,
tags: tags,
libraryToInputDill: libraryToInputDill);
diff --git a/pkg/front_end/lib/src/fasta/builder/builtin_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/builtin_type_builder.dart
index a673664..b3ff558 100644
--- a/pkg/front_end/lib/src/fasta/builder/builtin_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builtin_type_builder.dart
@@ -6,7 +6,12 @@
import 'package:kernel/ast.dart' show DartType, Nullability;
-import 'builder.dart' show LibraryBuilder, TypeBuilder, TypeDeclarationBuilder;
+import 'builder.dart'
+ show
+ LibraryBuilder,
+ NullabilityBuilder,
+ TypeBuilder,
+ TypeDeclarationBuilder;
abstract class BuiltinTypeBuilder extends TypeDeclarationBuilder {
final DartType type;
@@ -15,9 +20,9 @@
String name, this.type, LibraryBuilder compilationUnit, int charOffset)
: super(null, 0, name, compilationUnit, charOffset);
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
- // TODO(dmitryas): Use [nullability].
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
+ // TODO(dmitryas): Use [nullabilityBuilder].
return type;
}
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 1687f79..c4a1632 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -62,6 +62,7 @@
LibraryBuilder,
MemberBuilder,
MetadataBuilder,
+ NullabilityBuilder,
Scope,
ScopeBuilder,
TypeBuilder,
@@ -86,15 +87,15 @@
templateGenericFunctionTypeInferredAsActualTypeArgument,
templateImplementsRepeated,
templateImplementsSuperClass,
- templateImplicitMixinOverrideContext,
+ templateImplicitMixinOverride,
templateIncompatibleRedirecteeFunctionType,
templateIncorrectTypeArgument,
templateIncorrectTypeArgumentInSupertype,
templateIncorrectTypeArgumentInSupertypeInferred,
- templateInterfaceCheckContext,
+ templateInterfaceCheck,
templateInternalProblemNotFoundIn,
templateMixinApplicationIncompatibleSupertype,
- templateNamedMixinOverrideContext,
+ templateNamedMixinOverride,
templateOverriddenMethodCause,
templateOverrideFewerNamedArguments,
templateOverrideFewerPositionalArguments,
@@ -500,10 +501,12 @@
}
/// If [arguments] are null, the default types for the variables are used.
- InterfaceType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
+ InterfaceType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
return buildTypesWithBuiltArguments(
- library, nullability, buildTypeArguments(library, arguments));
+ library,
+ nullabilityBuilder.build(library),
+ buildTypeArguments(library, arguments));
}
Supertype buildSupertype(
@@ -1067,7 +1070,9 @@
}
if (declaredFunction?.typeParameters?.length !=
interfaceFunction?.typeParameters?.length) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideTypeVariablesMismatch.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1075,14 +1080,12 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
} else if (declaredFunction?.typeParameters != null) {
Map<TypeParameter, DartType> substitutionMap =
<TypeParameter, DartType>{};
@@ -1103,7 +1106,9 @@
interfaceSubstitution.substituteType(interfaceBound);
}
if (declaredBound != substitution.substituteType(interfaceBound)) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideTypeVariablesMismatch.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1111,14 +1116,12 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
}
}
}
@@ -1203,14 +1206,14 @@
interfaceMemberName);
fileOffset = declaredParameter.fileOffset;
}
- library.addProblem(message, fileOffset, noLength, declaredMember.fileUri,
+ reportInvalidOverride(
+ isInterfaceCheck, declaredMember, message, fileOffset, noLength,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
}
}
@@ -1248,7 +1251,9 @@
isInterfaceCheck);
if (declaredFunction.positionalParameters.length <
interfaceFunction.positionalParameters.length) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideFewerPositionalArguments.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1256,18 +1261,18 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
}
if (interfaceFunction.requiredParameterCount <
declaredFunction.requiredParameterCount) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideMoreRequiredArguments.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1275,14 +1280,12 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
}
for (int i = 0;
i < declaredFunction.positionalParameters.length &&
@@ -1311,7 +1314,9 @@
}
if (declaredFunction.namedParameters.length <
interfaceFunction.namedParameters.length) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideFewerNamedArguments.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1319,14 +1324,12 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
}
int compareNamedParameters(VariableDeclaration p0, VariableDeclaration p1) {
return p0.name.compareTo(p1.name);
@@ -1348,7 +1351,9 @@
while (declaredNamedParameters.current.name !=
interfaceNamedParameters.current.name) {
if (!declaredNamedParameters.moveNext()) {
- library.addProblem(
+ reportInvalidOverride(
+ isInterfaceCheck,
+ declaredMember,
templateOverrideMismatchNamedParameter.withArguments(
"${declaredMember.enclosingClass.name}."
"${declaredMember.name.name}",
@@ -1357,14 +1362,12 @@
"${interfaceMember.name.name}"),
declaredMember.fileOffset,
noLength,
- declaredMember.fileUri,
context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(interfaceMember.fileUri,
- interfaceMember.fileOffset, noLength)
- ] +
- inheritedContext(isInterfaceCheck, declaredMember));
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, noLength)
+ ]);
break outer;
}
}
@@ -1440,38 +1443,52 @@
return isCovariant;
}
- // Extra context on override messages when the overriding member is inherited
- List<LocatedMessage> inheritedContext(
- bool isInterfaceCheck, Member declaredMember) {
+ // When the overriding member is inherited, report the class containing
+ // the conflict as the main error.
+ void reportInvalidOverride(bool isInterfaceCheck, Member declaredMember,
+ Message message, int fileOffset, int length,
+ {List<LocatedMessage> context}) {
if (declaredMember.enclosingClass == cls) {
// Ordinary override
- return const [];
- }
- if (isInterfaceCheck) {
- // Interface check
- return [
- templateInterfaceCheckContext
- .withArguments(cls.name)
- .withLocation(cls.fileUri, cls.fileOffset, cls.name.length)
- ];
+ library.addProblem(message, fileOffset, length, declaredMember.fileUri,
+ context: context);
} else {
- if (cls.isAnonymousMixin) {
- // Implicit mixin application class
- String baseName = cls.superclass.demangledName;
- String mixinName = cls.mixedInClass.name;
- int classNameLength = cls.nameAsMixinApplicationSubclass.length;
- return [
- templateImplicitMixinOverrideContext
- .withArguments(mixinName, baseName)
- .withLocation(cls.fileUri, cls.fileOffset, classNameLength)
- ];
+ context = [
+ message.withLocation(declaredMember.fileUri, fileOffset, length),
+ ...?context
+ ];
+ if (isInterfaceCheck) {
+ // Interface check
+ library.addProblem(
+ templateInterfaceCheck.withArguments(
+ declaredMember.name.name, cls.name),
+ cls.fileOffset,
+ cls.name.length,
+ cls.fileUri,
+ context: context);
} else {
- // Named mixin application class
- return [
- templateNamedMixinOverrideContext
- .withArguments(cls.name)
- .withLocation(cls.fileUri, cls.fileOffset, cls.name.length)
- ];
+ if (cls.isAnonymousMixin) {
+ // Implicit mixin application class
+ String baseName = cls.superclass.demangledName;
+ String mixinName = cls.mixedInClass.name;
+ int classNameLength = cls.nameAsMixinApplicationSubclass.length;
+ library.addProblem(
+ templateImplicitMixinOverride.withArguments(
+ mixinName, baseName, declaredMember.name.name),
+ cls.fileOffset,
+ classNameLength,
+ cls.fileUri,
+ context: context);
+ } else {
+ // Named mixin application class
+ library.addProblem(
+ templateNamedMixinOverride.withArguments(
+ cls.name, declaredMember.name.name),
+ cls.fileOffset,
+ cls.name.length,
+ cls.fileUri,
+ context: context);
+ }
}
}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
index df6cd20..ef242db 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
@@ -19,7 +19,6 @@
IntLiteral,
InterfaceType,
ListLiteral,
- Nullability,
ProcedureKind,
ReturnStatement,
StaticGet,
@@ -263,9 +262,9 @@
TypeBuilder get mixedInType => null;
- InterfaceType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
- return rawType(nullability);
+ InterfaceType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
+ return rawType(nullabilityBuilder.build(library));
}
@override
diff --git a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
index 8984604..dc2007f 100644
--- a/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/extension_builder.dart
@@ -58,8 +58,8 @@
fileUri);
@override
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
throw new UnsupportedError("ExtensionBuilder.buildType is not supported.");
}
@@ -93,4 +93,17 @@
@override
String get debugName => "ExtensionBuilder";
+
+ void buildOutlineExpressions(LibraryBuilder library) {
+ void build(String ignore, Builder declaration) {
+ MemberBuilder member = declaration;
+ member.buildOutlineExpressions(library);
+ }
+
+ // TODO(johnniwinther): Handle annotations on the extension declaration.
+ //MetadataBuilder.buildAnnotations(
+ // isPatch ? origin.extension : extension,
+ // metadata, library, this, null);
+ scope.forEach(build);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 3083665..44e5a9a 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -69,8 +69,9 @@
Token initializerToken;
FormalParameterBuilder(this.metadata, this.modifiers, this.type, this.name,
- LibraryBuilder compilationUnit, int charOffset)
- : super(compilationUnit, charOffset);
+ LibraryBuilder compilationUnit, int charOffset,
+ [Uri fileUri])
+ : super(compilationUnit, charOffset, fileUri);
String get debugName => "FormalParameterBuilder";
@@ -114,8 +115,8 @@
FormalParameterBuilder clone(List<TypeBuilder> newTypes) {
// TODO(dmitryas): It's not clear how [metadata] is used currently, and
// how it should be cloned. Consider cloning it instead of reusing it.
- return new FormalParameterBuilder(
- metadata, modifiers, type?.clone(newTypes), name, parent, charOffset)
+ return new FormalParameterBuilder(metadata, modifiers,
+ type?.clone(newTypes), name, parent, charOffset, fileUri)
..kind = kind;
}
@@ -129,7 +130,8 @@
type,
name,
null,
- charOffset)
+ charOffset,
+ fileUri)
..parent = parent
..variable = variable);
}
diff --git a/pkg/front_end/lib/src/fasta/builder/invalid_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/invalid_type_builder.dart
index 4e71b742..c03cc7d 100644
--- a/pkg/front_end/lib/src/fasta/builder/invalid_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/invalid_type_builder.dart
@@ -8,7 +8,7 @@
import '../fasta_codes.dart' show LocatedMessage;
-import 'builder.dart' show TypeDeclarationBuilder;
+import 'builder.dart' show NullabilityBuilder, TypeDeclarationBuilder;
import '../kernel/kernel_builder.dart' show TypeBuilder, LibraryBuilder;
@@ -28,8 +28,8 @@
@override
InvalidType get target => const InvalidType();
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
return buildTypesWithBuiltArguments(library, null, null);
}
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 27f7bbf..71093d5 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -103,6 +103,9 @@
/// Returns the [Library] built by this builder.
Library get library;
+ /// Returns the import uri for the library.
+ ///
+ /// This is the canonical uri for the library, for instance 'dart:core'.
Uri get uri;
Iterator<Builder> get iterator {
@@ -292,15 +295,21 @@
return Nullability.legacy;
}
- NullabilityBuilder computeNullabilityFromToken(bool markedAsNullable) {
- if (!isNonNullableByDefault) {
- return const NullabilityBuilder.legacy();
- }
- if (markedAsNullable) {
- return const NullabilityBuilder.nullable();
- }
+ NullabilityBuilder get nullableBuilder {
+ return isNonNullableByDefault
+ ? const NullabilityBuilder.nullable()
+ : const NullabilityBuilder.omitted();
+ }
+
+ NullabilityBuilder get nonNullableBuilder {
return const NullabilityBuilder.omitted();
}
+
+ NullabilityBuilder nullableBuilderIfTrue(bool isNullable) {
+ return isNullable
+ ? const NullabilityBuilder.nullable()
+ : const NullabilityBuilder.omitted();
+ }
}
class LibraryLocalDeclarationIterator implements Iterator<Builder> {
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 458013a..38a57ae 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -214,8 +214,7 @@
DartType build(LibraryBuilder library) {
assert(declaration != null, "Declaration has not been resolved on $this.");
- return declaration.buildType(
- library, nullabilityBuilder.build(library), arguments);
+ return declaration.buildType(library, nullabilityBuilder, arguments);
}
Supertype buildSupertype(
@@ -254,8 +253,7 @@
}
}
- TypeBuilder subst(Map<TypeVariableBuilder, TypeBuilder> substitution,
- [List<NamedTypeBuilder> unboundTypes]) {
+ TypeBuilder subst(Map<TypeVariableBuilder, TypeBuilder> substitution) {
TypeBuilder result = substitution[declaration];
if (result != null) {
assert(declaration is TypeVariableBuilder);
@@ -264,7 +262,7 @@
List<TypeBuilder> arguments;
int i = 0;
for (TypeBuilder argument in this.arguments) {
- TypeBuilder type = argument.subst(substitution, unboundTypes);
+ TypeBuilder type = argument.subst(substitution);
if (type != argument) {
arguments ??= this.arguments.toList();
arguments[i] = type;
@@ -276,8 +274,6 @@
new NamedTypeBuilder(name, nullabilityBuilder, arguments);
if (declaration != null) {
result.bind(declaration);
- } else if (unboundTypes != null) {
- unboundTypes.add(result);
} else {
throw new UnsupportedError("Unbound type in substitution: $result.");
}
diff --git a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
index 4f67b7c..b723bdf 100644
--- a/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/nullability_builder.dart
@@ -29,9 +29,6 @@
const NullabilityBuilder.nullable()
: _syntacticNullability = SyntacticNullability.nullable;
- const NullabilityBuilder.legacy()
- : _syntacticNullability = SyntacticNullability.legacy;
-
const NullabilityBuilder.omitted()
: _syntacticNullability = SyntacticNullability.omitted;
@@ -40,7 +37,6 @@
case Nullability.nullable:
return const NullabilityBuilder.nullable();
case Nullability.legacy:
- return const NullabilityBuilder.legacy();
case Nullability.nonNullable:
case Nullability.neither:
default:
@@ -48,16 +44,6 @@
}
}
- /// Used temporarily in the places that need proper handling of NNBD features.
- ///
- /// Over time the uses of [NullabilityBuilder.pendingImplementation] should be
- /// eliminated, and the constructor should be eventually removed. Currently,
- /// it redirects to [NullabilityBuilder.legacy] as a conservative safety
- /// measure for the pre-NNBD code and as a visible reminder of the feature
- /// implementation being in progress in the NNBD code.
- // TODO(38286): Remove this constructor.
- const NullabilityBuilder.pendingImplementation() : this.legacy();
-
Nullability build(LibraryBuilder libraryBuilder, {Nullability ifOmitted}) {
// TODO(dmitryas): Ensure that either ifOmitted is set or libraryBuilder is
// provided;
@@ -94,4 +80,10 @@
unhandled("$_syntacticNullability", "writeNullabilityOn", TreeNode.noOffset,
noLocation);
}
+
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ writeNullabilityOn(buffer);
+ return "$buffer";
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index bf45b08..d818e4d 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -6,7 +6,8 @@
import 'dart:core' hide MapEntry;
-import 'package:kernel/ast.dart';
+import 'package:front_end/src/fasta/kernel/kernel_api.dart';
+import 'package:kernel/ast.dart' hide Variance;
import 'package:kernel/type_algebra.dart';
@@ -361,6 +362,27 @@
return function = result;
}
+ /// Returns the [index]th parameter of this function.
+ ///
+ /// The index is the syntactical index, including both positional and named
+ /// parameter in the order they are declared, and excluding the synthesized
+ /// this parameter on extension instance members.
+ VariableDeclaration getFormalParameter(int index) {
+ if (isExtensionInstanceMember) {
+ return formals[index + 1].variable;
+ } else {
+ return formals[index].variable;
+ }
+ }
+
+ /// If this is an extension instance method, the tear off closure parameter
+ /// corresponding to the [index]th parameter on the instance method is
+ /// returned.
+ ///
+ /// This is used to update the default value for the closure parameter when
+ /// it has been computed for the original parameter.
+ VariableDeclaration getExtensionTearOffParameter(int index) => null;
+
/// Returns the parameter for 'this' synthetically added to extension
/// instance members.
VariableDeclaration get extensionThis {
@@ -451,6 +473,14 @@
/// the synthetically created tear off function.
Procedure _extensionTearOff;
+ /// If this is an extension instance method then
+ /// [_extensionTearOffParameterMap] holds a map from the parameters of
+ /// the methods to the parameter of the closure returned in the tear-off.
+ ///
+ /// This map is used to set the default values on the closure parameters when
+ /// these have been built.
+ Map<VariableDeclaration, VariableDeclaration> _extensionTearOffParameterMap;
+
ProcedureBuilder(
List<MetadataBuilder> metadata,
int modifiers,
@@ -485,60 +515,6 @@
return _body;
}
- /// If this is an extension instance setter, wrap the setter body to return
- /// the rhs value from the method.
- ///
- /// That is, this setter
- ///
- /// extension E on A {
- /// void set property(B value) {
- /// value++;
- /// }
- /// }
- ///
- /// is converted into this top level method
- ///
- /// B E|property(A #this, B value) {
- /// final #t1 = value;
- /// value++;
- /// return #t1;
- /// }
- ///
- void _updateExtensionSetterBody() {
- if (isExtensionInstanceMember && isSetter) {
- // TODO(johnniwinther): Avoid the synthetic variable if the parameter is
- // never modified.
- // TODO(johnniwinther): Handle setter bodies with return statements.
- VariableDeclaration value = procedure.function.positionalParameters[1];
- procedure.function.returnType = value.type;
- Statement body = procedure.function.body;
- List<Statement> statements = [];
- Block block = new Block(statements);
- VariableDeclaration variableDeclaration =
- new VariableDeclarationImpl.forValue(
- new VariableGet(value)..fileOffset = procedure.fileOffset)
- ..type = value.type;
- statements.add(variableDeclaration);
- if (body is Block) {
- statements.addAll(body.statements);
- } else {
- statements.add(body);
- }
- ReturnStatement returnStatement = new ReturnStatement(
- new VariableGet(variableDeclaration)
- ..fileOffset = procedure.fileEndOffset);
- statements.add(returnStatement);
- setParents(block.statements, block);
- procedure.function.body = block;
- block.parent = procedure.function;
- }
- }
-
- void set body(Statement newBody) {
- super.body = newBody;
- _updateExtensionSetterBody();
- }
-
void set asyncModifier(AsyncMarker newModifier) {
actualAsyncModifier = newModifier;
if (function != null) {
@@ -639,6 +615,8 @@
_extensionTearOff != null, "No extension tear off created for $this.");
if (_extensionTearOff.name != null) return;
+ _extensionTearOffParameterMap = {};
+
int fileOffset = _procedure.fileOffset;
int extensionTypeParameterCount =
@@ -646,17 +624,18 @@
List<TypeParameter> typeParameters = <TypeParameter>[];
+ Map<TypeParameter, DartType> substitutionMap = {};
List<DartType> typeArguments = <DartType>[];
for (TypeParameter typeParameter in function.typeParameters) {
TypeParameter newTypeParameter = new TypeParameter(typeParameter.name);
typeParameters.add(newTypeParameter);
- typeArguments.add(new TypeParameterType(newTypeParameter));
+ typeArguments.add(substitutionMap[typeParameter] =
+ new TypeParameterType(newTypeParameter));
}
List<TypeParameter> tearOffTypeParameters = <TypeParameter>[];
List<TypeParameter> closureTypeParameters = <TypeParameter>[];
- Substitution substitution =
- Substitution.fromPairs(function.typeParameters, typeArguments);
+ Substitution substitution = Substitution.fromMap(substitutionMap);
for (int index = 0; index < typeParameters.length; index++) {
TypeParameter newTypeParameter = typeParameters[index];
newTypeParameter.bound =
@@ -672,12 +651,11 @@
VariableDeclaration copyParameter(
VariableDeclaration parameter, DartType type,
{bool isOptional}) {
- // TODO(johnniwinther): Handle default values.
- return new VariableDeclaration(parameter.name,
- type: type,
- initializer: isOptional ? new NullLiteral() : null,
- isFinal: parameter.isFinal)
+ VariableDeclaration newParameter = new VariableDeclaration(parameter.name,
+ type: type, isFinal: parameter.isFinal)
..fileOffset = parameter.fileOffset;
+ _extensionTearOffParameterMap[parameter] = newParameter;
+ return newParameter;
}
VariableDeclaration extensionThis = copyParameter(
@@ -751,6 +729,14 @@
_extensionTearOff.function.parent = _extensionTearOff;
}
+ @override
+ VariableDeclaration getExtensionTearOffParameter(int index) {
+ if (_extensionTearOffParameterMap != null) {
+ return _extensionTearOffParameterMap[getFormalParameter(index)];
+ }
+ return null;
+ }
+
/// The [Procedure] built by this builder.
Procedure get procedure => isPatch ? origin.procedure : _procedure;
@@ -940,9 +926,7 @@
assert(lastInitializer == superInitializer ||
lastInitializer == redirectingInitializer);
Initializer error = helper.buildInvalidInitializer(
- helper.desugarSyntheticExpression(
- helper.buildProblem(message, charOffset, noLength)),
- charOffset);
+ helper.buildProblem(message, charOffset, noLength));
initializers.add(error..parent = _constructor);
initializers.add(lastInitializer);
}
@@ -964,10 +948,8 @@
initializer.fileOffset, helper);
} else if (_constructor.initializers.isNotEmpty) {
Initializer first = _constructor.initializers.first;
- Initializer error = helper.buildInvalidInitializer(
- helper.desugarSyntheticExpression(helper.buildProblem(
- messageThisInitializerNotAlone, first.fileOffset, noLength)),
- first.fileOffset);
+ Initializer error = helper.buildInvalidInitializer(helper.buildProblem(
+ messageThisInitializerNotAlone, first.fileOffset, noLength));
initializers.add(error..parent = _constructor);
} else {
initializers.add(initializer..parent = _constructor);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index 35afd4b..f07de9d 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -38,6 +38,7 @@
show
LibraryBuilder,
MetadataBuilder,
+ NullabilityBuilder,
TypeBuilder,
TypeDeclarationBuilder,
TypeVariableBuilder;
@@ -204,15 +205,17 @@
int get typeVariablesCount => typeVariables?.length ?? 0;
@override
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
DartType thisType = buildThisType(library);
if (thisType is InvalidType) return thisType;
FunctionType result = thisType;
if (typedef.typeParameters.isEmpty && arguments == null) return result;
// Otherwise, substitute.
return buildTypesWithBuiltArguments(
- library, nullability, buildTypeArguments(library, arguments));
+ library,
+ nullabilityBuilder.build(library),
+ buildTypeArguments(library, arguments));
}
}
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index d3bf14f..93b1ade 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,7 +10,6 @@
import '../scope.dart';
import 'library_builder.dart';
-import 'named_type_builder.dart';
import 'type_declaration_builder.dart';
import 'type_variable_builder.dart';
@@ -48,9 +47,7 @@
// TODO(johnniwinther): Change [NamedTypeBuilder] to hold the
// [TypeParameterScopeBuilder] should resolve it, so that we cannot create
// [NamedTypeBuilder]s that are orphaned.
- TypeBuilder subst(Map<TypeVariableBuilder, TypeBuilder> substitution,
- [List<NamedTypeBuilder> unboundTypes]) =>
- this;
+ TypeBuilder subst(Map<TypeVariableBuilder, TypeBuilder> substitution) => this;
/// Clones the type builder recursively without binding the subterms to
/// existing declaration or type variable builders. All newly built types
diff --git a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
index e25faa6..8d4400c 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
@@ -7,7 +7,13 @@
import 'package:kernel/ast.dart' show DartType, Nullability;
import 'builder.dart'
- show Builder, LibraryBuilder, MetadataBuilder, ModifierBuilder, TypeBuilder;
+ show
+ Builder,
+ LibraryBuilder,
+ MetadataBuilder,
+ ModifierBuilder,
+ NullabilityBuilder,
+ TypeBuilder;
abstract class TypeDeclarationBuilder extends ModifierBuilder {
final List<MetadataBuilder> metadata;
@@ -31,8 +37,8 @@
int get typeVariablesCount => 0;
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments);
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments);
/// [arguments] have already been built.
DartType buildTypesWithBuiltArguments(LibraryBuilder library,
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index bea9904..87baf5b 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -14,7 +14,11 @@
import 'package:kernel/ast.dart'
show DartType, Nullability, TypeParameter, TypeParameterType;
-import '../fasta_codes.dart' show templateTypeArgumentsOnTypeVariable;
+import '../fasta_codes.dart'
+ show
+ templateCycleInTypeVariables,
+ templateInternalProblemUnfinishedTypeVariable,
+ templateTypeArgumentsOnTypeVariable;
import '../kernel/kernel_builder.dart'
show ClassBuilder, NamedTypeBuilder, LibraryBuilder, TypeBuilder;
@@ -79,8 +83,51 @@
charOffset,
fileUri);
- DartType buildType(LibraryBuilder library, Nullability nullability,
- List<TypeBuilder> arguments) {
+ int get variance => parameter.variance;
+
+ void set variance(int value) {
+ parameter.variance = value;
+ }
+
+ DartType buildType(LibraryBuilder library,
+ NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
+ if (arguments != null) {
+ int charOffset = -1; // TODO(ahe): Provide these.
+ Uri fileUri = null; // TODO(ahe): Provide these.
+ library.addProblem(
+ templateTypeArgumentsOnTypeVariable.withArguments(name),
+ charOffset,
+ name.length,
+ fileUri);
+ }
+ // If the bound is not set yet, the actual value is not important yet as it
+ // will be set later.
+ Nullability nullabilityIfOmitted = parameter.bound != null &&
+ library != null &&
+ library.isNonNullableByDefault
+ ? TypeParameterType.computeNullabilityFromBound(parameter)
+ : Nullability.legacy;
+ DartType type = buildTypesWithBuiltArguments(
+ library,
+ nullabilityBuilder.build(library, ifOmitted: nullabilityIfOmitted),
+ null);
+ if (parameter.bound == null) {
+ if (library is SourceLibraryBuilder) {
+ library.pendingNullabilities.add(type);
+ } else {
+ library.addProblem(
+ templateInternalProblemUnfinishedTypeVariable.withArguments(
+ name, library?.uri),
+ parameter.fileOffset,
+ name.length,
+ fileUri);
+ }
+ }
+ return type;
+ }
+
+ DartType buildTypesWithBuiltArguments(LibraryBuilder library,
+ Nullability nullability, List<DartType> arguments) {
// TODO(dmitryas): Use [nullability].
if (arguments != null) {
int charOffset = -1; // TODO(ahe): Provide these.
@@ -91,34 +138,19 @@
name.length,
fileUri);
}
- return new TypeParameterType(parameter);
- }
-
- DartType buildTypesWithBuiltArguments(LibraryBuilder library,
- Nullability nullability, List<DartType> arguments) {
- if (arguments != null) {
- int charOffset = -1; // TODO(ahe): Provide these.
- Uri fileUri = null; // TODO(ahe): Provide these.
- library.addProblem(
- templateTypeArgumentsOnTypeVariable.withArguments(name),
- charOffset,
- name.length,
- fileUri);
- }
- return buildType(library, nullability, null);
+ return new TypeParameterType(parameter, null, nullability);
}
TypeBuilder asTypeBuilder() {
- return new NamedTypeBuilder(
- name, const NullabilityBuilder.pendingImplementation(), null)
+ return new NamedTypeBuilder(name, const NullabilityBuilder.omitted(), null)
..bind(this);
}
void finish(
LibraryBuilder library, ClassBuilder object, TypeBuilder dynamicType) {
if (isPatch) return;
- // TODO(dmitryas): Set the nullability of objectType correctly.
- DartType objectType = object.buildType(library, Nullability.legacy, null);
+ DartType objectType =
+ object.buildType(library, library.nullableBuilder, null);
parameter.bound ??= bound?.build(library) ?? objectType;
// If defaultType is not set, initialize it to dynamic, unless the bound is
// explicitly specified as Object, in which case defaultType should also be
@@ -130,6 +162,74 @@
: dynamicType.build(library));
}
+ /// Assigns nullabilities to types in [pendingNullabilities].
+ ///
+ /// It's a helper function to assign the nullabilities to type-parameter types
+ /// after the corresponding type parameters have their bounds set or changed.
+ /// The function takes into account that some of the types in the input list
+ /// may be bounds to some of the type parameters of other types from the input
+ /// list.
+ static void finishNullabilities(LibraryBuilder libraryBuilder,
+ List<TypeParameterType> pendingNullabilities) {
+ // The bounds of type parameters may be type-parameter types of other
+ // parameters from the same declaration. In this case we need to set the
+ // nullability for them first. To preserve the ordering, we implement a
+ // depth-first search over the types. We use the fact that a nullability
+ // of a type parameter type can't ever be 'nullable' if computed from the
+ // bound. It allows us to use 'nullable' nullability as the marker in the
+ // DFS implementation.
+ Nullability marker = Nullability.nullable;
+ List<TypeParameterType> stack =
+ new List<TypeParameterType>.filled(pendingNullabilities.length, null);
+ int stackTop = 0;
+ for (TypeParameterType type in pendingNullabilities) {
+ type.typeParameterTypeNullability = null;
+ }
+ for (TypeParameterType type in pendingNullabilities) {
+ if (type.typeParameterTypeNullability != null) {
+ // Nullability for [type] was already computed on one of the branches
+ // of the depth-first search. Continue to the next one.
+ continue;
+ }
+ if (type.parameter.bound is TypeParameterType) {
+ TypeParameterType current = type;
+ TypeParameterType next = current.parameter.bound;
+ while (next != null && next.typeParameterTypeNullability == null) {
+ stack[stackTop++] = current;
+ current.typeParameterTypeNullability = marker;
+
+ current = next;
+ if (current.parameter.bound is TypeParameterType) {
+ next = current.parameter.bound;
+ if (next.typeParameterTypeNullability == marker) {
+ next.typeParameterTypeNullability = Nullability.neither;
+ libraryBuilder.addProblem(
+ templateCycleInTypeVariables.withArguments(
+ next.parameter.name, current.parameter.name),
+ next.parameter.fileOffset,
+ next.parameter.name.length,
+ next.parameter.location.file);
+ next = null;
+ }
+ } else {
+ next = null;
+ }
+ }
+ current.typeParameterTypeNullability =
+ TypeParameterType.computeNullabilityFromBound(current.parameter);
+ while (stackTop != 0) {
+ --stackTop;
+ current = stack[stackTop];
+ current.typeParameterTypeNullability =
+ TypeParameterType.computeNullabilityFromBound(current.parameter);
+ }
+ } else {
+ type.typeParameterTypeNullability =
+ TypeParameterType.computeNullabilityFromBound(type.parameter);
+ }
+ }
+ }
+
void applyPatch(covariant TypeVariableBuilder patch) {
patch.actualOrigin = this;
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index a2a2622..3f1df47 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -3318,6 +3318,26 @@
r"""Explicit extension application requires exactly 1 positional argument.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeExplicitExtensionAsExpression =
+ messageExplicitExtensionAsExpression;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageExplicitExtensionAsExpression = const MessageCode(
+ "ExplicitExtensionAsExpression",
+ message:
+ r"""Explicit extension application cannot be used as an expression.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeExplicitExtensionAsLvalue =
+ messageExplicitExtensionAsLvalue;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageExplicitExtensionAsLvalue = const MessageCode(
+ "ExplicitExtensionAsLvalue",
+ message:
+ r"""Explicit extension application cannot be a target for assignment.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String name,
@@ -4777,30 +4797,35 @@
const Template<
Message Function(
String name,
+ String name2,
String
- name2)> templateImplicitMixinOverrideContext = const Template<
- Message Function(String name, String name2)>(
+ name3)> templateImplicitMixinOverride = const Template<
+ Message Function(String name, String name2, String name3)>(
messageTemplate:
- r"""Override was introduced when the mixin '#name' was applied to '#name2'.""",
- withArguments: _withArgumentsImplicitMixinOverrideContext);
+ r"""Applying the mixin '#name' to '#name2' introduces an erroneous override of '#name3'.""",
+ withArguments: _withArgumentsImplicitMixinOverride);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name, String name2)>
- codeImplicitMixinOverrideContext =
- const Code<Message Function(String name, String name2)>(
- "ImplicitMixinOverrideContext", templateImplicitMixinOverrideContext,
- severity: Severity.context);
+const Code<Message Function(String name, String name2, String name3)>
+ codeImplicitMixinOverride =
+ const Code<Message Function(String name, String name2, String name3)>(
+ "ImplicitMixinOverride",
+ templateImplicitMixinOverride,
+);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsImplicitMixinOverrideContext(String name, String name2) {
+Message _withArgumentsImplicitMixinOverride(
+ String name, String name2, String name3) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
if (name2.isEmpty) throw 'No name provided';
name2 = demangleMixinApplicationName(name2);
- return new Message(codeImplicitMixinOverrideContext,
+ if (name3.isEmpty) throw 'No name provided';
+ name3 = demangleMixinApplicationName(name3);
+ return new Message(codeImplicitMixinOverride,
message:
- """Override was introduced when the mixin '${name}' was applied to '${name2}'.""",
- arguments: {'name': name, 'name2': name2});
+ """Applying the mixin '${name}' to '${name2}' introduces an erroneous override of '${name3}'.""",
+ arguments: {'name': name, 'name2': name2, 'name3': name3});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5656,27 +5681,31 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
+ String name,
String
- name)> templateInterfaceCheckContext = const Template<
- Message Function(String name)>(
+ name2)> templateInterfaceCheck = const Template<
+ Message Function(String name, String name2)>(
messageTemplate:
- r"""Both members are inherited by the non-abstract class '#name'.""",
- withArguments: _withArgumentsInterfaceCheckContext);
+ r"""The implementation of '#name' in the non-abstract class '#name2' does not conform to its interface.""",
+ withArguments: _withArgumentsInterfaceCheck);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeInterfaceCheckContext =
- const Code<Message Function(String name)>(
- "InterfaceCheckContext", templateInterfaceCheckContext,
- severity: Severity.context);
+const Code<Message Function(String name, String name2)> codeInterfaceCheck =
+ const Code<Message Function(String name, String name2)>(
+ "InterfaceCheck",
+ templateInterfaceCheck,
+);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsInterfaceCheckContext(String name) {
+Message _withArgumentsInterfaceCheck(String name, String name2) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
- return new Message(codeInterfaceCheckContext,
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ return new Message(codeInterfaceCheck,
message:
- """Both members are inherited by the non-abstract class '${name}'.""",
- arguments: {'name': name});
+ """The implementation of '${name}' in the non-abstract class '${name2}' does not conform to its interface.""",
+ arguments: {'name': name, 'name2': name2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5943,6 +5972,37 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String name,
+ Uri
+ uri_)> templateInternalProblemUnfinishedTypeVariable = const Template<
+ Message Function(String name, Uri uri_)>(
+ messageTemplate:
+ r"""Unfinished type variable '#name' found in non-source library '#uri'.""",
+ withArguments: _withArgumentsInternalProblemUnfinishedTypeVariable);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, Uri uri_)>
+ codeInternalProblemUnfinishedTypeVariable =
+ const Code<Message Function(String name, Uri uri_)>(
+ "InternalProblemUnfinishedTypeVariable",
+ templateInternalProblemUnfinishedTypeVariable,
+ severity: Severity.internalProblem);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsInternalProblemUnfinishedTypeVariable(
+ String name, Uri uri_) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ String uri = relativizeUri(uri_);
+ return new Message(codeInternalProblemUnfinishedTypeVariable,
+ message:
+ """Unfinished type variable '${name}' found in non-source library '${uri}'.""",
+ arguments: {'name': name, 'uri': uri_});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string, String string2)>
templateInternalProblemUnhandled =
const Template<Message Function(String string, String string2)>(
@@ -7300,6 +7360,17 @@
tip: r"""Try combining all of the on clauses into a single clause.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeMultipleVarianceModifiers =
+ messageMultipleVarianceModifiers;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageMultipleVarianceModifiers = const MessageCode(
+ "MultipleVarianceModifiers",
+ index: 97,
+ message: r"""Each type parameter can have at most one variance modifier.""",
+ tip: r"""Use at most one of the 'in', 'out', or 'inout' modifiers.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMultipleWith = messageMultipleWith;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7320,27 +7391,31 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
+ String name,
String
- name)> templateNamedMixinOverrideContext = const Template<
- Message Function(String name)>(
+ name2)> templateNamedMixinOverride = const Template<
+ Message Function(String name, String name2)>(
messageTemplate:
- r"""Override was introduced in the mixin application class '#name'.""",
- withArguments: _withArgumentsNamedMixinOverrideContext);
+ r"""The mixin application class '#name' introduces an erroneous override of '#name2'.""",
+ withArguments: _withArgumentsNamedMixinOverride);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeNamedMixinOverrideContext =
- const Code<Message Function(String name)>(
- "NamedMixinOverrideContext", templateNamedMixinOverrideContext,
- severity: Severity.context);
+const Code<Message Function(String name, String name2)> codeNamedMixinOverride =
+ const Code<Message Function(String name, String name2)>(
+ "NamedMixinOverride",
+ templateNamedMixinOverride,
+);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsNamedMixinOverrideContext(String name) {
+Message _withArgumentsNamedMixinOverride(String name, String name2) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
- return new Message(codeNamedMixinOverrideContext,
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ return new Message(codeNamedMixinOverride,
message:
- """Override was introduced in the mixin application class '${name}'.""",
- arguments: {'name': name});
+ """The mixin application class '${name}' introduces an erroneous override of '${name2}'.""",
+ arguments: {'name': name, 'name2': name2});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 8a82cd2..f1d6340 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -94,9 +94,6 @@
import 'implicit_type_argument.dart' show ImplicitTypeArgument;
-import 'kernel_shadow_ast.dart' as shadow
- show SyntheticExpressionJudgment, SyntheticWrapper;
-
import 'redirecting_factory_body.dart'
show
RedirectingFactoryBody,
@@ -111,6 +108,8 @@
import 'kernel_ast_api.dart';
+import 'kernel_shadow_ast.dart';
+
import 'kernel_builder.dart';
// TODO(ahe): Remove this and ensure all nodes have a location.
@@ -681,10 +680,10 @@
Initializer initializer;
if (member.isExternal) {
initializer = buildInvalidInitializer(
- desugarSyntheticExpression(buildProblem(
+ buildProblem(
fasta.messageExternalConstructorWithFieldInitializers,
formal.charOffset,
- formal.name.length)),
+ formal.name.length),
formal.charOffset);
} else {
initializer = buildFieldInitializer(
@@ -790,18 +789,31 @@
FormalParameterBuilder parameter = formals.parameters[i];
Expression initializer = parameter.target.initializer;
if (parameter.isOptional || initializer != null) {
- VariableDeclaration realParameter = builder.formals[i].target;
if (parameter.isOptional) {
initializer ??= forest.createNullLiteral(
- // TODO(ahe): Should store: realParameter.fileOffset
+ // TODO(ahe): Should store: originParameter.fileOffset
// https://github.com/dart-lang/sdk/issues/32289
null);
}
- realParameter.initializer = initializer..parent = realParameter;
+ VariableDeclaration originParameter = builder.getFormalParameter(i);
+ originParameter.initializer = initializer..parent = originParameter;
typeInferrer?.inferParameterInitializer(
- this, initializer, realParameter.type);
+ this, initializer, originParameter.type);
libraryBuilder.loader.transformPostInference(
- realParameter, transformSetLiterals, transformCollections);
+ originParameter, transformSetLiterals, transformCollections);
+
+ VariableDeclaration extensionTearOffParameter =
+ builder.getExtensionTearOffParameter(i);
+ if (extensionTearOffParameter != null) {
+ cloner ??= new CloneVisitor();
+ Expression tearOffInitializer = cloner.clone(initializer);
+ extensionTearOffParameter.initializer = tearOffInitializer
+ ..parent = extensionTearOffParameter;
+ libraryBuilder.loader.transformPostInference(
+ extensionTearOffParameter,
+ transformSetLiterals,
+ transformCollections);
+ }
}
}
}
@@ -895,10 +907,8 @@
forest.createExpressionStatement(
// This error is added after type inference is done, so we
// don't need to wrap errors in SyntheticExpressionJudgment.
- desugarSyntheticExpression(buildProblem(
- fasta.messageSetterWithWrongNumberOfFormals,
- charOffset,
- noLength)),
+ buildProblem(fasta.messageSetterWithWrongNumberOfFormals,
+ charOffset, noLength),
null),
body,
],
@@ -915,8 +925,8 @@
} else {
if (body != null) {
builder.body = new Block(<Statement>[
- new ExpressionStatement(desugarSyntheticExpression(buildProblem(
- fasta.messageExternalMethodWithBody, body.fileOffset, noLength)))
+ new ExpressionStatement(buildProblem(
+ fasta.messageExternalMethodWithBody, body.fileOffset, noLength))
..fileOffset = body.fileOffset,
body,
])
@@ -1007,11 +1017,11 @@
String name = constructorNameForDiagnostics(initialTarget.name.name,
className: initialTarget.enclosingClass.name);
// TODO(dmitryas): Report this error earlier.
- replacementNode = desugarSyntheticExpression(buildProblem(
+ replacementNode = buildProblem(
fasta.templateCyclicRedirectingFactoryConstructors
.withArguments(name),
initialTarget.fileOffset,
- name.length));
+ name.length);
} else if (resolvedTarget is Constructor &&
resolvedTarget.enclosingClass.isAbstract) {
replacementNode = evaluateArgumentsBefore(
@@ -1063,12 +1073,6 @@
? Constness.explicitConst
: Constness.explicitNew,
charOffset: invocation.fileOffset);
- // TODO(dmitryas): Find a better way to unwrap
- // [SyntheticExpressionJudgment] or not to build it in the first place
- // when it's not needed.
- if (replacementNode is shadow.SyntheticExpressionJudgment) {
- replacementNode = desugarSyntheticExpression(replacementNode);
- }
}
}
@@ -1177,7 +1181,7 @@
for (int i = 0; i < parameters.positionalParameters.length; i++) {
VariableDeclaration formal = parameters.positionalParameters[i];
formals[i] = new FormalParameterBuilder(
- null, 0, null, formal.name, libraryBuilder, formal.fileOffset)
+ null, 0, null, formal.name, libraryBuilder, formal.fileOffset, uri)
..variable = formal;
}
enterLocalScope(
@@ -1245,9 +1249,7 @@
// TODO(ahe): Change this to a null check.
int offset = builder.body?.fileOffset ?? builder.charOffset;
constructor.initializers.add(buildInvalidInitializer(
- desugarSyntheticExpression(
- buildProblem(fasta.messageConstructorNotSync, offset, noLength)),
- offset));
+ buildProblem(fasta.messageConstructorNotSync, offset, noLength)));
}
if (needsImplicitSuperInitializer) {
/// >If no superinitializer is provided, an implicit superinitializer
@@ -1266,11 +1268,11 @@
length = (constructor.parent as Class).name.length;
}
initializer = buildInvalidInitializer(
- desugarSyntheticExpression(buildProblem(
+ buildProblem(
fasta.templateSuperclassHasNoDefaultConstructor
.withArguments(superclass),
builder.charOffset,
- length)),
+ length),
builder.charOffset);
} else {
initializer = buildSuperInitializer(
@@ -1483,7 +1485,7 @@
if (receiver is ThisAccessGenerator && receiver.isSuper) {
ThisAccessGenerator thisAccessorReceiver = receiver;
isSuper = true;
- receiver = forest.createThisExpression(thisAccessorReceiver.token);
+ receiver = forest.createThisExpression(thisAccessorReceiver.fileOffset);
}
push(buildBinaryOperator(toValue(receiver), token, argument, isSuper));
}
@@ -1530,16 +1532,7 @@
void doIfNull(Token token) {
Expression b = popForValue();
Expression a = popForValue();
- VariableDeclaration variable = new VariableDeclaration.forValue(a);
- push(new IfNullJudgment(
- variable,
- forest.createConditionalExpression(
- buildIsNull(new VariableGet(variable), offsetForToken(token), this),
- token,
- b,
- null,
- new VariableGet(variable)))
- ..fileOffset = offsetForToken(token));
+ push(new IfNullExpression(a, b)..fileOffset = offsetForToken(token));
}
/// Handle `a?.b(...)`.
@@ -1619,9 +1612,9 @@
.withLocation(uri, charOffset, length);
}
}
- return desugarSyntheticExpression(buildProblem(
+ return buildProblem(
message.messageObject, message.charOffset, message.length,
- context: context));
+ context: context);
}
@override
@@ -1879,11 +1872,12 @@
Builder setter =
_getCorrespondingSetterBuilder(scope, declaration, name, charOffset);
// TODO(johnniwinther): Check for constantContext like below?
- return new ExtensionInstanceAccessGenerator.fromBuilder(this,
+ return new ExtensionInstanceAccessGenerator.fromBuilder(this, name,
extensionThis, extensionTypeParameters, declaration, token, setter);
} else if (declaration.isRegularMethod) {
assert(declaration.isStatic || declaration.isTopLevel);
- return new StaticAccessGenerator(this, token, declaration.target, null);
+ return new StaticAccessGenerator(
+ this, token, name, declaration.target, null);
} else if (declaration is PrefixBuilder) {
assert(prefix == null);
return new PrefixUseGenerator(this, token, declaration);
@@ -1895,7 +1889,7 @@
Builder setter =
_getCorrespondingSetterBuilder(scope, declaration, name, charOffset);
StaticAccessGenerator generator = new StaticAccessGenerator.fromBuilder(
- this, declaration, token, setter);
+ this, name, declaration, token, setter);
if (constantContext != ConstantContext.none) {
Member readTarget = generator.readTarget;
if (!(readTarget is Field && readTarget.isConst ||
@@ -2746,9 +2740,21 @@
@override
void handleNonNullAssertExpression(Token bang) {
+ assert(checkState(bang, [
+ unionOfKinds([ValueKind.Expression, ValueKind.Generator])
+ ]));
if (!libraryBuilder.loader.target.enableNonNullable) {
reportNonNullAssertExpressionNotEnabled(bang);
}
+ Object operand = pop();
+ Expression expression;
+ if (operand is Generator) {
+ expression = operand.buildSimpleRead();
+ } else {
+ assert(operand is Expression);
+ expression = operand;
+ }
+ push(forest.createNullCheck(offsetForToken(bang), expression));
}
@override
@@ -2775,10 +2781,8 @@
libraryBuilder.addProblem(
message, offset, lengthOfSpan(beginToken, suffix), uri);
push(new UnresolvedType(
- new NamedTypeBuilder(
- name,
- libraryBuilder.computeNullabilityFromToken(isMarkedAsNullable),
- null)
+ new NamedTypeBuilder(name,
+ libraryBuilder.nullableBuilderIfTrue(isMarkedAsNullable), null)
..bind(new InvalidTypeBuilder(
name,
message.withLocation(
@@ -2791,8 +2795,7 @@
TypeBuilder result;
if (name is Generator) {
result = name.buildTypeWithResolvedArguments(
- libraryBuilder.computeNullabilityFromToken(isMarkedAsNullable),
- arguments);
+ libraryBuilder.nullableBuilderIfTrue(isMarkedAsNullable), arguments);
if (result == null) {
unhandled("null", "result", beginToken.charOffset, uri);
}
@@ -2801,7 +2804,7 @@
libraryBuilder.addProblem(
name.message, name.charOffset, name.name.length, name.fileUri);
result = new NamedTypeBuilder(name.name,
- libraryBuilder.computeNullabilityFromToken(isMarkedAsNullable), null)
+ libraryBuilder.nullableBuilderIfTrue(isMarkedAsNullable), null)
..bind(new InvalidTypeBuilder(
name.name,
name.message.withLocation(
@@ -2847,7 +2850,7 @@
List<TypeVariableBuilder> typeVariables = pop();
UnresolvedType type = formals.toFunctionType(
returnType,
- libraryBuilder.computeNullabilityFromToken(questionMark != null),
+ libraryBuilder.nullableBuilderIfTrue(questionMark != null),
typeVariables);
exitLocalScope();
push(type);
@@ -2997,7 +3000,7 @@
}
} else {
parameter = new FormalParameterBuilder(null, modifiers, type?.builder,
- name?.name, libraryBuilder, offsetForToken(nameToken));
+ name?.name, libraryBuilder, offsetForToken(nameToken), uri);
}
VariableDeclaration variable =
parameter.build(libraryBuilder, functionNestingLevel);
@@ -3069,10 +3072,8 @@
if (!libraryBuilder.loader.target.enableNonNullable) {
reportErrorIfNullableType(question);
}
- UnresolvedType type = formals.toFunctionType(
- returnType,
- libraryBuilder.computeNullabilityFromToken(question != null),
- typeVariables);
+ UnresolvedType type = formals.toFunctionType(returnType,
+ libraryBuilder.nullableBuilderIfTrue(question != null), typeVariables);
exitLocalScope();
push(type);
functionNestingLevel--;
@@ -3277,7 +3278,7 @@
bool isSuper = false;
if (receiver is ThisAccessGenerator && receiver.isSuper) {
isSuper = true;
- receiverValue = forest.createThisExpression(receiver.token);
+ receiverValue = forest.createThisExpression(receiver.fileOffset);
} else {
receiverValue = toValue(receiver);
}
@@ -3444,15 +3445,13 @@
LocatedMessage argMessage = checkArgumentsForFunction(
target.function, arguments, charOffset, typeParameters);
if (argMessage != null) {
- return wrapSyntheticExpression(
- throwNoSuchMethodError(
- forest.createNullLiteral(null)..fileOffset = charOffset,
- target.name.name,
- arguments,
- charOffset,
- candidate: target,
- message: argMessage),
- charOffset);
+ return throwNoSuchMethodError(
+ forest.createNullLiteral(null)..fileOffset = charOffset,
+ target.name.name,
+ arguments,
+ charOffset,
+ candidate: target,
+ message: argMessage);
}
bool isConst = constness == Constness.explicitConst ||
@@ -3463,12 +3462,8 @@
addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
}
if (isConst && !target.isConst) {
- return wrapInvalidConstructorInvocation(
- desugarSyntheticExpression(buildProblem(
- fasta.messageNonConstConstructor, charOffset, charLength)),
- target,
- arguments,
- charOffset);
+ return buildProblem(
+ fasta.messageNonConstConstructor, charOffset, charLength);
}
ConstructorInvocation node =
new ConstructorInvocation(target, arguments, isConst: isConst)
@@ -3484,12 +3479,8 @@
addProblem(fasta.messageMissingExplicitConst, charOffset, charLength);
}
if (isConst && !procedure.isConst) {
- return wrapInvalidConstructorInvocation(
- desugarSyntheticExpression(buildProblem(
- fasta.messageNonConstFactory, charOffset, charLength)),
- target,
- arguments,
- charOffset);
+ return buildProblem(
+ fasta.messageNonConstFactory, charOffset, charLength);
}
StaticInvocation node = new FactoryConstructorInvocationJudgment(
target, arguments,
@@ -3517,15 +3508,13 @@
LocatedMessage argMessage = checkArgumentsForFunction(
target.function, arguments, fileOffset, typeParameters);
if (argMessage != null) {
- return wrapSyntheticExpression(
- throwNoSuchMethodError(
- forest.createNullLiteral(null)..fileOffset = fileOffset,
- target.name.name,
- arguments,
- fileOffset,
- candidate: target,
- message: argMessage),
- fileOffset);
+ return throwNoSuchMethodError(
+ forest.createNullLiteral(null)..fileOffset = fileOffset,
+ target.name.name,
+ arguments,
+ fileOffset,
+ candidate: target,
+ message: argMessage);
}
StaticInvocation node = new StaticInvocation(target, arguments)
@@ -3706,13 +3695,11 @@
if (type is ProblemBuilder) {
typeName = type.fullNameForErrors;
}
- push(wrapSyntheticExpression(
- throwNoSuchMethodError(
- forest.createNullLiteral(null)..fileOffset = offset,
- debugName(typeName, name),
- arguments,
- nameToken.charOffset),
- offset));
+ push(throwNoSuchMethodError(
+ forest.createNullLiteral(null)..fileOffset = offset,
+ debugName(typeName, name),
+ arguments,
+ nameToken.charOffset));
}
constantContext = savedConstantContext;
}
@@ -3766,17 +3753,13 @@
message = b.message.withLocation(uri, charOffset, noLength);
} else if (b.isConstructor) {
if (type.isAbstract) {
- return wrapInvalidConstructorInvocation(
- evaluateArgumentsBefore(
- arguments,
- buildAbstractClassInstantiationError(
- fasta.templateAbstractClassInstantiation
- .withArguments(type.name),
- type.name,
- nameToken.charOffset)),
- target,
+ return evaluateArgumentsBefore(
arguments,
- charOffset);
+ buildAbstractClassInstantiationError(
+ fasta.templateAbstractClassInstantiation
+ .withArguments(type.name),
+ type.name,
+ nameToken.charOffset));
}
}
if (target is Constructor ||
@@ -3808,15 +3791,12 @@
}
errorName ??= name;
- return wrapUnresolvedTargetInvocation(
- throwNoSuchMethodError(
- forest.createNullLiteral(null)..fileOffset = charOffset,
- errorName,
- arguments,
- nameLastToken.charOffset,
- message: message),
+ return throwNoSuchMethodError(
+ forest.createNullLiteral(null)..fileOffset = charOffset,
+ errorName,
arguments,
- arguments.fileOffset);
+ nameLastToken.charOffset,
+ message: message);
}
@override
@@ -3889,10 +3869,8 @@
? elseEntry.fileOffset
: offsetForToken(ifToken);
push(new MapEntry(
- desugarSyntheticExpression(buildProblem(
- fasta.templateExpectedAfterButGot.withArguments(':'),
- offset,
- 1)),
+ buildProblem(fasta.templateExpectedAfterButGot.withArguments(':'),
+ offset, 1),
new NullLiteral())
..fileOffset = offsetForToken(ifToken));
}
@@ -3908,10 +3886,8 @@
? thenEntry.fileOffset
: offsetForToken(ifToken);
push(new MapEntry(
- desugarSyntheticExpression(buildProblem(
- fasta.templateExpectedAfterButGot.withArguments(':'),
- offset,
- 1)),
+ buildProblem(fasta.templateExpectedAfterButGot.withArguments(':'),
+ offset, 1),
new NullLiteral())
..fileOffset = offsetForToken(ifToken));
}
@@ -4066,14 +4042,8 @@
if (!isFunctionExpression) {
annotations = pop(); // Metadata.
}
- FunctionNode function = formals.buildFunctionNode(
- libraryBuilder,
- returnType,
- typeParameters,
- asyncModifier,
- body,
- const NullabilityBuilder.pendingImplementation(),
- token.charOffset);
+ FunctionNode function = formals.buildFunctionNode(libraryBuilder,
+ returnType, typeParameters, asyncModifier, body, token.charOffset);
if (declaration is FunctionDeclaration) {
VariableDeclaration variable = declaration.variable;
@@ -4095,15 +4065,13 @@
Expression expression = new NamedFunctionExpressionJudgment(variable);
if (oldInitializer != null) {
// This must have been a compile-time error.
- Expression error = desugarSyntheticExpression(oldInitializer);
+ Expression error = oldInitializer;
assert(isErroneousNode(error));
int offset = forest.readOffset(expression);
- push(wrapSyntheticExpression(
- new Let(
- new VariableDeclaration.forValue(error)..fileOffset = offset,
- expression)
- ..fileOffset = offset,
- offset));
+ push(new Let(
+ new VariableDeclaration.forValue(error)..fileOffset = offset,
+ expression)
+ ..fileOffset = offset);
} else {
push(expression);
}
@@ -4154,14 +4122,8 @@
FormalParameters formals = pop();
exitFunction();
List<TypeVariableBuilder> typeParameters = pop();
- FunctionNode function = formals.buildFunctionNode(
- libraryBuilder,
- null,
- typeParameters,
- asyncModifier,
- body,
- const NullabilityBuilder.pendingImplementation(),
- token.charOffset)
+ FunctionNode function = formals.buildFunctionNode(libraryBuilder, null,
+ typeParameters, asyncModifier, body, token.charOffset)
..fileOffset = beginToken.charOffset;
if (constantContext != ConstantContext.none) {
@@ -4295,11 +4257,6 @@
new VariableGetImpl(variable, fact, scope)
..fileOffset = inKeyword.offset,
voidContext: true);
- if (syntheticAssignment is shadow.SyntheticExpressionJudgment) {
- syntheticAssignment = wrapSyntheticExpression(
- desugarSyntheticExpression(syntheticAssignment),
- offsetForToken(lvalue.token));
- }
return forest.createExpressionStatement(syntheticAssignment, null);
}
Message message = forest.isVariablesDeclaration(lvalue)
@@ -4824,6 +4781,16 @@
libraryBuilder.loader.target.objectClassBuilder,
libraryBuilder.loader.target.dynamicType);
}
+ TypeVariableBuilder.finishNullabilities(
+ libraryBuilder, libraryBuilder.pendingNullabilities);
+ libraryBuilder.pendingNullabilities.clear();
+ }
+
+ @override
+ void handleVarianceModifier(Token variance) {
+ if (!libraryBuilder.loader.target.enableVariance) {
+ reportVarianceModifierNotEnabled(variance);
+ }
}
@override
@@ -4849,15 +4816,13 @@
@override
void handleInvalidStatement(Token token, Message message) {
Statement statement = pop();
- push(new ExpressionStatement(desugarSyntheticExpression(
- buildProblem(message, statement.fileOffset, noLength))));
+ push(new ExpressionStatement(
+ buildProblem(message, statement.fileOffset, noLength)));
}
@override
Expression buildProblem(Message message, int charOffset, int length,
- {List<LocatedMessage> context,
- bool suppressMessage: false,
- bool wrapInSyntheticExpression: true}) {
+ {List<LocatedMessage> context, bool suppressMessage: false}) {
if (!suppressMessage) {
addProblem(message, charOffset, length,
wasHandled: true, context: context);
@@ -4866,9 +4831,7 @@
.format(message.withLocation(uri, charOffset, length), Severity.error);
InvalidExpression expression = new InvalidExpression(text)
..fileOffset = charOffset;
- return wrapInSyntheticExpression
- ? wrapSyntheticExpression(expression, charOffset)
- : expression;
+ return expression;
}
@override
@@ -4897,9 +4860,9 @@
}
return new Let(
new VariableDeclaration.forValue(
- desugarSyntheticExpression(buildProblem(
+ buildProblem(
message.messageObject, message.charOffset, message.length,
- context: context)),
+ context: context),
type: const BottomType())
..fileOffset = offset,
expression);
@@ -4944,9 +4907,6 @@
]),
constness: Constness.explicitNew,
charOffset: charOffset);
- if (invocation is shadow.SyntheticExpressionJudgment) {
- invocation = desugarSyntheticExpression(invocation);
- }
return forest.createThrow(null, invocation)..fileOffset = charOffset;
}
@@ -4986,12 +4946,11 @@
return new ShadowInvalidFieldInitializer(
field,
value,
- new VariableDeclaration.forValue(desugarSyntheticExpression(
- buildProblem(
- fasta.templateFinalInstanceVariableAlreadyInitialized
- .withArguments(name),
- offset,
- noLength))))
+ new VariableDeclaration.forValue(buildProblem(
+ fasta.templateFinalInstanceVariableAlreadyInitialized
+ .withArguments(name),
+ offset,
+ noLength)))
..fileOffset = offset;
}
@@ -5013,10 +4972,10 @@
// Duplicated name, already reported.
return new LocalInitializer(
new VariableDeclaration.forValue(
- desugarSyntheticExpression(buildProblem(
+ buildProblem(
fasta.templateDuplicatedDeclarationUse.withArguments(name),
fieldNameOffset,
- name.length))
+ name.length)
..fileOffset = fieldNameOffset)
..fileOffset = fieldNameOffset)
..fileOffset = fieldNameOffset;
@@ -5048,9 +5007,6 @@
]),
constness: Constness.explicitNew,
charOffset: assignmentOffset);
- if (invocation is shadow.SyntheticExpressionJudgment) {
- invocation = desugarSyntheticExpression(invocation);
- }
return new ShadowInvalidFieldInitializer(
builder.field,
expression,
@@ -5078,10 +5034,10 @@
}
} else {
return buildInvalidInitializer(
- desugarSyntheticExpression(buildProblem(
+ buildProblem(
fasta.templateInitializerForStaticField.withArguments(name),
fieldNameOffset,
- name.length)),
+ name.length),
fieldNameOffset);
}
}
@@ -5094,10 +5050,8 @@
return buildInvalidSuperInitializer(
constructor,
arguments,
- desugarSyntheticExpression(buildProblem(
- fasta.messageConstConstructorWithNonConstSuper,
- charOffset,
- constructor.name.name.length)),
+ buildProblem(fasta.messageConstConstructorWithNonConstSuper,
+ charOffset, constructor.name.name.length),
charOffset);
}
needsImplicitSuperInitializer = false;
@@ -5289,6 +5243,19 @@
}
@override
+ Expression buildProblemErrorIfConst(
+ Message message, int charOffset, int length,
+ {bool wasHandled: false, List<LocatedMessage> context}) {
+ addProblemErrorIfConst(message, charOffset, length,
+ wasHandled: wasHandled, context: context);
+ String text = libraryBuilder.loader.target.context
+ .format(message.withLocation(uri, charOffset, length), Severity.error);
+ InvalidExpression expression = new InvalidExpression(text)
+ ..fileOffset = charOffset;
+ return expression;
+ }
+
+ @override
void reportDuplicatedDeclaration(
Builder existing, String name, int charOffset) {
List<LocatedMessage> context = existing.isSynthetic
@@ -5369,49 +5336,6 @@
}
return name.isEmpty ? className : "$className.$name";
}
-
- @override
- Expression wrapSyntheticExpression(Expression desugared, int charOffset) {
- return shadow.SyntheticWrapper.wrapSyntheticExpression(desugared)
- ..fileOffset = charOffset;
- }
-
- @override
- Expression desugarSyntheticExpression(Expression node) {
- shadow.SyntheticExpressionJudgment shadowNode = node;
- return shadowNode.desugared;
- }
-
- @override
- Expression wrapInvalidConstructorInvocation(Expression desugared,
- Member constructor, Arguments arguments, int charOffset) {
- return shadow.SyntheticWrapper.wrapInvalidConstructorInvocation(
- desugared, constructor, arguments)
- ..fileOffset = charOffset;
- }
-
- @override
- Expression wrapInvalidWrite(
- Expression desugared, Expression expression, int charOffset) {
- return shadow.SyntheticWrapper.wrapInvalidWrite(desugared, expression)
- ..fileOffset = charOffset;
- }
-
- @override
- Expression wrapUnresolvedTargetInvocation(
- Expression desugared, Arguments arguments, int charOffset) {
- return shadow.SyntheticWrapper.wrapUnresolvedTargetInvocation(
- desugared, arguments)
- ..fileOffset = charOffset;
- }
-
- @override
- Expression wrapUnresolvedVariableAssignment(
- Expression desugared, bool isCompound, Expression rhs, int charOffset) {
- return shadow.SyntheticWrapper.wrapUnresolvedVariableAssignment(
- desugared, isCompound, rhs)
- ..fileOffset = charOffset;
- }
}
abstract class EnsureLoaded {
@@ -5580,12 +5504,11 @@
List<TypeVariableBuilder> typeParameters,
AsyncMarker asyncModifier,
Statement body,
- NullabilityBuilder nullabilityBuilder,
int fileEndOffset) {
- FunctionType type =
- toFunctionType(returnType, nullabilityBuilder, typeParameters)
- .builder
- .build(library);
+ FunctionType type = toFunctionType(
+ returnType, const NullabilityBuilder.omitted(), typeParameters)
+ .builder
+ .build(library);
List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
if (parameters != null) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 39d84cb..991fa4e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -247,8 +247,8 @@
TypeBuilder asSupertypeOf(Class cls, Class supertype) {
ClassHierarchyNode clsNode = getNodeFromKernelClass(cls);
if (cls == supertype) {
- return new NamedTypeBuilder(clsNode.classBuilder.name,
- const NullabilityBuilder.pendingImplementation(), null)
+ return new NamedTypeBuilder(
+ clsNode.classBuilder.name, const NullabilityBuilder.omitted(), null)
..bind(clsNode.classBuilder);
}
ClassHierarchyNode supertypeNode = getNodeFromKernelClass(supertype);
@@ -1964,10 +1964,11 @@
InterfaceType get nullType => hierarchy.coreTypes.nullType;
@override
- InterfaceType get objectType => hierarchy.coreTypes.objectLegacyRawType;
+ InterfaceType get objectLegacyRawType =>
+ hierarchy.coreTypes.objectLegacyRawType;
@override
- InterfaceType get rawFunctionType =>
+ InterfaceType get functionLegacyRawType =>
hierarchy.coreTypes.functionLegacyRawType;
@override
diff --git a/pkg/front_end/lib/src/fasta/kernel/collections.dart b/pkg/front_end/lib/src/fasta/kernel/collections.dart
index 21ba143..8803399 100644
--- a/pkg/front_end/lib/src/fasta/kernel/collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/collections.dart
@@ -413,11 +413,11 @@
isAsync: entry.isAsync)
..fileOffset = entry.fileOffset;
}
- return helper.desugarSyntheticExpression(helper.buildProblem(
+ return helper.buildProblem(
templateExpectedButGot.withArguments(','),
entry.fileOffset,
1,
- ));
+ );
}
bool isConvertibleToMapEntry(Expression element) {
@@ -466,11 +466,11 @@
..fileOffset = element.fileOffset;
}
return new MapEntry(
- helper.desugarSyntheticExpression(helper.buildProblem(
+ helper.buildProblem(
templateExpectedAfterButGot.withArguments(':'),
element.fileOffset,
// TODO(danrubel): what is the length of the expression?
1,
- )),
+ ),
new NullLiteral());
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index fa0afb1..539b86f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1230,15 +1230,17 @@
statement.message,
templateConstEvalInvalidType.withArguments(
message,
- typeEnvironment.stringType,
+ typeEnvironment.coreTypes.stringLegacyRawType,
message.getType(typeEnvironment)));
}
}
} else {
report(
statement.condition,
- templateConstEvalInvalidType.withArguments(condition,
- typeEnvironment.boolType, condition.getType(typeEnvironment)));
+ templateConstEvalInvalidType.withArguments(
+ condition,
+ typeEnvironment.coreTypes.boolLegacyRawType,
+ condition.getType(typeEnvironment)));
}
}
@@ -1303,7 +1305,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
'+',
receiver,
- typeEnvironment.stringType,
+ typeEnvironment.coreTypes.stringLegacyRawType,
other.getType(typeEnvironment)));
}
}
@@ -1323,7 +1325,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
other,
- typeEnvironment.intType,
+ typeEnvironment.coreTypes.intLegacyRawType,
other.getType(typeEnvironment)));
}
num receiverValue = (receiver as PrimitiveConstant<num>).value;
@@ -1335,7 +1337,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
receiver,
- typeEnvironment.numType,
+ typeEnvironment.coreTypes.numLegacyRawType,
other.getType(typeEnvironment)));
}
} else if (receiver is DoubleConstant) {
@@ -1346,7 +1348,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
receiver,
- typeEnvironment.intType,
+ typeEnvironment.coreTypes.intLegacyRawType,
receiver.getType(typeEnvironment)));
}
if (arguments.length == 0) {
@@ -1367,7 +1369,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
op,
receiver,
- typeEnvironment.numType,
+ typeEnvironment.coreTypes.numLegacyRawType,
other.getType(typeEnvironment)));
}
} else if (receiver is BoolConstant) {
@@ -1420,7 +1422,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
node.operator,
left,
- typeEnvironment.boolType,
+ typeEnvironment.coreTypes.boolLegacyRawType,
right.getType(typeEnvironment)));
}
return report(
@@ -1441,7 +1443,7 @@
templateConstEvalInvalidBinaryOperandType.withArguments(
node.operator,
left,
- typeEnvironment.boolType,
+ typeEnvironment.coreTypes.boolLegacyRawType,
right.getType(typeEnvironment)));
}
return report(
@@ -1479,8 +1481,10 @@
} else {
return report(
node.condition,
- templateConstEvalInvalidType.withArguments(condition,
- typeEnvironment.boolType, condition.getType(typeEnvironment)));
+ templateConstEvalInvalidType.withArguments(
+ condition,
+ typeEnvironment.coreTypes.boolLegacyRawType,
+ condition.getType(typeEnvironment)));
}
}
@@ -1746,7 +1750,7 @@
}
if (constant is NullConstant) {
return makeBoolConstant(node.type == typeEnvironment.nullType ||
- node.type == typeEnvironment.objectType ||
+ node.type == typeEnvironment.coreTypes.objectLegacyRawType ||
node.type is DynamicType);
}
return makeBoolConstant(
@@ -1764,8 +1768,10 @@
}
return report(
node,
- templateConstEvalInvalidType.withArguments(constant,
- typeEnvironment.boolType, constant.getType(typeEnvironment)));
+ templateConstEvalInvalidType.withArguments(
+ constant,
+ typeEnvironment.coreTypes.boolLegacyRawType,
+ constant.getType(typeEnvironment)));
}
@override
@@ -1850,14 +1856,14 @@
bool isSubtype(Constant constant, DartType type) {
DartType constantType = constant.getType(typeEnvironment);
if (targetingJavaScript) {
- if (constantType == typeEnvironment.intType &&
- type == typeEnvironment.doubleType) {
+ if (constantType == typeEnvironment.coreTypes.intLegacyRawType &&
+ type == typeEnvironment.coreTypes.doubleLegacyRawType) {
// With JS semantics, an integer is also a double.
return true;
}
- if (constantType == typeEnvironment.doubleType &&
- type == typeEnvironment.intType) {
+ if (constantType == typeEnvironment.coreTypes.doubleLegacyRawType &&
+ type == typeEnvironment.coreTypes.intLegacyRawType) {
double value = (constant as DoubleConstant).value;
if (value.isFinite && value == value.truncateToDouble()) {
return true;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index de53658..89098b2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -47,9 +47,6 @@
import '../scope.dart';
-import '../type_inference/type_promotion.dart'
- show TypePromotionFact, TypePromotionScope;
-
import 'body_builder.dart' show noLocation;
import 'constness.dart' show Constness;
@@ -85,6 +82,8 @@
import 'kernel_shadow_ast.dart';
+import '../type_inference/type_inferrer.dart';
+
/// A generator represents a subexpression for which we can't yet build an
/// expression because we don't yet know the context in which it's used.
///
@@ -127,39 +126,14 @@
///
/// The read of this subexpression does _not_ need to support a simultaneous
/// write of the same subexpression.
- Expression buildSimpleRead() {
- return _finish(_makeSimpleRead(), null);
- }
-
- /// Internal implementation for [buildSimpleRead].
- ///
- /// The read of the this subexpression does _not_ need to support a
- /// simultaneous write of the same subexpression.
- ///
- /// This is in contrast to [_makeRead] which is used for instance in compound
- /// assignments like `a.b += c` where both a read and a write of the
- /// subexpression `a.b` occurs.
- ///
- /// Subclasses that can benefit from this distinction should override this
- /// method.
- Expression _makeSimpleRead() => _makeRead(null);
+ Expression buildSimpleRead();
/// Builds a [Expression] representing an assignment with the generator on
/// the LHS and [value] on the RHS.
///
/// The returned expression evaluates to the assigned value, unless
/// [voidContext] is true, in which case it may evaluate to anything.
- Expression buildAssignment(Expression value, {bool voidContext: false}) {
- ComplexAssignmentJudgment complexAssignment = startComplexAssignment(value);
- return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
- complexAssignment);
- }
-
- /// Internal implementation for [buildAssignment].
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- return _makeWrite(value, voidContext, complexAssignment);
- }
+ Expression buildAssignment(Expression value, {bool voidContext: false});
/// Returns a [Expression] representing a null-aware assignment (`??=`) with
/// the generator on the LHS and [value] on the RHS.
@@ -169,31 +143,7 @@
///
/// [type] is the static type of the RHS.
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
- {bool voidContext: false}) {
- ComplexAssignmentJudgment complexAssignment = startComplexAssignment(value);
- if (voidContext) {
- Expression nullAwareCombiner = _forest.createConditionalExpression(
- buildIsNull(_makeRead(complexAssignment), offset, _helper),
- null,
- _makeWrite(value, false, complexAssignment),
- null,
- _forest.createNullLiteral(null)..fileOffset = offset)
- ..fileOffset = offset;
- complexAssignment?.nullAwareCombiner = nullAwareCombiner;
- return _finish(nullAwareCombiner, complexAssignment);
- }
- VariableDeclaration tmp =
- new VariableDeclaration.forValue(_makeRead(complexAssignment));
- Expression nullAwareCombiner = _forest.createConditionalExpression(
- buildIsNull(new VariableGet(tmp), offset, _helper),
- null,
- _makeWrite(value, false, complexAssignment),
- null,
- new VariableGet(tmp))
- ..fileOffset = offset;
- complexAssignment?.nullAwareCombiner = nullAwareCombiner;
- return _finish(makeLet(tmp, nullAwareCombiner), complexAssignment);
- }
+ {bool voidContext: false});
/// Returns a [Expression] representing a compound assignment (e.g. `+=`)
/// with the generator on the LHS and [value] on the RHS.
@@ -202,17 +152,7 @@
bool voidContext: false,
Procedure interfaceTarget,
bool isPreIncDec: false,
- bool isPostIncDec: false}) {
- ComplexAssignmentJudgment complexAssignment = startComplexAssignment(value);
- complexAssignment?.isPreIncDec = isPreIncDec;
- complexAssignment?.isPostIncDec = isPostIncDec;
- Expression combiner = makeBinary(_makeRead(complexAssignment),
- binaryOperator, interfaceTarget, value, _helper,
- offset: offset);
- complexAssignment?.combiner = combiner;
- return _finish(_makeWrite(combiner, voidContext, complexAssignment),
- complexAssignment);
- }
+ bool isPostIncDec: false});
/// Returns a [Expression] representing a pre-increment or pre-decrement of
/// the generator.
@@ -223,6 +163,9 @@
return buildCompoundAssignment(
binaryOperator, _forest.createIntLiteral(1, null)..fileOffset = offset,
offset: offset,
+ // TODO(johnniwinther): We are missing some void contexts here. For
+ // instance `++a?.b;` is not providing a void context making it default
+ // `true`.
voidContext: voidContext,
interfaceTarget: interfaceTarget,
isPreIncDec: true);
@@ -233,43 +176,15 @@
Expression buildPostfixIncrement(Name binaryOperator,
{int offset: TreeNode.noOffset,
bool voidContext: false,
- Procedure interfaceTarget}) {
- if (voidContext) {
- return buildCompoundAssignment(binaryOperator,
- _forest.createIntLiteral(1, null)..fileOffset = offset,
- offset: offset,
- voidContext: voidContext,
- interfaceTarget: interfaceTarget,
- isPostIncDec: true);
- }
- IntLiteral rhs = _forest.createIntLiteral(1, null)..fileOffset = offset;
- ComplexAssignmentJudgment complexAssignment = startComplexAssignment(rhs);
- VariableDeclaration value =
- new VariableDeclaration.forValue(_makeRead(complexAssignment));
- valueAccess() => new VariableGet(value);
- Expression combiner = makeBinary(
- valueAccess(), binaryOperator, interfaceTarget, rhs, _helper,
- offset: offset);
- complexAssignment?.combiner = combiner;
- complexAssignment?.isPostIncDec = true;
- VariableDeclarationImpl dummy = new VariableDeclarationImpl.forValue(
- _makeWrite(combiner, true, complexAssignment));
- return _finish(
- makeLet(value, makeLet(dummy, valueAccess())), complexAssignment);
- }
+ Procedure interfaceTarget});
/// Returns a [Expression] representing a compile-time error.
///
/// At runtime, an exception will be thrown.
Expression _makeInvalidRead() {
- return _helper.wrapSyntheticExpression(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(fileOffset),
- _plainNameForRead,
- _forest.createArgumentsEmpty(noLocation),
- fileOffset,
- isGetter: true),
- fileOffset);
+ return _helper.throwNoSuchMethodError(_forest.createNullLiteral(fileOffset),
+ _plainNameForRead, _forest.createArgumentsEmpty(noLocation), fileOffset,
+ isGetter: true);
}
/// Returns a [Expression] representing a compile-time error wrapping
@@ -277,90 +192,20 @@
///
/// At runtime, [value] will be evaluated before throwing an exception.
Expression _makeInvalidWrite(Expression value) {
- return _helper.wrapSyntheticExpression(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(fileOffset),
- _plainNameForRead,
- _forest.createArguments(noLocation, <Expression>[value]),
- fileOffset,
- isSetter: true),
- fileOffset);
+ return _helper.throwNoSuchMethodError(
+ _forest.createNullLiteral(fileOffset),
+ _plainNameForRead,
+ _forest.createArguments(noLocation, <Expression>[value]),
+ fileOffset,
+ isSetter: true);
}
- /// Returns an [Expression] the reads this subexpression.
- ///
- /// The created read expression must support a simultaneous write of the same
- /// expression with valid semantics.
- ///
- /// For instance in `a.b += c`, both a read and a write of the subexpression
- /// `a.b` is created, but `a` must _not_ be evaluated twice. For this reason
- /// [PropertyAccessGenerator] creates a synthetic local variable for `a` and
- /// uses this for the both the [PropertyGet] and [PropertySet] of property
- /// `b`.
- ///
- /// If [complexAssignment] is provided, the created expression is registered
- /// as the `read` of the complex assignment.
- ///
- /// The default implementation creates the expression through
- /// [_makeInvalidRead]. Subclasses with valid read operations must override
- /// this method with a valid implementation.
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- Expression read = _makeInvalidRead();
- if (complexAssignment != null) {
- read = _helper.desugarSyntheticExpression(read);
- complexAssignment.read = read;
- }
- return read;
- }
-
- /// Returns an [Expression] the write [value] to this subexpression.
- ///
- /// The created read expression must support a simultaneous read of the same
- /// expression with valid semantics.
- ///
- /// For instance in `a.b += c`, both a read and a write of the subexpression
- /// `a.b` is created, but `a` must _not_ be evaluated twice. For this reason
- /// [PropertyAccessGenerator] creates a synthetic local variable for `a` and
- /// uses this for the both the [PropertyGet] and [PropertySet] of property
- /// `b`.
- ///
- /// If [complexAssignment] is provided, the created expression is registered
- /// as the `write` of the complex assignment.
- ///
- /// The default implementation creates the expression through
- /// [_makeInvalidWrite]. Subclasses with valid write operations must override
- /// this method with a valid implementation.
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- Expression write = _makeInvalidWrite(value);
- if (complexAssignment != null) {
- write = _helper.desugarSyntheticExpression(write);
- complexAssignment.write = write;
- }
- return write;
- }
-
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- if (complexAssignment != null) {
- complexAssignment.desugared = body;
- return complexAssignment;
- } else {
- return body;
- }
- }
-
- /// Creates a data structure for tracking the desugaring of a complex
- /// assignment expression whose right hand side is [rhs].
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapIllegalAssignment(rhs);
-
Expression buildForEffect() => buildSimpleRead();
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
return _helper.buildInvalidInitializer(
- _helper.desugarSyntheticExpression(_helper.buildProblem(
- messageInvalidInitializer, fileOffset, lengthForToken(token))),
+ _helper.buildProblem(
+ messageInvalidInitializer, fileOffset, lengthForToken(token)),
fileOffset);
}
@@ -430,16 +275,12 @@
_forest.argumentsSetTypeArguments(
arguments, _helper.buildDartTypeArguments(typeArguments));
}
- return _helper.wrapInvalidConstructorInvocation(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(fileOffset),
- _helper.constructorNameForDiagnostics(name,
- className: _plainNameForRead),
- arguments,
- nameToken.charOffset),
- null,
+ return _helper.throwNoSuchMethodError(
+ _forest.createNullLiteral(fileOffset),
+ _helper.constructorNameForDiagnostics(name,
+ className: _plainNameForRead),
arguments,
- fileOffset);
+ nameToken.charOffset);
}
void printOn(StringSink sink);
@@ -496,17 +337,6 @@
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- TypePromotionFact fact = _helper.typePromoter
- ?.getFactForAccess(variable, _helper.functionNestingLevel);
- TypePromotionScope scope = _helper.typePromoter?.currentScope;
- VariableGetImpl read = new VariableGetImpl(variable, fact, scope)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
- }
-
- @override
Expression buildAssignment(Expression value, {bool voidContext: false}) {
return _createWrite(fileOffset, value);
}
@@ -523,6 +353,16 @@
return write;
}
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ Expression read = _createRead();
+ Expression write = _createWrite(fileOffset, value);
+ return new IfNullSet(read, write, forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
Expression buildCompoundAssignment(Name binaryOperator, Expression value,
{int offset: TreeNode.noOffset,
bool voidContext: false,
@@ -566,25 +406,6 @@
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- _helper.typePromoter
- ?.mutateVariable(variable, _helper.functionNestingLevel);
- Expression write;
- if (variable.isFinal || variable.isConst) {
- write = _makeInvalidWrite(value);
- if (complexAssignment != null) {
- write = _helper.desugarSyntheticExpression(write);
- complexAssignment.write = write;
- }
- } else {
- write = new VariableSet(variable, value)..fileOffset = fileOffset;
- complexAssignment?.write = write;
- }
- return write;
- }
-
- @override
Expression doInvocation(int offset, Arguments arguments) {
return _helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
adjustForImplicitCall(_plainNameForRead, offset),
@@ -592,12 +413,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) {
- return SyntheticWrapper.wrapVariableAssignment(rhs)
- ..fileOffset = fileOffset;
- }
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", variable: ");
@@ -660,10 +475,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapPropertyAssignment(receiver, rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", _receiverVariable: ");
@@ -679,14 +490,14 @@
}
@override
- Expression _makeSimpleRead() {
+ Expression buildSimpleRead() {
return new PropertyGet(receiver, name, getter)..fileOffset = fileOffset;
}
@override
Expression buildAssignment(Expression value, {bool voidContext: false}) {
- return new PropertySet(receiver, name, value, setter)
- ..fileOffset = fileOffset;
+ return _helper.forest.createPropertySet(fileOffset, receiver, name, value,
+ interfaceTarget: setter, forEffect: voidContext);
}
@override
@@ -697,9 +508,9 @@
PropertyGet read = new PropertyGet(
_helper.createVariableGet(variable, receiver.fileOffset), name)
..fileOffset = fileOffset;
- PropertySet write = new PropertySet(
- _helper.createVariableGet(variable, receiver.fileOffset), name, value)
- ..fileOffset = fileOffset;
+ PropertySet write = _helper.forest.createPropertySet(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), name, value,
+ forEffect: voidContext);
return new IfNullPropertySet(variable, read, write, forEffect: voidContext)
..fileOffset = offset;
}
@@ -721,9 +532,9 @@
binaryOperator,
_helper.forest.createArguments(offset, <Expression>[value]),
interfaceTarget: interfaceTarget);
- PropertySet write = new PropertySet(
- _helper.createVariableGet(variable, receiver.fileOffset), name, binary)
- ..fileOffset = fileOffset;
+ PropertySet write = _helper.forest.createPropertySet(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), name, binary,
+ forEffect: voidContext);
return new CompoundPropertySet(variable, write)..fileOffset = offset;
}
@@ -756,46 +567,15 @@
VariableDeclaration write = _helper.forest
.createVariableDeclarationForValue(
offset,
- new PropertySet(
+ _helper.forest.createPropertySet(
+ fileOffset,
_helper.createVariableGet(variable, receiver.fileOffset),
name,
- binary)
- ..fileOffset = fileOffset);
+ binary,
+ forEffect: true));
return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
}
- @override
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- PropertySet write = new PropertySet(receiver, name, value, setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- PropertyGet read = new PropertyGet(receiverAccess(), name, getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
- }
-
- @override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- PropertySet write = new PropertySet(receiverAccess(), name, value, setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- return super._finish(makeLet(_receiverVariable, body), complexAssignment);
- }
-
/// Creates a [Generator] for the access of property [name] on [receiver].
static Generator make(
ExpressionGeneratorHelper helper,
@@ -884,81 +664,91 @@
}
Expression _createRead() {
- if (getter == null) {
- _helper.warnUnresolvedGet(name, fileOffset);
- }
- return new PropertyGet(_forest.createThisExpression(token), name, getter)
+ return new PropertyGet(
+ _forest.createThisExpression(fileOffset), name, getter)
..fileOffset = fileOffset;
}
@override
Expression buildAssignment(Expression value, {bool voidContext: false}) {
- return _createWrite(fileOffset, value);
+ return _createWrite(fileOffset, value, forEffect: voidContext);
}
- Expression _createWrite(int offset, Expression value) {
- if (setter == null) {
- _helper.warnUnresolvedSet(name, fileOffset);
- }
- return new PropertySet(
- _forest.createThisExpression(token), name, value, setter)
- ..fileOffset = fileOffset;
+ Expression _createWrite(int offset, Expression value, {bool forEffect}) {
+ return _helper.forest.createPropertySet(
+ fileOffset, _forest.createThisExpression(fileOffset), name, value,
+ interfaceTarget: setter, forEffect: forEffect);
}
@override
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
- return new IfNullSet(_createRead(), _createWrite(offset, value),
+ return new IfNullSet(
+ _createRead(), _createWrite(offset, value, forEffect: voidContext),
forEffect: voidContext)
..fileOffset = offset;
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- if (getter == null) {
- _helper.warnUnresolvedGet(name, fileOffset);
- }
- PropertyGet read =
- new PropertyGet(_forest.createThisExpression(token), name, getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ new PropertyGet(_forest.createThisExpression(fileOffset), name)
+ ..fileOffset = fileOffset,
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _createWrite(fileOffset, binary, forEffect: voidContext);
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (setter == null) {
- _helper.warnUnresolvedSet(name, fileOffset);
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
}
- PropertySet write = new PropertySet(
- _forest.createThisExpression(token), name, value, setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
+ VariableDeclaration read = _helper.forest.createVariableDeclarationForValue(
+ fileOffset,
+ new PropertyGet(_forest.createThisExpression(fileOffset), name)
+ ..fileOffset = fileOffset);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset, _createWrite(fileOffset, binary, forEffect: true));
+ return new PropertyPostIncDec.onReadOnly(read, write)..fileOffset = offset;
}
@override
Expression doInvocation(int offset, Arguments arguments) {
Member interfaceTarget = getter;
- if (interfaceTarget == null) {
- _helper.warnUnresolvedMethod(name, offset);
- }
if (interfaceTarget is Field) {
// TODO(ahe): In strong mode we should probably rewrite this to
// `this.name.call(arguments)`.
interfaceTarget = null;
}
return _helper.buildMethodInvocation(
- _forest.createThisExpression(null), name, arguments, offset,
+ _forest.createThisExpression(fileOffset), name, arguments, offset,
interfaceTarget: interfaceTarget);
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapPropertyAssignment(null, rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", name: ");
@@ -1020,51 +810,52 @@
VariableDeclaration variable = _helper.forest
.createVariableDeclarationForValue(
receiverExpression.fileOffset, receiverExpression);
- PropertySet read = new PropertySet(
+ PropertySet read = _helper.forest.createPropertySet(
+ fileOffset,
_helper.createVariableGet(variable, receiverExpression.fileOffset),
name,
- value)
- ..fileOffset = fileOffset;
+ value,
+ forEffect: voidContext,
+ readOnlyReceiver: true);
return new NullAwarePropertySet(variable, read)
..fileOffset = receiverExpression.fileOffset;
}
- @override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- PropertyGet read = new PropertyGet(receiverAccess(), name, getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new NullAwareIfNullSet(receiverExpression, name, value,
+ forEffect: voidContext,
+ readOffset: fileOffset,
+ testOffset: offset,
+ writeOffset: fileOffset)
+ ..fileOffset = offset;
}
- @override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- PropertySet write = new PropertySet(receiverAccess(), name, value, setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return new NullAwareCompoundSet(
+ receiverExpression, name, binaryOperator, value,
+ readOffset: fileOffset,
+ binaryOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext,
+ forPostIncDec: isPostIncDec);
}
- @override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- Expression nullAwareGuard = _forest.createConditionalExpression(
- buildIsNull(receiverAccess(), fileOffset, _helper),
- null,
- _forest.createNullLiteral(null)..fileOffset = fileOffset,
- null,
- body)
- ..fileOffset = fileOffset;
- if (complexAssignment != null) {
- body = makeLet(receiver, nullAwareGuard);
- PropertyAssignmentJudgment kernelPropertyAssign = complexAssignment;
- kernelPropertyAssign.nullAwareGuard = nullAwareGuard;
- kernelPropertyAssign.desugared = body;
- return kernelPropertyAssign;
- } else {
- return unhandled('${runtimeType}', "_finish", fileOffset, _uri);
- }
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return buildCompoundAssignment(
+ binaryOperator, _forest.createIntLiteral(1, null)..fileOffset = offset,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
}
@override
@@ -1073,10 +864,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapPropertyAssignment(receiverExpression, rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", receiver: ");
@@ -1124,18 +911,6 @@
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- if (getter == null) {
- _helper.warnUnresolvedGet(name, fileOffset, isSuper: true);
- }
- // TODO(ahe): Use [DirectPropertyGet] when possible.
- SuperPropertyGet read = new SuperPropertyGet(name, getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
- }
-
- @override
Expression buildAssignment(Expression value, {bool voidContext = false}) {
return _createWrite(fileOffset, value);
}
@@ -1201,19 +976,6 @@
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (setter == null) {
- _helper.warnUnresolvedSet(name, fileOffset, isSuper: true);
- }
- // TODO(ahe): Use [DirectPropertySet] when possible.
- SuperPropertySet write = new SuperPropertySet(name, value, setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
Expression doInvocation(int offset, Arguments arguments) {
if (_helper.constantContext != ConstantContext.none) {
// TODO(brianwilkerson) Fix the length
@@ -1234,10 +996,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapPropertyAssignment(null, rhs, isSuper: true);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", name: ");
@@ -1258,10 +1016,6 @@
final Procedure setter;
- VariableDeclaration receiverVariable;
-
- VariableDeclaration indexVariable;
-
IndexedAccessGenerator(ExpressionGeneratorHelper helper, Token token,
this.receiver, this.index, this.getter, this.setter)
: super(helper, token);
@@ -1276,7 +1030,7 @@
Expression buildSimpleRead() {
return _helper.buildMethodInvocation(
receiver,
- new Name('[]'),
+ indexGetName,
_helper.forest.createArguments(fileOffset, <Expression>[index]),
fileOffset,
interfaceTarget: getter);
@@ -1287,7 +1041,7 @@
if (voidContext) {
return _helper.buildMethodInvocation(
receiver,
- new Name('[]='),
+ indexSetName,
_helper.forest
.createArguments(fileOffset, <Expression>[index, value]),
fileOffset,
@@ -1300,7 +1054,10 @@
@override
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
{bool voidContext: false}) {
- return new IfNullIndexSet(receiver, index, value, fileOffset,
+ return new IfNullIndexSet(receiver, index, value,
+ readOffset: fileOffset,
+ testOffset: offset,
+ writeOffset: fileOffset,
forEffect: voidContext)
..fileOffset = offset;
}
@@ -1332,97 +1089,6 @@
isPostIncDec: true);
}
- Expression indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable)..fileOffset = fileOffset;
- }
-
- Expression receiverAccess() {
- // We cannot reuse the receiver if it is a variable since it might be
- // reassigned in the index expression.
- receiverVariable ??= new VariableDeclaration.forValue(receiver);
- return new VariableGet(receiverVariable)..fileOffset = fileOffset;
- }
-
- @override
- Expression _makeSimpleRead() {
- MethodInvocationImpl read = new MethodInvocationImpl(receiver, indexGetName,
- _forest.createArguments(fileOffset, <Expression>[index]),
- interfaceTarget: getter)
- ..fileOffset = fileOffset;
- return read;
- }
-
- @override
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationImpl write = new MethodInvocationImpl(
- receiver,
- indexSetName,
- _forest.createArguments(fileOffset, <Expression>[index, value]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- MethodInvocationImpl read = new MethodInvocationImpl(
- receiverAccess(),
- indexGetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess()]),
- interfaceTarget: getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
- }
-
- @override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationImpl write = new MethodInvocationImpl(
- receiverAccess(),
- indexSetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess(), value]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- // TODO(dmitryas): remove this method after the "[]=" operator of the Context
- // class is made to return a value.
- Expression _makeWriteAndReturn(
- Expression value, ComplexAssignmentJudgment complexAssignment) {
- // The call to []= does not return the value like direct-style assignments
- // do. We need to bind the value in a let.
- VariableDeclaration valueVariable = new VariableDeclaration.forValue(value);
- MethodInvocationImpl write = new MethodInvocationImpl(
- receiverAccess(),
- indexSetName,
- _forest.createArguments(fileOffset,
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- VariableDeclarationImpl dummy = new VariableDeclarationImpl.forValue(write);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
- @override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- return super._finish(
- makeLet(receiverVariable,
- makeLet(indexVariable, body)..fileOffset = fileOffset)
- ..fileOffset = fileOffset,
- complexAssignment);
- }
-
@override
Expression doInvocation(int offset, Arguments arguments) {
return _helper.buildMethodInvocation(
@@ -1431,10 +1097,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapIndexAssignment(receiver, index, rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", receiver: ");
@@ -1445,10 +1107,6 @@
printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
sink.write(", setter: ");
printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
- sink.write(", receiverVariable: ");
- printNodeOn(receiverVariable, sink, syntheticNames: syntheticNames);
- sink.write(", indexVariable: ");
- printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
}
static Generator make(
@@ -1477,8 +1135,6 @@
final Procedure setter;
- VariableDeclaration indexVariable;
-
ThisIndexedAccessGenerator(ExpressionGeneratorHelper helper, Token token,
this.index, this.getter, this.setter)
: super(helper, token);
@@ -1489,79 +1145,73 @@
@override
String get _debugName => "ThisIndexedAccessGenerator";
- Expression indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- Expression _makeWriteAndReturn(
- Expression value, ComplexAssignmentJudgment complexAssignment) {
- VariableDeclaration valueVariable = new VariableDeclaration.forValue(value);
- MethodInvocationImpl write = new MethodInvocationImpl(
- _forest.createThisExpression(token),
- indexSetName,
- _forest.createArguments(fileOffset,
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- VariableDeclaration dummy = new VariableDeclaration.forValue(write);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
@override
- Expression _makeSimpleRead() {
- return new MethodInvocationImpl(_forest.createThisExpression(token),
- indexGetName, _forest.createArguments(fileOffset, <Expression>[index]),
- interfaceTarget: getter)
- ..fileOffset = fileOffset;
- }
-
- @override
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationImpl write = new MethodInvocationImpl(
- _forest.createThisExpression(token),
- indexSetName,
- _forest.createArguments(fileOffset, <Expression>[index, value]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- MethodInvocationImpl read = new MethodInvocationImpl(
- _forest.createThisExpression(token),
+ Expression buildSimpleRead() {
+ Expression receiver = _helper.forest.createThisExpression(fileOffset);
+ return _helper.buildMethodInvocation(
+ receiver,
indexGetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess()]),
- interfaceTarget: getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
+ _helper.forest.createArguments(fileOffset, <Expression>[index]),
+ fileOffset,
+ interfaceTarget: getter);
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- MethodInvocationImpl write = new MethodInvocationImpl(
- _forest.createThisExpression(token),
- indexSetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess(), value]),
- interfaceTarget: setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ Expression receiver = _helper.forest.createThisExpression(fileOffset);
+ if (voidContext) {
+ return _helper.buildMethodInvocation(
+ receiver,
+ indexSetName,
+ _helper.forest
+ .createArguments(fileOffset, <Expression>[index, value]),
+ fileOffset,
+ interfaceTarget: setter);
+ } else {
+ return new IndexSet(receiver, index, value)..fileOffset = fileOffset;
+ }
}
@override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- return super._finish(makeLet(indexVariable, body), complexAssignment);
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ Expression receiver = _helper.forest.createThisExpression(fileOffset);
+ return new IfNullIndexSet(receiver, index, value,
+ readOffset: fileOffset,
+ testOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext,
+ readOnlyReceiver: true)
+ ..fileOffset = offset;
+ }
+
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ Expression receiver = _helper.forest.createThisExpression(fileOffset);
+ return new CompoundIndexSet(receiver, index, binaryOperator, value,
+ readOffset: fileOffset,
+ binaryOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext,
+ forPostIncDec: isPostIncDec,
+ readOnlyReceiver: true);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
}
@override
@@ -1572,10 +1222,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapIndexAssignment(null, index, rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", index: ");
@@ -1584,8 +1230,6 @@
printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
sink.write(", setter: ");
printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
- sink.write(", indexVariable: ");
- printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
}
}
@@ -1596,8 +1240,6 @@
final Member setter;
- VariableDeclaration indexVariable;
-
SuperIndexedAccessGenerator(ExpressionGeneratorHelper helper, Token token,
this.index, this.getter, this.setter)
: super(helper, token);
@@ -1606,89 +1248,72 @@
String get _debugName => "SuperIndexedAccessGenerator";
- Expression indexAccess() {
- indexVariable ??= new VariableDeclaration.forValue(index);
- return new VariableGet(indexVariable);
- }
-
- Expression _makeWriteAndReturn(
- Expression value, ComplexAssignmentJudgment complexAssignment) {
- VariableDeclaration valueVariable = new VariableDeclaration.forValue(value);
- if (setter == null) {
- _helper.warnUnresolvedMethod(indexSetName, fileOffset, isSuper: true);
- }
- SuperMethodInvocation write = new SuperMethodInvocation(
- indexSetName,
- _forest.createArguments(fileOffset,
- <Expression>[indexAccess(), new VariableGet(valueVariable)]),
- setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- VariableDeclaration dummy = new VariableDeclaration.forValue(write);
- return makeLet(
- valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
- }
-
@override
- Expression _makeSimpleRead() {
+ Expression buildSimpleRead() {
if (getter == null) {
_helper.warnUnresolvedMethod(indexGetName, fileOffset, isSuper: true);
}
- // TODO(ahe): Use [DirectMethodInvocation] when possible.
- return new SuperMethodInvocation(indexGetName,
- _forest.createArguments(fileOffset, <Expression>[index]), getter)
- ..fileOffset = fileOffset;
- }
-
- @override
- Expression _makeSimpleWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- if (setter == null) {
- _helper.warnUnresolvedMethod(indexSetName, fileOffset, isSuper: true);
- }
- SuperMethodInvocation write = new SuperMethodInvocation(indexSetName,
- _forest.createArguments(fileOffset, <Expression>[index, value]), setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
- }
-
- @override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- if (getter == null) {
- _helper.warnUnresolvedMethod(indexGetName, fileOffset, isSuper: true);
- }
- SuperMethodInvocation read = new SuperMethodInvocation(
+ return _helper.forest.createSuperMethodInvocation(
+ fileOffset,
indexGetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess()]),
- getter)
- ..fileOffset = fileOffset;
- complexAssignment?.read = read;
- return read;
+ getter,
+ _helper.forest.createArguments(fileOffset, <Expression>[index]));
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
- if (setter == null) {
- _helper.warnUnresolvedMethod(indexSetName, fileOffset, isSuper: true);
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ if (voidContext) {
+ if (setter == null) {
+ _helper.warnUnresolvedMethod(indexSetName, fileOffset, isSuper: true);
+ }
+ return _helper.forest.createSuperMethodInvocation(
+ fileOffset,
+ indexSetName,
+ setter,
+ _helper.forest
+ .createArguments(fileOffset, <Expression>[index, value]));
+ } else {
+ return new SuperIndexSet(setter, index, value)..fileOffset = fileOffset;
}
- SuperMethodInvocation write = new SuperMethodInvocation(
- indexSetName,
- _forest.createArguments(fileOffset, <Expression>[indexAccess(), value]),
- setter)
- ..fileOffset = fileOffset;
- complexAssignment?.write = write;
- return write;
}
@override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) {
- return super._finish(makeLet(indexVariable, body)..fileOffset = fileOffset,
- complexAssignment);
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullSuperIndexSet(getter, setter, index, value,
+ readOffset: fileOffset,
+ testOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return new CompoundSuperIndexSet(
+ getter, setter, index, binaryOperator, value,
+ readOffset: fileOffset,
+ binaryOffset: offset,
+ writeOffset: fileOffset,
+ forEffect: voidContext,
+ forPostIncDec: isPostIncDec);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
}
@override
@@ -1699,10 +1324,6 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapIndexAssignment(null, index, rhs, isSuper: true);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
sink.write(", index: ");
@@ -1711,8 +1332,6 @@
printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
sink.write(", setter: ");
printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
- sink.write(", indexVariable: ");
- printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
}
}
@@ -1749,6 +1368,9 @@
/// }
///
class StaticAccessGenerator extends Generator {
+ /// The name of the original target;
+ final String targetName;
+
/// The static [Member] used for performing a read or invocation on this
/// subexpression.
///
@@ -1765,12 +1387,17 @@
final Member writeTarget;
StaticAccessGenerator(ExpressionGeneratorHelper helper, Token token,
- this.readTarget, this.writeTarget)
- : assert(readTarget != null || writeTarget != null),
+ this.targetName, this.readTarget, this.writeTarget)
+ : assert(targetName != null),
+ assert(readTarget != null || writeTarget != null),
super(helper, token);
- factory StaticAccessGenerator.fromBuilder(ExpressionGeneratorHelper helper,
- Builder declaration, Token token, Builder builderSetter) {
+ factory StaticAccessGenerator.fromBuilder(
+ ExpressionGeneratorHelper helper,
+ String targetName,
+ Builder declaration,
+ Token token,
+ Builder builderSetter) {
if (declaration is AccessErrorBuilder) {
AccessErrorBuilder error = declaration;
declaration = error.builder;
@@ -1791,14 +1418,14 @@
setter = builderSetter.target;
}
}
- return new StaticAccessGenerator(helper, token, getter, setter);
+ return new StaticAccessGenerator(helper, token, targetName, getter, setter);
}
@override
String get _debugName => "StaticAccessGenerator";
@override
- String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
+ String get _plainNameForRead => targetName;
@override
Expression buildSimpleRead() {
@@ -1882,38 +1509,6 @@
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- Expression read;
- if (readTarget == null) {
- read = _makeInvalidRead();
- if (complexAssignment != null) {
- read = _helper.desugarSyntheticExpression(read);
- }
- } else {
- read = _helper.makeStaticGet(readTarget, token);
- }
- complexAssignment?.read = read;
- return read;
- }
-
- @override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
- Expression write;
- if (writeTarget == null) {
- write = _makeInvalidWrite(value);
- if (complexAssignment != null) {
- write = _helper.desugarSyntheticExpression(write);
- }
- } else {
- write = new StaticSet(writeTarget, value);
- }
- complexAssignment?.write = write;
- write.fileOffset = fileOffset;
- return write;
- }
-
- @override
Expression doInvocation(int offset, Arguments arguments) {
if (_helper.constantContext != ConstantContext.none &&
!_helper.isIdentical(readTarget)) {
@@ -1936,12 +1531,10 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapStaticAssignment(rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
+ sink.write(", targetName: ");
+ sink.write(targetName);
sink.write(", readTarget: ");
printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
sink.write(", writeTarget: ");
@@ -1968,6 +1561,9 @@
///
/// These can only occur within an extension instance member.
class ExtensionInstanceAccessGenerator extends Generator {
+ /// The original name of the target.
+ final String targetName;
+
/// The static [Member] generated for an instance extension member which is
/// used for performing a read on this subexpression.
///
@@ -2004,17 +1600,20 @@
ExtensionInstanceAccessGenerator(
ExpressionGeneratorHelper helper,
Token token,
+ this.targetName,
this.readTarget,
this.invokeTarget,
this.writeTarget,
this.extensionThis,
this.extensionTypeParameters)
- : assert(readTarget != null || writeTarget != null),
+ : assert(targetName != null),
+ assert(readTarget != null || writeTarget != null),
assert(extensionThis != null),
super(helper, token);
factory ExtensionInstanceAccessGenerator.fromBuilder(
ExpressionGeneratorHelper helper,
+ String targetName,
VariableDeclaration extensionThis,
List<TypeParameter> extensionTypeParameters,
Builder declaration,
@@ -2046,15 +1645,22 @@
if (builderSetter != null && builderSetter.isSetter) {
writeTarget = builderSetter.target;
}
- return new ExtensionInstanceAccessGenerator(helper, token, readTarget,
- invokeTarget, writeTarget, extensionThis, extensionTypeParameters);
+ return new ExtensionInstanceAccessGenerator(
+ helper,
+ token,
+ targetName,
+ readTarget,
+ invokeTarget,
+ writeTarget,
+ extensionThis,
+ extensionTypeParameters);
}
@override
String get _debugName => "InstanceExtensionAccessGenerator";
@override
- String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
+ String get _plainNameForRead => targetName;
int get _extensionTypeParameterCount => extensionTypeParameters?.length ?? 0;
@@ -2071,13 +1677,14 @@
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
+ Expression buildSimpleRead() {
+ return _createRead();
+ }
+
+ Expression _createRead() {
Expression read;
if (readTarget == null) {
read = _makeInvalidRead();
- if (complexAssignment != null) {
- read = _helper.desugarSyntheticExpression(read);
- }
} else {
read = _helper.buildExtensionMethodInvocation(
fileOffset,
@@ -2089,37 +1696,84 @@
_helper.createVariableGet(extensionThis, fileOffset),
extensionTypeArguments: _createExtensionTypeArguments()));
}
- complexAssignment?.read = read;
return read;
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _createWrite(fileOffset, value, forEffect: voidContext);
+ }
+
+ Expression _createWrite(int offset, Expression value, {bool forEffect}) {
Expression write;
if (writeTarget == null) {
write = _makeInvalidWrite(value);
- if (complexAssignment != null) {
- write = _helper.desugarSyntheticExpression(write);
- }
} else {
- write = _helper.buildExtensionMethodInvocation(
- fileOffset,
- writeTarget,
- _helper.forest.createArgumentsForExtensionMethod(
- fileOffset,
- _extensionTypeParameterCount,
- 0,
- _helper.createVariableGet(extensionThis, fileOffset),
- extensionTypeArguments: _createExtensionTypeArguments(),
- positionalArguments: [value]));
+ write = new ExtensionSet(
+ _helper.createVariableGet(extensionThis, fileOffset),
+ new ExtensionAccessTarget(writeTarget, null, ProcedureKind.Setter,
+ _createExtensionTypeArguments()),
+ value,
+ forEffect: forEffect,
+ readOnlyReceiver: true);
}
- complexAssignment?.write = write;
- write.fileOffset = fileOffset;
+ write.fileOffset = offset;
return write;
}
@override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return new IfNullSet(
+ _createRead(), _createWrite(fileOffset, value, forEffect: voidContext),
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _createWrite(fileOffset, binary, forEffect: voidContext);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(fileOffset, _createRead());
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset, _createWrite(fileOffset, binary, forEffect: true));
+ return new PropertyPostIncDec.onReadOnly(read, write)..fileOffset = offset;
+ }
+
+ @override
Expression doInvocation(int offset, Arguments arguments) {
if (invokeTarget != null) {
return _helper.buildExtensionMethodInvocation(
@@ -2143,12 +1797,10 @@
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapStaticAssignment(rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
+ sink.write(", targetName: ");
+ sink.write(targetName);
sink.write(", readTarget: ");
printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
sink.write(", writeTarget: ");
@@ -2178,6 +1830,9 @@
/// }
///
class ExplicitExtensionInstanceAccessGenerator extends Generator {
+ /// The name of the original target;
+ final String targetName;
+
/// The static [Member] generated for an instance extension member which is
/// used for performing a read on this subexpression.
///
@@ -2209,19 +1864,27 @@
/// like `<int>` in `Extension<int>(a).method<String>()`.
final List<DartType> explicitTypeArguments;
+ /// The number of type parameters declared on the extension declaration.
final int extensionTypeParameterCount;
+ /// If `true` the access is null-aware, like `Extension(c)?.foo`.
+ final bool isNullAware;
+
ExplicitExtensionInstanceAccessGenerator(
ExpressionGeneratorHelper helper,
Token token,
+ this.targetName,
this.readTarget,
this.invokeTarget,
this.writeTarget,
this.receiver,
this.explicitTypeArguments,
- this.extensionTypeParameterCount)
- : assert(readTarget != null || writeTarget != null),
+ this.extensionTypeParameterCount,
+ {this.isNullAware})
+ : assert(targetName != null),
+ assert(readTarget != null || writeTarget != null),
assert(receiver != null),
+ assert(isNullAware != null),
super(helper, token);
factory ExplicitExtensionInstanceAccessGenerator.fromBuilder(
@@ -2231,7 +1894,9 @@
Builder setterBuilder,
Expression receiver,
List<DartType> explicitTypeArguments,
- int extensionTypeParameterCount) {
+ int extensionTypeParameterCount,
+ {bool isNullAware}) {
+ String targetName;
Procedure readTarget;
Procedure invokeTarget;
if (getterBuilder != null) {
@@ -2242,11 +1907,14 @@
// when not explicitly looking for a setter.
assert(getterBuilder.isSetter);
} else if (getterBuilder.isGetter) {
- readTarget = getterBuilder.target;
+ MemberBuilder memberBuilder = getterBuilder;
+ readTarget = memberBuilder.member;
+ targetName = memberBuilder.name;
} else if (getterBuilder.isRegularMethod) {
MemberBuilder procedureBuilder = getterBuilder;
readTarget = procedureBuilder.extensionTearOff;
invokeTarget = procedureBuilder.procedure;
+ targetName = procedureBuilder.name;
} else {
return unhandled(
"${getterBuilder.runtimeType}",
@@ -2256,38 +1924,53 @@
}
}
Procedure writeTarget;
- if (setterBuilder != null && setterBuilder.isSetter) {
- writeTarget = setterBuilder.target;
+ if (setterBuilder is AccessErrorBuilder) {
+ targetName ??= setterBuilder.name;
+ } else if (setterBuilder != null && setterBuilder.isSetter) {
+ MemberBuilder memberBuilder = setterBuilder;
+ writeTarget = memberBuilder.member;
+ targetName ??= memberBuilder.name;
}
return new ExplicitExtensionInstanceAccessGenerator(
helper,
token,
+ targetName,
readTarget,
invokeTarget,
writeTarget,
receiver,
explicitTypeArguments,
- extensionTypeParameterCount);
+ extensionTypeParameterCount,
+ isNullAware: isNullAware);
}
@override
String get _debugName => "InstanceExtensionAccessGenerator";
@override
- String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
+ String get _plainNameForRead => targetName;
List<DartType> _createExtensionTypeArguments() {
return explicitTypeArguments ?? const <DartType>[];
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
+ Expression buildSimpleRead() {
+ if (isNullAware) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ return new NullAwareExtension(variable,
+ _createRead(_helper.createVariableGet(variable, variable.fileOffset)))
+ ..fileOffset = fileOffset;
+ } else {
+ return _createRead(receiver);
+ }
+ }
+
+ Expression _createRead(Expression receiver) {
Expression read;
if (readTarget == null) {
read = _makeInvalidRead();
- if (complexAssignment != null) {
- read = _helper.desugarSyntheticExpression(read);
- }
} else {
read = _helper.buildExtensionMethodInvocation(
fileOffset,
@@ -2296,37 +1979,190 @@
fileOffset, extensionTypeParameterCount, 0, receiver,
extensionTypeArguments: _createExtensionTypeArguments()));
}
- complexAssignment?.read = read;
return read;
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ if (isNullAware) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ return new NullAwareExtension(
+ variable,
+ _createWrite(fileOffset,
+ _helper.createVariableGet(variable, variable.fileOffset), value,
+ forEffect: voidContext, readOnlyReceiver: true))
+ ..fileOffset = fileOffset;
+ } else {
+ return _createWrite(fileOffset, receiver, value,
+ forEffect: voidContext, readOnlyReceiver: false);
+ }
+ }
+
+ Expression _createWrite(int offset, Expression receiver, Expression value,
+ {bool readOnlyReceiver, bool forEffect}) {
Expression write;
if (writeTarget == null) {
write = _makeInvalidWrite(value);
- if (complexAssignment != null) {
- write = _helper.desugarSyntheticExpression(write);
- }
} else {
- write = _helper.buildExtensionMethodInvocation(
- fileOffset,
- writeTarget,
- _helper.forest.createArgumentsForExtensionMethod(
- fileOffset, extensionTypeParameterCount, 0, receiver,
- extensionTypeArguments: _createExtensionTypeArguments(),
- positionalArguments: [value]));
+ write = new ExtensionSet(
+ receiver,
+ new ExtensionAccessTarget(writeTarget, null, ProcedureKind.Setter,
+ _createExtensionTypeArguments()),
+ value,
+ readOnlyReceiver: readOnlyReceiver,
+ forEffect: forEffect);
}
- complexAssignment?.write = write;
- write.fileOffset = fileOffset;
+ write.fileOffset = offset;
return write;
}
@override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ if (isNullAware) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ Expression read =
+ _createRead(_helper.createVariableGet(variable, receiver.fileOffset));
+ Expression write = _createWrite(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), value,
+ forEffect: voidContext, readOnlyReceiver: true);
+ return new NullAwareExtension(
+ variable,
+ new IfNullSet(read, write, forEffect: voidContext)
+ ..fileOffset = offset)
+ ..fileOffset = fileOffset;
+ } else {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ Expression read =
+ _createRead(_helper.createVariableGet(variable, receiver.fileOffset));
+ Expression write = _createWrite(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), value,
+ forEffect: voidContext, readOnlyReceiver: true);
+ return new IfNullPropertySet(variable, read, write,
+ forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ if (isNullAware) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(_helper.createVariableGet(variable, receiver.fileOffset)),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ Expression write = _createWrite(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), binary,
+ forEffect: voidContext, readOnlyReceiver: true);
+ return new NullAwareExtension(variable, write)..fileOffset = offset;
+ } else {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _createRead(_helper.createVariableGet(variable, receiver.fileOffset)),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ Expression write = _createWrite(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), binary,
+ forEffect: voidContext, readOnlyReceiver: true);
+ return new CompoundPropertySet(variable, write)..fileOffset = offset;
+ }
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ } else if (isNullAware) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(
+ fileOffset,
+ _createRead(
+ _helper.createVariableGet(variable, receiver.fileOffset)));
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset,
+ _createWrite(
+ fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset),
+ binary,
+ forEffect: voidContext,
+ readOnlyReceiver: true)
+ ..fileOffset = fileOffset);
+ return new NullAwareExtension(
+ variable, new LocalPostIncDec(read, write)..fileOffset = offset)
+ ..fileOffset = fileOffset;
+ } else {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ VariableDeclaration read = _helper.forest
+ .createVariableDeclarationForValue(
+ fileOffset,
+ _createRead(
+ _helper.createVariableGet(variable, receiver.fileOffset)));
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset,
+ _createWrite(
+ fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset),
+ binary,
+ forEffect: voidContext,
+ readOnlyReceiver: true)
+ ..fileOffset = fileOffset);
+ return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
+ }
+ }
+
+ @override
Expression doInvocation(int offset, Arguments arguments) {
+ VariableDeclaration receiverVariable;
+ Expression receiverExpression = receiver;
+ if (isNullAware) {
+ receiverVariable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ receiverExpression = _helper.createVariableGet(
+ receiverVariable, receiverVariable.fileOffset);
+ }
+ Expression invocation;
if (invokeTarget != null) {
- return _helper.buildExtensionMethodInvocation(
+ invocation = _helper.buildExtensionMethodInvocation(
fileOffset,
invokeTarget,
_forest.createArgumentsForExtensionMethod(
@@ -2334,25 +2170,33 @@
extensionTypeParameterCount,
invokeTarget.function.typeParameters.length -
extensionTypeParameterCount,
- receiver,
+ receiverExpression,
extensionTypeArguments: _createExtensionTypeArguments(),
typeArguments: arguments.types,
positionalArguments: arguments.positional,
namedArguments: arguments.named));
} else {
- return _helper.buildMethodInvocation(buildSimpleRead(), callName,
- arguments, adjustForImplicitCall(_plainNameForRead, offset),
+ invocation = _helper.buildMethodInvocation(
+ _createRead(receiverExpression),
+ callName,
+ arguments,
+ adjustForImplicitCall(_plainNameForRead, offset),
isImplicitCall: true);
}
+ if (isNullAware) {
+ assert(receiverVariable != null);
+ return new NullAwareExtension(receiverVariable, invocation)
+ ..fileOffset = fileOffset;
+ } else {
+ return invocation;
+ }
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapStaticAssignment(rhs);
-
- @override
void printOn(StringSink sink) {
NameSystem syntheticNames = new NameSystem();
+ sink.write(", targetName: ");
+ sink.write(targetName);
sink.write(", readTarget: ");
printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
sink.write(", writeTarget: ");
@@ -2405,6 +2249,38 @@
@override
String get _debugName => "ExplicitExtensionAccessGenerator";
+ @override
+ Expression buildSimpleRead() {
+ return _makeInvalidRead();
+ }
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return _makeInvalidRead();
+ }
+
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return _makeInvalidRead();
+ }
+
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return _makeInvalidRead();
+ }
+
/* Expression | Generator */ buildPropertyAccess(
IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
if (_helper.constantContext != ConstantContext.none) {
@@ -2425,7 +2301,8 @@
setter,
receiver,
explicitTypeArguments,
- extensionBuilder.typeParameters?.length ?? 0);
+ extensionBuilder.typeParameters?.length ?? 0,
+ isNullAware: isNullAware);
if (send.arguments != null) {
return generator.doInvocation(offsetForToken(send.token), send.arguments);
} else {
@@ -2440,6 +2317,18 @@
}
@override
+ Expression _makeInvalidRead() {
+ return _helper.buildProblem(messageExplicitExtensionAsExpression,
+ fileOffset, lengthForToken(token));
+ }
+
+ @override
+ Expression _makeInvalidWrite(Expression value) {
+ return _helper.buildProblem(
+ messageExplicitExtensionAsLvalue, fileOffset, lengthForToken(token));
+ }
+
+ @override
void printOn(StringSink sink) {
sink.write(", extensionBuilder: ");
sink.write(extensionBuilder);
@@ -2462,16 +2351,58 @@
String get _debugName => "LoadLibraryGenerator";
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
+ Expression buildSimpleRead() {
builder.importDependency.targetLibrary;
LoadLibraryTearOff read = new LoadLibraryTearOff(
builder.importDependency, builder.createTearoffMethod(_helper.forest))
..fileOffset = fileOffset;
- complexAssignment?.read = read;
return read;
}
@override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ Expression read = buildSimpleRead();
+ Expression write = _makeInvalidWrite(value);
+ return new IfNullSet(read, write, forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ buildSimpleRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _makeInvalidWrite(binary);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+
+ @override
Expression doInvocation(int offset, Arguments arguments) {
if (_forest.argumentsPositional(arguments).length > 0 ||
_forest.argumentsNamed(arguments).length > 0) {
@@ -2498,31 +2429,60 @@
: super(helper, token);
@override
- Expression _makeSimpleRead() {
- return _helper.wrapInDeferredCheck(suffixGenerator._makeSimpleRead(),
+ Expression buildSimpleRead() {
+ return _helper.wrapInDeferredCheck(suffixGenerator.buildSimpleRead(),
prefixGenerator.prefix, token.charOffset);
}
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
return _helper.wrapInDeferredCheck(
- suffixGenerator._makeRead(complexAssignment),
+ suffixGenerator.buildAssignment(value, voidContext: voidContext),
prefixGenerator.prefix,
token.charOffset);
}
@override
- Expression _makeWrite(Expression value, bool voidContext,
- ComplexAssignmentJudgment complexAssignment) {
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
return _helper.wrapInDeferredCheck(
- suffixGenerator._makeWrite(value, voidContext, complexAssignment),
+ suffixGenerator.buildIfNullAssignment(value, type, offset,
+ voidContext: voidContext),
prefixGenerator.prefix,
token.charOffset);
}
@override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
- SyntheticWrapper.wrapStaticAssignment(rhs);
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return _helper.wrapInDeferredCheck(
+ suffixGenerator.buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPreIncDec: isPreIncDec,
+ isPostIncDec: isPostIncDec),
+ prefixGenerator.prefix,
+ token.charOffset);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return _helper.wrapInDeferredCheck(
+ suffixGenerator.buildPostfixIncrement(binaryOperator,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget),
+ prefixGenerator.prefix,
+ token.charOffset);
+ }
@override
buildPropertyAccess(
@@ -2630,8 +2590,8 @@
final TypeDeclarationBuilder declaration;
TypeUseGenerator(ExpressionGeneratorHelper helper, Token token,
- this.declaration, String plainNameForRead)
- : super(helper, token, null, plainNameForRead);
+ this.declaration, String targetName)
+ : super(helper, token, null, targetName);
@override
String get _debugName => "TypeUseGenerator";
@@ -2674,7 +2634,7 @@
}
}
return new NamedTypeBuilder(
- _plainNameForRead, nullabilityBuilder, argumentBuilders)
+ targetName, nullabilityBuilder, argumentBuilders)
..bind(declaration);
}
@@ -2710,19 +2670,14 @@
if (super.expression == null) {
if (declaration is InvalidTypeBuilder) {
InvalidTypeBuilder declaration = this.declaration;
- _helper.addProblemErrorIfConst(
+ super.expression = _helper.buildProblemErrorIfConst(
declaration.message.messageObject, fileOffset, token.length);
- super.expression = _helper.wrapSyntheticExpression(
- _forest.createThrow(null,
- _forest.createStringLiteral(declaration.message.message, token))
- ..fileOffset = fileOffset,
- fileOffset);
} else {
super.expression = _forest.createTypeLiteral(
_helper.buildDartType(
new UnresolvedType(
buildTypeWithResolvedArguments(
- const NullabilityBuilder.legacy(), null),
+ _helper.libraryBuilder.nonNullableBuilder, null),
fileOffset,
_uri),
nonInstanceAccessIsError: true),
@@ -2733,18 +2688,6 @@
}
@override
- Expression _makeInvalidWrite(Expression value) {
- return _helper.wrapSyntheticExpression(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(fileOffset),
- _plainNameForRead,
- _forest.createArguments(fileOffset, <Expression>[value]),
- fileOffset,
- isSetter: true),
- fileOffset);
- }
-
- @override
buildPropertyAccess(
IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
// `SomeType?.toString` is the same as `SomeType.toString`, not
@@ -2796,7 +2739,7 @@
}
}
generator = new StaticAccessGenerator.fromBuilder(
- _helper, member, send.token, setter);
+ _helper, name.name, member, send.token, setter);
}
return arguments == null
@@ -2865,38 +2808,72 @@
/// }
///
class ReadOnlyAccessGenerator extends Generator {
- @override
- final String _plainNameForRead;
+ final String targetName;
Expression expression;
VariableDeclaration value;
ReadOnlyAccessGenerator(ExpressionGeneratorHelper helper, Token token,
- this.expression, this._plainNameForRead)
+ this.expression, this.targetName)
: super(helper, token);
@override
String get _debugName => "ReadOnlyAccessGenerator";
@override
- Expression _makeSimpleRead() => expression;
+ String get _plainNameForRead => targetName;
@override
- Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
- value ??= new VariableDeclaration.forValue(expression);
- return new VariableGet(value);
+ Expression buildSimpleRead() => expression;
+
+ @override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _makeInvalidWrite(value);
}
@override
- Expression _finish(
- Expression body, ComplexAssignmentJudgment complexAssignment) =>
- super._finish(makeLet(value, body), complexAssignment);
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ Expression read = buildSimpleRead();
+ Expression write = _makeInvalidWrite(value);
+ return new IfNullSet(read, write, forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ buildSimpleRead(),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ return _makeInvalidWrite(binary);
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
@override
doInvocation(int offset, Arguments arguments) {
return _helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
- adjustForImplicitCall(_plainNameForRead, offset),
+ adjustForImplicitCall(targetName, offset),
isImplicitCall: true);
}
@@ -2906,7 +2883,7 @@
sink.write(", expression: ");
printNodeOn(expression, sink, syntheticNames: syntheticNames);
sink.write(", plainNameForRead: ");
- sink.write(_plainNameForRead);
+ sink.write(targetName);
sink.write(", value: ");
printNodeOn(value, sink, syntheticNames: syntheticNames);
}
@@ -2931,8 +2908,8 @@
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- return _helper.buildInvalidInitializer(_helper.desugarSyntheticExpression(
- buildError(_forest.createArgumentsEmpty(fileOffset), isSetter: true)));
+ return _helper.buildInvalidInitializer(
+ buildError(_forest.createArgumentsEmpty(fileOffset), isSetter: true));
}
@override
@@ -3022,11 +2999,7 @@
_forest.argumentsSetTypeArguments(
arguments, _helper.buildDartTypeArguments(typeArguments));
}
- return _helper.wrapInvalidConstructorInvocation(
- _helper.desugarSyntheticExpression(buildError(arguments)),
- null,
- arguments,
- fileOffset);
+ return buildError(arguments);
}
}
@@ -3051,26 +3024,20 @@
@override
Expression doInvocation(int charOffset, Arguments arguments) {
- return _helper.wrapUnresolvedTargetInvocation(
- _helper.desugarSyntheticExpression(
- buildError(arguments, offset: charOffset)),
- arguments,
- arguments.fileOffset);
+ return buildError(arguments, offset: charOffset);
}
@override
Expression buildError(Arguments arguments,
{bool isGetter: false, bool isSetter: false, int offset}) {
offset ??= fileOffset;
- return _helper.wrapSyntheticExpression(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(null)..fileOffset = offset,
- _plainNameForRead,
- arguments,
- offset,
- isGetter: isGetter,
- isSetter: isSetter),
- offset);
+ return _helper.throwNoSuchMethodError(
+ _forest.createNullLiteral(null)..fileOffset = offset,
+ _plainNameForRead,
+ arguments,
+ offset,
+ isGetter: isGetter,
+ isSetter: isSetter);
}
@override
@@ -3107,13 +3074,8 @@
Expression _buildUnresolvedVariableAssignment(
bool isCompound, Expression value) {
- return _helper.wrapUnresolvedVariableAssignment(
- _helper.desugarSyntheticExpression(buildError(
- _forest.createArguments(fileOffset, <Expression>[value]),
- isSetter: true)),
- isCompound,
- value,
- token.charOffset);
+ return buildError(_forest.createArguments(fileOffset, <Expression>[value]),
+ isSetter: true);
}
}
@@ -3145,7 +3107,8 @@
@override
Expression buildAssignment(Expression value, {bool voidContext: false}) {
- return new PropertySet(receiver, name, value)..fileOffset = fileOffset;
+ return _helper.forest.createPropertySet(fileOffset, receiver, name, value,
+ forEffect: voidContext);
}
@override
@@ -3154,6 +3117,82 @@
}
@override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ PropertyGet read = new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset;
+ PropertySet write = _helper.forest.createPropertySet(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), name, value,
+ forEffect: voidContext);
+ return new IfNullPropertySet(variable, read, write, forEffect: voidContext)
+ ..fileOffset = offset;
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset,
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ PropertySet write = _helper.forest.createPropertySet(fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset), name, binary,
+ forEffect: voidContext);
+ return new CompoundPropertySet(variable, write)..fileOffset = offset;
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ Expression value = _forest.createIntLiteral(1, null)..fileOffset = offset;
+ if (voidContext) {
+ return buildCompoundAssignment(binaryOperator, value,
+ offset: offset,
+ voidContext: voidContext,
+ interfaceTarget: interfaceTarget,
+ isPostIncDec: true);
+ }
+ VariableDeclaration variable = _helper.forest
+ .createVariableDeclarationForValue(receiver.fileOffset, receiver);
+ VariableDeclaration read = _helper.forest.createVariableDeclarationForValue(
+ fileOffset,
+ new PropertyGet(
+ _helper.createVariableGet(variable, receiver.fileOffset), name)
+ ..fileOffset = fileOffset);
+ MethodInvocation binary = _helper.forest.createMethodInvocation(
+ offset,
+ _helper.createVariableGet(read, fileOffset),
+ binaryOperator,
+ _helper.forest.createArguments(offset, <Expression>[value]),
+ interfaceTarget: interfaceTarget);
+ VariableDeclaration write = _helper.forest
+ .createVariableDeclarationForValue(
+ offset,
+ _helper.forest.createPropertySet(
+ fileOffset,
+ _helper.createVariableGet(variable, receiver.fileOffset),
+ name,
+ binary,
+ forEffect: true));
+ return new PropertyPostIncDec(variable, read, write)..fileOffset = offset;
+ }
+
+ @override
Expression doInvocation(int offset, Arguments arguments) {
return unsupported("doInvocation", offset, _uri);
}
@@ -3368,6 +3407,35 @@
Expression buildSimpleRead() => _makeInvalidRead();
@override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return _makeInvalidRead();
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return _makeInvalidRead();
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget}) {
+ return _makeInvalidRead();
+ }
+
+ @override
/* Expression | Generator */ Object qualifiedLookup(Token name) {
if (_helper.constantContext != ConstantContext.none && prefix.deferred) {
_helper.addProblem(
@@ -3449,9 +3517,8 @@
: super(helper, token);
@override
- String get _plainNameForRead {
- return "${prefixGenerator._plainNameForRead}.${token.lexeme}";
- }
+ String get _plainNameForRead =>
+ "${prefixGenerator._plainNameForRead}.${token.lexeme}";
@override
String get _debugName => "UnexpectedQualifiedUseGenerator";
@@ -3460,13 +3527,40 @@
Expression buildSimpleRead() => _makeInvalidRead();
@override
+ Expression buildAssignment(Expression value, {bool voidContext: false}) {
+ return _makeInvalidWrite(value);
+ }
+
+ @override
+ Expression buildIfNullAssignment(Expression value, DartType type, int offset,
+ {bool voidContext: false}) {
+ return _makeInvalidRead();
+ }
+
+ @override
+ Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+ {int offset: TreeNode.noOffset,
+ bool voidContext: false,
+ Procedure interfaceTarget,
+ bool isPreIncDec: false,
+ bool isPostIncDec: false}) {
+ return _makeInvalidRead();
+ }
+
+ @override
+ Expression buildPostfixIncrement(Name binaryOperator,
+ {int offset = TreeNode.noOffset,
+ bool voidContext = false,
+ Procedure interfaceTarget}) {
+ return _makeInvalidRead();
+ }
+
+ @override
Expression doInvocation(int offset, Arguments arguments) {
- return _helper.wrapSyntheticExpression(
- _helper.throwNoSuchMethodError(
- _forest.createNullLiteral(null)..fileOffset = offset,
- _plainNameForRead,
- arguments,
- fileOffset),
+ return _helper.throwNoSuchMethodError(
+ _forest.createNullLiteral(null)..fileOffset = offset,
+ _plainNameForRead,
+ arguments,
fileOffset);
}
@@ -3559,8 +3653,7 @@
Expression _makeInvalidWrite(Expression value) => buildProblem();
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- return _helper.buildInvalidInitializer(
- _helper.desugarSyntheticExpression(buildProblem()));
+ return _helper.buildInvalidInitializer(buildProblem());
}
Expression doInvocation(int offset, Arguments arguments) {
@@ -3662,7 +3755,7 @@
if (inFieldInitializer) {
return buildFieldInitializerError(null);
} else {
- return _forest.createThisExpression(token);
+ return _forest.createThisExpression(fileOffset);
}
} else {
return _helper.buildProblem(
@@ -3680,8 +3773,7 @@
@override
Initializer buildFieldInitializer(Map<String, int> initializedFields) {
- Expression error = _helper.desugarSyntheticExpression(
- buildFieldInitializerError(initializedFields));
+ Expression error = buildFieldInitializerError(initializedFields);
return _helper.buildInvalidInitializer(error, error.fileOffset);
}
@@ -3708,9 +3800,13 @@
_helper.warnUnresolvedMethod(name, offsetForToken(send.token),
isSuper: isSuper);
}
- return _helper.buildMethodInvocation(_forest.createThisExpression(null),
- name, send.arguments, offsetForToken(send.token),
- isSuper: isSuper, interfaceTarget: getter);
+ return _helper.buildMethodInvocation(
+ _forest.createThisExpression(fileOffset),
+ name,
+ send.arguments,
+ offsetForToken(send.token),
+ isSuper: isSuper,
+ interfaceTarget: getter);
} else {
Member setter =
_helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
@@ -3741,7 +3837,7 @@
return _helper.buildProblem(messageSuperAsExpression, offset, noLength);
} else {
return _helper.buildMethodInvocation(
- _forest.createThisExpression(null), callName, arguments, offset,
+ _forest.createThisExpression(fileOffset), callName, arguments, offset,
isImplicitCall: true);
}
}
@@ -3763,7 +3859,7 @@
.withLocation(_uri, fileOffset, lengthForToken(token));
}
if (message != null) {
- return _helper.buildInvalidInitializer(_helper.wrapSyntheticExpression(
+ return _helper.buildInvalidInitializer(
_helper.throwNoSuchMethodError(
_forest.createNullLiteral(null)..fileOffset = offset,
_helper.constructorNameForDiagnostics(name.name,
@@ -3772,7 +3868,7 @@
offset,
isSuper: isSuper,
message: message),
- offset));
+ offset);
} else if (isSuper) {
return _helper.buildSuperInitializer(
false, constructor, arguments, offset);
@@ -3815,10 +3911,10 @@
}
Expression buildAssignmentError() {
- return _helper.desugarSyntheticExpression(_helper.buildProblem(
+ return _helper.buildProblem(
isSuper ? messageCannotAssignToSuper : messageNotAnLvalue,
fileOffset,
- token.length));
+ token.length);
}
@override
@@ -4036,20 +4132,9 @@
String get _debugName => "ParenthesizedExpressionGenerator";
- @override
- ComplexAssignmentJudgment startComplexAssignment(Expression rhs) {
- return SyntheticWrapper.wrapIllegalAssignment(rhs,
- assignmentOffset: fileOffset);
- }
-
Expression _makeInvalidWrite(Expression value) {
- return _helper.wrapInvalidWrite(
- _helper.desugarSyntheticExpression(_helper.buildProblem(
- messageCannotAssignToParenthesizedExpression,
- fileOffset,
- lengthForToken(token))),
- expression,
- fileOffset);
+ return _helper.buildProblem(messageCannotAssignToParenthesizedExpression,
+ fileOffset, lengthForToken(token));
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 53d1baf..3231dc7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -126,6 +126,9 @@
void addProblemErrorIfConst(Message message, int charOffset, int length);
+ Expression buildProblemErrorIfConst(
+ Message message, int charOffset, int length);
+
Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
Message warnUnresolvedSet(Name name, int charOffset, {bool isSuper});
@@ -148,20 +151,6 @@
void reportDuplicatedDeclaration(
Builder existing, String name, int charOffset);
- Expression wrapSyntheticExpression(Expression node, int charOffset);
-
- Expression wrapInvalidConstructorInvocation(Expression desugared,
- Member constructor, Arguments arguments, int charOffset);
-
- Expression wrapInvalidWrite(
- Expression desugared, Expression expression, int charOffset);
-
- Expression wrapUnresolvedTargetInvocation(
- Expression desugared, Arguments arguments, int charOffset);
-
- Expression wrapUnresolvedVariableAssignment(
- Expression desugared, bool isCompound, Expression rhs, int charOffset);
-
/// Creates a [VariableGet] of the [variable] using [charOffset] as the file
/// offset of the created node.
Expression createVariableGet(VariableDeclaration variable, int charOffset);
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 37926f6..1a26c43 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -26,16 +26,7 @@
IfMapEntry,
SpreadElement;
-import 'kernel_shadow_ast.dart'
- show
- ArgumentsImpl,
- IntJudgment,
- LoadLibraryImpl,
- MethodInvocationImpl,
- ReturnStatementImpl,
- ShadowLargeIntLiteral,
- SyntheticExpressionJudgment,
- VariableDeclarationImpl;
+import 'kernel_shadow_ast.dart';
/// A shadow tree factory.
class Forest {
@@ -515,8 +506,9 @@
return new LabeledStatement(statement);
}
- Expression createThisExpression(Token token) {
- return new ThisExpression()..fileOffset = offsetForToken(token);
+ Expression createThisExpression(int offset) {
+ assert(offset != null);
+ return new ThisExpression()..fileOffset = offset;
}
/// Return a representation of a throw expression consisting of the
@@ -607,10 +599,6 @@
VariableDeclaration variable = node;
node = variable.initializer;
}
- if (node is SyntheticExpressionJudgment) {
- SyntheticExpressionJudgment synth = node;
- node = synth.desugared;
- }
if (node is Let) {
Let let = node;
node = let.variable.initializer;
@@ -716,6 +704,26 @@
return new StaticInvocation(procedure, arguments)
..fileOffset = fileOffset ?? TreeNode.noOffset;
}
+
+ SuperMethodInvocation createSuperMethodInvocation(
+ int fileOffset, Name name, Procedure procedure, Arguments arguments) {
+ return new SuperMethodInvocation(name, arguments, procedure)
+ ..fileOffset = fileOffset ?? TreeNode.noOffset;
+ }
+
+ NullCheck createNullCheck(int fileOffset, Expression expression) {
+ return new NullCheck(expression)..fileOffset = fileOffset;
+ }
+
+ PropertySet createPropertySet(
+ int fileOffset, Expression receiver, Name name, Expression value,
+ {Member interfaceTarget, bool forEffect, bool readOnlyReceiver: false}) {
+ return new PropertySetImpl(receiver, name, value,
+ interfaceTarget: interfaceTarget,
+ forEffect: forEffect,
+ readOnlyReceiver: readOnlyReceiver)
+ ..fileOffset = fileOffset;
+ }
}
class _VariablesDeclaration extends Statement {
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 cdfc0b1..b761c58 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -45,20 +45,34 @@
return visitCompoundIndexSet(node, typeContext);
case InternalExpressionKind.CompoundPropertySet:
return visitCompoundPropertySet(node, typeContext);
+ case InternalExpressionKind.CompoundSuperIndexSet:
+ return visitCompoundSuperIndexSet(node, typeContext);
case InternalExpressionKind.DeferredCheck:
return visitDeferredCheck(node, typeContext);
+ case InternalExpressionKind.ExtensionSet:
+ return visitExtensionSet(node, typeContext);
+ case InternalExpressionKind.IfNull:
+ return visitIfNull(node, typeContext);
case InternalExpressionKind.IfNullIndexSet:
return visitIfNullIndexSet(node, typeContext);
case InternalExpressionKind.IfNullPropertySet:
return visitIfNullPropertySet(node, typeContext);
case InternalExpressionKind.IfNullSet:
return visitIfNullSet(node, typeContext);
+ case InternalExpressionKind.IfNullSuperIndexSet:
+ return visitIfNullSuperIndexSet(node, typeContext);
case InternalExpressionKind.IndexSet:
return visitIndexSet(node, typeContext);
case InternalExpressionKind.LoadLibraryTearOff:
return visitLoadLibraryTearOff(node, typeContext);
case InternalExpressionKind.LocalPostIncDec:
return visitLocalPostIncDec(node, typeContext);
+ case InternalExpressionKind.NullAwareCompoundSet:
+ return visitNullAwareCompoundSet(node, typeContext);
+ case InternalExpressionKind.NullAwareExtension:
+ return visitNullAwareExtension(node, typeContext);
+ case InternalExpressionKind.NullAwareIfNullSet:
+ return visitNullAwareIfNullSet(node, typeContext);
case InternalExpressionKind.NullAwareMethodInvocation:
return visitNullAwareMethodInvocation(node, typeContext);
case InternalExpressionKind.NullAwarePropertyGet:
@@ -69,6 +83,8 @@
return visitPropertyPostIncDec(node, typeContext);
case InternalExpressionKind.StaticPostIncDec:
return visitStaticPostIncDec(node, typeContext);
+ case InternalExpressionKind.SuperIndexSet:
+ return visitSuperIndexSet(node, typeContext);
case InternalExpressionKind.SuperPostIncDec:
return visitSuperPostIncDec(node, typeContext);
}
@@ -186,7 +202,9 @@
@override
ExpressionInferenceResult visitInvalidExpression(
InvalidExpression node, DartType typeContext) {
- return const ExpressionInferenceResult(const BottomType());
+ // TODO(johnniwinther): The inferred type should be an InvalidType. Using
+ // BottomType leads to cascading errors so we use DynamicType for now.
+ return const ExpressionInferenceResult(const DynamicType());
}
@override
@@ -215,13 +233,15 @@
InterfaceType expectedType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel,
+ isVoidAllowed: true)
.inferredType;
inferrer.ensureAssignable(
expectedType, conditionType, node.condition, node.condition.fileOffset);
if (node.message != null) {
inferrer.inferExpression(
- node.message, const UnknownType(), !inferrer.isTopLevel);
+ node.message, const UnknownType(), !inferrer.isTopLevel,
+ isVoidAllowed: true);
}
}
@@ -259,8 +279,9 @@
}
ExpressionInferenceResult visitCascade(Cascade node, DartType typeContext) {
- ExpressionInferenceResult result =
- inferrer.inferExpression(node.expression, typeContext, true);
+ ExpressionInferenceResult result = inferrer.inferExpression(
+ node.expression, typeContext, true,
+ isVoidAllowed: false);
node.variable.type = result.inferredType;
for (Expression judgment in node.cascades) {
inferrer.inferExpression(
@@ -277,7 +298,8 @@
InterfaceType expectedType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel,
+ isVoidAllowed: true)
.inferredType;
inferrer.ensureAssignable(
expectedType, conditionType, node.condition, node.condition.fileOffset);
@@ -359,6 +381,68 @@
// No inference needs to be done.
}
+ ExpressionInferenceResult visitExtensionSet(
+ ExtensionSet node, DartType typeContext) {
+ // Since the variable is not used in the body we don't need to type infer
+ // it. We can just type infer the body.
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: false);
+
+ DartType valueType =
+ inferrer.getSetterType(node.target, receiverResult.inferredType);
+
+ ExpressionInferenceResult valueResult = inferrer.inferExpression(
+ node.value, const UnknownType(), true,
+ isVoidAllowed: false);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+
+ Expression value;
+ VariableDeclaration valueVariable;
+ if (node.forEffect) {
+ value = node.value;
+ } else {
+ valueVariable = createVariable(node.value, valueResult.inferredType);
+ value = createVariableGet(valueVariable);
+ }
+
+ VariableDeclaration receiverVariable;
+ Expression receiver;
+ if (node.forEffect || node.readOnlyReceiver) {
+ receiver = node.receiver;
+ } else {
+ receiverVariable =
+ createVariable(node.receiver, receiverResult.inferredType);
+ receiver = createVariableGet(receiverVariable);
+ }
+ Expression assignment = new StaticInvocation(
+ node.target.member,
+ new Arguments(<Expression>[receiver, value],
+ types: node.target.inferredExtensionTypeArguments)
+ ..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset;
+
+ Expression replacement;
+ if (node.forEffect) {
+ assert(receiverVariable == null);
+ assert(valueVariable == null);
+ replacement = assignment;
+ } else {
+ assert(valueVariable != null);
+ VariableDeclaration assignmentVariable =
+ createVariable(assignment, const VoidType());
+ replacement = createLet(valueVariable,
+ createLet(assignmentVariable, createVariableGet(valueVariable)));
+ if (receiverVariable != null) {
+ replacement = createLet(receiverVariable, replacement);
+ }
+ }
+ replacement.fileOffset = node.fileOffset;
+ node.replaceWith(replacement);
+ return new ExpressionInferenceResult(valueResult.inferredType, replacement);
+ }
+
ExpressionInferenceResult visitDeferredCheck(
DeferredCheck node, DartType typeContext) {
// Since the variable is not used in the body we don't need to type infer
@@ -376,7 +460,8 @@
InterfaceType boolType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, boolType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, boolType, !inferrer.isTopLevel,
+ isVoidAllowed: true)
.inferredType;
inferrer.ensureAssignable(
boolType, conditionType, node.condition, node.condition.fileOffset);
@@ -489,8 +574,8 @@
? inferrer.coreTypes.streamClass
: inferrer.coreTypes.iterableClass;
DartType context = inferrer.wrapType(elementType, iterableClass);
- ExpressionInferenceResult iterableResult =
- inferrer.inferExpression(iterable, context, typeNeeded);
+ ExpressionInferenceResult iterableResult = inferrer
+ .inferExpression(iterable, context, typeNeeded, isVoidAllowed: false);
DartType iterableType = iterableResult.inferredType;
if (iterableResult.replacement != null) {
iterable = iterableResult.replacement;
@@ -523,18 +608,13 @@
DartType elementType;
bool typeChecksNeeded = !inferrer.isTopLevel;
DartType syntheticWriteType;
- Expression syntheticAssignment;
Expression rhs;
// If `true`, the synthetic statement should not be visited.
bool skipStatement = false;
ExpressionStatement syntheticStatement =
body is Block ? body.statements.first : body;
Expression statementExpression = syntheticStatement.expression;
- if (statementExpression is SyntheticExpressionJudgment) {
- syntheticAssignment = statementExpression.desugared;
- } else {
- syntheticAssignment = statementExpression;
- }
+ Expression syntheticAssignment = statementExpression;
if (syntheticAssignment is VariableSet) {
syntheticWriteType = elementType = syntheticAssignment.variable.type;
rhs = syntheticAssignment.value;
@@ -625,7 +705,8 @@
InterfaceType expectedType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel,
+ isVoidAllowed: true)
.inferredType;
inferrer.ensureAssignable(expectedType, conditionType, node.condition,
node.condition.fileOffset);
@@ -677,13 +758,18 @@
skipTypeArgumentInference: true);
}
- ExpressionInferenceResult visitIfNullJudgment(
- IfNullJudgment node, DartType typeContext) {
+ ExpressionInferenceResult visitIfNull(
+ IfNullExpression node, DartType typeContext) {
// To infer `e0 ?? e1` in context K:
// - Infer e0 in context K to get T0
- DartType lhsType =
- inferrer.inferExpression(node.left, typeContext, true).inferredType;
- node.variable.type = lhsType;
+ DartType lhsType = inferrer
+ .inferExpression(node.left, typeContext, true, isVoidAllowed: false)
+ .inferredType;
+
+ Member equalsMember = inferrer
+ .findInterfaceMember(lhsType, equalsName, node.fileOffset)
+ .member;
+
// - Let J = T0 if K is `?` else K.
// - Infer e1 in context J to get T1
DartType rhsType;
@@ -701,8 +787,15 @@
// - Then the inferred type is T.
DartType inferredType =
inferrer.typeSchemaEnvironment.getStandardUpperBound(lhsType, rhsType);
- node.body.staticType = inferredType;
- return new ExpressionInferenceResult(inferredType);
+ VariableDeclaration variable = createVariable(node.left, lhsType);
+ MethodInvocation equalsNull = createEqualsNull(
+ node.left.fileOffset, createVariableGet(variable), equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull, node.right, createVariableGet(variable), inferredType);
+ Expression replacement = new Let(variable, conditional)
+ ..fileOffset = node.fileOffset;
+ node.replaceWith(replacement);
+ return new ExpressionInferenceResult(inferredType, replacement);
}
@override
@@ -710,7 +803,8 @@
InterfaceType expectedType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel,
+ isVoidAllowed: true)
.inferredType;
inferrer.ensureAssignable(
expectedType, conditionType, node.condition, node.condition.fileOffset);
@@ -720,85 +814,6 @@
}
}
- ExpressionInferenceResult visitIllegalAssignmentJudgment(
- IllegalAssignmentJudgment node, DartType typeContext) {
- if (node.write != null) {
- inferrer.inferExpression(
- node.write, const UnknownType(), !inferrer.isTopLevel);
- }
- inferrer.inferExpression(
- node.rhs, const UnknownType(), !inferrer.isTopLevel);
- node._replaceWithDesugared();
- return const ExpressionInferenceResult(const DynamicType());
- }
-
- ExpressionInferenceResult visitIndexAssignmentJudgment(
- IndexAssignmentJudgment node, DartType typeContext) {
- DartType receiverType = node._inferReceiver(inferrer);
- ObjectAccessTarget writeTarget =
- inferrer.findMethodInvocationMember(receiverType, node.write);
- // To replicate analyzer behavior, we base type inference on the write
- // member. TODO(paulberry): would it be better to use the read member
- // when doing compound assignment?
- DartType indexContext = const UnknownType();
- DartType expectedIndexTypeForWrite =
- inferrer.getIndexKeyType(writeTarget, receiverType);
- DartType writeContext =
- inferrer.getIndexSetValueType(writeTarget, receiverType);
- ExpressionInferenceResult indexResult =
- inferrer.inferExpression(node.index, indexContext, true);
- DartType indexType = indexResult.inferredType;
- node._storeLetType(inferrer, node.index, indexType);
- if (indexResult.replacement != null) {
- node.index = indexResult.replacement;
- }
- Expression writeIndexExpression =
- node._getInvocationArguments(inferrer, node.write).positional[0];
- if (writeTarget.isExtensionMember) {
- MethodInvocation write = node.write;
- Expression replacement = inferrer.transformExtensionMethodInvocation(
- writeTarget, write, write.receiver, write.arguments);
- node.write = replacement;
- }
- if (writeContext is! UnknownType) {
- inferrer.ensureAssignable(expectedIndexTypeForWrite, indexType,
- writeIndexExpression, node.write.fileOffset);
- }
-
- InvocationExpression read = node.read;
- DartType readType;
- if (read != null) {
- ObjectAccessTarget readMember = inferrer
- .findMethodInvocationMember(receiverType, read, instrumented: false);
- FunctionType calleeFunctionType =
- inferrer.getFunctionType(readMember, receiverType, false);
- inferrer.ensureAssignable(
- getPositionalParameterType(calleeFunctionType, 0),
- indexType,
- node._getInvocationArguments(inferrer, read).positional[0],
- read.fileOffset);
- readType = calleeFunctionType.returnType;
- MethodInvocation desugaredInvocation =
- read is MethodInvocation ? read : null;
- MethodContravarianceCheckKind checkKind =
- inferrer.preCheckInvocationContravariance(receiverType, readMember,
- isThisReceiver: node.receiver is ThisExpression);
- Expression replacedRead = inferrer.handleInvocationContravariance(
- checkKind,
- desugaredInvocation,
- read.arguments,
- read,
- readType,
- calleeFunctionType,
- read.fileOffset);
- node._storeLetType(inferrer, replacedRead, readType);
- }
- DartType inferredType =
- node._inferRhs(inferrer, readType, writeContext).inferredType;
- node._replaceWithDesugared();
- return new ExpressionInferenceResult(inferredType);
- }
-
ExpressionInferenceResult visitIntJudgment(
IntJudgment node, DartType typeContext) {
if (inferrer.isDoubleContext(typeContext)) {
@@ -838,11 +853,10 @@
int intValue = node.asInt64();
if (intValue == null) {
- Expression replacement = inferrer.helper.desugarSyntheticExpression(
- inferrer.helper.buildProblem(
- templateIntegerLiteralIsOutOfRange.withArguments(node.literal),
- node.fileOffset,
- node.literal.length));
+ Expression replacement = inferrer.helper.buildProblem(
+ templateIntegerLiteralIsOutOfRange.withArguments(node.literal),
+ node.fileOffset,
+ node.literal.length);
node.parent.replaceChild(node, replacement);
return const ExpressionInferenceResult(const BottomType());
}
@@ -861,18 +875,21 @@
void visitShadowInvalidInitializer(ShadowInvalidInitializer node) {
inferrer.inferExpression(
- node.variable.initializer, const UnknownType(), !inferrer.isTopLevel);
+ node.variable.initializer, const UnknownType(), !inferrer.isTopLevel,
+ isVoidAllowed: false);
}
void visitShadowInvalidFieldInitializer(ShadowInvalidFieldInitializer node) {
- inferrer.inferExpression(node.value, node.field.type, !inferrer.isTopLevel);
+ inferrer.inferExpression(node.value, node.field.type, !inferrer.isTopLevel,
+ isVoidAllowed: false);
}
@override
ExpressionInferenceResult visitIsExpression(
IsExpression node, DartType typeContext) {
inferrer.inferExpression(
- node.operand, const UnknownType(), !inferrer.isTopLevel);
+ node.operand, const UnknownType(), !inferrer.isTopLevel,
+ isVoidAllowed: false);
return new ExpressionInferenceResult(
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable));
}
@@ -922,28 +939,25 @@
!element.isNullAware) {
parent.replaceChild(
element,
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(messageNonNullAwareSpreadIsNull,
- element.expression.fileOffset, 1)));
+ inferrer.helper.buildProblem(messageNonNullAwareSpreadIsNull,
+ element.expression.fileOffset, 1));
} else {
parent.replaceChild(
element,
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(
- templateSpreadTypeMismatch.withArguments(spreadType),
- element.expression.fileOffset,
- 1)));
+ inferrer.helper.buildProblem(
+ templateSpreadTypeMismatch.withArguments(spreadType),
+ element.expression.fileOffset,
+ 1));
}
} else if (spreadType is InterfaceType) {
if (!inferrer.isAssignable(inferredTypeArgument, spreadElementType)) {
parent.replaceChild(
element,
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(
- templateSpreadElementTypeMismatch.withArguments(
- spreadElementType, inferredTypeArgument),
- element.expression.fileOffset,
- 1)));
+ inferrer.helper.buildProblem(
+ templateSpreadElementTypeMismatch.withArguments(
+ spreadElementType, inferredTypeArgument),
+ element.expression.fileOffset,
+ 1));
}
}
}
@@ -1187,10 +1201,12 @@
InterfaceType boolType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType leftType = inferrer
- .inferExpression(node.left, boolType, !inferrer.isTopLevel)
+ .inferExpression(node.left, boolType, !inferrer.isTopLevel,
+ isVoidAllowed: false)
.inferredType;
DartType rightType = inferrer
- .inferExpression(node.right, boolType, !inferrer.isTopLevel)
+ .inferExpression(node.right, boolType, !inferrer.isTopLevel,
+ isVoidAllowed: false)
.inferredType;
inferrer.ensureAssignable(
boolType, leftType, node.left, node.left.fileOffset);
@@ -1262,9 +1278,10 @@
parent.replaceChild(
entry,
new MapEntry(
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(messageNonNullAwareSpreadIsNull,
- entry.expression.fileOffset, 1)),
+ inferrer.helper.buildProblem(
+ messageNonNullAwareSpreadIsNull,
+ entry.expression.fileOffset,
+ 1),
new NullLiteral())
..fileOffset = entry.fileOffset);
} else if (actualElementType != null) {
@@ -1275,12 +1292,11 @@
parent.replaceChild(
entry,
new MapEntry(
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(
- templateSpreadMapEntryTypeMismatch
- .withArguments(spreadType),
- entry.expression.fileOffset,
- 1)),
+ inferrer.helper.buildProblem(
+ templateSpreadMapEntryTypeMismatch
+ .withArguments(spreadType),
+ entry.expression.fileOffset,
+ 1),
new NullLiteral())
..fileOffset = entry.fileOffset);
}
@@ -1288,20 +1304,18 @@
Expression keyError;
Expression valueError;
if (!inferrer.isAssignable(inferredKeyType, actualKeyType)) {
- keyError = inferrer.helper.desugarSyntheticExpression(
- inferrer.helper.buildProblem(
- templateSpreadMapEntryElementKeyTypeMismatch.withArguments(
- actualKeyType, inferredKeyType),
- entry.expression.fileOffset,
- 1));
+ keyError = inferrer.helper.buildProblem(
+ templateSpreadMapEntryElementKeyTypeMismatch.withArguments(
+ actualKeyType, inferredKeyType),
+ entry.expression.fileOffset,
+ 1);
}
if (!inferrer.isAssignable(inferredValueType, actualValueType)) {
- valueError = inferrer.helper.desugarSyntheticExpression(
- inferrer.helper.buildProblem(
- templateSpreadMapEntryElementValueTypeMismatch
- .withArguments(actualValueType, inferredValueType),
- entry.expression.fileOffset,
- 1));
+ valueError = inferrer.helper.buildProblem(
+ templateSpreadMapEntryElementValueTypeMismatch.withArguments(
+ actualValueType, inferredValueType),
+ entry.expression.fileOffset,
+ 1);
}
if (keyError != null || valueError != null) {
keyError ??= new NullLiteral();
@@ -1502,12 +1516,11 @@
parent.replaceChild(
entry,
new MapEntry(
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(
- templateSpreadMapEntryTypeMismatch
- .withArguments(iterableSpreadType),
- iterableSpreadOffset,
- 1)),
+ inferrer.helper.buildProblem(
+ templateSpreadMapEntryTypeMismatch
+ .withArguments(iterableSpreadType),
+ iterableSpreadOffset,
+ 1),
new NullLiteral()));
}
if (entry is SpreadMapEntry) {
@@ -1714,18 +1727,20 @@
if (canBeSet && canBeMap && node.entries.isNotEmpty) {
node.parent.replaceChild(
node,
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(messageCantDisambiguateNotEnoughInformation,
- node.fileOffset, 1)));
+ inferrer.helper.buildProblem(
+ messageCantDisambiguateNotEnoughInformation,
+ node.fileOffset,
+ 1));
return const ExpressionInferenceResult(const BottomType());
}
if (!canBeSet && !canBeMap) {
if (!inferrer.isTopLevel) {
node.parent.replaceChild(
node,
- inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(messageCantDisambiguateAmbiguousInformation,
- node.fileOffset, 1)));
+ inferrer.helper.buildProblem(
+ messageCantDisambiguateAmbiguousInformation,
+ node.fileOffset,
+ 1));
}
return const ExpressionInferenceResult(const BottomType());
}
@@ -1824,12 +1839,11 @@
}
int intValue = receiver.asInt64(negated: true);
if (intValue == null) {
- Expression error = inferrer.helper.desugarSyntheticExpression(
- inferrer.helper.buildProblem(
- templateIntegerLiteralIsOutOfRange
- .withArguments(receiver.literal),
- receiver.fileOffset,
- receiver.literal.length));
+ Expression error = inferrer.helper.buildProblem(
+ templateIntegerLiteralIsOutOfRange
+ .withArguments(receiver.literal),
+ receiver.fileOffset,
+ receiver.literal.length);
node.parent.replaceChild(node, error);
return const ExpressionInferenceResult(const BottomType());
}
@@ -1874,6 +1888,20 @@
return new ExpressionInferenceResult(boolType);
}
+ @override
+ ExpressionInferenceResult visitNullCheck(
+ NullCheck node, DartType typeContext) {
+ // TODO(johnniwinther): Should the typeContext for the operand be
+ // `Nullable(typeContext)`?
+ DartType inferredType = inferrer
+ .inferExpression(node.operand, typeContext, !inferrer.isTopLevel)
+ .inferredType;
+ // TODO(johnniwinther): Check that the inferred type is potentially
+ // nullable.
+ // TODO(johnniwinther): Return `NonNull(inferredType)`.
+ return new ExpressionInferenceResult(inferredType);
+ }
+
ExpressionInferenceResult visitNullAwareMethodInvocation(
NullAwareMethodInvocation node, DartType typeContext) {
inferrer.inferStatement(node.variable);
@@ -1881,8 +1909,7 @@
node.invocation, typeContext, true,
isVoidAllowed: true);
Member equalsMember = inferrer
- .findInterfaceMember(
- node.variable.type, new Name('=='), node.fileOffset)
+ .findInterfaceMember(node.variable.type, equalsName, node.fileOffset)
.member;
DartType inferredType = readResult.inferredType;
@@ -1908,8 +1935,7 @@
ExpressionInferenceResult readResult =
inferrer.inferExpression(node.read, const UnknownType(), true);
Member equalsMember = inferrer
- .findInterfaceMember(
- node.variable.type, new Name('=='), node.fileOffset)
+ .findInterfaceMember(node.variable.type, equalsName, node.fileOffset)
.member;
DartType inferredType = readResult.inferredType;
@@ -1935,8 +1961,7 @@
ExpressionInferenceResult writeResult =
inferrer.inferExpression(node.write, typeContext, true);
Member equalsMember = inferrer
- .findInterfaceMember(
- node.variable.type, new Name('=='), node.fileOffset)
+ .findInterfaceMember(node.variable.type, equalsName, node.fileOffset)
.member;
DartType inferredType = writeResult.inferredType;
@@ -1956,6 +1981,32 @@
return new ExpressionInferenceResult(inferredType, replacement);
}
+ ExpressionInferenceResult visitNullAwareExtension(
+ NullAwareExtension node, DartType typeContext) {
+ inferrer.inferStatement(node.variable);
+ ExpressionInferenceResult expressionResult =
+ inferrer.inferExpression(node.expression, const UnknownType(), true);
+ Member equalsMember = inferrer
+ .findInterfaceMember(node.variable.type, equalsName, node.fileOffset)
+ .member;
+
+ DartType inferredType = expressionResult.inferredType;
+
+ Expression replacement;
+ MethodInvocation equalsNull = createEqualsNull(
+ node.fileOffset,
+ new VariableGet(node.variable)..fileOffset = node.fileOffset,
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.fileOffset,
+ node.expression,
+ inferredType);
+ node.replaceWith(replacement = new Let(node.variable, condition)
+ ..fileOffset = node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
ExpressionInferenceResult visitStaticPostIncDec(
StaticPostIncDec node, DartType typeContext) {
inferrer.inferStatement(node.read);
@@ -1996,8 +2047,8 @@
ExpressionInferenceResult visitCompoundPropertySet(
CompoundPropertySet node, DartType typeContext) {
inferrer.inferStatement(node.variable);
- ExpressionInferenceResult writeResult =
- inferrer.inferExpression(node.write, typeContext, true);
+ ExpressionInferenceResult writeResult = inferrer
+ .inferExpression(node.write, typeContext, true, isVoidAllowed: true);
Expression replacement = node.replace();
return new ExpressionInferenceResult(writeResult.inferredType, replacement);
}
@@ -2005,13 +2056,14 @@
ExpressionInferenceResult visitIfNullPropertySet(
IfNullPropertySet node, DartType typeContext) {
inferrer.inferStatement(node.variable);
- ExpressionInferenceResult readResult =
- inferrer.inferExpression(node.read, const UnknownType(), true);
- ExpressionInferenceResult writeResult =
- inferrer.inferExpression(node.write, typeContext, true);
+ ExpressionInferenceResult readResult = inferrer.inferExpression(
+ node.read, const UnknownType(), true,
+ isVoidAllowed: true);
+ ExpressionInferenceResult writeResult = inferrer
+ .inferExpression(node.write, typeContext, true, isVoidAllowed: true);
Member equalsMember = inferrer
.findInterfaceMember(
- readResult.inferredType, new Name('=='), node.fileOffset)
+ readResult.inferredType, equalsName, node.fileOffset)
.member;
DartType inferredType = inferrer.typeSchemaEnvironment
@@ -2058,11 +2110,11 @@
IfNullSet node, DartType typeContext) {
ExpressionInferenceResult readResult =
inferrer.inferExpression(node.read, const UnknownType(), true);
- ExpressionInferenceResult writeResult =
- inferrer.inferExpression(node.write, typeContext, true);
+ ExpressionInferenceResult writeResult = inferrer
+ .inferExpression(node.write, typeContext, true, isVoidAllowed: true);
Member equalsMember = inferrer
.findInterfaceMember(
- readResult.inferredType, new Name('=='), node.fileOffset)
+ readResult.inferredType, equalsName, node.fileOffset)
.member;
DartType inferredType = inferrer.typeSchemaEnvironment
@@ -2110,7 +2162,7 @@
createVariable(node.receiver, receiverType);
ObjectAccessTarget indexSetTarget = inferrer.findInterfaceMember(
- receiverType, new Name('[]='), node.fileOffset,
+ receiverType, indexSetName, node.fileOffset,
includeExtensionMethods: true);
DartType indexType = inferrer.getIndexKeyType(indexSetTarget, receiverType);
@@ -2143,9 +2195,9 @@
assignment = inferrer.helper.buildProblem(
templateUndefinedMethod.withArguments('[]=', receiverType),
node.fileOffset,
- '[]='.length,
- wrapInSyntheticExpression: false);
+ '[]='.length);
} else if (indexSetTarget.isExtensionMember) {
+ assert(indexSetTarget.extensionMethodKind != ProcedureKind.Setter);
assignment = new StaticInvocation(
indexSetTarget.member,
new Arguments(<Expression>[
@@ -2158,7 +2210,7 @@
} else {
assignment = new MethodInvocation(
createVariableGet(receiverVariable),
- new Name('[]='),
+ indexSetName,
new Arguments(<Expression>[
createVariableGet(indexVariable),
createVariableGet(valueVariable)
@@ -2181,17 +2233,88 @@
return new ExpressionInferenceResult(inferredType, replacement);
}
+ ExpressionInferenceResult visitSuperIndexSet(
+ SuperIndexSet node, DartType typeContext) {
+ ObjectAccessTarget indexSetTarget = node.setter != null
+ ? new ObjectAccessTarget.interfaceMember(node.setter)
+ : const ObjectAccessTarget.missing();
+
+ DartType indexType =
+ inferrer.getIndexKeyType(indexSetTarget, inferrer.thisType);
+ DartType valueType =
+ inferrer.getIndexSetValueType(indexSetTarget, inferrer.thisType);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, indexType, true, isVoidAllowed: true);
+
+ inferrer.ensureAssignable(
+ indexType, indexResult.inferredType, node.index, node.index.fileOffset);
+
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ ExpressionInferenceResult valueResult = inferrer
+ .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+ VariableDeclaration valueVariable =
+ createVariable(node.value, valueResult.inferredType);
+
+ // The inferred type is that inferred type of the value expression and not
+ // the type of the value parameter.
+ DartType inferredType = valueResult.inferredType;
+
+ Expression replacement;
+ Expression assignment;
+ if (indexSetTarget.isMissing) {
+ assignment = inferrer.helper.buildProblem(
+ templateSuperclassHasNoMethod.withArguments('[]='),
+ node.fileOffset,
+ '[]='.length);
+ } else {
+ assert(indexSetTarget.isInstanceMember);
+ inferrer.instrumentation?.record(inferrer.uri, node.fileOffset, 'target',
+ new InstrumentationValueForMember(node.setter));
+ assignment = new SuperMethodInvocation(
+ indexSetName,
+ new Arguments(<Expression>[
+ createVariableGet(indexVariable),
+ createVariableGet(valueVariable)
+ ])
+ ..fileOffset = node.fileOffset,
+ indexSetTarget.member)
+ ..fileOffset = node.fileOffset;
+ }
+ VariableDeclaration assignmentVariable =
+ createVariable(assignment, const VoidType());
+ node.replaceWith(replacement = new Let(
+ indexVariable,
+ createLet(valueVariable,
+ createLet(assignmentVariable, createVariableGet(valueVariable))))
+ ..fileOffset = node.fileOffset);
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
ExpressionInferenceResult visitIfNullIndexSet(
IfNullIndexSet node, DartType typeContext) {
ExpressionInferenceResult receiverResult = inferrer.inferExpression(
node.receiver, const UnknownType(), true,
isVoidAllowed: true);
DartType receiverType = receiverResult.inferredType;
- VariableDeclaration receiverVariable =
- createVariable(node.receiver, receiverType);
+ VariableDeclaration receiverVariable;
+ Expression readReceiver;
+ Expression writeReceiver;
+ if (node.readOnlyReceiver) {
+ readReceiver = node.receiver;
+ writeReceiver = readReceiver.accept<TreeNode>(new CloneVisitor());
+ } else {
+ receiverVariable = createVariable(node.receiver, receiverType);
+ readReceiver = createVariableGet(receiverVariable);
+ writeReceiver = createVariableGet(receiverVariable);
+ }
ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
- receiverType, new Name('[]'), node.readOffset,
+ receiverType, indexGetName, node.readOffset,
includeExtensionMethods: true);
MethodContravarianceCheckKind checkKind =
@@ -2202,11 +2325,11 @@
DartType readIndexType = inferrer.getIndexKeyType(readTarget, receiverType);
Member equalsMember = inferrer
- .findInterfaceMember(readType, new Name('=='), node.fileOffset)
+ .findInterfaceMember(readType, equalsName, node.testOffset)
.member;
ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
- receiverType, new Name('[]='), node.fileOffset,
+ receiverType, indexSetName, node.writeOffset,
includeExtensionMethods: true);
DartType writeIndexType =
@@ -2244,21 +2367,20 @@
read = inferrer.helper.buildProblem(
templateUndefinedMethod.withArguments('[]', receiverType),
node.readOffset,
- '[]'.length,
- wrapInSyntheticExpression: false);
+ '[]'.length);
} else if (readTarget.isExtensionMember) {
read = new StaticInvocation(
readTarget.member,
new Arguments(<Expression>[
- createVariableGet(receiverVariable),
+ readReceiver,
readIndex,
], types: readTarget.inferredExtensionTypeArguments)
..fileOffset = node.readOffset)
..fileOffset = node.readOffset;
} else {
read = new MethodInvocation(
- createVariableGet(receiverVariable),
- new Name('[]'),
+ readReceiver,
+ indexGetName,
new Arguments(<Expression>[
readIndex,
])
@@ -2291,48 +2413,50 @@
if (writeTarget.isMissing) {
write = inferrer.helper.buildProblem(
templateUndefinedMethod.withArguments('[]=', receiverType),
- node.fileOffset,
- '[]='.length,
- wrapInSyntheticExpression: false);
+ node.writeOffset,
+ '[]='.length);
} else if (writeTarget.isExtensionMember) {
+ assert(writeTarget.extensionMethodKind != ProcedureKind.Setter);
write = new StaticInvocation(
writeTarget.member,
- new Arguments(<Expression>[
- createVariableGet(receiverVariable),
- writeIndex,
- valueExpression
- ], types: writeTarget.inferredExtensionTypeArguments)
- ..fileOffset = node.fileOffset)
- ..fileOffset = node.fileOffset;
+ new Arguments(
+ <Expression>[writeReceiver, writeIndex, valueExpression],
+ types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.writeOffset)
+ ..fileOffset = node.writeOffset;
} else {
write = new MethodInvocation(
- createVariableGet(receiverVariable),
- new Name('[]='),
+ writeReceiver,
+ indexSetName,
new Arguments(<Expression>[writeIndex, valueExpression])
- ..fileOffset = node.fileOffset,
+ ..fileOffset = node.writeOffset,
writeTarget.member)
- ..fileOffset = node.fileOffset;
+ ..fileOffset = node.writeOffset;
}
- Expression replacement;
+ Expression inner;
if (node.forEffect) {
- // Encode `o[a] ??= b` as:
+ // Encode `o[a] ??= b`, if `node.readOnlyReceiver` is false, as:
//
// let v1 = o in
// let v2 = a in
// let v3 = v1[v2] in
// v3 == null ? v1.[]=(v2, b) : null
//
+ // and if `node.readOnlyReceiver` is true as:
+ //
+ // let v2 = a in
+ // let v3 = o[v2] in
+ // v3 == null ? o.[]=(v2, b) : null
+ //
MethodInvocation equalsNull =
- createEqualsNull(node.fileOffset, read, equalsMember);
+ createEqualsNull(node.testOffset, read, equalsMember);
ConditionalExpression conditional = new ConditionalExpression(equalsNull,
- write, new NullLiteral()..fileOffset = node.fileOffset, inferredType)
- ..fileOffset = node.fileOffset;
- node.replaceWith(replacement =
- new Let(receiverVariable, createLet(indexVariable, conditional))
- ..fileOffset = node.fileOffset);
+ write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
+ ..fileOffset = node.testOffset;
+ inner = createLet(indexVariable, conditional);
} else {
- // Encode `o[a] ??= b` as:
+ // Encode `o[a] ??= b` as, if `node.readOnlyReceiver` is false, as:
//
// let v1 = o in
// let v2 = a in
@@ -2343,11 +2467,22 @@
// v4)
// : v3
//
+ // and if `node.readOnlyReceiver` is true as:
+ //
+ // let v2 = a in
+ // let v3 = o[v2] in
+ // v3 == null
+ // ? (let v4 = b in
+ // let _ = o.[]=(v2, v4) in
+ // v4)
+ // : v3
+ //
+ //
assert(valueVariable != null);
VariableDeclaration readVariable = createVariable(read, readType);
MethodInvocation equalsNull = createEqualsNull(
- node.fileOffset, createVariableGet(readVariable), equalsMember);
+ node.testOffset, createVariableGet(readVariable), equalsMember);
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
ConditionalExpression conditional = new ConditionalExpression(
@@ -2357,10 +2492,157 @@
createVariableGet(readVariable),
inferredType)
..fileOffset = node.fileOffset;
- node.replaceWith(replacement = new Let(receiverVariable,
- createLet(indexVariable, createLet(readVariable, conditional)))
- ..fileOffset = node.fileOffset);
+ inner = createLet(indexVariable, createLet(readVariable, conditional));
}
+
+ Expression replacement;
+ if (receiverVariable != null) {
+ node.replaceWith(replacement = new Let(receiverVariable, inner)
+ ..fileOffset = node.fileOffset);
+ } else {
+ node.replaceWith(replacement = inner);
+ }
+ return new ExpressionInferenceResult(inferredType, replacement);
+ }
+
+ ExpressionInferenceResult visitIfNullSuperIndexSet(
+ IfNullSuperIndexSet node, DartType typeContext) {
+ ObjectAccessTarget readTarget = node.getter != null
+ ? new ObjectAccessTarget.interfaceMember(node.getter)
+ : const ObjectAccessTarget.missing();
+
+ DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
+ DartType readIndexType =
+ inferrer.getIndexKeyType(readTarget, inferrer.thisType);
+
+ Member equalsMember = inferrer
+ .findInterfaceMember(readType, equalsName, node.testOffset)
+ .member;
+
+ ObjectAccessTarget writeTarget = node.setter != null
+ ? new ObjectAccessTarget.interfaceMember(node.setter)
+ : const ObjectAccessTarget.missing();
+
+ DartType writeIndexType =
+ inferrer.getIndexKeyType(writeTarget, inferrer.thisType);
+ DartType valueType =
+ inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ VariableGet readIndex = createVariableGet(indexVariable);
+ inferrer.ensureAssignable(readIndexType, indexResult.inferredType,
+ readIndex, readIndex.fileOffset);
+
+ VariableGet writeIndex = createVariableGet(indexVariable);
+ inferrer.ensureAssignable(writeIndexType, indexResult.inferredType,
+ writeIndex, writeIndex.fileOffset);
+
+ ExpressionInferenceResult valueResult = inferrer
+ .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+
+ DartType inferredType = inferrer.typeSchemaEnvironment
+ .getStandardUpperBound(readType, valueResult.inferredType);
+
+ Expression read;
+
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateSuperclassHasNoMethod.withArguments('[]'),
+ node.readOffset,
+ '[]'.length);
+ } else {
+ assert(readTarget.isInstanceMember);
+ inferrer.instrumentation?.record(inferrer.uri, node.readOffset, 'target',
+ new InstrumentationValueForMember(node.getter));
+ read = new SuperMethodInvocation(
+ indexGetName,
+ new Arguments(<Expression>[
+ readIndex,
+ ])
+ ..fileOffset = node.readOffset,
+ readTarget.member)
+ ..fileOffset = node.readOffset;
+ }
+
+ VariableDeclaration valueVariable;
+ Expression valueExpression;
+ if (node.forEffect) {
+ valueExpression = node.value;
+ } else {
+ valueVariable = createVariable(node.value, valueResult.inferredType);
+ valueExpression = createVariableGet(valueVariable);
+ }
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateSuperclassHasNoMethod.withArguments('[]='),
+ node.writeOffset,
+ '[]='.length);
+ } else {
+ assert(writeTarget.isInstanceMember);
+ inferrer.instrumentation?.record(inferrer.uri, node.writeOffset, 'target',
+ new InstrumentationValueForMember(node.setter));
+ write = new SuperMethodInvocation(
+ indexSetName,
+ new Arguments(
+ <Expression>[createVariableGet(indexVariable), valueExpression])
+ ..fileOffset = node.writeOffset,
+ writeTarget.member)
+ ..fileOffset = node.writeOffset;
+ }
+
+ Expression replacement;
+ if (node.forEffect) {
+ // Encode `o[a] ??= b` as:
+ //
+ // let v1 = a in
+ // super[v1] == null ? super.[]=(v1, b) : null
+ //
+ MethodInvocation equalsNull =
+ createEqualsNull(node.testOffset, read, equalsMember);
+ ConditionalExpression conditional = new ConditionalExpression(equalsNull,
+ write, new NullLiteral()..fileOffset = node.testOffset, inferredType)
+ ..fileOffset = node.testOffset;
+ replacement = createLet(indexVariable, conditional);
+ } else {
+ // Encode `o[a] ??= b` as:
+ //
+ // let v1 = a in
+ // let v2 = super[v1] in
+ // v2 == null
+ // ? (let v3 = b in
+ // let _ = super.[]=(v1, v3) in
+ // v3)
+ // : v2
+ //
+ assert(valueVariable != null);
+
+ VariableDeclaration readVariable = createVariable(read, readType);
+ MethodInvocation equalsNull = createEqualsNull(
+ node.testOffset, createVariableGet(readVariable), equalsMember);
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ ConditionalExpression conditional = new ConditionalExpression(
+ equalsNull,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable))),
+ createVariableGet(readVariable),
+ inferredType)
+ ..fileOffset = node.fileOffset;
+ replacement =
+ createLet(indexVariable, createLet(readVariable, conditional));
+ }
+
+ node.replaceWith(replacement);
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -2370,11 +2652,20 @@
node.receiver, const UnknownType(), true,
isVoidAllowed: true);
DartType receiverType = receiverResult.inferredType;
- VariableDeclaration receiverVariable =
- createVariable(node.receiver, receiverType);
+ VariableDeclaration receiverVariable;
+ Expression readReceiver;
+ Expression writeReceiver;
+ if (node.readOnlyReceiver) {
+ readReceiver = node.receiver;
+ writeReceiver = readReceiver.accept<TreeNode>(new CloneVisitor());
+ } else {
+ receiverVariable = createVariable(node.receiver, receiverType);
+ readReceiver = createVariableGet(receiverVariable);
+ writeReceiver = createVariableGet(receiverVariable);
+ }
ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
- receiverType, new Name('[]'), node.readOffset,
+ receiverType, indexGetName, node.readOffset,
includeExtensionMethods: true);
MethodContravarianceCheckKind readCheckKind =
@@ -2402,21 +2693,20 @@
read = inferrer.helper.buildProblem(
templateUndefinedMethod.withArguments('[]', receiverType),
node.readOffset,
- '[]'.length,
- wrapInSyntheticExpression: false);
+ '[]'.length);
} else if (readTarget.isExtensionMember) {
read = new StaticInvocation(
readTarget.member,
new Arguments(<Expression>[
- createVariableGet(receiverVariable),
+ readReceiver,
readIndex,
], types: readTarget.inferredExtensionTypeArguments)
..fileOffset = node.readOffset)
..fileOffset = node.readOffset;
} else {
read = new MethodInvocation(
- createVariableGet(receiverVariable),
- new Name('[]'),
+ readReceiver,
+ indexGetName,
new Arguments(<Expression>[
readIndex,
])
@@ -2471,11 +2761,247 @@
Expression binary;
if (binaryTarget.isMissing) {
binary = inferrer.helper.buildProblem(
- templateUndefinedMethod.withArguments(
- node.binaryName.name, receiverType),
+ templateUndefinedMethod.withArguments(node.binaryName.name, readType),
node.binaryOffset,
- node.binaryName.name.length,
- wrapInSyntheticExpression: false);
+ node.binaryName.name.length);
+ } else if (binaryTarget.isExtensionMember) {
+ assert(binaryTarget.extensionMethodKind != ProcedureKind.Setter);
+ binary = new StaticInvocation(
+ binaryTarget.member,
+ new Arguments(<Expression>[
+ left,
+ node.rhs,
+ ], types: binaryTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.binaryOffset)
+ ..fileOffset = node.binaryOffset;
+ } else {
+ binary = new MethodInvocation(
+ left,
+ node.binaryName,
+ new Arguments(<Expression>[
+ node.rhs,
+ ])
+ ..fileOffset = node.binaryOffset,
+ binaryTarget.member)
+ ..fileOffset = node.binaryOffset;
+
+ if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.binaryOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ binary = new AsExpression(binary, binaryType)
+ ..isTypeError = true
+ ..fileOffset = node.binaryOffset;
+ }
+ }
+
+ ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+ receiverType, indexSetName, node.writeOffset,
+ includeExtensionMethods: true);
+
+ DartType writeIndexType = inferrer.getPositionalParameterTypeForTarget(
+ writeTarget, receiverType, 0);
+ Expression writeIndex = createVariableGet(indexVariable);
+ Expression writeIndexReplacement = inferrer.ensureAssignable(writeIndexType,
+ indexResult.inferredType, writeIndex, writeIndex.fileOffset);
+ if (writeIndexReplacement != null) {
+ writeIndex = writeIndexReplacement;
+ }
+
+ DartType valueType =
+ inferrer.getIndexSetValueType(writeTarget, receiverType);
+ Expression binaryReplacement = inferrer.ensureAssignable(
+ valueType, binaryType, binary, node.fileOffset);
+ if (binaryReplacement != null) {
+ binary = binaryReplacement;
+ }
+
+ VariableDeclaration valueVariable;
+ Expression valueExpression;
+ if (node.forEffect || node.forPostIncDec) {
+ valueExpression = binary;
+ } else {
+ valueVariable = createVariable(binary, binaryType);
+ valueExpression = createVariableGet(valueVariable);
+ }
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments('[]=', receiverType),
+ node.writeOffset,
+ '[]='.length);
+ } else if (writeTarget.isExtensionMember) {
+ assert(writeTarget.extensionMethodKind != ProcedureKind.Setter);
+ write = new StaticInvocation(
+ writeTarget.member,
+ new Arguments(
+ <Expression>[writeReceiver, writeIndex, valueExpression],
+ types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.writeOffset)
+ ..fileOffset = node.writeOffset;
+ } else {
+ write = new MethodInvocation(
+ writeReceiver,
+ indexSetName,
+ new Arguments(<Expression>[writeIndex, valueExpression])
+ ..fileOffset = node.writeOffset,
+ writeTarget.member)
+ ..fileOffset = node.writeOffset;
+ }
+
+ Expression inner;
+ if (node.forEffect) {
+ assert(leftVariable == null);
+ assert(valueVariable == null);
+ // Encode `o[a] += b` as:
+ //
+ // let v1 = o in let v2 = a in v1.[]=(v2, v1.[](v2) + b)
+ //
+ inner = createLet(indexVariable, write);
+ } else if (node.forPostIncDec) {
+ // Encode `o[a]++` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1.[](v2)
+ // let v4 = v1.[]=(v2, c3 + b) in v3
+ //
+ assert(leftVariable != null);
+ assert(valueVariable == null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ inner = createLet(
+ indexVariable,
+ createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable))));
+ } else {
+ // Encode `o[a] += b` as:
+ //
+ // let v1 = o in
+ // let v2 = a in
+ // let v3 = v1.[](v2) + b
+ // let v4 = v1.[]=(v2, c3) in v3
+ //
+ assert(leftVariable == null);
+ assert(valueVariable != null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ inner = createLet(
+ indexVariable,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable))));
+ }
+
+ Expression replacement;
+ if (receiverVariable != null) {
+ node.replaceWith(replacement = new Let(receiverVariable, inner)
+ ..fileOffset = node.fileOffset);
+ } else {
+ node.replaceWith(replacement = inner);
+ }
+ return new ExpressionInferenceResult(
+ node.forPostIncDec ? readType : binaryType, replacement);
+ }
+
+ ExpressionInferenceResult visitNullAwareCompoundSet(
+ NullAwareCompoundSet node, DartType typeContext) {
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: true);
+ DartType receiverType = receiverResult.inferredType;
+ VariableDeclaration receiverVariable =
+ createVariable(node.receiver, receiverType);
+ Expression readReceiver = createVariableGet(receiverVariable);
+ Expression writeReceiver = createVariableGet(receiverVariable);
+
+ Member equalsMember = inferrer
+ .findInterfaceMember(receiverType, equalsName, node.receiver.fileOffset)
+ .member;
+
+ ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
+ receiverType, node.propertyName, node.readOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind readCheckKind =
+ inferrer.preCheckInvocationContravariance(receiverType, readTarget,
+ isThisReceiver: node.receiver is ThisExpression);
+
+ DartType readType = inferrer.getGetterType(readTarget, receiverType);
+
+ Expression read;
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(
+ node.propertyName.name, receiverType),
+ node.readOffset,
+ node.propertyName.name.length);
+ } else if (readTarget.isExtensionMember) {
+ read = new StaticInvocation(
+ readTarget.member,
+ new Arguments(<Expression>[
+ readReceiver,
+ ], types: readTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.readOffset)
+ ..fileOffset = node.readOffset;
+ } else {
+ read = new PropertyGet(readReceiver, node.propertyName, readTarget.member)
+ ..fileOffset = node.readOffset;
+ if (readCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.readOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ read = new AsExpression(read, readType)
+ ..isTypeError = true
+ ..fileOffset = node.readOffset;
+ }
+ }
+
+ VariableDeclaration leftVariable;
+ Expression left;
+ if (node.forEffect) {
+ left = read;
+ } else if (node.forPostIncDec) {
+ leftVariable = createVariable(read, readType);
+ left = createVariableGet(leftVariable);
+ } else {
+ left = read;
+ }
+
+ ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
+ readType, node.binaryName, node.binaryOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind binaryCheckKind =
+ inferrer.preCheckInvocationContravariance(readType, binaryTarget,
+ isThisReceiver: false);
+
+ DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
+ DartType rhsType =
+ inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
+
+ ExpressionInferenceResult rhsResult =
+ inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ rhsType, rhsResult.inferredType, node.rhs, node.rhs.fileOffset);
+
+ if (inferrer.isOverloadedArithmeticOperatorAndType(
+ binaryTarget, readType)) {
+ binaryType = inferrer.typeSchemaEnvironment
+ .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
+ }
+
+ Expression binary;
+ if (binaryTarget.isMissing) {
+ binary = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(node.binaryName.name, readType),
+ node.binaryOffset,
+ node.binaryName.name.length);
} else if (binaryTarget.isExtensionMember) {
binary = new StaticInvocation(
binaryTarget.member,
@@ -2508,28 +3034,16 @@
}
ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
- receiverType, new Name('[]='), node.writeOffset,
- includeExtensionMethods: true);
+ receiverType, node.propertyName, node.writeOffset,
+ setter: true, includeExtensionMethods: true);
- DartType writeIndexType = inferrer.getPositionalParameterTypeForTarget(
- writeTarget, receiverType, 0);
- Expression writeIndex = createVariableGet(indexVariable);
- Expression writeIndexReplacement = inferrer.ensureAssignable(writeIndexType,
- indexResult.inferredType, writeIndex, writeIndex.fileOffset);
- if (writeIndexReplacement != null) {
- writeIndex = writeIndexReplacement;
- }
-
- DartType valueType =
- inferrer.getIndexSetValueType(writeTarget, receiverType);
+ DartType valueType = inferrer.getSetterType(writeTarget, receiverType);
Expression binaryReplacement = inferrer.ensureAssignable(
valueType, binaryType, binary, node.fileOffset);
if (binaryReplacement != null) {
binary = binaryReplacement;
}
- Expression replacement;
-
VariableDeclaration valueVariable;
Expression valueExpression;
if (node.forEffect || node.forPostIncDec) {
@@ -2543,62 +3057,295 @@
if (writeTarget.isMissing) {
write = inferrer.helper.buildProblem(
- templateUndefinedMethod.withArguments('[]=', receiverType),
+ templateUndefinedMethod.withArguments(
+ node.propertyName.name, receiverType),
node.writeOffset,
- '[]='.length,
- wrapInSyntheticExpression: false);
+ node.propertyName.name.length);
} else if (writeTarget.isExtensionMember) {
write = new StaticInvocation(
writeTarget.member,
- new Arguments(<Expression>[
- createVariableGet(receiverVariable),
- writeIndex,
- valueExpression
- ], types: writeTarget.inferredExtensionTypeArguments)
+ new Arguments(<Expression>[writeReceiver, valueExpression],
+ types: writeTarget.inferredExtensionTypeArguments)
..fileOffset = node.writeOffset)
..fileOffset = node.writeOffset;
} else {
- write = new MethodInvocation(
- createVariableGet(receiverVariable),
- new Name('[]='),
- new Arguments(<Expression>[writeIndex, valueExpression])
- ..fileOffset = node.writeOffset,
- writeTarget.member)
+ write = new PropertySet(
+ writeReceiver, node.propertyName, valueExpression, writeTarget.member)
..fileOffset = node.writeOffset;
}
+ DartType resultType = node.forPostIncDec ? readType : binaryType;
+
+ Expression replacement;
if (node.forEffect) {
assert(leftVariable == null);
assert(valueVariable == null);
- // Encode `o[a] += b` as:
+ // Encode `receiver?.propertyName binaryName= rhs` as:
//
- // let v1 = o in let v2 = a in v1.[]=(v2, v1.[](v2) + b)
+ // let receiverVariable = receiver in
+ // receiverVariable == null ? null :
+ // receiverVariable.propertyName =
+ // receiverVariable.propertyName + rhs
//
- node.replaceWith(replacement =
- new Let(receiverVariable, createLet(indexVariable, write))
- ..fileOffset = node.fileOffset);
+
+ MethodInvocation equalsNull = createEqualsNull(
+ receiverVariable.fileOffset,
+ createVariableGet(receiverVariable),
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(equalsNull,
+ new NullLiteral()..fileOffset = node.readOffset, write, resultType);
+ replacement = createLet(receiverVariable, condition);
} else if (node.forPostIncDec) {
- // Encode `o[a]++` as:
+ // Encode `receiver?.propertyName binaryName= rhs` from a postfix
+ // expression like `o?.a++` as:
//
- // let v1 = o in
- // let v2 = a in
- // let v3 = v1.[](v2)
- // let v4 = v1.[]=(v2, c3 + b) in v3
+ // let receiverVariable = receiver in
+ // receiverVariable == null ? null :
+ // let leftVariable = receiverVariable.propertyName in
+ // let writeVariable =
+ // receiverVariable.propertyName =
+ // leftVariable binaryName rhs in
+ // leftVariable
//
assert(leftVariable != null);
assert(valueVariable == null);
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- node.replaceWith(replacement = new Let(
- receiverVariable,
- createLet(
- indexVariable,
- createLet(leftVariable,
- createLet(writeVariable, createVariableGet(leftVariable)))))
- ..fileOffset = node.fileOffset);
+ MethodInvocation equalsNull = createEqualsNull(
+ receiverVariable.fileOffset,
+ createVariableGet(receiverVariable),
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.readOffset,
+ createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable))),
+ resultType);
+ replacement = createLet(receiverVariable, condition);
} else {
- // Encode `o[a] += b` as:
+ // Encode `receiver?.propertyName binaryName= rhs` as:
+ //
+ // let receiverVariable = receiver in
+ // receiverVariable == null ? null :
+ // let leftVariable = receiverVariable.propertyName in
+ // let valueVariable = leftVariable binaryName rhs in
+ // let writeVariable =
+ // receiverVariable.propertyName = valueVariable in
+ // valueVariable
+ //
+ // TODO(johnniwinther): Do we need the `leftVariable` in this case?
+ assert(leftVariable == null);
+ assert(valueVariable != null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ MethodInvocation equalsNull = createEqualsNull(
+ receiverVariable.fileOffset,
+ createVariableGet(receiverVariable),
+ equalsMember);
+ ConditionalExpression condition = new ConditionalExpression(
+ equalsNull,
+ new NullLiteral()..fileOffset = node.readOffset,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable))),
+ resultType);
+ replacement = createLet(receiverVariable, condition);
+ }
+
+ node.replaceWith(replacement);
+ return new ExpressionInferenceResult(resultType, replacement);
+ }
+
+ ExpressionInferenceResult visitCompoundSuperIndexSet(
+ CompoundSuperIndexSet node, DartType typeContext) {
+ ObjectAccessTarget readTarget = node.getter != null
+ ? new ObjectAccessTarget.interfaceMember(node.getter)
+ : const ObjectAccessTarget.missing();
+
+ DartType readType = inferrer.getReturnType(readTarget, inferrer.thisType);
+ DartType readIndexType = inferrer.getPositionalParameterTypeForTarget(
+ readTarget, inferrer.thisType, 0);
+
+ ExpressionInferenceResult indexResult = inferrer
+ .inferExpression(node.index, readIndexType, true, isVoidAllowed: true);
+ VariableDeclaration indexVariable =
+ createVariable(node.index, indexResult.inferredType);
+
+ Expression readIndex = createVariableGet(indexVariable);
+ Expression readIndexReplacement = inferrer.ensureAssignable(readIndexType,
+ indexResult.inferredType, readIndex, readIndex.fileOffset);
+ if (readIndexReplacement != null) {
+ readIndex = readIndexReplacement;
+ }
+
+ Expression read;
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateSuperclassHasNoMethod.withArguments('[]'),
+ node.readOffset,
+ '[]'.length);
+ } else {
+ assert(readTarget.isInstanceMember);
+ inferrer.instrumentation?.record(inferrer.uri, node.readOffset, 'target',
+ new InstrumentationValueForMember(node.getter));
+ read = new SuperMethodInvocation(
+ indexGetName,
+ new Arguments(<Expression>[
+ readIndex,
+ ])
+ ..fileOffset = node.readOffset,
+ readTarget.member)
+ ..fileOffset = node.readOffset;
+ }
+
+ VariableDeclaration leftVariable;
+ Expression left;
+ if (node.forEffect) {
+ left = read;
+ } else if (node.forPostIncDec) {
+ leftVariable = createVariable(read, readType);
+ left = createVariableGet(leftVariable);
+ } else {
+ left = read;
+ }
+
+ ObjectAccessTarget binaryTarget = inferrer.findInterfaceMember(
+ readType, node.binaryName, node.binaryOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind binaryCheckKind =
+ inferrer.preCheckInvocationContravariance(readType, binaryTarget,
+ isThisReceiver: false);
+
+ DartType binaryType = inferrer.getReturnType(binaryTarget, readType);
+ DartType rhsType =
+ inferrer.getPositionalParameterTypeForTarget(binaryTarget, readType, 0);
+
+ ExpressionInferenceResult rhsResult =
+ inferrer.inferExpression(node.rhs, rhsType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ rhsType, rhsResult.inferredType, node.rhs, node.rhs.fileOffset);
+
+ if (inferrer.isOverloadedArithmeticOperatorAndType(
+ binaryTarget, readType)) {
+ binaryType = inferrer.typeSchemaEnvironment
+ .getTypeOfOverloadedArithmetic(readType, rhsResult.inferredType);
+ }
+
+ Expression binary;
+ if (binaryTarget.isMissing) {
+ binary = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(node.binaryName.name, readType),
+ node.binaryOffset,
+ node.binaryName.name.length);
+ } else if (binaryTarget.isExtensionMember) {
+ binary = new StaticInvocation(
+ binaryTarget.member,
+ new Arguments(<Expression>[
+ left,
+ node.rhs,
+ ], types: binaryTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.binaryOffset)
+ ..fileOffset = node.binaryOffset;
+ } else {
+ binary = new MethodInvocation(
+ left,
+ node.binaryName,
+ new Arguments(<Expression>[
+ node.rhs,
+ ])
+ ..fileOffset = node.binaryOffset,
+ binaryTarget.member)
+ ..fileOffset = node.binaryOffset;
+
+ if (binaryCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.binaryOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ binary = new AsExpression(binary, binaryType)
+ ..isTypeError = true
+ ..fileOffset = node.binaryOffset;
+ }
+ }
+
+ ObjectAccessTarget writeTarget = node.setter != null
+ ? new ObjectAccessTarget.interfaceMember(node.setter)
+ : const ObjectAccessTarget.missing();
+
+ DartType writeIndexType = inferrer.getPositionalParameterTypeForTarget(
+ writeTarget, inferrer.thisType, 0);
+ Expression writeIndex = createVariableGet(indexVariable);
+ Expression writeIndexReplacement = inferrer.ensureAssignable(writeIndexType,
+ indexResult.inferredType, writeIndex, writeIndex.fileOffset);
+ if (writeIndexReplacement != null) {
+ writeIndex = writeIndexReplacement;
+ }
+
+ DartType valueType =
+ inferrer.getIndexSetValueType(writeTarget, inferrer.thisType);
+ Expression binaryReplacement = inferrer.ensureAssignable(
+ valueType, binaryType, binary, node.fileOffset);
+ if (binaryReplacement != null) {
+ binary = binaryReplacement;
+ }
+
+ VariableDeclaration valueVariable;
+ Expression valueExpression;
+ if (node.forEffect || node.forPostIncDec) {
+ valueExpression = binary;
+ } else {
+ valueVariable = createVariable(binary, binaryType);
+ valueExpression = createVariableGet(valueVariable);
+ }
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateSuperclassHasNoMethod.withArguments('[]='),
+ node.writeOffset,
+ '[]='.length);
+ } else {
+ assert(writeTarget.isInstanceMember);
+ inferrer.instrumentation?.record(inferrer.uri, node.writeOffset, 'target',
+ new InstrumentationValueForMember(node.setter));
+ write = new SuperMethodInvocation(
+ indexSetName,
+ new Arguments(<Expression>[writeIndex, valueExpression])
+ ..fileOffset = node.writeOffset,
+ writeTarget.member)
+ ..fileOffset = node.writeOffset;
+ }
+
+ Expression replacement;
+ if (node.forEffect) {
+ assert(leftVariable == null);
+ assert(valueVariable == null);
+ // Encode `super[a] += b` as:
+ //
+ // let v1 = a in super.[]=(v1, super.[](v1) + b)
+ //
+ replacement = createLet(indexVariable, write);
+ } else if (node.forPostIncDec) {
+ // Encode `super[a]++` as:
+ //
+ // let v2 = a in
+ // let v3 = v1.[](v2)
+ // let v4 = v1.[]=(v2, v3 + 1) in v3
+ //
+ assert(leftVariable != null);
+ assert(valueVariable == null);
+
+ VariableDeclaration writeVariable =
+ createVariable(write, const VoidType());
+ replacement = createLet(
+ indexVariable,
+ createLet(leftVariable,
+ createLet(writeVariable, createVariableGet(leftVariable))));
+ } else {
+ // Encode `super[a] += b` as:
//
// let v1 = o in
// let v2 = a in
@@ -2610,14 +3357,13 @@
VariableDeclaration writeVariable =
createVariable(write, const VoidType());
- node.replaceWith(replacement = new Let(
- receiverVariable,
- createLet(
- indexVariable,
- createLet(valueVariable,
- createLet(writeVariable, createVariableGet(valueVariable)))))
- ..fileOffset = node.fileOffset);
+ replacement = createLet(
+ indexVariable,
+ createLet(valueVariable,
+ createLet(writeVariable, createVariableGet(valueVariable))));
}
+
+ node.replaceWith(replacement);
return new ExpressionInferenceResult(
node.forPostIncDec ? readType : binaryType, replacement);
}
@@ -2631,9 +3377,6 @@
@override
ExpressionInferenceResult visitLet(Let node, DartType typeContext) {
DartType variableType = node.variable.type;
- if (variableType == const DynamicType()) {
- return defaultExpression(node, typeContext);
- }
inferrer.inferExpression(node.variable.initializer, variableType, true,
isVoidAllowed: true);
ExpressionInferenceResult result = inferrer
@@ -2644,15 +3387,11 @@
@override
ExpressionInferenceResult visitPropertySet(
- PropertySet node, DartType typeContext) {
- DartType receiverType;
- if (node.receiver != null) {
- receiverType = inferrer
- .inferExpression(node.receiver, const UnknownType(), true)
- .inferredType;
- } else {
- receiverType = inferrer.thisType;
- }
+ covariant PropertySetImpl node, DartType typeContext) {
+ DartType receiverType = inferrer
+ .inferExpression(node.receiver, const UnknownType(), true,
+ isVoidAllowed: false)
+ .inferredType;
ObjectAccessTarget target =
inferrer.findPropertySetMember(receiverType, node);
DartType writeContext = inferrer.getSetterType(target, receiverType);
@@ -2665,70 +3404,215 @@
isVoidAllowed: writeContext is VoidType);
Expression replacement;
if (target.isExtensionMember) {
- node.parent.replaceChild(
- node,
- replacement = inferrer.helper.forest.createStaticInvocation(
- node.fileOffset,
- target.member,
- inferrer.helper.forest.createArgumentsForExtensionMethod(
- node.fileOffset,
- target.inferredExtensionTypeArguments.length,
- 0,
- node.receiver,
- extensionTypeArguments: target.inferredExtensionTypeArguments,
- positionalArguments: [node.value])));
+ if (node.forEffect) {
+ replacement = new StaticInvocation(
+ target.member,
+ new Arguments(<Expression>[node.receiver, node.value],
+ types: target.inferredExtensionTypeArguments)
+ ..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset;
+ } else {
+ Expression receiver;
+ VariableDeclaration receiverVariable;
+ if (node.readOnlyReceiver) {
+ receiver = node.receiver;
+ } else {
+ receiverVariable = createVariable(node.receiver, receiverType);
+ receiver = createVariableGet(receiverVariable);
+ }
+ VariableDeclaration valueVariable = createVariable(node.value, rhsType);
+ VariableDeclaration assignmentVariable = createVariable(
+ new StaticInvocation(
+ target.member,
+ new Arguments(
+ <Expression>[receiver, createVariableGet(valueVariable)],
+ types: target.inferredExtensionTypeArguments)
+ ..fileOffset = node.fileOffset)
+ ..fileOffset = node.fileOffset,
+ const VoidType());
+ replacement = createLet(valueVariable,
+ createLet(assignmentVariable, createVariableGet(valueVariable)));
+ if (receiverVariable != null) {
+ replacement = createLet(receiverVariable, replacement);
+ }
+ replacement..fileOffset = node.fileOffset;
+ }
+ node.replaceWith(replacement);
}
return new ExpressionInferenceResult(rhsType, replacement);
}
- ExpressionInferenceResult visitPropertyAssignmentJudgment(
- PropertyAssignmentJudgment node, DartType typeContext) {
- DartType receiverType = node._inferReceiver(inferrer);
+ ExpressionInferenceResult visitNullAwareIfNullSet(
+ NullAwareIfNullSet node, DartType typeContext) {
+ ExpressionInferenceResult receiverResult = inferrer.inferExpression(
+ node.receiver, const UnknownType(), true,
+ isVoidAllowed: false);
+ DartType receiverType = receiverResult.inferredType;
+ VariableDeclaration receiverVariable =
+ createVariable(node.receiver, receiverType);
+ Expression readReceiver = createVariableGet(receiverVariable);
+ Expression writeReceiver = createVariableGet(receiverVariable);
- DartType readType;
- if (node.read != null) {
- ObjectAccessTarget readTarget = inferrer
- .findPropertyGetMember(receiverType, node.read, instrumented: false);
- readType = inferrer.getGetterType(readTarget, receiverType);
- inferrer.handlePropertyGetContravariance(
- node.receiver,
- readTarget,
- node.read is PropertyGet ? node.read : null,
- node.read,
- readType,
- node.read.fileOffset);
- node._storeLetType(inferrer, node.read, readType);
- }
- ObjectAccessTarget writeTarget;
- if (node.write != null) {
- writeTarget = node._handleWriteContravariance(inferrer, receiverType);
- }
- // To replicate analyzer behavior, we base type inference on the write
- // member. TODO(paulberry): would it be better to use the read member when
- // doing compound assignment?
- DartType writeContext = inferrer.getSetterType(writeTarget, receiverType);
- DartType inferredType =
- node._inferRhs(inferrer, readType, writeContext).inferredType;
- node.nullAwareGuard?.staticType = inferredType;
- Expression replacement;
- if (writeTarget.isExtensionMember) {
- node.parent.replaceChild(
- node,
- replacement = inferrer.helper.forest.createStaticInvocation(
- node.fileOffset,
- writeTarget.member,
- inferrer.helper.forest.createArgumentsForExtensionMethod(
- node.fileOffset,
- writeTarget.inferredExtensionTypeArguments.length,
- 0,
- node.receiver,
- extensionTypeArguments:
- writeTarget.inferredExtensionTypeArguments,
- positionalArguments: [node.rhs])));
+ Member receiverEqualsMember = inferrer
+ .findInterfaceMember(receiverType, equalsName, node.receiver.fileOffset)
+ .member;
+
+ ObjectAccessTarget readTarget = inferrer.findInterfaceMember(
+ receiverType, node.name, node.readOffset,
+ includeExtensionMethods: true);
+
+ MethodContravarianceCheckKind readCheckKind =
+ inferrer.preCheckInvocationContravariance(receiverType, readTarget,
+ isThisReceiver: node.receiver is ThisExpression);
+
+ DartType readType = inferrer.getGetterType(readTarget, receiverType);
+
+ Member readEqualsMember = inferrer
+ .findInterfaceMember(readType, equalsName, node.testOffset)
+ .member;
+
+ Expression read;
+ if (readTarget.isMissing) {
+ read = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(node.name.name, receiverType),
+ node.readOffset,
+ node.name.name.length);
+ } else if (readTarget.isExtensionMember) {
+ read = new StaticInvocation(
+ readTarget.member,
+ new Arguments(<Expression>[
+ readReceiver,
+ ], types: readTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.readOffset)
+ ..fileOffset = node.readOffset;
} else {
- node._replaceWithDesugared();
+ read = new PropertyGet(readReceiver, node.name, readTarget.member)
+ ..fileOffset = node.readOffset;
+ if (readCheckKind == MethodContravarianceCheckKind.checkMethodReturn) {
+ if (inferrer.instrumentation != null) {
+ inferrer.instrumentation.record(inferrer.uri, node.readOffset,
+ 'checkReturn', new InstrumentationValueForType(readType));
+ }
+ read = new AsExpression(read, readType)
+ ..isTypeError = true
+ ..fileOffset = node.readOffset;
+ }
}
+ VariableDeclaration readVariable;
+ if (!node.forEffect) {
+ readVariable = createVariable(read, readType);
+ read = createVariableGet(readVariable);
+ }
+
+ ObjectAccessTarget writeTarget = inferrer.findInterfaceMember(
+ receiverType, node.name, node.writeOffset,
+ setter: true, includeExtensionMethods: true);
+
+ DartType valueType = inferrer.getSetterType(writeTarget, receiverType);
+
+ ExpressionInferenceResult valueResult = inferrer
+ .inferExpression(node.value, valueType, true, isVoidAllowed: true);
+ inferrer.ensureAssignable(
+ valueType, valueResult.inferredType, node.value, node.value.fileOffset);
+
+ Expression write;
+
+ if (writeTarget.isMissing) {
+ write = inferrer.helper.buildProblem(
+ templateUndefinedMethod.withArguments(node.name.name, receiverType),
+ node.writeOffset,
+ node.name.name.length);
+ } else if (writeTarget.isExtensionMember) {
+ if (node.forEffect) {
+ write = new StaticInvocation(
+ writeTarget.member,
+ new Arguments(<Expression>[writeReceiver, node.value],
+ types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.writeOffset)
+ ..fileOffset = node.writeOffset;
+ } else {
+ VariableDeclaration valueVariable =
+ createVariable(node.value, valueResult.inferredType);
+ VariableDeclaration assignmentVariable = createVariable(
+ new StaticInvocation(
+ writeTarget.member,
+ new Arguments(<Expression>[
+ writeReceiver,
+ createVariableGet(valueVariable)
+ ], types: writeTarget.inferredExtensionTypeArguments)
+ ..fileOffset = node.writeOffset)
+ ..fileOffset = node.writeOffset,
+ const VoidType());
+ write = createLet(valueVariable,
+ createLet(assignmentVariable, createVariableGet(valueVariable)))
+ ..fileOffset = node.writeOffset;
+ }
+ } else {
+ write = new PropertySet(
+ writeReceiver, node.name, node.value, writeTarget.member)
+ ..fileOffset = node.writeOffset;
+ }
+
+ DartType inferredType = inferrer.typeSchemaEnvironment
+ .getStandardUpperBound(readType, valueResult.inferredType);
+
+ Expression replacement;
+ if (node.forEffect) {
+ assert(readVariable == null);
+ // Encode `receiver?.name ??= value` as:
+ //
+ // let receiverVariable = receiver in
+ // receiverVariable == null ? null :
+ // (receiverVariable.name == null ?
+ // receiverVariable.name = value : null)
+ //
+
+ MethodInvocation receiverEqualsNull = createEqualsNull(
+ receiverVariable.fileOffset,
+ createVariableGet(receiverVariable),
+ receiverEqualsMember);
+ MethodInvocation readEqualsNull =
+ createEqualsNull(node.readOffset, read, readEqualsMember);
+ ConditionalExpression innerCondition = new ConditionalExpression(
+ readEqualsNull,
+ write,
+ new NullLiteral()..fileOffset = node.writeOffset,
+ inferredType);
+ ConditionalExpression outerCondition = new ConditionalExpression(
+ receiverEqualsNull,
+ new NullLiteral()..fileOffset = node.readOffset,
+ innerCondition,
+ inferredType);
+ replacement = createLet(receiverVariable, outerCondition);
+ } else {
+ // Encode `receiver?.name ??= value` as:
+ //
+ // let receiverVariable = receiver in
+ // receiverVariable == null ? null :
+ // (let readVariable = receiverVariable.name in
+ // readVariable == null ?
+ // receiverVariable.name = value : readVariable)
+ //
+ assert(readVariable != null);
+
+ MethodInvocation receiverEqualsNull = createEqualsNull(
+ receiverVariable.fileOffset,
+ createVariableGet(receiverVariable),
+ receiverEqualsMember);
+ MethodInvocation readEqualsNull =
+ createEqualsNull(receiverVariable.fileOffset, read, readEqualsMember);
+ ConditionalExpression innerCondition = new ConditionalExpression(
+ readEqualsNull, write, createVariableGet(readVariable), inferredType);
+ ConditionalExpression outerCondition = new ConditionalExpression(
+ receiverEqualsNull,
+ new NullLiteral()..fileOffset = node.readOffset,
+ createLet(readVariable, innerCondition),
+ inferredType);
+ replacement = createLet(receiverVariable, outerCondition);
+ }
+
+ node.replaceWith(replacement);
return new ExpressionInferenceResult(inferredType, replacement);
}
@@ -2880,28 +3764,6 @@
return new ExpressionInferenceResult(rhsType);
}
- ExpressionInferenceResult visitStaticAssignmentJudgment(
- StaticAssignmentJudgment node, DartType typeContext) {
- DartType readType = const DynamicType(); // Only used in error recovery
- Expression read = node.read;
- if (read is StaticGet) {
- readType = read.target.getterType;
- node._storeLetType(inferrer, read, readType);
- }
- Member writeMember;
- DartType writeContext = const UnknownType();
- Expression write = node.write;
- if (write is StaticSet) {
- writeContext = write.target.setterType;
- writeMember = write.target;
- TypeInferenceEngine.resolveInferenceNode(writeMember);
- }
- DartType inferredType =
- node._inferRhs(inferrer, readType, writeContext).inferredType;
- node._replaceWithDesugared();
- return new ExpressionInferenceResult(inferredType);
- }
-
@override
ExpressionInferenceResult visitStaticGet(
StaticGet node, DartType typeContext) {
@@ -2940,7 +3802,8 @@
if (!inferrer.isTopLevel) {
for (Expression expression in node.expressions) {
inferrer.inferExpression(
- expression, const UnknownType(), !inferrer.isTopLevel);
+ expression, const UnknownType(), !inferrer.isTopLevel,
+ isVoidAllowed: false);
}
}
return new ExpressionInferenceResult(
@@ -3027,13 +3890,15 @@
@override
void visitSwitchStatement(SwitchStatement node) {
DartType expressionType = inferrer
- .inferExpression(node.expression, const UnknownType(), true)
+ .inferExpression(node.expression, const UnknownType(), true,
+ isVoidAllowed: false)
.inferredType;
for (SwitchCase switchCase in node.cases) {
for (Expression caseExpression in switchCase.expressions) {
ExpressionInferenceResult caseExpressionResult =
- inferrer.inferExpression(caseExpression, expressionType, true);
+ inferrer.inferExpression(caseExpression, expressionType, true,
+ isVoidAllowed: false);
if (caseExpressionResult.replacement != null) {
caseExpression = caseExpressionResult.replacement;
}
@@ -3065,41 +3930,6 @@
return new ExpressionInferenceResult(inferredType);
}
- ExpressionInferenceResult visitInvalidConstructorInvocationJudgment(
- InvalidConstructorInvocationJudgment node, DartType typeContext) {
- FunctionType calleeType;
- DartType returnType;
- if (node.constructor != null) {
- calleeType = node.constructor.function.thisFunctionType;
- returnType = computeConstructorReturnType(node.constructor);
- } else {
- calleeType = new FunctionType([], const DynamicType());
- returnType = const DynamicType();
- }
- DartType inferredType = inferrer.inferInvocation(
- typeContext, node.fileOffset, calleeType, returnType, node.arguments);
- node._replaceWithDesugared();
- return new ExpressionInferenceResult(inferredType);
- }
-
- ExpressionInferenceResult visitInvalidWriteJudgment(
- InvalidWriteJudgment node, DartType typeContext) {
- // When a compound assignment, the expression is already wrapping in
- // VariableDeclaration in _makeRead(). Otherwise, temporary associate
- // the expression with this node.
- node.expression.parent ??= node;
-
- inferrer.inferExpression(
- node.expression, const UnknownType(), !inferrer.isTopLevel);
- return visitSyntheticExpressionJudgment(node, typeContext);
- }
-
- ExpressionInferenceResult visitSyntheticExpressionJudgment(
- SyntheticExpressionJudgment node, DartType typeContext) {
- node._replaceWithDesugared();
- return const ExpressionInferenceResult(const DynamicType());
- }
-
ExpressionInferenceResult visitThisExpression(
ThisExpression node, DartType typeContext) {
return new ExpressionInferenceResult(inferrer.thisType);
@@ -3108,7 +3938,8 @@
@override
ExpressionInferenceResult visitThrow(Throw node, DartType typeContext) {
inferrer.inferExpression(
- node.expression, const UnknownType(), !inferrer.isTopLevel);
+ node.expression, const UnknownType(), !inferrer.isTopLevel,
+ isVoidAllowed: false);
return const ExpressionInferenceResult(const BottomType());
}
@@ -3152,27 +3983,6 @@
return new ExpressionInferenceResult(rhsType);
}
- ExpressionInferenceResult visitVariableAssignmentJudgment(
- VariableAssignmentJudgment node, DartType typeContext) {
- DartType readType;
- Expression read = node.read;
- if (read is VariableGet) {
- readType = read.promotedType ?? read.variable.type;
- }
- DartType writeContext = const UnknownType();
- Expression write = node.write;
- if (write is VariableSet) {
- writeContext = write.variable.type;
- if (read != null) {
- node._storeLetType(inferrer, read, writeContext);
- }
- }
- DartType inferredType =
- node._inferRhs(inferrer, readType, writeContext).inferredType;
- node._replaceWithDesugared();
- return new ExpressionInferenceResult(inferredType);
- }
-
@override
void visitVariableDeclaration(covariant VariableDeclarationImpl node) {
DartType declaredType =
@@ -3213,29 +4023,6 @@
}
}
- ExpressionInferenceResult visitUnresolvedTargetInvocationJudgment(
- UnresolvedTargetInvocationJudgment node, DartType typeContext) {
- ExpressionInferenceResult result =
- visitSyntheticExpressionJudgment(node, typeContext);
- inferrer.inferInvocation(
- typeContext,
- node.fileOffset,
- TypeInferrerImpl.unknownFunction,
- const DynamicType(),
- node.argumentsJudgment);
- return result;
- }
-
- ExpressionInferenceResult visitUnresolvedVariableAssignmentJudgment(
- UnresolvedVariableAssignmentJudgment node, DartType typeContext) {
- DartType rhsType = inferrer
- .inferExpression(node.rhs, const UnknownType(), true)
- .inferredType;
- DartType inferredType = node.isCompound ? const DynamicType() : rhsType;
- node._replaceWithDesugared();
- return new ExpressionInferenceResult(inferredType);
- }
-
@override
ExpressionInferenceResult visitVariableGet(
covariant VariableGetImpl node, DartType typeContext) {
@@ -3262,7 +4049,8 @@
InterfaceType expectedType =
inferrer.coreTypes.boolRawType(inferrer.library.nonNullable);
DartType conditionType = inferrer
- .inferExpression(node.condition, expectedType, !inferrer.isTopLevel)
+ .inferExpression(node.condition, expectedType, !inferrer.isTopLevel,
+ isVoidAllowed: false)
.inferredType;
inferrer.ensureAssignable(
expectedType, conditionType, node.condition, node.condition.fileOffset);
@@ -3283,11 +4071,13 @@
: inferrer.coreTypes.iterableClass);
}
inferredType = inferrer
- .inferExpression(node.expression, typeContext, true)
+ .inferExpression(node.expression, typeContext, true,
+ isVoidAllowed: true)
.inferredType;
} else {
inferredType = inferrer
- .inferExpression(node.expression, const UnknownType(), true)
+ .inferExpression(node.expression, const UnknownType(), true,
+ isVoidAllowed: true)
.inferredType;
}
closureContext.handleYield(inferrer, node.isYieldStar, inferredType,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 65f8ccf..975c09a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -86,11 +86,9 @@
show
ArgumentsImpl,
Cascade,
- ComplexAssignmentJudgment,
DeferredCheck,
FactoryConstructorInvocationJudgment,
FunctionDeclarationImpl,
- IfNullJudgment,
InvalidSuperInitializerJudgment,
LoadLibraryTearOff,
MethodInvocationImpl,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 99d2714..294aa54 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -24,6 +24,8 @@
import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/clone.dart';
+
import '../../base/instrumentation.dart'
show
Instrumentation,
@@ -50,11 +52,14 @@
templateSpreadMapEntryElementValueTypeMismatch,
templateSpreadMapEntryTypeMismatch,
templateSpreadTypeMismatch,
+ templateSuperclassHasNoMethod,
templateSwitchExpressionNotAssignable,
templateUndefinedMethod,
templateWebLiteralCannotBeRepresentedExactly;
-import '../problems.dart' show getFileUri, unhandled, unsupported;
+import '../names.dart';
+
+import '../problems.dart' show unhandled, unsupported;
import '../source/source_class_builder.dart' show SourceClassBuilder;
@@ -75,7 +80,7 @@
import '../type_inference/type_schema_elimination.dart' show greatestClosure;
import '../type_inference/type_schema_environment.dart'
- show TypeSchemaEnvironment, getPositionalParameterType;
+ show TypeSchemaEnvironment;
import 'body_builder.dart' show combineStatements;
@@ -181,18 +186,26 @@
Cascade,
CompoundIndexSet,
CompoundPropertySet,
+ CompoundSuperIndexSet,
DeferredCheck,
+ ExtensionSet,
+ IfNull,
IfNullIndexSet,
IfNullPropertySet,
IfNullSet,
+ IfNullSuperIndexSet,
IndexSet,
LoadLibraryTearOff,
LocalPostIncDec,
+ NullAwareCompoundSet,
+ NullAwareExtension,
+ NullAwareIfNullSet,
NullAwareMethodInvocation,
NullAwarePropertyGet,
NullAwarePropertySet,
PropertyPostIncDec,
StaticPostIncDec,
+ SuperIndexSet,
SuperPostIncDec,
}
@@ -387,216 +400,6 @@
}
}
-/// Abstract shadow object representing a complex assignment in kernel form.
-///
-/// Since there are many forms a complex assignment might have been desugared
-/// to, this class wraps the desugared assignment rather than extending it.
-///
-/// TODO(paulberry): once we know exactly what constitutes a "complex
-/// assignment", document it here.
-abstract class ComplexAssignmentJudgment extends SyntheticExpressionJudgment {
- /// In a compound assignment, the expression that reads the old value, or
- /// `null` if this is not a compound assignment.
- Expression read;
-
- /// The expression appearing on the RHS of the assignment.
- Expression rhs;
-
- /// The expression that performs the write (e.g. `a.[]=(b, a.[](b) + 1)` in
- /// `++a[b]`).
- Expression write;
-
- /// In a compound assignment without shortcut semantics, the expression that
- /// combines the old and new values, or `null` if this is not a compound
- /// assignment.
- ///
- /// Note that in a compound assignment with shortcut semantics, this is not
- /// used; [nullAwareCombiner] is used instead.
- MethodInvocation combiner;
-
- /// In a compound assignment with shortcut semantics, the conditional
- /// expression that determines whether the assignment occurs.
- ///
- /// Note that in a compound assignment without shortcut semantics, this is not
- /// used; [combiner] is used instead.
- ConditionalExpression nullAwareCombiner;
-
- /// Indicates whether the expression arose from a post-increment or
- /// post-decrement.
- bool isPostIncDec = false;
-
- /// Indicates whether the expression arose from a pre-increment or
- /// pre-decrement.
- bool isPreIncDec = false;
-
- ComplexAssignmentJudgment._(this.rhs) : super._(null);
-
- String toString() {
- List<String> parts = _getToStringParts();
- return '${runtimeType}(${parts.join(', ')})';
- }
-
- List<String> _getToStringParts() {
- List<String> parts = [];
- if (desugared != null) parts.add('desugared=$desugared');
- if (read != null) parts.add('read=$read');
- if (rhs != null) parts.add('rhs=$rhs');
- if (write != null) parts.add('write=$write');
- if (combiner != null) parts.add('combiner=$combiner');
- if (nullAwareCombiner != null) {
- parts.add('nullAwareCombiner=$nullAwareCombiner');
- }
- if (isPostIncDec) parts.add('isPostIncDec=true');
- if (isPreIncDec) parts.add('isPreIncDec=true');
- return parts;
- }
-
- _ComplexAssignmentInferenceResult _inferRhs(
- ShadowTypeInferrer inferrer, DartType readType, DartType writeContext) {
- assert(writeContext != null);
- if (readType is VoidType &&
- (combiner != null || nullAwareCombiner != null)) {
- inferrer.helper
- ?.addProblem(messageVoidExpression, read.fileOffset, noLength);
- }
- int writeOffset = write == null ? -1 : write.fileOffset;
- ObjectAccessTarget combinerTarget = const ObjectAccessTarget.unresolved();
- DartType combinedType;
- if (combiner != null) {
- bool isOverloadedArithmeticOperator = false;
- combinerTarget = inferrer.findMethodInvocationMember(readType, combiner,
- instrumented: false);
- assert(!combinerTarget.isCallFunction);
- if (combinerTarget.isInstanceMember &&
- combinerTarget.member is Procedure) {
- isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment
- .isOverloadedArithmeticOperatorAndType(
- combinerTarget.member, readType);
- }
- DartType rhsType;
- FunctionType combinerType =
- inferrer.getFunctionType(combinerTarget, readType, false);
- if (isPreIncDec || isPostIncDec) {
- rhsType = inferrer.coreTypes.intRawType(inferrer.library.nonNullable);
- } else {
- // It's not necessary to call _storeLetType for [rhs] because the RHS
- // is always passed directly to the combiner; it's never stored in a
- // temporary variable first.
- assert(identical(combiner.arguments.positional.first, rhs));
- // Analyzer uses a null context for the RHS here.
- // TODO(paulberry): improve on this.
- ExpressionInferenceResult rhsResult =
- inferrer.inferExpression(rhs, const UnknownType(), true);
- if (rhsResult.replacement != null) {
- rhs = rhsResult.replacement;
- }
- rhsType = rhsResult.inferredType;
- // Do not use rhs after this point because it may be a Shadow node
- // that has been replaced in the tree with its desugaring.
- DartType expectedType = getPositionalParameterType(combinerType, 0);
- inferrer.ensureAssignable(expectedType, rhsType,
- combiner.arguments.positional.first, combiner.fileOffset);
- }
- if (isOverloadedArithmeticOperator) {
- combinedType = inferrer.typeSchemaEnvironment
- .getTypeOfOverloadedArithmetic(readType, rhsType);
- } else {
- combinedType = combinerType.returnType;
- }
- MethodContravarianceCheckKind checkKind =
- inferrer.preCheckInvocationContravariance(readType, combinerTarget,
- isThisReceiver: read is ThisExpression);
- Expression replacedCombiner = inferrer.handleInvocationContravariance(
- checkKind,
- combiner,
- combiner.arguments,
- combiner,
- combinedType,
- combinerType,
- combiner.fileOffset);
- Expression replacedCombiner2 = inferrer.ensureAssignable(
- writeContext, combinedType, replacedCombiner, writeOffset);
- if (replacedCombiner2 != null) {
- replacedCombiner = replacedCombiner2;
- }
- _storeLetType(inferrer, replacedCombiner, combinedType);
- } else {
- ExpressionInferenceResult rhsResult = inferrer.inferExpression(
- rhs, writeContext ?? const UnknownType(), true,
- isVoidAllowed: true);
- if (rhsResult.replacement != null) {
- rhs = rhsResult.replacement;
- }
- DartType rhsType = rhsResult.inferredType;
- Expression replacedRhs = inferrer.ensureAssignable(
- writeContext, rhsType, rhs, writeOffset,
- isVoidAllowed: writeContext is VoidType);
- _storeLetType(inferrer, replacedRhs ?? rhs, rhsType);
- if (nullAwareCombiner != null) {
- MethodInvocation equalsInvocation = nullAwareCombiner.condition;
- inferrer.findMethodInvocationMember(
- greatestClosure(inferrer.coreTypes, writeContext), equalsInvocation,
- instrumented: false);
- // Note: the case of readType=null only happens for erroneous code.
- combinedType = readType == null
- ? rhsType
- : inferrer.typeSchemaEnvironment
- .getStandardUpperBound(readType, rhsType);
- nullAwareCombiner.staticType = combinedType;
- } else {
- combinedType = rhsType;
- }
- }
- if (this is IndexAssignmentJudgment) {
- _storeLetType(inferrer, write, const VoidType());
- } else {
- _storeLetType(inferrer, write, combinedType);
- }
- DartType inferredType =
- isPostIncDec ? (readType ?? const DynamicType()) : combinedType;
- return new _ComplexAssignmentInferenceResult(
- combinerTarget.member, inferredType);
- }
-}
-
-/// Abstract shadow object representing a complex assignment involving a
-/// receiver.
-abstract class ComplexAssignmentJudgmentWithReceiver
- extends ComplexAssignmentJudgment {
- /// The receiver of the assignment target (e.g. `a` in `a[b] = c`).
- final Expression receiver;
-
- /// Indicates whether this assignment uses `super`.
- final bool isSuper;
-
- ComplexAssignmentJudgmentWithReceiver._(
- this.receiver, Expression rhs, this.isSuper)
- : super._(rhs);
-
- @override
- List<String> _getToStringParts() {
- List<String> parts = super._getToStringParts();
- if (receiver != null) parts.add('receiver=$receiver');
- if (isSuper) parts.add('isSuper=true');
- return parts;
- }
-
- DartType _inferReceiver(ShadowTypeInferrer inferrer) {
- if (receiver != null) {
- DartType receiverType = inferrer
- .inferExpression(receiver, const UnknownType(), true)
- .inferredType;
- _storeLetType(inferrer, receiver, receiverType);
- return receiverType;
- } else if (isSuper) {
- return inferrer.classHierarchy.getTypeAsInstanceOf(
- inferrer.thisType, inferrer.thisType.classNode.supertype.classNode);
- } else {
- return inferrer.thisType;
- }
- }
-}
-
/// Internal expression representing a deferred check.
// TODO(johnniwinther): Change the representation to be direct and perform
// the [Let] encoding in [replace].
@@ -695,84 +498,40 @@
}
}
-/// Concrete shadow object representing an if-null expression.
+/// Internal expression representing an if-null expression.
///
-/// An if-null expression of the form `a ?? b` is represented as the kernel
-/// expression:
+/// An if-null expression of the form `a ?? b` is encoded as:
///
/// let v = a in v == null ? b : v
-class IfNullJudgment extends Let implements ExpressionJudgment {
- IfNullJudgment(VariableDeclaration variable, Expression body)
- : super(variable, body);
+///
+class IfNullExpression extends InternalExpression {
+ Expression left;
+ Expression right;
- @override
- ConditionalExpression get body => super.body;
-
- /// Returns the expression to the left of `??`.
- Expression get left => variable.initializer;
-
- /// Returns the expression to the right of `??`.
- Expression get right => body.then;
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitIfNullJudgment(this, typeContext);
- }
-}
-
-/// Concrete shadow object representing an assignment to a target for which
-/// assignment is not allowed.
-class IllegalAssignmentJudgment extends ComplexAssignmentJudgment {
- /// The offset at which the invalid assignment should be stored.
- /// If `-1`, then there is no separate location for invalid assignment.
- final int assignmentOffset;
-
- IllegalAssignmentJudgment._(Expression rhs, {this.assignmentOffset: -1})
- : super._(rhs) {
- rhs.parent = this;
+ IfNullExpression(this.left, this.right) {
+ left?.parent = this;
+ right?.parent = this;
}
@override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitIllegalAssignmentJudgment(this, typeContext);
+ InternalExpressionKind get kind => InternalExpressionKind.IfNull;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ left?.accept(v);
+ right?.accept(v);
}
-}
-/// Concrete shadow object representing an assignment to a target of the form
-/// `a[b]`.
-class IndexAssignmentJudgment extends ComplexAssignmentJudgmentWithReceiver {
- /// In an assignment to an index expression, the index expression.
- Expression index;
-
- IndexAssignmentJudgment._(Expression receiver, this.index, Expression rhs,
- {bool isSuper: false})
- : super._(receiver, rhs, isSuper);
-
- Arguments _getInvocationArguments(
- ShadowTypeInferrer inferrer, Expression invocation) {
- if (invocation is MethodInvocation) {
- return invocation.arguments;
- } else if (invocation is SuperMethodInvocation) {
- return invocation.arguments;
- } else {
- throw unhandled("${invocation.runtimeType}", "_getInvocationArguments",
- fileOffset, inferrer.uri);
+ @override
+ void transformChildren(Transformer v) {
+ if (left != null) {
+ left = left.accept<TreeNode>(v);
+ left?.parent = this;
}
- }
-
- @override
- List<String> _getToStringParts() {
- List<String> parts = super._getToStringParts();
- if (index != null) parts.add('index=$index');
- return parts;
- }
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitIndexAssignmentJudgment(this, typeContext);
+ if (right != null) {
+ right = right.accept<TreeNode>(v);
+ right?.parent = this;
+ }
}
}
@@ -798,12 +557,10 @@
? '0x${asDouble.toRadixString(16)}'
: asDouble.toString();
int length = literal?.length ?? noLength;
- return inferrer.helper.desugarSyntheticExpression(inferrer.helper
- .buildProblem(
- templateWebLiteralCannotBeRepresentedExactly.withArguments(
- text, nearest),
- charOffset,
- length));
+ return inferrer.helper.buildProblem(
+ templateWebLiteralCannotBeRepresentedExactly.withArguments(text, nearest),
+ charOffset,
+ length);
}
/// Concrete shadow object representing an integer literal in kernel form.
@@ -1039,35 +796,6 @@
}
}
-/// Concrete shadow object representing an assignment to a property.
-class PropertyAssignmentJudgment extends ComplexAssignmentJudgmentWithReceiver {
- /// If this assignment uses null-aware access (`?.`), the conditional
- /// expression that guards the access; otherwise `null`.
- ConditionalExpression nullAwareGuard;
-
- PropertyAssignmentJudgment._(Expression receiver, Expression rhs,
- {bool isSuper: false})
- : super._(receiver, rhs, isSuper);
-
- @override
- List<String> _getToStringParts() {
- List<String> parts = super._getToStringParts();
- if (nullAwareGuard != null) parts.add('nullAwareGuard=$nullAwareGuard');
- return parts;
- }
-
- ObjectAccessTarget _handleWriteContravariance(
- ShadowTypeInferrer inferrer, DartType receiverType) {
- return inferrer.findPropertySetMember(receiverType, write);
- }
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitPropertyAssignmentJudgment(this, typeContext);
- }
-}
-
/// Front end specific implementation of [ReturnStatement].
class ReturnStatementImpl extends ReturnStatement {
final bool isArrow;
@@ -1076,140 +804,6 @@
: super(expression);
}
-/// Concrete shadow object representing an assignment to a static variable.
-class StaticAssignmentJudgment extends ComplexAssignmentJudgment {
- StaticAssignmentJudgment._(Expression rhs) : super._(rhs);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitStaticAssignmentJudgment(this, typeContext);
- }
-}
-
-/// Synthetic judgment class representing an attempt to invoke an unresolved
-/// constructor, or a constructor that cannot be invoked, or a resolved
-/// constructor with wrong number of arguments.
-// TODO(ahe): Remove this?
-class InvalidConstructorInvocationJudgment extends SyntheticExpressionJudgment {
- final Member constructor;
- final Arguments arguments;
-
- InvalidConstructorInvocationJudgment._(
- Expression desugared, this.constructor, this.arguments)
- : super._(desugared);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitInvalidConstructorInvocationJudgment(this, typeContext);
- }
-}
-
-/// Synthetic judgment class representing an attempt to assign to the
-/// [expression] which is not assignable.
-class InvalidWriteJudgment extends SyntheticExpressionJudgment {
- final Expression expression;
-
- InvalidWriteJudgment._(Expression desugared, this.expression)
- : super._(desugared);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitInvalidWriteJudgment(this, typeContext);
- }
-}
-
-/// Shadow object for expressions that are introduced by the front end as part
-/// of desugaring or the handling of error conditions.
-///
-/// These expressions are removed by type inference and replaced with their
-/// desugared equivalents.
-class SyntheticExpressionJudgment extends Let implements ExpressionJudgment {
- SyntheticExpressionJudgment._(Expression desugared)
- : super(new VariableDeclaration('_', initializer: new NullLiteral()),
- desugared);
-
- /// The desugared kernel representation of this synthetic expression.
- Expression get desugared => body;
-
- void set desugared(Expression value) {
- this.body = value;
- value.parent = this;
- }
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitSyntheticExpressionJudgment(this, typeContext);
- }
-
- /// Removes this expression from the expression tree, replacing it with
- /// [desugared].
- Expression _replaceWithDesugared() {
- Expression replacement = desugared;
- if (replacement is InternalExpression) {
- // This is needed because some (StaticAssignmentJudgment at least) do
- // not visit their desugared expression during inference.
- InternalExpression internalExpression = replacement;
- replacement = internalExpression.replace();
- }
- parent.replaceChild(this, replacement);
- parent = null;
- return replacement;
- }
-
- /// Updates any [Let] nodes in the desugared expression to account for the
- /// fact that [expression] has the given [type].
- void _storeLetType(
- TypeInferrerImpl inferrer, Expression expression, DartType type) {
- Expression desugared = this.desugared;
- while (true) {
- if (desugared is Let) {
- Let desugaredLet = desugared;
- VariableDeclaration variable = desugaredLet.variable;
- if (identical(variable.initializer, expression)) {
- variable.type = type;
- return;
- }
- desugared = desugaredLet.body;
- } else if (desugared is ConditionalExpression) {
- // When a null-aware assignment is desugared, often the "then" or "else"
- // branch of the conditional expression often contains "let" nodes that
- // need to be updated.
- ConditionalExpression desugaredConditionalExpression = desugared;
- if (desugaredConditionalExpression.then is Let) {
- desugared = desugaredConditionalExpression.then;
- } else {
- desugared = desugaredConditionalExpression.otherwise;
- }
- } else {
- break;
- }
- }
- }
-
- @override
- R accept<R>(ExpressionVisitor<R> v) {
- // This is designed to throw an exception during serialization. It can also
- // lead to exceptions during transformations, but we have to accept a
- // [Transformer] as this is used to implement `replaceChild`.
- if (v is Transformer) return super.accept(v);
- throw unsupported("${runtimeType}.accept", fileOffset, getFileUri(this));
- }
-
- @override
- R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) {
- throw unsupported("${runtimeType}.accept1", fileOffset, getFileUri(this));
- }
-
- @override
- visitChildren(Visitor<dynamic> v) {
- unsupported("${runtimeType}.visitChildren", fileOffset, getFileUri(this));
- }
-}
-
/// Concrete implementation of [TypeInferenceEngine] specialized to work with
/// kernel objects.
class ShadowTypeInferenceEngine extends TypeInferenceEngine {
@@ -1381,16 +975,6 @@
}
}
-class VariableAssignmentJudgment extends ComplexAssignmentJudgment {
- VariableAssignmentJudgment._(Expression rhs) : super._(rhs);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitVariableAssignmentJudgment(this, typeContext);
- }
-}
-
/// Front end specific implementation of [VariableDeclaration].
class VariableDeclarationImpl extends VariableDeclaration {
final bool forSyntheticToken;
@@ -1467,39 +1051,6 @@
variable._isLocalFunction;
}
-/// Synthetic judgment class representing an attempt to invoke an unresolved
-/// target.
-class UnresolvedTargetInvocationJudgment extends SyntheticExpressionJudgment {
- final ArgumentsImpl argumentsJudgment;
-
- UnresolvedTargetInvocationJudgment._(
- Expression desugared, this.argumentsJudgment)
- : super._(desugared);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitUnresolvedTargetInvocationJudgment(this, typeContext);
- }
-}
-
-/// Synthetic judgment class representing an attempt to assign to an unresolved
-/// variable.
-class UnresolvedVariableAssignmentJudgment extends SyntheticExpressionJudgment {
- final bool isCompound;
- final Expression rhs;
-
- UnresolvedVariableAssignmentJudgment._(
- Expression desugared, this.isCompound, this.rhs)
- : super._(desugared);
-
- @override
- ExpressionInferenceResult acceptInference(
- InferenceVisitor visitor, DartType typeContext) {
- return visitor.visitUnresolvedVariableAssignmentJudgment(this, typeContext);
- }
-}
-
/// Front end specific implementation of [VariableGet].
class VariableGetImpl extends VariableGet {
final TypePromotionFact _fact;
@@ -1552,18 +1103,6 @@
}
}
-/// The result of inference for a RHS of an assignment.
-class _ComplexAssignmentInferenceResult {
- /// The resolved combiner [Procedure], e.g. `operator+` for `a += 2`, or
- /// `null` if the assignment is not compound.
- final Procedure combiner;
-
- /// The inferred type of the RHS.
- final DartType inferredType;
-
- _ComplexAssignmentInferenceResult(this.combiner, this.inferredType);
-}
-
class _UnfinishedCascade extends Expression {
R accept<R>(v) => unsupported("accept", -1, null);
@@ -1576,67 +1115,6 @@
void visitChildren(v) => unsupported("visitChildren", -1, null);
}
-class SyntheticWrapper {
- static Expression wrapIllegalAssignment(Expression rhs,
- {int assignmentOffset: -1}) {
- return new IllegalAssignmentJudgment._(rhs,
- assignmentOffset: assignmentOffset)
- ..fileOffset = rhs.fileOffset;
- }
-
- static Expression wrapIndexAssignment(
- Expression receiver, Expression index, Expression rhs,
- {bool isSuper: false}) {
- return new IndexAssignmentJudgment._(receiver, index, rhs, isSuper: isSuper)
- ..fileOffset = index.fileOffset;
- }
-
- static Expression wrapInvalidConstructorInvocation(
- Expression desugared, Member constructor, Arguments arguments) {
- return new InvalidConstructorInvocationJudgment._(
- desugared, constructor, arguments)
- ..fileOffset = desugared.fileOffset;
- }
-
- static Expression wrapInvalidWrite(
- Expression desugared, Expression expression) {
- return new InvalidWriteJudgment._(desugared, expression)
- ..fileOffset = desugared.fileOffset;
- }
-
- static Expression wrapPropertyAssignment(Expression receiver, Expression rhs,
- {bool isSuper: false}) {
- return new PropertyAssignmentJudgment._(receiver, rhs, isSuper: isSuper)
- ..fileOffset = rhs.fileOffset;
- }
-
- static Expression wrapStaticAssignment(Expression rhs) {
- return new StaticAssignmentJudgment._(rhs)..fileOffset = rhs.fileOffset;
- }
-
- static Expression wrapSyntheticExpression(Expression desugared) {
- return new SyntheticExpressionJudgment._(desugared)
- ..fileOffset = desugared.fileOffset;
- }
-
- static Expression wrapUnresolvedTargetInvocation(
- Expression desugared, Arguments arguments) {
- return new UnresolvedTargetInvocationJudgment._(desugared, arguments)
- ..fileOffset = desugared.fileOffset;
- }
-
- static Expression wrapUnresolvedVariableAssignment(
- Expression desugared, bool isCompound, Expression rhs) {
- return new UnresolvedVariableAssignmentJudgment._(
- desugared, isCompound, rhs)
- ..fileOffset = desugared.fileOffset;
- }
-
- static Expression wrapVariableAssignment(Expression rhs) {
- return new VariableAssignmentJudgment._(rhs)..fileOffset = rhs.fileOffset;
- }
-}
-
/// Internal expression representing an if-null property set.
///
/// An if-null property set of the form `o.a ??= b` is, if used for value,
@@ -1803,6 +1281,9 @@
///
class PropertyPostIncDec extends InternalExpression {
/// The synthetic variable whose initializer hold the receiver.
+ ///
+ /// This is `null` if the receiver is read-only and therefore does not need to
+ /// be stored in a temporary variable.
VariableDeclaration variable;
/// The expression that reads the property on [variable].
@@ -1818,15 +1299,25 @@
write?.parent = this;
}
+ PropertyPostIncDec.onReadOnly(
+ VariableDeclaration read, VariableDeclaration write)
+ : this(null, read, write);
+
@override
InternalExpressionKind get kind => InternalExpressionKind.PropertyPostIncDec;
@override
Expression replace() {
Expression replacement;
- replaceWith(replacement = new Let(
- variable, createLet(read, createLet(write, createVariableGet(read))))
- ..fileOffset = fileOffset);
+ if (variable != null) {
+ replaceWith(replacement = new Let(
+ variable, createLet(read, createLet(write, createVariableGet(read))))
+ ..fileOffset = fileOffset);
+ } else {
+ replaceWith(
+ replacement = new Let(read, createLet(write, createVariableGet(read)))
+ ..fileOffset = fileOffset);
+ }
return replacement;
}
@@ -2026,6 +1517,7 @@
/// The value expression of the operation.
Expression value;
+ // TODO(johnniwinther): Add `readOnlyReceiver` capability.
IndexSet(this.receiver, this.index, this.value) {
receiver?.parent = this;
index?.parent = this;
@@ -2059,6 +1551,56 @@
}
}
+/// Internal expression representing a super index set expression.
+///
+/// A super index set expression of the form `super[a] = b` used for value is
+/// encoded as the expression:
+///
+/// let v1 = a in let v2 = b in let _ = super.[]=(v1, v2) in v2
+///
+/// An index set expression used for effect is encoded as
+///
+/// super.[]=(a, b)
+///
+/// using [SuperMethodInvocation].
+///
+class SuperIndexSet extends InternalExpression {
+ /// The []= member.
+ Member setter;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The value expression of the operation.
+ Expression value;
+
+ SuperIndexSet(this.setter, this.index, this.value) {
+ index?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.SuperIndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ index?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
/// Internal expression representing an if-null index assignment.
///
/// An if-null index assignment of the form `o[a] ??= b` is, if used for value,
@@ -2080,6 +1622,8 @@
/// let v3 = v1[v2] in
/// v3 == null ? v1.[]=(v2, b) : null
///
+/// If the [readOnlyReceiver] is true, no temporary variable is created for the
+/// receiver and its use is inlined.
class IfNullIndexSet extends InternalExpression {
/// The receiver on which the index set operation is performed.
Expression receiver;
@@ -2093,12 +1637,29 @@
/// The file offset for the [] operation.
final int readOffset;
+ /// The file offset for the == operation.
+ final int testOffset;
+
+ /// The file offset for the []= operation.
+ final int writeOffset;
+
/// If `true`, the expression is only need for effect and not for its value.
final bool forEffect;
- IfNullIndexSet(this.receiver, this.index, this.value, this.readOffset,
- {this.forEffect})
- : assert(forEffect != null) {
+ /// If `true`, the receiver is read-only and therefore doesn't need a
+ /// temporary variable for its value.
+ final bool readOnlyReceiver;
+
+ IfNullIndexSet(this.receiver, this.index, this.value,
+ {this.readOffset,
+ this.testOffset,
+ this.writeOffset,
+ this.forEffect,
+ this.readOnlyReceiver: false})
+ : assert(readOffset != null),
+ assert(testOffset != null),
+ assert(writeOffset != null),
+ assert(forEffect != null) {
receiver?.parent = this;
index?.parent = this;
value?.parent = this;
@@ -2131,7 +1692,83 @@
}
}
-/// Internal expression representing an if-null index assignment.
+/// Internal expression representing an if-null super index set expression.
+///
+/// An if-null super index set expression of the form `super[a] ??= b` is, if
+/// used for value, encoded as the expression:
+///
+/// let v1 = a in
+/// let v2 = super.[](v1) in
+/// v2 == null
+/// ? (let v3 = b in
+/// let _ = super.[]=(v1, v3) in
+/// v3)
+/// : v2
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let v1 = a in
+/// let v2 = super.[](v1) in
+/// v2 == null ? super.[]=(v1, b) : null
+///
+class IfNullSuperIndexSet extends InternalExpression {
+ /// The [] member;
+ Member getter;
+
+ /// The []= member;
+ Member setter;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The value expression of the operation.
+ Expression value;
+
+ /// The file offset for the [] operation.
+ final int readOffset;
+
+ /// The file offset for the == operation.
+ final int testOffset;
+
+ /// The file offset for the []= operation.
+ final int writeOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ IfNullSuperIndexSet(this.getter, this.setter, this.index, this.value,
+ {this.readOffset, this.testOffset, this.writeOffset, this.forEffect})
+ : assert(readOffset != null),
+ assert(testOffset != null),
+ assert(writeOffset != null),
+ assert(forEffect != null) {
+ index?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.IfNullSuperIndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ index?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing a compound index assignment.
///
/// An if-null index assignment of the form `o[a] += b` is, if used for value,
/// encoded as the expression:
@@ -2173,12 +1810,17 @@
/// If `true`, the expression is a post-fix inc/dec expression.
final bool forPostIncDec;
+ /// If `true`, the receiver is read-only and therefore doesn't need a
+ /// temporary variable for its value.
+ final bool readOnlyReceiver;
+
CompoundIndexSet(this.receiver, this.index, this.binaryName, this.rhs,
{this.readOffset,
this.binaryOffset,
this.writeOffset,
this.forEffect,
- this.forPostIncDec})
+ this.forPostIncDec,
+ this.readOnlyReceiver: false})
: assert(forEffect != null) {
receiver?.parent = this;
index?.parent = this;
@@ -2213,6 +1855,386 @@
}
}
+/// Internal expression representing a null-aware compound assignment.
+///
+/// A null-aware compound assignment of the form
+///
+/// receiver?.property binaryName= rhs
+///
+/// is, if used for value as a normal compound or prefix operation, encoded as
+/// the expression:
+///
+/// let receiverVariable = receiver in
+/// receiverVariable == null ? null :
+/// let leftVariable = receiverVariable.propertyName in
+/// let valueVariable = leftVariable binaryName rhs in
+/// let writeVariable =
+/// receiverVariable.propertyName = valueVariable in
+/// valueVariable
+///
+/// and, if used for value as a postfix operation, encoded as
+///
+/// let receiverVariable = receiver in
+/// receiverVariable == null ? null :
+/// let leftVariable = receiverVariable.propertyName in
+/// let writeVariable =
+/// receiverVariable.propertyName =
+/// leftVariable binaryName rhs in
+/// leftVariable
+///
+/// and, if used for effect, encoded as:
+///
+/// let receiverVariable = receiver in
+/// receiverVariable == null ? null :
+/// receiverVariable.propertyName = receiverVariable.propertyName + rhs
+///
+class NullAwareCompoundSet extends InternalExpression {
+ /// The receiver on which the null aware operation is performed.
+ Expression receiver;
+
+ /// The name of the null-aware property.
+ Name propertyName;
+
+ /// The name of the binary operation.
+ Name binaryName;
+
+ /// The right-hand side of the binary expression.
+ Expression rhs;
+
+ /// The file offset for the read operation.
+ final int readOffset;
+
+ /// The file offset for the write operation.
+ final int writeOffset;
+
+ /// The file offset for the binary operation.
+ final int binaryOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ /// If `true`, the expression is a postfix inc/dec expression.
+ final bool forPostIncDec;
+
+ NullAwareCompoundSet(
+ this.receiver, this.propertyName, this.binaryName, this.rhs,
+ {this.readOffset,
+ this.binaryOffset,
+ this.writeOffset,
+ this.forEffect,
+ this.forPostIncDec})
+ : assert(readOffset != null),
+ assert(binaryOffset != null),
+ assert(writeOffset != null),
+ assert(forEffect != null),
+ assert(forPostIncDec != null) {
+ receiver?.parent = this;
+ rhs?.parent = this;
+ fileOffset = binaryOffset;
+ }
+
+ @override
+ InternalExpressionKind get kind =>
+ InternalExpressionKind.NullAwareCompoundSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ rhs?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (rhs != null) {
+ rhs = rhs.accept<TreeNode>(v);
+ rhs?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an null-aware if-null property set.
+///
+/// A null-aware if-null property set of the form
+///
+/// receiver?.name ??= value
+///
+/// is, if used for value, encoded as the expression:
+///
+/// let receiverVariable = receiver in
+/// receiverVariable == null ? null :
+/// (let readVariable = receiverVariable.name in
+/// readVariable == null ?
+/// receiverVariable.name = value : readVariable)
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let receiverVariable = receiver in
+/// receiverVariable == null ? null :
+/// (receiverVariable.name == null ?
+/// receiverVariable.name = value : null)
+///
+///
+class NullAwareIfNullSet extends InternalExpression {
+ /// The synthetic variable whose initializer hold the receiver.
+ Expression receiver;
+
+ /// The expression that reads the property from [variable].
+ Name name;
+
+ /// The expression that writes the value to the property on [variable].
+ Expression value;
+
+ /// The file offset for the read operation.
+ final int readOffset;
+
+ /// The file offset for the write operation.
+ final int writeOffset;
+
+ /// The file offset for the == operation.
+ final int testOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ NullAwareIfNullSet(this.receiver, this.name, this.value,
+ {this.readOffset, this.writeOffset, this.testOffset, this.forEffect})
+ : assert(readOffset != null),
+ assert(writeOffset != null),
+ assert(testOffset != null),
+ assert(forEffect != null) {
+ receiver?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.NullAwareIfNullSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing a compound super index assignment.
+///
+/// An if-null index assignment of the form `super[a] += b` is, if used for
+/// value, encoded as the expression:
+///
+/// let v1 = a in
+/// let v2 = super.[](v1) + b
+/// let v3 = super.[]=(v1, v2) in v2
+///
+/// and, if used for effect, encoded as the expression:
+///
+/// let v1 = a in super.[]=(v2, super.[](v2) + b)
+///
+class CompoundSuperIndexSet extends InternalExpression {
+ /// The [] member.
+ Member getter;
+
+ /// The []= member.
+ Member setter;
+
+ /// The index expression of the operation.
+ Expression index;
+
+ /// The name of the binary operation.
+ Name binaryName;
+
+ /// The right-hand side of the binary expression.
+ Expression rhs;
+
+ /// The file offset for the [] operation.
+ final int readOffset;
+
+ /// The file offset for the []= operation.
+ final int writeOffset;
+
+ /// The file offset for the binary operation.
+ final int binaryOffset;
+
+ /// If `true`, the expression is only need for effect and not for its value.
+ final bool forEffect;
+
+ /// If `true`, the expression is a post-fix inc/dec expression.
+ final bool forPostIncDec;
+
+ CompoundSuperIndexSet(
+ this.getter, this.setter, this.index, this.binaryName, this.rhs,
+ {this.readOffset,
+ this.binaryOffset,
+ this.writeOffset,
+ this.forEffect,
+ this.forPostIncDec})
+ : assert(forEffect != null) {
+ index?.parent = this;
+ rhs?.parent = this;
+ fileOffset = binaryOffset;
+ }
+
+ @override
+ InternalExpressionKind get kind =>
+ InternalExpressionKind.CompoundSuperIndexSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ index?.accept(v);
+ rhs?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (index != null) {
+ index = index.accept<TreeNode>(v);
+ index?.parent = this;
+ }
+ if (rhs != null) {
+ rhs = rhs.accept<TreeNode>(v);
+ rhs?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an assignment to an extension setter.
+///
+/// An extension set of the form `receiver.target = value` is, if used for
+/// value, encoded as the expression:
+///
+/// let receiverVariable = receiver in
+/// let valueVariable = value in
+/// let writeVariable = target(receiverVariable, valueVariable) in
+/// valueVariable
+///
+/// or if the receiver is read-only, like `this` or a final variable,
+///
+/// let valueVariable = value in
+/// let writeVariable = target(receiver, valueVariable) in
+/// valueVariable
+///
+/// and, if used for effect, encoded as a [StaticInvocation]:
+///
+/// target(receiver, value)
+///
+// TODO(johnniwinther): Rename read-only to side-effect-free.
+class ExtensionSet extends InternalExpression {
+ /// The receiver for the assignment.
+ Expression receiver;
+
+ /// The extension member called for the assignment.
+ ObjectAccessTarget target;
+
+ /// The right-hand side value of the assignment.
+ Expression value;
+
+ /// If `true` the assignment is only needed for effect and not its result
+ /// value.
+ final bool forEffect;
+
+ /// If `true` the receiver can be cloned instead of creating a temporary
+ /// variable.
+ final bool readOnlyReceiver;
+
+ ExtensionSet(this.receiver, this.target, this.value,
+ {this.readOnlyReceiver, this.forEffect})
+ : assert(readOnlyReceiver != null),
+ assert(forEffect != null) {
+ receiver?.parent = this;
+ value?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.ExtensionSet;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ receiver?.accept(v);
+ value?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (receiver != null) {
+ receiver = receiver.accept<TreeNode>(v);
+ receiver?.parent = this;
+ }
+ if (value != null) {
+ value = value.accept<TreeNode>(v);
+ value?.parent = this;
+ }
+ }
+}
+
+/// Internal expression representing an null-aware extension expression.
+///
+/// An null-aware extension expression of the form `Extension(receiver)?.target`
+/// is encoded as the expression:
+///
+/// let variable = receiver in
+/// variable == null ? null : expression
+///
+/// where `expression` is an encoding of `receiverVariable.target`.
+class NullAwareExtension extends InternalExpression {
+ VariableDeclaration variable;
+ Expression expression;
+
+ NullAwareExtension(this.variable, this.expression) {
+ variable?.parent = this;
+ expression?.parent = this;
+ }
+
+ @override
+ InternalExpressionKind get kind => InternalExpressionKind.NullAwareExtension;
+
+ @override
+ void visitChildren(Visitor<dynamic> v) {
+ variable?.accept(v);
+ expression?.accept(v);
+ }
+
+ @override
+ void transformChildren(Transformer v) {
+ if (variable != null) {
+ variable = variable.accept<TreeNode>(v);
+ variable?.parent = this;
+ }
+ if (expression != null) {
+ expression = expression.accept<TreeNode>(v);
+ expression?.parent = this;
+ }
+ }
+}
+
+class PropertySetImpl extends PropertySet {
+ /// If `true` the assignment is need for its effect and not for its value.
+ final bool forEffect;
+
+ /// If `true` the receiver can be cloned and doesn't need a temporary variable
+ /// for multiple reads.
+ final bool readOnlyReceiver;
+
+ PropertySetImpl(Expression receiver, Name name, Expression value,
+ {Member interfaceTarget, this.forEffect, this.readOnlyReceiver})
+ : assert(forEffect != null),
+ super(receiver, name, value, interfaceTarget);
+}
+
/// Creates a [Let] of [variable] with the given [body] using
/// `variable.fileOffset` as the file offset for the let.
///
@@ -2247,7 +2269,7 @@
int fileOffset, Expression left, Member equalsMember) {
return new MethodInvocation(
left,
- new Name('=='),
+ equalsName,
new Arguments(<Expression>[new NullLiteral()..fileOffset = fileOffset])
..fileOffset = fileOffset)
..fileOffset = fileOffset
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 1c4a783..6be7601 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -465,7 +465,7 @@
unhandled("${type.runtimeType}", "installForwardingConstructors",
builder.charOffset, builder.fileUri);
}
- if (supertype.isMixinApplication) {
+ if (supertype.isMixinApplication && supertype is SourceClassBuilder) {
installForwardingConstructors(supertype);
}
if (supertype is ClassBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 010f327..544ff1d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -15,14 +15,15 @@
TypeParameter,
TypeParameterType,
TypedefType,
+ Variance,
VoidType;
import 'package:kernel/type_algebra.dart' show containsTypeVariable;
-import 'package:kernel/src/bounds_checks.dart' show Variance;
-
import 'package:kernel/util/graph.dart' show Graph, computeStrongComponents;
+import '../builder/builder.dart';
+
import 'kernel_builder.dart'
show
ClassBuilder,
@@ -47,7 +48,7 @@
templateNonSimpleBoundViaReference,
templateNonSimpleBoundViaVariable;
-export 'package:kernel/src/bounds_checks.dart' show Variance;
+export 'package:kernel/ast.dart' show Variance;
// Computes the variance of a variable in a type. The function can be run
// before the types are resolved to compute variances of typedefs' type
@@ -123,35 +124,91 @@
TypeBuilder type,
Map<TypeVariableBuilder, TypeBuilder> upperSubstitution,
Map<TypeVariableBuilder, TypeBuilder> lowerSubstitution,
- {bool isCovariant = true}) {
+ List<TypeBuilder> unboundTypes,
+ List<TypeVariableBuilder> unboundTypeVariables,
+ {final int variance = Variance.covariant}) {
if (type is NamedTypeBuilder) {
if (type.declaration is TypeVariableBuilder) {
- if (isCovariant) {
- return upperSubstitution[type.declaration] ?? type;
+ if (variance == Variance.contravariant) {
+ return lowerSubstitution[type.declaration] ?? type;
}
- return lowerSubstitution[type.declaration] ?? type;
+ return upperSubstitution[type.declaration] ?? type;
}
if (type.arguments == null || type.arguments.length == 0) {
return type;
}
List<TypeBuilder> arguments;
- for (int i = 0; i < type.arguments.length; i++) {
- TypeBuilder substitutedArgument = substituteRange(
- type.arguments[i], upperSubstitution, lowerSubstitution,
- isCovariant: isCovariant);
- if (substitutedArgument != type.arguments[i]) {
- arguments ??= type.arguments.toList();
- arguments[i] = substitutedArgument;
+ TypeDeclarationBuilder declaration = type.declaration;
+ if (declaration == null) {
+ assert(unboundTypes != null,
+ "Can not handle unbound named type builders without `unboundTypes`.");
+ assert(
+ unboundTypeVariables != null,
+ "Can not handle unbound named type builders without "
+ "`unboundTypeVariables`.");
+ assert(
+ identical(upperSubstitution, lowerSubstitution),
+ "Can only handle unbound named type builders identical "
+ "`upperSubstitution` and `lowerSubstitution`.");
+ for (int i = 0; i < type.arguments.length; ++i) {
+ TypeBuilder substitutedArgument = substituteRange(
+ type.arguments[i],
+ upperSubstitution,
+ lowerSubstitution,
+ unboundTypes,
+ unboundTypeVariables,
+ variance: variance);
+ if (substitutedArgument != type.arguments[i]) {
+ arguments ??= type.arguments.toList();
+ arguments[i] = substitutedArgument;
+ }
}
+ } else if (declaration is ClassBuilder) {
+ for (int i = 0; i < type.arguments.length; ++i) {
+ TypeBuilder substitutedArgument = substituteRange(
+ type.arguments[i],
+ upperSubstitution,
+ lowerSubstitution,
+ unboundTypes,
+ unboundTypeVariables,
+ variance: variance);
+ if (substitutedArgument != type.arguments[i]) {
+ arguments ??= type.arguments.toList();
+ arguments[i] = substitutedArgument;
+ }
+ }
+ } else if (declaration is TypeAliasBuilder) {
+ for (int i = 0; i < type.arguments.length; ++i) {
+ TypeVariableBuilder variable = declaration.typeVariables[i];
+ TypeBuilder substitutedArgument = substituteRange(
+ type.arguments[i],
+ upperSubstitution,
+ lowerSubstitution,
+ unboundTypes,
+ unboundTypeVariables,
+ variance: Variance.combine(variance, variable.variance));
+ if (substitutedArgument != type.arguments[i]) {
+ arguments ??= type.arguments.toList();
+ arguments[i] = substitutedArgument;
+ }
+ }
+ } else if (declaration is InvalidTypeBuilder) {
+ // Don't substitute.
+ } else {
+ assert(false, "Unexpected named type builder declaration: $declaration.");
}
if (arguments != null) {
- return new NamedTypeBuilder(type.name, type.nullabilityBuilder, arguments)
- ..bind(type.declaration);
+ NamedTypeBuilder newTypeBuilder =
+ new NamedTypeBuilder(type.name, type.nullabilityBuilder, arguments);
+ if (declaration != null) {
+ newTypeBuilder.bind(declaration);
+ } else {
+ unboundTypes.add(newTypeBuilder);
+ }
+ return newTypeBuilder;
}
return type;
- }
-
- if (type is FunctionTypeBuilder) {
+ } else if (type is FunctionTypeBuilder) {
List<TypeVariableBuilder> variables;
if (type.typeVariables != null) {
variables = new List<TypeVariableBuilder>(type.typeVariables.length);
@@ -163,29 +220,45 @@
TypeBuilder returnType;
bool changed = false;
+ Map<TypeVariableBuilder, TypeBuilder> functionTypeUpperSubstitution;
+ Map<TypeVariableBuilder, TypeBuilder> functionTypeLowerSubstitution;
if (type.typeVariables != null) {
for (int i = 0; i < variables.length; i++) {
TypeVariableBuilder variable = type.typeVariables[i];
- TypeBuilder bound = substituteRange(
- variable.bound, upperSubstitution, lowerSubstitution,
- isCovariant: isCovariant);
+ TypeBuilder bound = substituteRange(variable.bound, upperSubstitution,
+ lowerSubstitution, unboundTypes, unboundTypeVariables,
+ variance: Variance.invariant);
if (bound != variable.bound) {
- variables[i] = new TypeVariableBuilder(
- variable.name, variable.parent, variable.charOffset,
- bound: bound);
+ TypeVariableBuilder newTypeVariableBuilder = variables[i] =
+ new TypeVariableBuilder(
+ variable.name, variable.parent, variable.charOffset,
+ bound: bound);
+ unboundTypeVariables.add(newTypeVariableBuilder);
+ if (functionTypeUpperSubstitution == null) {
+ functionTypeUpperSubstitution = {}..addAll(upperSubstitution);
+ functionTypeLowerSubstitution = {}..addAll(lowerSubstitution);
+ }
+ functionTypeUpperSubstitution[variable] =
+ functionTypeLowerSubstitution[variable] =
+ new NamedTypeBuilder.fromTypeDeclarationBuilder(
+ newTypeVariableBuilder,
+ const NullabilityBuilder.omitted());
changed = true;
} else {
variables[i] = variable;
}
}
}
-
if (type.formals != null) {
for (int i = 0; i < formals.length; i++) {
FormalParameterBuilder formal = type.formals[i];
TypeBuilder parameterType = substituteRange(
- formal.type, upperSubstitution, lowerSubstitution,
- isCovariant: !isCovariant);
+ formal.type,
+ functionTypeUpperSubstitution ?? upperSubstitution,
+ functionTypeLowerSubstitution ?? lowerSubstitution,
+ unboundTypes,
+ unboundTypeVariables,
+ variance: Variance.combine(variance, Variance.contravariant));
if (parameterType != formal.type) {
formals[i] = new FormalParameterBuilder(
formal.metadata,
@@ -193,34 +266,39 @@
parameterType,
formal.name,
formal.parent,
- formal.charOffset);
+ formal.charOffset,
+ formal.fileUri);
changed = true;
} else {
formals[i] = formal;
}
}
}
-
returnType = substituteRange(
- type.returnType, upperSubstitution, lowerSubstitution,
- isCovariant: true);
- if (returnType != type.returnType) {
- changed = true;
- }
+ type.returnType,
+ functionTypeUpperSubstitution ?? upperSubstitution,
+ functionTypeLowerSubstitution ?? lowerSubstitution,
+ unboundTypes,
+ unboundTypeVariables,
+ variance: variance);
+ changed = changed || returnType != type.returnType;
if (changed) {
return new FunctionTypeBuilder(
returnType, variables, formals, type.nullabilityBuilder);
}
-
return type;
}
return type;
}
TypeBuilder substitute(
- TypeBuilder type, Map<TypeVariableBuilder, TypeBuilder> substitution) {
- return substituteRange(type, substitution, substitution, isCovariant: true);
+ TypeBuilder type, Map<TypeVariableBuilder, TypeBuilder> substitution,
+ {List<TypeBuilder> unboundTypes,
+ List<TypeVariableBuilder> unboundTypeVariables}) {
+ return substituteRange(
+ type, substitution, substitution, unboundTypes, unboundTypeVariables,
+ variance: Variance.covariant);
}
/// Calculates bounds to be provided as type arguments in place of missing type
@@ -249,9 +327,10 @@
nullSubstitution[variables[variableIndex]] = bottomType;
}
for (int variableIndex in component) {
- bounds[variableIndex] = substituteRange(
- bounds[variableIndex], dynamicSubstitution, nullSubstitution,
- isCovariant: true);
+ TypeVariableBuilder variable = variables[variableIndex];
+ bounds[variableIndex] = substituteRange(bounds[variableIndex],
+ dynamicSubstitution, nullSubstitution, null, null,
+ variance: variable.variance);
}
}
@@ -263,8 +342,10 @@
substitution[variables[i]] = bounds[i];
nullSubstitution[variables[i]] = bottomType;
for (int j = 0; j < variables.length; j++) {
- bounds[j] = substituteRange(bounds[j], substitution, nullSubstitution,
- isCovariant: true);
+ TypeVariableBuilder variable = variables[j];
+ bounds[j] = substituteRange(
+ bounds[j], substitution, nullSubstitution, null, null,
+ variance: variable.variance);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
index 1c060a6..d54e02f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
@@ -81,10 +81,8 @@
arguments[i] = kernelArguments[i].accept(this);
}
}
- // TODO(dmitryas): Compute the nullabilityBuilder field for the result from
- // the nullability field of 'node'.
- return new NamedTypeBuilder(
- cls.name, const NullabilityBuilder.pendingImplementation(), arguments)
+ return new NamedTypeBuilder(cls.name,
+ new NullabilityBuilder.fromNullability(node.nullability), arguments)
..bind(cls);
}
@@ -104,15 +102,16 @@
if (i >= node.requiredParameterCount) {
kind = FormalParameterKind.optionalPositional;
}
- formals[i] = new FormalParameterBuilder(null, 0, type, null, null, -1)
- ..kind = kind;
+ formals[i] =
+ new FormalParameterBuilder(null, 0, type, null, null, -1, null)
+ ..kind = kind;
}
for (int i = 0; i < namedParameters.length; i++) {
NamedType parameter = namedParameters[i];
TypeBuilder type = positionalParameters[i].accept(this);
- formals[i + positionalParameters.length] =
- new FormalParameterBuilder(null, 0, type, parameter.name, null, -1)
- ..kind = FormalParameterKind.optionalNamed;
+ formals[i + positionalParameters.length] = new FormalParameterBuilder(
+ null, 0, type, parameter.name, null, -1, null)
+ ..kind = FormalParameterKind.optionalNamed;
}
return new FunctionTypeBuilder(returnType, typeVariables, formals,
new NullabilityBuilder.fromNullability(node.nullability));
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 4f0387f..2762157 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -13,7 +13,6 @@
ExpressionStatement,
Field,
FunctionType,
- Let,
Library,
Member,
Procedure,
@@ -37,8 +36,6 @@
import '../type_inference/type_schema.dart' show UnknownType;
-import 'kernel_shadow_ast.dart' show SyntheticExpressionJudgment;
-
import 'redirecting_factory_body.dart'
show RedirectingFactoryBody, getRedirectingFactoryBody;
@@ -140,14 +137,6 @@
}
@override
- visitLet(Let node) {
- if (node is SyntheticExpressionJudgment) {
- problem(node, "Leaking shadow node: ${node.runtimeType}");
- }
- super.visitLet(node);
- }
-
- @override
visitLibrary(Library node) {
// Issue(http://dartbug.com/32530)
if (skipPlatform && node.importUri.scheme == 'dart') {
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index e569a14..af3ed3b 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1555,6 +1555,11 @@
}
@override
+ void handleVarianceModifier(Token variance) {
+ listener?.handleVarianceModifier(variance);
+ }
+
+ @override
void handleVoidKeyword(Token token) {
listener?.handleVoidKeyword(token);
}
@@ -1578,4 +1583,9 @@
void reportNonNullAssertExpressionNotEnabled(Token bang) {
listener?.reportNonNullAssertExpressionNotEnabled(bang);
}
+
+ @override
+ void reportVarianceModifierNotEnabled(Token variance) {
+ listener?.reportVarianceModifierNotEnabled(variance);
+ }
}
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 7d24308..9c67ac4 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1230,6 +1230,19 @@
logEvent("TypeVariables");
}
+ void handleVarianceModifier(Token variance) {
+ logEvent("VarianceModifier");
+ }
+
+ void reportVarianceModifierNotEnabled(Token variance) {
+ if (variance != null) {
+ handleRecoverableError(
+ templateExperimentNotEnabled.withArguments('variance'),
+ variance,
+ variance);
+ }
+ }
+
void beginFunctionExpression(Token token) {}
/// Handle the end of a function expression (e.g. "() { ... }").
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index c185f92..e139297 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1752,7 +1752,8 @@
listener.beginClassOrNamedMixinApplicationPrelude(begin);
Token name = ensureIdentifier(
classKeyword, IdentifierContext.classOrMixinOrExtensionDeclaration);
- Token token = computeTypeParamOrArg(name, true).parseVariables(name, this);
+ Token token =
+ computeTypeParamOrArg(name, true, true).parseVariables(name, this);
if (optional('=', token.next)) {
listener.beginNamedMixinApplication(begin, abstractToken, name);
return parseNamedMixinApplication(token, begin, classKeyword);
@@ -1959,7 +1960,7 @@
Token name = ensureIdentifier(
mixinKeyword, IdentifierContext.classOrMixinOrExtensionDeclaration);
Token headerStart =
- computeTypeParamOrArg(name, true).parseVariables(name, this);
+ computeTypeParamOrArg(name, true, true).parseVariables(name, this);
listener.beginMixinDeclaration(mixinKeyword, name);
Token token = parseMixinHeaderOpt(headerStart, mixinKeyword);
if (!optional('{', token.next)) {
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index cf59846..f18f43e 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -307,7 +307,7 @@
/// If [inDeclaration] is `true`, then this will more aggressively recover
/// given unbalanced `<` `>` and invalid parameters or arguments.
TypeParamOrArgInfo computeTypeParamOrArg(Token token,
- [bool inDeclaration = false]) {
+ [bool inDeclaration = false, bool allowsVariance = false]) {
Token beginGroup = token.next;
if (!optional('<', beginGroup)) {
return noTypeParamOrArg;
@@ -329,7 +329,8 @@
}
// TODO(danrubel): Consider adding additional const for common situations.
- return new ComplexTypeParamOrArgInfo(token, inDeclaration).compute();
+ return new ComplexTypeParamOrArgInfo(token, inDeclaration, allowsVariance)
+ .compute();
}
/// Called by the parser to obtain information about a possible group of type
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 28e7ba9..2a16412 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -844,6 +844,11 @@
/// given unbalanced `<` `>` and invalid parameters or arguments.
final bool inDeclaration;
+ // Only support variance parsing if it makes sense.
+ // Allows parsing of variance for certain structures.
+ // See https://github.com/dart-lang/language/issues/524
+ final bool allowsVariance;
+
@override
int typeArgumentCount;
@@ -853,9 +858,11 @@
/// and may not be part of the token stream.
Token skipEnd;
- ComplexTypeParamOrArgInfo(Token token, this.inDeclaration)
+ ComplexTypeParamOrArgInfo(
+ Token token, this.inDeclaration, this.allowsVariance)
: assert(optional('<', token.next)),
assert(inDeclaration != null),
+ assert(allowsVariance != null),
start = token.next;
/// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
@@ -978,9 +985,35 @@
Link<Token> typeStarts = const Link<Token>();
Link<TypeInfo> superTypeInfos = const Link<TypeInfo>();
+ Link<Token> variances = const Link<Token>();
while (true) {
token = parser.parseMetadataStar(next);
+
+ Token variance = next.next;
+ Token identifier = variance.next;
+ if (allowsVariance &&
+ isVariance(variance) &&
+ identifier != null &&
+ identifier.isKeywordOrIdentifier) {
+ variances = variances.prepend(variance);
+
+ // Recovery for multiple variance modifiers
+ while (isVariance(identifier) &&
+ identifier.next != null &&
+ identifier.next.isKeywordOrIdentifier) {
+ // Report an error and skip actual identifier
+ parser.reportRecoverableError(
+ identifier, fasta.messageMultipleVarianceModifiers);
+ variance = variance.next;
+ identifier = identifier.next;
+ }
+
+ token = variance;
+ } else {
+ variances = variances.prepend(null);
+ }
+
next = parser.ensureIdentifier(
token, IdentifierContext.typeVariableDeclaration);
token = next;
@@ -1015,12 +1048,18 @@
assert(count > 0);
assert(typeStarts.slowLength() == count);
assert(superTypeInfos.slowLength() == count);
+ assert(variances.slowLength() == count);
listener.handleTypeVariablesDefined(token, count);
token = null;
while (typeStarts.isNotEmpty) {
Token token2 = typeStarts.head;
TypeInfo typeInfo = superTypeInfos.head;
+ Token variance = variances.head;
+
+ if (variance != null) {
+ listener.handleVarianceModifier(variance);
+ }
Token extendsOrSuper = null;
Token next2 = token2.next;
@@ -1040,6 +1079,7 @@
typeStarts = typeStarts.tail;
superTypeInfos = superTypeInfos.tail;
+ variances = variances.tail;
}
if (!parseCloser(token)) {
@@ -1171,6 +1211,13 @@
}
}
+// Return `true` if [token] is one of `in`, `inout`, or `out`
+bool isVariance(Token token) {
+ return optional('in', token) ||
+ optional('inout', token) ||
+ optional('out', token);
+}
+
/// Return `true` if [token] is one of `>`, `>>`, `>>>`, `>=`, `>>=`, or `>>>=`.
bool isCloser(Token token) {
final String value = token.stringValue;
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index cae857c..e34362d 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -73,10 +73,6 @@
/// and https://github.com/dart-lang/language/issues/60
bool _enableTripleShift = false;
- /// Experimental flag for enabling variance.
- /// See https://github.com/dart-lang/language/issues/524
- bool _enableVariance = false;
-
/**
* The string offset for the next token that will be created.
*
@@ -143,7 +139,6 @@
_enableExtensionMethods = config.enableExtensionMethods;
_enableNonNullable = config.enableNonNullable;
_enableTripleShift = config.enableTripleShift;
- _enableVariance = config.enableVariance;
}
}
@@ -1488,10 +1483,6 @@
(state.keyword == Keyword.LATE || state.keyword == Keyword.REQUIRED)) {
return tokenizeIdentifier(next, start, allowDollar);
}
- if (!_enableVariance &&
- (state.keyword == Keyword.OUT || state.keyword == Keyword.INOUT)) {
- return tokenizeIdentifier(next, start, allowDollar);
- }
if (($A <= next && next <= $Z) ||
($0 <= next && next <= $9) ||
identical(next, $_) ||
@@ -1916,19 +1907,13 @@
/// and https://github.com/dart-lang/language/issues/60
final bool enableTripleShift;
- /// Experimental flag for enabling variance.
- /// See https://github.com/dart-lang/language/issues/524
- final bool enableVariance;
-
const ScannerConfiguration({
bool enableExtensionMethods,
bool enableNonNullable,
bool enableTripleShift,
- bool enableVariance,
}) : this.enableExtensionMethods = enableExtensionMethods ?? false,
this.enableNonNullable = enableNonNullable ?? false,
- this.enableTripleShift = enableTripleShift ?? false,
- this.enableVariance = enableVariance ?? false;
+ this.enableTripleShift = enableTripleShift ?? false;
}
bool _isIdentifierChar(int next, bool allowDollar) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index b855f5b..400fba9 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -554,6 +554,11 @@
}
@override
+ void handleVarianceModifier(Token variance) {
+ debugEvent("VarianceModifier");
+ }
+
+ @override
void endConstructorReference(
Token start, Token periodBeforeName, Token endToken) {
debugEvent("ConstructorReference");
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index d2272da..77ca872 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -45,6 +45,8 @@
NamedTypeBuilder,
TypeBuilder;
+import '../kernel/type_algorithms.dart';
+
import '../modifier.dart'
show
Const,
@@ -488,6 +490,8 @@
if (extensionThisType is TypeBuilder) {
library.currentTypeParameterScopeBuilder
.registerExtensionThisType(extensionThisType);
+ } else {
+ // TODO(johnniwinther): Supply an invalid type as the extension on type.
}
}
debugEvent("beginClassOrMixinBody");
@@ -974,7 +978,7 @@
substitution[extension.typeVariables[i]] =
new NamedTypeBuilder.fromTypeDeclarationBuilder(
synthesizedTypeVariables[i],
- const NullabilityBuilder.pendingImplementation());
+ const NullabilityBuilder.omitted());
}
if (typeVariables != null) {
typeVariables = synthesizedTypeVariables..addAll(typeVariables);
@@ -985,14 +989,18 @@
List<FormalParameterBuilder> synthesizedFormals = [];
TypeBuilder thisType = extension.extensionThisType;
if (substitution != null) {
- List<NamedTypeBuilder> unboundTypes = [];
- thisType = thisType.subst(substitution, unboundTypes);
- for (NamedTypeBuilder unboundType in unboundTypes) {
+ List<TypeBuilder> unboundTypes = [];
+ List<TypeVariableBuilder> unboundTypeVariables = [];
+ thisType = substitute(thisType, substitution,
+ unboundTypes: unboundTypes,
+ unboundTypeVariables: unboundTypeVariables);
+ for (TypeBuilder unboundType in unboundTypes) {
extension.addType(new UnresolvedType(unboundType, -1, null));
}
+ library.boundlessTypeVariables.addAll(unboundTypeVariables);
}
synthesizedFormals.add(new FormalParameterBuilder(
- null, finalMask, thisType, "#this", null, charOffset));
+ null, finalMask, thisType, "#this", null, charOffset, uri));
if (formals != null) {
synthesizedFormals.addAll(formals);
}
@@ -1145,7 +1153,7 @@
} else {
push(library.addNamedType(
name,
- library.computeNullabilityFromToken(isMarkedAsNullable),
+ library.nullableBuilderIfTrue(isMarkedAsNullable),
arguments,
charOffset));
}
@@ -1391,7 +1399,7 @@
returnType,
typeVariables,
formals,
- library.computeNullabilityFromToken(questionMark != null),
+ library.nullableBuilderIfTrue(questionMark != null),
functionToken.charOffset));
}
@@ -1406,7 +1414,7 @@
reportErrorIfNullableType(question);
}
push(library.addFunctionType(returnType, typeVariables, formals,
- library.computeNullabilityFromToken(question != null), formalsOffset));
+ library.nullableBuilderIfTrue(question != null), formalsOffset));
}
@override
@@ -1623,8 +1631,8 @@
: templateCycleInTypeVariables.withArguments(
builder.name, via.join("', '"));
addProblem(message, builder.charOffset, builder.name.length);
- builder.bound = new NamedTypeBuilder(builder.name,
- const NullabilityBuilder.pendingImplementation(), null)
+ builder.bound = new NamedTypeBuilder(
+ builder.name, const NullabilityBuilder.omitted(), null)
..bind(new InvalidTypeBuilder(
builder.name,
message.withLocation(
@@ -1642,6 +1650,13 @@
}
@override
+ void handleVarianceModifier(Token variance) {
+ if (!library.loader.target.enableVariance) {
+ reportVarianceModifierNotEnabled(variance);
+ }
+ }
+
+ @override
void endPartOf(
Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
debugEvent("endPartOf");
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index a55b41d..6499fc8 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -258,8 +258,8 @@
}
}
if (message != null) {
- return new NamedTypeBuilder(supertype.name,
- const NullabilityBuilder.pendingImplementation(), null)
+ return new NamedTypeBuilder(
+ supertype.name, const NullabilityBuilder.omitted(), null)
..bind(new InvalidTypeBuilder(supertype.name,
message.withLocation(fileUri, charOffset, noLength)));
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index 1961514..fd7df17 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -50,8 +50,17 @@
Extension get extension => _extension;
+ /// Builds the [Extension] for this extension build and inserts the members
+ /// into the [Library] of [libraryBuilder].
+ ///
+ /// [addMembersToLibrary] is `true` if the extension members should be added
+ /// to the library. This is `false` if the extension is in conflict with
+ /// another library member. In this case, the extension member should not be
+ /// added to the library to avoid name clashes with other members in the
+ /// library.
Extension build(
- SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) {
+ SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary,
+ {bool addMembersToLibrary}) {
void buildBuilders(String name, Builder declaration) {
do {
if (declaration.parent != this) {
@@ -64,48 +73,52 @@
}
} else if (declaration is FieldBuilder) {
Field field = declaration.build(libraryBuilder);
- libraryBuilder.library.addMember(field);
- _extension.members.add(new ExtensionMemberDescriptor(
- name: new Name(declaration.name, libraryBuilder.library),
- member: field.reference,
- isStatic: declaration.isStatic,
- kind: ExtensionMemberKind.Field));
- } else if (declaration is ProcedureBuilder) {
- Member function = declaration.build(libraryBuilder);
- libraryBuilder.library.addMember(function);
- ExtensionMemberKind kind;
- switch (declaration.kind) {
- case ProcedureKind.Method:
- kind = ExtensionMemberKind.Method;
- break;
- case ProcedureKind.Getter:
- kind = ExtensionMemberKind.Getter;
- break;
- case ProcedureKind.Setter:
- kind = ExtensionMemberKind.Setter;
- break;
- case ProcedureKind.Operator:
- kind = ExtensionMemberKind.Operator;
- break;
- case ProcedureKind.Factory:
- unsupported("Extension method kind: ${declaration.kind}",
- declaration.charOffset, declaration.fileUri);
- }
- _extension.members.add(new ExtensionMemberDescriptor(
- name: new Name(declaration.name, libraryBuilder.library),
- member: function.reference,
- isStatic: declaration.isStatic,
- isExternal: declaration.isExternal,
- kind: kind));
- Procedure tearOff = declaration.extensionTearOff;
- if (tearOff != null) {
- libraryBuilder.library.addMember(tearOff);
+ if (addMembersToLibrary && declaration.next == null) {
+ libraryBuilder.library.addMember(field);
_extension.members.add(new ExtensionMemberDescriptor(
name: new Name(declaration.name, libraryBuilder.library),
- member: tearOff.reference,
- isStatic: false,
- isExternal: false,
- kind: ExtensionMemberKind.TearOff));
+ member: field.reference,
+ isStatic: declaration.isStatic,
+ kind: ExtensionMemberKind.Field));
+ }
+ } else if (declaration is ProcedureBuilder) {
+ Member function = declaration.build(libraryBuilder);
+ if (addMembersToLibrary && declaration.next == null) {
+ libraryBuilder.library.addMember(function);
+ ExtensionMemberKind kind;
+ switch (declaration.kind) {
+ case ProcedureKind.Method:
+ kind = ExtensionMemberKind.Method;
+ break;
+ case ProcedureKind.Getter:
+ kind = ExtensionMemberKind.Getter;
+ break;
+ case ProcedureKind.Setter:
+ kind = ExtensionMemberKind.Setter;
+ break;
+ case ProcedureKind.Operator:
+ kind = ExtensionMemberKind.Operator;
+ break;
+ case ProcedureKind.Factory:
+ unsupported("Extension method kind: ${declaration.kind}",
+ declaration.charOffset, declaration.fileUri);
+ }
+ _extension.members.add(new ExtensionMemberDescriptor(
+ name: new Name(declaration.name, libraryBuilder.library),
+ member: function.reference,
+ isStatic: declaration.isStatic,
+ isExternal: declaration.isExternal,
+ kind: kind));
+ Procedure tearOff = declaration.extensionTearOff;
+ if (tearOff != null) {
+ libraryBuilder.library.addMember(tearOff);
+ _extension.members.add(new ExtensionMemberDescriptor(
+ name: new Name(declaration.name, libraryBuilder.library),
+ member: tearOff.reference,
+ isStatic: false,
+ isExternal: false,
+ kind: ExtensionMemberKind.TearOff));
+ }
}
} else {
unhandled("${declaration.runtimeType}", "buildBuilders",
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 3ef57cb..811db64 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -195,6 +195,7 @@
import '../kernel/type_algorithms.dart'
show
calculateBounds,
+ computeVariance,
findGenericFunctionTypes,
getNonSimplicityIssuesForDeclaration,
getNonSimplicityIssuesForTypeVariables;
@@ -298,6 +299,13 @@
// TODO(dmitryas): Find a way to mark inferred types.
final Set<DartType> inferredTypes = new Set<DartType>.identity();
+ // While the bounds of type parameters aren't compiled yet, we can't tell the
+ // default nullability of the corresponding type-parameter types. This list
+ // is used to collect such type-parameter types in order to set the
+ // nullability after the bounds are built.
+ final List<TypeParameterType> pendingNullabilities =
+ new List<TypeParameterType>();
+
// A library to use for Names generated when compiling code in this library.
// This allows code generated in one library to use the private namespace of
// another, for example during expression compilation (debugging).
@@ -720,8 +728,10 @@
.withLocation(
existing.fileUri, existing.charOffset, fullName.length)
]);
- }
- if (declaration.isExtension) {
+ } else if (declaration.isExtension) {
+ // We add the extension declaration to the extension scope only if its
+ // name is unique. Only the first of duplicate extensions is accessible
+ // by name or by resolution and the remaining are dropped for the output.
currentTypeParameterScopeBuilder.extensions.add(declaration);
}
return members[name] = declaration;
@@ -1647,11 +1657,8 @@
applicationTypeArguments = <TypeBuilder>[];
for (TypeVariableBuilder typeVariable in typeVariables) {
- applicationTypeArguments.add(addNamedType(
- typeVariable.name,
- const NullabilityBuilder.pendingImplementation(),
- null,
- charOffset)
+ applicationTypeArguments.add(addNamedType(typeVariable.name,
+ const NullabilityBuilder.omitted(), null, charOffset)
..bind(
// The type variable types passed as arguments to the
// generic class representing the anonymous mixin
@@ -1702,11 +1709,8 @@
// handle that :(
application.cls.isAnonymousMixin = !isNamedMixinApplication;
addBuilder(fullname, application, charOffset);
- supertype = addNamedType(
- fullname,
- const NullabilityBuilder.pendingImplementation(),
- applicationTypeArguments,
- charOffset);
+ supertype = addNamedType(fullname, const NullabilityBuilder.omitted(),
+ applicationTypeArguments, charOffset);
}
return supertype;
} else {
@@ -1976,6 +1980,12 @@
List<TypeVariableBuilder> typeVariables,
FunctionTypeBuilder type,
int charOffset) {
+ if (typeVariables != null) {
+ for (int i = 0; i < typeVariables.length; ++i) {
+ TypeVariableBuilder variable = typeVariables[i];
+ variable.variance = computeVariance(variable, type);
+ }
+ }
TypeAliasBuilder typedefBuilder = new TypeAliasBuilder(
metadata, name, typeVariables, type, this, charOffset);
loader.target.metadataCollector
@@ -2015,7 +2025,7 @@
modifiers |= initializingFormalMask;
}
FormalParameterBuilder formal = new FormalParameterBuilder(
- metadata, modifiers, type, name, this, charOffset);
+ metadata, modifiers, type, name, this, charOffset, uri);
formal.initializerToken = initializerToken;
return formal;
}
@@ -2041,7 +2051,8 @@
if (declaration is SourceClassBuilder) {
cls = declaration.build(this, coreLibrary);
} else if (declaration is SourceExtensionBuilder) {
- extension = declaration.build(this, coreLibrary);
+ extension = declaration.build(this, coreLibrary,
+ addMembersToLibrary: declaration.next == null);
} else if (declaration is FieldBuilder) {
member = declaration.build(this)..isStatic = true;
} else if (declaration is ProcedureBuilder) {
@@ -2364,6 +2375,10 @@
builder.finish(this, object, dynamicType);
}
boundlessTypeVariables.clear();
+
+ TypeVariableBuilder.finishNullabilities(this, pendingNullabilities);
+ pendingNullabilities.clear();
+
return count;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index eeb0bac..cd2c0bf 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -37,6 +37,8 @@
import '../blacklisted_classes.dart' show blacklistedCoreClasses;
+import '../builder/extension_builder.dart';
+
import '../export.dart' show Export;
import '../import.dart' show Import;
@@ -968,6 +970,8 @@
Builder declaration = iterator.current;
if (declaration is ClassBuilder) {
declaration.buildOutlineExpressions(library);
+ } else if (declaration is ExtensionBuilder) {
+ declaration.buildOutlineExpressions(library);
} else if (declaration is MemberBuilder) {
declaration.buildOutlineExpressions(library);
}
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index ebf430a..8a1c08d 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -1361,6 +1361,12 @@
}
@override
+ void handleNonNullAssertExpression(Token token) {
+ debugEvent("NonNullAssertExpression", token);
+ state.popPushNull("%NonNullAssertExpression%", token);
+ }
+
+ @override
void handleUnescapeError(
Message message, Token location, int stringOffset, int length) {
debugEvent("UnescapeError", location);
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 4aa0538..d0506c9 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -51,6 +51,7 @@
bool enableExtensionMethods;
bool enableNonNullable;
bool enableTripleShift;
+ bool enableVariance;
TargetImplementation(Ticker ticker, this.uriTranslator, this.backendTarget)
: enableExtensionMethods = CompilerContext.current.options
@@ -59,6 +60,8 @@
.isExperimentEnabled(ExperimentalFlag.nonNullable),
enableTripleShift = CompilerContext.current.options
.isExperimentEnabled(ExperimentalFlag.tripleShift),
+ enableVariance = CompilerContext.current.options
+ .isExperimentEnabled(ExperimentalFlag.variance),
super(ticker);
/// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
index f01923c..3f1988c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart
@@ -22,9 +22,7 @@
set transformSetLiterals(bool value);
Expression buildProblem(Message message, int charOffset, int length,
- {List<LocatedMessage> context,
- bool suppressMessage,
- bool wrapInSyntheticExpression: true});
+ {List<LocatedMessage> context, bool suppressMessage});
LocatedMessage checkArgumentsForType(
FunctionType function, Arguments arguments, int offset);
@@ -37,6 +35,4 @@
String constructorNameForDiagnostics(String name,
{String className, bool isSuper});
-
- Expression desugarSyntheticExpression(Expression node);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index 0fb91de..f2243b2 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -27,8 +27,8 @@
Class get futureClass;
Class get futureOrClass;
InterfaceType get nullType;
- InterfaceType get objectType;
- InterfaceType get rawFunctionType;
+ InterfaceType get objectLegacyRawType;
+ InterfaceType get functionLegacyRawType;
bool isSubtypeOf(DartType subtype, DartType supertype);
@@ -74,10 +74,10 @@
}
// SLB(Object, T) = SLB(T, Object) = T if T is not void or dynamic.
- if (type1 == objectType) {
+ if (type1 == objectLegacyRawType) {
return type2;
}
- if (type2 == objectType) {
+ if (type2 == objectLegacyRawType) {
return type1;
}
@@ -182,10 +182,10 @@
}
// SUB(Object, T) = SUB(T, Object) = Object if T is not void or dynamic.
- if (type1 == objectType) {
+ if (type1 == objectLegacyRawType) {
return type1;
}
- if (type2 == objectType) {
+ if (type2 == objectLegacyRawType) {
return type2;
}
@@ -202,10 +202,10 @@
// The standard upper bound of a function type and an interface type T is
// the standard upper bound of Function and T.
if (type1 is FunctionType && type2 is InterfaceType) {
- type1 = rawFunctionType;
+ type1 = functionLegacyRawType;
}
if (type2 is FunctionType && type1 is InterfaceType) {
- type2 = rawFunctionType;
+ type2 = functionLegacyRawType;
}
// At this point type1 and type2 should both either be interface types or
@@ -474,13 +474,13 @@
// C<T extends U, U extends List>, T gets resolved directly to List. Do
// we need to replicate that behavior?
return getStandardUpperBound(
- Substitution.fromMap({type1.parameter: objectType})
+ Substitution.fromMap({type1.parameter: objectLegacyRawType})
.substituteType(type1.parameter.bound),
type2);
} else if (type2 is TypeParameterType) {
return getStandardUpperBound(
type1,
- Substitution.fromMap({type2.parameter: objectType})
+ Substitution.fromMap({type2.parameter: objectLegacyRawType})
.substituteType(type2.parameter.bound));
} else {
// We should only be called when at least one of the types is a
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 9bb90d0..4717c77 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -6,7 +6,7 @@
import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:kernel/ast.dart';
+import 'package:kernel/ast.dart' hide Variance;
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -716,14 +716,26 @@
new InstrumentationValueForMember(target.member));
}
- if (target.isUnresolved && includeExtensionMethods) {
+ if (target.isUnresolved &&
+ receiverType is! DynamicType &&
+ includeExtensionMethods) {
+ Member otherMember =
+ _getInterfaceMember(classNode, name, !setter, fileOffset);
+ if (otherMember != null) {
+ // If we're looking for `foo` and `foo=` can be found or vice-versa then
+ // extension methods should not be found.
+ return target;
+ }
+
ExtensionAccessCandidate bestSoFar;
List<ExtensionAccessCandidate> noneMoreSpecific = [];
library.scope.forEachExtension((ExtensionBuilder extensionBuilder) {
- MemberBuilder memberBuilder =
- extensionBuilder.lookupLocalMember(name.name, setter: setter);
- if (memberBuilder != null && !memberBuilder.isStatic) {
- Extension extension = extensionBuilder.extension;
+ MemberBuilder getterBuilder =
+ extensionBuilder.lookupLocalMember(name.name, setter: false);
+ MemberBuilder setterBuilder =
+ extensionBuilder.lookupLocalMember(name.name, setter: true);
+ if ((getterBuilder != null && !getterBuilder.isStatic) ||
+ (setterBuilder != null && !setterBuilder.isStatic)) {
DartType onType;
DartType onTypeInstantiateToBounds;
List<DartType> inferredTypeArguments;
@@ -762,15 +774,20 @@
}
if (typeSchemaEnvironment.isSubtypeOf(receiverType, onType)) {
+ MemberBuilder memberBuilder =
+ setter ? setterBuilder : getterBuilder;
+
ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
- extension,
onType,
onTypeInstantiateToBounds,
- new ObjectAccessTarget.extensionMember(
- memberBuilder.procedure,
- memberBuilder.extensionTearOff,
- memberBuilder.kind,
- inferredTypeArguments));
+ memberBuilder != null
+ ? new ObjectAccessTarget.extensionMember(
+ memberBuilder.procedure,
+ memberBuilder.extensionTearOff,
+ memberBuilder.kind,
+ inferredTypeArguments)
+ : const ObjectAccessTarget.missing(),
+ isPlatform: extensionBuilder.library.uri.scheme == 'dart');
if (noneMoreSpecific.isNotEmpty) {
bool isMostSpecific = true;
for (ExtensionAccessCandidate other in noneMoreSpecific) {
@@ -852,11 +869,11 @@
}
expression.parent.replaceChild(
expression,
- helper.desugarSyntheticExpression(helper.buildProblem(
+ helper.buildProblem(
errorTemplate.withArguments(
name.name, resolveTypeParameter(receiverType)),
fileOffset,
- length)));
+ length));
}
return target;
}
@@ -1772,11 +1789,10 @@
if (named.length == 2) {
if (named[0].name == named[1].name) {
String name = named[1].name;
- Expression error = helper.desugarSyntheticExpression(
- helper.buildProblem(
- templateDuplicatedNamedArgument.withArguments(name),
- named[1].fileOffset,
- name.length));
+ Expression error = helper.buildProblem(
+ templateDuplicatedNamedArgument.withArguments(name),
+ named[1].fileOffset,
+ name.length);
arguments.named = [new NamedExpression(named[1].name, error)];
formalTypes.removeLast();
actualTypes.removeLast();
@@ -1791,11 +1807,10 @@
if (seenNames.containsKey(name)) {
hasProblem = true;
NamedExpression prevNamedExpression = seenNames[name];
- prevNamedExpression.value = helper.desugarSyntheticExpression(
- helper.buildProblem(
- templateDuplicatedNamedArgument.withArguments(name),
- expression.fileOffset,
- name.length))
+ prevNamedExpression.value = helper.buildProblem(
+ templateDuplicatedNamedArgument.withArguments(name),
+ expression.fileOffset,
+ name.length)
..parent = prevNamedExpression;
formalTypes.removeAt(namedTypeIndex);
actualTypes.removeAt(namedTypeIndex);
@@ -2549,7 +2564,7 @@
expectedType = (expectedType as InterfaceType).typeArguments[0];
}
if (expectedType is FunctionType) return true;
- if (expectedType == typeSchemaEnvironment.rawFunctionType) {
+ if (expectedType == typeSchemaEnvironment.functionLegacyRawType) {
if (!typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
return true;
}
@@ -2841,11 +2856,11 @@
final bool isPlatform;
final DartType onType;
final DartType onTypeInstantiateToBounds;
- final ExtensionAccessTarget target;
+ final ObjectAccessTarget target;
- ExtensionAccessCandidate(Extension extension, this.onType,
- this.onTypeInstantiateToBounds, this.target)
- : isPlatform = extension.enclosingLibrary.importUri.scheme == 'dart';
+ ExtensionAccessCandidate(
+ this.onType, this.onTypeInstantiateToBounds, this.target,
+ {this.isPlatform});
bool isMoreSpecificThan(TypeSchemaEnvironment typeSchemaEnvironment,
ExtensionAccessCandidate other) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index ad77c76..5f8280e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -120,11 +120,11 @@
// TODO(paulberry): this matches what is defined in the spec. It would be
// nice if we could change kernel to match the spec and not have to
// override.
- if (type1 == intType) {
- if (type2 == intType) return type2;
- if (type2 == doubleType) return type2;
+ if (type1 == coreTypes.intLegacyRawType) {
+ if (type2 == coreTypes.intLegacyRawType) return type2;
+ if (type2 == coreTypes.doubleLegacyRawType) return type2;
}
- return numType;
+ return coreTypes.numLegacyRawType;
}
/// Infers a generic type, function, method, or list/map literal
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 5c99198..3742020 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -197,6 +197,10 @@
ExplicitExtensionArgumentMismatch/example: Fail
ExplicitExtensionTypeArgumentMismatch/analyzerCode: Fail
ExplicitExtensionTypeArgumentMismatch/example: Fail
+ExplicitExtensionAsExpression/analyzerCode: Fail
+ExplicitExtensionAsExpression/example: Fail
+ExplicitExtensionAsLvalue/analyzerCode: Fail
+ExplicitExtensionAsLvalue/example: Fail
ExportAfterPart/part_wrapped_script1: Fail
ExportAfterPart/script1: Fail
ExpressionNotMetadata/analyzerCode: Fail
@@ -310,6 +314,8 @@
ImplementsFutureOr/analyzerCode: Fail # The analyzer doesn't report this error.
ImplementsFutureOr/part_wrapped_script1: Fail # Importing file in the (now) part.
ImplicitCallOfNonMethod/example: Fail
+ImplicitMixinOverride/analyzerCode: Fail
+ImplicitMixinOverride/example: Fail
ImportAfterPart/part_wrapped_script1: Fail
ImportAfterPart/script1: Fail
IncompatibleRedirecteeFunctionType/part_wrapped_script6: Fail
@@ -319,6 +325,8 @@
InputFileNotFound/analyzerCode: Fail
InputFileNotFound/example: Fail
IntegerLiteralIsOutOfRange/example: Fail
+InterfaceCheck/analyzerCode: Fail
+InterfaceCheck/example: Fail
InterpolationInUri/example: Fail
IntersectionTypeAsTypeArgument/analyzerCode: Fail # Analyzer doesn't catch this error.
InvalidBreakTarget/analyzerCode: Fail
@@ -387,7 +395,10 @@
MultipleOnClauses/script: Fail
MultipleWith/part_wrapped_script: Fail
MultipleWith/script: Fail
+MultipleVarianceModifiers/example: Fail # All trigger multiple errors for variance experiment
NamedFunctionExpression/example: Fail
+NamedMixinOverride/analyzerCode: Fail
+NamedMixinOverride/example: Fail
NativeClauseShouldBeAnnotation/example: Fail
NoFormals/example: Fail
NoSuchNamedParameter/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 0436850..8568a27 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1430,17 +1430,14 @@
template: "'#name' is defined here."
severity: CONTEXT
-InterfaceCheckContext:
- template: "Both members are inherited by the non-abstract class '#name'."
- severity: CONTEXT
+InterfaceCheck:
+ template: "The implementation of '#name' in the non-abstract class '#name2' does not conform to its interface."
-NamedMixinOverrideContext:
- template: "Override was introduced in the mixin application class '#name'."
- severity: CONTEXT
+NamedMixinOverride:
+ template: "The mixin application class '#name' introduces an erroneous override of '#name2'."
-ImplicitMixinOverrideContext:
- template: "Override was introduced when the mixin '#name' was applied to '#name2'."
- severity: CONTEXT
+ImplicitMixinOverride:
+ template: "Applying the mixin '#name' to '#name2' introduces an erroneous override of '#name3'."
ListLiteralTooManyTypeArguments:
template: "List literal requires exactly one type argument."
@@ -1700,6 +1697,10 @@
template: "Unexpected usage of label inside declaration of variables."
severity: INTERNAL_PROBLEM
+InternalProblemUnfinishedTypeVariable:
+ template: "Unfinished type variable '#name' found in non-source library '#uri'."
+ severity: INTERNAL_PROBLEM
+
LocalDefinitionHidesExport:
template: "Local definition of '#name' hides export from '#uri'."
severity: IGNORED
@@ -3706,3 +3707,15 @@
ExplicitExtensionTypeArgumentMismatch:
template: "Explicit extension application of extension '#name' takes '#count' type argument(s)."
+
+ExplicitExtensionAsExpression:
+ template: "Explicit extension application cannot be used as an expression."
+
+ExplicitExtensionAsLvalue:
+ template: "Explicit extension application cannot be a target for assignment."
+
+MultipleVarianceModifiers:
+ index: 97
+ template: "Each type parameter can have at most one variance modifier."
+ tip: "Use at most one of the 'in', 'out', or 'inout' modifiers."
+ analyzerCode: ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index e39bb2e..83a7f7d 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,17 +1,18 @@
name: front_end
# Currently, front_end API is not stable and users should not
# depend on semver semantics when depending on this package.
-version: 0.1.25
+version: 0.1.26
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
environment:
sdk: '>=2.2.2 <3.0.0'
dependencies:
- kernel: 0.3.25
+ kernel: 0.3.26
package_config: '^1.1.0'
+ meta: ^1.0.2
dev_dependencies:
- analyzer: 0.38.3
+ analyzer: 0.38.4
args: '>=0.13.0 <2.0.0'
build_integration:
path: ../build_integration
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 273a013..fe1bbc0 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -149,22 +149,22 @@
new SuperPropertyAccessGenerator(helper, token, name, getter, setter));
check(
"IndexedAccessGenerator(offset: 4, receiver: expression, index: index,"
- " getter: $uri::myGetter, setter: $uri::mySetter,"
- " receiverVariable: null, indexVariable: null)",
+ " getter: $uri::myGetter, setter: $uri::mySetter)",
new IndexedAccessGenerator(
helper, token, expression, index, getter, setter));
check(
"ThisIndexedAccessGenerator(offset: 4, index: index,"
- " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+ " getter: $uri::myGetter, setter: $uri::mySetter)",
new ThisIndexedAccessGenerator(helper, token, index, getter, setter));
check(
"SuperIndexedAccessGenerator(offset: 4, index: index,"
- " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
+ " getter: $uri::myGetter, setter: $uri::mySetter)",
new SuperIndexedAccessGenerator(helper, token, index, getter, setter));
check(
- "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
+ "StaticAccessGenerator(offset: 4, targetName: foo,"
+ " readTarget: $uri::myGetter,"
" writeTarget: $uri::mySetter)",
- new StaticAccessGenerator(helper, token, getter, setter));
+ new StaticAccessGenerator(helper, token, 'foo', getter, setter));
check(
"LoadLibraryGenerator(offset: 4,"
" builder: Instance of 'LoadLibraryBuilder')",
diff --git a/pkg/front_end/test/fasta/type_inference/type_inference_engine_test.dart b/pkg/front_end/test/fasta/type_inference/type_inference_engine_test.dart
index 3e79fd5..b3c3aba 100644
--- a/pkg/front_end/test/fasta/type_inference/type_inference_engine_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_inference_engine_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
-import 'package:kernel/ast.dart';
+import 'package:kernel/ast.dart' hide Variance;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/front_end/test/fasta/types/dill_hierachy_test.dart b/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
index 80393e4..56053fa 100644
--- a/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
+++ b/pkg/front_end/test/fasta/types/dill_hierachy_test.dart
@@ -69,7 +69,7 @@
Longest path to Object: 3
superclasses:
Object
- interfaces: B<T>*, A, C<U>*
+ interfaces: B<T>, A, C<U>
classMembers:
classSetters:
interfaceMembers:
@@ -79,7 +79,7 @@
Longest path to Object: 4
superclasses:
Object
- interfaces: D<int, double>*, B<int>*, A, C<double>*
+ interfaces: D<int, double>, B<int>, A, C<double>
classMembers:
classSetters:
interfaceMembers:
@@ -89,7 +89,7 @@
Longest path to Object: 4
superclasses:
Object
- interfaces: D<int, bool>*, B<int>*, A, C<bool>*
+ interfaces: D<int, bool>, B<int>, A, C<bool>
classMembers:
classSetters:
interfaceMembers:
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser.dart b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
index 4a7f3b8..ff98073 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
@@ -193,7 +193,7 @@
// the bound because it's not yet available, it will be set to null. In
// that case, put it to the list to be updated later, when the bound is
// available.
- if (type.declaredNullability == null) {
+ if (type.typeParameterTypeNullability == null) {
environment.pendingNullabilities.add(type);
}
return type;
@@ -355,7 +355,7 @@
}
for (TypeParameterType type in nestedEnvironment.pendingNullabilities) {
- type.declaredNullability =
+ type.typeParameterTypeNullability =
TypeParameterType.computeNullabilityFromBound(type.parameter);
}
nestedEnvironment.pendingNullabilities.clear();
diff --git a/pkg/front_end/test/flow_analysis/type_promotion/data/not_promoted.dart b/pkg/front_end/test/flow_analysis/type_promotion/data/not_promoted.dart
new file mode 100644
index 0000000..ecca539
--- /dev/null
+++ b/pkg/front_end/test/flow_analysis/type_promotion/data/not_promoted.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2019, 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.
+
+class C {
+ this_access() {
+ if (this is D) {
+ this;
+ }
+ }
+
+ Object x = 'foo';
+
+ field_by_scope() {
+ if (x is String) {
+ x;
+ }
+ }
+
+ Object get y => 'foo';
+
+ getter_by_scope() {
+ if (y is String) {
+ y;
+ }
+ }
+}
+
+class D extends C {}
+
+field_by_access(C c) {
+ if (c.x is String) {
+ c.x;
+ }
+}
+
+getter_by_access(C c) {
+ if (c.y is String) {
+ c.y;
+ }
+}
+
+Object f() => 'foo';
+
+top_level_function() {
+ if (f is int Function()) {
+ f;
+ }
+}
+
+local_function() {
+ Object g() => 'foo';
+ if (g is int Function()) {
+ g;
+ }
+}
+
+Object a = 'foo';
+
+top_level_variable() {
+ if (a is String) {
+ a;
+ }
+}
+
+Object get b => 'foo';
+
+top_level_getter() {
+ if (b is String) {
+ b;
+ }
+}
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index dd6bf04..9013baa 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -43,7 +43,8 @@
Name,
Procedure;
-import 'package:kernel/target/targets.dart' show TargetFlags;
+import 'package:kernel/target/targets.dart'
+ show NoneTarget, Target, TargetFlags;
import 'package:kernel/text/ast_to_text.dart' show componentToString;
@@ -115,8 +116,11 @@
Future<Result<TestData>> run(TestData data, Context context) async {
YamlMap map = data.map;
+ Set<String> keys = new Set<String>.from(map.keys.cast<String>());
+ keys.remove("type");
switch (map["type"]) {
case "basic":
+ keys.removeAll(["sources", "entry", "invalidate"]);
await basicTest(
map["sources"],
map["entry"],
@@ -125,15 +129,19 @@
);
break;
case "newworld":
+ keys.removeAll(["worlds", "modules", "omitPlatform", "target"]);
await newWorldTest(
map["worlds"],
map["modules"],
map["omitPlatform"],
+ map["target"],
);
break;
default:
throw "Unexpected type: ${map['type']}";
}
+
+ if (keys.isNotEmpty) throw "Unknown toplevel keys: $keys";
return pass(data);
}
}
@@ -198,7 +206,7 @@
}
Future<Map<String, List<int>>> createModules(
- Map module, final List<int> sdkSummaryData) async {
+ Map module, final List<int> sdkSummaryData, String targetName) async {
final Uri base = Uri.parse("org-dartlang-test:///");
final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
@@ -230,7 +238,7 @@
moduleSources.add(uri);
}
}
- CompilerOptions options = getOptions();
+ CompilerOptions options = getOptions(targetName: targetName);
options.fileSystem = fs;
options.sdkRoot = null;
options.sdkSummary = sdkSummary;
@@ -264,7 +272,8 @@
return moduleResult;
}
-Future<Null> newWorldTest(List worlds, Map modules, bool omitPlatform) async {
+Future<Null> newWorldTest(
+ List worlds, Map modules, bool omitPlatform, String targetName) async {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
final Uri base = Uri.parse("org-dartlang-test:///");
final Uri sdkSummary = base.resolve("vm_platform_strong.dill");
@@ -284,7 +293,7 @@
Map<String, Component> moduleComponents;
Component sdk;
if (modules != null) {
- moduleData = await createModules(modules, sdkSummaryData);
+ moduleData = await createModules(modules, sdkSummaryData, targetName);
sdk = newestWholeComponent = new Component();
new BinaryBuilder(sdkSummaryData, filename: null, disableLazyReading: false)
.readComponent(newestWholeComponent);
@@ -370,7 +379,7 @@
}
if (brandNewWorld) {
- options = getOptions();
+ options = getOptions(targetName: targetName);
options.fileSystem = fs;
options.sdkRoot = null;
options.sdkSummary = sdkSummary;
@@ -800,11 +809,21 @@
Expect.equals(a.length, b.length);
}
-CompilerOptions getOptions() {
+CompilerOptions getOptions({String targetName}) {
final Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
+ Target target = new VmTarget(new TargetFlags());
+ if (targetName != null) {
+ if (targetName == "None") {
+ target = new NoneTarget(new TargetFlags());
+ } else if (targetName == "VM") {
+ // default.
+ } else {
+ throw "Unknown target name '$targetName'";
+ }
+ }
CompilerOptions options = new CompilerOptions()
..sdkRoot = sdkRoot
- ..target = new VmTarget(new TargetFlags())
+ ..target = target
..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
..omitPlatform = true
..onDiagnostic = (DiagnosticMessage message) {
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 8f9700e..bb052b5 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -545,13 +545,7 @@
}
void test_keyword_inout() {
- _assertKeywordToken("inout",
- configuration: ScannerConfiguration(enableVariance: true));
- }
-
- void test_keyword_inout_old() {
- _assertNotKeywordToken("inout",
- configuration: ScannerConfiguration(enableVariance: false));
+ _assertKeywordToken("inout");
}
void test_keyword_is() {
@@ -601,13 +595,7 @@
}
void test_keyword_out() {
- _assertKeywordToken("out",
- configuration: ScannerConfiguration(enableVariance: true));
- }
-
- void test_keyword_out_old() {
- _assertNotKeywordToken("out",
- configuration: ScannerConfiguration(enableVariance: false));
+ _assertKeywordToken("out");
}
void test_keyword_part() {
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 893e05d..351b53d 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -14,6 +14,8 @@
accounts
accumulated
accumulating
+acon
+acov
across
affecting
afterwards
@@ -21,6 +23,7 @@
ahe
ai
aiki
+ainv
aka
alexmarkov
aligned
@@ -299,6 +302,8 @@
fasta
favoring
fc
+fcon
+fcov
fe
feff
ff
@@ -309,6 +314,7 @@
ffi
file's
filenames
+finv
firsts
fishy
fishythefish
@@ -331,6 +337,7 @@
frontend
frontends
fs
+fsource
function's
fuse
futured
@@ -377,6 +384,7 @@
human
i
i'll
+i2b
id
identifies
identifying
@@ -438,13 +446,14 @@
juxtaposition
juxtapositions
k
-k’s
+kallentu
kernel's
kernel2kernel
klass
kmillikin
kustermann
kv
+k’s
l
lacks
lang
@@ -621,13 +630,13 @@
quick
quoted
r
+r'$creation
r'\f
r'\r
r'\s
r'\t
r'\u
r'\v
-r'$creation
radix
raises
ran
@@ -1003,6 +1012,7 @@
xxxxxx
xxxxxxx
y
+y`s
yaml
yet
yielding
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 00968fa..40d83cd 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -97,8 +97,8 @@
also
alternating
alternative
-alternatives
alternatively
+alternatives
although
always
ambiguous
@@ -251,6 +251,7 @@
bets
better
between
+beyond
big
bigint
binaries
@@ -278,6 +279,7 @@
bound
boundary
bounded
+boundedness
boundless
bounds
box
@@ -319,6 +321,7 @@
calculated
calculates
calculation
+calculator
call
callback
called
@@ -740,6 +743,7 @@
development
devices
devise
+dfs
diagnostic
diagnostics
did
@@ -812,6 +816,7 @@
drive
driver
drop
+dropped
dropping
due
dump
@@ -1628,6 +1633,7 @@
matcher
matches
matching
+material
math
mathematical
matter
@@ -1725,6 +1731,7 @@
mutate
mutated
mutates
+mutating
mutation
mutations
mutual
@@ -1958,10 +1965,10 @@
piping
pivot
place
-places
placed
placeholder
placeholders
+places
plain
plan
platform
@@ -2292,6 +2299,7 @@
restores
restrict
restricted
+restrictive
result
resulting
results
@@ -2592,6 +2600,7 @@
substring
substrings
substructures
+subterm
subterms
subtly
subtract
@@ -2922,6 +2931,7 @@
var
variable
variables
+variance
various
verbose
verification
@@ -2939,6 +2949,7 @@
very
via
view
+viewed
violate
violates
violation
diff --git a/pkg/front_end/testcases/all_variances.dart b/pkg/front_end/testcases/all_variances.dart
new file mode 100644
index 0000000..3f1a118
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, 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.
+
+// The test checks how type parameters of different variances are serialized.
+
+typedef F<W, X, Y, Z> = X Function(Y, Z Function(Z));
+
+main() {}
diff --git a/pkg/front_end/testcases/all_variances.dart.legacy.expect b/pkg/front_end/testcases/all_variances.dart.legacy.expect
new file mode 100644
index 0000000..add5d55
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart.legacy.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated W extends core::Object = dynamic, X extends core::Object = dynamic, contravariant Y extends core::Object = dynamic, invariant Z extends core::Object = dynamic> = (Y, (Z) → Z) → X;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/all_variances.dart.legacy.transformed.expect b/pkg/front_end/testcases/all_variances.dart.legacy.transformed.expect
new file mode 100644
index 0000000..add5d55
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart.legacy.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated W extends core::Object = dynamic, X extends core::Object = dynamic, contravariant Y extends core::Object = dynamic, invariant Z extends core::Object = dynamic> = (Y, (Z) → Z) → X;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/all_variances.dart.outline.expect b/pkg/front_end/testcases/all_variances.dart.outline.expect
new file mode 100644
index 0000000..23f7ffa
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated W extends core::Object* = dynamic, X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> = (Y*, (Z*) →* Z*) →* X*;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/all_variances.dart.strong.expect b/pkg/front_end/testcases/all_variances.dart.strong.expect
new file mode 100644
index 0000000..f7afd1b
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart.strong.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated W extends core::Object* = dynamic, X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> = (Y*, (Z*) →* Z*) →* X*;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/all_variances.dart.strong.transformed.expect b/pkg/front_end/testcases/all_variances.dart.strong.transformed.expect
new file mode 100644
index 0000000..f7afd1b
--- /dev/null
+++ b/pkg/front_end/testcases/all_variances.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<unrelated W extends core::Object* = dynamic, X extends core::Object* = dynamic, contravariant Y extends core::Object* = dynamic, invariant Z extends core::Object* = dynamic> = (Y*, (Z*) →* Z*) →* X*;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
index b7af5e3..e7333cd 100644
--- a/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
+++ b/pkg/front_end/testcases/expression/lib_nonshown_ctor.expression.yaml.expect
@@ -2,10 +2,6 @@
org-dartlang-debug:synthetic_debug_expression:1:5: Error: Method not found: 'Directory'.
new Directory("test")
^^^^^^^^^
- org-dartlang-debug:synthetic_debug_expression:1:14: Error: Too many positional arguments: 0 allowed, but 1 found.
- Try removing the extra positional arguments.
- new Directory("test")
- ^
}
method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
return invalid-expression "org-dartlang-debug:synthetic_debug_expression:1:5: Error: Method not found: 'Directory'.\nnew Directory(\"test\")\n ^^^^^^^^^";
diff --git a/pkg/front_end/testcases/extensions/annotations.dart b/pkg/front_end/testcases/extensions/annotations.dart
new file mode 100644
index 0000000..0e0b623
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ @pragma('dart2js:noInline')
+ instanceMethod() {}
+
+ @pragma('dart2js:noInline')
+ static staticMethod() {}
+}
+
+extension Extension on Class {
+ @pragma('dart2js:noInline')
+ extensionInstanceMethod() {}
+
+ @pragma('dart2js:noInline')
+ static extensionStaticMethod() {}
+}
+
+@pragma('dart2js:noInline')
+topLevelMethod() {}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.outline.expect b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect
new file mode 100644
index 0000000..1c72331
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.outline.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+ @core::pragma::_("dart2js:noInline")
+ method instanceMethod() → dynamic
+ ;
+ @core::pragma::_("dart2js:noInline")
+ static method staticMethod() → dynamic
+ ;
+}
+extension Extension on self::Class* {
+ method extensionInstanceMethod = self::Extension|extensionInstanceMethod;
+ tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod;
+ static method extensionStaticMethod = self::Extension|extensionStaticMethod;
+}
+@core::pragma::_("dart2js:noInline")
+static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic
+ ;
+static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|extensionInstanceMethod(#this);
+@core::pragma::_("dart2js:noInline")
+static method Extension|extensionStaticMethod() → dynamic
+ ;
+@core::pragma::_("dart2js:noInline")
+static method topLevelMethod() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect
new file mode 100644
index 0000000..73aac11
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ @#C3
+ method instanceMethod() → dynamic {}
+ @#C3
+ static method staticMethod() → dynamic {}
+}
+extension Extension on self::Class* {
+ method extensionInstanceMethod = self::Extension|extensionInstanceMethod;
+ tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod;
+ static method extensionStaticMethod = self::Extension|extensionStaticMethod;
+}
+@#C3
+static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {}
+static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|extensionInstanceMethod(#this);
+@#C3
+static method Extension|extensionStaticMethod() → dynamic {}
+@#C3
+static method topLevelMethod() → dynamic {}
+static method main() → dynamic {}
+
+constants {
+ #C1 = "dart2js:noInline"
+ #C2 = null
+ #C3 = core::pragma {name:#C1, options:#C2}
+}
diff --git a/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect
new file mode 100644
index 0000000..73aac11
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/annotations.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ @#C3
+ method instanceMethod() → dynamic {}
+ @#C3
+ static method staticMethod() → dynamic {}
+}
+extension Extension on self::Class* {
+ method extensionInstanceMethod = self::Extension|extensionInstanceMethod;
+ tearoff extensionInstanceMethod = self::Extension|get#extensionInstanceMethod;
+ static method extensionStaticMethod = self::Extension|extensionStaticMethod;
+}
+@#C3
+static method Extension|extensionInstanceMethod(final self::Class* #this) → dynamic {}
+static method Extension|get#extensionInstanceMethod(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|extensionInstanceMethod(#this);
+@#C3
+static method Extension|extensionStaticMethod() → dynamic {}
+@#C3
+static method topLevelMethod() → dynamic {}
+static method main() → dynamic {}
+
+constants {
+ #C1 = "dart2js:noInline"
+ #C2 = null
+ #C3 = core::pragma {name:#C1, options:#C2}
+}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart b/pkg/front_end/testcases/extensions/compounds.dart
index 1664612..812e0c9 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart
+++ b/pkg/front_end/testcases/extensions/compounds.dart
@@ -46,11 +46,53 @@
void set property(Number value) {
field = value;
}
+
+ testImplicitProperties() {
+ Number n0 = new Number(0);
+ Number n1 = new Number(1);
+ Number n2 = new Number(2);
+
+ expect(n0, property);
+ expect(n1, property += n1);
+ expect(n2, property += n1);
+ expect(n0, property -= n2);
+ expect(n1, property += n1);
+ expect(n0, property -= n1);
+ expect(n1, ++property);
+ expect(n0, --property);
+ expect(n0, property++);
+ expect(n1, property--);
+ expect(n0, property);
+
+ expect(n0, property);
+ property += n1;
+ expect(n1, property);
+ property += n1;
+ expect(n2, property);
+ property -= n2;
+ expect(n0, property);
+ property += n1;
+ expect(n1, property);
+ property -= n1;
+ expect(n0, property);
+ ++property;
+ expect(n1, property);
+ --property;
+ expect(n0, property);
+ property++;
+ expect(n1, property);
+ property--;
+ expect(n0, property);
+ }
}
main() {
testLocals();
testProperties();
+ testExplicitProperties();
+ testExplicitNullAwareProperties(null);
+ testExplicitNullAwareProperties(new Class(new Number(0)));
+ new Class(new Number(0)).testImplicitProperties();
}
testLocals() {
@@ -69,6 +111,26 @@
expect(n0, v++);
expect(n1, v--);
expect(n0, v);
+
+ expect(n0, v);
+ v += n1;
+ expect(n1, v);
+ v += n1;
+ expect(n2, v);
+ v -= n2;
+ expect(n0, v);
+ v += n1;
+ expect(n1, v);
+ v -= n1;
+ expect(n0, v);
+ ++v;
+ expect(n1, v);
+ --v;
+ expect(n0, v);
+ v++;
+ expect(n1, v);
+ v--;
+ expect(n0, v);
}
testProperties() {
@@ -88,6 +150,26 @@
expect(n1, v.field--);
expect(n0, v.field);
+ expect(n0, v.field);
+ v.field += n1;
+ expect(n1, v.field);
+ v.field += n1;
+ expect(n2, v.field);
+ v.field -= n2;
+ expect(n0, v.field);
+ v.field += n1;
+ expect(n1, v.field);
+ v.field -= n1;
+ expect(n0, v.field);
+ ++v.field;
+ expect(n1, v.field);
+ --v.field;
+ expect(n0, v.field);
+ v.field++;
+ expect(n1, v.field);
+ v.field--;
+ expect(n0, v.field);
+
expect(n0, v.property);
expect(n1, v.property += n1);
expect(n2, v.property += n1);
@@ -99,9 +181,109 @@
expect(n0, v.property++);
expect(n1, v.property--);
expect(n0, v.property);
+
+ expect(n0, v.property);
+ v.property += n1;
+ expect(n1, v.property);
+ v.property += n1;
+ expect(n2, v.property);
+ v.property -= n2;
+ expect(n0, v.property);
+ v.property += n1;
+ expect(n1, v.property);
+ v.property -= n1;
+ expect(n0, v.property);
+ ++v.property;
+ expect(n1, v.property);
+ --v.property;
+ expect(n0, v.property);
+ v.property++;
+ expect(n1, v.property);
+ v.property--;
+ expect(n0, v.property);
}
-expect(expected, actual) {
+testExplicitProperties() {
+ Number n0 = new Number(0);
+ Number n1 = new Number(1);
+ Number n2 = new Number(2);
+ Class v = new Class(n0);
+
+ expect(n0, ClassExtension(v).property);
+ expect(n1, ClassExtension(v).property += n1);
+ expect(n2, ClassExtension(v).property += n1);
+ expect(n0, ClassExtension(v).property -= n2);
+ expect(n1, ClassExtension(v).property += n1);
+ expect(n0, ClassExtension(v).property -= n1);
+ expect(n1, ++ClassExtension(v).property);
+ expect(n0, --ClassExtension(v).property);
+ expect(n0, ClassExtension(v).property++);
+ expect(n1, ClassExtension(v).property--);
+ expect(n0, ClassExtension(v).property);
+
+ expect(n0, ClassExtension(v).property);
+ ClassExtension(v).property += n1;
+ expect(n1, ClassExtension(v).property);
+ ClassExtension(v).property += n1;
+ expect(n2, ClassExtension(v).property);
+ ClassExtension(v).property -= n2;
+ expect(n0, ClassExtension(v).property);
+ ClassExtension(v).property += n1;
+ expect(n1, ClassExtension(v).property);
+ ClassExtension(v).property -= n1;
+ expect(n0, ClassExtension(v).property);
+ ++ClassExtension(v).property;
+ expect(n1, ClassExtension(v).property);
+ --ClassExtension(v).property;
+ expect(n0, ClassExtension(v).property);
+ ClassExtension(v).property++;
+ expect(n1, ClassExtension(v).property);
+ ClassExtension(v).property--;
+ expect(n0, ClassExtension(v).property);
+}
+
+testExplicitNullAwareProperties(Class v) {
+ Number n0 = new Number(0);
+ Number n1 = new Number(1);
+ Number n2 = new Number(2);
+
+ expect(n0, ClassExtension(v)?.property, v == null);
+ expect(n1, ClassExtension(v)?.property += n1, v == null);
+ expect(n2, ClassExtension(v)?.property += n1, v == null);
+ expect(n0, ClassExtension(v)?.property -= n2, v == null);
+ expect(n1, ClassExtension(v)?.property += n1, v == null);
+ expect(n0, ClassExtension(v)?.property -= n1, v == null);
+ expect(n1, ++ClassExtension(v)?.property, v == null);
+ expect(n0, --ClassExtension(v)?.property, v == null);
+ expect(n0, ClassExtension(v)?.property++, v == null);
+ expect(n1, ClassExtension(v)?.property--, v == null);
+ expect(n0, ClassExtension(v)?.property, v == null);
+
+ expect(n0, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property += n1;
+ expect(n1, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property += n1;
+ expect(n2, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property -= n2;
+ expect(n0, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property += n1;
+ expect(n1, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property -= n1;
+ expect(n0, ClassExtension(v)?.property, v == null);
+ ++ClassExtension(v)?.property;
+ expect(n1, ClassExtension(v)?.property, v == null);
+ --ClassExtension(v)?.property;
+ expect(n0, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property++;
+ expect(n1, ClassExtension(v)?.property, v == null);
+ ClassExtension(v)?.property--;
+ expect(n0, ClassExtension(v)?.property, v == null);
+}
+
+expect(expected, actual, [expectNull = false]) {
+ if (expectNull) {
+ expected = null;
+ }
if (expected != actual) {
throw 'Mismatch: expected=$expected, actual=$actual';
}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.outline.expect b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
index 10363aa..42ab3e2 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.outline.expect
@@ -24,6 +24,8 @@
}
extension ClassExtension on self::Class* {
get property = self::ClassExtension|get#property;
+ method testImplicitProperties = self::ClassExtension|testImplicitProperties;
+ tearoff testImplicitProperties = self::ClassExtension|get#testImplicitProperties;
set property = self::ClassExtension|set#property;
}
static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number*
@@ -34,11 +36,19 @@
;
static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void
;
+static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic
+ ;
+static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
static method main() → dynamic
;
static method testLocals() → dynamic
;
static method testProperties() → dynamic
;
-static method expect(dynamic expected, dynamic actual) → dynamic
+static method testExplicitProperties() → dynamic
+ ;
+static method testExplicitNullAwareProperties(self::Class* v) → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual, [dynamic expectNull]) → dynamic
;
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
index 1360e1d..e0e9cdf 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.expect
@@ -26,6 +26,8 @@
}
extension ClassExtension on self::Class* {
get property = self::ClassExtension|get#property;
+ method testImplicitProperties = self::ClassExtension|testImplicitProperties;
+ tearoff testImplicitProperties = self::ClassExtension|get#testImplicitProperties;
set property = self::ClassExtension|set#property;
}
static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
@@ -54,14 +56,53 @@
}
static method ClassExtension|get#property(final self::Class* #this) → self::Number*
return #this.{self::Class::field};
-static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → self::Number* {
- final self::Number* #t1 = value;
+static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
+static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::expect(n1, let final self::Number* #t1 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t2 = self::ClassExtension|set#property(#this, #t1) in #t1);
+ self::expect(n2, let final self::Number* #t3 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t4 = self::ClassExtension|set#property(#this, #t3) in #t3);
+ self::expect(n0, let final self::Number* #t5 = self::NumberExtension|-(self::ClassExtension|get#property(#this), n2) in let final void #t6 = self::ClassExtension|set#property(#this, #t5) in #t5);
+ self::expect(n1, let final self::Number* #t7 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t8 = self::ClassExtension|set#property(#this, #t7) in #t7);
+ self::expect(n0, let final self::Number* #t9 = self::NumberExtension|-(self::ClassExtension|get#property(#this), n1) in let final void #t10 = self::ClassExtension|set#property(#this, #t9) in #t9);
+ self::expect(n1, let final self::Number* #t11 = self::NumberExtension|+(self::ClassExtension|get#property(#this), 1) in let final void #t12 = self::ClassExtension|set#property(#this, #t11) in #t11);
+ self::expect(n0, let final self::Number* #t13 = self::NumberExtension|-(self::ClassExtension|get#property(#this), 1) in let final void #t14 = self::ClassExtension|set#property(#this, #t13) in #t13);
+ self::expect(n0, let final self::Number* #t15 = self::ClassExtension|get#property(#this) in let final self::Number* #t16 = self::ClassExtension|set#property(#this, self::NumberExtension|+(#t15, 1)) in #t15);
+ self::expect(n1, let final self::Number* #t17 = self::ClassExtension|get#property(#this) in let final self::Number* #t18 = self::ClassExtension|set#property(#this, self::NumberExtension|-(#t17, 1)) in #t17);
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n2, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), n2));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), n1));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ let final self::Number* #t19 = self::NumberExtension|+(self::ClassExtension|get#property(#this), 1) in let final void #t20 = self::ClassExtension|set#property(#this, #t19) in #t19;
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ let final self::Number* #t21 = self::NumberExtension|-(self::ClassExtension|get#property(#this), 1) in let final void #t22 = self::ClassExtension|set#property(#this, #t21) in #t21;
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), 1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), 1));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+}
+static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
static method main() → dynamic {
self::testLocals();
self::testProperties();
+ self::testExplicitProperties();
+ self::testExplicitNullAwareProperties(null);
+ self::testExplicitNullAwareProperties(new self::Class::•(new self::Number::•(0)));
+ self::ClassExtension|testImplicitProperties(new self::Class::•(new self::Number::•(0)));
}
static method testLocals() → dynamic {
self::Number* n0 = new self::Number::•(0);
@@ -76,8 +117,27 @@
self::expect(n0, v = self::NumberExtension|-(v, n1));
self::expect(n1, v = self::NumberExtension|+(v, 1));
self::expect(n0, v = self::NumberExtension|-(v, 1));
- self::expect(n0, let final self::Number* #t2 = v in let final self::Number* #t3 = v = self::NumberExtension|+(#t2, 1) in #t2);
- self::expect(n1, let final self::Number* #t4 = v in let final self::Number* #t5 = v = self::NumberExtension|-(#t4, 1) in #t4);
+ self::expect(n0, let final self::Number* #t23 = v in let final self::Number* #t24 = v = self::NumberExtension|+(#t23, 1) in #t23);
+ self::expect(n1, let final self::Number* #t25 = v in let final self::Number* #t26 = v = self::NumberExtension|-(#t25, 1) in #t25);
+ self::expect(n0, v);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n1, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n2, v);
+ v = self::NumberExtension|-(v, n2);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, n1);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, 1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, 1);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, 1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, 1);
self::expect(n0, v);
}
static method testProperties() → dynamic {
@@ -86,30 +146,146 @@
self::Number* n2 = new self::Number::•(2);
self::Class* v = new self::Class::•(n0);
self::expect(n0, v.{self::Class::field});
- self::expect(n1, let final self::Class* #t6 = v in #t6.{self::Class::field} = self::NumberExtension|+(#t6.{self::Class::field}, n1));
- self::expect(n2, let final self::Class* #t7 = v in #t7.{self::Class::field} = self::NumberExtension|+(#t7.{self::Class::field}, n1));
- self::expect(n0, let final self::Class* #t8 = v in #t8.{self::Class::field} = self::NumberExtension|-(#t8.{self::Class::field}, n2));
- self::expect(n1, let final self::Class* #t9 = v in #t9.{self::Class::field} = self::NumberExtension|+(#t9.{self::Class::field}, n1));
- self::expect(n0, let final self::Class* #t10 = v in #t10.{self::Class::field} = self::NumberExtension|-(#t10.{self::Class::field}, n1));
- self::expect(n1, let final self::Class* #t11 = v in #t11.{self::Class::field} = self::NumberExtension|+(#t11.{self::Class::field}, 1));
- self::expect(n0, let final self::Class* #t12 = v in #t12.{self::Class::field} = self::NumberExtension|-(#t12.{self::Class::field}, 1));
- self::expect(n0, let final self::Class* #t13 = v in let final self::Number* #t14 = #t13.{self::Class::field} in let final self::Number* #t15 = #t13.{self::Class::field} = self::NumberExtension|+(#t14, 1) in #t14);
- self::expect(n1, let final self::Class* #t16 = v in let final self::Number* #t17 = #t16.{self::Class::field} in let final self::Number* #t18 = #t16.{self::Class::field} = self::NumberExtension|-(#t17, 1) in #t17);
+ self::expect(n1, let final self::Class* #t27 = v in #t27.{self::Class::field} = self::NumberExtension|+(#t27.{self::Class::field}, n1));
+ self::expect(n2, let final self::Class* #t28 = v in #t28.{self::Class::field} = self::NumberExtension|+(#t28.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t29 = v in #t29.{self::Class::field} = self::NumberExtension|-(#t29.{self::Class::field}, n2));
+ self::expect(n1, let final self::Class* #t30 = v in #t30.{self::Class::field} = self::NumberExtension|+(#t30.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t31 = v in #t31.{self::Class::field} = self::NumberExtension|-(#t31.{self::Class::field}, n1));
+ self::expect(n1, let final self::Class* #t32 = v in #t32.{self::Class::field} = self::NumberExtension|+(#t32.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t33 = v in #t33.{self::Class::field} = self::NumberExtension|-(#t33.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t34 = v in let final self::Number* #t35 = #t34.{self::Class::field} in let final self::Number* #t36 = #t34.{self::Class::field} = self::NumberExtension|+(#t35, 1) in #t35);
+ self::expect(n1, let final self::Class* #t37 = v in let final self::Number* #t38 = #t37.{self::Class::field} in let final self::Number* #t39 = #t37.{self::Class::field} = self::NumberExtension|-(#t38, 1) in #t38);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t40 = v in #t40.{self::Class::field} = self::NumberExtension|+(#t40.{self::Class::field}, n1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t41 = v in #t41.{self::Class::field} = self::NumberExtension|+(#t41.{self::Class::field}, n1);
+ self::expect(n2, v.{self::Class::field});
+ let final self::Class* #t42 = v in #t42.{self::Class::field} = self::NumberExtension|-(#t42.{self::Class::field}, n2);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t43 = v in #t43.{self::Class::field} = self::NumberExtension|+(#t43.{self::Class::field}, n1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t44 = v in #t44.{self::Class::field} = self::NumberExtension|-(#t44.{self::Class::field}, n1);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t45 = v in #t45.{self::Class::field} = self::NumberExtension|+(#t45.{self::Class::field}, 1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t46 = v in #t46.{self::Class::field} = self::NumberExtension|-(#t46.{self::Class::field}, 1);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t47 = v in #t47.{self::Class::field} = self::NumberExtension|+(#t47.{self::Class::field}, 1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t48 = v in #t48.{self::Class::field} = self::NumberExtension|-(#t48.{self::Class::field}, 1);
self::expect(n0, v.{self::Class::field});
self::expect(n0, self::ClassExtension|get#property(v));
- self::expect(n1, let final self::Class* #t19 = v in self::ClassExtension|set#property(#t19, self::NumberExtension|+(self::ClassExtension|get#property(#t19), n1)));
- self::expect(n2, let final self::Class* #t20 = v in self::ClassExtension|set#property(#t20, self::NumberExtension|+(self::ClassExtension|get#property(#t20), n1)));
- self::expect(n0, let final self::Class* #t21 = v in self::ClassExtension|set#property(#t21, self::NumberExtension|-(self::ClassExtension|get#property(#t21), n2)));
- self::expect(n1, let final self::Class* #t22 = v in self::ClassExtension|set#property(#t22, self::NumberExtension|+(self::ClassExtension|get#property(#t22), n1)));
- self::expect(n0, let final self::Class* #t23 = v in self::ClassExtension|set#property(#t23, self::NumberExtension|-(self::ClassExtension|get#property(#t23), n1)));
- self::expect(n1, let final self::Class* #t24 = v in self::ClassExtension|set#property(#t24, self::NumberExtension|+(self::ClassExtension|get#property(#t24), 1)));
- self::expect(n0, let final self::Class* #t25 = v in self::ClassExtension|set#property(#t25, self::NumberExtension|-(self::ClassExtension|get#property(#t25), 1)));
- self::expect(n0, let final self::Class* #t26 = v in let final self::Number* #t27 = self::ClassExtension|get#property(#t26) in let final self::Number* #t28 = self::ClassExtension|set#property(#t26, self::NumberExtension|+(#t27, 1)) in #t27);
- self::expect(n1, let final self::Class* #t29 = v in let final self::Number* #t30 = self::ClassExtension|get#property(#t29) in let final self::Number* #t31 = self::ClassExtension|set#property(#t29, self::NumberExtension|-(#t30, 1)) in #t30);
+ self::expect(n1, let final self::Class* #t49 = v in let final self::Class* #t50 = #t49 in let final self::Number* #t51 = self::NumberExtension|+(self::ClassExtension|get#property(#t49), n1) in let final void #t52 = self::ClassExtension|set#property(#t50, #t51) in #t51);
+ self::expect(n2, let final self::Class* #t53 = v in let final self::Class* #t54 = #t53 in let final self::Number* #t55 = self::NumberExtension|+(self::ClassExtension|get#property(#t53), n1) in let final void #t56 = self::ClassExtension|set#property(#t54, #t55) in #t55);
+ self::expect(n0, let final self::Class* #t57 = v in let final self::Class* #t58 = #t57 in let final self::Number* #t59 = self::NumberExtension|-(self::ClassExtension|get#property(#t57), n2) in let final void #t60 = self::ClassExtension|set#property(#t58, #t59) in #t59);
+ self::expect(n1, let final self::Class* #t61 = v in let final self::Class* #t62 = #t61 in let final self::Number* #t63 = self::NumberExtension|+(self::ClassExtension|get#property(#t61), n1) in let final void #t64 = self::ClassExtension|set#property(#t62, #t63) in #t63);
+ self::expect(n0, let final self::Class* #t65 = v in let final self::Class* #t66 = #t65 in let final self::Number* #t67 = self::NumberExtension|-(self::ClassExtension|get#property(#t65), n1) in let final void #t68 = self::ClassExtension|set#property(#t66, #t67) in #t67);
+ self::expect(n1, let final self::Class* #t69 = v in let final self::Class* #t70 = #t69 in let final self::Number* #t71 = self::NumberExtension|+(self::ClassExtension|get#property(#t69), 1) in let final void #t72 = self::ClassExtension|set#property(#t70, #t71) in #t71);
+ self::expect(n0, let final self::Class* #t73 = v in let final self::Class* #t74 = #t73 in let final self::Number* #t75 = self::NumberExtension|-(self::ClassExtension|get#property(#t73), 1) in let final void #t76 = self::ClassExtension|set#property(#t74, #t75) in #t75);
+ self::expect(n0, let final self::Class* #t77 = v in let final self::Number* #t78 = self::ClassExtension|get#property(#t77) in let final self::Number* #t79 = self::ClassExtension|set#property(#t77, self::NumberExtension|+(#t78, 1)) in #t78);
+ self::expect(n1, let final self::Class* #t80 = v in let final self::Number* #t81 = self::ClassExtension|get#property(#t80) in let final self::Number* #t82 = self::ClassExtension|set#property(#t80, self::NumberExtension|-(#t81, 1)) in #t81);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t83 = v in self::ClassExtension|set#property(#t83, self::NumberExtension|+(self::ClassExtension|get#property(#t83), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t84 = v in self::ClassExtension|set#property(#t84, self::NumberExtension|+(self::ClassExtension|get#property(#t84), n1));
+ self::expect(n2, self::ClassExtension|get#property(v));
+ let final self::Class* #t85 = v in self::ClassExtension|set#property(#t85, self::NumberExtension|-(self::ClassExtension|get#property(#t85), n2));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t86 = v in self::ClassExtension|set#property(#t86, self::NumberExtension|+(self::ClassExtension|get#property(#t86), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t87 = v in self::ClassExtension|set#property(#t87, self::NumberExtension|-(self::ClassExtension|get#property(#t87), n1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t88 = v in let final self::Class* #t89 = #t88 in let final self::Number* #t90 = self::NumberExtension|+(self::ClassExtension|get#property(#t88), 1) in let final void #t91 = self::ClassExtension|set#property(#t89, #t90) in #t90;
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t92 = v in let final self::Class* #t93 = #t92 in let final self::Number* #t94 = self::NumberExtension|-(self::ClassExtension|get#property(#t92), 1) in let final void #t95 = self::ClassExtension|set#property(#t93, #t94) in #t94;
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t96 = v in self::ClassExtension|set#property(#t96, self::NumberExtension|+(self::ClassExtension|get#property(#t96), 1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t97 = v in self::ClassExtension|set#property(#t97, self::NumberExtension|-(self::ClassExtension|get#property(#t97), 1));
self::expect(n0, self::ClassExtension|get#property(v));
}
-static method expect(dynamic expected, dynamic actual) → dynamic {
+static method testExplicitProperties() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Class* v = new self::Class::•(n0);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n1, let final self::Class* #t98 = v in let final self::Number* #t99 = self::NumberExtension|+(self::ClassExtension|get#property(#t98), n1) in let final void #t100 = self::ClassExtension|set#property(#t98, #t99) in #t99);
+ self::expect(n2, let final self::Class* #t101 = v in let final self::Number* #t102 = self::NumberExtension|+(self::ClassExtension|get#property(#t101), n1) in let final void #t103 = self::ClassExtension|set#property(#t101, #t102) in #t102);
+ self::expect(n0, let final self::Class* #t104 = v in let final self::Number* #t105 = self::NumberExtension|-(self::ClassExtension|get#property(#t104), n2) in let final void #t106 = self::ClassExtension|set#property(#t104, #t105) in #t105);
+ self::expect(n1, let final self::Class* #t107 = v in let final self::Number* #t108 = self::NumberExtension|+(self::ClassExtension|get#property(#t107), n1) in let final void #t109 = self::ClassExtension|set#property(#t107, #t108) in #t108);
+ self::expect(n0, let final self::Class* #t110 = v in let final self::Number* #t111 = self::NumberExtension|-(self::ClassExtension|get#property(#t110), n1) in let final void #t112 = self::ClassExtension|set#property(#t110, #t111) in #t111);
+ self::expect(n1, let final self::Class* #t113 = v in let final self::Number* #t114 = self::NumberExtension|+(self::ClassExtension|get#property(#t113), 1) in let final void #t115 = self::ClassExtension|set#property(#t113, #t114) in #t114);
+ self::expect(n0, let final self::Class* #t116 = v in let final self::Number* #t117 = self::NumberExtension|-(self::ClassExtension|get#property(#t116), 1) in let final void #t118 = self::ClassExtension|set#property(#t116, #t117) in #t117);
+ self::expect(n0, let final self::Class* #t119 = v in let final self::Number* #t120 = self::ClassExtension|get#property(#t119) in let final self::Number* #t121 = let final self::Number* #t122 = self::NumberExtension|+(#t120, 1) in let final void #t123 = self::ClassExtension|set#property(#t119, #t122) in #t122 in #t120);
+ self::expect(n1, let final self::Class* #t124 = v in let final self::Number* #t125 = self::ClassExtension|get#property(#t124) in let final self::Number* #t126 = let final self::Number* #t127 = self::NumberExtension|-(#t125, 1) in let final void #t128 = self::ClassExtension|set#property(#t124, #t127) in #t127 in #t125);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t129 = v in self::ClassExtension|set#property(#t129, self::NumberExtension|+(self::ClassExtension|get#property(#t129), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t130 = v in self::ClassExtension|set#property(#t130, self::NumberExtension|+(self::ClassExtension|get#property(#t130), n1));
+ self::expect(n2, self::ClassExtension|get#property(v));
+ let final self::Class* #t131 = v in self::ClassExtension|set#property(#t131, self::NumberExtension|-(self::ClassExtension|get#property(#t131), n2));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t132 = v in self::ClassExtension|set#property(#t132, self::NumberExtension|+(self::ClassExtension|get#property(#t132), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t133 = v in self::ClassExtension|set#property(#t133, self::NumberExtension|-(self::ClassExtension|get#property(#t133), n1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t134 = v in let final self::Number* #t135 = self::NumberExtension|+(self::ClassExtension|get#property(#t134), 1) in let final void #t136 = self::ClassExtension|set#property(#t134, #t135) in #t135;
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t137 = v in let final self::Number* #t138 = self::NumberExtension|-(self::ClassExtension|get#property(#t137), 1) in let final void #t139 = self::ClassExtension|set#property(#t137, #t138) in #t138;
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t140 = v in self::ClassExtension|set#property(#t140, self::NumberExtension|+(self::ClassExtension|get#property(#t140), 1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t141 = v in self::ClassExtension|set#property(#t141, self::NumberExtension|-(self::ClassExtension|get#property(#t141), 1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+}
+static method testExplicitNullAwareProperties(self::Class* v) → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::expect(n0, let final self::Class* #t142 = v in #t142.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t142), v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t143 = v in #t143.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t144 = self::NumberExtension|+(self::ClassExtension|get#property(#t143), n1) in let final void #t145 = self::ClassExtension|set#property(#t143, #t144) in #t144, v.{core::Object::==}(null));
+ self::expect(n2, let final self::Class* #t146 = v in #t146.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t147 = self::NumberExtension|+(self::ClassExtension|get#property(#t146), n1) in let final void #t148 = self::ClassExtension|set#property(#t146, #t147) in #t147, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t149 = v in #t149.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t150 = self::NumberExtension|-(self::ClassExtension|get#property(#t149), n2) in let final void #t151 = self::ClassExtension|set#property(#t149, #t150) in #t150, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t152 = v in #t152.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t153 = self::NumberExtension|+(self::ClassExtension|get#property(#t152), n1) in let final void #t154 = self::ClassExtension|set#property(#t152, #t153) in #t153, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t155 = v in #t155.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t156 = self::NumberExtension|-(self::ClassExtension|get#property(#t155), n1) in let final void #t157 = self::ClassExtension|set#property(#t155, #t156) in #t156, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t158 = v in #t158.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t159 = self::NumberExtension|+(self::ClassExtension|get#property(#t158), 1) in let final void #t160 = self::ClassExtension|set#property(#t158, #t159) in #t159, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t161 = v in #t161.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t162 = self::NumberExtension|-(self::ClassExtension|get#property(#t161), 1) in let final void #t163 = self::ClassExtension|set#property(#t161, #t162) in #t162, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t164 = v in #t164.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t165 = self::ClassExtension|get#property(#t164) in let final self::Number* #t166 = let final self::Number* #t167 = self::NumberExtension|+(#t165, 1) in let final void #t168 = self::ClassExtension|set#property(#t164, #t167) in #t167 in #t165, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t169 = v in #t169.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t170 = self::ClassExtension|get#property(#t169) in let final self::Number* #t171 = let final self::Number* #t172 = self::NumberExtension|-(#t170, 1) in let final void #t173 = self::ClassExtension|set#property(#t169, #t172) in #t172 in #t170, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t174 = v in #t174.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t174), v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t175 = v in #t175.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t175), v.{core::Object::==}(null));
+ let final self::Class* #t176 = v in #t176.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t176, self::NumberExtension|+(self::ClassExtension|get#property(#t176), n1));
+ self::expect(n1, let final self::Class* #t177 = v in #t177.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t177), v.{core::Object::==}(null));
+ let final self::Class* #t178 = v in #t178.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t178, self::NumberExtension|+(self::ClassExtension|get#property(#t178), n1));
+ self::expect(n2, let final self::Class* #t179 = v in #t179.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t179), v.{core::Object::==}(null));
+ let final self::Class* #t180 = v in #t180.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t180, self::NumberExtension|-(self::ClassExtension|get#property(#t180), n2));
+ self::expect(n0, let final self::Class* #t181 = v in #t181.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t181), v.{core::Object::==}(null));
+ let final self::Class* #t182 = v in #t182.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t182, self::NumberExtension|+(self::ClassExtension|get#property(#t182), n1));
+ self::expect(n1, let final self::Class* #t183 = v in #t183.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t183), v.{core::Object::==}(null));
+ let final self::Class* #t184 = v in #t184.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t184, self::NumberExtension|-(self::ClassExtension|get#property(#t184), n1));
+ self::expect(n0, let final self::Class* #t185 = v in #t185.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t185), v.{core::Object::==}(null));
+ let final self::Class* #t186 = v in #t186.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t187 = self::NumberExtension|+(self::ClassExtension|get#property(#t186), 1) in let final void #t188 = self::ClassExtension|set#property(#t186, #t187) in #t187;
+ self::expect(n1, let final self::Class* #t189 = v in #t189.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t189), v.{core::Object::==}(null));
+ let final self::Class* #t190 = v in #t190.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t191 = self::NumberExtension|-(self::ClassExtension|get#property(#t190), 1) in let final void #t192 = self::ClassExtension|set#property(#t190, #t191) in #t191;
+ self::expect(n0, let final self::Class* #t193 = v in #t193.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t193), v.{core::Object::==}(null));
+ let final self::Class* #t194 = v in #t194.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t194, self::NumberExtension|+(self::ClassExtension|get#property(#t194), 1));
+ self::expect(n1, let final self::Class* #t195 = v in #t195.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t195), v.{core::Object::==}(null));
+ let final self::Class* #t196 = v in #t196.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t196, self::NumberExtension|-(self::ClassExtension|get#property(#t196), 1));
+ self::expect(n0, let final self::Class* #t197 = v in #t197.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t197), v.{core::Object::==}(null));
+}
+static method expect(dynamic expected, dynamic actual, [dynamic expectNull = #C1]) → dynamic {
+ if(expectNull as{TypeError} core::bool*) {
+ expected = null;
+ }
if(!expected.{core::Object::==}(actual)) {
throw "Mismatch: expected=${expected}, actual=${actual}";
}
}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
index 1360e1d..e0e9cdf 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.strong.transformed.expect
@@ -26,6 +26,8 @@
}
extension ClassExtension on self::Class* {
get property = self::ClassExtension|get#property;
+ method testImplicitProperties = self::ClassExtension|testImplicitProperties;
+ tearoff testImplicitProperties = self::ClassExtension|get#testImplicitProperties;
set property = self::ClassExtension|set#property;
}
static method NumberExtension|+(final self::Number* #this, core::Object* other) → self::Number* {
@@ -54,14 +56,53 @@
}
static method ClassExtension|get#property(final self::Class* #this) → self::Number*
return #this.{self::Class::field};
-static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → self::Number* {
- final self::Number* #t1 = value;
+static method ClassExtension|set#property(final self::Class* #this, self::Number* value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
+static method ClassExtension|testImplicitProperties(final self::Class* #this) → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::expect(n1, let final self::Number* #t1 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t2 = self::ClassExtension|set#property(#this, #t1) in #t1);
+ self::expect(n2, let final self::Number* #t3 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t4 = self::ClassExtension|set#property(#this, #t3) in #t3);
+ self::expect(n0, let final self::Number* #t5 = self::NumberExtension|-(self::ClassExtension|get#property(#this), n2) in let final void #t6 = self::ClassExtension|set#property(#this, #t5) in #t5);
+ self::expect(n1, let final self::Number* #t7 = self::NumberExtension|+(self::ClassExtension|get#property(#this), n1) in let final void #t8 = self::ClassExtension|set#property(#this, #t7) in #t7);
+ self::expect(n0, let final self::Number* #t9 = self::NumberExtension|-(self::ClassExtension|get#property(#this), n1) in let final void #t10 = self::ClassExtension|set#property(#this, #t9) in #t9);
+ self::expect(n1, let final self::Number* #t11 = self::NumberExtension|+(self::ClassExtension|get#property(#this), 1) in let final void #t12 = self::ClassExtension|set#property(#this, #t11) in #t11);
+ self::expect(n0, let final self::Number* #t13 = self::NumberExtension|-(self::ClassExtension|get#property(#this), 1) in let final void #t14 = self::ClassExtension|set#property(#this, #t13) in #t13);
+ self::expect(n0, let final self::Number* #t15 = self::ClassExtension|get#property(#this) in let final self::Number* #t16 = self::ClassExtension|set#property(#this, self::NumberExtension|+(#t15, 1)) in #t15);
+ self::expect(n1, let final self::Number* #t17 = self::ClassExtension|get#property(#this) in let final self::Number* #t18 = self::ClassExtension|set#property(#this, self::NumberExtension|-(#t17, 1)) in #t17);
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n2, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), n2));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), n1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), n1));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ let final self::Number* #t19 = self::NumberExtension|+(self::ClassExtension|get#property(#this), 1) in let final void #t20 = self::ClassExtension|set#property(#this, #t19) in #t19;
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ let final self::Number* #t21 = self::NumberExtension|-(self::ClassExtension|get#property(#this), 1) in let final void #t22 = self::ClassExtension|set#property(#this, #t21) in #t21;
+ self::expect(n0, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|+(self::ClassExtension|get#property(#this), 1));
+ self::expect(n1, self::ClassExtension|get#property(#this));
+ self::ClassExtension|set#property(#this, self::NumberExtension|-(self::ClassExtension|get#property(#this), 1));
+ self::expect(n0, self::ClassExtension|get#property(#this));
+}
+static method ClassExtension|get#testImplicitProperties(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::ClassExtension|testImplicitProperties(#this);
static method main() → dynamic {
self::testLocals();
self::testProperties();
+ self::testExplicitProperties();
+ self::testExplicitNullAwareProperties(null);
+ self::testExplicitNullAwareProperties(new self::Class::•(new self::Number::•(0)));
+ self::ClassExtension|testImplicitProperties(new self::Class::•(new self::Number::•(0)));
}
static method testLocals() → dynamic {
self::Number* n0 = new self::Number::•(0);
@@ -76,8 +117,27 @@
self::expect(n0, v = self::NumberExtension|-(v, n1));
self::expect(n1, v = self::NumberExtension|+(v, 1));
self::expect(n0, v = self::NumberExtension|-(v, 1));
- self::expect(n0, let final self::Number* #t2 = v in let final self::Number* #t3 = v = self::NumberExtension|+(#t2, 1) in #t2);
- self::expect(n1, let final self::Number* #t4 = v in let final self::Number* #t5 = v = self::NumberExtension|-(#t4, 1) in #t4);
+ self::expect(n0, let final self::Number* #t23 = v in let final self::Number* #t24 = v = self::NumberExtension|+(#t23, 1) in #t23);
+ self::expect(n1, let final self::Number* #t25 = v in let final self::Number* #t26 = v = self::NumberExtension|-(#t25, 1) in #t25);
+ self::expect(n0, v);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n1, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n2, v);
+ v = self::NumberExtension|-(v, n2);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, n1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, n1);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, 1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, 1);
+ self::expect(n0, v);
+ v = self::NumberExtension|+(v, 1);
+ self::expect(n1, v);
+ v = self::NumberExtension|-(v, 1);
self::expect(n0, v);
}
static method testProperties() → dynamic {
@@ -86,30 +146,146 @@
self::Number* n2 = new self::Number::•(2);
self::Class* v = new self::Class::•(n0);
self::expect(n0, v.{self::Class::field});
- self::expect(n1, let final self::Class* #t6 = v in #t6.{self::Class::field} = self::NumberExtension|+(#t6.{self::Class::field}, n1));
- self::expect(n2, let final self::Class* #t7 = v in #t7.{self::Class::field} = self::NumberExtension|+(#t7.{self::Class::field}, n1));
- self::expect(n0, let final self::Class* #t8 = v in #t8.{self::Class::field} = self::NumberExtension|-(#t8.{self::Class::field}, n2));
- self::expect(n1, let final self::Class* #t9 = v in #t9.{self::Class::field} = self::NumberExtension|+(#t9.{self::Class::field}, n1));
- self::expect(n0, let final self::Class* #t10 = v in #t10.{self::Class::field} = self::NumberExtension|-(#t10.{self::Class::field}, n1));
- self::expect(n1, let final self::Class* #t11 = v in #t11.{self::Class::field} = self::NumberExtension|+(#t11.{self::Class::field}, 1));
- self::expect(n0, let final self::Class* #t12 = v in #t12.{self::Class::field} = self::NumberExtension|-(#t12.{self::Class::field}, 1));
- self::expect(n0, let final self::Class* #t13 = v in let final self::Number* #t14 = #t13.{self::Class::field} in let final self::Number* #t15 = #t13.{self::Class::field} = self::NumberExtension|+(#t14, 1) in #t14);
- self::expect(n1, let final self::Class* #t16 = v in let final self::Number* #t17 = #t16.{self::Class::field} in let final self::Number* #t18 = #t16.{self::Class::field} = self::NumberExtension|-(#t17, 1) in #t17);
+ self::expect(n1, let final self::Class* #t27 = v in #t27.{self::Class::field} = self::NumberExtension|+(#t27.{self::Class::field}, n1));
+ self::expect(n2, let final self::Class* #t28 = v in #t28.{self::Class::field} = self::NumberExtension|+(#t28.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t29 = v in #t29.{self::Class::field} = self::NumberExtension|-(#t29.{self::Class::field}, n2));
+ self::expect(n1, let final self::Class* #t30 = v in #t30.{self::Class::field} = self::NumberExtension|+(#t30.{self::Class::field}, n1));
+ self::expect(n0, let final self::Class* #t31 = v in #t31.{self::Class::field} = self::NumberExtension|-(#t31.{self::Class::field}, n1));
+ self::expect(n1, let final self::Class* #t32 = v in #t32.{self::Class::field} = self::NumberExtension|+(#t32.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t33 = v in #t33.{self::Class::field} = self::NumberExtension|-(#t33.{self::Class::field}, 1));
+ self::expect(n0, let final self::Class* #t34 = v in let final self::Number* #t35 = #t34.{self::Class::field} in let final self::Number* #t36 = #t34.{self::Class::field} = self::NumberExtension|+(#t35, 1) in #t35);
+ self::expect(n1, let final self::Class* #t37 = v in let final self::Number* #t38 = #t37.{self::Class::field} in let final self::Number* #t39 = #t37.{self::Class::field} = self::NumberExtension|-(#t38, 1) in #t38);
+ self::expect(n0, v.{self::Class::field});
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t40 = v in #t40.{self::Class::field} = self::NumberExtension|+(#t40.{self::Class::field}, n1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t41 = v in #t41.{self::Class::field} = self::NumberExtension|+(#t41.{self::Class::field}, n1);
+ self::expect(n2, v.{self::Class::field});
+ let final self::Class* #t42 = v in #t42.{self::Class::field} = self::NumberExtension|-(#t42.{self::Class::field}, n2);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t43 = v in #t43.{self::Class::field} = self::NumberExtension|+(#t43.{self::Class::field}, n1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t44 = v in #t44.{self::Class::field} = self::NumberExtension|-(#t44.{self::Class::field}, n1);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t45 = v in #t45.{self::Class::field} = self::NumberExtension|+(#t45.{self::Class::field}, 1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t46 = v in #t46.{self::Class::field} = self::NumberExtension|-(#t46.{self::Class::field}, 1);
+ self::expect(n0, v.{self::Class::field});
+ let final self::Class* #t47 = v in #t47.{self::Class::field} = self::NumberExtension|+(#t47.{self::Class::field}, 1);
+ self::expect(n1, v.{self::Class::field});
+ let final self::Class* #t48 = v in #t48.{self::Class::field} = self::NumberExtension|-(#t48.{self::Class::field}, 1);
self::expect(n0, v.{self::Class::field});
self::expect(n0, self::ClassExtension|get#property(v));
- self::expect(n1, let final self::Class* #t19 = v in self::ClassExtension|set#property(#t19, self::NumberExtension|+(self::ClassExtension|get#property(#t19), n1)));
- self::expect(n2, let final self::Class* #t20 = v in self::ClassExtension|set#property(#t20, self::NumberExtension|+(self::ClassExtension|get#property(#t20), n1)));
- self::expect(n0, let final self::Class* #t21 = v in self::ClassExtension|set#property(#t21, self::NumberExtension|-(self::ClassExtension|get#property(#t21), n2)));
- self::expect(n1, let final self::Class* #t22 = v in self::ClassExtension|set#property(#t22, self::NumberExtension|+(self::ClassExtension|get#property(#t22), n1)));
- self::expect(n0, let final self::Class* #t23 = v in self::ClassExtension|set#property(#t23, self::NumberExtension|-(self::ClassExtension|get#property(#t23), n1)));
- self::expect(n1, let final self::Class* #t24 = v in self::ClassExtension|set#property(#t24, self::NumberExtension|+(self::ClassExtension|get#property(#t24), 1)));
- self::expect(n0, let final self::Class* #t25 = v in self::ClassExtension|set#property(#t25, self::NumberExtension|-(self::ClassExtension|get#property(#t25), 1)));
- self::expect(n0, let final self::Class* #t26 = v in let final self::Number* #t27 = self::ClassExtension|get#property(#t26) in let final self::Number* #t28 = self::ClassExtension|set#property(#t26, self::NumberExtension|+(#t27, 1)) in #t27);
- self::expect(n1, let final self::Class* #t29 = v in let final self::Number* #t30 = self::ClassExtension|get#property(#t29) in let final self::Number* #t31 = self::ClassExtension|set#property(#t29, self::NumberExtension|-(#t30, 1)) in #t30);
+ self::expect(n1, let final self::Class* #t49 = v in let final self::Class* #t50 = #t49 in let final self::Number* #t51 = self::NumberExtension|+(self::ClassExtension|get#property(#t49), n1) in let final void #t52 = self::ClassExtension|set#property(#t50, #t51) in #t51);
+ self::expect(n2, let final self::Class* #t53 = v in let final self::Class* #t54 = #t53 in let final self::Number* #t55 = self::NumberExtension|+(self::ClassExtension|get#property(#t53), n1) in let final void #t56 = self::ClassExtension|set#property(#t54, #t55) in #t55);
+ self::expect(n0, let final self::Class* #t57 = v in let final self::Class* #t58 = #t57 in let final self::Number* #t59 = self::NumberExtension|-(self::ClassExtension|get#property(#t57), n2) in let final void #t60 = self::ClassExtension|set#property(#t58, #t59) in #t59);
+ self::expect(n1, let final self::Class* #t61 = v in let final self::Class* #t62 = #t61 in let final self::Number* #t63 = self::NumberExtension|+(self::ClassExtension|get#property(#t61), n1) in let final void #t64 = self::ClassExtension|set#property(#t62, #t63) in #t63);
+ self::expect(n0, let final self::Class* #t65 = v in let final self::Class* #t66 = #t65 in let final self::Number* #t67 = self::NumberExtension|-(self::ClassExtension|get#property(#t65), n1) in let final void #t68 = self::ClassExtension|set#property(#t66, #t67) in #t67);
+ self::expect(n1, let final self::Class* #t69 = v in let final self::Class* #t70 = #t69 in let final self::Number* #t71 = self::NumberExtension|+(self::ClassExtension|get#property(#t69), 1) in let final void #t72 = self::ClassExtension|set#property(#t70, #t71) in #t71);
+ self::expect(n0, let final self::Class* #t73 = v in let final self::Class* #t74 = #t73 in let final self::Number* #t75 = self::NumberExtension|-(self::ClassExtension|get#property(#t73), 1) in let final void #t76 = self::ClassExtension|set#property(#t74, #t75) in #t75);
+ self::expect(n0, let final self::Class* #t77 = v in let final self::Number* #t78 = self::ClassExtension|get#property(#t77) in let final self::Number* #t79 = self::ClassExtension|set#property(#t77, self::NumberExtension|+(#t78, 1)) in #t78);
+ self::expect(n1, let final self::Class* #t80 = v in let final self::Number* #t81 = self::ClassExtension|get#property(#t80) in let final self::Number* #t82 = self::ClassExtension|set#property(#t80, self::NumberExtension|-(#t81, 1)) in #t81);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t83 = v in self::ClassExtension|set#property(#t83, self::NumberExtension|+(self::ClassExtension|get#property(#t83), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t84 = v in self::ClassExtension|set#property(#t84, self::NumberExtension|+(self::ClassExtension|get#property(#t84), n1));
+ self::expect(n2, self::ClassExtension|get#property(v));
+ let final self::Class* #t85 = v in self::ClassExtension|set#property(#t85, self::NumberExtension|-(self::ClassExtension|get#property(#t85), n2));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t86 = v in self::ClassExtension|set#property(#t86, self::NumberExtension|+(self::ClassExtension|get#property(#t86), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t87 = v in self::ClassExtension|set#property(#t87, self::NumberExtension|-(self::ClassExtension|get#property(#t87), n1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t88 = v in let final self::Class* #t89 = #t88 in let final self::Number* #t90 = self::NumberExtension|+(self::ClassExtension|get#property(#t88), 1) in let final void #t91 = self::ClassExtension|set#property(#t89, #t90) in #t90;
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t92 = v in let final self::Class* #t93 = #t92 in let final self::Number* #t94 = self::NumberExtension|-(self::ClassExtension|get#property(#t92), 1) in let final void #t95 = self::ClassExtension|set#property(#t93, #t94) in #t94;
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t96 = v in self::ClassExtension|set#property(#t96, self::NumberExtension|+(self::ClassExtension|get#property(#t96), 1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t97 = v in self::ClassExtension|set#property(#t97, self::NumberExtension|-(self::ClassExtension|get#property(#t97), 1));
self::expect(n0, self::ClassExtension|get#property(v));
}
-static method expect(dynamic expected, dynamic actual) → dynamic {
+static method testExplicitProperties() → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::Class* v = new self::Class::•(n0);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n1, let final self::Class* #t98 = v in let final self::Number* #t99 = self::NumberExtension|+(self::ClassExtension|get#property(#t98), n1) in let final void #t100 = self::ClassExtension|set#property(#t98, #t99) in #t99);
+ self::expect(n2, let final self::Class* #t101 = v in let final self::Number* #t102 = self::NumberExtension|+(self::ClassExtension|get#property(#t101), n1) in let final void #t103 = self::ClassExtension|set#property(#t101, #t102) in #t102);
+ self::expect(n0, let final self::Class* #t104 = v in let final self::Number* #t105 = self::NumberExtension|-(self::ClassExtension|get#property(#t104), n2) in let final void #t106 = self::ClassExtension|set#property(#t104, #t105) in #t105);
+ self::expect(n1, let final self::Class* #t107 = v in let final self::Number* #t108 = self::NumberExtension|+(self::ClassExtension|get#property(#t107), n1) in let final void #t109 = self::ClassExtension|set#property(#t107, #t108) in #t108);
+ self::expect(n0, let final self::Class* #t110 = v in let final self::Number* #t111 = self::NumberExtension|-(self::ClassExtension|get#property(#t110), n1) in let final void #t112 = self::ClassExtension|set#property(#t110, #t111) in #t111);
+ self::expect(n1, let final self::Class* #t113 = v in let final self::Number* #t114 = self::NumberExtension|+(self::ClassExtension|get#property(#t113), 1) in let final void #t115 = self::ClassExtension|set#property(#t113, #t114) in #t114);
+ self::expect(n0, let final self::Class* #t116 = v in let final self::Number* #t117 = self::NumberExtension|-(self::ClassExtension|get#property(#t116), 1) in let final void #t118 = self::ClassExtension|set#property(#t116, #t117) in #t117);
+ self::expect(n0, let final self::Class* #t119 = v in let final self::Number* #t120 = self::ClassExtension|get#property(#t119) in let final self::Number* #t121 = let final self::Number* #t122 = self::NumberExtension|+(#t120, 1) in let final void #t123 = self::ClassExtension|set#property(#t119, #t122) in #t122 in #t120);
+ self::expect(n1, let final self::Class* #t124 = v in let final self::Number* #t125 = self::ClassExtension|get#property(#t124) in let final self::Number* #t126 = let final self::Number* #t127 = self::NumberExtension|-(#t125, 1) in let final void #t128 = self::ClassExtension|set#property(#t124, #t127) in #t127 in #t125);
+ self::expect(n0, self::ClassExtension|get#property(v));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t129 = v in self::ClassExtension|set#property(#t129, self::NumberExtension|+(self::ClassExtension|get#property(#t129), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t130 = v in self::ClassExtension|set#property(#t130, self::NumberExtension|+(self::ClassExtension|get#property(#t130), n1));
+ self::expect(n2, self::ClassExtension|get#property(v));
+ let final self::Class* #t131 = v in self::ClassExtension|set#property(#t131, self::NumberExtension|-(self::ClassExtension|get#property(#t131), n2));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t132 = v in self::ClassExtension|set#property(#t132, self::NumberExtension|+(self::ClassExtension|get#property(#t132), n1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t133 = v in self::ClassExtension|set#property(#t133, self::NumberExtension|-(self::ClassExtension|get#property(#t133), n1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t134 = v in let final self::Number* #t135 = self::NumberExtension|+(self::ClassExtension|get#property(#t134), 1) in let final void #t136 = self::ClassExtension|set#property(#t134, #t135) in #t135;
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t137 = v in let final self::Number* #t138 = self::NumberExtension|-(self::ClassExtension|get#property(#t137), 1) in let final void #t139 = self::ClassExtension|set#property(#t137, #t138) in #t138;
+ self::expect(n0, self::ClassExtension|get#property(v));
+ let final self::Class* #t140 = v in self::ClassExtension|set#property(#t140, self::NumberExtension|+(self::ClassExtension|get#property(#t140), 1));
+ self::expect(n1, self::ClassExtension|get#property(v));
+ let final self::Class* #t141 = v in self::ClassExtension|set#property(#t141, self::NumberExtension|-(self::ClassExtension|get#property(#t141), 1));
+ self::expect(n0, self::ClassExtension|get#property(v));
+}
+static method testExplicitNullAwareProperties(self::Class* v) → dynamic {
+ self::Number* n0 = new self::Number::•(0);
+ self::Number* n1 = new self::Number::•(1);
+ self::Number* n2 = new self::Number::•(2);
+ self::expect(n0, let final self::Class* #t142 = v in #t142.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t142), v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t143 = v in #t143.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t144 = self::NumberExtension|+(self::ClassExtension|get#property(#t143), n1) in let final void #t145 = self::ClassExtension|set#property(#t143, #t144) in #t144, v.{core::Object::==}(null));
+ self::expect(n2, let final self::Class* #t146 = v in #t146.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t147 = self::NumberExtension|+(self::ClassExtension|get#property(#t146), n1) in let final void #t148 = self::ClassExtension|set#property(#t146, #t147) in #t147, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t149 = v in #t149.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t150 = self::NumberExtension|-(self::ClassExtension|get#property(#t149), n2) in let final void #t151 = self::ClassExtension|set#property(#t149, #t150) in #t150, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t152 = v in #t152.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t153 = self::NumberExtension|+(self::ClassExtension|get#property(#t152), n1) in let final void #t154 = self::ClassExtension|set#property(#t152, #t153) in #t153, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t155 = v in #t155.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t156 = self::NumberExtension|-(self::ClassExtension|get#property(#t155), n1) in let final void #t157 = self::ClassExtension|set#property(#t155, #t156) in #t156, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t158 = v in #t158.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t159 = self::NumberExtension|+(self::ClassExtension|get#property(#t158), 1) in let final void #t160 = self::ClassExtension|set#property(#t158, #t159) in #t159, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t161 = v in #t161.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t162 = self::NumberExtension|-(self::ClassExtension|get#property(#t161), 1) in let final void #t163 = self::ClassExtension|set#property(#t161, #t162) in #t162, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t164 = v in #t164.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t165 = self::ClassExtension|get#property(#t164) in let final self::Number* #t166 = let final self::Number* #t167 = self::NumberExtension|+(#t165, 1) in let final void #t168 = self::ClassExtension|set#property(#t164, #t167) in #t167 in #t165, v.{core::Object::==}(null));
+ self::expect(n1, let final self::Class* #t169 = v in #t169.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t170 = self::ClassExtension|get#property(#t169) in let final self::Number* #t171 = let final self::Number* #t172 = self::NumberExtension|-(#t170, 1) in let final void #t173 = self::ClassExtension|set#property(#t169, #t172) in #t172 in #t170, v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t174 = v in #t174.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t174), v.{core::Object::==}(null));
+ self::expect(n0, let final self::Class* #t175 = v in #t175.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t175), v.{core::Object::==}(null));
+ let final self::Class* #t176 = v in #t176.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t176, self::NumberExtension|+(self::ClassExtension|get#property(#t176), n1));
+ self::expect(n1, let final self::Class* #t177 = v in #t177.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t177), v.{core::Object::==}(null));
+ let final self::Class* #t178 = v in #t178.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t178, self::NumberExtension|+(self::ClassExtension|get#property(#t178), n1));
+ self::expect(n2, let final self::Class* #t179 = v in #t179.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t179), v.{core::Object::==}(null));
+ let final self::Class* #t180 = v in #t180.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t180, self::NumberExtension|-(self::ClassExtension|get#property(#t180), n2));
+ self::expect(n0, let final self::Class* #t181 = v in #t181.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t181), v.{core::Object::==}(null));
+ let final self::Class* #t182 = v in #t182.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t182, self::NumberExtension|+(self::ClassExtension|get#property(#t182), n1));
+ self::expect(n1, let final self::Class* #t183 = v in #t183.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t183), v.{core::Object::==}(null));
+ let final self::Class* #t184 = v in #t184.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t184, self::NumberExtension|-(self::ClassExtension|get#property(#t184), n1));
+ self::expect(n0, let final self::Class* #t185 = v in #t185.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t185), v.{core::Object::==}(null));
+ let final self::Class* #t186 = v in #t186.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t187 = self::NumberExtension|+(self::ClassExtension|get#property(#t186), 1) in let final void #t188 = self::ClassExtension|set#property(#t186, #t187) in #t187;
+ self::expect(n1, let final self::Class* #t189 = v in #t189.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t189), v.{core::Object::==}(null));
+ let final self::Class* #t190 = v in #t190.{core::Object::==}(null) ?{self::Number*} null : let final self::Number* #t191 = self::NumberExtension|-(self::ClassExtension|get#property(#t190), 1) in let final void #t192 = self::ClassExtension|set#property(#t190, #t191) in #t191;
+ self::expect(n0, let final self::Class* #t193 = v in #t193.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t193), v.{core::Object::==}(null));
+ let final self::Class* #t194 = v in #t194.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t194, self::NumberExtension|+(self::ClassExtension|get#property(#t194), 1));
+ self::expect(n1, let final self::Class* #t195 = v in #t195.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t195), v.{core::Object::==}(null));
+ let final self::Class* #t196 = v in #t196.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|set#property(#t196, self::NumberExtension|-(self::ClassExtension|get#property(#t196), 1));
+ self::expect(n0, let final self::Class* #t197 = v in #t197.{core::Object::==}(null) ?{self::Number*} null : self::ClassExtension|get#property(#t197), v.{core::Object::==}(null));
+}
+static method expect(dynamic expected, dynamic actual, [dynamic expectNull = #C1]) → dynamic {
+ if(expectNull as{TypeError} core::bool*) {
+ expected = null;
+ }
if(!expected.{core::Object::==}(actual)) {
throw "Mismatch: expected=${expected}, actual=${actual}";
}
}
+
+constants {
+ #C1 = false
+}
diff --git a/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect
index 28a5f00..ffaf9b8 100644
--- a/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/extensions/compounds.dart.type_promotion.expect
@@ -13,30 +13,60 @@
pkg/front_end/testcases/extensions/compounds.dart:30:22: Context: Possible promotion of other@501
} else if (other is Number) {
^^
-pkg/front_end/testcases/extensions/compounds.dart:62:16: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:104:16: Context: Write to v@2369
expect(n1, v += n1);
^^
-pkg/front_end/testcases/extensions/compounds.dart:63:16: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:105:16: Context: Write to v@2369
expect(n2, v += n1);
^^
-pkg/front_end/testcases/extensions/compounds.dart:64:16: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:106:16: Context: Write to v@2369
expect(n0, v -= n2);
^^
-pkg/front_end/testcases/extensions/compounds.dart:65:16: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:107:16: Context: Write to v@2369
expect(n1, v += n1);
^^
-pkg/front_end/testcases/extensions/compounds.dart:66:16: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:108:16: Context: Write to v@2369
expect(n0, v -= n1);
^^
-pkg/front_end/testcases/extensions/compounds.dart:67:14: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:109:14: Context: Write to v@2369
expect(n1, ++v);
^^
-pkg/front_end/testcases/extensions/compounds.dart:68:14: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:110:14: Context: Write to v@2369
expect(n0, --v);
^^
-pkg/front_end/testcases/extensions/compounds.dart:69:15: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:111:15: Context: Write to v@2369
expect(n0, v++);
^^
-pkg/front_end/testcases/extensions/compounds.dart:70:15: Context: Write to v@1309
+pkg/front_end/testcases/extensions/compounds.dart:112:15: Context: Write to v@2369
expect(n1, v--);
^^
+pkg/front_end/testcases/extensions/compounds.dart:116:5: Context: Write to v@2369
+ v += n1;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:118:5: Context: Write to v@2369
+ v += n1;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:120:5: Context: Write to v@2369
+ v -= n2;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:122:5: Context: Write to v@2369
+ v += n1;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:124:5: Context: Write to v@2369
+ v -= n1;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:126:3: Context: Write to v@2369
+ ++v;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:128:3: Context: Write to v@2369
+ --v;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:130:4: Context: Write to v@2369
+ v++;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:132:4: Context: Write to v@2369
+ v--;
+ ^^
+pkg/front_end/testcases/extensions/compounds.dart:285:14: Context: Write to expected@7409
+ expected = null;
+ ^
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart b/pkg/front_end/testcases/extensions/conflicts.dart
new file mode 100644
index 0000000..b05aa28
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2019, 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.
+
+class Class1 {
+}
+class Class2 {}
+
+extension DuplicateExtensionName on Class1 {
+ uniqueMethod1() {}
+ duplicateMethodName2() => 1;
+}
+
+extension DuplicateExtensionName on Class2 {
+ uniqueMethod2() {}
+ duplicateMethodName2() => 2;
+}
+
+extension UniqueExtensionName on Class1 {
+ duplicateMethodName1() => 1;
+ duplicateMethodName1() => 2;
+}
+
+main() {
+ var c1 = new Class1();
+ c1.uniqueMethod1();
+}
+
+errors() {
+ var c2 = new Class2();
+ c2.uniqueMethod2();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect b/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect
new file mode 100644
index 0000000..268695d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.outline.expect
@@ -0,0 +1,55 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:14:11: Error: 'DuplicateExtensionName' is already declared in this scope.
+// extension DuplicateExtensionName on Class2 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:9:11: Context: Previous declaration of 'DuplicateExtensionName'.
+// extension DuplicateExtensionName on Class1 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:21:3: Error: 'duplicateMethodName1' is already declared in this scope.
+// duplicateMethodName1() => 2;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:20:3: Context: Previous declaration of 'duplicateMethodName1'.
+// duplicateMethodName1() => 1;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ synthetic constructor •() → self::Class1*
+ ;
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ ;
+}
+extension DuplicateExtensionName on self::Class1* {
+ method uniqueMethod1 = self::DuplicateExtensionName|uniqueMethod1;
+ tearoff uniqueMethod1 = self::DuplicateExtensionName|get#uniqueMethod1;
+ method duplicateMethodName2 = self::DuplicateExtensionName|duplicateMethodName2;
+ tearoff duplicateMethodName2 = self::DuplicateExtensionName|get#duplicateMethodName2;
+}
+extension UniqueExtensionName on self::Class1* {
+ method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
+ tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
+}
+static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic
+ ;
+static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
+static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+ ;
+static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
+static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+ ;
+static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
+static method main() → dynamic
+ ;
+static method errors() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect b/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect
new file mode 100644
index 0000000..5481d64
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.strong.expect
@@ -0,0 +1,70 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:14:11: Error: 'DuplicateExtensionName' is already declared in this scope.
+// extension DuplicateExtensionName on Class2 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:9:11: Context: Previous declaration of 'DuplicateExtensionName'.
+// extension DuplicateExtensionName on Class1 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:21:3: Error: 'duplicateMethodName1' is already declared in this scope.
+// duplicateMethodName1() => 2;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:20:3: Context: Previous declaration of 'duplicateMethodName1'.
+// duplicateMethodName1() => 1;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:31:6: Error: The method 'uniqueMethod2' isn't defined for the class 'Class2'.
+// - 'Class2' is from 'pkg/front_end/testcases/extensions/conflicts.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'uniqueMethod2'.
+// c2.uniqueMethod2();
+// ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ synthetic constructor •() → self::Class1*
+ : super core::Object::•()
+ ;
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ : super core::Object::•()
+ ;
+}
+extension DuplicateExtensionName on self::Class1* {
+ method uniqueMethod1 = self::DuplicateExtensionName|uniqueMethod1;
+ tearoff uniqueMethod1 = self::DuplicateExtensionName|get#uniqueMethod1;
+ method duplicateMethodName2 = self::DuplicateExtensionName|duplicateMethodName2;
+ tearoff duplicateMethodName2 = self::DuplicateExtensionName|get#duplicateMethodName2;
+}
+extension UniqueExtensionName on self::Class1* {
+ method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
+ tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
+}
+static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic {}
+static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
+static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+ return 1;
+static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
+static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+ return 1;
+static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
+static method main() → dynamic {
+ self::Class1* c1 = new self::Class1::•();
+ self::DuplicateExtensionName|uniqueMethod1(c1);
+}
+static method errors() → dynamic {
+ self::Class2* c2 = new self::Class2::•();
+ invalid-expression "pkg/front_end/testcases/extensions/conflicts.dart:31:6: Error: The method 'uniqueMethod2' isn't defined for the class 'Class2'.
+ - 'Class2' is from 'pkg/front_end/testcases/extensions/conflicts.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'uniqueMethod2'.
+ c2.uniqueMethod2();
+ ^^^^^^^^^^^^^";
+}
diff --git a/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect
new file mode 100644
index 0000000..5481d64
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/conflicts.dart.strong.transformed.expect
@@ -0,0 +1,70 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:14:11: Error: 'DuplicateExtensionName' is already declared in this scope.
+// extension DuplicateExtensionName on Class2 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:9:11: Context: Previous declaration of 'DuplicateExtensionName'.
+// extension DuplicateExtensionName on Class1 {
+// ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:21:3: Error: 'duplicateMethodName1' is already declared in this scope.
+// duplicateMethodName1() => 2;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/conflicts.dart:20:3: Context: Previous declaration of 'duplicateMethodName1'.
+// duplicateMethodName1() => 1;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/conflicts.dart:31:6: Error: The method 'uniqueMethod2' isn't defined for the class 'Class2'.
+// - 'Class2' is from 'pkg/front_end/testcases/extensions/conflicts.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'uniqueMethod2'.
+// c2.uniqueMethod2();
+// ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class1 extends core::Object {
+ synthetic constructor •() → self::Class1*
+ : super core::Object::•()
+ ;
+}
+class Class2 extends core::Object {
+ synthetic constructor •() → self::Class2*
+ : super core::Object::•()
+ ;
+}
+extension DuplicateExtensionName on self::Class1* {
+ method uniqueMethod1 = self::DuplicateExtensionName|uniqueMethod1;
+ tearoff uniqueMethod1 = self::DuplicateExtensionName|get#uniqueMethod1;
+ method duplicateMethodName2 = self::DuplicateExtensionName|duplicateMethodName2;
+ tearoff duplicateMethodName2 = self::DuplicateExtensionName|get#duplicateMethodName2;
+}
+extension UniqueExtensionName on self::Class1* {
+ method duplicateMethodName1 = self::UniqueExtensionName|duplicateMethodName1;
+ tearoff duplicateMethodName1 = self::UniqueExtensionName|get#duplicateMethodName1;
+}
+static method DuplicateExtensionName|uniqueMethod1(final self::Class1* #this) → dynamic {}
+static method DuplicateExtensionName|get#uniqueMethod1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|uniqueMethod1(#this);
+static method DuplicateExtensionName|duplicateMethodName2(final self::Class1* #this) → dynamic
+ return 1;
+static method DuplicateExtensionName|get#duplicateMethodName2(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::DuplicateExtensionName|duplicateMethodName2(#this);
+static method UniqueExtensionName|duplicateMethodName1(final self::Class1* #this) → dynamic
+ return 1;
+static method UniqueExtensionName|get#duplicateMethodName1(final self::Class1* #this) → () →* dynamic
+ return () → dynamic => self::UniqueExtensionName|duplicateMethodName1(#this);
+static method main() → dynamic {
+ self::Class1* c1 = new self::Class1::•();
+ self::DuplicateExtensionName|uniqueMethod1(c1);
+}
+static method errors() → dynamic {
+ self::Class2* c2 = new self::Class2::•();
+ invalid-expression "pkg/front_end/testcases/extensions/conflicts.dart:31:6: Error: The method 'uniqueMethod2' isn't defined for the class 'Class2'.
+ - 'Class2' is from 'pkg/front_end/testcases/extensions/conflicts.dart'.
+Try correcting the name to the name of an existing method, or defining a method named 'uniqueMethod2'.
+ c2.uniqueMethod2();
+ ^^^^^^^^^^^^^";
+}
diff --git a/pkg/front_end/testcases/extensions/default_values.dart b/pkg/front_end/testcases/extensions/default_values.dart
new file mode 100644
index 0000000..0b08f6d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2019, 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.
+
+class Class {}
+
+extension Extension on Class {
+ method0([a]) => a;
+ method1([a = 42]) => a;
+ method2({b = 87}) => b;
+ method3({c = staticMethod}) => c();
+ static staticMethod() => 123;
+}
+
+main() {
+ Class c = new Class();
+ var tearOff0 = c.method0;
+ expect(0, tearOff0(0));
+ expect(null, tearOff0());
+ var tearOff1 = c.method1;
+ expect(0, tearOff1(0));
+ expect(42, tearOff1());
+ var tearOff2 = c.method2;
+ expect(0, tearOff2(b: 0));
+ expect(87, tearOff2());
+ var tearOff3 = c.method3;
+ expect(0, tearOff3(c: () => 0));
+ expect(123, tearOff3());
+}
+
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.outline.expect b/pkg/front_end/testcases/extensions/default_values.dart.outline.expect
new file mode 100644
index 0000000..77ed4f4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.outline.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension Extension on self::Class* {
+ method method0 = self::Extension|method0;
+ tearoff method0 = self::Extension|get#method0;
+ method method1 = self::Extension|method1;
+ tearoff method1 = self::Extension|get#method1;
+ method method2 = self::Extension|method2;
+ tearoff method2 = self::Extension|get#method2;
+ method method3 = self::Extension|method3;
+ tearoff method3 = self::Extension|get#method3;
+ static method staticMethod = self::Extension|staticMethod;
+}
+static method Extension|method0(final self::Class* #this, [dynamic a]) → dynamic
+ ;
+static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a]) → dynamic => self::Extension|method0(#this, a);
+static method Extension|method1(final self::Class* #this, [dynamic a]) → dynamic
+ ;
+static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a]) → dynamic => self::Extension|method1(#this, a);
+static method Extension|method2(final self::Class* #this, {dynamic b}) → dynamic
+ ;
+static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+ return ({dynamic b}) → dynamic => self::Extension|method2(#this, b: b);
+static method Extension|method3(final self::Class* #this, {dynamic c}) → dynamic
+ ;
+static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+ return ({dynamic c}) → dynamic => self::Extension|method3(#this, c: c);
+static method Extension|staticMethod() → dynamic
+ ;
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.strong.expect b/pkg/front_end/testcases/extensions/default_values.dart.strong.expect
new file mode 100644
index 0000000..e6b8869
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.strong.expect
@@ -0,0 +1,65 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ method method0 = self::Extension|method0;
+ tearoff method0 = self::Extension|get#method0;
+ method method1 = self::Extension|method1;
+ tearoff method1 = self::Extension|get#method1;
+ method method2 = self::Extension|method2;
+ tearoff method2 = self::Extension|get#method2;
+ method method3 = self::Extension|method3;
+ tearoff method3 = self::Extension|get#method3;
+ static method staticMethod = self::Extension|staticMethod;
+}
+static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
+ return a;
+static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
+static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
+ return a;
+static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
+static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
+ return b;
+static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+ return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
+static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
+ return c.call();
+static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+ return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
+static method Extension|staticMethod() → dynamic
+ return 123;
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ ([dynamic]) →* dynamic tearOff0 = self::Extension|get#method0(c);
+ self::expect(0, tearOff0.call(0));
+ self::expect(null, tearOff0.call());
+ ([dynamic]) →* dynamic tearOff1 = self::Extension|get#method1(c);
+ self::expect(0, tearOff1.call(0));
+ self::expect(42, tearOff1.call());
+ ({b: dynamic}) →* dynamic tearOff2 = self::Extension|get#method2(c);
+ self::expect(0, tearOff2.call(b: 0));
+ self::expect(87, tearOff2.call());
+ ({c: dynamic}) →* dynamic tearOff3 = self::Extension|get#method3(c);
+ self::expect(0, tearOff3.call(c: () → core::int* => 0));
+ self::expect(123, tearOff3.call());
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
+
+constants {
+ #C1 = null
+ #C2 = 42
+ #C3 = 87
+ #C4 = tearoff self::Extension|staticMethod
+}
diff --git a/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..e6b8869
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/default_values.dart.strong.transformed.expect
@@ -0,0 +1,65 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ method method0 = self::Extension|method0;
+ tearoff method0 = self::Extension|get#method0;
+ method method1 = self::Extension|method1;
+ tearoff method1 = self::Extension|get#method1;
+ method method2 = self::Extension|method2;
+ tearoff method2 = self::Extension|get#method2;
+ method method3 = self::Extension|method3;
+ tearoff method3 = self::Extension|get#method3;
+ static method staticMethod = self::Extension|staticMethod;
+}
+static method Extension|method0(final self::Class* #this, [dynamic a = #C1]) → dynamic
+ return a;
+static method Extension|get#method0(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a = #C1]) → dynamic => self::Extension|method0(#this, a);
+static method Extension|method1(final self::Class* #this, [dynamic a = #C2]) → dynamic
+ return a;
+static method Extension|get#method1(final self::Class* #this) → ([dynamic]) →* dynamic
+ return ([dynamic a = #C2]) → dynamic => self::Extension|method1(#this, a);
+static method Extension|method2(final self::Class* #this, {dynamic b = #C3}) → dynamic
+ return b;
+static method Extension|get#method2(final self::Class* #this) → ({b: dynamic}) →* dynamic
+ return ({dynamic b = #C3}) → dynamic => self::Extension|method2(#this, b: b);
+static method Extension|method3(final self::Class* #this, {dynamic c = #C4}) → dynamic
+ return c.call();
+static method Extension|get#method3(final self::Class* #this) → ({c: dynamic}) →* dynamic
+ return ({dynamic c = #C4}) → dynamic => self::Extension|method3(#this, c: c);
+static method Extension|staticMethod() → dynamic
+ return 123;
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ ([dynamic]) →* dynamic tearOff0 = self::Extension|get#method0(c);
+ self::expect(0, tearOff0.call(0));
+ self::expect(null, tearOff0.call());
+ ([dynamic]) →* dynamic tearOff1 = self::Extension|get#method1(c);
+ self::expect(0, tearOff1.call(0));
+ self::expect(42, tearOff1.call());
+ ({b: dynamic}) →* dynamic tearOff2 = self::Extension|get#method2(c);
+ self::expect(0, tearOff2.call(b: 0));
+ self::expect(87, tearOff2.call());
+ ({c: dynamic}) →* dynamic tearOff3 = self::Extension|get#method3(c);
+ self::expect(0, tearOff3.call(c: () → core::int* => 0));
+ self::expect(123, tearOff3.call());
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
+
+constants {
+ #C1 = null
+ #C2 = 42
+ #C3 = 87
+ #C4 = tearoff self::Extension|staticMethod
+}
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart b/pkg/front_end/testcases/extensions/direct_instance_access.dart
index 32094b5..9ccfeda 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart
@@ -120,10 +120,7 @@
writeSetterOptional(value);
writeSetterNamed();
writeSetterNamed(value: value);
- // TODO(johnniwinther): Handle direct calls to generic methods. This
- // requires inference to special-case the extension type parameters and
- // perform a two-step type argument inference.
- /*genericWriteSetterRequired(value);
+ genericWriteSetterRequired(value);
genericWriteSetterRequired<T>(value);
genericWriteSetterRequired<S>(value);
genericWriteSetterOptional();
@@ -137,7 +134,7 @@
genericWriteSetterNamed<S>();
genericWriteSetterNamed(value: value);
genericWriteSetterNamed<T>(value: value);
- genericWriteSetterNamed<S>(value: value);*/
+ genericWriteSetterNamed<S>(value: value);
}
tearOffs<S extends T>(S value) {
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
index 86ff6e6..f38f7f8c 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.outline.expect
@@ -76,11 +76,11 @@
static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value]) → dynamic
;
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
- return ([dynamic value = null]) → dynamic => self::Extension|writeSetterOptional(#this, value);
+ return ([dynamic value]) → dynamic => self::Extension|writeSetterOptional(#this, value);
static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value}) → dynamic
;
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
- return ({dynamic value = null}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
+ return ({dynamic value}) → dynamic => self::Extension|writeSetterNamed(#this, value: value);
static method Extension|get#tearOffGetterNoArgs(final self::Class* #this) → dynamic
;
static method Extension|get#tearOffGetterRequired(final self::Class* #this) → dynamic
@@ -116,11 +116,11 @@
static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value]) → dynamic
;
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
- return ([self::GenericExtension|get#writeSetterOptional::T* value = null]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
+ return ([self::GenericExtension|get#writeSetterOptional::T* value]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value}) → dynamic
;
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
- return ({self::GenericExtension|get#writeSetterNamed::T* value = null}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
+ return ({self::GenericExtension|get#writeSetterNamed::T* value}) → dynamic => self::GenericExtension|writeSetterNamed<self::GenericExtension|get#writeSetterNamed::T*>(#this, value: value);
static method GenericExtension|genericWriteSetterRequired<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterRequired::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterRequired::T*>* #this, self::GenericExtension|genericWriteSetterRequired::S* value) → dynamic
;
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
@@ -128,9 +128,9 @@
static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value]) → dynamic
;
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
- return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = null]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
+ return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
- return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = null}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
+ return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value}) → dynamic
;
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
index a652a17..ee8966f 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.expect
@@ -77,12 +77,12 @@
}
static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
-static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
+static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
self::Extension|set#property(#this, value);
}
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
-static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
+static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
self::Extension|set#property(#this, value);
}
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
@@ -97,10 +97,8 @@
return self::Extension|get#writeSetterNamed(#this);
static method Extension|get#property(final self::Class* #this) → dynamic
return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
+static method Extension|set#property(final self::Class* #this, dynamic value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
self::Extension|readGetter(#this);
@@ -146,12 +144,12 @@
}
static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
-static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
+static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
}
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
-static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
+static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
}
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
@@ -161,22 +159,20 @@
}
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
-static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
}
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
-static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
}
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
return #this.{self::GenericClass::field};
-static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → self::GenericExtension|set#property::T* {
- final self::GenericExtension|set#property::T* #t2 = value;
+static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
#this.{self::GenericClass::field} = value;
- return #t2;
}
static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
return self::GenericExtension|get#readGetter<self::GenericExtension|get#tearOffGetterNoArgs::T*>(#this);
@@ -199,6 +195,21 @@
self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::T*>(#this, value);
self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::T*>(#this);
self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::T*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
}
static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
return <S extends self::GenericExtension|get#invocations::T* = dynamic>(S* value) → dynamic => self::GenericExtension|invocations<self::GenericExtension|get#invocations::T*, S*>(#this, value);
diff --git a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
index a652a17..ee8966f 100644
--- a/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/direct_instance_access.dart.strong.transformed.expect
@@ -77,12 +77,12 @@
}
static method Extension|get#writeSetterRequired(final self::Class* #this) → (dynamic) →* dynamic
return (dynamic value) → dynamic => self::Extension|writeSetterRequired(#this, value);
-static method Extension|writeSetterOptional(final self::Class* #this = #C1, [dynamic value = #C1]) → dynamic {
+static method Extension|writeSetterOptional(final self::Class* #this, [dynamic value = #C1]) → dynamic {
self::Extension|set#property(#this, value);
}
static method Extension|get#writeSetterOptional(final self::Class* #this) → ([dynamic]) →* dynamic
return ([dynamic value = #C1]) → dynamic => self::Extension|writeSetterOptional(#this, value);
-static method Extension|writeSetterNamed(final self::Class* #this = #C1, {dynamic value = #C1}) → dynamic {
+static method Extension|writeSetterNamed(final self::Class* #this, {dynamic value = #C1}) → dynamic {
self::Extension|set#property(#this, value);
}
static method Extension|get#writeSetterNamed(final self::Class* #this) → ({value: dynamic}) →* dynamic
@@ -97,10 +97,8 @@
return self::Extension|get#writeSetterNamed(#this);
static method Extension|get#property(final self::Class* #this) → dynamic
return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
+static method Extension|set#property(final self::Class* #this, dynamic value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
static method Extension|invocations(final self::Class* #this, dynamic value) → dynamic {
self::Extension|readGetter(#this);
@@ -146,12 +144,12 @@
}
static method GenericExtension|get#writeSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterRequired::T*>* #this) → (self::GenericExtension|get#writeSetterRequired::T*) →* dynamic
return (self::GenericExtension|get#writeSetterRequired::T* value) → dynamic => self::GenericExtension|writeSetterRequired<self::GenericExtension|get#writeSetterRequired::T*>(#this, value);
-static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this = #C1, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
+static method GenericExtension|writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterOptional::T*>* #this, [self::GenericExtension|writeSetterOptional::T* value = #C1]) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|writeSetterOptional::T*>(#this, value);
}
static method GenericExtension|get#writeSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterOptional::T*>* #this) → ([self::GenericExtension|get#writeSetterOptional::T*]) →* dynamic
return ([self::GenericExtension|get#writeSetterOptional::T* value = #C1]) → dynamic => self::GenericExtension|writeSetterOptional<self::GenericExtension|get#writeSetterOptional::T*>(#this, value);
-static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this = #C1, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
+static method GenericExtension|writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|writeSetterNamed::T*>* #this, {self::GenericExtension|writeSetterNamed::T* value = #C1}) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|writeSetterNamed::T*>(#this, value);
}
static method GenericExtension|get#writeSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#writeSetterNamed::T*>* #this) → ({value: self::GenericExtension|get#writeSetterNamed::T*}) →* dynamic
@@ -161,22 +159,20 @@
}
static method GenericExtension|get#genericWriteSetterRequired<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterRequired::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S*) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterRequired::T* = dynamic>(S* value) → dynamic => self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|get#genericWriteSetterRequired::T*, S*>(#this, value);
-static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this = #C1, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
+static method GenericExtension|genericWriteSetterOptional<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterOptional::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterOptional::T*>* #this, [self::GenericExtension|genericWriteSetterOptional::S* value = #C1]) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterOptional::T*>(#this, value);
}
static method GenericExtension|get#genericWriteSetterOptional<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterOptional::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S*]) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterOptional::T* = dynamic>([S* value = #C1]) → dynamic => self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|get#genericWriteSetterOptional::T*, S*>(#this, value);
static method GenericExtension|get#genericWriteSetterNamed<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericWriteSetterNamed::T*>* #this) → <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({value: S*}) →* dynamic
return <S extends self::GenericExtension|get#genericWriteSetterNamed::T* = dynamic>({S* value = #C1}) → dynamic => self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|get#genericWriteSetterNamed::T*, S*>(#this, value: value);
-static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this = #C1, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
+static method GenericExtension|genericWriteSetterNamed<T extends core::Object* = dynamic, S extends self::GenericExtension|genericWriteSetterNamed::T* = dynamic>(final self::GenericClass<self::GenericExtension|genericWriteSetterNamed::T*>* #this, {self::GenericExtension|genericWriteSetterNamed::S* value = #C1}) → dynamic {
self::GenericExtension|set#property<self::GenericExtension|genericWriteSetterNamed::T*>(#this, value);
}
static method GenericExtension|get#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::T*>* #this) → self::GenericExtension|get#property::T*
return #this.{self::GenericClass::field};
-static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → self::GenericExtension|set#property::T* {
- final self::GenericExtension|set#property::T* #t2 = value;
+static method GenericExtension|set#property<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|set#property::T*>* #this, self::GenericExtension|set#property::T* value) → void {
#this.{self::GenericClass::field} = value;
- return #t2;
}
static method GenericExtension|get#tearOffGetterNoArgs<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#tearOffGetterNoArgs::T*>* #this) → dynamic
return self::GenericExtension|get#readGetter<self::GenericExtension|get#tearOffGetterNoArgs::T*>(#this);
@@ -199,6 +195,21 @@
self::GenericExtension|writeSetterOptional<self::GenericExtension|invocations::T*>(#this, value);
self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::T*>(#this);
self::GenericExtension|writeSetterNamed<self::GenericExtension|invocations::T*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value);
+ self::GenericExtension|genericWriteSetterRequired<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value);
+ self::GenericExtension|genericWriteSetterOptional<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::T*>(#this, value: value);
+ self::GenericExtension|genericWriteSetterNamed<self::GenericExtension|invocations::T*, self::GenericExtension|invocations::S*>(#this, value: value);
}
static method GenericExtension|get#invocations<T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#invocations::T*>* #this) → <S extends self::GenericExtension|get#invocations::T* = dynamic>(S*) →* dynamic
return <S extends self::GenericExtension|get#invocations::T* = dynamic>(S* value) → dynamic => self::GenericExtension|invocations<self::GenericExtension|get#invocations::T*, S*>(#this, value);
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart b/pkg/front_end/testcases/extensions/dynamic_invoke.dart
new file mode 100644
index 0000000..bd327b7
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ noSuchMethod(Invocation i) => 123;
+}
+
+extension ClassExtension on Class {
+ int method() => 42;
+}
+
+extension Extension on dynamic {
+ int method() => 87;
+}
+
+main() {
+ dynamic c0 = new Class();
+ Object c1 = new Class();
+ Class c2 = new Class();
+
+ expect(123, c0.method());
+ expect(87, c1.method());
+ expect(42, c2.method());
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect
new file mode 100644
index 0000000..c8a99ef
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.outline.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+ method noSuchMethod(core::Invocation* i) → dynamic
+ ;
+}
+extension ClassExtension on self::Class* {
+ method method = self::ClassExtension|method;
+ tearoff method = self::ClassExtension|get#method;
+}
+extension Extension on dynamic {
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+}
+static method ClassExtension|method(final self::Class* #this) → core::int*
+ ;
+static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::ClassExtension|method(#this);
+static method Extension|method(final dynamic #this) → core::int*
+ ;
+static method Extension|get#method(final dynamic #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect
new file mode 100644
index 0000000..95ddf7a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation* i) → dynamic
+ return 123;
+}
+extension ClassExtension on self::Class* {
+ method method = self::ClassExtension|method;
+ tearoff method = self::ClassExtension|get#method;
+}
+extension Extension on dynamic {
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+}
+static method ClassExtension|method(final self::Class* #this) → core::int*
+ return 42;
+static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::ClassExtension|method(#this);
+static method Extension|method(final dynamic #this) → core::int*
+ return 87;
+static method Extension|get#method(final dynamic #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ dynamic c0 = new self::Class::•();
+ core::Object* c1 = new self::Class::•();
+ self::Class* c2 = new self::Class::•();
+ self::expect(123, c0.method());
+ self::expect(87, self::Extension|method(c1));
+ self::expect(42, self::ClassExtension|method(c2));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect
new file mode 100644
index 0000000..95ddf7a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/dynamic_invoke.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation* i) → dynamic
+ return 123;
+}
+extension ClassExtension on self::Class* {
+ method method = self::ClassExtension|method;
+ tearoff method = self::ClassExtension|get#method;
+}
+extension Extension on dynamic {
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+}
+static method ClassExtension|method(final self::Class* #this) → core::int*
+ return 42;
+static method ClassExtension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::ClassExtension|method(#this);
+static method Extension|method(final dynamic #this) → core::int*
+ return 87;
+static method Extension|get#method(final dynamic #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ dynamic c0 = new self::Class::•();
+ core::Object* c1 = new self::Class::•();
+ self::Class* c2 = new self::Class::•();
+ self::expect(123, c0.method());
+ self::expect(87, self::Extension|method(c1));
+ self::expect(42, self::ClassExtension|method(c2));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
index 70f01be..4f30c9d 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.expect
@@ -27,10 +27,8 @@
}
static method Extension1|get#field(final self::Class* #this) → core::int*
return #this.{self::Class::field1};
-static method Extension1|set#field(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension1|set#field(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field1} = value;
- return #t1;
}
static method Extension1|method(final self::Class* #this) → core::int*
return #this.{self::Class::field1};
@@ -42,10 +40,8 @@
return <T extends core::num* = dynamic>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
static method Extension2|get#field(final self::Class* #this) → core::int*
return #this.{self::Class::field2};
-static method Extension2|set#field(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method Extension2|set#field(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field2} = value;
- return #t2;
}
static method Extension2|method(final self::Class* #this) → core::int*
return #this.{self::Class::field2};
@@ -75,8 +71,8 @@
self::expect(97, genericTearOff2.call<core::int*>(10));
self::expect(52, genericTearOff1.call<core::num*>(10));
self::expect(97, genericTearOff2.call<core::num*>(10));
- self::expect(23, self::Extension1|set#field(c, 23));
- self::expect(67, self::Extension2|set#field(c, 67));
+ self::expect(23, let final self::Class* #t1 = c in let final core::int* #t2 = 23 in let final void #t3 = self::Extension1|set#field(#t1, #t2) in #t2);
+ self::expect(67, let final self::Class* #t4 = c in let final core::int* #t5 = 67 in let final void #t6 = self::Extension2|set#field(#t4, #t5) in #t5);
self::expect(23, self::Extension1|get#field(c));
self::expect(67, self::Extension2|get#field(c));
}
diff --git a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
index 70f01be..4f30c9d 100644
--- a/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_extension_access.dart.strong.transformed.expect
@@ -27,10 +27,8 @@
}
static method Extension1|get#field(final self::Class* #this) → core::int*
return #this.{self::Class::field1};
-static method Extension1|set#field(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension1|set#field(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field1} = value;
- return #t1;
}
static method Extension1|method(final self::Class* #this) → core::int*
return #this.{self::Class::field1};
@@ -42,10 +40,8 @@
return <T extends core::num* = dynamic>(T* t) → core::int* => self::Extension1|genericMethod<T*>(#this, t);
static method Extension2|get#field(final self::Class* #this) → core::int*
return #this.{self::Class::field2};
-static method Extension2|set#field(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method Extension2|set#field(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field2} = value;
- return #t2;
}
static method Extension2|method(final self::Class* #this) → core::int*
return #this.{self::Class::field2};
@@ -75,8 +71,8 @@
self::expect(97, genericTearOff2.call<core::int*>(10));
self::expect(52, genericTearOff1.call<core::num*>(10));
self::expect(97, genericTearOff2.call<core::num*>(10));
- self::expect(23, self::Extension1|set#field(c, 23));
- self::expect(67, self::Extension2|set#field(c, 67));
+ self::expect(23, let final self::Class* #t1 = c in let final core::int* #t2 = 23 in let final void #t3 = self::Extension1|set#field(#t1, #t2) in #t2);
+ self::expect(67, let final self::Class* #t4 = c in let final core::int* #t5 = 67 in let final void #t6 = self::Extension2|set#field(#t4, #t5) in #t5);
self::expect(23, self::Extension1|get#field(c));
self::expect(67, self::Extension2|get#field(c));
}
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
index e203cfb..accfea8 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.expect
@@ -31,11 +31,9 @@
self::Extension1|latestType = "${self::Extension1|get#field::T*}";
return #this.{self::Class::field1};
}
-static method Extension1|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → self::Extension1|set#field::T* {
- final self::Extension1|set#field::T* #t1 = value;
+static method Extension1|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
self::Extension1|latestType = "${self::Extension1|set#field::T*}";
#this.{self::Class::field1} = value;
- return #t1;
}
static method Extension1|method<T extends core::num* = dynamic>(final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
self::Extension1|latestType = "${self::Extension1|method::T*}";
@@ -51,10 +49,8 @@
return <S extends core::num* = dynamic>(S* t) → self::Extension1|get#genericMethod::T* => self::Extension1|genericMethod<self::Extension1|get#genericMethod::T*, S*>(#this, t);
static method Extension2|get#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
return #this.{self::Class::field2};
-static method Extension2|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → self::Extension2|set#field::T* {
- final self::Extension2|set#field::T* #t2 = value;
+static method Extension2|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
#this.{self::Class::field2} = value;
- return #t2;
}
static method Extension2|method<T extends core::num* = dynamic>(final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
return #this.{self::Class::field2};
@@ -113,11 +109,11 @@
self::expect(52, genericTearOffInteger1.call<core::num*>(10));
self::expect("int:num", self::Extension1|latestType);
self::expect(97, genericTearOff2.call<core::num*>(10));
- self::expect(23, self::Extension1|set#field<core::num*>(c, 23));
+ self::expect(23, let final self::Class<core::int*>* #t1 = c in let final core::int* #t2 = 23 in let final void #t3 = self::Extension1|set#field<core::num*>(#t1, #t2) in #t2);
self::expect("num", self::Extension1|latestType);
- self::expect(23, self::Extension1|set#field<core::int*>(c, 23));
+ self::expect(23, let final self::Class<core::int*>* #t4 = c in let final core::int* #t5 = 23 in let final void #t6 = self::Extension1|set#field<core::int*>(#t4, #t5) in #t5);
self::expect("int", self::Extension1|latestType);
- self::expect(67, self::Extension2|set#field<core::num*>(c, 67));
+ self::expect(67, let final self::Class<core::int*>* #t7 = c in let final core::int* #t8 = 67 in let final void #t9 = self::Extension2|set#field<core::num*>(#t7, #t8) in #t8);
self::expect(23, self::Extension1|get#field<core::num*>(c));
self::expect(67, self::Extension2|get#field<core::num*>(c));
}
diff --git a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
index e203cfb..accfea8 100644
--- a/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/explicit_generic_extension_access.dart.strong.transformed.expect
@@ -31,11 +31,9 @@
self::Extension1|latestType = "${self::Extension1|get#field::T*}";
return #this.{self::Class::field1};
}
-static method Extension1|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → self::Extension1|set#field::T* {
- final self::Extension1|set#field::T* #t1 = value;
+static method Extension1|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension1|set#field::T*>* #this, self::Extension1|set#field::T* value) → void {
self::Extension1|latestType = "${self::Extension1|set#field::T*}";
#this.{self::Class::field1} = value;
- return #t1;
}
static method Extension1|method<T extends core::num* = dynamic>(final self::Class<self::Extension1|method::T*>* #this) → self::Extension1|method::T* {
self::Extension1|latestType = "${self::Extension1|method::T*}";
@@ -51,10 +49,8 @@
return <S extends core::num* = dynamic>(S* t) → self::Extension1|get#genericMethod::T* => self::Extension1|genericMethod<self::Extension1|get#genericMethod::T*, S*>(#this, t);
static method Extension2|get#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|get#field::T*>* #this) → self::Extension2|get#field::T*
return #this.{self::Class::field2};
-static method Extension2|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → self::Extension2|set#field::T* {
- final self::Extension2|set#field::T* #t2 = value;
+static method Extension2|set#field<T extends core::num* = dynamic>(final self::Class<self::Extension2|set#field::T*>* #this, self::Extension2|set#field::T* value) → void {
#this.{self::Class::field2} = value;
- return #t2;
}
static method Extension2|method<T extends core::num* = dynamic>(final self::Class<self::Extension2|method::T*>* #this) → self::Extension2|method::T*
return #this.{self::Class::field2};
@@ -113,11 +109,11 @@
self::expect(52, genericTearOffInteger1.call<core::num*>(10));
self::expect("int:num", self::Extension1|latestType);
self::expect(97, genericTearOff2.call<core::num*>(10));
- self::expect(23, self::Extension1|set#field<core::num*>(c, 23));
+ self::expect(23, let final self::Class<core::int*>* #t1 = c in let final core::int* #t2 = 23 in let final void #t3 = self::Extension1|set#field<core::num*>(#t1, #t2) in #t2);
self::expect("num", self::Extension1|latestType);
- self::expect(23, self::Extension1|set#field<core::int*>(c, 23));
+ self::expect(23, let final self::Class<core::int*>* #t4 = c in let final core::int* #t5 = 23 in let final void #t6 = self::Extension1|set#field<core::int*>(#t4, #t5) in #t5);
self::expect("int", self::Extension1|latestType);
- self::expect(67, self::Extension2|set#field<core::num*>(c, 67));
+ self::expect(67, let final self::Class<core::int*>* #t7 = c in let final core::int* #t8 = 67 in let final void #t9 = self::Extension2|set#field<core::num*>(#t7, #t8) in #t8);
self::expect(23, self::Extension1|get#field<core::num*>(c));
self::expect(67, self::Extension2|get#field<core::num*>(c));
}
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart
new file mode 100644
index 0000000..fc8cd69
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2019, 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.
+
+class Class {}
+
+extension Extension on Class {}
+
+errors(Class c) {
+ Extension(c);
+ Extension(c) = 42;
+ Extension(c) += 42;
+ Extension(c)++;
+ ++Extension(c);
+}
+
+main() {
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.outline.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.outline.expect
new file mode 100644
index 0000000..d4546e9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.outline.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension Extension on self::Class* {
+}
+static method errors(self::Class* c) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.expect
new file mode 100644
index 0000000..a751f73
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.expect
@@ -0,0 +1,52 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:10:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c);
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:11:3: Error: Explicit extension application cannot be a target for assignment.
+// Extension(c) = 42;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:12:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c) += 42;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:13:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c)++;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:14:5: Error: Explicit extension application cannot be used as an expression.
+// ++Extension(c);
+// ^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+}
+static method errors(self::Class* c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:10:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c);
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:11:3: Error: Explicit extension application cannot be a target for assignment.
+ Extension(c) = 42;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:12:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c) += 42;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:13:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c)++;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:14:5: Error: Explicit extension application cannot be used as an expression.
+ ++Extension(c);
+ ^^^^^^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.transformed.expect
new file mode 100644
index 0000000..a751f73
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/explicit_invalid_access.dart.strong.transformed.expect
@@ -0,0 +1,52 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:10:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c);
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:11:3: Error: Explicit extension application cannot be a target for assignment.
+// Extension(c) = 42;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:12:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c) += 42;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:13:3: Error: Explicit extension application cannot be used as an expression.
+// Extension(c)++;
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/explicit_invalid_access.dart:14:5: Error: Explicit extension application cannot be used as an expression.
+// ++Extension(c);
+// ^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+}
+static method errors(self::Class* c) → dynamic {
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:10:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c);
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:11:3: Error: Explicit extension application cannot be a target for assignment.
+ Extension(c) = 42;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:12:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c) += 42;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:13:3: Error: Explicit extension application cannot be used as an expression.
+ Extension(c)++;
+ ^^^^^^^^^";
+ invalid-expression "pkg/front_end/testcases/extensions/explicit_invalid_access.dart:14:5: Error: Explicit extension application cannot be used as an expression.
+ ++Extension(c);
+ ^^^^^^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart b/pkg/front_end/testcases/extensions/extension_setter.dart
new file mode 100644
index 0000000..de0ed9e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart
@@ -0,0 +1,201 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int field;
+}
+
+extension Extension on Class {
+ int get simpleSetter => field;
+
+ set simpleSetter(int value) {
+ field = value;
+ }
+
+ int get mutatingSetter => field;
+
+ set mutatingSetter(int value) {
+ value = value + 1;
+ field = value;
+ }
+
+ int get setterWithReturn => field;
+
+ set setterWithReturn(int value) {
+ if (value < 0) {
+ field = -value;
+ return;
+ }
+ field = value;
+ }
+
+ int get setterWithClosure => field;
+
+ set setterWithClosure(int value) {
+ abs(value) {
+ return value < 0 ? -value : value;
+ }
+ field = abs(value);
+ }
+
+ testInternal() {
+ expect(null, field);
+
+ simpleSetter = 0;
+ expect(0, field);
+ expect(1, simpleSetter = 1);
+
+ mutatingSetter = 0;
+ expect(1, field);
+ expect(2, mutatingSetter = 2);
+ expect(3, field);
+
+ setterWithReturn = 1;
+ expect(1, field);
+ setterWithReturn = -2;
+ expect(2, field);
+ expect(3, setterWithReturn = 3);
+ expect(3, field);
+ expect(-4, setterWithReturn = -4);
+ expect(4, field);
+
+ setterWithClosure = 1;
+ expect(1, field);
+ setterWithClosure = -2;
+ expect(2, field);
+ expect(3, setterWithClosure = 3);
+ expect(3, field);
+ expect(-4, setterWithClosure = -4);
+ expect(4, field);
+ }
+}
+
+main() {
+ var c = new Class();
+ expect(null, c.field);
+
+ c.simpleSetter = 0;
+ expect(0, c.field);
+ expect(1, c.simpleSetter = 1);
+ Extension(c).simpleSetter = 2;
+ expect(2, c.field);
+ expect(3, Extension(c).simpleSetter = 3);
+
+ c.mutatingSetter = 0;
+ expect(1, c.field);
+ expect(2, c.mutatingSetter = 2);
+ expect(3, c.field);
+ Extension(c).mutatingSetter = 4;
+ expect(5, c.field);
+ expect(6, Extension(c).mutatingSetter = 6);
+ expect(7, c.field);
+
+ c.setterWithReturn = 1;
+ expect(1, c.field);
+ c.setterWithReturn = -2;
+ expect(2, c.field);
+ expect(3, c.setterWithReturn = 3);
+ expect(3, c.field);
+ expect(-4, c.setterWithReturn = -4);
+ expect(4, c.field);
+ Extension(c).setterWithReturn = 5;
+ expect(5, c.field);
+ Extension(c).setterWithReturn = -6;
+ expect(6, c.field);
+ expect(7, Extension(c).setterWithReturn = 7);
+ expect(7, c.field);
+ expect(-8, Extension(c).setterWithReturn = -8);
+ expect(8, c.field);
+
+ c.setterWithClosure = 1;
+ expect(1, c.field);
+ c.setterWithClosure = -2;
+ expect(2, c.field);
+ expect(3, c.setterWithClosure = 3);
+ expect(3, c.field);
+ expect(-4, c.setterWithClosure = -4);
+ expect(4, c.field);
+ Extension(c).setterWithClosure = 5;
+ expect(5, c.field);
+ Extension(c).setterWithClosure = -6;
+ expect(6, c.field);
+ expect(7, Extension(c).setterWithClosure = 7);
+ expect(7, c.field);
+ expect(-8, Extension(c).setterWithClosure = -8);
+ expect(8, c.field);
+
+ c.simpleSetter = 0;
+ expect(0, c?.field);
+ expect(1, c?.simpleSetter = 1);
+ Extension(c).simpleSetter = 2;
+ expect(2, c?.field);
+ expect(3, Extension(c).simpleSetter = 3);
+
+ c.mutatingSetter = 0;
+ expect(1, c?.field);
+ expect(2, c?.mutatingSetter = 2);
+ expect(3, c?.field);
+ Extension(c).mutatingSetter = 4;
+ expect(5, c?.field);
+ expect(6, Extension(c).mutatingSetter = 6);
+ expect(7, c?.field);
+
+ c?.setterWithReturn = 1;
+ expect(1, c?.field);
+ c?.setterWithReturn = -2;
+ expect(2, c?.field);
+ expect(3, c?.setterWithReturn = 3);
+ expect(3, c?.field);
+ expect(-4, c?.setterWithReturn = -4);
+ expect(4, c?.field);
+ Extension(c).setterWithReturn = 5;
+ expect(5, c?.field);
+ Extension(c).setterWithReturn = -6;
+ expect(6, c?.field);
+ expect(7, Extension(c).setterWithReturn = 7);
+ expect(7, c?.field);
+ expect(-8, Extension(c).setterWithReturn = -8);
+ expect(8, c?.field);
+
+ c?.setterWithClosure = 1;
+ expect(1, c?.field);
+ c?.setterWithClosure = -2;
+ expect(2, c?.field);
+ expect(3, c?.setterWithClosure = 3);
+ expect(3, c?.field);
+ expect(-4, c?.setterWithClosure = -4);
+ expect(4, c?.field);
+ Extension(c).setterWithClosure = 5;
+ expect(5, c?.field);
+ Extension(c).setterWithClosure = -6;
+ expect(6, c?.field);
+ expect(7, Extension(c).setterWithClosure = 7);
+ expect(7, c?.field);
+ expect(-8, Extension(c).setterWithClosure = -8);
+ expect(8, c?.field);
+
+ c.field = null;
+ c.simpleSetter ??= 1;
+ expect(1, c.field);
+ expect(1, c.simpleSetter ??= 2);
+ c.field = null;
+ expect(2, c.simpleSetter ??= 2);
+
+ c?.field = null;
+ c?.simpleSetter ??= 1;
+ expect(1, c?.field);
+ expect(1, c?.simpleSetter ??= 2);
+ c?.field = null;
+ expect(2, c?.simpleSetter ??= 2);
+
+ new Class().testInternal();
+
+}
+
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
new file mode 100644
index 0000000..15b272e
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.outline.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field;
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension Extension on self::Class* {
+ get simpleSetter = self::Extension|get#simpleSetter;
+ get mutatingSetter = self::Extension|get#mutatingSetter;
+ get setterWithReturn = self::Extension|get#setterWithReturn;
+ get setterWithClosure = self::Extension|get#setterWithClosure;
+ method testInternal = self::Extension|testInternal;
+ tearoff testInternal = self::Extension|get#testInternal;
+ set simpleSetter = self::Extension|set#simpleSetter;
+ set mutatingSetter = self::Extension|set#mutatingSetter;
+ set setterWithReturn = self::Extension|set#setterWithReturn;
+ set setterWithClosure = self::Extension|set#setterWithClosure;
+}
+static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|testInternal(final self::Class* #this) → dynamic
+ ;
+static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testInternal(#this);
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
new file mode 100644
index 0000000..f487199
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.expect
@@ -0,0 +1,192 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get simpleSetter = self::Extension|get#simpleSetter;
+ get mutatingSetter = self::Extension|get#mutatingSetter;
+ get setterWithReturn = self::Extension|get#setterWithReturn;
+ get setterWithClosure = self::Extension|get#setterWithClosure;
+ method testInternal = self::Extension|testInternal;
+ tearoff testInternal = self::Extension|get#testInternal;
+ set simpleSetter = self::Extension|set#simpleSetter;
+ set mutatingSetter = self::Extension|set#mutatingSetter;
+ set setterWithReturn = self::Extension|set#setterWithReturn;
+ set setterWithClosure = self::Extension|set#setterWithClosure;
+}
+static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void {
+ value = value.{core::num::+}(1);
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void {
+ if(value.{core::num::<}(0)) {
+ #this.{self::Class::field} = value.{core::int::unary-}();
+ return;
+ }
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void {
+ function abs(dynamic value) → dynamic {
+ return value.<(0) as{TypeError} core::bool* ?{dynamic} value.unary-() : value;
+ }
+ #this.{self::Class::field} = abs.call(value) as{TypeError} core::int*;
+}
+static method Extension|testInternal(final self::Class* #this) → dynamic {
+ self::expect(null, #this.{self::Class::field});
+ self::Extension|set#simpleSetter(#this, 0);
+ self::expect(0, #this.{self::Class::field});
+ self::expect(1, let final core::int* #t1 = 1 in let final void #t2 = self::Extension|set#simpleSetter(#this, #t1) in #t1);
+ self::Extension|set#mutatingSetter(#this, 0);
+ self::expect(1, #this.{self::Class::field});
+ self::expect(2, let final core::int* #t3 = 2 in let final void #t4 = self::Extension|set#mutatingSetter(#this, #t3) in #t3);
+ self::expect(3, #this.{self::Class::field});
+ self::Extension|set#setterWithReturn(#this, 1);
+ self::expect(1, #this.{self::Class::field});
+ self::Extension|set#setterWithReturn(#this, 2.{core::int::unary-}());
+ self::expect(2, #this.{self::Class::field});
+ self::expect(3, let final core::int* #t5 = 3 in let final void #t6 = self::Extension|set#setterWithReturn(#this, #t5) in #t5);
+ self::expect(3, #this.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final core::int* #t7 = 4.{core::int::unary-}() in let final void #t8 = self::Extension|set#setterWithReturn(#this, #t7) in #t7);
+ self::expect(4, #this.{self::Class::field});
+ self::Extension|set#setterWithClosure(#this, 1);
+ self::expect(1, #this.{self::Class::field});
+ self::Extension|set#setterWithClosure(#this, 2.{core::int::unary-}());
+ self::expect(2, #this.{self::Class::field});
+ self::expect(3, let final core::int* #t9 = 3 in let final void #t10 = self::Extension|set#setterWithClosure(#this, #t9) in #t9);
+ self::expect(3, #this.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final core::int* #t11 = 4.{core::int::unary-}() in let final void #t12 = self::Extension|set#setterWithClosure(#this, #t11) in #t11);
+ self::expect(4, #this.{self::Class::field});
+}
+static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testInternal(#this);
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(null, c.{self::Class::field});
+ self::Extension|set#simpleSetter(c, 0);
+ self::expect(0, c.{self::Class::field});
+ self::expect(1, let final self::Class* #t13 = c in let final core::int* #t14 = 1 in let final void #t15 = self::Extension|set#simpleSetter(#t13, #t14) in #t14);
+ self::Extension|set#simpleSetter(c, 2);
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t16 = c in let final core::int* #t17 = 3 in let final void #t18 = self::Extension|set#simpleSetter(#t16, #t17) in #t17);
+ self::Extension|set#mutatingSetter(c, 0);
+ self::expect(1, c.{self::Class::field});
+ self::expect(2, let final self::Class* #t19 = c in let final core::int* #t20 = 2 in let final void #t21 = self::Extension|set#mutatingSetter(#t19, #t20) in #t20);
+ self::expect(3, c.{self::Class::field});
+ self::Extension|set#mutatingSetter(c, 4);
+ self::expect(5, c.{self::Class::field});
+ self::expect(6, let final self::Class* #t22 = c in let final core::int* #t23 = 6 in let final void #t24 = self::Extension|set#mutatingSetter(#t22, #t23) in #t23);
+ self::expect(7, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 1);
+ self::expect(1, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 2.{core::int::unary-}());
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t25 = c in let final core::int* #t26 = 3 in let final void #t27 = self::Extension|set#setterWithReturn(#t25, #t26) in #t26);
+ self::expect(3, c.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t28 = c in let final core::int* #t29 = 4.{core::int::unary-}() in let final void #t30 = self::Extension|set#setterWithReturn(#t28, #t29) in #t29);
+ self::expect(4, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 5);
+ self::expect(5, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 6.{core::int::unary-}());
+ self::expect(6, c.{self::Class::field});
+ self::expect(7, let final self::Class* #t31 = c in let final core::int* #t32 = 7 in let final void #t33 = self::Extension|set#setterWithReturn(#t31, #t32) in #t32);
+ self::expect(7, c.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t34 = c in let final core::int* #t35 = 8.{core::int::unary-}() in let final void #t36 = self::Extension|set#setterWithReturn(#t34, #t35) in #t35);
+ self::expect(8, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 1);
+ self::expect(1, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 2.{core::int::unary-}());
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t37 = c in let final core::int* #t38 = 3 in let final void #t39 = self::Extension|set#setterWithClosure(#t37, #t38) in #t38);
+ self::expect(3, c.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t40 = c in let final core::int* #t41 = 4.{core::int::unary-}() in let final void #t42 = self::Extension|set#setterWithClosure(#t40, #t41) in #t41);
+ self::expect(4, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 5);
+ self::expect(5, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 6.{core::int::unary-}());
+ self::expect(6, c.{self::Class::field});
+ self::expect(7, let final self::Class* #t43 = c in let final core::int* #t44 = 7 in let final void #t45 = self::Extension|set#setterWithClosure(#t43, #t44) in #t44);
+ self::expect(7, c.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t46 = c in let final core::int* #t47 = 8.{core::int::unary-}() in let final void #t48 = self::Extension|set#setterWithClosure(#t46, #t47) in #t47);
+ self::expect(8, c.{self::Class::field});
+ self::Extension|set#simpleSetter(c, 0);
+ self::expect(0, let final self::Class* #t49 = c in #t49.{core::Object::==}(null) ?{core::int*} null : #t49.{self::Class::field});
+ self::expect(1, let final self::Class* #t50 = c in #t50.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t51 = 1 in let final void #t52 = self::Extension|set#simpleSetter(#t50, #t51) in #t51);
+ self::Extension|set#simpleSetter(c, 2);
+ self::expect(2, let final self::Class* #t53 = c in #t53.{core::Object::==}(null) ?{core::int*} null : #t53.{self::Class::field});
+ self::expect(3, let final self::Class* #t54 = c in let final core::int* #t55 = 3 in let final void #t56 = self::Extension|set#simpleSetter(#t54, #t55) in #t55);
+ self::Extension|set#mutatingSetter(c, 0);
+ self::expect(1, let final self::Class* #t57 = c in #t57.{core::Object::==}(null) ?{core::int*} null : #t57.{self::Class::field});
+ self::expect(2, let final self::Class* #t58 = c in #t58.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t59 = 2 in let final void #t60 = self::Extension|set#mutatingSetter(#t58, #t59) in #t59);
+ self::expect(3, let final self::Class* #t61 = c in #t61.{core::Object::==}(null) ?{core::int*} null : #t61.{self::Class::field});
+ self::Extension|set#mutatingSetter(c, 4);
+ self::expect(5, let final self::Class* #t62 = c in #t62.{core::Object::==}(null) ?{core::int*} null : #t62.{self::Class::field});
+ self::expect(6, let final self::Class* #t63 = c in let final core::int* #t64 = 6 in let final void #t65 = self::Extension|set#mutatingSetter(#t63, #t64) in #t64);
+ self::expect(7, let final self::Class* #t66 = c in #t66.{core::Object::==}(null) ?{core::int*} null : #t66.{self::Class::field});
+ let final self::Class* #t67 = c in #t67.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithReturn(#t67, 1);
+ self::expect(1, let final self::Class* #t68 = c in #t68.{core::Object::==}(null) ?{core::int*} null : #t68.{self::Class::field});
+ let final self::Class* #t69 = c in #t69.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithReturn(#t69, 2.{core::int::unary-}());
+ self::expect(2, let final self::Class* #t70 = c in #t70.{core::Object::==}(null) ?{core::int*} null : #t70.{self::Class::field});
+ self::expect(3, let final self::Class* #t71 = c in #t71.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t72 = 3 in let final void #t73 = self::Extension|set#setterWithReturn(#t71, #t72) in #t72);
+ self::expect(3, let final self::Class* #t74 = c in #t74.{core::Object::==}(null) ?{core::int*} null : #t74.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t75 = c in #t75.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t76 = 4.{core::int::unary-}() in let final void #t77 = self::Extension|set#setterWithReturn(#t75, #t76) in #t76);
+ self::expect(4, let final self::Class* #t78 = c in #t78.{core::Object::==}(null) ?{core::int*} null : #t78.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 5);
+ self::expect(5, let final self::Class* #t79 = c in #t79.{core::Object::==}(null) ?{core::int*} null : #t79.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 6.{core::int::unary-}());
+ self::expect(6, let final self::Class* #t80 = c in #t80.{core::Object::==}(null) ?{core::int*} null : #t80.{self::Class::field});
+ self::expect(7, let final self::Class* #t81 = c in let final core::int* #t82 = 7 in let final void #t83 = self::Extension|set#setterWithReturn(#t81, #t82) in #t82);
+ self::expect(7, let final self::Class* #t84 = c in #t84.{core::Object::==}(null) ?{core::int*} null : #t84.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t85 = c in let final core::int* #t86 = 8.{core::int::unary-}() in let final void #t87 = self::Extension|set#setterWithReturn(#t85, #t86) in #t86);
+ self::expect(8, let final self::Class* #t88 = c in #t88.{core::Object::==}(null) ?{core::int*} null : #t88.{self::Class::field});
+ let final self::Class* #t89 = c in #t89.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithClosure(#t89, 1);
+ self::expect(1, let final self::Class* #t90 = c in #t90.{core::Object::==}(null) ?{core::int*} null : #t90.{self::Class::field});
+ let final self::Class* #t91 = c in #t91.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithClosure(#t91, 2.{core::int::unary-}());
+ self::expect(2, let final self::Class* #t92 = c in #t92.{core::Object::==}(null) ?{core::int*} null : #t92.{self::Class::field});
+ self::expect(3, let final self::Class* #t93 = c in #t93.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t94 = 3 in let final void #t95 = self::Extension|set#setterWithClosure(#t93, #t94) in #t94);
+ self::expect(3, let final self::Class* #t96 = c in #t96.{core::Object::==}(null) ?{core::int*} null : #t96.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t97 = c in #t97.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t98 = 4.{core::int::unary-}() in let final void #t99 = self::Extension|set#setterWithClosure(#t97, #t98) in #t98);
+ self::expect(4, let final self::Class* #t100 = c in #t100.{core::Object::==}(null) ?{core::int*} null : #t100.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 5);
+ self::expect(5, let final self::Class* #t101 = c in #t101.{core::Object::==}(null) ?{core::int*} null : #t101.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 6.{core::int::unary-}());
+ self::expect(6, let final self::Class* #t102 = c in #t102.{core::Object::==}(null) ?{core::int*} null : #t102.{self::Class::field});
+ self::expect(7, let final self::Class* #t103 = c in let final core::int* #t104 = 7 in let final void #t105 = self::Extension|set#setterWithClosure(#t103, #t104) in #t104);
+ self::expect(7, let final self::Class* #t106 = c in #t106.{core::Object::==}(null) ?{core::int*} null : #t106.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t107 = c in let final core::int* #t108 = 8.{core::int::unary-}() in let final void #t109 = self::Extension|set#setterWithClosure(#t107, #t108) in #t108);
+ self::expect(8, let final self::Class* #t110 = c in #t110.{core::Object::==}(null) ?{core::int*} null : #t110.{self::Class::field});
+ c.{self::Class::field} = null;
+ let final self::Class* #t111 = c in self::Extension|get#simpleSetter(#t111).{core::num::==}(null) ?{core::int*} self::Extension|set#simpleSetter(#t111, 1) : null;
+ self::expect(1, c.{self::Class::field});
+ self::expect(1, let final self::Class* #t112 = c in let final core::int* #t113 = self::Extension|get#simpleSetter(#t112) in #t113.{core::num::==}(null) ?{core::int*} let final self::Class* #t114 = #t112 in let final core::int* #t115 = 2 in let final void #t116 = self::Extension|set#simpleSetter(#t114, #t115) in #t115 : #t113);
+ c.{self::Class::field} = null;
+ self::expect(2, let final self::Class* #t117 = c in let final core::int* #t118 = self::Extension|get#simpleSetter(#t117) in #t118.{core::num::==}(null) ?{core::int*} let final self::Class* #t119 = #t117 in let final core::int* #t120 = 2 in let final void #t121 = self::Extension|set#simpleSetter(#t119, #t120) in #t120 : #t118);
+ let final self::Class* #t122 = c in #t122.{core::Object::==}(null) ?{core::Null?} null : #t122.{self::Class::field} = null;
+ let final self::Class* #t123 = c in #t123.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#simpleSetter(#t123).{core::num::==}(null) ?{core::int*} self::Extension|set#simpleSetter(#t123, 1) : null;
+ self::expect(1, let final self::Class* #t124 = c in #t124.{core::Object::==}(null) ?{core::int*} null : #t124.{self::Class::field});
+ self::expect(1, let final self::Class* #t125 = c in #t125.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t126 = self::Extension|get#simpleSetter(#t125) in #t126.{core::num::==}(null) ?{core::int*} let final core::int* #t127 = 2 in let final void #t128 = self::Extension|set#simpleSetter(#t125, #t127) in #t127 : #t126);
+ let final self::Class* #t129 = c in #t129.{core::Object::==}(null) ?{core::Null?} null : #t129.{self::Class::field} = null;
+ self::expect(2, let final self::Class* #t130 = c in #t130.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t131 = self::Extension|get#simpleSetter(#t130) in #t131.{core::num::==}(null) ?{core::int*} let final core::int* #t132 = 2 in let final void #t133 = self::Extension|set#simpleSetter(#t130, #t132) in #t132 : #t131);
+ self::Extension|testInternal(new self::Class::•());
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..f487199
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.strong.transformed.expect
@@ -0,0 +1,192 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get simpleSetter = self::Extension|get#simpleSetter;
+ get mutatingSetter = self::Extension|get#mutatingSetter;
+ get setterWithReturn = self::Extension|get#setterWithReturn;
+ get setterWithClosure = self::Extension|get#setterWithClosure;
+ method testInternal = self::Extension|testInternal;
+ tearoff testInternal = self::Extension|get#testInternal;
+ set simpleSetter = self::Extension|set#simpleSetter;
+ set mutatingSetter = self::Extension|set#mutatingSetter;
+ set setterWithReturn = self::Extension|set#setterWithReturn;
+ set setterWithClosure = self::Extension|set#setterWithClosure;
+}
+static method Extension|get#simpleSetter(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#simpleSetter(final self::Class* #this, core::int* value) → void {
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#mutatingSetter(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#mutatingSetter(final self::Class* #this, core::int* value) → void {
+ value = value.{core::num::+}(1);
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#setterWithReturn(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#setterWithReturn(final self::Class* #this, core::int* value) → void {
+ if(value.{core::num::<}(0)) {
+ #this.{self::Class::field} = value.{core::int::unary-}();
+ return;
+ }
+ #this.{self::Class::field} = value;
+}
+static method Extension|get#setterWithClosure(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#setterWithClosure(final self::Class* #this, core::int* value) → void {
+ function abs(dynamic value) → dynamic {
+ return value.<(0) as{TypeError} core::bool* ?{dynamic} value.unary-() : value;
+ }
+ #this.{self::Class::field} = abs.call(value) as{TypeError} core::int*;
+}
+static method Extension|testInternal(final self::Class* #this) → dynamic {
+ self::expect(null, #this.{self::Class::field});
+ self::Extension|set#simpleSetter(#this, 0);
+ self::expect(0, #this.{self::Class::field});
+ self::expect(1, let final core::int* #t1 = 1 in let final void #t2 = self::Extension|set#simpleSetter(#this, #t1) in #t1);
+ self::Extension|set#mutatingSetter(#this, 0);
+ self::expect(1, #this.{self::Class::field});
+ self::expect(2, let final core::int* #t3 = 2 in let final void #t4 = self::Extension|set#mutatingSetter(#this, #t3) in #t3);
+ self::expect(3, #this.{self::Class::field});
+ self::Extension|set#setterWithReturn(#this, 1);
+ self::expect(1, #this.{self::Class::field});
+ self::Extension|set#setterWithReturn(#this, 2.{core::int::unary-}());
+ self::expect(2, #this.{self::Class::field});
+ self::expect(3, let final core::int* #t5 = 3 in let final void #t6 = self::Extension|set#setterWithReturn(#this, #t5) in #t5);
+ self::expect(3, #this.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final core::int* #t7 = 4.{core::int::unary-}() in let final void #t8 = self::Extension|set#setterWithReturn(#this, #t7) in #t7);
+ self::expect(4, #this.{self::Class::field});
+ self::Extension|set#setterWithClosure(#this, 1);
+ self::expect(1, #this.{self::Class::field});
+ self::Extension|set#setterWithClosure(#this, 2.{core::int::unary-}());
+ self::expect(2, #this.{self::Class::field});
+ self::expect(3, let final core::int* #t9 = 3 in let final void #t10 = self::Extension|set#setterWithClosure(#this, #t9) in #t9);
+ self::expect(3, #this.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final core::int* #t11 = 4.{core::int::unary-}() in let final void #t12 = self::Extension|set#setterWithClosure(#this, #t11) in #t11);
+ self::expect(4, #this.{self::Class::field});
+}
+static method Extension|get#testInternal(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testInternal(#this);
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(null, c.{self::Class::field});
+ self::Extension|set#simpleSetter(c, 0);
+ self::expect(0, c.{self::Class::field});
+ self::expect(1, let final self::Class* #t13 = c in let final core::int* #t14 = 1 in let final void #t15 = self::Extension|set#simpleSetter(#t13, #t14) in #t14);
+ self::Extension|set#simpleSetter(c, 2);
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t16 = c in let final core::int* #t17 = 3 in let final void #t18 = self::Extension|set#simpleSetter(#t16, #t17) in #t17);
+ self::Extension|set#mutatingSetter(c, 0);
+ self::expect(1, c.{self::Class::field});
+ self::expect(2, let final self::Class* #t19 = c in let final core::int* #t20 = 2 in let final void #t21 = self::Extension|set#mutatingSetter(#t19, #t20) in #t20);
+ self::expect(3, c.{self::Class::field});
+ self::Extension|set#mutatingSetter(c, 4);
+ self::expect(5, c.{self::Class::field});
+ self::expect(6, let final self::Class* #t22 = c in let final core::int* #t23 = 6 in let final void #t24 = self::Extension|set#mutatingSetter(#t22, #t23) in #t23);
+ self::expect(7, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 1);
+ self::expect(1, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 2.{core::int::unary-}());
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t25 = c in let final core::int* #t26 = 3 in let final void #t27 = self::Extension|set#setterWithReturn(#t25, #t26) in #t26);
+ self::expect(3, c.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t28 = c in let final core::int* #t29 = 4.{core::int::unary-}() in let final void #t30 = self::Extension|set#setterWithReturn(#t28, #t29) in #t29);
+ self::expect(4, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 5);
+ self::expect(5, c.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 6.{core::int::unary-}());
+ self::expect(6, c.{self::Class::field});
+ self::expect(7, let final self::Class* #t31 = c in let final core::int* #t32 = 7 in let final void #t33 = self::Extension|set#setterWithReturn(#t31, #t32) in #t32);
+ self::expect(7, c.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t34 = c in let final core::int* #t35 = 8.{core::int::unary-}() in let final void #t36 = self::Extension|set#setterWithReturn(#t34, #t35) in #t35);
+ self::expect(8, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 1);
+ self::expect(1, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 2.{core::int::unary-}());
+ self::expect(2, c.{self::Class::field});
+ self::expect(3, let final self::Class* #t37 = c in let final core::int* #t38 = 3 in let final void #t39 = self::Extension|set#setterWithClosure(#t37, #t38) in #t38);
+ self::expect(3, c.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t40 = c in let final core::int* #t41 = 4.{core::int::unary-}() in let final void #t42 = self::Extension|set#setterWithClosure(#t40, #t41) in #t41);
+ self::expect(4, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 5);
+ self::expect(5, c.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 6.{core::int::unary-}());
+ self::expect(6, c.{self::Class::field});
+ self::expect(7, let final self::Class* #t43 = c in let final core::int* #t44 = 7 in let final void #t45 = self::Extension|set#setterWithClosure(#t43, #t44) in #t44);
+ self::expect(7, c.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t46 = c in let final core::int* #t47 = 8.{core::int::unary-}() in let final void #t48 = self::Extension|set#setterWithClosure(#t46, #t47) in #t47);
+ self::expect(8, c.{self::Class::field});
+ self::Extension|set#simpleSetter(c, 0);
+ self::expect(0, let final self::Class* #t49 = c in #t49.{core::Object::==}(null) ?{core::int*} null : #t49.{self::Class::field});
+ self::expect(1, let final self::Class* #t50 = c in #t50.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t51 = 1 in let final void #t52 = self::Extension|set#simpleSetter(#t50, #t51) in #t51);
+ self::Extension|set#simpleSetter(c, 2);
+ self::expect(2, let final self::Class* #t53 = c in #t53.{core::Object::==}(null) ?{core::int*} null : #t53.{self::Class::field});
+ self::expect(3, let final self::Class* #t54 = c in let final core::int* #t55 = 3 in let final void #t56 = self::Extension|set#simpleSetter(#t54, #t55) in #t55);
+ self::Extension|set#mutatingSetter(c, 0);
+ self::expect(1, let final self::Class* #t57 = c in #t57.{core::Object::==}(null) ?{core::int*} null : #t57.{self::Class::field});
+ self::expect(2, let final self::Class* #t58 = c in #t58.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t59 = 2 in let final void #t60 = self::Extension|set#mutatingSetter(#t58, #t59) in #t59);
+ self::expect(3, let final self::Class* #t61 = c in #t61.{core::Object::==}(null) ?{core::int*} null : #t61.{self::Class::field});
+ self::Extension|set#mutatingSetter(c, 4);
+ self::expect(5, let final self::Class* #t62 = c in #t62.{core::Object::==}(null) ?{core::int*} null : #t62.{self::Class::field});
+ self::expect(6, let final self::Class* #t63 = c in let final core::int* #t64 = 6 in let final void #t65 = self::Extension|set#mutatingSetter(#t63, #t64) in #t64);
+ self::expect(7, let final self::Class* #t66 = c in #t66.{core::Object::==}(null) ?{core::int*} null : #t66.{self::Class::field});
+ let final self::Class* #t67 = c in #t67.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithReturn(#t67, 1);
+ self::expect(1, let final self::Class* #t68 = c in #t68.{core::Object::==}(null) ?{core::int*} null : #t68.{self::Class::field});
+ let final self::Class* #t69 = c in #t69.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithReturn(#t69, 2.{core::int::unary-}());
+ self::expect(2, let final self::Class* #t70 = c in #t70.{core::Object::==}(null) ?{core::int*} null : #t70.{self::Class::field});
+ self::expect(3, let final self::Class* #t71 = c in #t71.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t72 = 3 in let final void #t73 = self::Extension|set#setterWithReturn(#t71, #t72) in #t72);
+ self::expect(3, let final self::Class* #t74 = c in #t74.{core::Object::==}(null) ?{core::int*} null : #t74.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t75 = c in #t75.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t76 = 4.{core::int::unary-}() in let final void #t77 = self::Extension|set#setterWithReturn(#t75, #t76) in #t76);
+ self::expect(4, let final self::Class* #t78 = c in #t78.{core::Object::==}(null) ?{core::int*} null : #t78.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 5);
+ self::expect(5, let final self::Class* #t79 = c in #t79.{core::Object::==}(null) ?{core::int*} null : #t79.{self::Class::field});
+ self::Extension|set#setterWithReturn(c, 6.{core::int::unary-}());
+ self::expect(6, let final self::Class* #t80 = c in #t80.{core::Object::==}(null) ?{core::int*} null : #t80.{self::Class::field});
+ self::expect(7, let final self::Class* #t81 = c in let final core::int* #t82 = 7 in let final void #t83 = self::Extension|set#setterWithReturn(#t81, #t82) in #t82);
+ self::expect(7, let final self::Class* #t84 = c in #t84.{core::Object::==}(null) ?{core::int*} null : #t84.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t85 = c in let final core::int* #t86 = 8.{core::int::unary-}() in let final void #t87 = self::Extension|set#setterWithReturn(#t85, #t86) in #t86);
+ self::expect(8, let final self::Class* #t88 = c in #t88.{core::Object::==}(null) ?{core::int*} null : #t88.{self::Class::field});
+ let final self::Class* #t89 = c in #t89.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithClosure(#t89, 1);
+ self::expect(1, let final self::Class* #t90 = c in #t90.{core::Object::==}(null) ?{core::int*} null : #t90.{self::Class::field});
+ let final self::Class* #t91 = c in #t91.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#setterWithClosure(#t91, 2.{core::int::unary-}());
+ self::expect(2, let final self::Class* #t92 = c in #t92.{core::Object::==}(null) ?{core::int*} null : #t92.{self::Class::field});
+ self::expect(3, let final self::Class* #t93 = c in #t93.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t94 = 3 in let final void #t95 = self::Extension|set#setterWithClosure(#t93, #t94) in #t94);
+ self::expect(3, let final self::Class* #t96 = c in #t96.{core::Object::==}(null) ?{core::int*} null : #t96.{self::Class::field});
+ self::expect(4.{core::int::unary-}(), let final self::Class* #t97 = c in #t97.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t98 = 4.{core::int::unary-}() in let final void #t99 = self::Extension|set#setterWithClosure(#t97, #t98) in #t98);
+ self::expect(4, let final self::Class* #t100 = c in #t100.{core::Object::==}(null) ?{core::int*} null : #t100.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 5);
+ self::expect(5, let final self::Class* #t101 = c in #t101.{core::Object::==}(null) ?{core::int*} null : #t101.{self::Class::field});
+ self::Extension|set#setterWithClosure(c, 6.{core::int::unary-}());
+ self::expect(6, let final self::Class* #t102 = c in #t102.{core::Object::==}(null) ?{core::int*} null : #t102.{self::Class::field});
+ self::expect(7, let final self::Class* #t103 = c in let final core::int* #t104 = 7 in let final void #t105 = self::Extension|set#setterWithClosure(#t103, #t104) in #t104);
+ self::expect(7, let final self::Class* #t106 = c in #t106.{core::Object::==}(null) ?{core::int*} null : #t106.{self::Class::field});
+ self::expect(8.{core::int::unary-}(), let final self::Class* #t107 = c in let final core::int* #t108 = 8.{core::int::unary-}() in let final void #t109 = self::Extension|set#setterWithClosure(#t107, #t108) in #t108);
+ self::expect(8, let final self::Class* #t110 = c in #t110.{core::Object::==}(null) ?{core::int*} null : #t110.{self::Class::field});
+ c.{self::Class::field} = null;
+ let final self::Class* #t111 = c in self::Extension|get#simpleSetter(#t111).{core::num::==}(null) ?{core::int*} self::Extension|set#simpleSetter(#t111, 1) : null;
+ self::expect(1, c.{self::Class::field});
+ self::expect(1, let final self::Class* #t112 = c in let final core::int* #t113 = self::Extension|get#simpleSetter(#t112) in #t113.{core::num::==}(null) ?{core::int*} let final self::Class* #t114 = #t112 in let final core::int* #t115 = 2 in let final void #t116 = self::Extension|set#simpleSetter(#t114, #t115) in #t115 : #t113);
+ c.{self::Class::field} = null;
+ self::expect(2, let final self::Class* #t117 = c in let final core::int* #t118 = self::Extension|get#simpleSetter(#t117) in #t118.{core::num::==}(null) ?{core::int*} let final self::Class* #t119 = #t117 in let final core::int* #t120 = 2 in let final void #t121 = self::Extension|set#simpleSetter(#t119, #t120) in #t120 : #t118);
+ let final self::Class* #t122 = c in #t122.{core::Object::==}(null) ?{core::Null?} null : #t122.{self::Class::field} = null;
+ let final self::Class* #t123 = c in #t123.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#simpleSetter(#t123).{core::num::==}(null) ?{core::int*} self::Extension|set#simpleSetter(#t123, 1) : null;
+ self::expect(1, let final self::Class* #t124 = c in #t124.{core::Object::==}(null) ?{core::int*} null : #t124.{self::Class::field});
+ self::expect(1, let final self::Class* #t125 = c in #t125.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t126 = self::Extension|get#simpleSetter(#t125) in #t126.{core::num::==}(null) ?{core::int*} let final core::int* #t127 = 2 in let final void #t128 = self::Extension|set#simpleSetter(#t125, #t127) in #t127 : #t126);
+ let final self::Class* #t129 = c in #t129.{core::Object::==}(null) ?{core::Null?} null : #t129.{self::Class::field} = null;
+ self::expect(2, let final self::Class* #t130 = c in #t130.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t131 = self::Extension|get#simpleSetter(#t130) in #t131.{core::num::==}(null) ?{core::int*} let final core::int* #t132 = 2 in let final void #t133 = self::Extension|set#simpleSetter(#t130, #t132) in #t132 : #t131);
+ self::Extension|testInternal(new self::Class::•());
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/extension_setter.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/extension_setter.dart.type_promotion.expect
new file mode 100644
index 0000000..759a79d
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_setter.dart.type_promotion.expect
@@ -0,0 +1,3 @@
+pkg/front_end/testcases/extensions/extension_setter.dart:19:11: Context: Write to value@335
+ value = value + 1;
+ ^
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart
new file mode 100644
index 0000000..eb42294
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int get m1 => 0;
+ void set m2(int x) {}
+}
+
+extension Extension0 on Class {
+ void set m1(int x) {}
+ int get m2 => 0;
+ void set m3(int x) {}
+ int get m4 => 0;
+}
+
+extension Extension1 on Class {
+ int get m3 => 0;
+ void set m4(int x) {}
+}
+
+main() {
+ var c = new Class();
+ expect(0, c.m1);
+ c.m2 = 2;
+}
+
+errors() {
+ var c = new Class();
+ expect(0, c.m2);
+ c.m1 = 2;
+ c.m3;
+ c.m3 = 2;
+ c.m4;
+ c.m4 = 2;
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect
new file mode 100644
index 0000000..ed922f8
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.outline.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ ;
+ get m1() → core::int*
+ ;
+ set m2(core::int* x) → void
+ ;
+}
+extension Extension0 on self::Class* {
+ get m2 = self::Extension0|get#m2;
+ get m4 = self::Extension0|get#m4;
+ set m1 = self::Extension0|set#m1;
+ set m3 = self::Extension0|set#m3;
+}
+extension Extension1 on self::Class* {
+ get m3 = self::Extension1|get#m3;
+ set m4 = self::Extension1|set#m4;
+}
+static method Extension0|set#m1(final self::Class* #this, core::int* x) → void
+ ;
+static method Extension0|get#m2(final self::Class* #this) → core::int*
+ ;
+static method Extension0|set#m3(final self::Class* #this, core::int* x) → void
+ ;
+static method Extension0|get#m4(final self::Class* #this) → core::int*
+ ;
+static method Extension1|get#m3(final self::Class* #this) → core::int*
+ ;
+static method Extension1|set#m4(final self::Class* #this, core::int* x) → void
+ ;
+static method main() → dynamic
+ ;
+static method errors() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect
new file mode 100644
index 0000000..f432ee9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.expect
@@ -0,0 +1,113 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:30:15: Error: The getter 'm2' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm2'.
+// expect(0, c.m2);
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:31:5: Error: The setter 'm1' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm1'.
+// c.m1 = 2;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:32:5: Error: The getter 'm3' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm3'.
+// c.m3;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:33:5: Error: The setter 'm3' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm3'.
+// c.m3 = 2;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:34:5: Error: The getter 'm4' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm4'.
+// c.m4;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:35:5: Error: The setter 'm4' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm4'.
+// c.m4 = 2;
+// ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ get m1() → core::int*
+ return 0;
+ set m2(core::int* x) → void {}
+}
+extension Extension0 on self::Class* {
+ get m2 = self::Extension0|get#m2;
+ get m4 = self::Extension0|get#m4;
+ set m1 = self::Extension0|set#m1;
+ set m3 = self::Extension0|set#m3;
+}
+extension Extension1 on self::Class* {
+ get m3 = self::Extension1|get#m3;
+ set m4 = self::Extension1|set#m4;
+}
+static method Extension0|set#m1(final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m2(final self::Class* #this) → core::int*
+ return 0;
+static method Extension0|set#m3(final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m4(final self::Class* #this) → core::int*
+ return 0;
+static method Extension1|get#m3(final self::Class* #this) → core::int*
+ return 0;
+static method Extension1|set#m4(final self::Class* #this, core::int* x) → void {}
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(0, c.{self::Class::m1});
+ c.{self::Class::m2} = 2;
+}
+static method errors() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(0, invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:30:15: Error: The getter 'm2' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm2'.
+ expect(0, c.m2);
+ ^^");
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:31:5: Error: The setter 'm1' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm1'.
+ c.m1 = 2;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:32:5: Error: The getter 'm3' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm3'.
+ c.m3;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:33:5: Error: The setter 'm3' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm3'.
+ c.m3 = 2;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:34:5: Error: The getter 'm4' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm4'.
+ c.m4;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:35:5: Error: The setter 'm4' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm4'.
+ c.m4 = 2;
+ ^^";
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect
new file mode 100644
index 0000000..f432ee9
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/getter_setter_conflict.dart.strong.transformed.expect
@@ -0,0 +1,113 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:30:15: Error: The getter 'm2' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm2'.
+// expect(0, c.m2);
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:31:5: Error: The setter 'm1' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm1'.
+// c.m1 = 2;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:32:5: Error: The getter 'm3' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm3'.
+// c.m3;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:33:5: Error: The setter 'm3' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm3'.
+// c.m3 = 2;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:34:5: Error: The getter 'm4' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm4'.
+// c.m4;
+// ^^
+//
+// pkg/front_end/testcases/extensions/getter_setter_conflict.dart:35:5: Error: The setter 'm4' isn't defined for the class 'Class'.
+// - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'm4'.
+// c.m4 = 2;
+// ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ get m1() → core::int*
+ return 0;
+ set m2(core::int* x) → void {}
+}
+extension Extension0 on self::Class* {
+ get m2 = self::Extension0|get#m2;
+ get m4 = self::Extension0|get#m4;
+ set m1 = self::Extension0|set#m1;
+ set m3 = self::Extension0|set#m3;
+}
+extension Extension1 on self::Class* {
+ get m3 = self::Extension1|get#m3;
+ set m4 = self::Extension1|set#m4;
+}
+static method Extension0|set#m1(final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m2(final self::Class* #this) → core::int*
+ return 0;
+static method Extension0|set#m3(final self::Class* #this, core::int* x) → void {}
+static method Extension0|get#m4(final self::Class* #this) → core::int*
+ return 0;
+static method Extension1|get#m3(final self::Class* #this) → core::int*
+ return 0;
+static method Extension1|set#m4(final self::Class* #this, core::int* x) → void {}
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(0, c.{self::Class::m1});
+ c.{self::Class::m2} = 2;
+}
+static method errors() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(0, invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:30:15: Error: The getter 'm2' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm2'.
+ expect(0, c.m2);
+ ^^");
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:31:5: Error: The setter 'm1' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm1'.
+ c.m1 = 2;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:32:5: Error: The getter 'm3' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm3'.
+ c.m3;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:33:5: Error: The setter 'm3' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm3'.
+ c.m3 = 2;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:34:5: Error: The getter 'm4' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'm4'.
+ c.m4;
+ ^^";
+ invalid-expression "pkg/front_end/testcases/extensions/getter_setter_conflict.dart:35:5: Error: The setter 'm4' isn't defined for the class 'Class'.
+ - 'Class' is from 'pkg/front_end/testcases/extensions/getter_setter_conflict.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'm4'.
+ c.m4 = 2;
+ ^^";
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart b/pkg/front_end/testcases/extensions/if_null.dart
new file mode 100644
index 0000000..4dadffb
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int field;
+}
+
+extension Extension on Class {
+ int get property => field;
+ void set property(int value) {
+ field = value;
+ }
+ int method() => field;
+}
+
+main() {
+ Class c;
+ c?.property ?? 0;
+ Extension(c)?.property ?? 0;
+ c?.property = 42 ?? 0;
+ Extension(c)?.property = 42 ?? 0;
+ (c?.property = 42) ?? 0;
+ (Extension(c)?.property = 42) ?? 0;
+ c?.method() ?? 0;
+ Extension(c)?.method() ?? 0;
+ c = new Class();
+ c.property ?? 0;
+ Extension(c).property ?? 0;
+}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.outline.expect b/pkg/front_end/testcases/extensions/if_null.dart.outline.expect
new file mode 100644
index 0000000..17223f2
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.outline.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field;
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ ;
+static method Extension|set#property(final self::Class* #this, core::int* value) → void
+ ;
+static method Extension|method(final self::Class* #this) → core::int*
+ ;
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.strong.expect b/pkg/front_end/testcases/extensions/if_null.dart.strong.expect
new file mode 100644
index 0000000..76f0f9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+ #this.{self::Class::field} = value;
+}
+static method Extension|method(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ self::Class* c;
+ let final core::int* #t1 = let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2) in #t1.{core::num::==}(null) ?{core::int*} 0 : #t1;
+ let final core::int* #t3 = let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t4) in #t3.{core::num::==}(null) ?{core::int*} 0 : #t3;
+ let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, let final core::int* #t6 = 42 in #t6.{core::num::==}(null) ?{core::int*} 0 : #t6);
+ let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t7, let final core::int* #t8 = 42 in #t8.{core::num::==}(null) ?{core::int*} 0 : #t8);
+ let final core::int* #t9 = let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = 42 in let final void #t12 = self::Extension|set#property(#t10, #t11) in #t11 in #t9.{core::num::==}(null) ?{core::int*} 0 : #t9;
+ let final core::int* #t13 = let final self::Class* #t14 = c in #t14.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t15 = 42 in let final void #t16 = self::Extension|set#property(#t14, #t15) in #t15 in #t13.{core::num::==}(null) ?{core::int*} 0 : #t13;
+ let final core::int* #t17 = let final self::Class* #t18 = c in #t18.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t18) in #t17.{core::num::==}(null) ?{core::int*} 0 : #t17;
+ let final core::int* #t19 = let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t20) in #t19.{core::num::==}(null) ?{core::int*} 0 : #t19;
+ c = new self::Class::•();
+ let final core::int* #t21 = self::Extension|get#property(c) in #t21.{core::num::==}(null) ?{core::int*} 0 : #t21;
+ let final core::int* #t22 = self::Extension|get#property(c) in #t22.{core::num::==}(null) ?{core::int*} 0 : #t22;
+}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..76f0f9b
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension Extension on self::Class* {
+ get property = self::Extension|get#property;
+ method method = self::Extension|method;
+ tearoff method = self::Extension|get#method;
+ set property = self::Extension|set#property;
+}
+static method Extension|get#property(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|set#property(final self::Class* #this, core::int* value) → void {
+ #this.{self::Class::field} = value;
+}
+static method Extension|method(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method Extension|get#method(final self::Class* #this) → () →* core::int*
+ return () → core::int* => self::Extension|method(#this);
+static method main() → dynamic {
+ self::Class* c;
+ let final core::int* #t1 = let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2) in #t1.{core::num::==}(null) ?{core::int*} 0 : #t1;
+ let final core::int* #t3 = let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t4) in #t3.{core::num::==}(null) ?{core::int*} 0 : #t3;
+ let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, let final core::int* #t6 = 42 in #t6.{core::num::==}(null) ?{core::int*} 0 : #t6);
+ let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t7, let final core::int* #t8 = 42 in #t8.{core::num::==}(null) ?{core::int*} 0 : #t8);
+ let final core::int* #t9 = let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = 42 in let final void #t12 = self::Extension|set#property(#t10, #t11) in #t11 in #t9.{core::num::==}(null) ?{core::int*} 0 : #t9;
+ let final core::int* #t13 = let final self::Class* #t14 = c in #t14.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t15 = 42 in let final void #t16 = self::Extension|set#property(#t14, #t15) in #t15 in #t13.{core::num::==}(null) ?{core::int*} 0 : #t13;
+ let final core::int* #t17 = let final self::Class* #t18 = c in #t18.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t18) in #t17.{core::num::==}(null) ?{core::int*} 0 : #t17;
+ let final core::int* #t19 = let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t20) in #t19.{core::num::==}(null) ?{core::int*} 0 : #t19;
+ c = new self::Class::•();
+ let final core::int* #t21 = self::Extension|get#property(c) in #t21.{core::num::==}(null) ?{core::int*} 0 : #t21;
+ let final core::int* #t22 = self::Extension|get#property(c) in #t22.{core::num::==}(null) ?{core::int*} 0 : #t22;
+}
diff --git a/pkg/front_end/testcases/extensions/if_null.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/if_null.dart.type_promotion.expect
new file mode 100644
index 0000000..8431aad
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/if_null.dart.type_promotion.expect
@@ -0,0 +1,3 @@
+pkg/front_end/testcases/extensions/if_null.dart:27:5: Context: Write to c@408
+ c = new Class();
+ ^
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
index 9812038..895ddb7 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.expect
@@ -50,12 +50,10 @@
core::print("Extension1.property get on ${#this}");
return #this.{self::Class1::field};
}
-static method Extension1|set#property(final self::Class1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension1|set#property(final self::Class1* #this, core::int* value) → void {
#this.{self::Class1::field} = value;
core::print("Extension1.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
- return #t1;
}
static method Extension2|method(final self::Class2* #this) → core::int* {
core::print("Extension2.method on ${#this}");
@@ -73,12 +71,10 @@
core::print("Extension2.property get on ${#this}");
return #this.{self::Class2::field}.{core::num::+}(5);
}
-static method Extension2|set#property(final self::Class2* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method Extension2|set#property(final self::Class2* #this, core::int* value) → void {
core::print("Extension2.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
#this.{self::Class2::field} = value;
- return #t2;
}
static method main() → dynamic {
self::testExtension1();
@@ -89,42 +85,42 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::Extension1|method(c0));
self::expect(1, self::Extension1|method(c1));
- self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t3));
+ self::expect(1, let final self::Class1* #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t1));
self::expect(42, self::Extension1|genericMethod<core::int*>(c0, 42));
self::expect(43, self::Extension1|genericMethod<core::num*>(c0, 43));
self::expect(88, self::Extension1|genericMethod<core::int*>(c1, 87));
self::expect(89, self::Extension1|genericMethod<core::num*>(c1, 88));
self::expect(0, self::Extension1|get#property(c0));
- self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t4));
- self::expect(42, self::Extension1|set#property(c0, 42));
+ self::expect(0, let final self::Class1* #t2 = c0 in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t2));
+ self::expect(42, let final self::Class1* #t3 = c0 in let final core::int* #t4 = 42 in let final void #t5 = self::Extension1|set#property(#t3, #t4) in #t4);
self::expect(1, self::Extension1|get#property(c1));
- self::expect(87, self::Extension1|set#property(c0, 87));
- self::expect(27, self::Extension1|set#property(c0, self::Extension1|set#property(c1, 27)));
- self::expect(37, self::Extension1|set#property(c1, self::Extension1|set#property(c0, 37)));
- self::expect(77, self::Extension1|set#property(c1, self::Extension1|set#property(c0, self::Extension1|set#property(c1, 77))));
- self::expect(67, self::Extension1|set#property(c0, self::Extension1|set#property(c1, self::Extension1|set#property(c0, 67))));
+ self::expect(87, let final self::Class1* #t6 = c0 in let final core::int* #t7 = 87 in let final void #t8 = self::Extension1|set#property(#t6, #t7) in #t7);
+ self::expect(27, let final self::Class1* #t9 = c0 in let final core::int* #t10 = let final self::Class1* #t11 = c1 in let final core::int* #t12 = 27 in let final void #t13 = self::Extension1|set#property(#t11, #t12) in #t12 in let final void #t14 = self::Extension1|set#property(#t9, #t10) in #t10);
+ self::expect(37, let final self::Class1* #t15 = c1 in let final core::int* #t16 = let final self::Class1* #t17 = c0 in let final core::int* #t18 = 37 in let final void #t19 = self::Extension1|set#property(#t17, #t18) in #t18 in let final void #t20 = self::Extension1|set#property(#t15, #t16) in #t16);
+ self::expect(77, let final self::Class1* #t21 = c1 in let final core::int* #t22 = let final self::Class1* #t23 = c0 in let final core::int* #t24 = let final self::Class1* #t25 = c1 in let final core::int* #t26 = 77 in let final void #t27 = self::Extension1|set#property(#t25, #t26) in #t26 in let final void #t28 = self::Extension1|set#property(#t23, #t24) in #t24 in let final void #t29 = self::Extension1|set#property(#t21, #t22) in #t22);
+ self::expect(67, let final self::Class1* #t30 = c0 in let final core::int* #t31 = let final self::Class1* #t32 = c1 in let final core::int* #t33 = let final self::Class1* #t34 = c0 in let final core::int* #t35 = 67 in let final void #t36 = self::Extension1|set#property(#t34, #t35) in #t35 in let final void #t37 = self::Extension1|set#property(#t32, #t33) in #t33 in let final void #t38 = self::Extension1|set#property(#t30, #t31) in #t31);
}
static method testExtension2() → dynamic {
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::Extension2|method(c0));
- self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t5));
+ self::expect(3, let final self::Class2* #t39 = c0 in #t39.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t39));
self::expect(4, self::Extension2|method(c1));
self::expect(46, self::Extension2|genericMethod<core::int*>(c0, 42));
self::expect(47, self::Extension2|genericMethod<core::num*>(c0, 43));
self::expect(92, self::Extension2|genericMethod<core::int*>(c1, 87));
self::expect(93, self::Extension2|genericMethod<core::num*>(c1, 88));
self::expect(5, self::Extension2|get#property(c0));
- self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t6));
- self::expect(42, self::Extension2|set#property(c0, 42));
+ self::expect(5, let final self::Class2* #t40 = c0 in #t40.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t40));
+ self::expect(42, let final self::Class2* #t41 = c0 in let final core::int* #t42 = 42 in let final void #t43 = self::Extension2|set#property(#t41, #t42) in #t42);
self::expect(48, self::Extension2|get#property(c0));
self::expect(6, self::Extension2|get#property(c1));
- self::expect(43, self::Extension2|set#property(c1, 43));
+ self::expect(43, let final self::Class2* #t44 = c1 in let final core::int* #t45 = 43 in let final void #t46 = self::Extension2|set#property(#t44, #t45) in #t45);
self::expect(49, self::Extension2|get#property(c1));
- self::expect(49, self::Extension2|set#property(c0, self::Extension2|get#property(c1)));
- self::expect(55, self::Extension2|set#property(c1, self::Extension2|get#property(c0)));
- self::expect(61, self::Extension2|set#property(c1, self::Extension2|set#property(c0, self::Extension2|get#property(c1))));
- self::expect(67, self::Extension2|set#property(c0, self::Extension2|set#property(c1, self::Extension2|get#property(c0))));
+ self::expect(49, let final self::Class2* #t47 = c0 in let final core::int* #t48 = self::Extension2|get#property(c1) in let final void #t49 = self::Extension2|set#property(#t47, #t48) in #t48);
+ self::expect(55, let final self::Class2* #t50 = c1 in let final core::int* #t51 = self::Extension2|get#property(c0) in let final void #t52 = self::Extension2|set#property(#t50, #t51) in #t51);
+ self::expect(61, let final self::Class2* #t53 = c1 in let final core::int* #t54 = let final self::Class2* #t55 = c0 in let final core::int* #t56 = self::Extension2|get#property(c1) in let final void #t57 = self::Extension2|set#property(#t55, #t56) in #t56 in let final void #t58 = self::Extension2|set#property(#t53, #t54) in #t54);
+ self::expect(67, let final self::Class2* #t59 = c0 in let final core::int* #t60 = let final self::Class2* #t61 = c1 in let final core::int* #t62 = self::Extension2|get#property(c0) in let final void #t63 = self::Extension2|set#property(#t61, #t62) in #t62 in let final void #t64 = self::Extension2|set#property(#t59, #t60) in #t60);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
index 9812038..895ddb7 100644
--- a/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_access.dart.strong.transformed.expect
@@ -50,12 +50,10 @@
core::print("Extension1.property get on ${#this}");
return #this.{self::Class1::field};
}
-static method Extension1|set#property(final self::Class1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension1|set#property(final self::Class1* #this, core::int* value) → void {
#this.{self::Class1::field} = value;
core::print("Extension1.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
- return #t1;
}
static method Extension2|method(final self::Class2* #this) → core::int* {
core::print("Extension2.method on ${#this}");
@@ -73,12 +71,10 @@
core::print("Extension2.property get on ${#this}");
return #this.{self::Class2::field}.{core::num::+}(5);
}
-static method Extension2|set#property(final self::Class2* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method Extension2|set#property(final self::Class2* #this, core::int* value) → void {
core::print("Extension2.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
#this.{self::Class2::field} = value;
- return #t2;
}
static method main() → dynamic {
self::testExtension1();
@@ -89,42 +85,42 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::Extension1|method(c0));
self::expect(1, self::Extension1|method(c1));
- self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t3));
+ self::expect(1, let final self::Class1* #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int*} null : self::Extension1|method(#t1));
self::expect(42, self::Extension1|genericMethod<core::int*>(c0, 42));
self::expect(43, self::Extension1|genericMethod<core::num*>(c0, 43));
self::expect(88, self::Extension1|genericMethod<core::int*>(c1, 87));
self::expect(89, self::Extension1|genericMethod<core::num*>(c1, 88));
self::expect(0, self::Extension1|get#property(c0));
- self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t4));
- self::expect(42, self::Extension1|set#property(c0, 42));
+ self::expect(0, let final self::Class1* #t2 = c0 in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension1|get#property(#t2));
+ self::expect(42, let final self::Class1* #t3 = c0 in let final core::int* #t4 = 42 in let final void #t5 = self::Extension1|set#property(#t3, #t4) in #t4);
self::expect(1, self::Extension1|get#property(c1));
- self::expect(87, self::Extension1|set#property(c0, 87));
- self::expect(27, self::Extension1|set#property(c0, self::Extension1|set#property(c1, 27)));
- self::expect(37, self::Extension1|set#property(c1, self::Extension1|set#property(c0, 37)));
- self::expect(77, self::Extension1|set#property(c1, self::Extension1|set#property(c0, self::Extension1|set#property(c1, 77))));
- self::expect(67, self::Extension1|set#property(c0, self::Extension1|set#property(c1, self::Extension1|set#property(c0, 67))));
+ self::expect(87, let final self::Class1* #t6 = c0 in let final core::int* #t7 = 87 in let final void #t8 = self::Extension1|set#property(#t6, #t7) in #t7);
+ self::expect(27, let final self::Class1* #t9 = c0 in let final core::int* #t10 = let final self::Class1* #t11 = c1 in let final core::int* #t12 = 27 in let final void #t13 = self::Extension1|set#property(#t11, #t12) in #t12 in let final void #t14 = self::Extension1|set#property(#t9, #t10) in #t10);
+ self::expect(37, let final self::Class1* #t15 = c1 in let final core::int* #t16 = let final self::Class1* #t17 = c0 in let final core::int* #t18 = 37 in let final void #t19 = self::Extension1|set#property(#t17, #t18) in #t18 in let final void #t20 = self::Extension1|set#property(#t15, #t16) in #t16);
+ self::expect(77, let final self::Class1* #t21 = c1 in let final core::int* #t22 = let final self::Class1* #t23 = c0 in let final core::int* #t24 = let final self::Class1* #t25 = c1 in let final core::int* #t26 = 77 in let final void #t27 = self::Extension1|set#property(#t25, #t26) in #t26 in let final void #t28 = self::Extension1|set#property(#t23, #t24) in #t24 in let final void #t29 = self::Extension1|set#property(#t21, #t22) in #t22);
+ self::expect(67, let final self::Class1* #t30 = c0 in let final core::int* #t31 = let final self::Class1* #t32 = c1 in let final core::int* #t33 = let final self::Class1* #t34 = c0 in let final core::int* #t35 = 67 in let final void #t36 = self::Extension1|set#property(#t34, #t35) in #t35 in let final void #t37 = self::Extension1|set#property(#t32, #t33) in #t33 in let final void #t38 = self::Extension1|set#property(#t30, #t31) in #t31);
}
static method testExtension2() → dynamic {
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::Extension2|method(c0));
- self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t5));
+ self::expect(3, let final self::Class2* #t39 = c0 in #t39.{core::Object::==}(null) ?{core::int*} null : self::Extension2|method(#t39));
self::expect(4, self::Extension2|method(c1));
self::expect(46, self::Extension2|genericMethod<core::int*>(c0, 42));
self::expect(47, self::Extension2|genericMethod<core::num*>(c0, 43));
self::expect(92, self::Extension2|genericMethod<core::int*>(c1, 87));
self::expect(93, self::Extension2|genericMethod<core::num*>(c1, 88));
self::expect(5, self::Extension2|get#property(c0));
- self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t6));
- self::expect(42, self::Extension2|set#property(c0, 42));
+ self::expect(5, let final self::Class2* #t40 = c0 in #t40.{core::Object::==}(null) ?{core::int*} null : self::Extension2|get#property(#t40));
+ self::expect(42, let final self::Class2* #t41 = c0 in let final core::int* #t42 = 42 in let final void #t43 = self::Extension2|set#property(#t41, #t42) in #t42);
self::expect(48, self::Extension2|get#property(c0));
self::expect(6, self::Extension2|get#property(c1));
- self::expect(43, self::Extension2|set#property(c1, 43));
+ self::expect(43, let final self::Class2* #t44 = c1 in let final core::int* #t45 = 43 in let final void #t46 = self::Extension2|set#property(#t44, #t45) in #t45);
self::expect(49, self::Extension2|get#property(c1));
- self::expect(49, self::Extension2|set#property(c0, self::Extension2|get#property(c1)));
- self::expect(55, self::Extension2|set#property(c1, self::Extension2|get#property(c0)));
- self::expect(61, self::Extension2|set#property(c1, self::Extension2|set#property(c0, self::Extension2|get#property(c1))));
- self::expect(67, self::Extension2|set#property(c0, self::Extension2|set#property(c1, self::Extension2|get#property(c0))));
+ self::expect(49, let final self::Class2* #t47 = c0 in let final core::int* #t48 = self::Extension2|get#property(c1) in let final void #t49 = self::Extension2|set#property(#t47, #t48) in #t48);
+ self::expect(55, let final self::Class2* #t50 = c1 in let final core::int* #t51 = self::Extension2|get#property(c0) in let final void #t52 = self::Extension2|set#property(#t50, #t51) in #t51);
+ self::expect(61, let final self::Class2* #t53 = c1 in let final core::int* #t54 = let final self::Class2* #t55 = c0 in let final core::int* #t56 = self::Extension2|get#property(c1) in let final void #t57 = self::Extension2|set#property(#t55, #t56) in #t56 in let final void #t58 = self::Extension2|set#property(#t53, #t54) in #t54);
+ self::expect(67, let final self::Class2* #t59 = c0 in let final core::int* #t60 = let final self::Class2* #t61 = c1 in let final core::int* #t62 = self::Extension2|get#property(c0) in let final void #t63 = self::Extension2|set#property(#t61, #t62) in #t62 in let final void #t64 = self::Extension2|set#property(#t59, #t60) in #t60);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect b/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
index 36c0330..09050c7 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.outline.expect
@@ -37,11 +37,11 @@
static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o]) → self::A1*
;
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
- return <T extends core::Object* = dynamic>([T* o = null]) → self::A1* => self::A2|method3<T*>(#this, o);
+ return <T extends core::Object* = dynamic>([T* o]) → self::A1* => self::A2|method3<T*>(#this, o);
static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o}) → self::A1*
;
static method A2|get#method4(final self::A1* #this) → <T extends core::Object* = dynamic>({o: T*}) →* self::A1*
- return <T extends core::Object* = dynamic>({T* o = null}) → self::A1* => self::A2|method4<T*>(#this, o: o);
+ return <T extends core::Object* = dynamic>({T* o}) → self::A1* => self::A2|method4<T*>(#this, o: o);
static method B2|method1<T extends core::Object* = dynamic>(final self::B1<self::B2|method1::T*>* #this) → self::B1<self::B2|method1::T*>*
;
static method B2|get#method1<T extends core::Object* = dynamic>(final self::B1<self::B2|get#method1::T*>* #this) → () →* self::B1<self::B2|get#method1::T*>*
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
index dfed3fb..5b79a6b 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.expect
@@ -39,13 +39,13 @@
}
static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
core::print(o);
return #this;
}
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
-static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
core::print(o);
return #this;
}
diff --git a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
index dfed3fb..5b79a6b 100644
--- a/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/instance_members.dart.strong.transformed.expect
@@ -39,13 +39,13 @@
}
static method A2|get#method2(final self::A1* #this) → <T extends core::Object* = dynamic>(T*) →* self::A1*
return <T extends core::Object* = dynamic>(T* o) → self::A1* => self::A2|method2<T*>(#this, o);
-static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this = #C1, [self::A2|method3::T* o = #C1]) → self::A1* {
+static method A2|method3<T extends core::Object* = dynamic>(final self::A1* #this, [self::A2|method3::T* o = #C1]) → self::A1* {
core::print(o);
return #this;
}
static method A2|get#method3(final self::A1* #this) → <T extends core::Object* = dynamic>([T*]) →* self::A1*
return <T extends core::Object* = dynamic>([T* o = #C1]) → self::A1* => self::A2|method3<T*>(#this, o);
-static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this = #C1, {self::A2|method4::T* o = #C1}) → self::A1* {
+static method A2|method4<T extends core::Object* = dynamic>(final self::A1* #this, {self::A2|method4::T* o = #C1}) → self::A1* {
core::print(o);
return #this;
}
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart b/pkg/front_end/testcases/extensions/internal_resolution.dart
new file mode 100644
index 0000000..1494e16
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int field;
+}
+
+extension on Class {
+ int get property1 => property2;
+ void set property1(int value) => field = value;
+}
+
+extension on Class {
+ int get property2 => field;
+ void set property2(int value) => property1 = value;
+}
+
+main() {
+ var c = new Class();
+ expect(null, c.property1);
+ expect(null, c.property2);
+ expect(42, c.property1 = 42);
+ expect(42, c.property2);
+ expect(87, c.property2 = 87);
+ expect(87, c.property1);
+}
+
+expect(expected, actual) {
+ if (expected != actual) {
+ throw 'Mismatch: expected=$expected, actual=$actual';
+ }
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect
new file mode 100644
index 0000000..5c9540a
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field;
+ synthetic constructor •() → self::Class*
+ ;
+}
+extension _extension#0 on self::Class* {
+ get property1 = self::_extension#0|get#property1;
+ set property1 = self::_extension#0|set#property1;
+}
+extension _extension#1 on self::Class* {
+ get property2 = self::_extension#1|get#property2;
+ set property2 = self::_extension#1|set#property2;
+}
+static method _extension#0|get#property1(final self::Class* #this) → core::int*
+ ;
+static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+ ;
+static method _extension#1|get#property2(final self::Class* #this) → core::int*
+ ;
+static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+ ;
+static method main() → dynamic
+ ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect
new file mode 100644
index 0000000..0225e55
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension _extension#0 on self::Class* {
+ get property1 = self::_extension#0|get#property1;
+ set property1 = self::_extension#0|set#property1;
+}
+extension _extension#1 on self::Class* {
+ get property2 = self::_extension#1|get#property2;
+ set property2 = self::_extension#1|set#property2;
+}
+static method _extension#0|get#property1(final self::Class* #this) → core::int*
+ return self::_extension#1|get#property2(#this);
+static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+ return #this.{self::Class::field} = value;
+static method _extension#1|get#property2(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+ return let final self::Class* #t1 = #this in let final core::int* #t2 = value in let final void #t3 = self::_extension#0|set#property1(#t1, #t2) in #t2;
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(null, self::_extension#0|get#property1(c));
+ self::expect(null, self::_extension#1|get#property2(c));
+ self::expect(42, let final self::Class* #t4 = c in let final core::int* #t5 = 42 in let final void #t6 = self::_extension#0|set#property1(#t4, #t5) in #t5);
+ self::expect(42, self::_extension#1|get#property2(c));
+ self::expect(87, let final self::Class* #t7 = c in let final core::int* #t8 = 87 in let final void #t9 = self::_extension#1|set#property2(#t7, #t8) in #t8);
+ self::expect(87, self::_extension#0|get#property1(c));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect
new file mode 100644
index 0000000..0225e55
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/internal_resolution.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int* field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+}
+extension _extension#0 on self::Class* {
+ get property1 = self::_extension#0|get#property1;
+ set property1 = self::_extension#0|set#property1;
+}
+extension _extension#1 on self::Class* {
+ get property2 = self::_extension#1|get#property2;
+ set property2 = self::_extension#1|set#property2;
+}
+static method _extension#0|get#property1(final self::Class* #this) → core::int*
+ return self::_extension#1|get#property2(#this);
+static method _extension#0|set#property1(final self::Class* #this, core::int* value) → void
+ return #this.{self::Class::field} = value;
+static method _extension#1|get#property2(final self::Class* #this) → core::int*
+ return #this.{self::Class::field};
+static method _extension#1|set#property2(final self::Class* #this, core::int* value) → void
+ return let final self::Class* #t1 = #this in let final core::int* #t2 = value in let final void #t3 = self::_extension#0|set#property1(#t1, #t2) in #t2;
+static method main() → dynamic {
+ self::Class* c = new self::Class::•();
+ self::expect(null, self::_extension#0|get#property1(c));
+ self::expect(null, self::_extension#1|get#property2(c));
+ self::expect(42, let final self::Class* #t4 = c in let final core::int* #t5 = 42 in let final void #t6 = self::_extension#0|set#property1(#t4, #t5) in #t5);
+ self::expect(42, self::_extension#1|get#property2(c));
+ self::expect(87, let final self::Class* #t7 = c in let final core::int* #t8 = 87 in let final void #t9 = self::_extension#1|set#property2(#t7, #t8) in #t8);
+ self::expect(87, self::_extension#0|get#property1(c));
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+ if(!expected.{core::Object::==}(actual)) {
+ throw "Mismatch: expected=${expected}, actual=${actual}";
+ }
+}
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart b/pkg/front_end/testcases/extensions/null_aware.dart
index d645b13..6b8d908 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart
+++ b/pkg/front_end/testcases/extensions/null_aware.dart
@@ -12,6 +12,12 @@
field = value;
}
int method() => field;
+
+ testImplicitThis() {
+ expect(null, property);
+ expect(42, property ??= 42);
+ expect(42, property ??= 87);
+ }
}
main() {
@@ -20,6 +26,8 @@
expect(null, c?.method);
expect(null, c?.method());
expect(null, c?.property = 42);
+ expect(null, Extension(c)?.property ??= 42);
+
c = new Class();
expect(null, c?.property);
expect(null, c?.method());
@@ -27,9 +35,35 @@
expect(null, tearOff());
expect(42, c?.property = 42);
expect(42, tearOff());
+
expect(null, c?.property = null);
+ expect(42, c?.property = 42);
+
+ c?.property = null;
+ expect(null, c?.property);
expect(42, c.property ??= 42);
expect(42, c.property ??= 87);
+
+ expect(null, c?.property = null);
+ c.property ??= 42;
+ expect(42, c?.property);
+ c.property ??= 87;
+ expect(42, c?.property);
+
+ c?.property = null;
+ expect(null, c?.property);
+ expect(42, Extension(c).property ??= 42);
+ expect(42, Extension(c).property ??= 87);
+
+ c?.property = null;
+ expect(null, c?.property);
+ Extension(c).property ??= 42;
+ expect(42, c?.property);
+ Extension(c).property ??= 87;
+ expect(42, c?.property);
+
+ c?.property = null;
+ c.testImplicitThis();
}
expect(expected, actual) {
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
index 50dde61..3e892cf 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.outline.expect
@@ -11,6 +11,8 @@
get property = self::Extension|get#property;
method method = self::Extension|method;
tearoff method = self::Extension|get#method;
+ method testImplicitThis = self::Extension|testImplicitThis;
+ tearoff testImplicitThis = self::Extension|get#testImplicitThis;
set property = self::Extension|set#property;
}
static method Extension|get#property(final self::Class* #this) → core::int*
@@ -21,6 +23,10 @@
;
static method Extension|get#method(final self::Class* #this) → () →* core::int*
return () → core::int* => self::Extension|method(#this);
+static method Extension|testImplicitThis(final self::Class* #this) → dynamic
+ ;
+static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testImplicitThis(#this);
static method main() → dynamic
;
static method expect(dynamic expected, dynamic actual) → dynamic
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
index 6b4ef8f..6d32899 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.expect
@@ -12,35 +12,63 @@
get property = self::Extension|get#property;
method method = self::Extension|method;
tearoff method = self::Extension|get#method;
+ method testImplicitThis = self::Extension|testImplicitThis;
+ tearoff testImplicitThis = self::Extension|get#testImplicitThis;
set property = self::Extension|set#property;
}
static method Extension|get#property(final self::Class* #this) → core::int*
return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension|set#property(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
static method Extension|method(final self::Class* #this) → core::int*
return #this.{self::Class::field};
static method Extension|get#method(final self::Class* #this) → () →* core::int*
return () → core::int* => self::Extension|method(#this);
+static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
+ self::expect(null, self::Extension|get#property(#this));
+ self::expect(42, let final core::int* #t1 = self::Extension|get#property(#this) in #t1.{core::num::==}(null) ?{core::int*} let final core::int* #t2 = 42 in let final void #t3 = self::Extension|set#property(#this, #t2) in #t2 : #t1);
+ self::expect(42, let final core::int* #t4 = self::Extension|get#property(#this) in #t4.{core::num::==}(null) ?{core::int*} let final core::int* #t5 = 87 in let final void #t6 = self::Extension|set#property(#this, #t5) in #t5 : #t4);
+}
+static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testImplicitThis(#this);
static method main() → dynamic {
self::Class* c;
- self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
- self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
- self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
- self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
+ self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t7));
+ self::expect(null, let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8));
+ self::expect(null, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t9));
+ self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = 42 in let final void #t12 = self::Extension|set#property(#t10, #t11) in #t11);
+ self::expect(null, let final self::Class* #t13 = c in #t13.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} let final core::int* #t15 = 42 in let final void #t16 = self::Extension|set#property(#t13, #t15) in #t15 : #t14);
c = new self::Class::•();
- self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
- self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
- () →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
+ self::expect(null, let final self::Class* #t17 = c in #t17.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t17));
+ self::expect(null, let final self::Class* #t18 = c in #t18.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t18));
+ () →* core::int* tearOff = let final self::Class* #t19 = c in #t19.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t19);
self::expect(null, tearOff.call());
- self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
+ self::expect(42, let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t21 = 42 in let final void #t22 = self::Extension|set#property(#t20, #t21) in #t21);
self::expect(42, tearOff.call());
- self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
- self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
- self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
+ self::expect(null, let final self::Class* #t23 = c in #t23.{core::Object::==}(null) ?{core::Null?} null : let final core::Null? #t24 = null in let final void #t25 = self::Extension|set#property(#t23, #t24) in #t24);
+ self::expect(42, let final self::Class* #t26 = c in #t26.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t27 = 42 in let final void #t28 = self::Extension|set#property(#t26, #t27) in #t27);
+ let final self::Class* #t29 = c in #t29.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t29, null);
+ self::expect(null, let final self::Class* #t30 = c in #t30.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t30));
+ self::expect(42, let final self::Class* #t31 = c in let final core::int* #t32 = self::Extension|get#property(#t31) in #t32.{core::num::==}(null) ?{core::int*} let final self::Class* #t33 = #t31 in let final core::int* #t34 = 42 in let final void #t35 = self::Extension|set#property(#t33, #t34) in #t34 : #t32);
+ self::expect(42, let final self::Class* #t36 = c in let final core::int* #t37 = self::Extension|get#property(#t36) in #t37.{core::num::==}(null) ?{core::int*} let final self::Class* #t38 = #t36 in let final core::int* #t39 = 87 in let final void #t40 = self::Extension|set#property(#t38, #t39) in #t39 : #t37);
+ self::expect(null, let final self::Class* #t41 = c in #t41.{core::Object::==}(null) ?{core::Null?} null : let final core::Null? #t42 = null in let final void #t43 = self::Extension|set#property(#t41, #t42) in #t42);
+ let final self::Class* #t44 = c in self::Extension|get#property(#t44).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t44, 42) : null;
+ self::expect(42, let final self::Class* #t45 = c in #t45.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t45));
+ let final self::Class* #t46 = c in self::Extension|get#property(#t46).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t46, 87) : null;
+ self::expect(42, let final self::Class* #t47 = c in #t47.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t47));
+ let final self::Class* #t48 = c in #t48.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t48, null);
+ self::expect(null, let final self::Class* #t49 = c in #t49.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t49));
+ self::expect(42, let final self::Class* #t50 = c in let final core::int* #t51 = self::Extension|get#property(#t50) in #t51.{core::num::==}(null) ?{core::int*} let final core::int* #t52 = 42 in let final void #t53 = self::Extension|set#property(#t50, #t52) in #t52 : #t51);
+ self::expect(42, let final self::Class* #t54 = c in let final core::int* #t55 = self::Extension|get#property(#t54) in #t55.{core::num::==}(null) ?{core::int*} let final core::int* #t56 = 87 in let final void #t57 = self::Extension|set#property(#t54, #t56) in #t56 : #t55);
+ let final self::Class* #t58 = c in #t58.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t58, null);
+ self::expect(null, let final self::Class* #t59 = c in #t59.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t59));
+ let final self::Class* #t60 = c in self::Extension|get#property(#t60).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t60, 42) : null;
+ self::expect(42, let final self::Class* #t61 = c in #t61.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t61));
+ let final self::Class* #t62 = c in self::Extension|get#property(#t62).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t62, 87) : null;
+ self::expect(42, let final self::Class* #t63 = c in #t63.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t63));
+ let final self::Class* #t64 = c in #t64.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t64, null);
+ self::Extension|testImplicitThis(c);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
index 6b4ef8f..6d32899 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.strong.transformed.expect
@@ -12,35 +12,63 @@
get property = self::Extension|get#property;
method method = self::Extension|method;
tearoff method = self::Extension|get#method;
+ method testImplicitThis = self::Extension|testImplicitThis;
+ tearoff testImplicitThis = self::Extension|get#testImplicitThis;
set property = self::Extension|set#property;
}
static method Extension|get#property(final self::Class* #this) → core::int*
return #this.{self::Class::field};
-static method Extension|set#property(final self::Class* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method Extension|set#property(final self::Class* #this, core::int* value) → void {
#this.{self::Class::field} = value;
- return #t1;
}
static method Extension|method(final self::Class* #this) → core::int*
return #this.{self::Class::field};
static method Extension|get#method(final self::Class* #this) → () →* core::int*
return () → core::int* => self::Extension|method(#this);
+static method Extension|testImplicitThis(final self::Class* #this) → dynamic {
+ self::expect(null, self::Extension|get#property(#this));
+ self::expect(42, let final core::int* #t1 = self::Extension|get#property(#this) in #t1.{core::num::==}(null) ?{core::int*} let final core::int* #t2 = 42 in let final void #t3 = self::Extension|set#property(#this, #t2) in #t2 : #t1);
+ self::expect(42, let final core::int* #t4 = self::Extension|get#property(#this) in #t4.{core::num::==}(null) ?{core::int*} let final core::int* #t5 = 87 in let final void #t6 = self::Extension|set#property(#this, #t5) in #t5 : #t4);
+}
+static method Extension|get#testImplicitThis(final self::Class* #this) → () →* dynamic
+ return () → dynamic => self::Extension|testImplicitThis(#this);
static method main() → dynamic {
self::Class* c;
- self::expect(null, let final self::Class* #t2 = c in #t2.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t2));
- self::expect(null, let final self::Class* #t3 = c in #t3.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t3));
- self::expect(null, let final self::Class* #t4 = c in #t4.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t4));
- self::expect(null, let final self::Class* #t5 = c in #t5.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t5, 42));
+ self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t7));
+ self::expect(null, let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8));
+ self::expect(null, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t9));
+ self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = 42 in let final void #t12 = self::Extension|set#property(#t10, #t11) in #t11);
+ self::expect(null, let final self::Class* #t13 = c in #t13.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} let final core::int* #t15 = 42 in let final void #t16 = self::Extension|set#property(#t13, #t15) in #t15 : #t14);
c = new self::Class::•();
- self::expect(null, let final self::Class* #t6 = c in #t6.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t6));
- self::expect(null, let final self::Class* #t7 = c in #t7.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t7));
- () →* core::int* tearOff = let final self::Class* #t8 = c in #t8.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t8);
+ self::expect(null, let final self::Class* #t17 = c in #t17.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t17));
+ self::expect(null, let final self::Class* #t18 = c in #t18.{core::Object::==}(null) ?{core::int*} null : self::Extension|method(#t18));
+ () →* core::int* tearOff = let final self::Class* #t19 = c in #t19.{core::Object::==}(null) ?{() →* core::int*} null : self::Extension|get#method(#t19);
self::expect(null, tearOff.call());
- self::expect(42, let final self::Class* #t9 = c in #t9.{core::Object::==}(null) ?{core::int*} null : self::Extension|set#property(#t9, 42));
+ self::expect(42, let final self::Class* #t20 = c in #t20.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t21 = 42 in let final void #t22 = self::Extension|set#property(#t20, #t21) in #t21);
self::expect(42, tearOff.call());
- self::expect(null, let final self::Class* #t10 = c in #t10.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t10, null));
- self::expect(42, let final self::Class* #t11 = c in let final core::int* #t12 = self::Extension|get#property(#t11) in #t12.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t11, 42) : #t12);
- self::expect(42, let final self::Class* #t13 = c in let final core::int* #t14 = self::Extension|get#property(#t13) in #t14.{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t13, 87) : #t14);
+ self::expect(null, let final self::Class* #t23 = c in #t23.{core::Object::==}(null) ?{core::Null?} null : let final core::Null? #t24 = null in let final void #t25 = self::Extension|set#property(#t23, #t24) in #t24);
+ self::expect(42, let final self::Class* #t26 = c in #t26.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t27 = 42 in let final void #t28 = self::Extension|set#property(#t26, #t27) in #t27);
+ let final self::Class* #t29 = c in #t29.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t29, null);
+ self::expect(null, let final self::Class* #t30 = c in #t30.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t30));
+ self::expect(42, let final self::Class* #t31 = c in let final core::int* #t32 = self::Extension|get#property(#t31) in #t32.{core::num::==}(null) ?{core::int*} let final self::Class* #t33 = #t31 in let final core::int* #t34 = 42 in let final void #t35 = self::Extension|set#property(#t33, #t34) in #t34 : #t32);
+ self::expect(42, let final self::Class* #t36 = c in let final core::int* #t37 = self::Extension|get#property(#t36) in #t37.{core::num::==}(null) ?{core::int*} let final self::Class* #t38 = #t36 in let final core::int* #t39 = 87 in let final void #t40 = self::Extension|set#property(#t38, #t39) in #t39 : #t37);
+ self::expect(null, let final self::Class* #t41 = c in #t41.{core::Object::==}(null) ?{core::Null?} null : let final core::Null? #t42 = null in let final void #t43 = self::Extension|set#property(#t41, #t42) in #t42);
+ let final self::Class* #t44 = c in self::Extension|get#property(#t44).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t44, 42) : null;
+ self::expect(42, let final self::Class* #t45 = c in #t45.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t45));
+ let final self::Class* #t46 = c in self::Extension|get#property(#t46).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t46, 87) : null;
+ self::expect(42, let final self::Class* #t47 = c in #t47.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t47));
+ let final self::Class* #t48 = c in #t48.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t48, null);
+ self::expect(null, let final self::Class* #t49 = c in #t49.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t49));
+ self::expect(42, let final self::Class* #t50 = c in let final core::int* #t51 = self::Extension|get#property(#t50) in #t51.{core::num::==}(null) ?{core::int*} let final core::int* #t52 = 42 in let final void #t53 = self::Extension|set#property(#t50, #t52) in #t52 : #t51);
+ self::expect(42, let final self::Class* #t54 = c in let final core::int* #t55 = self::Extension|get#property(#t54) in #t55.{core::num::==}(null) ?{core::int*} let final core::int* #t56 = 87 in let final void #t57 = self::Extension|set#property(#t54, #t56) in #t56 : #t55);
+ let final self::Class* #t58 = c in #t58.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t58, null);
+ self::expect(null, let final self::Class* #t59 = c in #t59.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t59));
+ let final self::Class* #t60 = c in self::Extension|get#property(#t60).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t60, 42) : null;
+ self::expect(42, let final self::Class* #t61 = c in #t61.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t61));
+ let final self::Class* #t62 = c in self::Extension|get#property(#t62).{core::num::==}(null) ?{core::int*} self::Extension|set#property(#t62, 87) : null;
+ self::expect(42, let final self::Class* #t63 = c in #t63.{core::Object::==}(null) ?{core::int*} null : self::Extension|get#property(#t63));
+ let final self::Class* #t64 = c in #t64.{core::Object::==}(null) ?{core::Null?} null : self::Extension|set#property(#t64, null);
+ self::Extension|testImplicitThis(c);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect b/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect
index dee5817..5534d1b 100644
--- a/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/extensions/null_aware.dart.type_promotion.expect
@@ -1,3 +1,3 @@
-pkg/front_end/testcases/extensions/null_aware.dart:23:5: Context: Write to c@408
+pkg/front_end/testcases/extensions/null_aware.dart:31:5: Context: Write to c@530
c = new Class();
^
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart b/pkg/front_end/testcases/extensions/on_function_type.dart
new file mode 100644
index 0000000..b3e30d2
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, 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.
+
+extension<R, T> on R Function(T) {
+ Type get returnType => R;
+ Type get parameterType => T;
+}
+
+class Class<T extends Class<T>> {}
+
+class Subclass extends Class<Subclass> {}
+
+extension<T extends Class<T>> on dynamic Function<S extends T>(T, S) {
+ Type get parameterType => T;
+}
+
+main() {
+ int local1(int i) => i;
+
+ print(local1.returnType);
+ print(local1.parameterType);
+
+ Subclass local2<S extends Subclass>(Subclass a, S b) => a;
+
+ print(local2.parameterType);
+}
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect
new file mode 100644
index 0000000..b83d5f5
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.outline.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends self::Class<self::Class::T*>* = self::Class<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::Class<self::Class::T*>*
+ ;
+}
+class Subclass extends self::Class<self::Subclass*> {
+ synthetic constructor •() → self::Subclass*
+ ;
+}
+extension _extension#0<R extends core::Object* = dynamic, T extends core::Object* = dynamic> on (T*) →* R* {
+ get returnType = self::_extension#0|get#returnType;
+ get parameterType = self::_extension#0|get#parameterType;
+}
+extension _extension#1<T extends self::Class<T*>* = dynamic> on <S extends T* = dynamic>(T*, S*) →* dynamic {
+ get parameterType = self::_extension#1|get#parameterType;
+}
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+ ;
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+ ;
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = dynamic>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect
new file mode 100644
index 0000000..c4d4880
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends self::Class<self::Class::T*>* = self::Class<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::Class<self::Class::T*>*
+ : super core::Object::•()
+ ;
+}
+class Subclass extends self::Class<self::Subclass*> {
+ synthetic constructor •() → self::Subclass*
+ : super self::Class::•()
+ ;
+}
+extension _extension#0<R extends core::Object* = dynamic, T extends core::Object* = dynamic> on (T*) →* R* {
+ get returnType = self::_extension#0|get#returnType;
+ get parameterType = self::_extension#0|get#parameterType;
+}
+extension _extension#1<T extends self::Class<T*>* = dynamic> on <S extends T* = dynamic>(T*, S*) →* dynamic {
+ get parameterType = self::_extension#1|get#parameterType;
+}
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+ return self::_extension#0|get#returnType::R*;
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+ return self::_extension#0|get#parameterType::T*;
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = dynamic>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+ return self::_extension#1|get#parameterType::T*;
+static method main() → dynamic {
+ function local1(core::int* i) → core::int*
+ return i;
+ core::print(self::_extension#0|get#returnType<core::int*, core::int*>(local1));
+ core::print(self::_extension#0|get#parameterType<core::int*, core::int*>(local1));
+ function local2<S extends self::Subclass* = self::Subclass*>(self::Subclass* a, S* b) → self::Subclass*
+ return a;
+ core::print(self::_extension#1|get#parameterType<self::Subclass*>(local2));
+}
diff --git a/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..c4d4880
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/on_function_type.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class<T extends self::Class<self::Class::T*>* = self::Class<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::Class<self::Class::T*>*
+ : super core::Object::•()
+ ;
+}
+class Subclass extends self::Class<self::Subclass*> {
+ synthetic constructor •() → self::Subclass*
+ : super self::Class::•()
+ ;
+}
+extension _extension#0<R extends core::Object* = dynamic, T extends core::Object* = dynamic> on (T*) →* R* {
+ get returnType = self::_extension#0|get#returnType;
+ get parameterType = self::_extension#0|get#parameterType;
+}
+extension _extension#1<T extends self::Class<T*>* = dynamic> on <S extends T* = dynamic>(T*, S*) →* dynamic {
+ get parameterType = self::_extension#1|get#parameterType;
+}
+static method _extension#0|get#returnType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#returnType::T*) →* self::_extension#0|get#returnType::R* #this) → core::Type*
+ return self::_extension#0|get#returnType::R*;
+static method _extension#0|get#parameterType<R extends core::Object* = dynamic, T extends core::Object* = dynamic>(final (self::_extension#0|get#parameterType::T*) →* self::_extension#0|get#parameterType::R* #this) → core::Type*
+ return self::_extension#0|get#parameterType::T*;
+static method _extension#1|get#parameterType<T extends self::Class<self::_extension#1|get#parameterType::T*>* = dynamic>(final <S extends self::_extension#1|get#parameterType::T* = dynamic>(self::_extension#1|get#parameterType::T*, S*) →* dynamic #this) → core::Type*
+ return self::_extension#1|get#parameterType::T*;
+static method main() → dynamic {
+ function local1(core::int* i) → core::int*
+ return i;
+ core::print(self::_extension#0|get#returnType<core::int*, core::int*>(local1));
+ core::print(self::_extension#0|get#parameterType<core::int*, core::int*>(local1));
+ function local2<S extends self::Subclass* = self::Subclass*>(self::Subclass* a, S* b) → self::Subclass*
+ return a;
+ core::print(self::_extension#1|get#parameterType<self::Subclass*>(local2));
+}
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
index f788aff..157b936 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.expect
@@ -73,10 +73,7 @@
return () → self::Extension|get#method::T* => self::Extension|method<self::Extension|get#method::T*>(#this);
static method Extension|get#property<T extends self::Struct* = dynamic>(final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
return #this;
-static method Extension|set#property<T extends self::Struct* = dynamic>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → self::Extension|set#property::T* {
- final self::Extension|set#property::T* #t1 = value;
- return #t1;
-}
+static method Extension|set#property<T extends self::Struct* = dynamic>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
static method main() → dynamic {
self::Struct* struct;
self::StructA* structA;
diff --git a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
index f788aff..157b936 100644
--- a/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/on_type_variable_inference.dart.strong.transformed.expect
@@ -73,10 +73,7 @@
return () → self::Extension|get#method::T* => self::Extension|method<self::Extension|get#method::T*>(#this);
static method Extension|get#property<T extends self::Struct* = dynamic>(final self::Extension|get#property::T* #this) → self::Extension|get#property::T*
return #this;
-static method Extension|set#property<T extends self::Struct* = dynamic>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → self::Extension|set#property::T* {
- final self::Extension|set#property::T* #t1 = value;
- return #t1;
-}
+static method Extension|set#property<T extends self::Struct* = dynamic>(final self::Extension|set#property::T* #this, self::Extension|set#property::T* value) → void {}
static method main() → dynamic {
self::Struct* struct;
self::StructA* structA;
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart b/pkg/front_end/testcases/extensions/other_kinds.dart
index 21e21b4..1958166 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart
@@ -22,12 +22,18 @@
setInstanceField(value);
}
- // TODO(johnniwinther): Test operator -() and operator -(val).
-
int operator +(int value) {
return getInstanceField() + value;
}
+ int operator -(int value) {
+ return getInstanceField() - value;
+ }
+
+ int operator -() {
+ return -getInstanceField();
+ }
+
static int staticField = A1.getStaticField();
static int get staticProperty => A1.getStaticField();
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
index 48438c1..964d48f 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.outline.expect
@@ -19,6 +19,8 @@
extension A2 on self::A1* {
get instanceProperty = self::A2|get#instanceProperty;
operator + = self::A2|+;
+ operator - = self::A2|-;
+ operator unary- = self::A2|unary-;
static field staticField = self::A2|staticField;
static get staticProperty = get self::A2|staticProperty;
set instanceProperty = self::A2|set#instanceProperty;
@@ -31,6 +33,10 @@
;
static method A2|+(final self::A1* #this, core::int* value) → core::int*
;
+static method A2|-(final self::A1* #this, core::int* value) → core::int*
+ ;
+static method A2|unary-(final self::A1* #this) → core::int*
+ ;
static get A2|staticProperty() → core::int*
;
static set A2|staticProperty(core::int* value) → void
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
index 4c4e60c..b4b386a 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.expect
@@ -22,6 +22,8 @@
extension A2 on self::A1* {
get instanceProperty = self::A2|get#instanceProperty;
operator + = self::A2|+;
+ operator - = self::A2|-;
+ operator unary- = self::A2|unary-;
static field staticField = self::A2|staticField;
static get staticProperty = get self::A2|staticProperty;
set instanceProperty = self::A2|set#instanceProperty;
@@ -30,14 +32,18 @@
static field core::int* A2|staticField = self::A1::getStaticField();
static method A2|get#instanceProperty(final self::A1* #this) → core::int*
return #this.{self::A1::getInstanceField}();
-static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
#this.{self::A1::setInstanceField}(value);
- return #t1;
}
static method A2|+(final self::A1* #this, core::int* value) → core::int* {
return #this.{self::A1::getInstanceField}().{core::num::+}(value);
}
+static method A2|-(final self::A1* #this, core::int* value) → core::int* {
+ return #this.{self::A1::getInstanceField}().{core::num::-}(value);
+}
+static method A2|unary-(final self::A1* #this) → core::int* {
+ return #this.{self::A1::getInstanceField}().{core::int::unary-}();
+}
static get A2|staticProperty() → core::int*
return self::A1::getStaticField();
static set A2|staticProperty(core::int* value) → void {
diff --git a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
index 4c4e60c..b4b386a 100644
--- a/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/other_kinds.dart.strong.transformed.expect
@@ -22,6 +22,8 @@
extension A2 on self::A1* {
get instanceProperty = self::A2|get#instanceProperty;
operator + = self::A2|+;
+ operator - = self::A2|-;
+ operator unary- = self::A2|unary-;
static field staticField = self::A2|staticField;
static get staticProperty = get self::A2|staticProperty;
set instanceProperty = self::A2|set#instanceProperty;
@@ -30,14 +32,18 @@
static field core::int* A2|staticField = self::A1::getStaticField();
static method A2|get#instanceProperty(final self::A1* #this) → core::int*
return #this.{self::A1::getInstanceField}();
-static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method A2|set#instanceProperty(final self::A1* #this, core::int* value) → void {
#this.{self::A1::setInstanceField}(value);
- return #t1;
}
static method A2|+(final self::A1* #this, core::int* value) → core::int* {
return #this.{self::A1::getInstanceField}().{core::num::+}(value);
}
+static method A2|-(final self::A1* #this, core::int* value) → core::int* {
+ return #this.{self::A1::getInstanceField}().{core::num::-}(value);
+}
+static method A2|unary-(final self::A1* #this) → core::int* {
+ return #this.{self::A1::getInstanceField}().{core::int::unary-}();
+}
static get A2|staticProperty() → core::int*
return self::A1::getStaticField();
static set A2|staticProperty(core::int* value) → void {
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
index 9c616d4..b5659e5 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.expect
@@ -29,10 +29,7 @@
return () → dynamic => self::Extension|instanceMethod(#this);
static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
- return #t1;
-}
+static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
static method main() → dynamic {
self::Extension|method();
self::Extension|genericMethod<core::int*>(42);
diff --git a/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
index 9c616d4..b5659e5 100644
--- a/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/static_access.dart.strong.transformed.expect
@@ -29,10 +29,7 @@
return () → dynamic => self::Extension|instanceMethod(#this);
static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
- return #t1;
-}
+static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
static method main() → dynamic {
self::Extension|method();
self::Extension|genericMethod<core::int*>(42);
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
index 10c2dbb..5ad2d40 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.expect
@@ -37,10 +37,7 @@
return () → dynamic => self::Extension|instanceMethod(#this);
static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
- return #t1;
-}
+static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/extensions/static_access_of_instance.dart:14:13: Error: Method not found: 'Extension.instanceMethod'.
Extension.instanceMethod();
diff --git a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
index 10c2dbb..5ad2d40 100644
--- a/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/static_access_of_instance.dart.strong.transformed.expect
@@ -37,10 +37,7 @@
return () → dynamic => self::Extension|instanceMethod(#this);
static method Extension|get#instanceProperty(final self::Class* #this) → dynamic
return 42;
-static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → dynamic {
- final dynamic #t1 = value;
- return #t1;
-}
+static method Extension|set#instanceProperty(final self::Class* #this, dynamic value) → void {}
static method main() → dynamic {
invalid-expression "pkg/front_end/testcases/extensions/static_access_of_instance.dart:14:13: Error: Method not found: 'Extension.instanceMethod'.
Extension.instanceMethod();
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
index ec79050..ee67c10 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.expect
@@ -50,12 +50,10 @@
core::print("Extension1.property get on ${#this}");
return #this.{self::Class1::field};
}
-static method _extension#0|set#property(final self::Class1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void {
#this.{self::Class1::field} = value;
core::print("Extension1.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
- return #t1;
}
static method _extension#1|method(final self::Class2* #this) → core::int* {
core::print("Extension2.method on ${#this}");
@@ -73,12 +71,10 @@
core::print("Extension2.property get on ${#this}");
return #this.{self::Class2::field}.{core::num::+}(5);
}
-static method _extension#1|set#property(final self::Class2* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void {
core::print("Extension2.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
#this.{self::Class2::field} = value;
- return #t2;
}
static method main() → dynamic {
self::testExtension1();
@@ -89,42 +85,42 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::_extension#0|method(c0));
self::expect(1, self::_extension#0|method(c1));
- self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t3));
+ self::expect(1, let final self::Class1* #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t1));
self::expect(42, self::_extension#0|genericMethod<core::int*>(c0, 42));
self::expect(43, self::_extension#0|genericMethod<core::num*>(c0, 43));
self::expect(88, self::_extension#0|genericMethod<core::int*>(c1, 87));
self::expect(89, self::_extension#0|genericMethod<core::num*>(c1, 88));
self::expect(0, self::_extension#0|get#property(c0));
- self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t4));
- self::expect(42, self::_extension#0|set#property(c0, 42));
+ self::expect(0, let final self::Class1* #t2 = c0 in #t2.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t2));
+ self::expect(42, let final self::Class1* #t3 = c0 in let final core::int* #t4 = 42 in let final void #t5 = self::_extension#0|set#property(#t3, #t4) in #t4);
self::expect(1, self::_extension#0|get#property(c1));
- self::expect(87, self::_extension#0|set#property(c0, 87));
- self::expect(27, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 27)));
- self::expect(37, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 37)));
- self::expect(77, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 77))));
- self::expect(67, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 67))));
+ self::expect(87, let final self::Class1* #t6 = c0 in let final core::int* #t7 = 87 in let final void #t8 = self::_extension#0|set#property(#t6, #t7) in #t7);
+ self::expect(27, let final self::Class1* #t9 = c0 in let final core::int* #t10 = let final self::Class1* #t11 = c1 in let final core::int* #t12 = 27 in let final void #t13 = self::_extension#0|set#property(#t11, #t12) in #t12 in let final void #t14 = self::_extension#0|set#property(#t9, #t10) in #t10);
+ self::expect(37, let final self::Class1* #t15 = c1 in let final core::int* #t16 = let final self::Class1* #t17 = c0 in let final core::int* #t18 = 37 in let final void #t19 = self::_extension#0|set#property(#t17, #t18) in #t18 in let final void #t20 = self::_extension#0|set#property(#t15, #t16) in #t16);
+ self::expect(77, let final self::Class1* #t21 = c1 in let final core::int* #t22 = let final self::Class1* #t23 = c0 in let final core::int* #t24 = let final self::Class1* #t25 = c1 in let final core::int* #t26 = 77 in let final void #t27 = self::_extension#0|set#property(#t25, #t26) in #t26 in let final void #t28 = self::_extension#0|set#property(#t23, #t24) in #t24 in let final void #t29 = self::_extension#0|set#property(#t21, #t22) in #t22);
+ self::expect(67, let final self::Class1* #t30 = c0 in let final core::int* #t31 = let final self::Class1* #t32 = c1 in let final core::int* #t33 = let final self::Class1* #t34 = c0 in let final core::int* #t35 = 67 in let final void #t36 = self::_extension#0|set#property(#t34, #t35) in #t35 in let final void #t37 = self::_extension#0|set#property(#t32, #t33) in #t33 in let final void #t38 = self::_extension#0|set#property(#t30, #t31) in #t31);
}
static method testExtension2() → dynamic {
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::_extension#1|method(c0));
- self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t5));
+ self::expect(3, let final self::Class2* #t39 = c0 in #t39.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t39));
self::expect(4, self::_extension#1|method(c1));
self::expect(46, self::_extension#1|genericMethod<core::int*>(c0, 42));
self::expect(47, self::_extension#1|genericMethod<core::num*>(c0, 43));
self::expect(92, self::_extension#1|genericMethod<core::int*>(c1, 87));
self::expect(93, self::_extension#1|genericMethod<core::num*>(c1, 88));
self::expect(5, self::_extension#1|get#property(c0));
- self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t6));
- self::expect(42, self::_extension#1|set#property(c0, 42));
+ self::expect(5, let final self::Class2* #t40 = c0 in #t40.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t40));
+ self::expect(42, let final self::Class2* #t41 = c0 in let final core::int* #t42 = 42 in let final void #t43 = self::_extension#1|set#property(#t41, #t42) in #t42);
self::expect(48, self::_extension#1|get#property(c0));
self::expect(6, self::_extension#1|get#property(c1));
- self::expect(43, self::_extension#1|set#property(c1, 43));
+ self::expect(43, let final self::Class2* #t44 = c1 in let final core::int* #t45 = 43 in let final void #t46 = self::_extension#1|set#property(#t44, #t45) in #t45);
self::expect(49, self::_extension#1|get#property(c1));
- self::expect(49, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1)));
- self::expect(55, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0)));
- self::expect(61, self::_extension#1|set#property(c1, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1))));
- self::expect(67, self::_extension#1|set#property(c0, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0))));
+ self::expect(49, let final self::Class2* #t47 = c0 in let final core::int* #t48 = self::_extension#1|get#property(c1) in let final void #t49 = self::_extension#1|set#property(#t47, #t48) in #t48);
+ self::expect(55, let final self::Class2* #t50 = c1 in let final core::int* #t51 = self::_extension#1|get#property(c0) in let final void #t52 = self::_extension#1|set#property(#t50, #t51) in #t51);
+ self::expect(61, let final self::Class2* #t53 = c1 in let final core::int* #t54 = let final self::Class2* #t55 = c0 in let final core::int* #t56 = self::_extension#1|get#property(c1) in let final void #t57 = self::_extension#1|set#property(#t55, #t56) in #t56 in let final void #t58 = self::_extension#1|set#property(#t53, #t54) in #t54);
+ self::expect(67, let final self::Class2* #t59 = c0 in let final core::int* #t60 = let final self::Class2* #t61 = c1 in let final core::int* #t62 = self::_extension#1|get#property(c0) in let final void #t63 = self::_extension#1|set#property(#t61, #t62) in #t62 in let final void #t64 = self::_extension#1|set#property(#t59, #t60) in #t60);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
index ec79050..ee67c10 100644
--- a/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/unnamed_extensions.dart.strong.transformed.expect
@@ -50,12 +50,10 @@
core::print("Extension1.property get on ${#this}");
return #this.{self::Class1::field};
}
-static method _extension#0|set#property(final self::Class1* #this, core::int* value) → core::int* {
- final core::int* #t1 = value;
+static method _extension#0|set#property(final self::Class1* #this, core::int* value) → void {
#this.{self::Class1::field} = value;
core::print("Extension1.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
- return #t1;
}
static method _extension#1|method(final self::Class2* #this) → core::int* {
core::print("Extension2.method on ${#this}");
@@ -73,12 +71,10 @@
core::print("Extension2.property get on ${#this}");
return #this.{self::Class2::field}.{core::num::+}(5);
}
-static method _extension#1|set#property(final self::Class2* #this, core::int* value) → core::int* {
- final core::int* #t2 = value;
+static method _extension#1|set#property(final self::Class2* #this, core::int* value) → void {
core::print("Extension2.property set(${value}) on ${#this}");
value = value.{core::num::+}(1);
#this.{self::Class2::field} = value;
- return #t2;
}
static method main() → dynamic {
self::testExtension1();
@@ -89,42 +85,42 @@
self::Class1* c1 = new self::Class1::•(1);
self::expect(0, self::_extension#0|method(c0));
self::expect(1, self::_extension#0|method(c1));
- self::expect(1, let final self::Class1* #t3 = c1 in #t3.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t3));
+ self::expect(1, let final self::Class1* #t1 = c1 in #t1.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|method(#t1));
self::expect(42, self::_extension#0|genericMethod<core::int*>(c0, 42));
self::expect(43, self::_extension#0|genericMethod<core::num*>(c0, 43));
self::expect(88, self::_extension#0|genericMethod<core::int*>(c1, 87));
self::expect(89, self::_extension#0|genericMethod<core::num*>(c1, 88));
self::expect(0, self::_extension#0|get#property(c0));
- self::expect(0, let final self::Class1* #t4 = c0 in #t4.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t4));
- self::expect(42, self::_extension#0|set#property(c0, 42));
+ self::expect(0, let final self::Class1* #t2 = c0 in #t2.{core::Object::==}(null) ?{core::int*} null : self::_extension#0|get#property(#t2));
+ self::expect(42, let final self::Class1* #t3 = c0 in let final core::int* #t4 = 42 in let final void #t5 = self::_extension#0|set#property(#t3, #t4) in #t4);
self::expect(1, self::_extension#0|get#property(c1));
- self::expect(87, self::_extension#0|set#property(c0, 87));
- self::expect(27, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 27)));
- self::expect(37, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 37)));
- self::expect(77, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, 77))));
- self::expect(67, self::_extension#0|set#property(c0, self::_extension#0|set#property(c1, self::_extension#0|set#property(c0, 67))));
+ self::expect(87, let final self::Class1* #t6 = c0 in let final core::int* #t7 = 87 in let final void #t8 = self::_extension#0|set#property(#t6, #t7) in #t7);
+ self::expect(27, let final self::Class1* #t9 = c0 in let final core::int* #t10 = let final self::Class1* #t11 = c1 in let final core::int* #t12 = 27 in let final void #t13 = self::_extension#0|set#property(#t11, #t12) in #t12 in let final void #t14 = self::_extension#0|set#property(#t9, #t10) in #t10);
+ self::expect(37, let final self::Class1* #t15 = c1 in let final core::int* #t16 = let final self::Class1* #t17 = c0 in let final core::int* #t18 = 37 in let final void #t19 = self::_extension#0|set#property(#t17, #t18) in #t18 in let final void #t20 = self::_extension#0|set#property(#t15, #t16) in #t16);
+ self::expect(77, let final self::Class1* #t21 = c1 in let final core::int* #t22 = let final self::Class1* #t23 = c0 in let final core::int* #t24 = let final self::Class1* #t25 = c1 in let final core::int* #t26 = 77 in let final void #t27 = self::_extension#0|set#property(#t25, #t26) in #t26 in let final void #t28 = self::_extension#0|set#property(#t23, #t24) in #t24 in let final void #t29 = self::_extension#0|set#property(#t21, #t22) in #t22);
+ self::expect(67, let final self::Class1* #t30 = c0 in let final core::int* #t31 = let final self::Class1* #t32 = c1 in let final core::int* #t33 = let final self::Class1* #t34 = c0 in let final core::int* #t35 = 67 in let final void #t36 = self::_extension#0|set#property(#t34, #t35) in #t35 in let final void #t37 = self::_extension#0|set#property(#t32, #t33) in #t33 in let final void #t38 = self::_extension#0|set#property(#t30, #t31) in #t31);
}
static method testExtension2() → dynamic {
self::Class2* c0 = new self::Class2::•(0);
self::Class2* c1 = new self::Class2::•(1);
self::expect(3, self::_extension#1|method(c0));
- self::expect(3, let final self::Class2* #t5 = c0 in #t5.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t5));
+ self::expect(3, let final self::Class2* #t39 = c0 in #t39.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|method(#t39));
self::expect(4, self::_extension#1|method(c1));
self::expect(46, self::_extension#1|genericMethod<core::int*>(c0, 42));
self::expect(47, self::_extension#1|genericMethod<core::num*>(c0, 43));
self::expect(92, self::_extension#1|genericMethod<core::int*>(c1, 87));
self::expect(93, self::_extension#1|genericMethod<core::num*>(c1, 88));
self::expect(5, self::_extension#1|get#property(c0));
- self::expect(5, let final self::Class2* #t6 = c0 in #t6.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t6));
- self::expect(42, self::_extension#1|set#property(c0, 42));
+ self::expect(5, let final self::Class2* #t40 = c0 in #t40.{core::Object::==}(null) ?{core::int*} null : self::_extension#1|get#property(#t40));
+ self::expect(42, let final self::Class2* #t41 = c0 in let final core::int* #t42 = 42 in let final void #t43 = self::_extension#1|set#property(#t41, #t42) in #t42);
self::expect(48, self::_extension#1|get#property(c0));
self::expect(6, self::_extension#1|get#property(c1));
- self::expect(43, self::_extension#1|set#property(c1, 43));
+ self::expect(43, let final self::Class2* #t44 = c1 in let final core::int* #t45 = 43 in let final void #t46 = self::_extension#1|set#property(#t44, #t45) in #t45);
self::expect(49, self::_extension#1|get#property(c1));
- self::expect(49, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1)));
- self::expect(55, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0)));
- self::expect(61, self::_extension#1|set#property(c1, self::_extension#1|set#property(c0, self::_extension#1|get#property(c1))));
- self::expect(67, self::_extension#1|set#property(c0, self::_extension#1|set#property(c1, self::_extension#1|get#property(c0))));
+ self::expect(49, let final self::Class2* #t47 = c0 in let final core::int* #t48 = self::_extension#1|get#property(c1) in let final void #t49 = self::_extension#1|set#property(#t47, #t48) in #t48);
+ self::expect(55, let final self::Class2* #t50 = c1 in let final core::int* #t51 = self::_extension#1|get#property(c0) in let final void #t52 = self::_extension#1|set#property(#t50, #t51) in #t51);
+ self::expect(61, let final self::Class2* #t53 = c1 in let final core::int* #t54 = let final self::Class2* #t55 = c0 in let final core::int* #t56 = self::_extension#1|get#property(c1) in let final void #t57 = self::_extension#1|set#property(#t55, #t56) in #t56 in let final void #t58 = self::_extension#1|set#property(#t53, #t54) in #t54);
+ self::expect(67, let final self::Class2* #t59 = c0 in let final core::int* #t60 = let final self::Class2* #t61 = c1 in let final core::int* #t62 = self::_extension#1|get#property(c0) in let final void #t63 = self::_extension#1|set#property(#t61, #t62) in #t62 in let final void #t64 = self::_extension#1|set#property(#t59, #t60) in #t60);
}
static method expect(dynamic expected, dynamic actual) → dynamic {
if(!expected.{core::Object::==}(actual)) {
diff --git a/pkg/front_end/testcases/general/accessors.dart.strong.expect b/pkg/front_end/testcases/general/accessors.dart.strong.expect
index efe4a1c..1265410 100644
--- a/pkg/front_end/testcases/general/accessors.dart.strong.expect
+++ b/pkg/front_end/testcases/general/accessors.dart.strong.expect
@@ -2,20 +2,12 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/general/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
-// print(onlySetter);
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
// print(onlySetter);
// ^^^^^^^^^^
//
-// pkg/front_end/testcases/general/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
-// print(onlySetter);
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
diff --git a/pkg/front_end/testcases/general/accessors.dart.strong.transformed.expect b/pkg/front_end/testcases/general/accessors.dart.strong.transformed.expect
index efe4a1c..1265410 100644
--- a/pkg/front_end/testcases/general/accessors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/accessors.dart.strong.transformed.expect
@@ -2,20 +2,12 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/general/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
-// print(onlySetter);
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
// print(onlySetter);
// ^^^^^^^^^^
//
-// pkg/front_end/testcases/general/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
-// print(onlySetter);
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/general/accessors.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.outline.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.outline.expect
index 737b3a9..7949f03 100644
--- a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.outline.expect
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.outline.expect
@@ -113,8 +113,8 @@
import self as self;
import "dart:core" as core;
-typedef ContravariantUse<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef InvariantUse<T extends core::Object* = dynamic> = (T*) →* T*;
+typedef ContravariantUse<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef InvariantUse<invariant T extends core::Object* = dynamic> = (T*) →* T*;
class Empty extends core::Object {
synthetic constructor •() → self::Empty*
;
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.expect
index 133519d..efccee2 100644
--- a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.expect
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.expect
@@ -113,8 +113,8 @@
import self as self;
import "dart:core" as core;
-typedef ContravariantUse<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef InvariantUse<T extends core::Object* = dynamic> = (T*) →* T*;
+typedef ContravariantUse<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef InvariantUse<invariant T extends core::Object* = dynamic> = (T*) →* T*;
class Empty extends core::Object {
synthetic constructor •() → self::Empty*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.transformed.expect
index cf5fe36..8a0566b 100644
--- a/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bad_type_variable_uses_in_supertypes.dart.strong.transformed.expect
@@ -113,8 +113,8 @@
import self as self;
import "dart:core" as core;
-typedef ContravariantUse<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef InvariantUse<T extends core::Object* = dynamic> = (T*) →* T*;
+typedef ContravariantUse<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef InvariantUse<invariant T extends core::Object* = dynamic> = (T*) →* T*;
class Empty extends core::Object {
synthetic constructor •() → self::Empty*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/bug32629.dart.outline.expect b/pkg/front_end/testcases/general/bug32629.dart.outline.expect
index 742088c..4c03145 100644
--- a/pkg/front_end/testcases/general/bug32629.dart.outline.expect
+++ b/pkg/front_end/testcases/general/bug32629.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Reducer<S extends core::Object* = dynamic> = (S*, dynamic) →* S*;
+typedef Reducer<invariant S extends core::Object* = dynamic> = (S*, dynamic) →* S*;
class A extends core::Object {
synthetic constructor •() → self::A*
;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
index a7c5eb0..c0c603a 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
@@ -1208,10 +1208,10 @@
core::Map<dynamic, dynamic>* map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
- core::Map<<BottomType>, core::Null?>* map12 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+ core::Map<dynamic, core::Null?>* map12 = <dynamic, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
^": null};
- core::Map<<BottomType>, core::Null?>* map13 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+ core::Map<dynamic, core::Null?>* map13 = <dynamic, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
core::List<core::int*>* list20 = block {
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 5cc5798..27878cb 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -1208,10 +1208,10 @@
core::Map<dynamic, dynamic>* map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
- core::Map<<BottomType>, core::Null?>* map12 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+ core::Map<dynamic, core::Null?>* map12 = <dynamic, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
^": null};
- core::Map<<BottomType>, core::Null?>* map13 = <<BottomType>, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+ core::Map<dynamic, core::Null?>* map13 = <dynamic, core::Null?>{invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
^": null};
core::List<core::int*>* list20 = block {
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.outline.expect b/pkg/front_end/testcases/general/covariant_generic.dart.outline.expect
index a516d86..830c5bd 100644
--- a/pkg/front_end/testcases/general/covariant_generic.dart.outline.expect
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Callback<T extends core::Object* = dynamic> = (T*) →* void;
+typedef Callback<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class Foo<T extends core::Object* = dynamic> extends core::Object {
final field self::Foo::T* finalField;
final field (self::Foo::T*) →* void callbackField;
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect b/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
index 684ab99..d794499 100644
--- a/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Callback<T extends core::Object* = dynamic> = (T*) →* void;
+typedef Callback<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class Foo<T extends core::Object* = dynamic> extends core::Object {
final field self::Foo::T* finalField;
final field (self::Foo::T*) →* void callbackField;
diff --git a/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
index 684ab99..d794499 100644
--- a/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/covariant_generic.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Callback<T extends core::Object* = dynamic> = (T*) →* void;
+typedef Callback<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class Foo<T extends core::Object* = dynamic> extends core::Object {
final field self::Foo::T* finalField;
final field (self::Foo::T*) →* void callbackField;
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart b/pkg/front_end/testcases/general/error_locations/error_location_05.dart
new file mode 100644
index 0000000..98a013d
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2019, 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.
+
+library error_location_05;
+
+part 'error_location_05_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.outline.expect
new file mode 100644
index 0000000..ee7a72e
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.outline.expect
@@ -0,0 +1,18 @@
+library error_location_05;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+import self as self;
+
+part error_location_05_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x1(dynamic z, {dynamic z}) → dynamic
+ ;
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x2() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.expect
new file mode 100644
index 0000000..b4a23c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.expect
@@ -0,0 +1,30 @@
+library error_location_05;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:10:9: Error: 'z' is already declared in this scope.
+// y(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:10:5: Context: Previous declaration of 'z'.
+// y(z, {z}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+part error_location_05_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x1(dynamic z = #C1, {dynamic z = #C1}) → dynamic {}
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x2() → dynamic {
+ function y(dynamic z, {dynamic z = #C1}) → core::Null? {}
+}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.transformed.expect
new file mode 100644
index 0000000..b4a23c0
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library error_location_05;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:7:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:10:9: Error: 'z' is already declared in this scope.
+// y(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart:10:5: Context: Previous declaration of 'z'.
+// y(z, {z}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+part error_location_05_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x1(dynamic z = #C1, {dynamic z = #C1}) → dynamic {}
+static method /* from org-dartlang-testcase:///error_location_05_lib1.dart */ x2() → dynamic {
+ function y(dynamic z, {dynamic z = #C1}) → core::Null? {}
+}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart b/pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart
new file mode 100644
index 0000000..f896142
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_05_lib1.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2019, 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.
+
+part of error_location_05;
+
+x1(z, {z}) {}
+
+x2() {
+ y(z, {z}) {}
+}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart b/pkg/front_end/testcases/general/error_locations/error_location_06.dart
new file mode 100644
index 0000000..b97ac23
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2019, 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.
+
+library error_location_06;
+
+part 'error_location_06_lib1.dart';
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.outline.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.outline.expect
new file mode 100644
index 0000000..6f0dc86
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.outline.expect
@@ -0,0 +1,18 @@
+library error_location_06;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+import self as self;
+
+part error_location_06_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x1(dynamic z, {dynamic z}) → dynamic
+ ;
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x2() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.expect
new file mode 100644
index 0000000..2d14468
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.expect
@@ -0,0 +1,30 @@
+library error_location_06;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:15:9: Error: 'z' is already declared in this scope.
+// y(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:15:5: Context: Previous declaration of 'z'.
+// y(z, {z}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+part error_location_06_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x1(dynamic z = #C1, {dynamic z = #C1}) → dynamic {}
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x2() → dynamic {
+ function y(dynamic z, {dynamic z = #C1}) → core::Null? {}
+}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.transformed.expect
new file mode 100644
index 0000000..2d14468
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library error_location_06;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:8: Error: Duplicated parameter name 'z'.
+// x1(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:12:4: Context: Other parameter named 'z'.
+// x1(z, {z}) {}
+// ^
+//
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:15:9: Error: 'z' is already declared in this scope.
+// y(z, {z}) {}
+// ^
+// pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart:15:5: Context: Previous declaration of 'z'.
+// y(z, {z}) {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+part error_location_06_lib1.dart;
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x1(dynamic z = #C1, {dynamic z = #C1}) → dynamic {}
+static method /* from org-dartlang-testcase:///error_location_06_lib1.dart */ x2() → dynamic {
+ function y(dynamic z, {dynamic z = #C1}) → core::Null? {}
+}
+
+constants {
+ #C1 = null
+}
diff --git a/pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart b/pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart
new file mode 100644
index 0000000..47a8883
--- /dev/null
+++ b/pkg/front_end/testcases/general/error_locations/error_location_06_lib1.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, 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.
+
+// Lots of comment lines that pushes the length of this file beyond that of
+// error_location_06. This in turn causes the (first) 'z' in 'x2' to get an
+// offset that is larger than the largest valid offset in error_location_06.
+// This in turn can cause a crash, if the fileUri for that z is the wrong file.
+
+part of error_location_06;
+
+x1(z, {z}) {}
+
+x2() {
+ y(z, {z}) {}
+}
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
index 8e90b12..fe5752c 100644
--- a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
@@ -18,14 +18,6 @@
// for (c.untypedSuperInstanceField in []) {}
// ^
//
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
-// for (unresolved in []) {}
-// ^^^^^^^^^^
-//
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
-// for (unresolved.foo in []) {}
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
// for (unresolved.foo in []) {}
// ^
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
index 8e90b12..fe5752c 100644
--- a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
@@ -18,14 +18,6 @@
// for (c.untypedSuperInstanceField in []) {}
// ^
//
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
-// for (unresolved in []) {}
-// ^^^^^^^^^^
-//
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
-// for (unresolved.foo in []) {}
-// ^^^^^^^^^^
-//
// pkg/front_end/testcases/general/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
// for (unresolved.foo in []) {}
// ^
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.outline.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.outline.expect
index 34b3c11..17ceeb6 100644
--- a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.outline.expect
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.outline.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
;
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.expect
index ffb8e82..e612779 100644
--- a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.expect
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.transformed.expect b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.transformed.expect
index ffb8e82..e612779 100644
--- a/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/interface_contravariant_from_class.dart.strong.transformed.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.outline.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.outline.expect
index 8432152..174bfb1 100644
--- a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.outline.expect
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.outline.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
;
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.expect
index 7cca990..b21225c 100644
--- a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.expect
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.transformed.expect b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.transformed.expect
index 7cca990..b21225c 100644
--- a/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/interface_covariantImpl_from_class.dart.strong.transformed.expect
@@ -13,7 +13,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.outline.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.outline.expect
index 2ddd767..61cb63d 100644
--- a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.outline.expect
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.outline.expect
@@ -21,7 +21,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
abstract class A<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
;
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.expect
index abbdcd7..3257f5f 100644
--- a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.expect
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.expect
@@ -21,7 +21,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
abstract class A<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.transformed.expect b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.transformed.expect
index abbdcd7..3257f5f 100644
--- a/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/interface_covariantInterface_from_class.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
abstract class A<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/mixin_application_override.dart.outline.expect b/pkg/front_end/testcases/general/mixin_application_override.dart.outline.expect
index c8bbb73..5454a33 100644
--- a/pkg/front_end/testcases/general/mixin_application_override.dart.outline.expect
+++ b/pkg/front_end/testcases/general/mixin_application_override.dart.outline.expect
@@ -2,125 +2,125 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-// foo() {}
-// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
-// foo([x]) {}
-// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:21:7: Context: Override was introduced in the mixin application class 'A0'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:21:7: Error: The mixin application class 'A0' introduces an erroneous override of 'foo'.
// class A0 = S with M;
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:22:7: Context: Override was introduced in the mixin application class 'A1'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:22:7: Error: The mixin application class 'A1' introduces an erroneous override of 'foo'.
// class A1 = S with M1, M;
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:23:7: Context: Override was introduced in the mixin application class 'A2'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:23:7: Error: The mixin application class 'A2' introduces an erroneous override of 'foo'.
// class A2 = S with M1, M2, M;
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:25:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:25:7: Error: Applying the mixin 'M' to 'S' introduces an erroneous override of 'foo'.
// class A0X = S with M, MX;
// ^^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:26:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:26:7: Error: Applying the mixin 'M' to 'S with M1' introduces an erroneous override of 'foo'.
// class A1X = S with M1, M, MX;
// ^^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:27:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:27:7: Error: Applying the mixin 'M' to 'S with M1, M2' introduces an erroneous override of 'foo'.
// class A2X = S with M1, M2, M, MX;
// ^^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:29:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:29:7: Error: Applying the mixin 'M' to 'S' introduces an erroneous override of 'foo'.
// class B0 extends S with M {}
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:31:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:31:7: Error: Applying the mixin 'M' to 'S with M1' introduces an erroneous override of 'foo'.
// class B1 extends S with M1, M {}
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:33:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:33:7: Error: Applying the mixin 'M' to 'S with M1, M2' introduces an erroneous override of 'foo'.
// class B2 extends S with M1, M2, M {}
// ^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:35:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:35:7: Error: Applying the mixin 'M' to 'S' introduces an erroneous override of 'foo'.
// class B0X extends S with M, MX {}
// ^^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:37:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:37:7: Error: Applying the mixin 'M' to 'S with M1' introduces an erroneous override of 'foo'.
// class B1X extends S with M1, M, MX {}
// ^^^
-//
-// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
// foo() {}
// ^
// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
// foo([x]) {}
// ^
-// pkg/front_end/testcases/general/mixin_application_override.dart:39:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+//
+// pkg/front_end/testcases/general/mixin_application_override.dart:39:7: Error: Applying the mixin 'M' to 'S with M1, M2' introduces an erroneous override of 'foo'.
// class B2X extends S with M1, M2, M, MX {}
// ^^^
+// pkg/front_end/testcases/general/mixin_application_override.dart:12:3: Context: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+// foo() {}
+// ^
+// pkg/front_end/testcases/general/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+// foo([x]) {}
+// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
index d13b4f3..d20dd45 100644
--- a/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.strong.expect
@@ -120,9 +120,9 @@
^" in null;
}
{
- dynamic x = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:41:15: Error: Can't declare 'T' because it was already used in this scope.
+ () →* core::Null? x = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:41:15: Error: Can't declare 'T' because it was already used in this scope.
var x = T T() {};
- ^" in let final () →* self::T* T = () → self::T* {} in T;
+ ^" in let final () →* core::Null? T = () → core::Null? {} in T;
}
{
self::V* V = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:47:7: Error: Can't declare 'V' because it was already used in this scope.
@@ -130,9 +130,9 @@
^" as{TypeError} self::V*;
}
{
- dynamic x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:52:13: Error: 'T' is already declared in this scope.
+ <T extends core::Object* = dynamic>() →* core::Null? x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:52:13: Error: 'T' is already declared in this scope.
var x = T<T>() {};
- ^" in let final <T extends core::Object* = dynamic>() →* dynamic T = <T extends core::Object* = dynamic>() → dynamic {} in T;
+ ^" in let final <T extends core::Object* = dynamic>() →* core::Null? T = <T extends core::Object* = dynamic>() → core::Null? {} in T;
}
{
self::T* t;
diff --git a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
index d13b4f3..d20dd45 100644
--- a/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/named_function_scope.dart.strong.transformed.expect
@@ -120,9 +120,9 @@
^" in null;
}
{
- dynamic x = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:41:15: Error: Can't declare 'T' because it was already used in this scope.
+ () →* core::Null? x = let final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:41:15: Error: Can't declare 'T' because it was already used in this scope.
var x = T T() {};
- ^" in let final () →* self::T* T = () → self::T* {} in T;
+ ^" in let final () →* core::Null? T = () → core::Null? {} in T;
}
{
self::V* V = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:47:7: Error: Can't declare 'V' because it was already used in this scope.
@@ -130,9 +130,9 @@
^" as{TypeError} self::V*;
}
{
- dynamic x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:52:13: Error: 'T' is already declared in this scope.
+ <T extends core::Object* = dynamic>() →* core::Null? x = let final dynamic #t3 = invalid-expression "pkg/front_end/testcases/general/named_function_scope.dart:52:13: Error: 'T' is already declared in this scope.
var x = T<T>() {};
- ^" in let final <T extends core::Object* = dynamic>() →* dynamic T = <T extends core::Object* = dynamic>() → dynamic {} in T;
+ ^" in let final <T extends core::Object* = dynamic>() →* core::Null? T = <T extends core::Object* = dynamic>() → core::Null? {} in T;
}
{
self::T* t;
diff --git a/pkg/front_end/testcases/general/null_aware.dart.strong.expect b/pkg/front_end/testcases/general/null_aware.dart.strong.expect
index 8410392..d2551c7 100644
--- a/pkg/front_end/testcases/general/null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/general/null_aware.dart.strong.expect
@@ -15,8 +15,8 @@
self::Foo::staticField = 5;
let final self::Foo* #t2 = foo in #t2.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t2.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
- let final self::Foo* #t3 = foo in #t3.==(null) ?{core::int*} null : #t3.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t3.{self::Foo::field} = 5 : null;
+ let final self::Foo* #t3 = foo in #t3.{core::Object::==}(null) ?{core::int*} null : #t3.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t3.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
- core::int* intValue = let final core::int* #t4 = foo.{self::Foo::field} in #t4.==(null) ?{core::int*} 6 : #t4;
- core::num* numValue = let final core::int* #t5 = foo.{self::Foo::field} in #t5.==(null) ?{core::num*} 4.5 : #t5;
+ core::int* intValue = let final core::int* #t4 = foo.{self::Foo::field} in #t4.{core::num::==}(null) ?{core::int*} 6 : #t4;
+ core::num* numValue = let final core::int* #t5 = foo.{self::Foo::field} in #t5.{core::num::==}(null) ?{core::num*} 4.5 : #t5;
}
diff --git a/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
index 8410392..d2551c7 100644
--- a/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/null_aware.dart.strong.transformed.expect
@@ -15,8 +15,8 @@
self::Foo::staticField = 5;
let final self::Foo* #t2 = foo in #t2.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t2.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
- let final self::Foo* #t3 = foo in #t3.==(null) ?{core::int*} null : #t3.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t3.{self::Foo::field} = 5 : null;
+ let final self::Foo* #t3 = foo in #t3.{core::Object::==}(null) ?{core::int*} null : #t3.{self::Foo::field}.{core::num::==}(null) ?{core::int*} #t3.{self::Foo::field} = 5 : null;
self::Foo::staticField.{core::num::==}(null) ?{core::int*} self::Foo::staticField = 5 : null;
- core::int* intValue = let final core::int* #t4 = foo.{self::Foo::field} in #t4.==(null) ?{core::int*} 6 : #t4;
- core::num* numValue = let final core::int* #t5 = foo.{self::Foo::field} in #t5.==(null) ?{core::num*} 4.5 : #t5;
+ core::int* intValue = let final core::int* #t4 = foo.{self::Foo::field} in #t4.{core::num::==}(null) ?{core::int*} 6 : #t4;
+ core::num* numValue = let final core::int* #t5 = foo.{self::Foo::field} in #t5.{core::num::==}(null) ?{core::num*} 4.5 : #t5;
}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart b/pkg/front_end/testcases/general/null_aware_postfix.dart
new file mode 100644
index 0000000..e468e8f
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, 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.
+
+class A {
+ B b;
+}
+
+class B {
+ C operator +(int i) => null;
+}
+
+class C extends B {}
+
+main() {
+ A a;
+ a?.b++;
+ C c = a?.b++;
+}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.outline.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.outline.expect
new file mode 100644
index 0000000..89edf56
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.outline.expect
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field self::B* b;
+ synthetic constructor •() → self::A*
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ ;
+ operator +(core::int* i) → self::C*
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C*
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.expect
new file mode 100644
index 0000000..594d81b
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field self::B* b = null;
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ : super core::Object::•()
+ ;
+ operator +(core::int* i) → self::C*
+ return null;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C*
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {
+ self::A* a;
+ let final self::A* #t1 = a in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::A::b} = #t1.{self::A::b}.{self::B::+}(1);
+ self::C* c = (let final self::A* #t2 = a in #t2.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t3 = #t2.{self::A::b} in let final void #t4 = #t2.{self::A::b} = #t3.{self::B::+}(1) in #t3) as{TypeError} self::C*;
+}
diff --git a/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.transformed.expect b/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.transformed.expect
new file mode 100644
index 0000000..594d81b
--- /dev/null
+++ b/pkg/front_end/testcases/general/null_aware_postfix.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field self::B* b = null;
+ synthetic constructor •() → self::A*
+ : super core::Object::•()
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B*
+ : super core::Object::•()
+ ;
+ operator +(core::int* i) → self::C*
+ return null;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C*
+ : super self::B::•()
+ ;
+}
+static method main() → dynamic {
+ self::A* a;
+ let final self::A* #t1 = a in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::A::b} = #t1.{self::A::b}.{self::B::+}(1);
+ self::C* c = (let final self::A* #t2 = a in #t2.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t3 = #t2.{self::A::b} in let final void #t4 = #t2.{self::A::b} = #t3.{self::B::+}(1) in #t3) as{TypeError} self::C*;
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml
index abcb6aa..d8a8994 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_10.yaml
@@ -7,7 +7,6 @@
# the same.
type: newworld
-strong: true
modules:
module:
module/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml
index a4a6cd9..c4dc3df 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_11.yaml
@@ -7,7 +7,6 @@
# the same.
type: newworld
-strong: true
modules:
module:
module/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml
index 4f4762e..19a5268 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_12.yaml
@@ -6,7 +6,6 @@
# which - if loaded - pulls in more of itself.
type: newworld
-strong: true
modules:
module:
module/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_13.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_13.yaml
new file mode 100644
index 0000000..f7261a4
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_13.yaml
@@ -0,0 +1,28 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Reproduction fo https://github.com/flutter/flutter/issues/40966.
+
+type: newworld
+target: None
+modules:
+ module:
+ module/a.dart: |
+ class A { }
+ class B { }
+ class C { }
+ class AB = A with B;
+ module/.packages: |
+ module:.
+worlds:
+ - entry: main.dart
+ sources:
+ main.dart: |
+ import "package:module/a.dart";
+ class ABC = AB with C;
+ .packages: |
+ module:module
+ modules:
+ - module
+ expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_4.yaml
index 6869e85..d19784b 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_4.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_4.yaml
@@ -7,7 +7,6 @@
# dill libraries.
type: newworld
-strong: true
modules:
moduleB:
moduleB/b.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_5.yaml
index 449b319..02e89d3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_5.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_5.yaml
@@ -7,7 +7,6 @@
# dill libraries.
type: newworld
-strong: true
modules:
moduleB:
moduleB/b.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_6.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_6.yaml
index 89367ec..84cb4d7 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_6.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_6.yaml
@@ -7,7 +7,6 @@
# dill libraries.
type: newworld
-strong: true
modules:
moduleB:
moduleB/b.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_7.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_7.yaml
index 3ad421d..07c9b1c 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_7.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_7.yaml
@@ -7,7 +7,6 @@
# dill libraries.
type: newworld
-strong: true
modules:
module:
module/lib1.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_8.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_8.yaml
index dbe8c91..2e2d653 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_8.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_8.yaml
@@ -7,7 +7,6 @@
# dill libraries.
type: newworld
-strong: true
modules:
module:
module/lib1.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml
index 03cc5bd..2a4d912 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/changing_modules_9.yaml
@@ -7,7 +7,6 @@
# the same.
type: newworld
-strong: true
modules:
moduleA:
moduleA/a.dart: |
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
index 404e5a5..10b94fd 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/crash_test_1.yaml
@@ -5,7 +5,6 @@
# This have crashed at one point (assertion error).
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_10.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_10.yaml
index 0ecda031..3a869c5 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_10.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_10.yaml
@@ -10,7 +10,6 @@
# Fix both and the error should go away.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_11.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_11.yaml
index 4c8455b..76e71de 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_11.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_11.yaml
@@ -8,7 +8,6 @@
# Fixing that should fix everything.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_6.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_6.yaml
index 79727eb..309b436 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_6.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_6.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_7.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_7.yaml
index 1b18f5c..20ae3a1 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_7.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_7.yaml
@@ -7,7 +7,6 @@
# we keep getting errors. Once we fix it, we no longer get errors.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_8.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_8.yaml
index 9e1b824..3eb0124 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_8.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_8.yaml
@@ -8,7 +8,6 @@
# Remove said file again and the error should go away.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_9.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_9.yaml
index c8ec3fa..308cc60 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_9.yaml
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_9.yaml
@@ -9,7 +9,6 @@
# Any references to the constant shouldn't matter in this regard.
type: newworld
-strong: true
worlds:
- entry: main.dart
sources:
diff --git a/pkg/front_end/testcases/inference/bug30624.dart b/pkg/front_end/testcases/inference/bug30624.dart
index 39f822e..58f7c33 100644
--- a/pkg/front_end/testcases/inference/bug30624.dart
+++ b/pkg/front_end/testcases/inference/bug30624.dart
@@ -9,20 +9,21 @@
class C<E> {
void barA([int cmp(E a, E b)]) {
- /*@ typeArgs=C::E* */ foo(this, cmp ?? _default);
+ /*@ typeArgs=C::E* */ foo(this, cmp /*@ target=Object::== */ ?? _default);
}
void barB([int cmp(E a, E b)]) {
- /*@ typeArgs=C::E* */ foo(this, cmp ?? (_default as int Function(E, E)));
+ /*@ typeArgs=C::E* */ foo(
+ this, cmp /*@ target=Object::== */ ?? (_default as int Function(E, E)));
}
void barC([int cmp(E a, E b)]) {
int Function(E, E) v = _default;
- /*@ typeArgs=C::E* */ foo(this, cmp ?? v);
+ /*@ typeArgs=C::E* */ foo(this, cmp /*@ target=Object::== */ ?? v);
}
void barD([int cmp(E a, E b)]) {
- foo<E>(this, cmp ?? _default);
+ foo<E>(this, cmp /*@ target=Object::== */ ?? _default);
}
void barE([int cmp(E a, E b)]) {
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.strong.expect b/pkg/front_end/testcases/inference/bug30624.dart.strong.expect
index 5f1bb52..825e93c 100644
--- a/pkg/front_end/testcases/inference/bug30624.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/bug30624.dart.strong.expect
@@ -7,17 +7,17 @@
: super core::Object::•()
;
method barA([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = cmp in #t1.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = cmp in #t1.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
}
method barB([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} (#C2) as (self::C::E*, self::C::E*) →* core::int* : #t2);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} (#C2) as (self::C::E*, self::C::E*) →* core::int* : #t2);
}
method barC([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
(self::C::E*, self::C::E*) →* core::int* v = #C2;
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t3 = cmp in #t3.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} v : #t3);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t3 = cmp in #t3.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} v : #t3);
}
method barD([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t4 = cmp in #t4.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t4);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t4 = cmp in #t4.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t4);
}
method barE([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
self::foo<self::C::E*>(this, cmp.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : cmp);
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
index 5f1bb52..825e93c 100644
--- a/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
@@ -7,17 +7,17 @@
: super core::Object::•()
;
method barA([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = cmp in #t1.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = cmp in #t1.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
}
method barB([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} (#C2) as (self::C::E*, self::C::E*) →* core::int* : #t2);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t2 = cmp in #t2.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} (#C2) as (self::C::E*, self::C::E*) →* core::int* : #t2);
}
method barC([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
(self::C::E*, self::C::E*) →* core::int* v = #C2;
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t3 = cmp in #t3.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} v : #t3);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t3 = cmp in #t3.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} v : #t3);
}
method barD([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
- self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t4 = cmp in #t4.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t4);
+ self::foo<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t4 = cmp in #t4.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t4);
}
method barE([(self::C::E*, self::C::E*) →* core::int* cmp = #C1]) → void {
self::foo<self::C::E*>(this, cmp.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : cmp);
diff --git a/pkg/front_end/testcases/inference/bug32291.dart b/pkg/front_end/testcases/inference/bug32291.dart
index e325f33..08ea27f 100644
--- a/pkg/front_end/testcases/inference/bug32291.dart
+++ b/pkg/front_end/testcases/inference/bug32291.dart
@@ -12,7 +12,7 @@
var /*@ type=Iterable<List<String*>*>* */ i1 =
l. /*@target=Iterable::map*/ /*@ typeArgs=List<String*>* */ map(
/*@ returnType=List<String*>* */ (/*@ type=List<String*>* */ ll) =>
- ll ?? /*@ typeArgs=String* */ []);
+ ll /*@ target=List::== */ ?? /*@ typeArgs=String* */ []);
var /*@ type=Iterable<int*>* */ i2 =
i1. /*@target=Iterable::map*/ /*@ typeArgs=int* */ map(
/*@ returnType=int* */ (List<String> l) =>
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.strong.expect b/pkg/front_end/testcases/inference/bug32291.dart.strong.expect
index 6c30ca4..b8775a7 100644
--- a/pkg/front_end/testcases/inference/bug32291.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/bug32291.dart.strong.expect
@@ -4,7 +4,7 @@
static method main() → void {
core::List<core::List<core::String*>*>* l = <core::List<core::String*>*>[<core::String*>["hi", "world"]];
- core::Iterable<core::List<core::String*>*>* i1 = l.{core::Iterable::map}<core::List<core::String*>*>((core::List<core::String*>* ll) → core::List<core::String*>* => let final core::List<core::String*>* #t1 = ll in #t1.==(null) ?{core::List<core::String*>*} <core::String*>[] : #t1);
+ core::Iterable<core::List<core::String*>*>* i1 = l.{core::Iterable::map}<core::List<core::String*>*>((core::List<core::String*>* ll) → core::List<core::String*>* => let final core::List<core::String*>* #t1 = ll in #t1.{core::List::==}(null) ?{core::List<core::String*>*} <core::String*>[] : #t1);
core::Iterable<core::int*>* i2 = i1.{core::Iterable::map}<core::int*>((core::List<core::String*>* l) → core::int* => l.{core::List::length});
core::print(i2);
}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect
index 6c30ca4..b8775a7 100644
--- a/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
static method main() → void {
core::List<core::List<core::String*>*>* l = <core::List<core::String*>*>[<core::String*>["hi", "world"]];
- core::Iterable<core::List<core::String*>*>* i1 = l.{core::Iterable::map}<core::List<core::String*>*>((core::List<core::String*>* ll) → core::List<core::String*>* => let final core::List<core::String*>* #t1 = ll in #t1.==(null) ?{core::List<core::String*>*} <core::String*>[] : #t1);
+ core::Iterable<core::List<core::String*>*>* i1 = l.{core::Iterable::map}<core::List<core::String*>*>((core::List<core::String*>* ll) → core::List<core::String*>* => let final core::List<core::String*>* #t1 = ll in #t1.{core::List::==}(null) ?{core::List<core::String*>*} <core::String*>[] : #t1);
core::Iterable<core::int*>* i2 = i1.{core::Iterable::map}<core::int*>((core::List<core::String*>* l) → core::int* => l.{core::List::length});
core::print(i2);
}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.outline.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.outline.expect
index 5df14ed..3801c07 100644
--- a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
class A<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field (self::A::T*) →* self::A::T* x;
constructor •((self::A::T*) →* self::A::T* x) → self::A<self::A::T*>*
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
index 53daa23..7655fcc 100644
--- a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
class A<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field (self::A::T*) →* self::A::T* x;
constructor •((self::A::T*) →* self::A::T* x) → self::A<self::A::T*>*
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
index 53daa23..7655fcc 100644
--- a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
class A<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field (self::A::T*) →* self::A::T* x;
constructor •((self::A::T*) →* self::A::T* x) → self::A<self::A::T*>*
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.outline.expect
index 38a6f9a..74ed489 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = () →* void;
+typedef F<unrelated T extends core::Object* = dynamic> = () →* void;
class Foo extends core::Object {
const constructor •(core::List<core::String*>* l) → self::Foo*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.outline.expect
index e0a7edc..2f4353d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
class Foo extends core::Object {
field core::List<core::int*>* x;
constructor •([core::List<core::int*>* x]) → self::Foo*
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.expect
index ae4583b..2cfdda7 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
class Foo extends core::Object {
field core::List<core::int*>* x;
constructor •([core::List<core::int*>* x = #C2]) → self::Foo*
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect
index ae4583b..2cfdda7 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = ([S*]) →* T*;
class Foo extends core::Object {
field core::List<core::int*>* x;
constructor •([core::List<core::int*>* x = #C2]) → self::Foo*
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.outline.expect
index 3539aa7..86b1ec1 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
static method test() → void
;
static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
index 7c74d42..e7f54af 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
@@ -61,7 +61,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
static method test() → void {
{
(core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
index 7c74d42..e7f54af 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -61,7 +61,7 @@
import self as self;
import "dart:core" as core;
-typedef Function2<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
+typedef Function2<contravariant S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* T*;
static method test() → void {
{
(core::int*) →* core::String* l0 = (core::int* x) → core::Null? => null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.outline.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.outline.expect
index 57c5b68..2fc00f4 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef Asserter<T extends core::Object* = dynamic> = (T*) →* void;
-typedef AsserterBuilder<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
+typedef Asserter<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef AsserterBuilder<contravariant S extends core::Object* = dynamic, unrelated T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
class DartType extends core::Object {
synthetic constructor •() → self::DartType*
;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.expect
index ca17455..43326c3 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef Asserter<T extends core::Object* = dynamic> = (T*) →* void;
-typedef AsserterBuilder<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
+typedef Asserter<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef AsserterBuilder<contravariant S extends core::Object* = dynamic, unrelated T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
class DartType extends core::Object {
synthetic constructor •() → self::DartType*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect
index ca17455..43326c3 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef Asserter<T extends core::Object* = dynamic> = (T*) →* void;
-typedef AsserterBuilder<S extends core::Object* = dynamic, T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
+typedef Asserter<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef AsserterBuilder<contravariant S extends core::Object* = dynamic, unrelated T extends core::Object* = dynamic> = (S*) →* (T*) →* void;
class DartType extends core::Object {
synthetic constructor •() → self::DartType*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart b/pkg/front_end/testcases/inference/future_then_ifNull.dart
index 2246903..d84927f 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart
@@ -18,18 +18,20 @@
MyFuture<int> f;
Future<int> t1 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=int* */ x) async =>
- x ?? await new Future<int>.value(3));
+ x /*@ target=num::== */ ?? await new Future<int>.value(3));
Future<int> t2 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
/*@ returnType=Future<int*>* */ (/*@ type=int* */ x) async {
- return /*info:DOWN_CAST_COMPOSITE*/ await x ?? new Future<int>.value(3);
+ return /*info:DOWN_CAST_COMPOSITE*/ await x /*@ target=num::== */ ??
+ new Future<int>.value(3);
});
Future<int> t5 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
/*error:INVALID_CAST_FUNCTION_EXPR*/
/*@ returnType=FutureOr<int*>* */ (/*@ type=int* */ x) =>
- x ?? new Future<int>.value(3));
+ x /*@ target=num::== */ ?? new Future<int>.value(3));
Future<int> t6 = f. /*@ typeArgs=int* */ /*@target=MyFuture::then*/ then(
/*@ returnType=FutureOr<int*>* */ (/*@ type=int* */ x) {
- return /*info:DOWN_CAST_COMPOSITE*/ x ?? new Future<int>.value(3);
+ return /*info:DOWN_CAST_COMPOSITE*/ x /*@ target=num::== */ ??
+ new Future<int>.value(3);
});
}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
index 000016c..0bec8e6 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
@@ -25,13 +25,13 @@
}
static method test() → void {
self::MyFuture<core::int*>* f;
- asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async => let final core::int* #t1 = x in #t1.==(null) ?{core::int*} await asy::Future::value<core::int*>(3) : #t1);
+ asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async => let final core::int* #t1 = x in #t1.{core::num::==}(null) ?{core::int*} await asy::Future::value<core::int*>(3) : #t1);
asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async {
- return (let final core::int* #t2 = await x in #t2.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t2) as{TypeError} asy::FutureOr<core::int*>*;
+ return (let final core::int* #t2 = await x in #t2.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t2) as{TypeError} asy::FutureOr<core::int*>*;
});
- asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* => (let final core::int* #t3 = x in #t3.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t3) as{TypeError} asy::FutureOr<core::int*>*);
+ asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* => (let final core::int* #t3 = x in #t3.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t3) as{TypeError} asy::FutureOr<core::int*>*);
asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* {
- return (let final core::int* #t4 = x in #t4.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} asy::FutureOr<core::int*>*;
+ return (let final core::int* #t4 = x in #t4.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} asy::FutureOr<core::int*>*;
});
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index ce5d23f1..49ce857 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -40,7 +40,7 @@
#L1:
{
final core::int* #t1 = x;
- if(#t1.==(null)) {
+ if(#t1.{core::num::==}(null)) {
[yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int*>(3), :async_op_then, :async_op_error, :async_op) in null;
:async_temporary_0 = :result;
}
@@ -76,7 +76,7 @@
#L2:
{
[yield] let dynamic #t3 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = (let final core::int* #t4 = :result in #t4.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} asy::FutureOr<core::int*>*;
+ :return_value = (let final core::int* #t4 = :result in #t4.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} asy::FutureOr<core::int*>*;
break #L2;
}
asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -91,9 +91,9 @@
:async_completer.start(:async_op);
return :async_completer.{asy::Completer::future};
});
- asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* => (let final core::int* #t5 = x in #t5.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t5) as{TypeError} asy::FutureOr<core::int*>*);
+ asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* => (let final core::int* #t5 = x in #t5.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t5) as{TypeError} asy::FutureOr<core::int*>*);
asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::FutureOr<core::int*>* {
- return (let final core::int* #t6 = x in #t6.==(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t6) as{TypeError} asy::FutureOr<core::int*>*;
+ return (let final core::int* #t6 = x in #t6.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t6) as{TypeError} asy::FutureOr<core::int*>*;
});
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.outline.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.outline.expect
index c410a31..3a0416f 100644
--- a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.outline.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef ToValue<T extends core::Object* = dynamic> = (T*) →* void;
+typedef ToValue<contravariant T extends core::Object* = dynamic> = (T*) →* void;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.outline.expect
index 465372c..c2f4469 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<V extends core::Object* = dynamic> = (V*) →* void;
+typedef F<contravariant V extends core::Object* = dynamic> = (V*) →* void;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.expect
index f47805d..abcd1fc 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<V extends core::Object* = dynamic> = (V*) →* void;
+typedef F<contravariant V extends core::Object* = dynamic> = (V*) →* void;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
: super self::D::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect
index f47805d..abcd1fc 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<V extends core::Object* = dynamic> = (V*) →* void;
+typedef F<contravariant V extends core::Object* = dynamic> = (V*) →* void;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
: super self::D::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.outline.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.outline.expect
index cd56022..4c088aa 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef G<V extends core::Object* = dynamic> = () →* core::List<V*>*;
+typedef G<unrelated V extends core::Object* = dynamic> = () →* core::List<V*>*;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.expect
index bd37b92..90e061b 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef G<V extends core::Object* = dynamic> = () →* core::List<V*>*;
+typedef G<unrelated V extends core::Object* = dynamic> = () →* core::List<V*>*;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
: super self::D::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect
index bd37b92..90e061b 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef G<V extends core::Object* = dynamic> = () →* core::List<V*>*;
+typedef G<unrelated V extends core::Object* = dynamic> = () →* core::List<V*>*;
class C<T extends core::Object* = dynamic> extends self::D<self::C::T*> {
synthetic constructor •() → self::C<self::C::T*>*
: super self::D::•()
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
index 68a2344..6d7ebaa 100644
--- a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart
@@ -7,7 +7,8 @@
abstract class C<E> {
void sort([int compare(E a, E b)]) {
- /*@ typeArgs=C::E* */ sort2(this, compare ?? _compareAny);
+ /*@ typeArgs=C::E* */ sort2(
+ this, compare /*@ target=Object::== */ ?? _compareAny);
}
static int _compareAny(a, b) {
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.expect
index d7c1006..c6a9ba8 100644
--- a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
method sort([(self::C::E*, self::C::E*) →* core::int* compare = #C1]) → void {
- self::C::sort2<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = compare in #t1.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
+ self::C::sort2<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = compare in #t1.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
}
static method _compareAny(dynamic a, dynamic b) → core::int* {
throw "unimplemented";
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect
index d7c1006..c6a9ba8 100644
--- a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
method sort([(self::C::E*, self::C::E*) →* core::int* compare = #C1]) → void {
- self::C::sort2<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = compare in #t1.==(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
+ self::C::sort2<self::C::E*>(this, let final (self::C::E*, self::C::E*) →* core::int* #t1 = compare in #t1.{core::Object::==}(null) ?{(self::C::E*, self::C::E*) →* core::int*} #C2 : #t1);
}
static method _compareAny(dynamic a, dynamic b) → core::int* {
throw "unimplemented";
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
index 118957d..4973261 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart
@@ -27,15 +27,20 @@
/*@target=Test::member*/ /*@target=Test::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
- /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- -- /*@target=Test::member*/ member;
+ /*@ target=B::- */ -- /*@target=Test::member*/ /*@target=Test::member*/
+ member;
- /*@target=Test::member*/ member--;
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
/*@ typeArgs=B* */ f();
@@ -43,15 +48,24 @@
var /*@ type=B* */ v2 = /*@target=Test::member*/ /*@target=Test::member*/
member /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = /*@target=Test::member*/ member *=
- /*@ typeArgs=dynamic */ f();
+ var /*@ type=A* */ v3 = /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ target=B::+ */ +=
+ /*@ typeArgs=C* */ f();
- var /*@ type=C* */ v5 = /*@target=Test::member*/ member &=
- /*@ typeArgs=dynamic */ f();
+ var /*@ type=B* */ v4 = /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ target=B::* */ *=
+ /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v6 = -- /*@target=Test::member*/ member;
+ var /*@ type=C* */ v5 = /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ target=B::& */ &=
+ /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v7 = /*@target=Test::member*/ member--;
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --
+ /*@target=Test::member*/ /*@target=Test::member*/ member;
+
+ var /*@ type=B* */ v7 =
+ /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.expect
index 41cf1f1..043ccf2 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.expect
@@ -33,15 +33,16 @@
method test() → void {
this.{self::Test::member} = self::f<self::B*>();
this.{self::Test::member}.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : null;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v1 = this.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : #t1;
- self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = this.{self::Test::member} in let final self::B* #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect
index 41cf1f1..043ccf2 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect
@@ -33,15 +33,16 @@
method test() → void {
this.{self::Test::member} = self::f<self::B*>();
this.{self::Test::member}.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : null;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v1 = this.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : #t1;
- self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = this.{self::Test::member} in let final self::B* #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
index 0f111a2..25db588 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart
@@ -18,11 +18,15 @@
var /*@ type=int* */ v4 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
/*@ target=num::== */ ??= getInt();
- var /*@ type=int* */ v7 = /*@target=Test1::t*/ t += getInt();
+ var /*@ type=int* */ v7 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::+ */ += getInt();
- var /*@ type=int* */ v10 = ++ /*@target=Test1::t*/ t;
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
+ /*@target=Test1::t*/ /*@target=Test1::t*/ t;
- var /*@ type=int* */ v11 = /*@target=Test1::t*/ t++;
+ var /*@ type=int* */ v11 =
+ /*@ type=int* */ /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
@@ -45,15 +49,21 @@
var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
/*@ target=num::== */ ??= getDouble();
- var /*@ type=num* */ v7 = /*@target=Test2::t*/ t += getInt();
+ var /*@ type=num* */ v7 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test2::t*/ t += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getNum();
- var /*@ type=num* */ v9 = /*@target=Test2::t*/ t += getDouble();
+ var /*@ type=num* */ v9 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getDouble();
- var /*@ type=num* */ v10 = ++ /*@target=Test2::t*/ t;
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++
+ /*@target=Test2::t*/ /*@target=Test2::t*/ t;
- var /*@ type=num* */ v11 = /*@target=Test2::t*/ t++;
+ var /*@ type=num* */ v11 =
+ /*@ type=num* */ /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -66,15 +76,21 @@
var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
/*@ target=num::== */ ??= getDouble();
- var /*@ type=double* */ v7 = /*@target=Test3::t*/ t += getInt();
+ var /*@ type=double* */ v7 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getInt();
- var /*@ type=double* */ v8 = /*@target=Test3::t*/ t += getNum();
+ var /*@ type=double* */ v8 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getNum();
- var /*@ type=double* */ v9 = /*@target=Test3::t*/ t += getDouble();
+ var /*@ type=double* */ v9 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getDouble();
- var /*@ type=double* */ v10 = ++ /*@target=Test3::t*/ t;
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++
+ /*@target=Test3::t*/ /*@target=Test3::t*/ t;
- var /*@ type=double* */ v11 = /*@target=Test3::t*/ t++;
+ var /*@ type=double* */ v11 =
+ /*@ type=double* */ /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
index d344928..5fb409e 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart
@@ -30,8 +30,8 @@
t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ [/*@ typeArgs=Index* */ f()]
- /*@ target=Object::== */ /*@ target=Test::[]= */
+ t /*@target=Test::[]*/ /*@ target=Test::[]= */ [/*@ typeArgs=Index* */ f()]
+ /*@ target=Object::== */
??= /*@ typeArgs=B* */ f();
t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
@@ -54,9 +54,9 @@
var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]*/ [
+ var /*@ type=B* */ v2 = t /*@target=Test::[]*/ /*@ target=Test::[]= */ [
/*@ typeArgs=Index* */ f()]
- /*@ target=Object::== */ /*@ target=Test::[]= */
+ /*@ target=Object::== */
??= /*@ typeArgs=B* */ f();
var /*@ type=B* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
index 0d41509..838656d 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart
@@ -28,29 +28,56 @@
class Test extends Base {
void test() {
super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()];
- super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=Object::== */
+ ??= /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ [/*@ typeArgs=Index* */ f()];
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 =
- --super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 =
- super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=Object::== */
+ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 = super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.expect
index 88446ef..6386cbd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.expect
@@ -43,19 +43,20 @@
: super self::Base::•()
;
method test() → void {
- super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index*, super.{self::Base::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index*, super.{self::Base::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index*, super.{self::Base::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index*, super.{self::Base::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::B* v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::C* v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C* #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::B* v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B* #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index*) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index*, #t28.{self::B::-}(1)) in #t28;
+ super.{self::Base::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in super.{self::Base::[]}(#t1).{core::Object::==}(null) ?{self::B*} super.{self::Base::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in super.{self::Base::[]=}(#t2, super.{self::Base::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in super.{self::Base::[]=}(#t3, super.{self::Base::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = super.{self::Base::[]}(#t5).{self::B::-}(1) in let final void #t7 = super.{self::Base::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in super.{self::Base::[]=}(#t8, super.{self::Base::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Index* #t9 = self::f<self::Index*>() in let final self::B* #t10 = self::f<self::B*>() in let final void #t11 = super.{self::Base::[]=}(#t9, #t10) in #t10;
+ self::B* v2 = let final self::Index* #t12 = self::f<self::Index*>() in let final self::B* #t13 = super.{self::Base::[]}(#t12) in #t13.{core::Object::==}(null) ?{self::B*} let final self::B* #t14 = self::f<self::B*>() in let final void #t15 = super.{self::Base::[]=}(#t12, #t14) in #t14 : #t13;
+ self::A* v3 = let final self::Index* #t16 = self::f<self::Index*>() in let final self::A* #t17 = super.{self::Base::[]}(#t16).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t18 = super.{self::Base::[]=}(#t16, #t17) in #t17;
+ self::B* v4 = let final self::Index* #t19 = self::f<self::Index*>() in let final self::B* #t20 = super.{self::Base::[]}(#t19).{self::B::*}(self::f<self::B*>()) in let final void #t21 = super.{self::Base::[]=}(#t19, #t20) in #t20;
+ self::C* v5 = let final self::Index* #t22 = self::f<self::Index*>() in let final self::C* #t23 = super.{self::Base::[]}(#t22).{self::B::&}(self::f<self::A*>()) in let final void #t24 = super.{self::Base::[]=}(#t22, #t23) in #t23;
+ self::B* v6 = let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = super.{self::Base::[]}(#t25).{self::B::-}(1) in let final void #t27 = super.{self::Base::[]=}(#t25, #t26) in #t26;
+ self::B* v7 = let final self::Index* #t28 = self::f<self::Index*>() in let final self::B* #t29 = super.{self::Base::[]}(#t28) in let final void #t30 = super.{self::Base::[]=}(#t28, #t29.{self::B::-}(1)) in #t29;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect
index 88446ef..6386cbd 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect
@@ -43,19 +43,20 @@
: super self::Base::•()
;
method test() → void {
- super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index*, super.{self::Base::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index*, super.{self::Base::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index*, super.{self::Base::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index*, super.{self::Base::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::B* v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::C* v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C* #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::B* v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B* #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index*) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index*, #t28.{self::B::-}(1)) in #t28;
+ super.{self::Base::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in super.{self::Base::[]}(#t1).{core::Object::==}(null) ?{self::B*} super.{self::Base::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in super.{self::Base::[]=}(#t2, super.{self::Base::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in super.{self::Base::[]=}(#t3, super.{self::Base::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = super.{self::Base::[]}(#t5).{self::B::-}(1) in let final void #t7 = super.{self::Base::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in super.{self::Base::[]=}(#t8, super.{self::Base::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Index* #t9 = self::f<self::Index*>() in let final self::B* #t10 = self::f<self::B*>() in let final void #t11 = super.{self::Base::[]=}(#t9, #t10) in #t10;
+ self::B* v2 = let final self::Index* #t12 = self::f<self::Index*>() in let final self::B* #t13 = super.{self::Base::[]}(#t12) in #t13.{core::Object::==}(null) ?{self::B*} let final self::B* #t14 = self::f<self::B*>() in let final void #t15 = super.{self::Base::[]=}(#t12, #t14) in #t14 : #t13;
+ self::A* v3 = let final self::Index* #t16 = self::f<self::Index*>() in let final self::A* #t17 = super.{self::Base::[]}(#t16).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t18 = super.{self::Base::[]=}(#t16, #t17) in #t17;
+ self::B* v4 = let final self::Index* #t19 = self::f<self::Index*>() in let final self::B* #t20 = super.{self::Base::[]}(#t19).{self::B::*}(self::f<self::B*>()) in let final void #t21 = super.{self::Base::[]=}(#t19, #t20) in #t20;
+ self::C* v5 = let final self::Index* #t22 = self::f<self::Index*>() in let final self::C* #t23 = super.{self::Base::[]}(#t22).{self::B::&}(self::f<self::A*>()) in let final void #t24 = super.{self::Base::[]=}(#t22, #t23) in #t23;
+ self::B* v6 = let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = super.{self::Base::[]}(#t25).{self::B::-}(1) in let final void #t27 = super.{self::Base::[]=}(#t25, #t26) in #t26;
+ self::B* v7 = let final self::Index* #t28 = self::f<self::Index*>() in let final self::B* #t29 = super.{self::Base::[]}(#t28) in let final void #t30 = super.{self::Base::[]=}(#t28, #t29.{self::B::-}(1)) in #t29;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
index 539a43d..b2919a1 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart
@@ -26,29 +26,55 @@
void test() {
this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=Object::== */
+ ??= /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::+ */
+ += /*@ typeArgs=C* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::* */
+ *= /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::& */
+ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v4 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 =
- --this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 =
- this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=Object::== */
+ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v4 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::+ */
+ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v3 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::* */
+ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::& */
+ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --this
+ /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.expect
index cc540e8..116991f 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.expect
@@ -38,19 +38,20 @@
return null;
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
- this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index*, this.{self::Test::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index*, this.{self::Test::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index*, this.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index*, this.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::B* v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::C* v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C* #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::B* v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B* #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index*) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28.{self::B::-}(1)) in #t28;
+ this.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in this.{self::Test::[]}(#t1).{core::Object::==}(null) ?{self::B*} this.{self::Test::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in this.{self::Test::[]=}(#t2, this.{self::Test::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in this.{self::Test::[]=}(#t3, this.{self::Test::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in this.{self::Test::[]=}(#t4, this.{self::Test::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = this.{self::Test::[]}(#t5).{self::B::-}(1) in let final void #t7 = this.{self::Test::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in this.{self::Test::[]=}(#t8, this.{self::Test::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t9 = this in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = self::f<self::B*>() in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ self::B* v2 = let final self::Index* #t13 = self::f<self::Index*>() in let final self::B* #t14 = this.{self::Test::[]}(#t13) in #t14.{core::Object::==}(null) ?{self::B*} let final self::B* #t15 = self::f<self::B*>() in let final void #t16 = this.{self::Test::[]=}(#t13, #t15) in #t15 : #t14;
+ self::A* v4 = let final self::Index* #t17 = self::f<self::Index*>() in let final self::A* #t18 = this.{self::Test::[]}(#t17).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t19 = this.{self::Test::[]=}(#t17, #t18) in #t18;
+ self::B* v3 = let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = this.{self::Test::[]}(#t20).{self::B::*}(self::f<self::B*>()) in let final void #t22 = this.{self::Test::[]=}(#t20, #t21) in #t21;
+ self::C* v5 = let final self::Index* #t23 = self::f<self::Index*>() in let final self::C* #t24 = this.{self::Test::[]}(#t23).{self::B::&}(self::f<self::A*>()) in let final void #t25 = this.{self::Test::[]=}(#t23, #t24) in #t24;
+ self::B* v6 = let final self::Index* #t26 = self::f<self::Index*>() in let final self::B* #t27 = this.{self::Test::[]}(#t26).{self::B::-}(1) in let final void #t28 = this.{self::Test::[]=}(#t26, #t27) in #t27;
+ self::B* v7 = let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = this.{self::Test::[]}(#t29) in let final void #t31 = this.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect
index cc540e8..116991f 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect
@@ -38,19 +38,20 @@
return null;
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
- this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index*, this.{self::Test::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index*, this.{self::Test::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index*, this.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index*, this.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::B* v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B* #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::C* v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C* #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::B* v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B* #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index*) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28.{self::B::-}(1)) in #t28;
+ this.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in this.{self::Test::[]}(#t1).{core::Object::==}(null) ?{self::B*} this.{self::Test::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in this.{self::Test::[]=}(#t2, this.{self::Test::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in this.{self::Test::[]=}(#t3, this.{self::Test::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in this.{self::Test::[]=}(#t4, this.{self::Test::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = this.{self::Test::[]}(#t5).{self::B::-}(1) in let final void #t7 = this.{self::Test::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in this.{self::Test::[]=}(#t8, this.{self::Test::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t9 = this in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = self::f<self::B*>() in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ self::B* v2 = let final self::Index* #t13 = self::f<self::Index*>() in let final self::B* #t14 = this.{self::Test::[]}(#t13) in #t14.{core::Object::==}(null) ?{self::B*} let final self::B* #t15 = self::f<self::B*>() in let final void #t16 = this.{self::Test::[]=}(#t13, #t15) in #t15 : #t14;
+ self::A* v4 = let final self::Index* #t17 = self::f<self::Index*>() in let final self::A* #t18 = this.{self::Test::[]}(#t17).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t19 = this.{self::Test::[]=}(#t17, #t18) in #t18;
+ self::B* v3 = let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = this.{self::Test::[]}(#t20).{self::B::*}(self::f<self::B*>()) in let final void #t22 = this.{self::Test::[]=}(#t20, #t21) in #t21;
+ self::C* v5 = let final self::Index* #t23 = self::f<self::Index*>() in let final self::C* #t24 = this.{self::Test::[]}(#t23).{self::B::&}(self::f<self::A*>()) in let final void #t25 = this.{self::Test::[]=}(#t23, #t24) in #t24;
+ self::B* v6 = let final self::Index* #t26 = self::f<self::Index*>() in let final self::B* #t27 = this.{self::Test::[]}(#t26).{self::B::-}(1) in let final void #t28 = this.{self::Test::[]=}(#t26, #t27) in #t27;
+ self::B* v7 = let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = this.{self::Test::[]}(#t29) in let final void #t31 = this.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
index ebc99ac..16eb415 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart
@@ -21,18 +21,32 @@
void test() {
B local;
local = /*@ typeArgs=B* */ f();
- local ??= /*@ typeArgs=B* */ f();
+
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
/*@ target=B::- */ --local;
+
local /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 =
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
var /*@ type=A* */ v3 = local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 = local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 = local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+
var /*@ type=B* */ v7 = /*@ type=B* */ local
/*@ type=B* */ /*@ target=B::- */ --;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
index e0dc7dd..cd4a8a3 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.type_promotion.expect
@@ -1,42 +1,42 @@
pkg/front_end/testcases/inference/infer_assign_to_local.dart:23:9: Context: Write to local@474
local = /*@ typeArgs=B* */ f();
^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:24:9: Context: Write to local@474
- local ??= /*@ typeArgs=B* */ f();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:25:28: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:25:34: Context: Write to local@474
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:27:28: Context: Write to local@474
local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:26:28: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:29:28: Context: Write to local@474
local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:27:28: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:31:28: Context: Write to local@474
local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:28:22: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:33:22: Context: Write to local@474
/*@ target=B::- */ --local;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:29:28: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:35:28: Context: Write to local@474
local /*@ target=B::- */ --;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:30:33: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:37:33: Context: Write to local@474
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:31:33: Context: Write to local@474
- var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:32:52: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:40:38: Context: Write to local@474
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:42:52: Context: Write to local@474
var /*@ type=A* */ v3 = local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:33:52: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:44:52: Context: Write to local@474
var /*@ type=B* */ v4 = local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:34:52: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:46:52: Context: Write to local@474
var /*@ type=C* */ v5 = local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:35:46: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:48:46: Context: Write to local@474
var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local.dart:37:41: Context: Write to local@474
+pkg/front_end/testcases/inference/infer_assign_to_local.dart:51:41: Context: Write to local@474
/*@ type=B* */ /*@ target=B::- */ --;
^^
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
index fef536a..8619d3b 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart
@@ -11,33 +11,55 @@
void test1(int t) {
var /*@ type=int* */ v1 = t = getInt();
- var /*@ type=int* */ v4 = t ??= getInt();
+
+ var /*@ type=int* */ v4 = t /*@target=num::==*/ ??= getInt();
+
var /*@ type=int* */ v7 = t /*@target=num::+*/ += getInt();
+
var /*@ type=int* */ v10 = /*@target=num::+*/ ++t;
- var /*@ type=int* */ v11 = /*@ type=int* */ t /*@ type=int* */ /*@target=num::+*/ ++;
+
+ var /*@ type=int* */ v11 = /*@ type=int* */ t
+ /*@ type=int* */ /*@target=num::+*/ ++;
}
void test2(num t) {
var /*@ type=int* */ v1 = t = getInt();
+
var /*@ type=num* */ v2 = t = getNum();
+
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v4 = t ??= getInt();
- var /*@ type=num* */ v5 = t ??= getNum();
- var /*@ type=num* */ v6 = t ??= getDouble();
+
+ var /*@ type=num* */ v4 = t /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = t /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = t /*@target=num::==*/ ??= getDouble();
+
var /*@ type=num* */ v7 = t /*@target=num::+*/ += getInt();
+
var /*@ type=num* */ v8 = t /*@target=num::+*/ += getNum();
+
var /*@ type=num* */ v9 = t /*@target=num::+*/ += getDouble();
+
var /*@ type=num* */ v10 = /*@target=num::+*/ ++t;
- var /*@ type=num* */ v11 = /*@ type=num* */ t /*@ type=num* */ /*@target=num::+*/ ++;
+
+ var /*@ type=num* */ v11 = /*@ type=num* */ t
+ /*@ type=num* */ /*@target=num::+*/ ++;
}
void test3(double t) {
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=double* */ v6 = t ??= getDouble();
+
+ var /*@ type=double* */ v6 = t /*@target=num::==*/ ??= getDouble();
+
var /*@ type=double* */ v7 = t /*@target=double::+*/ += getInt();
+
var /*@ type=double* */ v8 = t /*@target=double::+*/ += getNum();
+
var /*@ type=double* */ v9 = t /*@target=double::+*/ += getDouble();
+
var /*@ type=double* */ v10 = /*@target=double::+*/ ++t;
+
var /*@ type=double* */ v11 = /*@ type=double* */ t
/*@ type=double* */ /*@target=double::+*/ ++;
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
index 80ef25c..e4950d8 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.type_promotion.expect
@@ -1,69 +1,69 @@
pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:13:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:14:31: Context: Write to t@343
- var /*@ type=int* */ v4 = t ??= getInt();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:15:50: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:15:51: Context: Write to t@343
+ var /*@ type=int* */ v4 = t /*@target=num::==*/ ??= getInt();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:17:50: Context: Write to t@343
var /*@ type=int* */ v7 = t /*@target=num::+*/ += getInt();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:16:49: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:19:49: Context: Write to t@343
var /*@ type=int* */ v10 = /*@target=num::+*/ ++t;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:17:85: Context: Write to t@343
- var /*@ type=int* */ v11 = /*@ type=int* */ t /*@ type=int* */ /*@target=num::+*/ ++;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:21:31: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:22:43: Context: Write to t@343
+ /*@ type=int* */ /*@target=num::+*/ ++;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:26:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:22:31: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:28:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:23:34: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:30:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:24:31: Context: Write to t@343
- var /*@ type=num* */ v4 = t ??= getInt();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:25:31: Context: Write to t@343
- var /*@ type=num* */ v5 = t ??= getNum();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:26:31: Context: Write to t@343
- var /*@ type=num* */ v6 = t ??= getDouble();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:27:50: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:32:51: Context: Write to t@343
+ var /*@ type=num* */ v4 = t /*@target=num::==*/ ??= getInt();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:34:51: Context: Write to t@343
+ var /*@ type=num* */ v5 = t /*@target=num::==*/ ??= getNum();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:36:51: Context: Write to t@343
+ var /*@ type=num* */ v6 = t /*@target=num::==*/ ??= getDouble();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:38:50: Context: Write to t@343
var /*@ type=num* */ v7 = t /*@target=num::+*/ += getInt();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:28:50: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:40:50: Context: Write to t@343
var /*@ type=num* */ v8 = t /*@target=num::+*/ += getNum();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:29:50: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:42:50: Context: Write to t@343
var /*@ type=num* */ v9 = t /*@target=num::+*/ += getDouble();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:30:49: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:44:49: Context: Write to t@343
var /*@ type=num* */ v10 = /*@target=num::+*/ ++t;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:31:85: Context: Write to t@343
- var /*@ type=num* */ v11 = /*@ type=num* */ t /*@ type=num* */ /*@target=num::+*/ ++;
- ^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:35:34: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:47:43: Context: Write to t@343
+ /*@ type=num* */ /*@target=num::+*/ ++;
+ ^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:51:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:36:34: Context: Write to t@343
- var /*@ type=double* */ v6 = t ??= getDouble();
- ^^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:37:56: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:53:54: Context: Write to t@343
+ var /*@ type=double* */ v6 = t /*@target=num::==*/ ??= getDouble();
+ ^^^
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:55:56: Context: Write to t@343
var /*@ type=double* */ v7 = t /*@target=double::+*/ += getInt();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:38:56: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:57:56: Context: Write to t@343
var /*@ type=double* */ v8 = t /*@target=double::+*/ += getNum();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:39:56: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:59:56: Context: Write to t@343
var /*@ type=double* */ v9 = t /*@target=double::+*/ += getDouble();
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:40:55: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:61:55: Context: Write to t@343
var /*@ type=double* */ v10 = /*@target=double::+*/ ++t;
^^
-pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:42:49: Context: Write to t@343
+pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart:64:49: Context: Write to t@343
/*@ type=double* */ /*@target=double::+*/ ++;
^^
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
index 55d9fb1..e28b42c 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart
@@ -24,23 +24,62 @@
static void test(Test t) {
/*@ type=Test* */ /*@target=Object::==*/ t?. /*@target=Test::member*/
member = /*@ typeArgs=B* */ f();
- t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- t?. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
- t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- t?. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- --t?. /*@target=Test::member*/ member;
- t?. /*@target=Test::member*/ member--;
+
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ -- /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 =
/*@ type=Test* */ /*@target=Object::==*/ t?. /*@target=Test::member*/
member = /*@ typeArgs=B* */ f();
+
var /*@ type=B* */ v2 =
- t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 =
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 =
- t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 =
- t?. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t?. /*@target=Test::member*/ member;
- var /*@ type=B* */ v7 = t?. /*@target=Test::member*/ member--;
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 =
+ /*@ target=B::- */ -- /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+
+ var /*@ type=B* */ v7 =
+ /*@ target=Object::== */ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
index 6c00bcb4..60aa66d 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.expect
@@ -32,18 +32,19 @@
;
static method test(self::Test* t) → void {
let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
- let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
- let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
- self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
- self::B* v4 = let final self::Test* #t11 = t in #t11.==(null) ?{self::B*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t12 = t in #t12.==(null) ?{self::C*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t13 = t in #t13.==(null) ?{self::B*} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t14 = t in #t14.==(null) ?{self::B*} null : let final self::B* #t15 = #t14.{self::Test::member} in let final self::B* #t16 = #t14.{self::Test::member} = #t15.{self::B::-}(1) in #t15;
+ let final self::Test* #t2 = t in #t2.{core::Object::==}(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
+ let final self::Test* #t3 = t in #t3.{core::Object::==}(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t4 = t in #t4.{core::Object::==}(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t5 = t in #t5.{core::Object::==}(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ let final self::Test* #t6 = t in #t6.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t7 = #t6.{self::Test::member}.{self::B::-}(1) in let final void #t8 = #t6.{self::Test::member} = #t7 in #t7;
+ let final self::Test* #t9 = t in #t9.{core::Object::==}(null) ?{self::B*} null : #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::-}(1);
+ self::B* v1 = let final self::Test* #t10 = t in #t10.{core::Object::==}(null) ?{self::B*} null : #t10.{self::Test::member} = self::f<self::B*>();
+ self::B* v2 = let final self::Test* #t11 = t in #t11.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t12 = #t11.{self::Test::member} in #t12.{core::Object::==}(null) ?{self::B*} #t11.{self::Test::member} = self::f<self::B*>() : #t12;
+ self::A* v3 = let final self::Test* #t13 = t in #t13.{core::Object::==}(null) ?{self::A*} null : let final self::A* #t14 = #t13.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t15 = #t13.{self::Test::member} = #t14 in #t14;
+ self::B* v4 = let final self::Test* #t16 = t in #t16.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t17 = #t16.{self::Test::member}.{self::B::*}(self::f<self::B*>()) in let final void #t18 = #t16.{self::Test::member} = #t17 in #t17;
+ self::C* v5 = let final self::Test* #t19 = t in #t19.{core::Object::==}(null) ?{self::C*} null : let final self::C* #t20 = #t19.{self::Test::member}.{self::B::&}(self::f<self::A*>()) in let final void #t21 = #t19.{self::Test::member} = #t20 in #t20;
+ self::B* v6 = let final self::Test* #t22 = t in #t22.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t23 = #t22.{self::Test::member}.{self::B::-}(1) in let final void #t24 = #t22.{self::Test::member} = #t23 in #t23;
+ self::B* v7 = let final self::Test* #t25 = t in #t25.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t26 = #t25.{self::Test::member} in let final void #t27 = #t25.{self::Test::member} = #t26.{self::B::-}(1) in #t26;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
index 6c00bcb4..60aa66d 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -32,18 +32,19 @@
;
static method test(self::Test* t) → void {
let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
- let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
- let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
- self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
- self::B* v4 = let final self::Test* #t11 = t in #t11.==(null) ?{self::B*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t12 = t in #t12.==(null) ?{self::C*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t13 = t in #t13.==(null) ?{self::B*} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t14 = t in #t14.==(null) ?{self::B*} null : let final self::B* #t15 = #t14.{self::Test::member} in let final self::B* #t16 = #t14.{self::Test::member} = #t15.{self::B::-}(1) in #t15;
+ let final self::Test* #t2 = t in #t2.{core::Object::==}(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
+ let final self::Test* #t3 = t in #t3.{core::Object::==}(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t4 = t in #t4.{core::Object::==}(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t5 = t in #t5.{core::Object::==}(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ let final self::Test* #t6 = t in #t6.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t7 = #t6.{self::Test::member}.{self::B::-}(1) in let final void #t8 = #t6.{self::Test::member} = #t7 in #t7;
+ let final self::Test* #t9 = t in #t9.{core::Object::==}(null) ?{self::B*} null : #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::-}(1);
+ self::B* v1 = let final self::Test* #t10 = t in #t10.{core::Object::==}(null) ?{self::B*} null : #t10.{self::Test::member} = self::f<self::B*>();
+ self::B* v2 = let final self::Test* #t11 = t in #t11.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t12 = #t11.{self::Test::member} in #t12.{core::Object::==}(null) ?{self::B*} #t11.{self::Test::member} = self::f<self::B*>() : #t12;
+ self::A* v3 = let final self::Test* #t13 = t in #t13.{core::Object::==}(null) ?{self::A*} null : let final self::A* #t14 = #t13.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t15 = #t13.{self::Test::member} = #t14 in #t14;
+ self::B* v4 = let final self::Test* #t16 = t in #t16.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t17 = #t16.{self::Test::member}.{self::B::*}(self::f<self::B*>()) in let final void #t18 = #t16.{self::Test::member} = #t17 in #t17;
+ self::C* v5 = let final self::Test* #t19 = t in #t19.{core::Object::==}(null) ?{self::C*} null : let final self::C* #t20 = #t19.{self::Test::member}.{self::B::&}(self::f<self::A*>()) in let final void #t21 = #t19.{self::Test::member} = #t20 in #t20;
+ self::B* v6 = let final self::Test* #t22 = t in #t22.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t23 = #t22.{self::Test::member}.{self::B::-}(1) in let final void #t24 = #t22.{self::Test::member} = #t23 in #t23;
+ self::B* v7 = let final self::Test* #t25 = t in #t25.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t26 = #t25.{self::Test::member} in let final void #t27 = #t25.{self::Test::member} = #t26.{self::B::-}(1) in #t26;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
index eab5036..6b4a521 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart
@@ -15,10 +15,24 @@
static void test(Test1 t) {
var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Object::==*/ t
?. /*@target=Test1::prop*/ prop = getInt();
- var /*@ type=int* */ v4 = t?. /*@target=Test1::prop*/ prop ??= getInt();
- var /*@ type=int* */ v7 = t?. /*@target=Test1::prop*/ prop += getInt();
- var /*@ type=int* */ v10 = ++t?. /*@target=Test1::prop*/ prop;
- var /*@ type=int* */ v11 = t?. /*@target=Test1::prop*/ prop++;
+
+ var /*@ type=int* */ v4 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=int* */ v7 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+
+ var /*@ type=int* */ v11 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@target=num::+*/ ++;
}
}
@@ -28,18 +42,49 @@
static void test(Test2 t) {
var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getInt();
+
var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getNum();
+
var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getDouble();
- var /*@ type=num* */ v4 = t?. /*@target=Test2::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t?. /*@target=Test2::prop*/ prop ??= getNum();
- var /*@ type=num* */ v6 = t?. /*@target=Test2::prop*/ prop ??= getDouble();
- var /*@ type=num* */ v7 = t?. /*@target=Test2::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t?. /*@target=Test2::prop*/ prop += getNum();
- var /*@ type=num* */ v9 = t?. /*@target=Test2::prop*/ prop += getDouble();
- var /*@ type=num* */ v10 = ++t?. /*@target=Test2::prop*/ prop;
- var /*@ type=num* */ v11 = t?. /*@target=Test2::prop*/ prop++;
+
+ var /*@ type=num* */ v4 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=num* */ v7 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=num* */ v9 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::+*/ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+
+ var /*@ type=num* */ v11 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@target=num::+*/ ++;
}
}
@@ -50,14 +95,35 @@
var /*@ type=double* */ v3 =
/*@ type=Test3* */ /*@target=Object::==*/ t
?. /*@target=Test3::prop*/ prop = getDouble();
+
var /*@ type=double* */ v6 =
- t?. /*@target=Test3::prop*/ prop ??= getDouble();
- var /*@ type=double* */ v7 = t?. /*@target=Test3::prop*/ prop += getInt();
- var /*@ type=double* */ v8 = t?. /*@target=Test3::prop*/ prop += getNum();
+ /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=double* */ v7 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=double::+*/ += getInt();
+
+ var /*@ type=double* */ v8 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=double::+*/ += getNum();
+
var /*@ type=double* */ v9 =
- t?. /*@target=Test3::prop*/ prop += getDouble();
- var /*@ type=double* */ v10 = ++t?. /*@target=Test3::prop*/ prop;
- var /*@ type=double* */ v11 = t?. /*@target=Test3::prop*/ prop++;
+ /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=double::+*/ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++
+ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+
+ var /*@ type=double* */ v11 =
+ /*@target=Object::==*/ t
+ ?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@target=double::+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
index 891b1bd..c7353f0 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.expect
@@ -9,10 +9,10 @@
;
static method test(self::Test1* t) → void {
core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
- core::int* v4 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
- core::int* v7 = let final self::Test1* #t4 = t in #t4.==(null) ?{core::int*} null : #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(self::getInt());
- core::int* v10 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::int*} null : #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(1);
- core::int* v11 = let final self::Test1* #t6 = t in #t6.==(null) ?{core::int*} null : let final core::int* #t7 = #t6.{self::Test1::prop} in let final core::int* #t8 = #t6.{self::Test1::prop} = #t7.{core::num::+}(1) in #t7;
+ core::int* v4 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
+ core::int* v7 = let final self::Test1* #t4 = t in #t4.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t5 = #t4.{self::Test1::prop}.{core::num::+}(self::getInt()) in let final void #t6 = #t4.{self::Test1::prop} = #t5 in #t5;
+ core::int* v10 = let final self::Test1* #t7 = t in #t7.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t8 = #t7.{self::Test1::prop}.{core::num::+}(1) in let final void #t9 = #t7.{self::Test1::prop} = #t8 in #t8;
+ core::int* v11 = let final self::Test1* #t10 = t in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = #t10.{self::Test1::prop} in let final void #t12 = #t10.{self::Test1::prop} = #t11.{core::num::+}(1) in #t11;
}
}
class Test2 extends core::Object {
@@ -21,17 +21,17 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t9 = t in #t9.{core::Object::==}(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t11 = t in #t11.{core::Object::==}(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
- core::num* v4 = let final self::Test2* #t12 = t in #t12.==(null) ?{core::num*} null : let final core::num* #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num*} #t12.{self::Test2::prop} = self::getInt() : #t13;
- core::num* v5 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : let final core::num* #t15 = #t14.{self::Test2::prop} in #t15.{core::num::==}(null) ?{core::num*} #t14.{self::Test2::prop} = self::getNum() : #t15;
- core::num* v6 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getDouble() : #t17;
- core::num* v7 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : #t18.{self::Test2::prop} = #t18.{self::Test2::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test2* #t19 = t in #t19.==(null) ?{core::num*} null : #t19.{self::Test2::prop} = #t19.{self::Test2::prop}.{core::num::+}(self::getNum());
- core::num* v9 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : #t20.{self::Test2::prop} = #t20.{self::Test2::prop}.{core::num::+}(self::getDouble());
- core::num* v10 = let final self::Test2* #t21 = t in #t21.==(null) ?{core::num*} null : #t21.{self::Test2::prop} = #t21.{self::Test2::prop}.{core::num::+}(1);
- core::num* v11 = let final self::Test2* #t22 = t in #t22.==(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop} in let final core::num* #t24 = #t22.{self::Test2::prop} = #t23.{core::num::+}(1) in #t23;
+ core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
+ core::num* v4 = let final self::Test2* #t16 = t in #t16.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
+ core::num* v5 = let final self::Test2* #t18 = t in #t18.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
+ core::num* v6 = let final self::Test2* #t20 = t in #t20.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
+ core::num* v7 = let final self::Test2* #t22 = t in #t22.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop}.{core::num::+}(self::getInt()) in let final void #t24 = #t22.{self::Test2::prop} = #t23 in #t23;
+ core::num* v8 = let final self::Test2* #t25 = t in #t25.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t26 = #t25.{self::Test2::prop}.{core::num::+}(self::getNum()) in let final void #t27 = #t25.{self::Test2::prop} = #t26 in #t26;
+ core::num* v9 = let final self::Test2* #t28 = t in #t28.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t29 = #t28.{self::Test2::prop}.{core::num::+}(self::getDouble()) in let final void #t30 = #t28.{self::Test2::prop} = #t29 in #t29;
+ core::num* v10 = let final self::Test2* #t31 = t in #t31.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t32 = #t31.{self::Test2::prop}.{core::num::+}(1) in let final void #t33 = #t31.{self::Test2::prop} = #t32 in #t32;
+ core::num* v11 = let final self::Test2* #t34 = t in #t34.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t35 = #t34.{self::Test2::prop} in let final void #t36 = #t34.{self::Test2::prop} = #t35.{core::num::+}(1) in #t35;
}
}
class Test3 extends core::Object {
@@ -40,13 +40,13 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::double* v3 = let final self::Test3* #t25 = t in #t25.{core::Object::==}(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
- core::double* v6 = let final self::Test3* #t26 = t in #t26.==(null) ?{core::double*} null : let final core::double* #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double*} #t26.{self::Test3::prop} = self::getDouble() : #t27;
- core::double* v7 = let final self::Test3* #t28 = t in #t28.==(null) ?{core::double*} null : #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
- core::double* v8 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::double*} null : #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
- core::double* v9 = let final self::Test3* #t30 = t in #t30.==(null) ?{core::double*} null : #t30.{self::Test3::prop} = #t30.{self::Test3::prop}.{core::double::+}(self::getDouble());
- core::double* v10 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::double*} null : #t31.{self::Test3::prop} = #t31.{self::Test3::prop}.{core::double::+}(1);
- core::double* v11 = let final self::Test3* #t32 = t in #t32.==(null) ?{core::double*} null : let final core::double* #t33 = #t32.{self::Test3::prop} in let final core::double* #t34 = #t32.{self::Test3::prop} = #t33.{core::double::+}(1) in #t33;
+ core::double* v3 = let final self::Test3* #t37 = t in #t37.{core::Object::==}(null) ?{core::double*} null : #t37.{self::Test3::prop} = self::getDouble();
+ core::double* v6 = let final self::Test3* #t38 = t in #t38.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t39 = #t38.{self::Test3::prop} in #t39.{core::num::==}(null) ?{core::double*} #t38.{self::Test3::prop} = self::getDouble() : #t39;
+ core::double* v7 = let final self::Test3* #t40 = t in #t40.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t41 = #t40.{self::Test3::prop}.{core::double::+}(self::getInt()) in let final void #t42 = #t40.{self::Test3::prop} = #t41 in #t41;
+ core::double* v8 = let final self::Test3* #t43 = t in #t43.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t44 = #t43.{self::Test3::prop}.{core::double::+}(self::getNum()) in let final void #t45 = #t43.{self::Test3::prop} = #t44 in #t44;
+ core::double* v9 = let final self::Test3* #t46 = t in #t46.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t47 = #t46.{self::Test3::prop}.{core::double::+}(self::getDouble()) in let final void #t48 = #t46.{self::Test3::prop} = #t47 in #t47;
+ core::double* v10 = let final self::Test3* #t49 = t in #t49.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t50 = #t49.{self::Test3::prop}.{core::double::+}(1) in let final void #t51 = #t49.{self::Test3::prop} = #t50 in #t50;
+ core::double* v11 = let final self::Test3* #t52 = t in #t52.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t53 = #t52.{self::Test3::prop} in let final void #t54 = #t52.{self::Test3::prop} = #t53.{core::double::+}(1) in #t53;
}
}
static method getInt() → core::int*
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
index 891b1bd..c7353f0 100644
--- a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -9,10 +9,10 @@
;
static method test(self::Test1* t) → void {
core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
- core::int* v4 = let final self::Test1* #t2 = t in #t2.==(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
- core::int* v7 = let final self::Test1* #t4 = t in #t4.==(null) ?{core::int*} null : #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(self::getInt());
- core::int* v10 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::int*} null : #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(1);
- core::int* v11 = let final self::Test1* #t6 = t in #t6.==(null) ?{core::int*} null : let final core::int* #t7 = #t6.{self::Test1::prop} in let final core::int* #t8 = #t6.{self::Test1::prop} = #t7.{core::num::+}(1) in #t7;
+ core::int* v4 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int*} #t2.{self::Test1::prop} = self::getInt() : #t3;
+ core::int* v7 = let final self::Test1* #t4 = t in #t4.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t5 = #t4.{self::Test1::prop}.{core::num::+}(self::getInt()) in let final void #t6 = #t4.{self::Test1::prop} = #t5 in #t5;
+ core::int* v10 = let final self::Test1* #t7 = t in #t7.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t8 = #t7.{self::Test1::prop}.{core::num::+}(1) in let final void #t9 = #t7.{self::Test1::prop} = #t8 in #t8;
+ core::int* v11 = let final self::Test1* #t10 = t in #t10.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t11 = #t10.{self::Test1::prop} in let final void #t12 = #t10.{self::Test1::prop} = #t11.{core::num::+}(1) in #t11;
}
}
class Test2 extends core::Object {
@@ -21,17 +21,17 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t9 = t in #t9.{core::Object::==}(null) ?{core::int*} null : #t9.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : #t10.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t11 = t in #t11.{core::Object::==}(null) ?{core::double*} null : #t11.{self::Test2::prop} = self::getDouble();
- core::num* v4 = let final self::Test2* #t12 = t in #t12.==(null) ?{core::num*} null : let final core::num* #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num*} #t12.{self::Test2::prop} = self::getInt() : #t13;
- core::num* v5 = let final self::Test2* #t14 = t in #t14.==(null) ?{core::num*} null : let final core::num* #t15 = #t14.{self::Test2::prop} in #t15.{core::num::==}(null) ?{core::num*} #t14.{self::Test2::prop} = self::getNum() : #t15;
- core::num* v6 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getDouble() : #t17;
- core::num* v7 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : #t18.{self::Test2::prop} = #t18.{self::Test2::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test2* #t19 = t in #t19.==(null) ?{core::num*} null : #t19.{self::Test2::prop} = #t19.{self::Test2::prop}.{core::num::+}(self::getNum());
- core::num* v9 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : #t20.{self::Test2::prop} = #t20.{self::Test2::prop}.{core::num::+}(self::getDouble());
- core::num* v10 = let final self::Test2* #t21 = t in #t21.==(null) ?{core::num*} null : #t21.{self::Test2::prop} = #t21.{self::Test2::prop}.{core::num::+}(1);
- core::num* v11 = let final self::Test2* #t22 = t in #t22.==(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop} in let final core::num* #t24 = #t22.{self::Test2::prop} = #t23.{core::num::+}(1) in #t23;
+ core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
+ core::num* v4 = let final self::Test2* #t16 = t in #t16.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
+ core::num* v5 = let final self::Test2* #t18 = t in #t18.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
+ core::num* v6 = let final self::Test2* #t20 = t in #t20.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
+ core::num* v7 = let final self::Test2* #t22 = t in #t22.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop}.{core::num::+}(self::getInt()) in let final void #t24 = #t22.{self::Test2::prop} = #t23 in #t23;
+ core::num* v8 = let final self::Test2* #t25 = t in #t25.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t26 = #t25.{self::Test2::prop}.{core::num::+}(self::getNum()) in let final void #t27 = #t25.{self::Test2::prop} = #t26 in #t26;
+ core::num* v9 = let final self::Test2* #t28 = t in #t28.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t29 = #t28.{self::Test2::prop}.{core::num::+}(self::getDouble()) in let final void #t30 = #t28.{self::Test2::prop} = #t29 in #t29;
+ core::num* v10 = let final self::Test2* #t31 = t in #t31.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t32 = #t31.{self::Test2::prop}.{core::num::+}(1) in let final void #t33 = #t31.{self::Test2::prop} = #t32 in #t32;
+ core::num* v11 = let final self::Test2* #t34 = t in #t34.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t35 = #t34.{self::Test2::prop} in let final void #t36 = #t34.{self::Test2::prop} = #t35.{core::num::+}(1) in #t35;
}
}
class Test3 extends core::Object {
@@ -40,13 +40,13 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::double* v3 = let final self::Test3* #t25 = t in #t25.{core::Object::==}(null) ?{core::double*} null : #t25.{self::Test3::prop} = self::getDouble();
- core::double* v6 = let final self::Test3* #t26 = t in #t26.==(null) ?{core::double*} null : let final core::double* #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double*} #t26.{self::Test3::prop} = self::getDouble() : #t27;
- core::double* v7 = let final self::Test3* #t28 = t in #t28.==(null) ?{core::double*} null : #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
- core::double* v8 = let final self::Test3* #t29 = t in #t29.==(null) ?{core::double*} null : #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
- core::double* v9 = let final self::Test3* #t30 = t in #t30.==(null) ?{core::double*} null : #t30.{self::Test3::prop} = #t30.{self::Test3::prop}.{core::double::+}(self::getDouble());
- core::double* v10 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::double*} null : #t31.{self::Test3::prop} = #t31.{self::Test3::prop}.{core::double::+}(1);
- core::double* v11 = let final self::Test3* #t32 = t in #t32.==(null) ?{core::double*} null : let final core::double* #t33 = #t32.{self::Test3::prop} in let final core::double* #t34 = #t32.{self::Test3::prop} = #t33.{core::double::+}(1) in #t33;
+ core::double* v3 = let final self::Test3* #t37 = t in #t37.{core::Object::==}(null) ?{core::double*} null : #t37.{self::Test3::prop} = self::getDouble();
+ core::double* v6 = let final self::Test3* #t38 = t in #t38.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t39 = #t38.{self::Test3::prop} in #t39.{core::num::==}(null) ?{core::double*} #t38.{self::Test3::prop} = self::getDouble() : #t39;
+ core::double* v7 = let final self::Test3* #t40 = t in #t40.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t41 = #t40.{self::Test3::prop}.{core::double::+}(self::getInt()) in let final void #t42 = #t40.{self::Test3::prop} = #t41 in #t41;
+ core::double* v8 = let final self::Test3* #t43 = t in #t43.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t44 = #t43.{self::Test3::prop}.{core::double::+}(self::getNum()) in let final void #t45 = #t43.{self::Test3::prop} = #t44 in #t44;
+ core::double* v9 = let final self::Test3* #t46 = t in #t46.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t47 = #t46.{self::Test3::prop}.{core::double::+}(self::getDouble()) in let final void #t48 = #t46.{self::Test3::prop} = #t47 in #t47;
+ core::double* v10 = let final self::Test3* #t49 = t in #t49.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t50 = #t49.{self::Test3::prop}.{core::double::+}(1) in let final void #t51 = #t49.{self::Test3::prop} = #t50 in #t50;
+ core::double* v11 = let final self::Test3* #t52 = t in #t52.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t53 = #t52.{self::Test3::prop} in let final void #t54 = #t52.{self::Test3::prop} = #t53.{core::double::+}(1) in #t53;
}
}
static method getInt() → core::int*
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.outline.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.outline.expect
index e56ff7a..1ce9cd4 100644
--- a/pkg/front_end/testcases/inference/non_const_invocation.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
;
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.expect
index 1124614..310bddf 100644
--- a/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect
index 1124614..310bddf 100644
--- a/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart b/pkg/front_end/testcases/inference/null_coalescing_operator.dart
index ac55bb7..bbf853c 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator.dart
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart
@@ -7,6 +7,7 @@
main() {
List<int> x;
- var /*@ type=List<int*>* */ y = x ?? /*@ typeArgs=int* */ [];
+ var /*@ type=List<int*>* */ y =
+ x /*@ target=List::== */ ?? /*@ typeArgs=int* */ [];
List<int> z = y;
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.expect
index f2e6ea1..ec63329 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.expect
@@ -4,6 +4,6 @@
static method main() → dynamic {
core::List<core::int*>* x;
- core::List<core::int*>* y = let final core::List<core::int*>* #t1 = x in #t1.==(null) ?{core::List<core::int*>*} <core::int*>[] : #t1;
+ core::List<core::int*>* y = let final core::List<core::int*>* #t1 = x in #t1.{core::List::==}(null) ?{core::List<core::int*>*} <core::int*>[] : #t1;
core::List<core::int*>* z = y;
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect
index f2e6ea1..ec63329 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect
@@ -4,6 +4,6 @@
static method main() → dynamic {
core::List<core::int*>* x;
- core::List<core::int*>* y = let final core::List<core::int*>* #t1 = x in #t1.==(null) ?{core::List<core::int*>*} <core::int*>[] : #t1;
+ core::List<core::int*>* y = let final core::List<core::int*>* #t1 = x in #t1.{core::List::==}(null) ?{core::List<core::int*>*} <core::int*>[] : #t1;
core::List<core::int*>* z = y;
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
index c8888a7..0836850 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart
@@ -7,5 +7,5 @@
main() {
List<int> x;
- List<num> y = x ?? /*@ typeArgs=num* */ [];
+ List<num> y = x /*@ target=List::== */ ?? /*@ typeArgs=num* */ [];
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.expect
index 1b28952..c4ca3fe 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.expect
@@ -4,5 +4,5 @@
static method main() → dynamic {
core::List<core::int*>* x;
- core::List<core::num*>* y = let final core::List<core::int*>* #t1 = x in #t1.==(null) ?{core::List<core::num*>*} <core::num*>[] : #t1;
+ core::List<core::num*>* y = let final core::List<core::int*>* #t1 = x in #t1.{core::List::==}(null) ?{core::List<core::num*>*} <core::num*>[] : #t1;
}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect
index 1b28952..c4ca3fe 100644
--- a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect
@@ -4,5 +4,5 @@
static method main() → dynamic {
core::List<core::int*>* x;
- core::List<core::num*>* y = let final core::List<core::int*>* #t1 = x in #t1.==(null) ?{core::List<core::num*>*} <core::num*>[] : #t1;
+ core::List<core::num*>* y = let final core::List<core::int*>* #t1 = x in #t1.{core::List::==}(null) ?{core::List<core::num*>*} <core::num*>[] : #t1;
}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
index e85b749..757a80f 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart
@@ -15,9 +15,9 @@
}
void opEq(int b) {
- /*@target=C::a*/ a += b;
- /*@target=C::a*/ a -= b;
- /*@target=C::a*/ a *= b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::+*/ += b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::-*/ -= b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::**/ *= b;
}
}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
index 60ab287..17f1189 100644
--- a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart
@@ -15,9 +15,9 @@
}
void opEq(T b) {
- /*@target=C::a*/ a += b;
- /*@target=C::a*/ a -= b;
- /*@target=C::a*/ a *= b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::+*/ += b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::-*/ -= b;
+ /*@target=C::a*/ /*@target=C::a*/ a /*@target=num::**/ *= b;
}
}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart b/pkg/front_end/testcases/inference/super_index_set.dart
index 82ad78d..195028e 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart
+++ b/pkg/front_end/testcases/inference/super_index_set.dart
@@ -16,9 +16,8 @@
class C extends B {
void operator []=(Object x, Object y) {}
void h() {
- // Note: the index is inferred with an empty context due to issue 31336.
super /*@target=B::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=String* */ f();
+ /*@ typeArgs=int* */ f()] = /*@ typeArgs=String* */ f();
}
}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect b/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
index 7e58394..6683122 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
@@ -16,7 +16,7 @@
;
operator []=(core::Object* x, core::Object* y) → void {}
method h() → void {
- super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::int*, self::f<core::String*>());
+ super.{self::B::[]=}(self::f<core::int*>(), self::f<core::String*>());
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
index 7e58394..6683122 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
@@ -16,7 +16,7 @@
;
operator []=(core::Object* x, core::Object* y) → void {}
method h() → void {
- super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::int*, self::f<core::String*>());
+ super.{self::B::[]=}(self::f<core::int*>(), self::f<core::String*>());
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart b/pkg/front_end/testcases/inference/super_index_set_substitution.dart
index e686edc..f17da64 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart
@@ -16,9 +16,9 @@
class C<U> extends B<Future<U>> {
void operator []=(Object x, Object y) {}
void h() {
- // Note: the index is inferred with an empty context due to issue 31336.
super /*@target=B::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=List<Future<C::U*>*>* */ f();
+ /*@ typeArgs=Map<int*, Future<C::U*>*>* */ f()] =
+ /*@ typeArgs=List<Future<C::U*>*>* */ f();
}
}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
index 7827c2f..6d2e13b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
@@ -17,7 +17,7 @@
;
operator []=(generic-covariant-impl core::Object* x, generic-covariant-impl core::Object* y) → void {}
method h() → void {
- super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::Map<core::int*, asy::Future<self::C::U*>*>*, self::f<core::List<asy::Future<self::C::U*>*>*>());
+ super.{self::B::[]=}(self::f<core::Map<core::int*, asy::Future<self::C::U*>*>*>(), self::f<core::List<asy::Future<self::C::U*>*>*>());
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
index 7827c2f..6d2e13b 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
@@ -17,7 +17,7 @@
;
operator []=(generic-covariant-impl core::Object* x, generic-covariant-impl core::Object* y) → void {}
method h() → void {
- super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::Map<core::int*, asy::Future<self::C::U*>*>*, self::f<core::List<asy::Future<self::C::U*>*>*>());
+ super.{self::B::[]=}(self::f<core::Map<core::int*, asy::Future<self::C::U*>*>*>(), self::f<core::List<asy::Future<self::C::U*>*>*>());
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart b/pkg/front_end/testcases/inference/unresolved_super.dart
index f9e96ce..fc14162 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart
@@ -9,10 +9,10 @@
class C {
void test() {
- var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
+ /*var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
var /*@type=dynamic*/ v2 = super.bar;
var /*@type=dynamic*/ v3 = super[0];
- var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
+ var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();*/
var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
}
}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
index 0addd70..d7d9a11 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
@@ -2,25 +2,9 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Error: Superclass has no method named 'foo'.
-// var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
-// ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:13:38: Error: Superclass has no getter named 'bar'.
-// var /*@type=dynamic*/ v2 = super.bar;
-// ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:14:37: Error: Superclass has no method named '[]'.
-// var /*@type=dynamic*/ v3 = super[0];
-// ^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:15:38: Error: Superclass has no setter named 'bar'.
-// var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
-// ^^^
-//
// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
// var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-// ^
+// ^^^
//
import self as self;
import "dart:core" as core;
@@ -30,11 +14,9 @@
: super core::Object::•()
;
method test() → void {
- dynamic v1 = super.foo(self::f<dynamic>());
- dynamic v2 = super.bar;
- dynamic v3 = super.[](0);
- dynamic v4 = super.bar = self::f<dynamic>();
- dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = super.[]=(#t1, #t2) in #t2;
+ dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
+ var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+ ^^^" in #t2;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..d7d9a11
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
+// var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+ synthetic constructor •() → self::C*
+ : super core::Object::•()
+ ;
+ method test() → void {
+ dynamic v5 = let final core::int* #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final void #t3 = invalid-expression "pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
+ var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+ ^^^" in #t2;
+ }
+}
+static method f<T extends core::Object* = dynamic>() → self::f::T*
+ return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.outline.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.outline.expect
index e56ff7a..1ce9cd4 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
;
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
index c1f792b..6895096 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
index c1f792b..6895096 100644
--- a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
+typedef F<contravariant U extends core::Object* = dynamic, V extends core::Object* = dynamic> = (U*) →* V*;
class Foo<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::Foo<self::Foo::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
index f1f28c4..0501678 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart
@@ -27,15 +27,20 @@
/*@target=Test::member*/ /*@target=Test::member*/ member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
- /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
- /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
- -- /*@target=Test::member*/ member;
+ /*@ target=B::- */ --
+ /*@target=Test::member*/ /*@target=Test::member*/ member;
- /*@target=Test::member*/ member--;
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
var /*@ type=B* */ v1 = /*@target=Test::member*/ member =
/*@ typeArgs=B* */ f();
@@ -44,18 +49,27 @@
member
/*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = /*@target=Test::member*/ member +=
- /*@ typeArgs=dynamic */ f();
+ var /*@ type=A* */ v3 =
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ +=
+ /*@ typeArgs=C* */ f();
- var /*@ type=B* */ v4 = /*@target=Test::member*/ member *=
- /*@ typeArgs=dynamic */ f();
+ var /*@ type=B* */ v4 =
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *=
+ /*@ typeArgs=B* */ f();
- var /*@ type=C* */ v5 = /*@target=Test::member*/ member &=
- /*@ typeArgs=dynamic */ f();
+ var /*@ type=C* */ v5 =
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &=
+ /*@ typeArgs=A* */ f();
- var /*@ type=B* */ v6 = -- /*@target=Test::member*/ member;
+ var /*@ type=B* */ v6 = /*@ target=B::- */ --
+ /*@target=Test::member*/ /*@target=Test::member*/ member;
- var /*@ type=B* */ v7 = /*@target=Test::member*/ member--;
+ var /*@ type=B* */ v7 =
+ /*@ type=B* */ /*@target=Test::member*/ /*@target=Test::member*/
+ member /*@ type=B* */ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.expect
index 9986ad5..043ccf2 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.expect
@@ -33,16 +33,16 @@
method test() → void {
this.{self::Test::member} = self::f<self::B*>();
this.{self::Test::member}.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : null;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v1 = this.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : #t1;
- self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = this.{self::Test::member} in let final self::B* #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect
index 9986ad5..043ccf2 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect
@@ -33,16 +33,16 @@
method test() → void {
this.{self::Test::member} = self::f<self::B*>();
this.{self::Test::member}.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : null;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v1 = this.{self::Test::member} = self::f<self::B*>();
self::B* v2 = let final self::B* #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B*} this.{self::Test::member} = self::f<self::B*>() : #t1;
- self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
+ self::A* v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ self::B* v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ self::C* v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<self::A*>());
self::B* v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
self::B* v7 = let final self::B* #t2 = this.{self::Test::member} in let final self::B* #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
index cfabd2b..e042927 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart
@@ -23,13 +23,18 @@
var /*@ type=num* */ v5 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
/*@ target=num::== */ ??= getNum();
- var /*@ type=int* */ v7 = /*@target=Test1::t*/ t += getInt();
+ var /*@ type=int* */ v7 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::+ */ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test1::t*/ t += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ target=num::+ */ += getNum();
- var /*@ type=int* */ v10 = ++ /*@target=Test1::t*/ t;
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
+ /*@target=Test1::t*/ /*@target=Test1::t*/ t;
- var /*@ type=int* */ v11 = /*@target=Test1::t*/ t++;
+ var /*@ type=int* */ v11 =
+ /*@ type=int* */ /*@target=Test1::t*/ /*@target=Test1::t*/ t
+ /*@ type=int* */ /*@ target=num::+ */ ++;
}
}
@@ -52,15 +57,21 @@
var /*@ type=num* */ v6 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
/*@ target=num::== */ ??= getDouble();
- var /*@ type=num* */ v7 = /*@target=Test2::t*/ t += getInt();
+ var /*@ type=num* */ v7 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getInt();
- var /*@ type=num* */ v8 = /*@target=Test2::t*/ t += getNum();
+ var /*@ type=num* */ v8 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getNum();
- var /*@ type=num* */ v9 = /*@target=Test2::t*/ t += getDouble();
+ var /*@ type=num* */ v9 = /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ target=num::+ */ += getDouble();
- var /*@ type=num* */ v10 = ++ /*@target=Test2::t*/ t;
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++
+ /*@target=Test2::t*/ /*@target=Test2::t*/ t;
- var /*@ type=num* */ v11 = /*@target=Test2::t*/ t++;
+ var /*@ type=num* */ v11 =
+ /*@ type=num* */ /*@target=Test2::t*/ /*@target=Test2::t*/ t
+ /*@ type=num* */ /*@ target=num::+ */ ++;
}
}
@@ -78,15 +89,21 @@
var /*@ type=double* */ v6 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
/*@ target=num::== */ ??= getDouble();
- var /*@ type=double* */ v7 = /*@target=Test3::t*/ t += getInt();
+ var /*@ type=double* */ v7 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getInt();
- var /*@ type=double* */ v8 = /*@target=Test3::t*/ t += getNum();
+ var /*@ type=double* */ v8 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getNum();
- var /*@ type=double* */ v9 = /*@target=Test3::t*/ t += getDouble();
+ var /*@ type=double* */ v9 = /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ target=double::+ */ += getDouble();
- var /*@ type=double* */ v10 = ++ /*@target=Test3::t*/ t;
+ var /*@ type=double* */ v10 =
+ /*@ target=double::+ */ ++ /*@target=Test3::t*/ /*@target=Test3::t*/ t;
- var /*@ type=double* */ v11 = /*@target=Test3::t*/ t++;
+ var /*@ type=double* */ v11 =
+ /*@ type=double* */ /*@target=Test3::t*/ /*@target=Test3::t*/ t
+ /*@ type=double* */ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
index 4d3a249..4b6482c 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart
@@ -30,9 +30,9 @@
t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- t /*@target=Test::[]*/ [
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
@@ -55,9 +55,9 @@
var /*@ type=B* */ v1 = t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = t /*@target=Test::[]*/ [
+ var /*@ type=B* */ v2 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=B* */ f();
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
var /*@ type=A* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()]
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
index 4f4b0ba..4bebdb8 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart
@@ -37,9 +37,8 @@
t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
- t /*@target=Test::[]*/ [
- /*@ typeArgs=Index* */ f()]
- /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=A* */ f();
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
+ /*@target=Object::==*/ ??= /*@ typeArgs=A* */ f();
t /*@target=Test::[]*/ /*@target=Test::[]=*/ [/*@ typeArgs=Index* */ f()]
/*@ target=B::+ */ += /*@ typeArgs=E* */ f();
@@ -53,9 +52,9 @@
var /*@ type=A* */ v1 = t /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()] = /*@ typeArgs=A* */ f();
- var /*@ type=A* */ v2 = t /*@target=Test::[]*/ [
+ var /*@ type=A* */ v2 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()]
- /*@target=Object::==*/ /*@target=Test::[]=*/ ??= /*@ typeArgs=A* */ f();
+ /*@target=Object::==*/ ??= /*@ typeArgs=A* */ f();
var /*@ type=D* */ v3 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
/*@ typeArgs=Index* */ f()]
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
index 06b4ca1..6b091a7 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart
@@ -28,31 +28,54 @@
class Test extends Base {
void test() {
super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()];
- super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::-*/ --super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ [/*@ typeArgs=Index* */ f()];
+
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@ target=B::-*/ --;
+
var /*@ type=B* */ v1 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = super /*@target=Base::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 =
- --super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 =
- super /*@target=Base::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = super /*@target=Base::[]*/ /*@target=Base::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::-*/ --super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ [/*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@ target=B::-*/ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.expect
index ade4cca..6386cbd 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.expect
@@ -43,20 +43,20 @@
: super self::Base::•()
;
method test() → void {
- super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index*, super.{self::Base::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index*, super.{self::Base::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index*, super.{self::Base::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index*, super.{self::Base::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::A* v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A* #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B* #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::C* v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C* #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B* #t31 = super.{self::Base::[]}(#t30 as{TypeError} self::Index*) in let final void #t32 = super.{self::Base::[]=}(#t30 as{TypeError} self::Index*, #t31.{self::B::-}(1)) in #t31;
+ super.{self::Base::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in super.{self::Base::[]}(#t1).{core::Object::==}(null) ?{self::B*} super.{self::Base::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in super.{self::Base::[]=}(#t2, super.{self::Base::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in super.{self::Base::[]=}(#t3, super.{self::Base::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = super.{self::Base::[]}(#t5).{self::B::-}(1) in let final void #t7 = super.{self::Base::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in super.{self::Base::[]=}(#t8, super.{self::Base::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Index* #t9 = self::f<self::Index*>() in let final self::B* #t10 = self::f<self::B*>() in let final void #t11 = super.{self::Base::[]=}(#t9, #t10) in #t10;
+ self::B* v2 = let final self::Index* #t12 = self::f<self::Index*>() in let final self::B* #t13 = super.{self::Base::[]}(#t12) in #t13.{core::Object::==}(null) ?{self::B*} let final self::B* #t14 = self::f<self::B*>() in let final void #t15 = super.{self::Base::[]=}(#t12, #t14) in #t14 : #t13;
+ self::A* v3 = let final self::Index* #t16 = self::f<self::Index*>() in let final self::A* #t17 = super.{self::Base::[]}(#t16).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t18 = super.{self::Base::[]=}(#t16, #t17) in #t17;
+ self::B* v4 = let final self::Index* #t19 = self::f<self::Index*>() in let final self::B* #t20 = super.{self::Base::[]}(#t19).{self::B::*}(self::f<self::B*>()) in let final void #t21 = super.{self::Base::[]=}(#t19, #t20) in #t20;
+ self::C* v5 = let final self::Index* #t22 = self::f<self::Index*>() in let final self::C* #t23 = super.{self::Base::[]}(#t22).{self::B::&}(self::f<self::A*>()) in let final void #t24 = super.{self::Base::[]=}(#t22, #t23) in #t23;
+ self::B* v6 = let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = super.{self::Base::[]}(#t25).{self::B::-}(1) in let final void #t27 = super.{self::Base::[]=}(#t25, #t26) in #t26;
+ self::B* v7 = let final self::Index* #t28 = self::f<self::Index*>() in let final self::B* #t29 = super.{self::Base::[]}(#t28) in let final void #t30 = super.{self::Base::[]=}(#t28, #t29.{self::B::-}(1)) in #t29;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect
index ade4cca..6386cbd 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect
@@ -43,20 +43,20 @@
: super self::Base::•()
;
method test() → void {
- super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index*, super.{self::Base::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index*, super.{self::Base::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index*, super.{self::Base::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index*, super.{self::Base::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::A* v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A* #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B* #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::C* v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C* #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B* #t31 = super.{self::Base::[]}(#t30 as{TypeError} self::Index*) in let final void #t32 = super.{self::Base::[]=}(#t30 as{TypeError} self::Index*, #t31.{self::B::-}(1)) in #t31;
+ super.{self::Base::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in super.{self::Base::[]}(#t1).{core::Object::==}(null) ?{self::B*} super.{self::Base::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in super.{self::Base::[]=}(#t2, super.{self::Base::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in super.{self::Base::[]=}(#t3, super.{self::Base::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = super.{self::Base::[]}(#t5).{self::B::-}(1) in let final void #t7 = super.{self::Base::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in super.{self::Base::[]=}(#t8, super.{self::Base::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Index* #t9 = self::f<self::Index*>() in let final self::B* #t10 = self::f<self::B*>() in let final void #t11 = super.{self::Base::[]=}(#t9, #t10) in #t10;
+ self::B* v2 = let final self::Index* #t12 = self::f<self::Index*>() in let final self::B* #t13 = super.{self::Base::[]}(#t12) in #t13.{core::Object::==}(null) ?{self::B*} let final self::B* #t14 = self::f<self::B*>() in let final void #t15 = super.{self::Base::[]=}(#t12, #t14) in #t14 : #t13;
+ self::A* v3 = let final self::Index* #t16 = self::f<self::Index*>() in let final self::A* #t17 = super.{self::Base::[]}(#t16).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t18 = super.{self::Base::[]=}(#t16, #t17) in #t17;
+ self::B* v4 = let final self::Index* #t19 = self::f<self::Index*>() in let final self::B* #t20 = super.{self::Base::[]}(#t19).{self::B::*}(self::f<self::B*>()) in let final void #t21 = super.{self::Base::[]=}(#t19, #t20) in #t20;
+ self::C* v5 = let final self::Index* #t22 = self::f<self::Index*>() in let final self::C* #t23 = super.{self::Base::[]}(#t22).{self::B::&}(self::f<self::A*>()) in let final void #t24 = super.{self::Base::[]=}(#t22, #t23) in #t23;
+ self::B* v6 = let final self::Index* #t25 = self::f<self::Index*>() in let final self::B* #t26 = super.{self::Base::[]}(#t25).{self::B::-}(1) in let final void #t27 = super.{self::Base::[]=}(#t25, #t26) in #t26;
+ self::B* v7 = let final self::Index* #t28 = self::f<self::Index*>() in let final self::B* #t29 = super.{self::Base::[]}(#t28) in let final void #t30 = super.{self::Base::[]=}(#t28, #t29.{self::B::-}(1)) in #t29;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
index 0ea9a12e..ebd811a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart
@@ -20,129 +20,321 @@
abstract class Test1 extends Base<int, int> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=int* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=int* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=int* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=int* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=int* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test2 extends Base<int, num> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=int* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=int* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=int* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test3 extends Base<int, double> {
void test() {
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=int* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=int* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test4 extends Base<num, int> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test5 extends Base<num, num> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test6 extends Base<num, double> {
void test() {
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=num* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=num::+ */ ++;
}
}
abstract class Test7 extends Base<double, int> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=double* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=double::+ */ ++;
}
}
abstract class Test8 extends Base<double, num> {
void test() {
var /*@ type=int* */ v1 = super /*@target=Base::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = super /*@target=Base::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=double* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v4 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=double::+ */ ++;
}
}
abstract class Test9 extends Base<double, double> {
void test() {
var /*@ type=num* */ v2 = super /*@target=Base::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = super /*@target=Base::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = super /*@target=Base::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = super /*@target=Base::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = super /*@target=Base::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- var /*@ type=double* */ v11 = super /*@target=Base::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ super /*@target=Base::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getNum();
+
+ var /*@ type=double* */ v9 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x']
+ /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+ /*@target=Base::[]*/ /*@target=Base::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 =
+ super /*@target=Base::[]*/ /*@target=Base::[]=*/
+ ['x'] /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
index 3a8ed7b..82e6557 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
@@ -2,40 +2,40 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:55:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
-// ^
+// /*@ target=num::+ */ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:58:32: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
-// ^
+// var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:59:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v11 = super /*@target=Base::[]=*/ ['x']++;
-// ^
+// ['x'] /*@ target=num::+ */ ++;
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:112:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
-// ^
+// /*@ target=double::+ */ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:113:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
-// ^
+// /*@ target=double::+ */ += getNum();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:114:35: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
-// ^
+// var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:115:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v11 = super /*@target=Base::[]=*/ ['x']++;
-// ^
+// ['x'] /*@ target=double::+ */ ++;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -93,20 +93,20 @@
core::double* v3 = let final core::String* #t66 = "x" in let final core::double* #t67 = self::getDouble() in let final void #t68 = super.{self::Base::[]=}(#t66, #t67) in #t67;
core::num* v5 = let final core::String* #t69 = "x" in let final core::int* #t70 = super.{self::Base::[]}(#t69) in #t70.{core::num::==}(null) ?{core::num*} let final core::num* #t71 = self::getNum() as{TypeError} core::double* in let final void #t72 = super.{self::Base::[]=}(#t69, #t71) in #t71 : #t70;
core::num* v6 = let final core::String* #t73 = "x" in let final core::int* #t74 = super.{self::Base::[]}(#t73) in #t74.{core::num::==}(null) ?{core::num*} let final core::double* #t75 = self::getDouble() in let final void #t76 = super.{self::Base::[]=}(#t73, #t75) in #t75 : #t74;
- core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:55:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:108:34: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- ^" in super.{self::Base::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = super.{self::Base::[]=}(#t77, #t78) in #t78;
+ /*@ target=num::+ */ += getInt();
+ ^" in super.{self::Base::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = super.{self::Base::[]=}(#t77, #t78) in #t78;
core::num* v8 = let final core::String* #t81 = "x" in let final core::num* #t82 = super.{self::Base::[]}(#t81).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t83 = super.{self::Base::[]=}(#t81, #t82) in #t82;
core::double* v9 = let final core::String* #t84 = "x" in let final core::double* #t85 = super.{self::Base::[]}(#t84).{core::num::+}(self::getDouble()) in let final void #t86 = super.{self::Base::[]=}(#t84, #t85) in #t85;
- core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:58:32: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:118:53: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- ^" in super.{self::Base::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = super.{self::Base::[]=}(#t87, #t88) in #t88;
- core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = super.{self::Base::[]}(#t91) in let final void #t93 = super.{self::Base::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:59:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++super
+ ^" in super.{self::Base::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = super.{self::Base::[]=}(#t87, #t88) in #t88;
+ core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = super.{self::Base::[]}(#t91) in let final void #t93 = super.{self::Base::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:122:36: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v11 = super /*@target=Base::[]=*/ ['x']++;
- ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
+ ['x'] /*@ target=num::+ */ ++;
+ ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
}
}
abstract class Test4 extends self::Base<core::num*, core::int*> {
@@ -167,22 +167,22 @@
core::num* v2 = let final core::String* #t189 = "x" in let final core::num* #t190 = self::getNum() as{TypeError} core::int* in let final void #t191 = super.{self::Base::[]=}(#t189, #t190) in #t190;
core::num* v4 = let final core::String* #t192 = "x" in let final core::double* #t193 = super.{self::Base::[]}(#t192) in #t193.{core::num::==}(null) ?{core::num*} let final core::int* #t194 = self::getInt() in let final void #t195 = super.{self::Base::[]=}(#t192, #t194) in #t194 : #t193;
core::num* v5 = let final core::String* #t196 = "x" in let final core::double* #t197 = super.{self::Base::[]}(#t196) in #t197.{core::num::==}(null) ?{core::num*} let final core::num* #t198 = self::getNum() as{TypeError} core::int* in let final void #t199 = super.{self::Base::[]=}(#t196, #t198) in #t198 : #t197;
- core::double* v7 = let final core::String* #t200 = "x" in let final core::double* #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:112:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v7 = let final core::String* #t200 = "x" in let final core::double* #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:248:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v7 = super /*@target=Base::[]=*/ ['x'] += getInt();
- ^" in super.{self::Base::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = super.{self::Base::[]=}(#t200, #t201) in #t201;
- core::double* v8 = let final core::String* #t204 = "x" in let final core::double* #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:113:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@ target=double::+ */ += getInt();
+ ^" in super.{self::Base::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = super.{self::Base::[]=}(#t200, #t201) in #t201;
+ core::double* v8 = let final core::String* #t204 = "x" in let final core::double* #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:252:37: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v8 = super /*@target=Base::[]=*/ ['x'] += getNum();
- ^" in super.{self::Base::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = super.{self::Base::[]=}(#t204, #t205) in #t205;
- core::double* v10 = let final core::String* #t208 = "x" in let final core::double* #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:114:35: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@ target=double::+ */ += getNum();
+ ^" in super.{self::Base::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = super.{self::Base::[]=}(#t204, #t205) in #t205;
+ core::double* v10 = let final core::String* #t208 = "x" in let final core::double* #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:254:59: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v10 = ++super /*@target=Base::[]=*/ ['x'];
- ^" in super.{self::Base::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = super.{self::Base::[]=}(#t208, #t209) in #t209;
- core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = super.{self::Base::[]}(#t212) in let final void #t214 = super.{self::Base::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:115:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++super
+ ^" in super.{self::Base::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = super.{self::Base::[]=}(#t208, #t209) in #t209;
+ core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = super.{self::Base::[]}(#t212) in let final void #t214 = super.{self::Base::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:259:43: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v11 = super /*@target=Base::[]=*/ ['x']++;
- ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
+ ['x'] /*@ target=double::+ */ ++;
+ ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
}
}
abstract class Test8 extends self::Base<core::double*, core::num*> {
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
index ccccceb..c584f61 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart
@@ -26,31 +26,55 @@
void test() {
this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
- --this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ [/*@ typeArgs=Index* */ f()];
+
+ this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] ??= /*@ typeArgs=B* */ f();
- var /*@ type=A* */ v3 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] += /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v4 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] *= /*@ typeArgs=dynamic */ f();
- var /*@ type=C* */ v5 = this /*@target=Test::[]=*/ [
- /*@ typeArgs=dynamic */ f()] &= /*@ typeArgs=dynamic */ f();
+ /*@ typeArgs=Index* */ f()] = /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=A* */ v3 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ var /*@ type=B* */ v4 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ var /*@ type=C* */ v5 = this /*@target=Test::[]*/ /*@target=Test::[]=*/ [
+ /*@ typeArgs=Index* */ f()]
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
var /*@ type=B* */ v6 =
- --this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()];
- var /*@ type=B* */ v7 =
- this /*@target=Test::[]=*/ [/*@ typeArgs=dynamic */ f()]--;
+ /*@ target=B::- */ --this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ [/*@ typeArgs=Index* */ f()];
+
+ var /*@ type=B* */ v7 = this /*@target=Test::[]*/ /*@target=Test::[]=*/
+ [/*@ typeArgs=Index* */ f()] /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.expect
index 036a9c0..909ee1a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.expect
@@ -38,20 +38,20 @@
return null;
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
- this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index*, this.{self::Test::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index*, this.{self::Test::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index*, this.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index*, this.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::A* v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A* #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B* #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::C* v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C* #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B* #t31 = this.{self::Test::[]}(#t30 as{TypeError} self::Index*) in let final void #t32 = this.{self::Test::[]=}(#t30 as{TypeError} self::Index*, #t31.{self::B::-}(1)) in #t31;
+ this.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in this.{self::Test::[]}(#t1).{core::Object::==}(null) ?{self::B*} this.{self::Test::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in this.{self::Test::[]=}(#t2, this.{self::Test::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in this.{self::Test::[]=}(#t3, this.{self::Test::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in this.{self::Test::[]=}(#t4, this.{self::Test::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = this.{self::Test::[]}(#t5).{self::B::-}(1) in let final void #t7 = this.{self::Test::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in this.{self::Test::[]=}(#t8, this.{self::Test::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t9 = this in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = self::f<self::B*>() in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ self::B* v2 = let final self::Index* #t13 = self::f<self::Index*>() in let final self::B* #t14 = this.{self::Test::[]}(#t13) in #t14.{core::Object::==}(null) ?{self::B*} let final self::B* #t15 = self::f<self::B*>() in let final void #t16 = this.{self::Test::[]=}(#t13, #t15) in #t15 : #t14;
+ self::A* v3 = let final self::Index* #t17 = self::f<self::Index*>() in let final self::A* #t18 = this.{self::Test::[]}(#t17).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t19 = this.{self::Test::[]=}(#t17, #t18) in #t18;
+ self::B* v4 = let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = this.{self::Test::[]}(#t20).{self::B::*}(self::f<self::B*>()) in let final void #t22 = this.{self::Test::[]=}(#t20, #t21) in #t21;
+ self::C* v5 = let final self::Index* #t23 = self::f<self::Index*>() in let final self::C* #t24 = this.{self::Test::[]}(#t23).{self::B::&}(self::f<self::A*>()) in let final void #t25 = this.{self::Test::[]=}(#t23, #t24) in #t24;
+ self::B* v6 = let final self::Index* #t26 = self::f<self::Index*>() in let final self::B* #t27 = this.{self::Test::[]}(#t26).{self::B::-}(1) in let final void #t28 = this.{self::Test::[]=}(#t26, #t27) in #t27;
+ self::B* v7 = let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = this.{self::Test::[]}(#t29) in let final void #t31 = this.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect
index 036a9c0..909ee1a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect
@@ -38,20 +38,20 @@
return null;
operator []=(self::Index* i, self::B* v) → void {}
method test() → void {
- this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index*, self::f<self::B*>());
- let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index*).{core::Object::==}(null) ?{self::B*} let final self::B* #t2 = self::f<self::B*>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index*, #t2) in #t2 : null;
- let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index*, this.{self::Test::[]}(#t4 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*);
- let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index*, this.{self::Test::[]}(#t5 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*));
- let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index*, this.{self::Test::[]}(#t6 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*));
- let final dynamic #t7 = self::f<dynamic>() in let final self::B* #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index*, #t8) in #t8;
- let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index*, this.{self::Test::[]}(#t10 as{TypeError} self::Index*).{self::B::-}(1));
- self::B* v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B* #t12 = self::f<self::B*>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index*, #t12) in #t12;
- self::B* v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B* #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index*) in #t15.{core::Object::==}(null) ?{self::B*} let final self::B* #t16 = self::f<self::B*>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index*, #t16) in #t16 : #t15;
- self::A* v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A* #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index*).{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B* in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index*, #t19) in #t19;
- self::B* v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B* #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index*).{self::B::*}(self::f<dynamic>() as{TypeError} self::B*) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index*, #t22) in #t22;
- self::C* v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C* #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index*).{self::B::&}(self::f<dynamic>() as{TypeError} self::A*) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index*, #t25) in #t25;
- self::B* v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B* #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index*).{self::B::-}(1) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index*, #t28) in #t28;
- self::B* v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B* #t31 = this.{self::Test::[]}(#t30 as{TypeError} self::Index*) in let final void #t32 = this.{self::Test::[]=}(#t30 as{TypeError} self::Index*, #t31.{self::B::-}(1)) in #t31;
+ this.{self::Test::[]=}(self::f<self::Index*>(), self::f<self::B*>());
+ let final self::Index* #t1 = self::f<self::Index*>() in this.{self::Test::[]}(#t1).{core::Object::==}(null) ?{self::B*} this.{self::Test::[]=}(#t1, self::f<self::B*>()) : null;
+ let final self::Index* #t2 = self::f<self::Index*>() in this.{self::Test::[]=}(#t2, this.{self::Test::[]}(#t2).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*);
+ let final self::Index* #t3 = self::f<self::Index*>() in this.{self::Test::[]=}(#t3, this.{self::Test::[]}(#t3).{self::B::*}(self::f<self::B*>()));
+ let final self::Index* #t4 = self::f<self::Index*>() in this.{self::Test::[]=}(#t4, this.{self::Test::[]}(#t4).{self::B::&}(self::f<self::A*>()));
+ let final self::Index* #t5 = self::f<self::Index*>() in let final self::B* #t6 = this.{self::Test::[]}(#t5).{self::B::-}(1) in let final void #t7 = this.{self::Test::[]=}(#t5, #t6) in #t6;
+ let final self::Index* #t8 = self::f<self::Index*>() in this.{self::Test::[]=}(#t8, this.{self::Test::[]}(#t8).{self::B::-}(1));
+ self::B* v1 = let final self::Test* #t9 = this in let final self::Index* #t10 = self::f<self::Index*>() in let final self::B* #t11 = self::f<self::B*>() in let final void #t12 = #t9.{self::Test::[]=}(#t10, #t11) in #t11;
+ self::B* v2 = let final self::Index* #t13 = self::f<self::Index*>() in let final self::B* #t14 = this.{self::Test::[]}(#t13) in #t14.{core::Object::==}(null) ?{self::B*} let final self::B* #t15 = self::f<self::B*>() in let final void #t16 = this.{self::Test::[]=}(#t13, #t15) in #t15 : #t14;
+ self::A* v3 = let final self::Index* #t17 = self::f<self::Index*>() in let final self::A* #t18 = this.{self::Test::[]}(#t17).{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t19 = this.{self::Test::[]=}(#t17, #t18) in #t18;
+ self::B* v4 = let final self::Index* #t20 = self::f<self::Index*>() in let final self::B* #t21 = this.{self::Test::[]}(#t20).{self::B::*}(self::f<self::B*>()) in let final void #t22 = this.{self::Test::[]=}(#t20, #t21) in #t21;
+ self::C* v5 = let final self::Index* #t23 = self::f<self::Index*>() in let final self::C* #t24 = this.{self::Test::[]}(#t23).{self::B::&}(self::f<self::A*>()) in let final void #t25 = this.{self::Test::[]=}(#t23, #t24) in #t24;
+ self::B* v6 = let final self::Index* #t26 = self::f<self::Index*>() in let final self::B* #t27 = this.{self::Test::[]}(#t26).{self::B::-}(1) in let final void #t28 = this.{self::Test::[]=}(#t26, #t27) in #t27;
+ self::B* v7 = let final self::Index* #t29 = self::f<self::Index*>() in let final self::B* #t30 = this.{self::Test::[]}(#t29) in let final void #t31 = this.{self::Test::[]=}(#t29, #t30.{self::B::-}(1)) in #t30;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
index 4656c2b..35de18e 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart
@@ -15,13 +15,31 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test1::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = this /*@target=Test1::[]=*/ ['x'] = getNum();
- var /*@ type=int* */ v4 = this /*@target=Test1::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test1::[]=*/ ['x'] ??= getNum();
- var /*@ type=int* */ v7 = this /*@target=Test1::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test1::[]=*/ ['x'] += getNum();
- var /*@ type=int* */ v10 = ++this /*@target=Test1::[]=*/ ['x'];
- var /*@ type=int* */ v11 = this /*@target=Test1::[]=*/ ['x']++;
+
+ var /*@ type=int* */ v4 = this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=int* */ v7 = this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = this
+ /*@target=Test1::[]*/ /*@target=Test1::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -31,16 +49,42 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test2::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = this /*@target=Test2::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test2::[]=*/ ['x'] = getDouble();
- var /*@ type=int* */ v4 = this /*@target=Test2::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test2::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = this /*@target=Test2::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = this /*@target=Test2::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test2::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = this /*@target=Test2::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++this /*@target=Test2::[]=*/ ['x'];
- var /*@ type=int* */ v11 = this /*@target=Test2::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ this /*@target=Test2::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=int* */ v4 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=int* */ v7 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=double* */ v9 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::+*/ += getDouble();
+
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = this
+ /*@target=Test2::[]*/ /*@target=Test2::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -50,14 +94,36 @@
void test() {
var /*@ type=num* */ v2 = this /*@target=Test3::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test3::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = this /*@target=Test3::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = this /*@target=Test3::[]=*/ ['x'] ??= getDouble();
- var /*@ type=int* */ v7 = this /*@target=Test3::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test3::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = this /*@target=Test3::[]=*/ ['x'] += getDouble();
- var /*@ type=int* */ v10 = ++this /*@target=Test3::[]=*/ ['x'];
- var /*@ type=int* */ v11 = this /*@target=Test3::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ this /*@target=Test3::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=int* */ v7 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=double* */ v9 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::+*/ += getDouble();
+
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x'];
+
+ var /*@ type=int* */ v11 = this
+ /*@target=Test3::[]*/ /*@target=Test3::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -67,13 +133,31 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test4::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = this /*@target=Test4::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = this /*@target=Test4::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test4::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v7 = this /*@target=Test4::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test4::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v10 = ++this /*@target=Test4::[]=*/ ['x'];
- var /*@ type=num* */ v11 = this /*@target=Test4::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v4 = this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v7 = this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = this
+ /*@target=Test4::[]*/ /*@target=Test4::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -83,16 +167,42 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test5::[]=*/ ['x'] = getInt();
+
var /*@ type=num* */ v2 = this /*@target=Test5::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test5::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = this /*@target=Test5::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test5::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = this /*@target=Test5::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = this /*@target=Test5::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test5::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = this /*@target=Test5::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++this /*@target=Test5::[]=*/ ['x'];
- var /*@ type=num* */ v11 = this /*@target=Test5::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ this /*@target=Test5::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v4 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=num* */ v7 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=num* */ v9 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::+*/ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = this
+ /*@target=Test5::[]*/ /*@target=Test5::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -102,14 +212,36 @@
void test() {
var /*@ type=num* */ v2 = this /*@target=Test6::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test6::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = this /*@target=Test6::[]=*/ ['x'] ??= getNum();
- var /*@ type=num* */ v6 = this /*@target=Test6::[]=*/ ['x'] ??= getDouble();
- var /*@ type=num* */ v7 = this /*@target=Test6::[]=*/ ['x'] += getInt();
- var /*@ type=num* */ v8 = this /*@target=Test6::[]=*/ ['x'] += getNum();
- var /*@ type=num* */ v9 = this /*@target=Test6::[]=*/ ['x'] += getDouble();
- var /*@ type=num* */ v10 = ++this /*@target=Test6::[]=*/ ['x'];
- var /*@ type=num* */ v11 = this /*@target=Test6::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 =
+ this /*@target=Test6::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=num* */ v6 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=num* */ v7 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::+*/ += getInt();
+
+ var /*@ type=num* */ v8 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::+*/ += getNum();
+
+ var /*@ type=num* */ v9 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::+*/ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@target=num::+*/ ++this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x'];
+
+ var /*@ type=num* */ v11 = this
+ /*@target=Test6::[]*/ /*@target=Test6::[]=*/ ['x']
+ /*@target=num::+*/ ++;
}
}
@@ -119,13 +251,32 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test7::[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test7::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 = this /*@target=Test7::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test7::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v7 = this /*@target=Test7::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = this /*@target=Test7::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v10 = ++this /*@target=Test7::[]=*/ ['x'];
- var /*@ type=double* */ v11 = this /*@target=Test7::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v2 = this
+ /*@target=Test7::[]=*/ ['x'] = getNum();
+
+ var /*@ type=num* */ v4 = this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=double* */ v7 = this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
+ /*@target=double::+*/ += getInt();
+
+ var /*@ type=double* */ v8 = this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
+ /*@target=double::+*/ += getNum();
+
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = this
+ /*@target=Test7::[]*/ /*@target=Test7::[]=*/ ['x']
+ /*@target=double::+*/ ++;
}
}
@@ -135,16 +286,43 @@
void test() {
var /*@ type=int* */ v1 = this /*@target=Test8::[]=*/ ['x'] = getInt();
- var /*@ type=num* */ v2 = this /*@target=Test8::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test8::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 = this /*@target=Test8::[]=*/ ['x'] ??= getInt();
- var /*@ type=num* */ v5 = this /*@target=Test8::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = this /*@target=Test8::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = this /*@target=Test8::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = this /*@target=Test8::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = this /*@target=Test8::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++this /*@target=Test8::[]=*/ ['x'];
- var /*@ type=double* */ v11 = this /*@target=Test8::[]=*/ ['x']++;
+
+ var /*@ type=num* */ v2 = this
+ /*@target=Test8::[]=*/ ['x'] = getNum();
+
+ var /*@ type=double* */ v3 = this
+ /*@target=Test8::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v4 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=double* */ v6 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=double* */ v7 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=double::+*/ += getInt();
+
+ var /*@ type=double* */ v8 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=double::+*/ += getNum();
+
+ var /*@ type=double* */ v9 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x']
+ /*@target=double::+*/ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = this
+ /*@target=Test8::[]*/ /*@target=Test8::[]=*/ [
+ 'x'] /*@target=double::+*/ ++;
}
}
@@ -154,14 +332,36 @@
void test() {
var /*@ type=num* */ v2 = this /*@target=Test9::[]=*/ ['x'] = getNum();
- var /*@ type=double* */ v3 = this /*@target=Test9::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 = this /*@target=Test9::[]=*/ ['x'] ??= getNum();
- var /*@ type=double* */ v6 = this /*@target=Test9::[]=*/ ['x'] ??= getDouble();
- var /*@ type=double* */ v7 = this /*@target=Test9::[]=*/ ['x'] += getInt();
- var /*@ type=double* */ v8 = this /*@target=Test9::[]=*/ ['x'] += getNum();
- var /*@ type=double* */ v9 = this /*@target=Test9::[]=*/ ['x'] += getDouble();
- var /*@ type=double* */ v10 = ++this /*@target=Test9::[]=*/ ['x'];
- var /*@ type=double* */ v11 = this /*@target=Test9::[]=*/ ['x']++;
+
+ var /*@ type=double* */ v3 = this
+ /*@target=Test9::[]=*/ ['x'] = getDouble();
+
+ var /*@ type=num* */ v5 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
+
+ var /*@ type=double* */ v6 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
+
+ var /*@ type=double* */ v7 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=double::+*/ += getInt();
+
+ var /*@ type=double* */ v8 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=double::+*/ += getNum();
+
+ var /*@ type=double* */ v9 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=double::+*/ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x'];
+
+ var /*@ type=double* */ v11 = this
+ /*@target=Test9::[]*/ /*@target=Test9::[]=*/ ['x']
+ /*@target=double::+*/ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
index 2baa260..805d030 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
@@ -2,40 +2,40 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:56:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v7 = this /*@target=Test3::[]=*/ ['x'] += getInt();
-// ^
+// /*@target=num::+*/ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:59:32: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v10 = ++this /*@target=Test3::[]=*/ ['x'];
-// ^
+// var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:60:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
-// var /*@ type=int* */ v11 = this /*@target=Test3::[]=*/ ['x']++;
-// ^
+// /*@target=num::+*/ ++;
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:125:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v7 = this /*@target=Test7::[]=*/ ['x'] += getInt();
-// ^
+// /*@target=double::+*/ += getInt();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v8 = this /*@target=Test7::[]=*/ ['x'] += getNum();
-// ^
+// /*@target=double::+*/ += getNum();
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:127:35: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v10 = ++this /*@target=Test7::[]=*/ ['x'];
-// ^
+// var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
+// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:128:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-// var /*@ type=double* */ v11 = this /*@target=Test7::[]=*/ ['x']++;
-// ^
+// /*@target=double::+*/ ++;
+// ^
//
import self as self;
import "dart:core" as core;
@@ -47,14 +47,14 @@
abstract operator [](core::String* s) → core::int*;
abstract operator []=(core::String* s, core::int* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t1 = "x" in let final core::int* #t2 = self::getInt() in let final void #t3 = this.{self::Test1::[]=}(#t1, #t2) in #t2;
- core::num* v2 = let final core::String* #t4 = "x" in let final core::num* #t5 = self::getNum() as{TypeError} core::int* in let final void #t6 = this.{self::Test1::[]=}(#t4, #t5) in #t5;
- core::int* v4 = let final core::String* #t7 = "x" in let final core::int* #t8 = this.{self::Test1::[]}(#t7) in #t8.{core::num::==}(null) ?{core::int*} let final core::int* #t9 = self::getInt() in let final void #t10 = this.{self::Test1::[]=}(#t7, #t9) in #t9 : #t8;
- core::num* v5 = let final core::String* #t11 = "x" in let final core::int* #t12 = this.{self::Test1::[]}(#t11) in #t12.{core::num::==}(null) ?{core::num*} let final core::num* #t13 = self::getNum() as{TypeError} core::int* in let final void #t14 = this.{self::Test1::[]=}(#t11, #t13) in #t13 : #t12;
- core::int* v7 = let final core::String* #t15 = "x" in let final core::int* #t16 = this.{self::Test1::[]}(#t15).{core::num::+}(self::getInt()) in let final void #t17 = this.{self::Test1::[]=}(#t15, #t16) in #t16;
- core::num* v8 = let final core::String* #t18 = "x" in let final core::num* #t19 = this.{self::Test1::[]}(#t18).{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t20 = this.{self::Test1::[]=}(#t18, #t19) in #t19;
- core::int* v10 = let final core::String* #t21 = "x" in let final core::int* #t22 = this.{self::Test1::[]}(#t21).{core::num::+}(1) in let final void #t23 = this.{self::Test1::[]=}(#t21, #t22) in #t22;
- core::int* v11 = let final core::String* #t24 = "x" in let final core::int* #t25 = this.{self::Test1::[]}(#t24) in let final void #t26 = this.{self::Test1::[]=}(#t24, #t25.{core::num::+}(1)) in #t25;
+ core::int* v1 = let final self::Test1* #t1 = this in let final core::String* #t2 = "x" in let final core::int* #t3 = self::getInt() in let final void #t4 = #t1.{self::Test1::[]=}(#t2, #t3) in #t3;
+ core::num* v2 = let final self::Test1* #t5 = this in let final core::String* #t6 = "x" in let final core::num* #t7 = self::getNum() as{TypeError} core::int* in let final void #t8 = #t5.{self::Test1::[]=}(#t6, #t7) in #t7;
+ core::int* v4 = let final core::String* #t9 = "x" in let final core::int* #t10 = this.{self::Test1::[]}(#t9) in #t10.{core::num::==}(null) ?{core::int*} let final core::int* #t11 = self::getInt() in let final void #t12 = this.{self::Test1::[]=}(#t9, #t11) in #t11 : #t10;
+ core::num* v5 = let final core::String* #t13 = "x" in let final core::int* #t14 = this.{self::Test1::[]}(#t13) in #t14.{core::num::==}(null) ?{core::num*} let final core::num* #t15 = self::getNum() as{TypeError} core::int* in let final void #t16 = this.{self::Test1::[]=}(#t13, #t15) in #t15 : #t14;
+ core::int* v7 = let final core::String* #t17 = "x" in let final core::int* #t18 = this.{self::Test1::[]}(#t17).{core::num::+}(self::getInt()) in let final void #t19 = this.{self::Test1::[]=}(#t17, #t18) in #t18;
+ core::num* v8 = let final core::String* #t20 = "x" in let final core::num* #t21 = this.{self::Test1::[]}(#t20).{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t22 = this.{self::Test1::[]=}(#t20, #t21) in #t21;
+ core::int* v10 = let final core::String* #t23 = "x" in let final core::int* #t24 = this.{self::Test1::[]}(#t23).{core::num::+}(1) in let final void #t25 = this.{self::Test1::[]=}(#t23, #t24) in #t24;
+ core::int* v11 = let final core::String* #t26 = "x" in let final core::int* #t27 = this.{self::Test1::[]}(#t26) in let final void #t28 = this.{self::Test1::[]=}(#t26, #t27.{core::num::+}(1)) in #t27;
}
}
abstract class Test2 extends core::Object {
@@ -64,17 +64,17 @@
abstract operator [](core::String* s) → core::int*;
abstract operator []=(core::String* s, core::num* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t27 = "x" in let final core::int* #t28 = self::getInt() in let final void #t29 = this.{self::Test2::[]=}(#t27, #t28) in #t28;
- core::num* v2 = let final core::String* #t30 = "x" in let final core::num* #t31 = self::getNum() in let final void #t32 = this.{self::Test2::[]=}(#t30, #t31) in #t31;
- core::double* v3 = let final core::String* #t33 = "x" in let final core::double* #t34 = self::getDouble() in let final void #t35 = this.{self::Test2::[]=}(#t33, #t34) in #t34;
- core::int* v4 = let final core::String* #t36 = "x" in let final core::int* #t37 = this.{self::Test2::[]}(#t36) in #t37.{core::num::==}(null) ?{core::int*} let final core::int* #t38 = self::getInt() in let final void #t39 = this.{self::Test2::[]=}(#t36, #t38) in #t38 : #t37;
- core::num* v5 = let final core::String* #t40 = "x" in let final core::int* #t41 = this.{self::Test2::[]}(#t40) in #t41.{core::num::==}(null) ?{core::num*} let final core::num* #t42 = self::getNum() in let final void #t43 = this.{self::Test2::[]=}(#t40, #t42) in #t42 : #t41;
- core::num* v6 = let final core::String* #t44 = "x" in let final core::int* #t45 = this.{self::Test2::[]}(#t44) in #t45.{core::num::==}(null) ?{core::num*} let final core::double* #t46 = self::getDouble() in let final void #t47 = this.{self::Test2::[]=}(#t44, #t46) in #t46 : #t45;
- core::int* v7 = let final core::String* #t48 = "x" in let final core::int* #t49 = this.{self::Test2::[]}(#t48).{core::num::+}(self::getInt()) in let final void #t50 = this.{self::Test2::[]=}(#t48, #t49) in #t49;
- core::num* v8 = let final core::String* #t51 = "x" in let final core::num* #t52 = this.{self::Test2::[]}(#t51).{core::num::+}(self::getNum()) in let final void #t53 = this.{self::Test2::[]=}(#t51, #t52) in #t52;
- core::double* v9 = let final core::String* #t54 = "x" in let final core::double* #t55 = this.{self::Test2::[]}(#t54).{core::num::+}(self::getDouble()) in let final void #t56 = this.{self::Test2::[]=}(#t54, #t55) in #t55;
- core::int* v10 = let final core::String* #t57 = "x" in let final core::int* #t58 = this.{self::Test2::[]}(#t57).{core::num::+}(1) in let final void #t59 = this.{self::Test2::[]=}(#t57, #t58) in #t58;
- core::int* v11 = let final core::String* #t60 = "x" in let final core::int* #t61 = this.{self::Test2::[]}(#t60) in let final void #t62 = this.{self::Test2::[]=}(#t60, #t61.{core::num::+}(1)) in #t61;
+ core::int* v1 = let final self::Test2* #t29 = this in let final core::String* #t30 = "x" in let final core::int* #t31 = self::getInt() in let final void #t32 = #t29.{self::Test2::[]=}(#t30, #t31) in #t31;
+ core::num* v2 = let final self::Test2* #t33 = this in let final core::String* #t34 = "x" in let final core::num* #t35 = self::getNum() in let final void #t36 = #t33.{self::Test2::[]=}(#t34, #t35) in #t35;
+ core::double* v3 = let final self::Test2* #t37 = this in let final core::String* #t38 = "x" in let final core::double* #t39 = self::getDouble() in let final void #t40 = #t37.{self::Test2::[]=}(#t38, #t39) in #t39;
+ core::int* v4 = let final core::String* #t41 = "x" in let final core::int* #t42 = this.{self::Test2::[]}(#t41) in #t42.{core::num::==}(null) ?{core::int*} let final core::int* #t43 = self::getInt() in let final void #t44 = this.{self::Test2::[]=}(#t41, #t43) in #t43 : #t42;
+ core::num* v5 = let final core::String* #t45 = "x" in let final core::int* #t46 = this.{self::Test2::[]}(#t45) in #t46.{core::num::==}(null) ?{core::num*} let final core::num* #t47 = self::getNum() in let final void #t48 = this.{self::Test2::[]=}(#t45, #t47) in #t47 : #t46;
+ core::num* v6 = let final core::String* #t49 = "x" in let final core::int* #t50 = this.{self::Test2::[]}(#t49) in #t50.{core::num::==}(null) ?{core::num*} let final core::double* #t51 = self::getDouble() in let final void #t52 = this.{self::Test2::[]=}(#t49, #t51) in #t51 : #t50;
+ core::int* v7 = let final core::String* #t53 = "x" in let final core::int* #t54 = this.{self::Test2::[]}(#t53).{core::num::+}(self::getInt()) in let final void #t55 = this.{self::Test2::[]=}(#t53, #t54) in #t54;
+ core::num* v8 = let final core::String* #t56 = "x" in let final core::num* #t57 = this.{self::Test2::[]}(#t56).{core::num::+}(self::getNum()) in let final void #t58 = this.{self::Test2::[]=}(#t56, #t57) in #t57;
+ core::double* v9 = let final core::String* #t59 = "x" in let final core::double* #t60 = this.{self::Test2::[]}(#t59).{core::num::+}(self::getDouble()) in let final void #t61 = this.{self::Test2::[]=}(#t59, #t60) in #t60;
+ core::int* v10 = let final core::String* #t62 = "x" in let final core::int* #t63 = this.{self::Test2::[]}(#t62).{core::num::+}(1) in let final void #t64 = this.{self::Test2::[]=}(#t62, #t63) in #t63;
+ core::int* v11 = let final core::String* #t65 = "x" in let final core::int* #t66 = this.{self::Test2::[]}(#t65) in let final void #t67 = this.{self::Test2::[]=}(#t65, #t66.{core::num::+}(1)) in #t66;
}
}
abstract class Test3 extends core::Object {
@@ -84,24 +84,24 @@
abstract operator [](core::String* s) → core::int*;
abstract operator []=(core::String* s, core::double* v) → void;
method test() → void {
- core::num* v2 = let final core::String* #t63 = "x" in let final core::num* #t64 = self::getNum() as{TypeError} core::double* in let final void #t65 = this.{self::Test3::[]=}(#t63, #t64) in #t64;
- core::double* v3 = let final core::String* #t66 = "x" in let final core::double* #t67 = self::getDouble() in let final void #t68 = this.{self::Test3::[]=}(#t66, #t67) in #t67;
- core::num* v5 = let final core::String* #t69 = "x" in let final core::int* #t70 = this.{self::Test3::[]}(#t69) in #t70.{core::num::==}(null) ?{core::num*} let final core::num* #t71 = self::getNum() as{TypeError} core::double* in let final void #t72 = this.{self::Test3::[]=}(#t69, #t71) in #t71 : #t70;
- core::num* v6 = let final core::String* #t73 = "x" in let final core::int* #t74 = this.{self::Test3::[]}(#t73) in #t74.{core::num::==}(null) ?{core::num*} let final core::double* #t75 = self::getDouble() in let final void #t76 = this.{self::Test3::[]=}(#t73, #t75) in #t75 : #t74;
- core::int* v7 = let final core::String* #t77 = "x" in let final core::int* #t78 = let final<BottomType> #t79 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:56:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::num* v2 = let final self::Test3* #t68 = this in let final core::String* #t69 = "x" in let final core::num* #t70 = self::getNum() as{TypeError} core::double* in let final void #t71 = #t68.{self::Test3::[]=}(#t69, #t70) in #t70;
+ core::double* v3 = let final self::Test3* #t72 = this in let final core::String* #t73 = "x" in let final core::double* #t74 = self::getDouble() in let final void #t75 = #t72.{self::Test3::[]=}(#t73, #t74) in #t74;
+ core::num* v5 = let final core::String* #t76 = "x" in let final core::int* #t77 = this.{self::Test3::[]}(#t76) in #t77.{core::num::==}(null) ?{core::num*} let final core::num* #t78 = self::getNum() as{TypeError} core::double* in let final void #t79 = this.{self::Test3::[]=}(#t76, #t78) in #t78 : #t77;
+ core::num* v6 = let final core::String* #t80 = "x" in let final core::int* #t81 = this.{self::Test3::[]}(#t80) in #t81.{core::num::==}(null) ?{core::num*} let final core::double* #t82 = self::getDouble() in let final void #t83 = this.{self::Test3::[]=}(#t80, #t82) in #t82 : #t81;
+ core::int* v7 = let final core::String* #t84 = "x" in let final core::int* #t85 = let final<BottomType> #t86 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:111:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v7 = this /*@target=Test3::[]=*/ ['x'] += getInt();
- ^" in this.{self::Test3::[]}(#t77).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t80 = this.{self::Test3::[]=}(#t77, #t78) in #t78;
- core::num* v8 = let final core::String* #t81 = "x" in let final core::num* #t82 = this.{self::Test3::[]}(#t81).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t83 = this.{self::Test3::[]=}(#t81, #t82) in #t82;
- core::double* v9 = let final core::String* #t84 = "x" in let final core::double* #t85 = this.{self::Test3::[]}(#t84).{core::num::+}(self::getDouble()) in let final void #t86 = this.{self::Test3::[]=}(#t84, #t85) in #t85;
- core::int* v10 = let final core::String* #t87 = "x" in let final core::int* #t88 = let final<BottomType> #t89 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:59:32: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ /*@target=num::+*/ += getInt();
+ ^" in this.{self::Test3::[]}(#t84).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t87 = this.{self::Test3::[]=}(#t84, #t85) in #t85;
+ core::num* v8 = let final core::String* #t88 = "x" in let final core::num* #t89 = this.{self::Test3::[]}(#t88).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t90 = this.{self::Test3::[]=}(#t88, #t89) in #t89;
+ core::double* v9 = let final core::String* #t91 = "x" in let final core::double* #t92 = this.{self::Test3::[]}(#t91).{core::num::+}(self::getDouble()) in let final void #t93 = this.{self::Test3::[]=}(#t91, #t92) in #t92;
+ core::int* v10 = let final core::String* #t94 = "x" in let final core::int* #t95 = let final<BottomType> #t96 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:121:51: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v10 = ++this /*@target=Test3::[]=*/ ['x'];
- ^" in this.{self::Test3::[]}(#t87).{core::num::+}(1) as{TypeError} core::double* in let final void #t90 = this.{self::Test3::[]=}(#t87, #t88) in #t88;
- core::int* v11 = let final core::String* #t91 = "x" in let final core::int* #t92 = this.{self::Test3::[]}(#t91) in let final void #t93 = this.{self::Test3::[]=}(#t91, let final<BottomType> #t94 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:60:65: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ var /*@ type=int* */ v10 = /*@target=num::+*/ ++this
+ ^" in this.{self::Test3::[]}(#t94).{core::num::+}(1) as{TypeError} core::double* in let final void #t97 = this.{self::Test3::[]=}(#t94, #t95) in #t95;
+ core::int* v11 = let final core::String* #t98 = "x" in let final core::int* #t99 = this.{self::Test3::[]}(#t98) in let final void #t100 = this.{self::Test3::[]=}(#t98, let final<BottomType> #t101 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
- var /*@ type=int* */ v11 = this /*@target=Test3::[]=*/ ['x']++;
- ^" in #t92.{core::num::+}(1) as{TypeError} core::double*) in #t92;
+ /*@target=num::+*/ ++;
+ ^" in #t99.{core::num::+}(1) as{TypeError} core::double*) in #t99;
}
}
abstract class Test4 extends core::Object {
@@ -111,14 +111,14 @@
abstract operator [](core::String* s) → core::num*;
abstract operator []=(core::String* s, core::int* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t95 = "x" in let final core::int* #t96 = self::getInt() in let final void #t97 = this.{self::Test4::[]=}(#t95, #t96) in #t96;
- core::num* v2 = let final core::String* #t98 = "x" in let final core::num* #t99 = self::getNum() as{TypeError} core::int* in let final void #t100 = this.{self::Test4::[]=}(#t98, #t99) in #t99;
- core::num* v4 = let final core::String* #t101 = "x" in let final core::num* #t102 = this.{self::Test4::[]}(#t101) in #t102.{core::num::==}(null) ?{core::num*} let final core::int* #t103 = self::getInt() in let final void #t104 = this.{self::Test4::[]=}(#t101, #t103) in #t103 : #t102;
- core::num* v5 = let final core::String* #t105 = "x" in let final core::num* #t106 = this.{self::Test4::[]}(#t105) in #t106.{core::num::==}(null) ?{core::num*} let final core::num* #t107 = self::getNum() as{TypeError} core::int* in let final void #t108 = this.{self::Test4::[]=}(#t105, #t107) in #t107 : #t106;
- core::num* v7 = let final core::String* #t109 = "x" in let final core::num* #t110 = this.{self::Test4::[]}(#t109).{core::num::+}(self::getInt()) as{TypeError} core::int* in let final void #t111 = this.{self::Test4::[]=}(#t109, #t110) in #t110;
- core::num* v8 = let final core::String* #t112 = "x" in let final core::num* #t113 = this.{self::Test4::[]}(#t112).{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t114 = this.{self::Test4::[]=}(#t112, #t113) in #t113;
- core::num* v10 = let final core::String* #t115 = "x" in let final core::num* #t116 = this.{self::Test4::[]}(#t115).{core::num::+}(1) as{TypeError} core::int* in let final void #t117 = this.{self::Test4::[]=}(#t115, #t116) in #t116;
- core::num* v11 = let final core::String* #t118 = "x" in let final core::num* #t119 = this.{self::Test4::[]}(#t118) in let final void #t120 = this.{self::Test4::[]=}(#t118, #t119.{core::num::+}(1) as{TypeError} core::int*) in #t119;
+ core::int* v1 = let final self::Test4* #t102 = this in let final core::String* #t103 = "x" in let final core::int* #t104 = self::getInt() in let final void #t105 = #t102.{self::Test4::[]=}(#t103, #t104) in #t104;
+ core::num* v2 = let final self::Test4* #t106 = this in let final core::String* #t107 = "x" in let final core::num* #t108 = self::getNum() as{TypeError} core::int* in let final void #t109 = #t106.{self::Test4::[]=}(#t107, #t108) in #t108;
+ core::num* v4 = let final core::String* #t110 = "x" in let final core::num* #t111 = this.{self::Test4::[]}(#t110) in #t111.{core::num::==}(null) ?{core::num*} let final core::int* #t112 = self::getInt() in let final void #t113 = this.{self::Test4::[]=}(#t110, #t112) in #t112 : #t111;
+ core::num* v5 = let final core::String* #t114 = "x" in let final core::num* #t115 = this.{self::Test4::[]}(#t114) in #t115.{core::num::==}(null) ?{core::num*} let final core::num* #t116 = self::getNum() as{TypeError} core::int* in let final void #t117 = this.{self::Test4::[]=}(#t114, #t116) in #t116 : #t115;
+ core::num* v7 = let final core::String* #t118 = "x" in let final core::num* #t119 = this.{self::Test4::[]}(#t118).{core::num::+}(self::getInt()) as{TypeError} core::int* in let final void #t120 = this.{self::Test4::[]=}(#t118, #t119) in #t119;
+ core::num* v8 = let final core::String* #t121 = "x" in let final core::num* #t122 = this.{self::Test4::[]}(#t121).{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t123 = this.{self::Test4::[]=}(#t121, #t122) in #t122;
+ core::num* v10 = let final core::String* #t124 = "x" in let final core::num* #t125 = this.{self::Test4::[]}(#t124).{core::num::+}(1) as{TypeError} core::int* in let final void #t126 = this.{self::Test4::[]=}(#t124, #t125) in #t125;
+ core::num* v11 = let final core::String* #t127 = "x" in let final core::num* #t128 = this.{self::Test4::[]}(#t127) in let final void #t129 = this.{self::Test4::[]=}(#t127, #t128.{core::num::+}(1) as{TypeError} core::int*) in #t128;
}
}
abstract class Test5 extends core::Object {
@@ -128,17 +128,17 @@
abstract operator [](core::String* s) → core::num*;
abstract operator []=(core::String* s, core::num* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t121 = "x" in let final core::int* #t122 = self::getInt() in let final void #t123 = this.{self::Test5::[]=}(#t121, #t122) in #t122;
- core::num* v2 = let final core::String* #t124 = "x" in let final core::num* #t125 = self::getNum() in let final void #t126 = this.{self::Test5::[]=}(#t124, #t125) in #t125;
- core::double* v3 = let final core::String* #t127 = "x" in let final core::double* #t128 = self::getDouble() in let final void #t129 = this.{self::Test5::[]=}(#t127, #t128) in #t128;
- core::num* v4 = let final core::String* #t130 = "x" in let final core::num* #t131 = this.{self::Test5::[]}(#t130) in #t131.{core::num::==}(null) ?{core::num*} let final core::int* #t132 = self::getInt() in let final void #t133 = this.{self::Test5::[]=}(#t130, #t132) in #t132 : #t131;
- core::num* v5 = let final core::String* #t134 = "x" in let final core::num* #t135 = this.{self::Test5::[]}(#t134) in #t135.{core::num::==}(null) ?{core::num*} let final core::num* #t136 = self::getNum() in let final void #t137 = this.{self::Test5::[]=}(#t134, #t136) in #t136 : #t135;
- core::num* v6 = let final core::String* #t138 = "x" in let final core::num* #t139 = this.{self::Test5::[]}(#t138) in #t139.{core::num::==}(null) ?{core::num*} let final core::double* #t140 = self::getDouble() in let final void #t141 = this.{self::Test5::[]=}(#t138, #t140) in #t140 : #t139;
- core::num* v7 = let final core::String* #t142 = "x" in let final core::num* #t143 = this.{self::Test5::[]}(#t142).{core::num::+}(self::getInt()) in let final void #t144 = this.{self::Test5::[]=}(#t142, #t143) in #t143;
- core::num* v8 = let final core::String* #t145 = "x" in let final core::num* #t146 = this.{self::Test5::[]}(#t145).{core::num::+}(self::getNum()) in let final void #t147 = this.{self::Test5::[]=}(#t145, #t146) in #t146;
- core::num* v9 = let final core::String* #t148 = "x" in let final core::num* #t149 = this.{self::Test5::[]}(#t148).{core::num::+}(self::getDouble()) in let final void #t150 = this.{self::Test5::[]=}(#t148, #t149) in #t149;
- core::num* v10 = let final core::String* #t151 = "x" in let final core::num* #t152 = this.{self::Test5::[]}(#t151).{core::num::+}(1) in let final void #t153 = this.{self::Test5::[]=}(#t151, #t152) in #t152;
- core::num* v11 = let final core::String* #t154 = "x" in let final core::num* #t155 = this.{self::Test5::[]}(#t154) in let final void #t156 = this.{self::Test5::[]=}(#t154, #t155.{core::num::+}(1)) in #t155;
+ core::int* v1 = let final self::Test5* #t130 = this in let final core::String* #t131 = "x" in let final core::int* #t132 = self::getInt() in let final void #t133 = #t130.{self::Test5::[]=}(#t131, #t132) in #t132;
+ core::num* v2 = let final self::Test5* #t134 = this in let final core::String* #t135 = "x" in let final core::num* #t136 = self::getNum() in let final void #t137 = #t134.{self::Test5::[]=}(#t135, #t136) in #t136;
+ core::double* v3 = let final self::Test5* #t138 = this in let final core::String* #t139 = "x" in let final core::double* #t140 = self::getDouble() in let final void #t141 = #t138.{self::Test5::[]=}(#t139, #t140) in #t140;
+ core::num* v4 = let final core::String* #t142 = "x" in let final core::num* #t143 = this.{self::Test5::[]}(#t142) in #t143.{core::num::==}(null) ?{core::num*} let final core::int* #t144 = self::getInt() in let final void #t145 = this.{self::Test5::[]=}(#t142, #t144) in #t144 : #t143;
+ core::num* v5 = let final core::String* #t146 = "x" in let final core::num* #t147 = this.{self::Test5::[]}(#t146) in #t147.{core::num::==}(null) ?{core::num*} let final core::num* #t148 = self::getNum() in let final void #t149 = this.{self::Test5::[]=}(#t146, #t148) in #t148 : #t147;
+ core::num* v6 = let final core::String* #t150 = "x" in let final core::num* #t151 = this.{self::Test5::[]}(#t150) in #t151.{core::num::==}(null) ?{core::num*} let final core::double* #t152 = self::getDouble() in let final void #t153 = this.{self::Test5::[]=}(#t150, #t152) in #t152 : #t151;
+ core::num* v7 = let final core::String* #t154 = "x" in let final core::num* #t155 = this.{self::Test5::[]}(#t154).{core::num::+}(self::getInt()) in let final void #t156 = this.{self::Test5::[]=}(#t154, #t155) in #t155;
+ core::num* v8 = let final core::String* #t157 = "x" in let final core::num* #t158 = this.{self::Test5::[]}(#t157).{core::num::+}(self::getNum()) in let final void #t159 = this.{self::Test5::[]=}(#t157, #t158) in #t158;
+ core::num* v9 = let final core::String* #t160 = "x" in let final core::num* #t161 = this.{self::Test5::[]}(#t160).{core::num::+}(self::getDouble()) in let final void #t162 = this.{self::Test5::[]=}(#t160, #t161) in #t161;
+ core::num* v10 = let final core::String* #t163 = "x" in let final core::num* #t164 = this.{self::Test5::[]}(#t163).{core::num::+}(1) in let final void #t165 = this.{self::Test5::[]=}(#t163, #t164) in #t164;
+ core::num* v11 = let final core::String* #t166 = "x" in let final core::num* #t167 = this.{self::Test5::[]}(#t166) in let final void #t168 = this.{self::Test5::[]=}(#t166, #t167.{core::num::+}(1)) in #t167;
}
}
abstract class Test6 extends core::Object {
@@ -148,15 +148,15 @@
abstract operator [](core::String* s) → core::num*;
abstract operator []=(core::String* s, core::double* v) → void;
method test() → void {
- core::num* v2 = let final core::String* #t157 = "x" in let final core::num* #t158 = self::getNum() as{TypeError} core::double* in let final void #t159 = this.{self::Test6::[]=}(#t157, #t158) in #t158;
- core::double* v3 = let final core::String* #t160 = "x" in let final core::double* #t161 = self::getDouble() in let final void #t162 = this.{self::Test6::[]=}(#t160, #t161) in #t161;
- core::num* v5 = let final core::String* #t163 = "x" in let final core::num* #t164 = this.{self::Test6::[]}(#t163) in #t164.{core::num::==}(null) ?{core::num*} let final core::num* #t165 = self::getNum() as{TypeError} core::double* in let final void #t166 = this.{self::Test6::[]=}(#t163, #t165) in #t165 : #t164;
- core::num* v6 = let final core::String* #t167 = "x" in let final core::num* #t168 = this.{self::Test6::[]}(#t167) in #t168.{core::num::==}(null) ?{core::num*} let final core::double* #t169 = self::getDouble() in let final void #t170 = this.{self::Test6::[]=}(#t167, #t169) in #t169 : #t168;
- core::num* v7 = let final core::String* #t171 = "x" in let final core::num* #t172 = this.{self::Test6::[]}(#t171).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t173 = this.{self::Test6::[]=}(#t171, #t172) in #t172;
- core::num* v8 = let final core::String* #t174 = "x" in let final core::num* #t175 = this.{self::Test6::[]}(#t174).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t176 = this.{self::Test6::[]=}(#t174, #t175) in #t175;
- core::num* v9 = let final core::String* #t177 = "x" in let final core::num* #t178 = this.{self::Test6::[]}(#t177).{core::num::+}(self::getDouble()) as{TypeError} core::double* in let final void #t179 = this.{self::Test6::[]=}(#t177, #t178) in #t178;
- core::num* v10 = let final core::String* #t180 = "x" in let final core::num* #t181 = this.{self::Test6::[]}(#t180).{core::num::+}(1) as{TypeError} core::double* in let final void #t182 = this.{self::Test6::[]=}(#t180, #t181) in #t181;
- core::num* v11 = let final core::String* #t183 = "x" in let final core::num* #t184 = this.{self::Test6::[]}(#t183) in let final void #t185 = this.{self::Test6::[]=}(#t183, #t184.{core::num::+}(1) as{TypeError} core::double*) in #t184;
+ core::num* v2 = let final self::Test6* #t169 = this in let final core::String* #t170 = "x" in let final core::num* #t171 = self::getNum() as{TypeError} core::double* in let final void #t172 = #t169.{self::Test6::[]=}(#t170, #t171) in #t171;
+ core::double* v3 = let final self::Test6* #t173 = this in let final core::String* #t174 = "x" in let final core::double* #t175 = self::getDouble() in let final void #t176 = #t173.{self::Test6::[]=}(#t174, #t175) in #t175;
+ core::num* v5 = let final core::String* #t177 = "x" in let final core::num* #t178 = this.{self::Test6::[]}(#t177) in #t178.{core::num::==}(null) ?{core::num*} let final core::num* #t179 = self::getNum() as{TypeError} core::double* in let final void #t180 = this.{self::Test6::[]=}(#t177, #t179) in #t179 : #t178;
+ core::num* v6 = let final core::String* #t181 = "x" in let final core::num* #t182 = this.{self::Test6::[]}(#t181) in #t182.{core::num::==}(null) ?{core::num*} let final core::double* #t183 = self::getDouble() in let final void #t184 = this.{self::Test6::[]=}(#t181, #t183) in #t183 : #t182;
+ core::num* v7 = let final core::String* #t185 = "x" in let final core::num* #t186 = this.{self::Test6::[]}(#t185).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t187 = this.{self::Test6::[]=}(#t185, #t186) in #t186;
+ core::num* v8 = let final core::String* #t188 = "x" in let final core::num* #t189 = this.{self::Test6::[]}(#t188).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t190 = this.{self::Test6::[]=}(#t188, #t189) in #t189;
+ core::num* v9 = let final core::String* #t191 = "x" in let final core::num* #t192 = this.{self::Test6::[]}(#t191).{core::num::+}(self::getDouble()) as{TypeError} core::double* in let final void #t193 = this.{self::Test6::[]=}(#t191, #t192) in #t192;
+ core::num* v10 = let final core::String* #t194 = "x" in let final core::num* #t195 = this.{self::Test6::[]}(#t194).{core::num::+}(1) as{TypeError} core::double* in let final void #t196 = this.{self::Test6::[]=}(#t194, #t195) in #t195;
+ core::num* v11 = let final core::String* #t197 = "x" in let final core::num* #t198 = this.{self::Test6::[]}(#t197) in let final void #t199 = this.{self::Test6::[]=}(#t197, #t198.{core::num::+}(1) as{TypeError} core::double*) in #t198;
}
}
abstract class Test7 extends core::Object {
@@ -166,26 +166,26 @@
abstract operator [](core::String* s) → core::double*;
abstract operator []=(core::String* s, core::int* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t186 = "x" in let final core::int* #t187 = self::getInt() in let final void #t188 = this.{self::Test7::[]=}(#t186, #t187) in #t187;
- core::num* v2 = let final core::String* #t189 = "x" in let final core::num* #t190 = self::getNum() as{TypeError} core::int* in let final void #t191 = this.{self::Test7::[]=}(#t189, #t190) in #t190;
- core::num* v4 = let final core::String* #t192 = "x" in let final core::double* #t193 = this.{self::Test7::[]}(#t192) in #t193.{core::num::==}(null) ?{core::num*} let final core::int* #t194 = self::getInt() in let final void #t195 = this.{self::Test7::[]=}(#t192, #t194) in #t194 : #t193;
- core::num* v5 = let final core::String* #t196 = "x" in let final core::double* #t197 = this.{self::Test7::[]}(#t196) in #t197.{core::num::==}(null) ?{core::num*} let final core::num* #t198 = self::getNum() as{TypeError} core::int* in let final void #t199 = this.{self::Test7::[]=}(#t196, #t198) in #t198 : #t197;
- core::double* v7 = let final core::String* #t200 = "x" in let final core::double* #t201 = let final<BottomType> #t202 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:125:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::int* v1 = let final self::Test7* #t200 = this in let final core::String* #t201 = "x" in let final core::int* #t202 = self::getInt() in let final void #t203 = #t200.{self::Test7::[]=}(#t201, #t202) in #t202;
+ core::num* v2 = let final self::Test7* #t204 = this in let final core::String* #t205 = "x" in let final core::num* #t206 = self::getNum() as{TypeError} core::int* in let final void #t207 = #t204.{self::Test7::[]=}(#t205, #t206) in #t206;
+ core::num* v4 = let final core::String* #t208 = "x" in let final core::double* #t209 = this.{self::Test7::[]}(#t208) in #t209.{core::num::==}(null) ?{core::num*} let final core::int* #t210 = self::getInt() in let final void #t211 = this.{self::Test7::[]=}(#t208, #t210) in #t210 : #t209;
+ core::num* v5 = let final core::String* #t212 = "x" in let final core::double* #t213 = this.{self::Test7::[]}(#t212) in #t213.{core::num::==}(null) ?{core::num*} let final core::num* #t214 = self::getNum() as{TypeError} core::int* in let final void #t215 = this.{self::Test7::[]=}(#t212, #t214) in #t214 : #t213;
+ core::double* v7 = let final core::String* #t216 = "x" in let final core::double* #t217 = let final<BottomType> #t218 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:268:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v7 = this /*@target=Test7::[]=*/ ['x'] += getInt();
- ^" in this.{self::Test7::[]}(#t200).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t203 = this.{self::Test7::[]=}(#t200, #t201) in #t201;
- core::double* v8 = let final core::String* #t204 = "x" in let final core::double* #t205 = let final<BottomType> #t206 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:126:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double::+*/ += getInt();
+ ^" in this.{self::Test7::[]}(#t216).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t219 = this.{self::Test7::[]=}(#t216, #t217) in #t217;
+ core::double* v8 = let final core::String* #t220 = "x" in let final core::double* #t221 = let final<BottomType> #t222 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:272:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v8 = this /*@target=Test7::[]=*/ ['x'] += getNum();
- ^" in this.{self::Test7::[]}(#t204).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t207 = this.{self::Test7::[]=}(#t204, #t205) in #t205;
- core::double* v10 = let final core::String* #t208 = "x" in let final core::double* #t209 = let final<BottomType> #t210 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:127:35: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ /*@target=double::+*/ += getNum();
+ ^" in this.{self::Test7::[]}(#t220).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t223 = this.{self::Test7::[]=}(#t220, #t221) in #t221;
+ core::double* v10 = let final core::String* #t224 = "x" in let final core::double* #t225 = let final<BottomType> #t226 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:274:57: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v10 = ++this /*@target=Test7::[]=*/ ['x'];
- ^" in this.{self::Test7::[]}(#t208).{core::double::+}(1) as{TypeError} core::int* in let final void #t211 = this.{self::Test7::[]=}(#t208, #t209) in #t209;
- core::double* v11 = let final core::String* #t212 = "x" in let final core::double* #t213 = this.{self::Test7::[]}(#t212) in let final void #t214 = this.{self::Test7::[]=}(#t212, let final<BottomType> #t215 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:128:68: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ var /*@ type=double* */ v10 = /*@target=double::+*/ ++this
+ ^" in this.{self::Test7::[]}(#t224).{core::double::+}(1) as{TypeError} core::int* in let final void #t227 = this.{self::Test7::[]=}(#t224, #t225) in #t225;
+ core::double* v11 = let final core::String* #t228 = "x" in let final core::double* #t229 = this.{self::Test7::[]}(#t228) in let final void #t230 = this.{self::Test7::[]=}(#t228, let final<BottomType> #t231 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:279:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
- var /*@ type=double* */ v11 = this /*@target=Test7::[]=*/ ['x']++;
- ^" in #t213.{core::double::+}(1) as{TypeError} core::int*) in #t213;
+ /*@target=double::+*/ ++;
+ ^" in #t229.{core::double::+}(1) as{TypeError} core::int*) in #t229;
}
}
abstract class Test8 extends core::Object {
@@ -195,17 +195,17 @@
abstract operator [](core::String* s) → core::double*;
abstract operator []=(core::String* s, core::num* v) → void;
method test() → void {
- core::int* v1 = let final core::String* #t216 = "x" in let final core::int* #t217 = self::getInt() in let final void #t218 = this.{self::Test8::[]=}(#t216, #t217) in #t217;
- core::num* v2 = let final core::String* #t219 = "x" in let final core::num* #t220 = self::getNum() in let final void #t221 = this.{self::Test8::[]=}(#t219, #t220) in #t220;
- core::double* v3 = let final core::String* #t222 = "x" in let final core::double* #t223 = self::getDouble() in let final void #t224 = this.{self::Test8::[]=}(#t222, #t223) in #t223;
- core::num* v4 = let final core::String* #t225 = "x" in let final core::double* #t226 = this.{self::Test8::[]}(#t225) in #t226.{core::num::==}(null) ?{core::num*} let final core::int* #t227 = self::getInt() in let final void #t228 = this.{self::Test8::[]=}(#t225, #t227) in #t227 : #t226;
- core::num* v5 = let final core::String* #t229 = "x" in let final core::double* #t230 = this.{self::Test8::[]}(#t229) in #t230.{core::num::==}(null) ?{core::num*} let final core::num* #t231 = self::getNum() in let final void #t232 = this.{self::Test8::[]=}(#t229, #t231) in #t231 : #t230;
- core::double* v6 = let final core::String* #t233 = "x" in let final core::double* #t234 = this.{self::Test8::[]}(#t233) in #t234.{core::num::==}(null) ?{core::double*} let final core::double* #t235 = self::getDouble() in let final void #t236 = this.{self::Test8::[]=}(#t233, #t235) in #t235 : #t234;
- core::double* v7 = let final core::String* #t237 = "x" in let final core::double* #t238 = this.{self::Test8::[]}(#t237).{core::double::+}(self::getInt()) in let final void #t239 = this.{self::Test8::[]=}(#t237, #t238) in #t238;
- core::double* v8 = let final core::String* #t240 = "x" in let final core::double* #t241 = this.{self::Test8::[]}(#t240).{core::double::+}(self::getNum()) in let final void #t242 = this.{self::Test8::[]=}(#t240, #t241) in #t241;
- core::double* v9 = let final core::String* #t243 = "x" in let final core::double* #t244 = this.{self::Test8::[]}(#t243).{core::double::+}(self::getDouble()) in let final void #t245 = this.{self::Test8::[]=}(#t243, #t244) in #t244;
- core::double* v10 = let final core::String* #t246 = "x" in let final core::double* #t247 = this.{self::Test8::[]}(#t246).{core::double::+}(1) in let final void #t248 = this.{self::Test8::[]=}(#t246, #t247) in #t247;
- core::double* v11 = let final core::String* #t249 = "x" in let final core::double* #t250 = this.{self::Test8::[]}(#t249) in let final void #t251 = this.{self::Test8::[]=}(#t249, #t250.{core::double::+}(1)) in #t250;
+ core::int* v1 = let final self::Test8* #t232 = this in let final core::String* #t233 = "x" in let final core::int* #t234 = self::getInt() in let final void #t235 = #t232.{self::Test8::[]=}(#t233, #t234) in #t234;
+ core::num* v2 = let final self::Test8* #t236 = this in let final core::String* #t237 = "x" in let final core::num* #t238 = self::getNum() in let final void #t239 = #t236.{self::Test8::[]=}(#t237, #t238) in #t238;
+ core::double* v3 = let final self::Test8* #t240 = this in let final core::String* #t241 = "x" in let final core::double* #t242 = self::getDouble() in let final void #t243 = #t240.{self::Test8::[]=}(#t241, #t242) in #t242;
+ core::num* v4 = let final core::String* #t244 = "x" in let final core::double* #t245 = this.{self::Test8::[]}(#t244) in #t245.{core::num::==}(null) ?{core::num*} let final core::int* #t246 = self::getInt() in let final void #t247 = this.{self::Test8::[]=}(#t244, #t246) in #t246 : #t245;
+ core::num* v5 = let final core::String* #t248 = "x" in let final core::double* #t249 = this.{self::Test8::[]}(#t248) in #t249.{core::num::==}(null) ?{core::num*} let final core::num* #t250 = self::getNum() in let final void #t251 = this.{self::Test8::[]=}(#t248, #t250) in #t250 : #t249;
+ core::double* v6 = let final core::String* #t252 = "x" in let final core::double* #t253 = this.{self::Test8::[]}(#t252) in #t253.{core::num::==}(null) ?{core::double*} let final core::double* #t254 = self::getDouble() in let final void #t255 = this.{self::Test8::[]=}(#t252, #t254) in #t254 : #t253;
+ core::double* v7 = let final core::String* #t256 = "x" in let final core::double* #t257 = this.{self::Test8::[]}(#t256).{core::double::+}(self::getInt()) in let final void #t258 = this.{self::Test8::[]=}(#t256, #t257) in #t257;
+ core::double* v8 = let final core::String* #t259 = "x" in let final core::double* #t260 = this.{self::Test8::[]}(#t259).{core::double::+}(self::getNum()) in let final void #t261 = this.{self::Test8::[]=}(#t259, #t260) in #t260;
+ core::double* v9 = let final core::String* #t262 = "x" in let final core::double* #t263 = this.{self::Test8::[]}(#t262).{core::double::+}(self::getDouble()) in let final void #t264 = this.{self::Test8::[]=}(#t262, #t263) in #t263;
+ core::double* v10 = let final core::String* #t265 = "x" in let final core::double* #t266 = this.{self::Test8::[]}(#t265).{core::double::+}(1) in let final void #t267 = this.{self::Test8::[]=}(#t265, #t266) in #t266;
+ core::double* v11 = let final core::String* #t268 = "x" in let final core::double* #t269 = this.{self::Test8::[]}(#t268) in let final void #t270 = this.{self::Test8::[]=}(#t268, #t269.{core::double::+}(1)) in #t269;
}
}
abstract class Test9 extends core::Object {
@@ -215,15 +215,15 @@
abstract operator [](core::String* s) → core::double*;
abstract operator []=(core::String* s, core::double* v) → void;
method test() → void {
- core::num* v2 = let final core::String* #t252 = "x" in let final core::num* #t253 = self::getNum() as{TypeError} core::double* in let final void #t254 = this.{self::Test9::[]=}(#t252, #t253) in #t253;
- core::double* v3 = let final core::String* #t255 = "x" in let final core::double* #t256 = self::getDouble() in let final void #t257 = this.{self::Test9::[]=}(#t255, #t256) in #t256;
- core::num* v5 = let final core::String* #t258 = "x" in let final core::double* #t259 = this.{self::Test9::[]}(#t258) in #t259.{core::num::==}(null) ?{core::num*} let final core::num* #t260 = self::getNum() as{TypeError} core::double* in let final void #t261 = this.{self::Test9::[]=}(#t258, #t260) in #t260 : #t259;
- core::double* v6 = let final core::String* #t262 = "x" in let final core::double* #t263 = this.{self::Test9::[]}(#t262) in #t263.{core::num::==}(null) ?{core::double*} let final core::double* #t264 = self::getDouble() in let final void #t265 = this.{self::Test9::[]=}(#t262, #t264) in #t264 : #t263;
- core::double* v7 = let final core::String* #t266 = "x" in let final core::double* #t267 = this.{self::Test9::[]}(#t266).{core::double::+}(self::getInt()) in let final void #t268 = this.{self::Test9::[]=}(#t266, #t267) in #t267;
- core::double* v8 = let final core::String* #t269 = "x" in let final core::double* #t270 = this.{self::Test9::[]}(#t269).{core::double::+}(self::getNum()) in let final void #t271 = this.{self::Test9::[]=}(#t269, #t270) in #t270;
- core::double* v9 = let final core::String* #t272 = "x" in let final core::double* #t273 = this.{self::Test9::[]}(#t272).{core::double::+}(self::getDouble()) in let final void #t274 = this.{self::Test9::[]=}(#t272, #t273) in #t273;
- core::double* v10 = let final core::String* #t275 = "x" in let final core::double* #t276 = this.{self::Test9::[]}(#t275).{core::double::+}(1) in let final void #t277 = this.{self::Test9::[]=}(#t275, #t276) in #t276;
- core::double* v11 = let final core::String* #t278 = "x" in let final core::double* #t279 = this.{self::Test9::[]}(#t278) in let final void #t280 = this.{self::Test9::[]=}(#t278, #t279.{core::double::+}(1)) in #t279;
+ core::num* v2 = let final self::Test9* #t271 = this in let final core::String* #t272 = "x" in let final core::num* #t273 = self::getNum() as{TypeError} core::double* in let final void #t274 = #t271.{self::Test9::[]=}(#t272, #t273) in #t273;
+ core::double* v3 = let final self::Test9* #t275 = this in let final core::String* #t276 = "x" in let final core::double* #t277 = self::getDouble() in let final void #t278 = #t275.{self::Test9::[]=}(#t276, #t277) in #t277;
+ core::num* v5 = let final core::String* #t279 = "x" in let final core::double* #t280 = this.{self::Test9::[]}(#t279) in #t280.{core::num::==}(null) ?{core::num*} let final core::num* #t281 = self::getNum() as{TypeError} core::double* in let final void #t282 = this.{self::Test9::[]=}(#t279, #t281) in #t281 : #t280;
+ core::double* v6 = let final core::String* #t283 = "x" in let final core::double* #t284 = this.{self::Test9::[]}(#t283) in #t284.{core::num::==}(null) ?{core::double*} let final core::double* #t285 = self::getDouble() in let final void #t286 = this.{self::Test9::[]=}(#t283, #t285) in #t285 : #t284;
+ core::double* v7 = let final core::String* #t287 = "x" in let final core::double* #t288 = this.{self::Test9::[]}(#t287).{core::double::+}(self::getInt()) in let final void #t289 = this.{self::Test9::[]=}(#t287, #t288) in #t288;
+ core::double* v8 = let final core::String* #t290 = "x" in let final core::double* #t291 = this.{self::Test9::[]}(#t290).{core::double::+}(self::getNum()) in let final void #t292 = this.{self::Test9::[]=}(#t290, #t291) in #t291;
+ core::double* v9 = let final core::String* #t293 = "x" in let final core::double* #t294 = this.{self::Test9::[]}(#t293).{core::double::+}(self::getDouble()) in let final void #t295 = this.{self::Test9::[]=}(#t293, #t294) in #t294;
+ core::double* v10 = let final core::String* #t296 = "x" in let final core::double* #t297 = this.{self::Test9::[]}(#t296).{core::double::+}(1) in let final void #t298 = this.{self::Test9::[]=}(#t296, #t297) in #t297;
+ core::double* v11 = let final core::String* #t299 = "x" in let final core::double* #t300 = this.{self::Test9::[]}(#t299) in let final void #t301 = this.{self::Test9::[]=}(#t299, #t300.{core::double::+}(1)) in #t300;
}
}
static method getInt() → core::int*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
index dee0c7d..b758ab5 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart
@@ -19,13 +19,11 @@
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=int* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=int* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
var /*@ type=int* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -49,17 +47,14 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=int* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=int* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
- var /*@ type=num* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=int* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -85,13 +80,11 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
- var /*@ type=num* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=int* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -117,13 +110,11 @@
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
var /*@ type=num* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -147,17 +138,14 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
- var /*@ type=num* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=num* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -183,13 +171,11 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
- var /*@ type=num* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ var /*@ type=num* */ v6 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=num* */ v7 =
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
@@ -215,13 +201,11 @@
var /*@ type=num* */ v2 = t /*@target=Test::[]=*/ ['x'] = getNum();
- var /*@ type=num* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
'x'] /*@ target=double::+ */ += getInt();
@@ -244,17 +228,15 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v4 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getInt();
+ var /*@ type=num* */ v4 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getInt();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
var /*@ type=double* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
'x'] /*@ target=double::+ */ += getInt();
@@ -278,13 +260,12 @@
var /*@ type=double* */ v3 = t /*@target=Test::[]=*/ ['x'] = getDouble();
- var /*@ type=num* */ v5 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getNum();
+ var /*@ type=num* */ v5 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getNum();
var /*@ type=double* */ v6 =
- t /*@target=Test::[]*/ ['x'] /*@target=num::==*/ /*@target=Test::[]=*/ ??=
- getDouble();
+ t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x']
+ /*@target=num::==*/ ??= getDouble();
var /*@ type=double* */ v7 = t /*@target=Test::[]*/ /*@target=Test::[]=*/ [
'x'] /*@ target=double::+ */ += getInt();
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
index 6e5b788..7ee2c5a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
@@ -2,37 +2,37 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
// t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:109:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
// /*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:112:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
// Try changing the type of the left hand side, or casting the right hand side to 'double'.
// 'x'] /*@ target=num::+ */ ++;
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:227:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
// 'x'] /*@ target=double::+ */ += getInt();
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:230:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
// 'x'] /*@ target=double::+ */ += getNum();
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:233:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
// /*@ target=double::+ */ ++t
// ^
//
-// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:237:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
// Try changing the type of the left hand side, or casting the right hand side to 'int'.
// 'x'] /*@ target=double::+ */ ++;
// ^
@@ -81,17 +81,17 @@
core::double* v3 = let final self::Test<core::int*, core::double*>* #t86 = t in let final core::String* #t87 = "x" in let final core::double* #t88 = self::getDouble() in let final void #t89 = #t86.{self::Test::[]=}(#t87, #t88) in #t88;
core::num* v5 = let final self::Test<core::int*, core::double*>* #t90 = t in let final core::String* #t91 = "x" in let final core::int* #t92 = #t90.{self::Test::[]}(#t91) in #t92.{core::num::==}(null) ?{core::num*} let final core::num* #t93 = self::getNum() as{TypeError} core::double* in let final void #t94 = #t90.{self::Test::[]=}(#t91, #t93) in #t93 : #t92;
core::num* v6 = let final self::Test<core::int*, core::double*>* #t95 = t in let final core::String* #t96 = "x" in let final core::int* #t97 = #t95.{self::Test::[]}(#t96) in #t97.{core::num::==}(null) ?{core::num*} let final core::double* #t98 = self::getDouble() in let final void #t99 = #t95.{self::Test::[]=}(#t96, #t98) in #t98 : #t97;
- core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:97:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v7 = let final self::Test<core::int*, core::double*>* #t100 = t in let final core::String* #t101 = "x" in let final core::int* #t102 = let final<BottomType> #t103 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:90:79: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'] /*@ target=num::+ */ +=
^" in #t100.{self::Test::[]}(#t101).{core::num::+}(self::getInt()) as{TypeError} core::double* in let final void #t104 = #t100.{self::Test::[]=}(#t101, #t102) in #t102;
core::num* v8 = let final self::Test<core::int*, core::double*>* #t105 = t in let final core::String* #t106 = "x" in let final core::num* #t107 = #t105.{self::Test::[]}(#t106).{core::num::+}(self::getNum()) as{TypeError} core::double* in let final void #t108 = #t105.{self::Test::[]=}(#t106, #t107) in #t107;
core::double* v9 = let final self::Test<core::int*, core::double*>* #t109 = t in let final core::String* #t110 = "x" in let final core::double* #t111 = #t109.{self::Test::[]}(#t110).{core::num::+}(self::getDouble()) in let final void #t112 = #t109.{self::Test::[]=}(#t110, #t111) in #t111;
- core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:109:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v10 = let final self::Test<core::int*, core::double*>* #t113 = t in let final core::String* #t114 = "x" in let final core::int* #t115 = let final<BottomType> #t116 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:102:28: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
/*@ target=num::+ */ ++t /*@target=Test::[]*/ /*@target=Test::[]=*/ ['x'];
^" in #t113.{self::Test::[]}(#t114).{core::num::+}(1) as{TypeError} core::double* in let final void #t117 = #t113.{self::Test::[]=}(#t114, #t115) in #t115;
- core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:112:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
+ core::int* v11 = let final self::Test<core::int*, core::double*>* #t118 = t in let final core::String* #t119 = "x" in let final core::int* #t120 = #t118.{self::Test::[]}(#t119) in let final void #t121 = #t118.{self::Test::[]=}(#t119, let final<BottomType> #t122 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:105:33: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
Try changing the type of the left hand side, or casting the right hand side to 'double'.
'x'] /*@ target=num::+ */ ++;
^" in #t120.{core::num::+}(1) as{TypeError} core::double*) in #t120;
@@ -135,19 +135,19 @@
core::num* v2 = let final self::Test<core::double*, core::int*>* #t246 = t in let final core::String* #t247 = "x" in let final core::num* #t248 = self::getNum() as{TypeError} core::int* in let final void #t249 = #t246.{self::Test::[]=}(#t247, #t248) in #t248;
core::num* v4 = let final self::Test<core::double*, core::int*>* #t250 = t in let final core::String* #t251 = "x" in let final core::double* #t252 = #t250.{self::Test::[]}(#t251) in #t252.{core::num::==}(null) ?{core::num*} let final core::int* #t253 = self::getInt() in let final void #t254 = #t250.{self::Test::[]=}(#t251, #t253) in #t253 : #t252;
core::num* v5 = let final self::Test<core::double*, core::int*>* #t255 = t in let final core::String* #t256 = "x" in let final core::double* #t257 = #t255.{self::Test::[]}(#t256) in #t257.{core::num::==}(null) ?{core::num*} let final core::num* #t258 = self::getNum() as{TypeError} core::int* in let final void #t259 = #t255.{self::Test::[]=}(#t256, #t258) in #t258 : #t257;
- core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double* #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:227:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v7 = let final self::Test<core::double*, core::int*>* #t260 = t in let final core::String* #t261 = "x" in let final core::double* #t262 = let final<BottomType> #t263 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:211:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
'x'] /*@ target=double::+ */ += getInt();
^" in #t260.{self::Test::[]}(#t261).{core::double::+}(self::getInt()) as{TypeError} core::int* in let final void #t264 = #t260.{self::Test::[]=}(#t261, #t262) in #t262;
- core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double* #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:230:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v8 = let final self::Test<core::double*, core::int*>* #t265 = t in let final core::String* #t266 = "x" in let final core::double* #t267 = let final<BottomType> #t268 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:214:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
'x'] /*@ target=double::+ */ += getNum();
^" in #t265.{self::Test::[]}(#t266).{core::double::+}(self::getNum()) as{TypeError} core::int* in let final void #t269 = #t265.{self::Test::[]=}(#t266, #t267) in #t267;
- core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double* #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:233:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v10 = let final self::Test<core::double*, core::int*>* #t270 = t in let final core::String* #t271 = "x" in let final core::double* #t272 = let final<BottomType> #t273 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:217:31: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
/*@ target=double::+ */ ++t
^" in #t270.{self::Test::[]}(#t271).{core::double::+}(1) as{TypeError} core::int* in let final void #t274 = #t270.{self::Test::[]=}(#t271, #t272) in #t272;
- core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:237:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+ core::double* v11 = let final self::Test<core::double*, core::int*>* #t275 = t in let final core::String* #t276 = "x" in let final core::double* #t277 = #t275.{self::Test::[]}(#t276) in let final void #t278 = #t275.{self::Test::[]=}(#t276, let final<BottomType> #t279 = invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:221:36: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
Try changing the type of the left hand side, or casting the right hand side to 'int'.
'x'] /*@ target=double::+ */ ++;
^" in #t277.{core::double::+}(1) as{TypeError} core::int*) in #t277;
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
index 05354e5..ddc5083 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart
@@ -21,21 +21,35 @@
void test() {
B local;
local = /*@ typeArgs=B* */ f();
- local ??= /*@ typeArgs=B* */ f();
+
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
/*@ target=B::- */ --local;
+
local /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
- var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
+
+ var /*@ type=B* */ v2 =
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+
var /*@ type=A* */ v3 = local
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 = local
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 = local
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
+
var /*@ type=B* */ v7 = /*@ type=B* */ local
/*@ type=B* */ /*@ target=B::- */ --;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
index 7113cbf..64f43c5 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.type_promotion.expect
@@ -1,42 +1,42 @@
pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:23:9: Context: Write to local@474
local = /*@ typeArgs=B* */ f();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:24:9: Context: Write to local@474
- local ??= /*@ typeArgs=B* */ f();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:25:28: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:25:34: Context: Write to local@474
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:27:28: Context: Write to local@474
local /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:26:28: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:29:28: Context: Write to local@474
local /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:27:28: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:31:28: Context: Write to local@474
local /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:28:22: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:33:22: Context: Write to local@474
/*@ target=B::- */ --local;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:29:28: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:35:28: Context: Write to local@474
local /*@ target=B::- */ --;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:30:33: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:37:33: Context: Write to local@474
var /*@ type=B* */ v1 = local = /*@ typeArgs=B* */ f();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:31:33: Context: Write to local@474
- var /*@ type=B* */ v2 = local ??= /*@ typeArgs=B* */ f();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:33:26: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:40:38: Context: Write to local@474
+ local /*@ target=Object::== */ ??= /*@ typeArgs=B* */ f();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:43:26: Context: Write to local@474
/*@ target=B::+ */ += /*@ typeArgs=C* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:35:26: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:46:26: Context: Write to local@474
/*@ target=B::* */ *= /*@ typeArgs=B* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:37:26: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:49:26: Context: Write to local@474
/*@ target=B::& */ &= /*@ typeArgs=A* */ f();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:38:46: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:51:46: Context: Write to local@474
var /*@ type=B* */ v6 = /*@ target=B::- */ --local;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:40:41: Context: Write to local@474
+pkg/front_end/testcases/inference_new/infer_assign_to_local.dart:54:41: Context: Write to local@474
/*@ type=B* */ /*@ target=B::- */ --;
^^
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
index b88af64..e8b79a0 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart
@@ -11,40 +11,65 @@
void test1(int t) {
var /*@ type=int* */ v1 = t = getInt();
+
var /*@ type=num* */ v2 = t = getNum();
- var /*@ type=int* */ v4 = t ??= getInt();
- var /*@ type=num* */ v5 = t ??= getNum();
+
+ var /*@ type=int* */ v4 = t /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+
var /*@ type=int* */ v7 = t /*@ target=num::+ */ += getInt();
+
var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+
var /*@ type=int* */ v10 = /*@ target=num::+ */ ++t;
+
var /*@ type=int* */ v11 =
/*@ type=int* */ t /*@ type=int* */ /*@ target=num::+ */ ++;
}
void test2(num t) {
var /*@ type=int* */ v1 = t = getInt();
+
var /*@ type=num* */ v2 = t = getNum();
+
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v4 = t ??= getInt();
- var /*@ type=num* */ v5 = t ??= getNum();
- var /*@ type=num* */ v6 = t ??= getDouble();
+
+ var /*@ type=num* */ v4 = t /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = t /*@ target=num::== */ ??= getDouble();
+
var /*@ type=num* */ v7 = t /*@ target=num::+ */ += getInt();
+
var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
+
var /*@ type=num* */ v9 = t /*@ target=num::+ */ += getDouble();
+
var /*@ type=num* */ v10 = /*@ target=num::+ */ ++t;
+
var /*@ type=num* */ v11 =
/*@ type=num* */ t /*@ type=num* */ /*@ target=num::+ */ ++;
}
void test3(double t) {
var /*@ type=num* */ v2 = t = getNum();
+
var /*@ type=double* */ v3 = t = getDouble();
- var /*@ type=num* */ v5 = t ??= getNum();
- var /*@ type=double* */ v6 = t ??= getDouble();
+
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=double* */ v6 = t /*@ target=num::== */ ??= getDouble();
+
var /*@ type=double* */ v7 = t /*@ target=double::+ */ += getInt();
+
var /*@ type=double* */ v8 = t /*@ target=double::+ */ += getNum();
+
var /*@ type=double* */ v9 = t /*@ target=double::+ */ += getDouble();
+
var /*@ type=double* */ v10 = /*@ target=double::+ */ ++t;
+
var /*@ type=double* */ v11 =
/*@ type=double* */ t /*@ type=double* */ /*@ target=double::+ */ ++;
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
index e076b03..db044b6 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.type_promotion.expect
@@ -1,84 +1,84 @@
pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:13:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:14:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:15:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:15:31: Context: Write to t@343
- var /*@ type=int* */ v4 = t ??= getInt();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:16:31: Context: Write to t@343
- var /*@ type=num* */ v5 = t ??= getNum();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:17:52: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:17:53: Context: Write to t@343
+ var /*@ type=int* */ v4 = t /*@ target=num::== */ ??= getInt();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:19:53: Context: Write to t@343
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:21:52: Context: Write to t@343
var /*@ type=int* */ v7 = t /*@ target=num::+ */ += getInt();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:18:52: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:23:52: Context: Write to t@343
var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:19:51: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:25:51: Context: Write to t@343
var /*@ type=int* */ v10 = /*@ target=num::+ */ ++t;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:21:64: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:28:64: Context: Write to t@343
/*@ type=int* */ t /*@ type=int* */ /*@ target=num::+ */ ++;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:25:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:32:31: Context: Write to t@343
var /*@ type=int* */ v1 = t = getInt();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:26:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:34:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:27:34: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:36:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:28:31: Context: Write to t@343
- var /*@ type=num* */ v4 = t ??= getInt();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:29:31: Context: Write to t@343
- var /*@ type=num* */ v5 = t ??= getNum();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:30:31: Context: Write to t@343
- var /*@ type=num* */ v6 = t ??= getDouble();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:31:52: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:38:53: Context: Write to t@343
+ var /*@ type=num* */ v4 = t /*@ target=num::== */ ??= getInt();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:40:53: Context: Write to t@343
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:42:53: Context: Write to t@343
+ var /*@ type=num* */ v6 = t /*@ target=num::== */ ??= getDouble();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:44:52: Context: Write to t@343
var /*@ type=num* */ v7 = t /*@ target=num::+ */ += getInt();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:32:52: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:46:52: Context: Write to t@343
var /*@ type=num* */ v8 = t /*@ target=num::+ */ += getNum();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:33:52: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:48:52: Context: Write to t@343
var /*@ type=num* */ v9 = t /*@ target=num::+ */ += getDouble();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:34:51: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:50:51: Context: Write to t@343
var /*@ type=num* */ v10 = /*@ target=num::+ */ ++t;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:36:64: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:53:64: Context: Write to t@343
/*@ type=num* */ t /*@ type=num* */ /*@ target=num::+ */ ++;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:40:31: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:57:31: Context: Write to t@343
var /*@ type=num* */ v2 = t = getNum();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:41:34: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:59:34: Context: Write to t@343
var /*@ type=double* */ v3 = t = getDouble();
^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:42:31: Context: Write to t@343
- var /*@ type=num* */ v5 = t ??= getNum();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:43:34: Context: Write to t@343
- var /*@ type=double* */ v6 = t ??= getDouble();
- ^^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:44:58: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:61:53: Context: Write to t@343
+ var /*@ type=num* */ v5 = t /*@ target=num::== */ ??= getNum();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:63:56: Context: Write to t@343
+ var /*@ type=double* */ v6 = t /*@ target=num::== */ ??= getDouble();
+ ^^^
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:65:58: Context: Write to t@343
var /*@ type=double* */ v7 = t /*@ target=double::+ */ += getInt();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:45:58: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:67:58: Context: Write to t@343
var /*@ type=double* */ v8 = t /*@ target=double::+ */ += getNum();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:46:58: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:69:58: Context: Write to t@343
var /*@ type=double* */ v9 = t /*@ target=double::+ */ += getDouble();
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:47:57: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:71:57: Context: Write to t@343
var /*@ type=double* */ v10 = /*@ target=double::+ */ ++t;
^^
-pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:49:73: Context: Write to t@343
+pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart:74:73: Context: Write to t@343
/*@ type=double* */ t /*@ type=double* */ /*@ target=double::+ */ ++;
^^
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
index b2b1f77..0833acd 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart
@@ -24,25 +24,60 @@
static void test(Test t) {
/*@ type=Test* */ /*@target=Object::==*/ t
?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
- t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
- t?. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
- t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
- t?. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- --t?. /*@target=Test::member*/ member;
- t?. /*@target=Test::member*/ member--;
+
+ /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+
+ /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
+ /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
+ /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ /*@ target=B::- */ -- /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member;
+
+ /*@target=Object::==*/ t?.
+ /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
+
var /*@ type=B* */ v1 =
/*@ type=Test* */ /*@target=Object::==*/ t
?. /*@target=Test::member*/ member = /*@ typeArgs=B* */ f();
+
var /*@ type=B* */ v2 =
- t?. /*@target=Test::member*/ member ??= /*@ typeArgs=B* */ f();
+ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@target=Object::==*/ ??= /*@ typeArgs=B* */ f();
+
var /*@ type=A* */ v3 =
- t?. /*@target=Test::member*/ member += /*@ typeArgs=dynamic */ f();
+ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::+ */ += /*@ typeArgs=C* */ f();
+
var /*@ type=B* */ v4 =
- t?. /*@target=Test::member*/ member *= /*@ typeArgs=dynamic */ f();
+ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::* */ *= /*@ typeArgs=B* */ f();
+
var /*@ type=C* */ v5 =
- t?. /*@target=Test::member*/ member &= /*@ typeArgs=dynamic */ f();
- var /*@ type=B* */ v6 = --t?. /*@target=Test::member*/ member;
- var /*@ type=B* */ v7 = t?. /*@target=Test::member*/ member--;
+ /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::& */ &= /*@ typeArgs=A* */ f();
+
+ var /*@ type=B* */ v6 = /*@ target=B::- */ -- /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member;
+
+ var /*@ type=B* */ v7 = /*@target=Object::==*/ t
+ ?. /*@target=Test::member*/ /*@target=Test::member*/ member
+ /*@ target=B::- */ --;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
index 52f7978..60aa66d 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.expect
@@ -32,19 +32,19 @@
;
static method test(self::Test* t) → void {
let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
- let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
- let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
- self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
- self::A* v3 = let final self::Test* #t11 = t in #t11.==(null) ?{self::A*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = let final self::Test* #t12 = t in #t12.==(null) ?{self::B*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t13 = t in #t13.==(null) ?{self::C*} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t14 = t in #t14.==(null) ?{self::B*} null : #t14.{self::Test::member} = #t14.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t15 = t in #t15.==(null) ?{self::B*} null : let final self::B* #t16 = #t15.{self::Test::member} in let final self::B* #t17 = #t15.{self::Test::member} = #t16.{self::B::-}(1) in #t16;
+ let final self::Test* #t2 = t in #t2.{core::Object::==}(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
+ let final self::Test* #t3 = t in #t3.{core::Object::==}(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t4 = t in #t4.{core::Object::==}(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t5 = t in #t5.{core::Object::==}(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ let final self::Test* #t6 = t in #t6.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t7 = #t6.{self::Test::member}.{self::B::-}(1) in let final void #t8 = #t6.{self::Test::member} = #t7 in #t7;
+ let final self::Test* #t9 = t in #t9.{core::Object::==}(null) ?{self::B*} null : #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::-}(1);
+ self::B* v1 = let final self::Test* #t10 = t in #t10.{core::Object::==}(null) ?{self::B*} null : #t10.{self::Test::member} = self::f<self::B*>();
+ self::B* v2 = let final self::Test* #t11 = t in #t11.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t12 = #t11.{self::Test::member} in #t12.{core::Object::==}(null) ?{self::B*} #t11.{self::Test::member} = self::f<self::B*>() : #t12;
+ self::A* v3 = let final self::Test* #t13 = t in #t13.{core::Object::==}(null) ?{self::A*} null : let final self::A* #t14 = #t13.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t15 = #t13.{self::Test::member} = #t14 in #t14;
+ self::B* v4 = let final self::Test* #t16 = t in #t16.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t17 = #t16.{self::Test::member}.{self::B::*}(self::f<self::B*>()) in let final void #t18 = #t16.{self::Test::member} = #t17 in #t17;
+ self::C* v5 = let final self::Test* #t19 = t in #t19.{core::Object::==}(null) ?{self::C*} null : let final self::C* #t20 = #t19.{self::Test::member}.{self::B::&}(self::f<self::A*>()) in let final void #t21 = #t19.{self::Test::member} = #t20 in #t20;
+ self::B* v6 = let final self::Test* #t22 = t in #t22.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t23 = #t22.{self::Test::member}.{self::B::-}(1) in let final void #t24 = #t22.{self::Test::member} = #t23 in #t23;
+ self::B* v7 = let final self::Test* #t25 = t in #t25.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t26 = #t25.{self::Test::member} in let final void #t27 = #t25.{self::Test::member} = #t26.{self::B::-}(1) in #t26;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
index 52f7978..60aa66d 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -32,19 +32,19 @@
;
static method test(self::Test* t) → void {
let final self::Test* #t1 = t in #t1.{core::Object::==}(null) ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
- let final self::Test* #t2 = t in #t2.==(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
- let final self::Test* #t3 = t in #t3.==(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- let final self::Test* #t4 = t in #t4.==(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- let final self::Test* #t5 = t in #t5.==(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- let final self::Test* #t6 = t in #t6.==(null) ?{self::B*} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
- let final self::Test* #t7 = t in #t7.==(null) ?{self::B*} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
- self::B* v1 = let final self::Test* #t8 = t in #t8.{core::Object::==}(null) ?{self::B*} null : #t8.{self::Test::member} = self::f<self::B*>();
- self::B* v2 = let final self::Test* #t9 = t in #t9.==(null) ?{self::B*} null : let final self::B* #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B*} #t9.{self::Test::member} = self::f<self::B*>() : #t10;
- self::A* v3 = let final self::Test* #t11 = t in #t11.==(null) ?{self::A*} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C*) as{TypeError} self::B*;
- self::B* v4 = let final self::Test* #t12 = t in #t12.==(null) ?{self::B*} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B*);
- self::C* v5 = let final self::Test* #t13 = t in #t13.==(null) ?{self::C*} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A*);
- self::B* v6 = let final self::Test* #t14 = t in #t14.==(null) ?{self::B*} null : #t14.{self::Test::member} = #t14.{self::Test::member}.{self::B::-}(1);
- self::B* v7 = let final self::Test* #t15 = t in #t15.==(null) ?{self::B*} null : let final self::B* #t16 = #t15.{self::Test::member} in let final self::B* #t17 = #t15.{self::Test::member} = #t16.{self::B::-}(1) in #t16;
+ let final self::Test* #t2 = t in #t2.{core::Object::==}(null) ?{self::B*} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
+ let final self::Test* #t3 = t in #t3.{core::Object::==}(null) ?{self::A*} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B*;
+ let final self::Test* #t4 = t in #t4.{core::Object::==}(null) ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<self::B*>());
+ let final self::Test* #t5 = t in #t5.{core::Object::==}(null) ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<self::A*>());
+ let final self::Test* #t6 = t in #t6.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t7 = #t6.{self::Test::member}.{self::B::-}(1) in let final void #t8 = #t6.{self::Test::member} = #t7 in #t7;
+ let final self::Test* #t9 = t in #t9.{core::Object::==}(null) ?{self::B*} null : #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::-}(1);
+ self::B* v1 = let final self::Test* #t10 = t in #t10.{core::Object::==}(null) ?{self::B*} null : #t10.{self::Test::member} = self::f<self::B*>();
+ self::B* v2 = let final self::Test* #t11 = t in #t11.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t12 = #t11.{self::Test::member} in #t12.{core::Object::==}(null) ?{self::B*} #t11.{self::Test::member} = self::f<self::B*>() : #t12;
+ self::A* v3 = let final self::Test* #t13 = t in #t13.{core::Object::==}(null) ?{self::A*} null : let final self::A* #t14 = #t13.{self::Test::member}.{self::B::+}(self::f<self::C*>()) as{TypeError} self::B* in let final void #t15 = #t13.{self::Test::member} = #t14 in #t14;
+ self::B* v4 = let final self::Test* #t16 = t in #t16.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t17 = #t16.{self::Test::member}.{self::B::*}(self::f<self::B*>()) in let final void #t18 = #t16.{self::Test::member} = #t17 in #t17;
+ self::C* v5 = let final self::Test* #t19 = t in #t19.{core::Object::==}(null) ?{self::C*} null : let final self::C* #t20 = #t19.{self::Test::member}.{self::B::&}(self::f<self::A*>()) in let final void #t21 = #t19.{self::Test::member} = #t20 in #t20;
+ self::B* v6 = let final self::Test* #t22 = t in #t22.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t23 = #t22.{self::Test::member}.{self::B::-}(1) in let final void #t24 = #t22.{self::Test::member} = #t23 in #t23;
+ self::B* v7 = let final self::Test* #t25 = t in #t25.{core::Object::==}(null) ?{self::B*} null : let final self::B* #t26 = #t25.{self::Test::member} in let final void #t27 = #t25.{self::Test::member} = #t26.{self::B::-}(1) in #t26;
}
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
index a8d4387..75ea000 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart
@@ -15,14 +15,33 @@
static void test(Test1 t) {
var /*@ type=int* */ v1 = /*@ type=Test1* */ /*@target=Object::==*/ t
?. /*@target=Test1::prop*/ prop = getInt();
+
var /*@ type=num* */ v2 = /*@ type=Test1* */ /*@target=Object::==*/ t
?. /*@target=Test1::prop*/ prop = getNum();
- var /*@ type=int* */ v4 = t?. /*@target=Test1::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t?. /*@target=Test1::prop*/ prop ??= getNum();
- var /*@ type=int* */ v7 = t?. /*@target=Test1::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t?. /*@target=Test1::prop*/ prop += getNum();
- var /*@ type=int* */ v10 = ++t?. /*@target=Test1::prop*/ prop;
- var /*@ type=int* */ v11 = t?. /*@target=Test1::prop*/ prop++;
+
+ var /*@ type=int* */ v4 = /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=int* */ v7 = /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 = /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=int* */ v10 = /*@ target=num::+ */ ++
+ /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop;
+
+ var /*@ type=int* */ v11 = /*@target=Object::==*/ t?.
+ /*@target=Test1::prop*/ /*@target=Test1::prop*/ prop
+ /*@ target=num::+ */ ++;
}
}
@@ -32,18 +51,43 @@
static void test(Test2 t) {
var /*@ type=int* */ v1 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getInt();
+
var /*@ type=num* */ v2 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getNum();
+
var /*@ type=double* */ v3 = /*@ type=Test2* */ /*@target=Object::==*/ t
?. /*@target=Test2::prop*/ prop = getDouble();
- var /*@ type=num* */ v4 = t?. /*@target=Test2::prop*/ prop ??= getInt();
- var /*@ type=num* */ v5 = t?. /*@target=Test2::prop*/ prop ??= getNum();
- var /*@ type=num* */ v6 = t?. /*@target=Test2::prop*/ prop ??= getDouble();
- var /*@ type=num* */ v7 = t?. /*@target=Test2::prop*/ prop += getInt();
- var /*@ type=num* */ v8 = t?. /*@target=Test2::prop*/ prop += getNum();
- var /*@ type=num* */ v9 = t?. /*@target=Test2::prop*/ prop += getDouble();
- var /*@ type=num* */ v10 = ++t?. /*@target=Test2::prop*/ prop;
- var /*@ type=num* */ v11 = t?. /*@target=Test2::prop*/ prop++;
+
+ var /*@ type=num* */ v4 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::== */ ??= getInt();
+
+ var /*@ type=num* */ v5 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::== */ ??= getNum();
+
+ var /*@ type=num* */ v6 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=num* */ v7 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getInt();
+
+ var /*@ type=num* */ v8 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ += getNum();
+
+ var /*@ type=num* */ v9 = /*@target=Object::==*/ t?.
+ /*@target=Test2::prop*/ /*@target=Test2::prop*/
+ prop /*@ target=num::+ */ += getDouble();
+
+ var /*@ type=num* */ v10 = /*@ target=num::+ */ ++ /*@target=Object::==*/
+ t?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop;
+
+ var /*@ type=num* */ v11 = /*@target=Object::==*/
+ t?. /*@target=Test2::prop*/ /*@target=Test2::prop*/ prop
+ /*@ target=num::+ */ ++;
}
}
@@ -53,17 +97,39 @@
static void test3(Test3 t) {
var /*@ type=num* */ v2 = /*@ type=Test3* */ /*@target=Object::==*/ t
?. /*@target=Test3::prop*/ prop = getNum();
+
var /*@ type=double* */ v3 = /*@ type=Test3* */ /*@target=Object::==*/ t
?. /*@target=Test3::prop*/ prop = getDouble();
- var /*@ type=num* */ v5 = t?. /*@target=Test3::prop*/ prop ??= getNum();
+
+ var /*@ type=num* */ v5 = /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=num::== */ ??= getNum();
+
var /*@ type=double* */ v6 =
- t?. /*@target=Test3::prop*/ prop ??= getDouble();
- var /*@ type=double* */ v7 = t?. /*@target=Test3::prop*/ prop += getInt();
- var /*@ type=double* */ v8 = t?. /*@target=Test3::prop*/ prop += getNum();
+ /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=num::== */ ??= getDouble();
+
+ var /*@ type=double* */ v7 = /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getInt();
+
+ var /*@ type=double* */ v8 = /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getNum();
+
var /*@ type=double* */ v9 =
- t?. /*@target=Test3::prop*/ prop += getDouble();
- var /*@ type=double* */ v10 = ++t?. /*@target=Test3::prop*/ prop;
- var /*@ type=double* */ v11 = t?. /*@target=Test3::prop*/ prop++;
+ /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ += getDouble();
+
+ var /*@ type=double* */ v10 = /*@ target=double::+ */ ++
+ /*@target=Object::==*/ t?.
+ /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop;
+
+ var /*@ type=double* */ v11 = /*@target=Object::==*/
+ t?. /*@target=Test3::prop*/ /*@target=Test3::prop*/ prop
+ /*@ target=double::+ */ ++;
}
}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
index da54b4b..97a828a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.expect
@@ -10,12 +10,12 @@
static method test(self::Test1* t) → void {
core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
core::num* v2 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
- core::int* v4 = let final self::Test1* #t3 = t in #t3.==(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
- core::num* v5 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
- core::int* v7 = let final self::Test1* #t7 = t in #t7.==(null) ?{core::int*} null : #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test1* #t8 = t in #t8.==(null) ?{core::num*} null : #t8.{self::Test1::prop} = #t8.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int*;
- core::int* v10 = let final self::Test1* #t9 = t in #t9.==(null) ?{core::int*} null : #t9.{self::Test1::prop} = #t9.{self::Test1::prop}.{core::num::+}(1);
- core::int* v11 = let final self::Test1* #t10 = t in #t10.==(null) ?{core::int*} null : let final core::int* #t11 = #t10.{self::Test1::prop} in let final core::int* #t12 = #t10.{self::Test1::prop} = #t11.{core::num::+}(1) in #t11;
+ core::int* v4 = let final self::Test1* #t3 = t in #t3.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
+ core::num* v5 = let final self::Test1* #t5 = t in #t5.{core::Object::==}(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
+ core::int* v7 = let final self::Test1* #t7 = t in #t7.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t8 = #t7.{self::Test1::prop}.{core::num::+}(self::getInt()) in let final void #t9 = #t7.{self::Test1::prop} = #t8 in #t8;
+ core::num* v8 = let final self::Test1* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t11 = #t10.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t12 = #t10.{self::Test1::prop} = #t11 in #t11;
+ core::int* v10 = let final self::Test1* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t14 = #t13.{self::Test1::prop}.{core::num::+}(1) in let final void #t15 = #t13.{self::Test1::prop} = #t14 in #t14;
+ core::int* v11 = let final self::Test1* #t16 = t in #t16.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t17 = #t16.{self::Test1::prop} in let final void #t18 = #t16.{self::Test1::prop} = #t17.{core::num::+}(1) in #t17;
}
}
class Test2 extends core::Object {
@@ -24,17 +24,17 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
- core::num* v4 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
- core::num* v5 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
- core::num* v6 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
- core::num* v7 = let final self::Test2* #t22 = t in #t22.==(null) ?{core::num*} null : #t22.{self::Test2::prop} = #t22.{self::Test2::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test2* #t23 = t in #t23.==(null) ?{core::num*} null : #t23.{self::Test2::prop} = #t23.{self::Test2::prop}.{core::num::+}(self::getNum());
- core::num* v9 = let final self::Test2* #t24 = t in #t24.==(null) ?{core::num*} null : #t24.{self::Test2::prop} = #t24.{self::Test2::prop}.{core::num::+}(self::getDouble());
- core::num* v10 = let final self::Test2* #t25 = t in #t25.==(null) ?{core::num*} null : #t25.{self::Test2::prop} = #t25.{self::Test2::prop}.{core::num::+}(1);
- core::num* v11 = let final self::Test2* #t26 = t in #t26.==(null) ?{core::num*} null : let final core::num* #t27 = #t26.{self::Test2::prop} in let final core::num* #t28 = #t26.{self::Test2::prop} = #t27.{core::num::+}(1) in #t27;
+ core::int* v1 = let final self::Test2* #t19 = t in #t19.{core::Object::==}(null) ?{core::int*} null : #t19.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t20 = t in #t20.{core::Object::==}(null) ?{core::num*} null : #t20.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t21 = t in #t21.{core::Object::==}(null) ?{core::double*} null : #t21.{self::Test2::prop} = self::getDouble();
+ core::num* v4 = let final self::Test2* #t22 = t in #t22.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop} in #t23.{core::num::==}(null) ?{core::num*} #t22.{self::Test2::prop} = self::getInt() : #t23;
+ core::num* v5 = let final self::Test2* #t24 = t in #t24.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t25 = #t24.{self::Test2::prop} in #t25.{core::num::==}(null) ?{core::num*} #t24.{self::Test2::prop} = self::getNum() : #t25;
+ core::num* v6 = let final self::Test2* #t26 = t in #t26.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t27 = #t26.{self::Test2::prop} in #t27.{core::num::==}(null) ?{core::num*} #t26.{self::Test2::prop} = self::getDouble() : #t27;
+ core::num* v7 = let final self::Test2* #t28 = t in #t28.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t29 = #t28.{self::Test2::prop}.{core::num::+}(self::getInt()) in let final void #t30 = #t28.{self::Test2::prop} = #t29 in #t29;
+ core::num* v8 = let final self::Test2* #t31 = t in #t31.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t32 = #t31.{self::Test2::prop}.{core::num::+}(self::getNum()) in let final void #t33 = #t31.{self::Test2::prop} = #t32 in #t32;
+ core::num* v9 = let final self::Test2* #t34 = t in #t34.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t35 = #t34.{self::Test2::prop}.{core::num::+}(self::getDouble()) in let final void #t36 = #t34.{self::Test2::prop} = #t35 in #t35;
+ core::num* v10 = let final self::Test2* #t37 = t in #t37.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t38 = #t37.{self::Test2::prop}.{core::num::+}(1) in let final void #t39 = #t37.{self::Test2::prop} = #t38 in #t38;
+ core::num* v11 = let final self::Test2* #t40 = t in #t40.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t41 = #t40.{self::Test2::prop} in let final void #t42 = #t40.{self::Test2::prop} = #t41.{core::num::+}(1) in #t41;
}
}
class Test3 extends core::Object {
@@ -43,15 +43,15 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::num* v2 = let final self::Test3* #t29 = t in #t29.{core::Object::==}(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
- core::double* v3 = let final self::Test3* #t30 = t in #t30.{core::Object::==}(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
- core::num* v5 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::num*} null : let final core::double* #t32 = #t31.{self::Test3::prop} in #t32.{core::num::==}(null) ?{core::num*} #t31.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t32;
- core::double* v6 = let final self::Test3* #t33 = t in #t33.==(null) ?{core::double*} null : let final core::double* #t34 = #t33.{self::Test3::prop} in #t34.{core::num::==}(null) ?{core::double*} #t33.{self::Test3::prop} = self::getDouble() : #t34;
- core::double* v7 = let final self::Test3* #t35 = t in #t35.==(null) ?{core::double*} null : #t35.{self::Test3::prop} = #t35.{self::Test3::prop}.{core::double::+}(self::getInt());
- core::double* v8 = let final self::Test3* #t36 = t in #t36.==(null) ?{core::double*} null : #t36.{self::Test3::prop} = #t36.{self::Test3::prop}.{core::double::+}(self::getNum());
- core::double* v9 = let final self::Test3* #t37 = t in #t37.==(null) ?{core::double*} null : #t37.{self::Test3::prop} = #t37.{self::Test3::prop}.{core::double::+}(self::getDouble());
- core::double* v10 = let final self::Test3* #t38 = t in #t38.==(null) ?{core::double*} null : #t38.{self::Test3::prop} = #t38.{self::Test3::prop}.{core::double::+}(1);
- core::double* v11 = let final self::Test3* #t39 = t in #t39.==(null) ?{core::double*} null : let final core::double* #t40 = #t39.{self::Test3::prop} in let final core::double* #t41 = #t39.{self::Test3::prop} = #t40.{core::double::+}(1) in #t40;
+ core::num* v2 = let final self::Test3* #t43 = t in #t43.{core::Object::==}(null) ?{core::num*} null : #t43.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
+ core::double* v3 = let final self::Test3* #t44 = t in #t44.{core::Object::==}(null) ?{core::double*} null : #t44.{self::Test3::prop} = self::getDouble();
+ core::num* v5 = let final self::Test3* #t45 = t in #t45.{core::Object::==}(null) ?{core::num*} null : let final core::double* #t46 = #t45.{self::Test3::prop} in #t46.{core::num::==}(null) ?{core::num*} #t45.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t46;
+ core::double* v6 = let final self::Test3* #t47 = t in #t47.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t48 = #t47.{self::Test3::prop} in #t48.{core::num::==}(null) ?{core::double*} #t47.{self::Test3::prop} = self::getDouble() : #t48;
+ core::double* v7 = let final self::Test3* #t49 = t in #t49.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t50 = #t49.{self::Test3::prop}.{core::double::+}(self::getInt()) in let final void #t51 = #t49.{self::Test3::prop} = #t50 in #t50;
+ core::double* v8 = let final self::Test3* #t52 = t in #t52.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t53 = #t52.{self::Test3::prop}.{core::double::+}(self::getNum()) in let final void #t54 = #t52.{self::Test3::prop} = #t53 in #t53;
+ core::double* v9 = let final self::Test3* #t55 = t in #t55.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t56 = #t55.{self::Test3::prop}.{core::double::+}(self::getDouble()) in let final void #t57 = #t55.{self::Test3::prop} = #t56 in #t56;
+ core::double* v10 = let final self::Test3* #t58 = t in #t58.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t59 = #t58.{self::Test3::prop}.{core::double::+}(1) in let final void #t60 = #t58.{self::Test3::prop} = #t59 in #t59;
+ core::double* v11 = let final self::Test3* #t61 = t in #t61.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t62 = #t61.{self::Test3::prop} in let final void #t63 = #t61.{self::Test3::prop} = #t62.{core::double::+}(1) in #t62;
}
}
static method getInt() → core::int*
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
index da54b4b..97a828a 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -10,12 +10,12 @@
static method test(self::Test1* t) → void {
core::int* v1 = let final self::Test1* #t1 = t in #t1.{core::Object::==}(null) ?{core::int*} null : #t1.{self::Test1::prop} = self::getInt();
core::num* v2 = let final self::Test1* #t2 = t in #t2.{core::Object::==}(null) ?{core::num*} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int*;
- core::int* v4 = let final self::Test1* #t3 = t in #t3.==(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
- core::num* v5 = let final self::Test1* #t5 = t in #t5.==(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
- core::int* v7 = let final self::Test1* #t7 = t in #t7.==(null) ?{core::int*} null : #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test1* #t8 = t in #t8.==(null) ?{core::num*} null : #t8.{self::Test1::prop} = #t8.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int*;
- core::int* v10 = let final self::Test1* #t9 = t in #t9.==(null) ?{core::int*} null : #t9.{self::Test1::prop} = #t9.{self::Test1::prop}.{core::num::+}(1);
- core::int* v11 = let final self::Test1* #t10 = t in #t10.==(null) ?{core::int*} null : let final core::int* #t11 = #t10.{self::Test1::prop} in let final core::int* #t12 = #t10.{self::Test1::prop} = #t11.{core::num::+}(1) in #t11;
+ core::int* v4 = let final self::Test1* #t3 = t in #t3.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int*} #t3.{self::Test1::prop} = self::getInt() : #t4;
+ core::num* v5 = let final self::Test1* #t5 = t in #t5.{core::Object::==}(null) ?{core::num*} null : let final core::int* #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num*} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int* : #t6;
+ core::int* v7 = let final self::Test1* #t7 = t in #t7.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t8 = #t7.{self::Test1::prop}.{core::num::+}(self::getInt()) in let final void #t9 = #t7.{self::Test1::prop} = #t8 in #t8;
+ core::num* v8 = let final self::Test1* #t10 = t in #t10.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t11 = #t10.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int* in let final void #t12 = #t10.{self::Test1::prop} = #t11 in #t11;
+ core::int* v10 = let final self::Test1* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t14 = #t13.{self::Test1::prop}.{core::num::+}(1) in let final void #t15 = #t13.{self::Test1::prop} = #t14 in #t14;
+ core::int* v11 = let final self::Test1* #t16 = t in #t16.{core::Object::==}(null) ?{core::int*} null : let final core::int* #t17 = #t16.{self::Test1::prop} in let final void #t18 = #t16.{self::Test1::prop} = #t17.{core::num::+}(1) in #t17;
}
}
class Test2 extends core::Object {
@@ -24,17 +24,17 @@
: super core::Object::•()
;
static method test(self::Test2* t) → void {
- core::int* v1 = let final self::Test2* #t13 = t in #t13.{core::Object::==}(null) ?{core::int*} null : #t13.{self::Test2::prop} = self::getInt();
- core::num* v2 = let final self::Test2* #t14 = t in #t14.{core::Object::==}(null) ?{core::num*} null : #t14.{self::Test2::prop} = self::getNum();
- core::double* v3 = let final self::Test2* #t15 = t in #t15.{core::Object::==}(null) ?{core::double*} null : #t15.{self::Test2::prop} = self::getDouble();
- core::num* v4 = let final self::Test2* #t16 = t in #t16.==(null) ?{core::num*} null : let final core::num* #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num*} #t16.{self::Test2::prop} = self::getInt() : #t17;
- core::num* v5 = let final self::Test2* #t18 = t in #t18.==(null) ?{core::num*} null : let final core::num* #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num*} #t18.{self::Test2::prop} = self::getNum() : #t19;
- core::num* v6 = let final self::Test2* #t20 = t in #t20.==(null) ?{core::num*} null : let final core::num* #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num*} #t20.{self::Test2::prop} = self::getDouble() : #t21;
- core::num* v7 = let final self::Test2* #t22 = t in #t22.==(null) ?{core::num*} null : #t22.{self::Test2::prop} = #t22.{self::Test2::prop}.{core::num::+}(self::getInt());
- core::num* v8 = let final self::Test2* #t23 = t in #t23.==(null) ?{core::num*} null : #t23.{self::Test2::prop} = #t23.{self::Test2::prop}.{core::num::+}(self::getNum());
- core::num* v9 = let final self::Test2* #t24 = t in #t24.==(null) ?{core::num*} null : #t24.{self::Test2::prop} = #t24.{self::Test2::prop}.{core::num::+}(self::getDouble());
- core::num* v10 = let final self::Test2* #t25 = t in #t25.==(null) ?{core::num*} null : #t25.{self::Test2::prop} = #t25.{self::Test2::prop}.{core::num::+}(1);
- core::num* v11 = let final self::Test2* #t26 = t in #t26.==(null) ?{core::num*} null : let final core::num* #t27 = #t26.{self::Test2::prop} in let final core::num* #t28 = #t26.{self::Test2::prop} = #t27.{core::num::+}(1) in #t27;
+ core::int* v1 = let final self::Test2* #t19 = t in #t19.{core::Object::==}(null) ?{core::int*} null : #t19.{self::Test2::prop} = self::getInt();
+ core::num* v2 = let final self::Test2* #t20 = t in #t20.{core::Object::==}(null) ?{core::num*} null : #t20.{self::Test2::prop} = self::getNum();
+ core::double* v3 = let final self::Test2* #t21 = t in #t21.{core::Object::==}(null) ?{core::double*} null : #t21.{self::Test2::prop} = self::getDouble();
+ core::num* v4 = let final self::Test2* #t22 = t in #t22.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t23 = #t22.{self::Test2::prop} in #t23.{core::num::==}(null) ?{core::num*} #t22.{self::Test2::prop} = self::getInt() : #t23;
+ core::num* v5 = let final self::Test2* #t24 = t in #t24.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t25 = #t24.{self::Test2::prop} in #t25.{core::num::==}(null) ?{core::num*} #t24.{self::Test2::prop} = self::getNum() : #t25;
+ core::num* v6 = let final self::Test2* #t26 = t in #t26.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t27 = #t26.{self::Test2::prop} in #t27.{core::num::==}(null) ?{core::num*} #t26.{self::Test2::prop} = self::getDouble() : #t27;
+ core::num* v7 = let final self::Test2* #t28 = t in #t28.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t29 = #t28.{self::Test2::prop}.{core::num::+}(self::getInt()) in let final void #t30 = #t28.{self::Test2::prop} = #t29 in #t29;
+ core::num* v8 = let final self::Test2* #t31 = t in #t31.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t32 = #t31.{self::Test2::prop}.{core::num::+}(self::getNum()) in let final void #t33 = #t31.{self::Test2::prop} = #t32 in #t32;
+ core::num* v9 = let final self::Test2* #t34 = t in #t34.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t35 = #t34.{self::Test2::prop}.{core::num::+}(self::getDouble()) in let final void #t36 = #t34.{self::Test2::prop} = #t35 in #t35;
+ core::num* v10 = let final self::Test2* #t37 = t in #t37.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t38 = #t37.{self::Test2::prop}.{core::num::+}(1) in let final void #t39 = #t37.{self::Test2::prop} = #t38 in #t38;
+ core::num* v11 = let final self::Test2* #t40 = t in #t40.{core::Object::==}(null) ?{core::num*} null : let final core::num* #t41 = #t40.{self::Test2::prop} in let final void #t42 = #t40.{self::Test2::prop} = #t41.{core::num::+}(1) in #t41;
}
}
class Test3 extends core::Object {
@@ -43,15 +43,15 @@
: super core::Object::•()
;
static method test3(self::Test3* t) → void {
- core::num* v2 = let final self::Test3* #t29 = t in #t29.{core::Object::==}(null) ?{core::num*} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
- core::double* v3 = let final self::Test3* #t30 = t in #t30.{core::Object::==}(null) ?{core::double*} null : #t30.{self::Test3::prop} = self::getDouble();
- core::num* v5 = let final self::Test3* #t31 = t in #t31.==(null) ?{core::num*} null : let final core::double* #t32 = #t31.{self::Test3::prop} in #t32.{core::num::==}(null) ?{core::num*} #t31.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t32;
- core::double* v6 = let final self::Test3* #t33 = t in #t33.==(null) ?{core::double*} null : let final core::double* #t34 = #t33.{self::Test3::prop} in #t34.{core::num::==}(null) ?{core::double*} #t33.{self::Test3::prop} = self::getDouble() : #t34;
- core::double* v7 = let final self::Test3* #t35 = t in #t35.==(null) ?{core::double*} null : #t35.{self::Test3::prop} = #t35.{self::Test3::prop}.{core::double::+}(self::getInt());
- core::double* v8 = let final self::Test3* #t36 = t in #t36.==(null) ?{core::double*} null : #t36.{self::Test3::prop} = #t36.{self::Test3::prop}.{core::double::+}(self::getNum());
- core::double* v9 = let final self::Test3* #t37 = t in #t37.==(null) ?{core::double*} null : #t37.{self::Test3::prop} = #t37.{self::Test3::prop}.{core::double::+}(self::getDouble());
- core::double* v10 = let final self::Test3* #t38 = t in #t38.==(null) ?{core::double*} null : #t38.{self::Test3::prop} = #t38.{self::Test3::prop}.{core::double::+}(1);
- core::double* v11 = let final self::Test3* #t39 = t in #t39.==(null) ?{core::double*} null : let final core::double* #t40 = #t39.{self::Test3::prop} in let final core::double* #t41 = #t39.{self::Test3::prop} = #t40.{core::double::+}(1) in #t40;
+ core::num* v2 = let final self::Test3* #t43 = t in #t43.{core::Object::==}(null) ?{core::num*} null : #t43.{self::Test3::prop} = self::getNum() as{TypeError} core::double*;
+ core::double* v3 = let final self::Test3* #t44 = t in #t44.{core::Object::==}(null) ?{core::double*} null : #t44.{self::Test3::prop} = self::getDouble();
+ core::num* v5 = let final self::Test3* #t45 = t in #t45.{core::Object::==}(null) ?{core::num*} null : let final core::double* #t46 = #t45.{self::Test3::prop} in #t46.{core::num::==}(null) ?{core::num*} #t45.{self::Test3::prop} = self::getNum() as{TypeError} core::double* : #t46;
+ core::double* v6 = let final self::Test3* #t47 = t in #t47.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t48 = #t47.{self::Test3::prop} in #t48.{core::num::==}(null) ?{core::double*} #t47.{self::Test3::prop} = self::getDouble() : #t48;
+ core::double* v7 = let final self::Test3* #t49 = t in #t49.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t50 = #t49.{self::Test3::prop}.{core::double::+}(self::getInt()) in let final void #t51 = #t49.{self::Test3::prop} = #t50 in #t50;
+ core::double* v8 = let final self::Test3* #t52 = t in #t52.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t53 = #t52.{self::Test3::prop}.{core::double::+}(self::getNum()) in let final void #t54 = #t52.{self::Test3::prop} = #t53 in #t53;
+ core::double* v9 = let final self::Test3* #t55 = t in #t55.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t56 = #t55.{self::Test3::prop}.{core::double::+}(self::getDouble()) in let final void #t57 = #t55.{self::Test3::prop} = #t56 in #t56;
+ core::double* v10 = let final self::Test3* #t58 = t in #t58.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t59 = #t58.{self::Test3::prop}.{core::double::+}(1) in let final void #t60 = #t58.{self::Test3::prop} = #t59 in #t59;
+ core::double* v11 = let final self::Test3* #t61 = t in #t61.{core::Object::==}(null) ?{core::double*} null : let final core::double* #t62 = #t61.{self::Test3::prop} in let final void #t63 = #t61.{self::Test3::prop} = #t62.{core::double::+}(1) in #t62;
}
}
static method getInt() → core::int*
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.outline.expect
index 3d491c7..e828a66 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.expect
index fcd6d80..1a0ffd7 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect
index fcd6d80..1a0ffd7 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.outline.expect
index bcf2c7a..d6a3a24 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<U extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::U*>*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.expect
index e923e16..c12b23e 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<U extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::U*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
index e923e16..c12b23e 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<U extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::U*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.outline.expect
index 3d491c7..e828a66 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.expect
index 22d342d..62cd600 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect
index 22d342d..62cd600 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.outline.expect
index f75d4ee..0a850b0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.expect
index b0dc0d8..455e663 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect
index b0dc0d8..455e663 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.outline.expect
index dcce18a..bb96cdb 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.expect
index 0ce72d7..d17c1dd 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.transformed.expect
index 0ce72d7..d17c1dd 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant U extends (U*) →* dynamic = (dynamic) →* dynamic> = (U*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.outline.expect
index 1283fc5..5985c4c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.outline.expect
@@ -16,7 +16,7 @@
import self as self;
import "dart:core" as core;
-typedef Fisk<TypeY extends core::Object* = dynamic> = () →* void;
+typedef Fisk<unrelated TypeY extends core::Object* = dynamic> = () →* void;
class Hest<TypeX extends () →* void = () →* void> extends core::Object {
synthetic constructor •() → self::Hest<self::Hest::TypeX*>*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
index 548d055..7b9d47f 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
@@ -16,7 +16,7 @@
import self as self;
import "dart:core" as core;
-typedef Fisk<TypeY extends core::Object* = dynamic> = () →* void;
+typedef Fisk<unrelated TypeY extends core::Object* = dynamic> = () →* void;
class Hest<TypeX extends () →* void = () →* void> extends core::Object {
synthetic constructor •() → self::Hest<self::Hest::TypeX*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
index 548d055..7b9d47f 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
@@ -16,7 +16,7 @@
import self as self;
import "dart:core" as core;
-typedef Fisk<TypeY extends core::Object* = dynamic> = () →* void;
+typedef Fisk<unrelated TypeY extends core::Object* = dynamic> = () →* void;
class Hest<TypeX extends () →* void = () →* void> extends core::Object {
synthetic constructor •() → self::Hest<self::Hest::TypeX*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.outline.expect
index a9a5b64..734815e 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.expect
index 47cd11d..e626b04 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect
index 47cd11d..e626b04 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B extends core::Object {
synthetic constructor •() → self::B*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.outline.expect
index 9af14c6..e6917ea 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::List<(core::num*) →* dynamic>* a;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.expect
index 424bbbe..e5555e7 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::List<(core::num*) →* dynamic>* a = <(core::num*) →* dynamic>[];
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect
index 424bbbe..e5555e7 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::List<(core::num*) →* dynamic>* a = <(core::num*) →* dynamic>[];
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.outline.expect
index b2250e8..3a72d6c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<S extends core::Object* = dynamic> extends core::Object {
final field core::List<(self::B::S*) →* dynamic>* foo;
final field core::List<(core::num*) →* dynamic>* bar;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.expect
index 66e0166..95a1206 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<S extends core::Object* = dynamic> extends core::Object {
final field core::List<(self::B::S*) →* dynamic>* foo = <(self::B::S*) →* dynamic>[];
final field core::List<(core::num*) →* dynamic>* bar = <(core::num*) →* dynamic>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
index 66e0166..95a1206 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class B<S extends core::Object* = dynamic> extends core::Object {
final field core::List<(self::B::S*) →* dynamic>* foo = <(self::B::S*) →* dynamic>[];
final field core::List<(core::num*) →* dynamic>* bar = <(core::num*) →* dynamic>[];
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.outline.expect
index a1238c5..90306c1 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::Map<(core::num*) →* dynamic, (core::num*) →* dynamic>* a;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.expect
index 45dc4c2..5412826 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::Map<(core::num*) →* dynamic, (core::num*) →* dynamic>* a = <(core::num*) →* dynamic, (core::num*) →* dynamic>{};
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect
index 45dc4c2..5412826 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
static field core::Map<(core::num*) →* dynamic, (core::num*) →* dynamic>* a = <(core::num*) →* dynamic, (core::num*) →* dynamic>{};
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.outline.expect
index aa6c819..63af415 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.expect
index 4bca658..4164860 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect
index 4bca658..4164860 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.outline.expect
index 345eb14..86efbd9 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B<T extends (core::num*) →* dynamic = (core::num*) →* dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.expect
index 4036b32..d46f295 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B<T extends (core::num*) →* dynamic = (core::num*) →* dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect
index 4036b32..d46f295 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::num* = core::num*> = (T*) →* dynamic;
+typedef A<contravariant T extends core::num* = core::num*> = (T*) →* dynamic;
class B<T extends (core::num*) →* dynamic = (core::num*) →* dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.outline.expect
index bbce9e4..32182bf 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
static field ((dynamic) →* dynamic) →* dynamic b;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.expect
index d59e608..4280623 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
static field ((dynamic) →* dynamic) →* dynamic b;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.transformed.expect
index d59e608..4280623 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef A<T extends core::Object* = dynamic> = (T*) →* dynamic;
-typedef B<S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
+typedef A<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef B<contravariant S extends (S*) →* dynamic = (dynamic) →* dynamic> = (S*) →* dynamic;
static field ((dynamic) →* dynamic) →* dynamic b;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nested_variance_test.dart b/pkg/front_end/testcases/nested_variance_test.dart
new file mode 100644
index 0000000..28a2f62
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart
@@ -0,0 +1,243 @@
+// Copyright (c) 2019, 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.
+
+// Testing that i2b and checks for correct super-boundedness are applied
+// to type arguments, taking the variance of type parameters into account.
+
+// Standard type comparison support.
+
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+
+// Material specific to this test.
+
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+class Acov<X extends Fcov<Y>, Y> {}
+
+class Acon<X extends Fcon<Y>, Y> {}
+
+class Ainv<X extends Finv<Y>, Y> {}
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class AcovBound<X extends FcovBound<Y>, Y extends num> {}
+
+class AconBound<X extends FconBound<Y>, Y extends num> {}
+
+class AinvBound<X extends FinvBound<Y>, Y extends num> {}
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+class AcovCyclicBound<X extends FcovCyclicBound<Y>, Y extends A<Y>> {}
+
+class AconCyclicBound<X extends FconCyclicBound<Y>, Y extends A<Y>> {}
+
+class AinvCyclicBound<X extends FinvCyclicBound<Y>, Y extends A<Y>> {}
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class AcovCyclicCoBound<X extends FcovCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AconCyclicCoBound<X extends FconCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class AinvCyclicCoBound<X extends FinvCyclicCoBound<Y>, Y extends Function(Y)> {
+}
+
+class B<X> {}
+
+void testTypeAliasAsTypeArgument() {
+ // I2b: Use bounds (Fcov<Y>, dynamic), then replace covariant occurrence
+ // (of `Y` in `Acov<Fcov<Y>, _>`) by `Y`s value `dynamic`. Resulting type
+ // `Acov<Fcov<dynamic>, dynamic>` is regular-bounded.
+ Acov source1;
+ var fsource1 = toF(source1);
+ F<Acov<Fcov<dynamic>, dynamic>> target1 = fsource1;
+
+ // I2b: Use bounds (Fcon<Y>, dynamic), then replace contravariant occurrence
+ // (of `Y` in `Acon<Fcon<Y>, _>`) by `Null`. Resulting type
+ // is super-bounded: Acon<Fcon<Object>, Null> is regular-bounded.
+ Acon source2;
+ var fsource2 = toF(source2);
+ F<Acon<Fcon<Null>, dynamic>> target2 = fsource2;
+
+ // I2b: Use bounds (Finv<Y>, dynamic) then replace invariant occurrence
+ // (of `Y` in `Ainv<Finv<Y>, _>`) by `Y`s value `dynamic`. Resulting type
+ // `Ainv<Finv<dynamic>, dynamic>` is regular-bounded.
+ Ainv source3;
+ var fsource3 = toF(source3);
+ F<Ainv<Finv<dynamic>, dynamic>> target3 = fsource3;
+
+ // I2b: Use bounds (FcovBound<Y>, num), then replace covariant occurrence
+ // (of `Y` in `AcovBound<FcovBound<Y>, _>`) by `Y`s value `num`.
+ // Resulting type `AcovBound<FcovBound<num>, num>` is regular-bounded.
+ AcovBound source4;
+ var fsource4 = toF(source4);
+ F<AcovBound<FcovBound<num>, num>> target4 = fsource4;
+
+ // I2b: Use bounds (FconBound<Y>, num), then replace contravariant occurrence
+ // of `Y` in `AconBound<FconBound<Y>, _>` by `Null`. Resulting type is
+ // super-bounded: AconBound<FconBound<Object>, num> is regular-bounded.
+ AconBound source5;
+ var fsource5 = toF(source5);
+ F<AconBound<FconBound<Null>, num>> target5 = fsource5;
+
+ // I2b: Use bounds (FinvBound<Y>, num), then replace invariant occurrence
+ // of `Y` in `AinvBound<FinvBound<Y>, _>` by `Y`s value `num`. Resulting
+ // type `AinvBound<FinvBound<num>, num>` is regular-bounded.
+ AinvBound source6;
+ var fsource6 = toF(source6);
+ F<AinvBound<FinvBound<num>, num>> target6 = fsource6;
+
+ // I2b: Use bounds (FcovCyclicBound<Y>, A<Y>), then break cycle {Y} by
+ // replacing covariant occurrence of `Y` in `AcovCyclicBound<_, A<Y>>`
+ // by `dynamic`; then replace covariant occurrence of `Y` in
+ // `AcovCyclicBound<FcovCyclicBound<Y>, _>` by `Y`s value `A<dynamic>`.
+ // Resulting type `AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>>`
+ // is regular-bounded.
+ AcovCyclicBound source7;
+ var fsource7 = toF(source7);
+ F<AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>> target7 =
+ fsource7;
+
+ // I2b: Use bounds (FconCyclicBound<Y>, A<Y>), then break cycle {Y} by
+ // replacing covariant occurrence of `Y` in `AconCyclicBound<_, A<Y>>`
+ // by `dynamic`; then replace contravariant occurrence of `Y` in
+ // `AconCyclicBound<FconCyclicBound<Y>, _>` by `Null`.
+ // Resulting type `AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>>` is
+ // super-bounded because `AconCyclicBound<FconCyclicBound<Object>, A<Null>>>`
+ // is regular-bounded.
+ AconCyclicBound source8;
+ var fsource8 = toF(source8);
+ F<AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>> target8 = fsource8;
+
+ // I2b: Use bounds (FinvCyclicBound<Y>, A<Y>), then break cycle {Y} by
+ // replacing covariant occurrence of `Y` in `AinvCyclicBound<_, A<Y>>`
+ // by `dynamic`; then replace invariant occurrence of `Y` in
+ // `AinvCyclicBound<FinvCyclicBound<Y>, _>` by `Y`s value `A<dynamic>`.
+ // Resulting type `AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>>`
+ // looks regular-bounded, but contains `FinvCyclicBound<A<dynamic>>` which
+ // is not well-bounded.
+ AinvCyclicBound source9; //# 01: compile-time error
+ // var fsource9 = toF(source9);
+ // F<AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>> target9 =
+ // fsource9;
+
+ // I2b: Use bounds (FcovCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
+ // by replacing contravariant occurrence of `Y` in
+ // `AcovCyclicCoBound<_, Function(Y)>` by `Null`; then replace covariant
+ // occurrence of `Y` in `AcovCyclicCoBound<FcovCyclicCoBound<Y>, _>` by `Y`s
+ // value `Function(Null)`. Resulting type
+ // `AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>`
+ // is regular-bounded, with subterm `FcovCyclicCoBound<Function(Null)>` which
+ // is super-bounded because `FcovCyclicCoBound<Function(Object)>` is
+ // regular-bounded.
+ AcovCyclicCoBound source10;
+ var fsource10 = toF(source10);
+ F<AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>>
+ target10 = fsource10;
+
+ // I2b: Use bounds (FconCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
+ // by replacing contravariant occurrence of `Y` in
+ // `AconCyclicCoBound<_, Function(Y)>` by `Null`; then replace contravariant
+ // occurrence of `Y` in `AconCyclicCoBound<FconCyclicCoBound<Y>, _>` by
+ // `Null`. Resulting type
+ // `AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>` is
+ // super-bounded because
+ // `AconCyclicCoBound<FconCyclicCoBound<Object>, Function(Object)>` is
+ // regular-bounded.
+ AconCyclicCoBound source11;
+ var fsource11 = toF(source11);
+ F<AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>> target11 =
+ fsource11;
+
+ // I2b: Use bounds (FinvCyclicCoBound<Y>, Function(Y)), then break cycle {Y}
+ // by replacing contravariant occurrence of `Y` in
+ // `AinvCyclicCoBound<_, Function(Y)>` by `Null`; then replace invariant
+ // occurrence of `Y` in `AinvCyclicCoBound<FinvCyclicCoBound<Y>, _>` by `Y`s
+ // value `Function(Null)`.
+ // Resulting type
+ // `AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>`
+ // looks regular-bounded, but contains `FinvCyclicCoBound<Function(Null)>`
+ // which is not well-bounded.
+ AinvCyclicCoBound source12; //# 02: compile-time error
+ // var fsource12 = toF(source12);
+ // F<AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>
+ // target12 = fsource12;
+}
+
+void testNested() {
+ // Everything gets the same treatment when the cases from `testTopLevel`
+ // are duplicated at the nested level in a covariant position.
+
+ B<Acov> source1;
+ var fsource1 = toF(source1);
+ F<B<Acov<Fcov<dynamic>, dynamic>>> target1 = fsource1;
+
+ B<Acon> source2;
+ var fsource2 = toF(source2);
+ F<B<Acon<Fcon<Null>, dynamic>>> target2 = fsource2;
+
+ B<Ainv> source3;
+ var fsource3 = toF(source3);
+ F<B<Ainv<Finv<dynamic>, dynamic>>> target3 = fsource3;
+
+ B<AcovBound> source4;
+ var fsource4 = toF(source4);
+ F<B<AcovBound<FcovBound<num>, num>>> target4 = fsource4;
+
+ B<AconBound> source5;
+ var fsource5 = toF(source5);
+ F<B<AconBound<FconBound<Null>, num>>> target5 = fsource5;
+
+ B<AinvBound> source6;
+ var fsource6 = toF(source6);
+ F<B<AinvBound<FinvBound<num>, num>>> target6 = fsource6;
+
+ B<AcovCyclicBound> source7;
+ var fsource7 = toF(source7);
+ F<B<AcovCyclicBound<FcovCyclicBound<A<dynamic>>, A<dynamic>>>> target7 =
+ fsource7;
+
+ B<AconCyclicBound> source8;
+ var fsource8 = toF(source8);
+ F<B<AconCyclicBound<FconCyclicBound<Null>, A<dynamic>>>> target8 = fsource8;
+
+ B<AinvCyclicBound> source9; //# 03: compile-time error
+ // var fsource9 = toF(source9);
+ // F<B<AinvCyclicBound<FinvCyclicBound<A<dynamic>>, A<dynamic>>>> target9 =
+ // fsource9;
+
+ B<AcovCyclicCoBound> source10;
+ var fsource10 = toF(source10);
+ F<B<AcovCyclicCoBound<FcovCyclicCoBound<Function(Null)>, Function(Null)>>>
+ target10 = fsource10;
+
+ B<AconCyclicCoBound> source11;
+ var fsource11 = toF(source11);
+ F<B<AconCyclicCoBound<FconCyclicCoBound<Null>, Function(Null)>>> target11 =
+ fsource11;
+
+ B<AinvCyclicCoBound> source12; //# 04: compile-time error
+ // var fsource12 = toF(source12);
+ // F<B<AinvCyclicCoBound<FinvCyclicCoBound<Function(Null)>, Function(Null)>>>
+ // target12 = fsource12;
+}
+
+main() {
+ testTypeAliasAsTypeArgument();
+ testNested();
+}
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.hierarchy.expect b/pkg/front_end/testcases/nested_variance_test.dart.hierarchy.expect
new file mode 100644
index 0000000..943b7be
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.hierarchy.expect
@@ -0,0 +1,257 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+Acov:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+Acon:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+Ainv:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AcovBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AconBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AinvBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AcovCyclicBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AconCyclicBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AinvCyclicBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AcovCyclicCoBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AconCyclicCoBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+AinvCyclicCoBound:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.legacy.expect b/pkg/front_end/testcases/nested_variance_test.dart.legacy.expect
new file mode 100644
index 0000000..b9c9ad3
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.legacy.expect
@@ -0,0 +1,161 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object = dynamic> = <Y extends X = dynamic>() → void;
+typedef Fcov<X extends core::Object = dynamic> = () → X;
+typedef Fcon<contravariant X extends core::Object = dynamic> = (X) → dynamic;
+typedef Finv<invariant X extends core::Object = dynamic> = (X) → X;
+typedef FcovBound<X extends core::num = dynamic> = () → X;
+typedef FconBound<contravariant X extends core::num = dynamic> = (X) → dynamic;
+typedef FinvBound<invariant X extends core::num = dynamic> = (X) → X;
+typedef FcovCyclicBound<X extends self::A<X> = dynamic> = () → X;
+typedef FconCyclicBound<contravariant X extends self::A<X> = dynamic> = (X) → dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X> = dynamic> = (X) → X;
+typedef FcovCyclicCoBound<X extends (X) → dynamic = dynamic> = () → X;
+typedef FconCyclicCoBound<contravariant X extends (X) → dynamic = dynamic> = (X) → dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X) → dynamic = dynamic> = (X) → X;
+class Acov<X extends () → self::Acov::Y = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acov<self::Acov::X, self::Acov::Y>
+ : super core::Object::•()
+ ;
+}
+class Acon<X extends (self::Acon::Y) → dynamic = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acon<self::Acon::X, self::Acon::Y>
+ : super core::Object::•()
+ ;
+}
+class Ainv<X extends (self::Ainv::Y) → self::Ainv::Y = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Ainv<self::Ainv::X, self::Ainv::Y>
+ : super core::Object::•()
+ ;
+}
+class AcovBound<X extends () → self::AcovBound::Y = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovBound<self::AcovBound::X, self::AcovBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconBound<X extends (self::AconBound::Y) → dynamic = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconBound<self::AconBound::X, self::AconBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvBound<X extends (self::AinvBound::Y) → self::AinvBound::Y = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvBound<self::AinvBound::X, self::AinvBound::Y>
+ : super core::Object::•()
+ ;
+}
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicBound<X extends () → self::AcovCyclicBound::Y = dynamic, Y extends self::A<self::AcovCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicBound<self::AcovCyclicBound::X, self::AcovCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconCyclicBound<X extends (self::AconCyclicBound::Y) → dynamic = dynamic, Y extends self::A<self::AconCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicBound<self::AconCyclicBound::X, self::AconCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicBound<X extends (self::AinvCyclicBound::Y) → self::AinvCyclicBound::Y = dynamic, Y extends self::A<self::AinvCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicBound<self::AinvCyclicBound::X, self::AinvCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicCoBound<X extends () → self::AcovCyclicCoBound::Y = dynamic, Y extends (self::AcovCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicCoBound<self::AcovCyclicCoBound::X, self::AcovCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconCyclicCoBound<X extends (self::AconCyclicCoBound::Y) → dynamic = dynamic, Y extends (self::AconCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicCoBound<self::AconCyclicCoBound::X, self::AconCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicCoBound<X extends (self::AinvCyclicCoBound::Y) → self::AinvCyclicCoBound::Y = dynamic, Y extends (self::AinvCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicCoBound<self::AinvCyclicCoBound::X, self::AinvCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X>
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object = dynamic>(self::toF::X x) → <Y extends self::toF::X = dynamic>() → void
+ return null;
+static method testTypeAliasAsTypeArgument() → void {
+ self::Acov<dynamic, dynamic> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::Acov<() → dynamic, dynamic> = dynamic>() → void target1 = fsource1;
+ self::Acon<dynamic, dynamic> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::Acon<(core::Null) → dynamic, dynamic> = dynamic>() → void target2 = fsource2;
+ self::Ainv<dynamic, dynamic> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::Ainv<(dynamic) → dynamic, dynamic> = dynamic>() → void target3 = fsource3;
+ self::AcovBound<dynamic, dynamic> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::AcovBound<() → core::num, core::num> = dynamic>() → void target4 = fsource4;
+ self::AconBound<dynamic, dynamic> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::AconBound<(core::Null) → dynamic, core::num> = dynamic>() → void target5 = fsource5;
+ self::AinvBound<dynamic, dynamic> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::AinvBound<(core::num) → core::num, core::num> = dynamic>() → void target6 = fsource6;
+ self::AcovCyclicBound<dynamic, dynamic> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::AcovCyclicBound<() → self::A<dynamic>, self::A<dynamic>> = dynamic>() → void target7 = fsource7;
+ self::AconCyclicBound<dynamic, dynamic> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::AconCyclicBound<(core::Null) → dynamic, self::A<dynamic>> = dynamic>() → void target8 = fsource8;
+ self::AinvCyclicBound<dynamic, dynamic> source9;
+ self::AcovCyclicCoBound<dynamic, dynamic> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::AcovCyclicCoBound<() → (core::Null) → dynamic, (core::Null) → dynamic> = dynamic>() → void target10 = fsource10;
+ self::AconCyclicCoBound<dynamic, dynamic> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::AconCyclicCoBound<(core::Null) → dynamic, (core::Null) → dynamic> = dynamic>() → void target11 = fsource11;
+ self::AinvCyclicCoBound<dynamic, dynamic> source12;
+}
+static method testNested() → void {
+ self::B<self::Acov<dynamic, dynamic>> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::B<self::Acov<() → dynamic, dynamic>> = dynamic>() → void target1 = fsource1;
+ self::B<self::Acon<dynamic, dynamic>> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::B<self::Acon<(core::Null) → dynamic, dynamic>> = dynamic>() → void target2 = fsource2;
+ self::B<self::Ainv<dynamic, dynamic>> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::B<self::Ainv<(dynamic) → dynamic, dynamic>> = dynamic>() → void target3 = fsource3;
+ self::B<self::AcovBound<dynamic, dynamic>> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::B<self::AcovBound<() → core::num, core::num>> = dynamic>() → void target4 = fsource4;
+ self::B<self::AconBound<dynamic, dynamic>> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::B<self::AconBound<(core::Null) → dynamic, core::num>> = dynamic>() → void target5 = fsource5;
+ self::B<self::AinvBound<dynamic, dynamic>> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::B<self::AinvBound<(core::num) → core::num, core::num>> = dynamic>() → void target6 = fsource6;
+ self::B<self::AcovCyclicBound<dynamic, dynamic>> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::B<self::AcovCyclicBound<() → self::A<dynamic>, self::A<dynamic>>> = dynamic>() → void target7 = fsource7;
+ self::B<self::AconCyclicBound<dynamic, dynamic>> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::B<self::AconCyclicBound<(core::Null) → dynamic, self::A<dynamic>>> = dynamic>() → void target8 = fsource8;
+ self::B<self::AinvCyclicBound<dynamic, dynamic>> source9;
+ self::B<self::AcovCyclicCoBound<dynamic, dynamic>> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::B<self::AcovCyclicCoBound<() → (core::Null) → dynamic, (core::Null) → dynamic>> = dynamic>() → void target10 = fsource10;
+ self::B<self::AconCyclicCoBound<dynamic, dynamic>> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null) → dynamic, (core::Null) → dynamic>> = dynamic>() → void target11 = fsource11;
+ self::B<self::AinvCyclicCoBound<dynamic, dynamic>> source12;
+}
+static method main() → dynamic {
+ self::testTypeAliasAsTypeArgument();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.legacy.transformed.expect b/pkg/front_end/testcases/nested_variance_test.dart.legacy.transformed.expect
new file mode 100644
index 0000000..b9c9ad3
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.legacy.transformed.expect
@@ -0,0 +1,161 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object = dynamic> = <Y extends X = dynamic>() → void;
+typedef Fcov<X extends core::Object = dynamic> = () → X;
+typedef Fcon<contravariant X extends core::Object = dynamic> = (X) → dynamic;
+typedef Finv<invariant X extends core::Object = dynamic> = (X) → X;
+typedef FcovBound<X extends core::num = dynamic> = () → X;
+typedef FconBound<contravariant X extends core::num = dynamic> = (X) → dynamic;
+typedef FinvBound<invariant X extends core::num = dynamic> = (X) → X;
+typedef FcovCyclicBound<X extends self::A<X> = dynamic> = () → X;
+typedef FconCyclicBound<contravariant X extends self::A<X> = dynamic> = (X) → dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X> = dynamic> = (X) → X;
+typedef FcovCyclicCoBound<X extends (X) → dynamic = dynamic> = () → X;
+typedef FconCyclicCoBound<contravariant X extends (X) → dynamic = dynamic> = (X) → dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X) → dynamic = dynamic> = (X) → X;
+class Acov<X extends () → self::Acov::Y = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acov<self::Acov::X, self::Acov::Y>
+ : super core::Object::•()
+ ;
+}
+class Acon<X extends (self::Acon::Y) → dynamic = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acon<self::Acon::X, self::Acon::Y>
+ : super core::Object::•()
+ ;
+}
+class Ainv<X extends (self::Ainv::Y) → self::Ainv::Y = dynamic, Y extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::Ainv<self::Ainv::X, self::Ainv::Y>
+ : super core::Object::•()
+ ;
+}
+class AcovBound<X extends () → self::AcovBound::Y = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovBound<self::AcovBound::X, self::AcovBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconBound<X extends (self::AconBound::Y) → dynamic = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconBound<self::AconBound::X, self::AconBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvBound<X extends (self::AinvBound::Y) → self::AinvBound::Y = dynamic, Y extends core::num = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvBound<self::AinvBound::X, self::AinvBound::Y>
+ : super core::Object::•()
+ ;
+}
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicBound<X extends () → self::AcovCyclicBound::Y = dynamic, Y extends self::A<self::AcovCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicBound<self::AcovCyclicBound::X, self::AcovCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconCyclicBound<X extends (self::AconCyclicBound::Y) → dynamic = dynamic, Y extends self::A<self::AconCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicBound<self::AconCyclicBound::X, self::AconCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicBound<X extends (self::AinvCyclicBound::Y) → self::AinvCyclicBound::Y = dynamic, Y extends self::A<self::AinvCyclicBound::Y> = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicBound<self::AinvCyclicBound::X, self::AinvCyclicBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicCoBound<X extends () → self::AcovCyclicCoBound::Y = dynamic, Y extends (self::AcovCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicCoBound<self::AcovCyclicCoBound::X, self::AcovCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AconCyclicCoBound<X extends (self::AconCyclicCoBound::Y) → dynamic = dynamic, Y extends (self::AconCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicCoBound<self::AconCyclicCoBound::X, self::AconCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicCoBound<X extends (self::AinvCyclicCoBound::Y) → self::AinvCyclicCoBound::Y = dynamic, Y extends (self::AinvCyclicCoBound::Y) → dynamic = dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicCoBound<self::AinvCyclicCoBound::X, self::AinvCyclicCoBound::Y>
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X>
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object = dynamic>(self::toF::X x) → <Y extends self::toF::X = dynamic>() → void
+ return null;
+static method testTypeAliasAsTypeArgument() → void {
+ self::Acov<dynamic, dynamic> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::Acov<() → dynamic, dynamic> = dynamic>() → void target1 = fsource1;
+ self::Acon<dynamic, dynamic> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::Acon<(core::Null) → dynamic, dynamic> = dynamic>() → void target2 = fsource2;
+ self::Ainv<dynamic, dynamic> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::Ainv<(dynamic) → dynamic, dynamic> = dynamic>() → void target3 = fsource3;
+ self::AcovBound<dynamic, dynamic> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::AcovBound<() → core::num, core::num> = dynamic>() → void target4 = fsource4;
+ self::AconBound<dynamic, dynamic> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::AconBound<(core::Null) → dynamic, core::num> = dynamic>() → void target5 = fsource5;
+ self::AinvBound<dynamic, dynamic> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::AinvBound<(core::num) → core::num, core::num> = dynamic>() → void target6 = fsource6;
+ self::AcovCyclicBound<dynamic, dynamic> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::AcovCyclicBound<() → self::A<dynamic>, self::A<dynamic>> = dynamic>() → void target7 = fsource7;
+ self::AconCyclicBound<dynamic, dynamic> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::AconCyclicBound<(core::Null) → dynamic, self::A<dynamic>> = dynamic>() → void target8 = fsource8;
+ self::AinvCyclicBound<dynamic, dynamic> source9;
+ self::AcovCyclicCoBound<dynamic, dynamic> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::AcovCyclicCoBound<() → (core::Null) → dynamic, (core::Null) → dynamic> = dynamic>() → void target10 = fsource10;
+ self::AconCyclicCoBound<dynamic, dynamic> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::AconCyclicCoBound<(core::Null) → dynamic, (core::Null) → dynamic> = dynamic>() → void target11 = fsource11;
+ self::AinvCyclicCoBound<dynamic, dynamic> source12;
+}
+static method testNested() → void {
+ self::B<self::Acov<dynamic, dynamic>> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::B<self::Acov<() → dynamic, dynamic>> = dynamic>() → void target1 = fsource1;
+ self::B<self::Acon<dynamic, dynamic>> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::B<self::Acon<(core::Null) → dynamic, dynamic>> = dynamic>() → void target2 = fsource2;
+ self::B<self::Ainv<dynamic, dynamic>> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::B<self::Ainv<(dynamic) → dynamic, dynamic>> = dynamic>() → void target3 = fsource3;
+ self::B<self::AcovBound<dynamic, dynamic>> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::B<self::AcovBound<() → core::num, core::num>> = dynamic>() → void target4 = fsource4;
+ self::B<self::AconBound<dynamic, dynamic>> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::B<self::AconBound<(core::Null) → dynamic, core::num>> = dynamic>() → void target5 = fsource5;
+ self::B<self::AinvBound<dynamic, dynamic>> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::B<self::AinvBound<(core::num) → core::num, core::num>> = dynamic>() → void target6 = fsource6;
+ self::B<self::AcovCyclicBound<dynamic, dynamic>> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::B<self::AcovCyclicBound<() → self::A<dynamic>, self::A<dynamic>>> = dynamic>() → void target7 = fsource7;
+ self::B<self::AconCyclicBound<dynamic, dynamic>> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::B<self::AconCyclicBound<(core::Null) → dynamic, self::A<dynamic>>> = dynamic>() → void target8 = fsource8;
+ self::B<self::AinvCyclicBound<dynamic, dynamic>> source9;
+ self::B<self::AcovCyclicCoBound<dynamic, dynamic>> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::B<self::AcovCyclicCoBound<() → (core::Null) → dynamic, (core::Null) → dynamic>> = dynamic>() → void target10 = fsource10;
+ self::B<self::AconCyclicCoBound<dynamic, dynamic>> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null) → dynamic, (core::Null) → dynamic>> = dynamic>() → void target11 = fsource11;
+ self::B<self::AinvCyclicCoBound<dynamic, dynamic>> source12;
+}
+static method main() → dynamic {
+ self::testTypeAliasAsTypeArgument();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.outline.expect b/pkg/front_end/testcases/nested_variance_test.dart.outline.expect
new file mode 100644
index 0000000..5bfe24d
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.outline.expect
@@ -0,0 +1,81 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class Acov<X extends () →* self::Acov::Y* = () →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acov<self::Acov::X*, self::Acov::Y*>*
+ ;
+}
+class Acon<X extends (self::Acon::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acon<self::Acon::X*, self::Acon::Y*>*
+ ;
+}
+class Ainv<X extends (self::Ainv::Y*) →* self::Ainv::Y* = (dynamic) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Ainv<self::Ainv::X*, self::Ainv::Y*>*
+ ;
+}
+class AcovBound<X extends () →* self::AcovBound::Y* = () →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AcovBound<self::AcovBound::X*, self::AcovBound::Y*>*
+ ;
+}
+class AconBound<X extends (self::AconBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AconBound<self::AconBound::X*, self::AconBound::Y*>*
+ ;
+}
+class AinvBound<X extends (self::AinvBound::Y*) →* self::AinvBound::Y* = (core::num*) →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AinvBound<self::AinvBound::X*, self::AinvBound::Y*>*
+ ;
+}
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ ;
+}
+class AcovCyclicBound<X extends () →* self::AcovCyclicBound::Y* = () →* self::A<dynamic>*, Y extends self::A<self::AcovCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicBound<self::AcovCyclicBound::X*, self::AcovCyclicBound::Y*>*
+ ;
+}
+class AconCyclicBound<X extends (self::AconCyclicBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends self::A<self::AconCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AconCyclicBound<self::AconCyclicBound::X*, self::AconCyclicBound::Y*>*
+ ;
+}
+class AinvCyclicBound<X extends (self::AinvCyclicBound::Y*) →* self::AinvCyclicBound::Y* = (self::A<dynamic>*) →* self::A<dynamic>*, Y extends self::A<self::AinvCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicBound<self::AinvCyclicBound::X*, self::AinvCyclicBound::Y*>*
+ ;
+}
+class AcovCyclicCoBound<X extends () →* self::AcovCyclicCoBound::Y* = () →* (core::Null?) →* dynamic, Y extends (self::AcovCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicCoBound<self::AcovCyclicCoBound::X*, self::AcovCyclicCoBound::Y*>*
+ ;
+}
+class AconCyclicCoBound<X extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicCoBound<self::AconCyclicCoBound::X*, self::AconCyclicCoBound::Y*>*
+ ;
+}
+class AinvCyclicCoBound<X extends (self::AinvCyclicCoBound::Y*) →* self::AinvCyclicCoBound::Y* = ((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, Y extends (self::AinvCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicCoBound<self::AinvCyclicCoBound::X*, self::AinvCyclicCoBound::Y*>*
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ ;
+static method testTypeAliasAsTypeArgument() → void
+ ;
+static method testNested() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.strong.expect b/pkg/front_end/testcases/nested_variance_test.dart.strong.expect
new file mode 100644
index 0000000..44abf90
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.strong.expect
@@ -0,0 +1,161 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class Acov<X extends () →* self::Acov::Y* = () →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acov<self::Acov::X*, self::Acov::Y*>*
+ : super core::Object::•()
+ ;
+}
+class Acon<X extends (self::Acon::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acon<self::Acon::X*, self::Acon::Y*>*
+ : super core::Object::•()
+ ;
+}
+class Ainv<X extends (self::Ainv::Y*) →* self::Ainv::Y* = (dynamic) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Ainv<self::Ainv::X*, self::Ainv::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AcovBound<X extends () →* self::AcovBound::Y* = () →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AcovBound<self::AcovBound::X*, self::AcovBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconBound<X extends (self::AconBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AconBound<self::AconBound::X*, self::AconBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvBound<X extends (self::AinvBound::Y*) →* self::AinvBound::Y* = (core::num*) →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AinvBound<self::AinvBound::X*, self::AinvBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicBound<X extends () →* self::AcovCyclicBound::Y* = () →* self::A<dynamic>*, Y extends self::A<self::AcovCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicBound<self::AcovCyclicBound::X*, self::AcovCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconCyclicBound<X extends (self::AconCyclicBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends self::A<self::AconCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AconCyclicBound<self::AconCyclicBound::X*, self::AconCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicBound<X extends (self::AinvCyclicBound::Y*) →* self::AinvCyclicBound::Y* = (self::A<dynamic>*) →* self::A<dynamic>*, Y extends self::A<self::AinvCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicBound<self::AinvCyclicBound::X*, self::AinvCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicCoBound<X extends () →* self::AcovCyclicCoBound::Y* = () →* (core::Null?) →* dynamic, Y extends (self::AcovCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicCoBound<self::AcovCyclicCoBound::X*, self::AcovCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconCyclicCoBound<X extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicCoBound<self::AconCyclicCoBound::X*, self::AconCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicCoBound<X extends (self::AinvCyclicCoBound::Y*) →* self::AinvCyclicCoBound::Y* = ((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, Y extends (self::AinvCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicCoBound<self::AinvCyclicCoBound::X*, self::AinvCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ return null;
+static method testTypeAliasAsTypeArgument() → void {
+ self::Acov<() →* dynamic, dynamic>* source1;
+ <Y extends self::Acov<() →* dynamic, dynamic>* = dynamic>() →* void fsource1 = self::toF<self::Acov<() →* dynamic, dynamic>*>(source1);
+ <Y extends self::Acov<() →* dynamic, dynamic>* = dynamic>() →* void target1 = fsource1;
+ self::Acon<(core::Null?) →* dynamic, dynamic>* source2;
+ <Y extends self::Acon<(core::Null?) →* dynamic, dynamic>* = dynamic>() →* void fsource2 = self::toF<self::Acon<(core::Null?) →* dynamic, dynamic>*>(source2);
+ <Y extends self::Acon<(core::Null*) →* dynamic, dynamic>* = dynamic>() →* void target2 = fsource2;
+ self::Ainv<(dynamic) →* dynamic, dynamic>* source3;
+ <Y extends self::Ainv<(dynamic) →* dynamic, dynamic>* = dynamic>() →* void fsource3 = self::toF<self::Ainv<(dynamic) →* dynamic, dynamic>*>(source3);
+ <Y extends self::Ainv<(dynamic) →* dynamic, dynamic>* = dynamic>() →* void target3 = fsource3;
+ self::AcovBound<() →* core::num*, core::num*>* source4;
+ <Y extends self::AcovBound<() →* core::num*, core::num*>* = dynamic>() →* void fsource4 = self::toF<self::AcovBound<() →* core::num*, core::num*>*>(source4);
+ <Y extends self::AcovBound<() →* core::num*, core::num*>* = dynamic>() →* void target4 = fsource4;
+ self::AconBound<(core::Null?) →* dynamic, core::num*>* source5;
+ <Y extends self::AconBound<(core::Null?) →* dynamic, core::num*>* = dynamic>() →* void fsource5 = self::toF<self::AconBound<(core::Null?) →* dynamic, core::num*>*>(source5);
+ <Y extends self::AconBound<(core::Null*) →* dynamic, core::num*>* = dynamic>() →* void target5 = fsource5;
+ self::AinvBound<(core::num*) →* core::num*, core::num*>* source6;
+ <Y extends self::AinvBound<(core::num*) →* core::num*, core::num*>* = dynamic>() →* void fsource6 = self::toF<self::AinvBound<(core::num*) →* core::num*, core::num*>*>(source6);
+ <Y extends self::AinvBound<(core::num*) →* core::num*, core::num*>* = dynamic>() →* void target6 = fsource6;
+ self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* source7;
+ <Y extends self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* = dynamic>() →* void fsource7 = self::toF<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>(source7);
+ <Y extends self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* = dynamic>() →* void target7 = fsource7;
+ self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>* source8;
+ <Y extends self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>* = dynamic>() →* void fsource8 = self::toF<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>(source8);
+ <Y extends self::AconCyclicBound<(core::Null*) →* dynamic, self::A<dynamic>*>* = dynamic>() →* void target8 = fsource8;
+ self::AinvCyclicBound<(self::A<dynamic>*) →* self::A<dynamic>*, self::A<dynamic>*>* source9;
+ self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* source10;
+ <Y extends self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* = dynamic>() →* void fsource10 = self::toF<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>(source10);
+ <Y extends self::AcovCyclicCoBound<() →* (core::Null*) →* dynamic, (core::Null*) →* dynamic>* = dynamic>() →* void target10 = fsource10;
+ self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>* source11;
+ <Y extends self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>* = dynamic>() →* void fsource11 = self::toF<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>(source11);
+ <Y extends self::AconCyclicCoBound<(core::Null*) →* dynamic, (core::Null*) →* dynamic>* = dynamic>() →* void target11 = fsource11;
+ self::AinvCyclicCoBound<((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* source12;
+}
+static method testNested() → void {
+ self::B<self::Acov<() →* dynamic, dynamic>*>* source1;
+ <Y extends self::B<self::Acov<() →* dynamic, dynamic>*>* = dynamic>() →* void fsource1 = self::toF<self::B<self::Acov<() →* dynamic, dynamic>*>*>(source1);
+ <Y extends self::B<self::Acov<() →* dynamic, dynamic>*>* = dynamic>() →* void target1 = fsource1;
+ self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>* source2;
+ <Y extends self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>* = dynamic>() →* void fsource2 = self::toF<self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>*>(source2);
+ <Y extends self::B<self::Acon<(core::Null*) →* dynamic, dynamic>*>* = dynamic>() →* void target2 = fsource2;
+ self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* source3;
+ <Y extends self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* = dynamic>() →* void fsource3 = self::toF<self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>*>(source3);
+ <Y extends self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* = dynamic>() →* void target3 = fsource3;
+ self::B<self::AcovBound<() →* core::num*, core::num*>*>* source4;
+ <Y extends self::B<self::AcovBound<() →* core::num*, core::num*>*>* = dynamic>() →* void fsource4 = self::toF<self::B<self::AcovBound<() →* core::num*, core::num*>*>*>(source4);
+ <Y extends self::B<self::AcovBound<() →* core::num*, core::num*>*>* = dynamic>() →* void target4 = fsource4;
+ self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>* source5;
+ <Y extends self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>* = dynamic>() →* void fsource5 = self::toF<self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>*>(source5);
+ <Y extends self::B<self::AconBound<(core::Null*) →* dynamic, core::num*>*>* = dynamic>() →* void target5 = fsource5;
+ self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* source6;
+ <Y extends self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* = dynamic>() →* void fsource6 = self::toF<self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>*>(source6);
+ <Y extends self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* = dynamic>() →* void target6 = fsource6;
+ self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* source7;
+ <Y extends self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* = dynamic>() →* void fsource7 = self::toF<self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>*>(source7);
+ <Y extends self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* = dynamic>() →* void target7 = fsource7;
+ self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>* source8;
+ <Y extends self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>* = dynamic>() →* void fsource8 = self::toF<self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>*>(source8);
+ <Y extends self::B<self::AconCyclicBound<(core::Null*) →* dynamic, self::A<dynamic>*>*>* = dynamic>() →* void target8 = fsource8;
+ self::B<self::AinvCyclicBound<(self::A<dynamic>*) →* self::A<dynamic>*, self::A<dynamic>*>*>* source9;
+ self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source10;
+ <Y extends self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* = dynamic>() →* void fsource10 = self::toF<self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>*>(source10);
+ <Y extends self::B<self::AcovCyclicCoBound<() →* (core::Null*) →* dynamic, (core::Null*) →* dynamic>*>* = dynamic>() →* void target10 = fsource10;
+ self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source11;
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* = dynamic>() →* void fsource11 = self::toF<self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>*>(source11);
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null*) →* dynamic, (core::Null*) →* dynamic>*>* = dynamic>() →* void target11 = fsource11;
+ self::B<self::AinvCyclicCoBound<((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source12;
+}
+static method main() → dynamic {
+ self::testTypeAliasAsTypeArgument();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/nested_variance_test.dart.strong.transformed.expect b/pkg/front_end/testcases/nested_variance_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..44abf90
--- /dev/null
+++ b/pkg/front_end/testcases/nested_variance_test.dart.strong.transformed.expect
@@ -0,0 +1,161 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class Acov<X extends () →* self::Acov::Y* = () →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acov<self::Acov::X*, self::Acov::Y*>*
+ : super core::Object::•()
+ ;
+}
+class Acon<X extends (self::Acon::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Acon<self::Acon::X*, self::Acon::Y*>*
+ : super core::Object::•()
+ ;
+}
+class Ainv<X extends (self::Ainv::Y*) →* self::Ainv::Y* = (dynamic) →* dynamic, Y extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::Ainv<self::Ainv::X*, self::Ainv::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AcovBound<X extends () →* self::AcovBound::Y* = () →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AcovBound<self::AcovBound::X*, self::AcovBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconBound<X extends (self::AconBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AconBound<self::AconBound::X*, self::AconBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvBound<X extends (self::AinvBound::Y*) →* self::AinvBound::Y* = (core::num*) →* core::num*, Y extends core::num* = core::num*> extends core::Object {
+ synthetic constructor •() → self::AinvBound<self::AinvBound::X*, self::AinvBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicBound<X extends () →* self::AcovCyclicBound::Y* = () →* self::A<dynamic>*, Y extends self::A<self::AcovCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicBound<self::AcovCyclicBound::X*, self::AcovCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconCyclicBound<X extends (self::AconCyclicBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends self::A<self::AconCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AconCyclicBound<self::AconCyclicBound::X*, self::AconCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicBound<X extends (self::AinvCyclicBound::Y*) →* self::AinvCyclicBound::Y* = (self::A<dynamic>*) →* self::A<dynamic>*, Y extends self::A<self::AinvCyclicBound::Y*>* = self::A<dynamic>*> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicBound<self::AinvCyclicBound::X*, self::AinvCyclicBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AcovCyclicCoBound<X extends () →* self::AcovCyclicCoBound::Y* = () →* (core::Null?) →* dynamic, Y extends (self::AcovCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AcovCyclicCoBound<self::AcovCyclicCoBound::X*, self::AcovCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AconCyclicCoBound<X extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic, Y extends (self::AconCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AconCyclicCoBound<self::AconCyclicCoBound::X*, self::AconCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class AinvCyclicCoBound<X extends (self::AinvCyclicCoBound::Y*) →* self::AinvCyclicCoBound::Y* = ((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, Y extends (self::AinvCyclicCoBound::Y*) →* dynamic = (core::Null?) →* dynamic> extends core::Object {
+ synthetic constructor •() → self::AinvCyclicCoBound<self::AinvCyclicCoBound::X*, self::AinvCyclicCoBound::Y*>*
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ return null;
+static method testTypeAliasAsTypeArgument() → void {
+ self::Acov<() →* dynamic, dynamic>* source1;
+ <Y extends self::Acov<() →* dynamic, dynamic>* = dynamic>() →* void fsource1 = self::toF<self::Acov<() →* dynamic, dynamic>*>(source1);
+ <Y extends self::Acov<() →* dynamic, dynamic>* = dynamic>() →* void target1 = fsource1;
+ self::Acon<(core::Null?) →* dynamic, dynamic>* source2;
+ <Y extends self::Acon<(core::Null?) →* dynamic, dynamic>* = dynamic>() →* void fsource2 = self::toF<self::Acon<(core::Null?) →* dynamic, dynamic>*>(source2);
+ <Y extends self::Acon<(core::Null*) →* dynamic, dynamic>* = dynamic>() →* void target2 = fsource2;
+ self::Ainv<(dynamic) →* dynamic, dynamic>* source3;
+ <Y extends self::Ainv<(dynamic) →* dynamic, dynamic>* = dynamic>() →* void fsource3 = self::toF<self::Ainv<(dynamic) →* dynamic, dynamic>*>(source3);
+ <Y extends self::Ainv<(dynamic) →* dynamic, dynamic>* = dynamic>() →* void target3 = fsource3;
+ self::AcovBound<() →* core::num*, core::num*>* source4;
+ <Y extends self::AcovBound<() →* core::num*, core::num*>* = dynamic>() →* void fsource4 = self::toF<self::AcovBound<() →* core::num*, core::num*>*>(source4);
+ <Y extends self::AcovBound<() →* core::num*, core::num*>* = dynamic>() →* void target4 = fsource4;
+ self::AconBound<(core::Null?) →* dynamic, core::num*>* source5;
+ <Y extends self::AconBound<(core::Null?) →* dynamic, core::num*>* = dynamic>() →* void fsource5 = self::toF<self::AconBound<(core::Null?) →* dynamic, core::num*>*>(source5);
+ <Y extends self::AconBound<(core::Null*) →* dynamic, core::num*>* = dynamic>() →* void target5 = fsource5;
+ self::AinvBound<(core::num*) →* core::num*, core::num*>* source6;
+ <Y extends self::AinvBound<(core::num*) →* core::num*, core::num*>* = dynamic>() →* void fsource6 = self::toF<self::AinvBound<(core::num*) →* core::num*, core::num*>*>(source6);
+ <Y extends self::AinvBound<(core::num*) →* core::num*, core::num*>* = dynamic>() →* void target6 = fsource6;
+ self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* source7;
+ <Y extends self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* = dynamic>() →* void fsource7 = self::toF<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>(source7);
+ <Y extends self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>* = dynamic>() →* void target7 = fsource7;
+ self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>* source8;
+ <Y extends self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>* = dynamic>() →* void fsource8 = self::toF<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>(source8);
+ <Y extends self::AconCyclicBound<(core::Null*) →* dynamic, self::A<dynamic>*>* = dynamic>() →* void target8 = fsource8;
+ self::AinvCyclicBound<(self::A<dynamic>*) →* self::A<dynamic>*, self::A<dynamic>*>* source9;
+ self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* source10;
+ <Y extends self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* = dynamic>() →* void fsource10 = self::toF<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>(source10);
+ <Y extends self::AcovCyclicCoBound<() →* (core::Null*) →* dynamic, (core::Null*) →* dynamic>* = dynamic>() →* void target10 = fsource10;
+ self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>* source11;
+ <Y extends self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>* = dynamic>() →* void fsource11 = self::toF<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>(source11);
+ <Y extends self::AconCyclicCoBound<(core::Null*) →* dynamic, (core::Null*) →* dynamic>* = dynamic>() →* void target11 = fsource11;
+ self::AinvCyclicCoBound<((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>* source12;
+}
+static method testNested() → void {
+ self::B<self::Acov<() →* dynamic, dynamic>*>* source1;
+ <Y extends self::B<self::Acov<() →* dynamic, dynamic>*>* = dynamic>() →* void fsource1 = self::toF<self::B<self::Acov<() →* dynamic, dynamic>*>*>(source1);
+ <Y extends self::B<self::Acov<() →* dynamic, dynamic>*>* = dynamic>() →* void target1 = fsource1;
+ self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>* source2;
+ <Y extends self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>* = dynamic>() →* void fsource2 = self::toF<self::B<self::Acon<(core::Null?) →* dynamic, dynamic>*>*>(source2);
+ <Y extends self::B<self::Acon<(core::Null*) →* dynamic, dynamic>*>* = dynamic>() →* void target2 = fsource2;
+ self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* source3;
+ <Y extends self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* = dynamic>() →* void fsource3 = self::toF<self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>*>(source3);
+ <Y extends self::B<self::Ainv<(dynamic) →* dynamic, dynamic>*>* = dynamic>() →* void target3 = fsource3;
+ self::B<self::AcovBound<() →* core::num*, core::num*>*>* source4;
+ <Y extends self::B<self::AcovBound<() →* core::num*, core::num*>*>* = dynamic>() →* void fsource4 = self::toF<self::B<self::AcovBound<() →* core::num*, core::num*>*>*>(source4);
+ <Y extends self::B<self::AcovBound<() →* core::num*, core::num*>*>* = dynamic>() →* void target4 = fsource4;
+ self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>* source5;
+ <Y extends self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>* = dynamic>() →* void fsource5 = self::toF<self::B<self::AconBound<(core::Null?) →* dynamic, core::num*>*>*>(source5);
+ <Y extends self::B<self::AconBound<(core::Null*) →* dynamic, core::num*>*>* = dynamic>() →* void target5 = fsource5;
+ self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* source6;
+ <Y extends self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* = dynamic>() →* void fsource6 = self::toF<self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>*>(source6);
+ <Y extends self::B<self::AinvBound<(core::num*) →* core::num*, core::num*>*>* = dynamic>() →* void target6 = fsource6;
+ self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* source7;
+ <Y extends self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* = dynamic>() →* void fsource7 = self::toF<self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>*>(source7);
+ <Y extends self::B<self::AcovCyclicBound<() →* self::A<dynamic>*, self::A<dynamic>*>*>* = dynamic>() →* void target7 = fsource7;
+ self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>* source8;
+ <Y extends self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>* = dynamic>() →* void fsource8 = self::toF<self::B<self::AconCyclicBound<(core::Null?) →* dynamic, self::A<dynamic>*>*>*>(source8);
+ <Y extends self::B<self::AconCyclicBound<(core::Null*) →* dynamic, self::A<dynamic>*>*>* = dynamic>() →* void target8 = fsource8;
+ self::B<self::AinvCyclicBound<(self::A<dynamic>*) →* self::A<dynamic>*, self::A<dynamic>*>*>* source9;
+ self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source10;
+ <Y extends self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* = dynamic>() →* void fsource10 = self::toF<self::B<self::AcovCyclicCoBound<() →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>*>(source10);
+ <Y extends self::B<self::AcovCyclicCoBound<() →* (core::Null*) →* dynamic, (core::Null*) →* dynamic>*>* = dynamic>() →* void target10 = fsource10;
+ self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source11;
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* = dynamic>() →* void fsource11 = self::toF<self::B<self::AconCyclicCoBound<(core::Null?) →* dynamic, (core::Null?) →* dynamic>*>*>(source11);
+ <Y extends self::B<self::AconCyclicCoBound<(core::Null*) →* dynamic, (core::Null*) →* dynamic>*>* = dynamic>() →* void target11 = fsource11;
+ self::B<self::AinvCyclicCoBound<((core::Null?) →* dynamic) →* (core::Null?) →* dynamic, (core::Null?) →* dynamic>*>* source12;
+}
+static method main() → dynamic {
+ self::testTypeAliasAsTypeArgument();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
index eb8a0fd..30f7d49 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.outline.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
typedef F = () → void;
-class A<T extends core::Object* = dynamic> extends core::Object {
+class A<T extends core::Object? = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
;
}
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
index a1e7b4a..71aef3b 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
typedef F = () → void;
-class A<T extends core::Object* = dynamic> extends core::Object {
+class A<T extends core::Object? = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
index a1e7b4a..71aef3b 100644
--- a/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/function_types.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
typedef F = () → void;
-class A<T extends core::Object* = dynamic> extends core::Object {
+class A<T extends core::Object? = dynamic> extends core::Object {
synthetic constructor •() → self::A<self::A::T*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart b/pkg/front_end/testcases/nnbd/null_check.dart
new file mode 100644
index 0000000..110d74f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, 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.
+
+class Class {
+ int? field;
+ int? method() => field;
+ Class operator +(Class other) => new Class();
+}
+
+main() {
+ Class? c = new Class();
+ c!;
+ c!.field;
+ c!.field = 42;
+ c!.method;
+ c!.method();
+ c!.field!.toString();
+ c!.method()!.toString();
+ c! + c;
+ c! + c!;
+ c + c!;
+ (c + c)!;
+
+ bool? o = true;
+ !o! ? !o! : !!o!!;
+ !(o!) ? (!o)! : (!(!o)!)!;
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect b/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect
new file mode 100644
index 0000000..5dd134e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.outline.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int? field;
+ synthetic constructor •() → self::Class*
+ ;
+ method method() → core::int?
+ ;
+ operator +(self::Class other) → self::Class
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect b/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect
new file mode 100644
index 0000000..d9dcefa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.strong.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int? field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ method method() → core::int?
+ return this.{self::Class::field};
+ operator +(self::Class other) → self::Class
+ return new self::Class::•();
+}
+static method main() → dynamic {
+ self::Class? c = new self::Class::•();
+ c!;
+ c!.{self::Class::field};
+ c!.{self::Class::field} = 42;
+ c!.{self::Class::method};
+ c!.{self::Class::method}();
+ c!.{self::Class::field}!.{core::int::toString}();
+ c!.{self::Class::method}()!.{core::int::toString}();
+ c!.{self::Class::+}(c);
+ c!.{self::Class::+}(c!);
+ c.{self::Class::+}(c!);
+ c.{self::Class::+}(c)!;
+ core::bool? o = true;
+ !o! ?{core::bool} !o! : !!o!!;
+ !o! ?{core::bool} (!o)! : (!(!o)!)!;
+}
diff --git a/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..d9dcefa
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/null_check.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Class extends core::Object {
+ field core::int? field = null;
+ synthetic constructor •() → self::Class*
+ : super core::Object::•()
+ ;
+ method method() → core::int?
+ return this.{self::Class::field};
+ operator +(self::Class other) → self::Class
+ return new self::Class::•();
+}
+static method main() → dynamic {
+ self::Class? c = new self::Class::•();
+ c!;
+ c!.{self::Class::field};
+ c!.{self::Class::field} = 42;
+ c!.{self::Class::method};
+ c!.{self::Class::method}();
+ c!.{self::Class::field}!.{core::int::toString}();
+ c!.{self::Class::method}()!.{core::int::toString}();
+ c!.{self::Class::+}(c);
+ c!.{self::Class::+}(c!);
+ c.{self::Class::+}(c!);
+ c.{self::Class::+}(c)!;
+ core::bool? o = true;
+ !o! ?{core::bool} !o! : !!o!!;
+ !o! ?{core::bool} (!o)! : (!(!o)!)!;
+}
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
index d0af2e7..610a9ee 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.expect
@@ -33,7 +33,7 @@
self::test_nullable_function_type_formal_param(f: () → core::int => 2);
}
static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
- return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+ return let final core::int #t1 = f.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
index d0af2e7..610a9ee 100644
--- a/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/nullable_param.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
self::test_nullable_function_type_formal_param(f: () → core::int => 2);
}
static method test_nullable_function_type_formal_param({() →? core::int f = #C1}) → core::int {
- return let final core::int #t1 = f.call() in #t1.==(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
+ return let final core::int #t1 = f.call() in #t1.{core::num::==}(null) ?{core::int*} 1.{core::int::unary-}() : #t1;
}
constants {
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart b/pkg/front_end/testcases/nnbd/type_parameter_types.dart
new file mode 100644
index 0000000..67353a0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2019, 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.
+
+class A<X extends Object, Y extends Object?> {
+ X foo() => null;
+ X? bar() => null;
+ Y baz() => null;
+}
+
+class B<X extends List<Y>, Y extends Object?> {
+ foo(X x, Y y) {}
+}
+
+class C<X extends List<Y>?, Y extends List<X>?> {
+ foo(X x, Y y) {}
+}
+
+class D<X extends Y, Y extends Z, Z> {
+ foo(X x, Y y, Z z) {}
+}
+
+main() {
+ X fun1<X extends Object, Y extends Object?>() => null;
+ Y fun2<X extends Object, Y extends Object?>() => null;
+ X fun3<X extends List<Y>, Y extends Object?>() => null;
+ Y fun4<X extends List<Y>, Y extends Object?>() => null;
+ X fun5<X extends List<Y>?, Y extends List<X>?>() => null;
+ Y fun6<X extends List<Y>?, Y extends List<X>?>() => null;
+ X fun7<X extends Y, Y extends Z, Z>() => null;
+ Y fun8<X extends Y, Y extends Z, Z>() => null;
+ Z fun9<X extends Y, Y extends Z, Z>() => null;
+}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect
new file mode 100644
index 0000000..ce46e5f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.outline.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = core::Object, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*, self::A::Y*>*
+ ;
+ method foo() → self::A::X
+ ;
+ method bar() → self::A::X?
+ ;
+ method baz() → self::A::Y%
+ ;
+}
+class B<X extends core::List<self::B::Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*, self::B::Y*>*
+ ;
+ method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic
+ ;
+}
+class C<X extends core::List<self::C::Y%>? = core::List<dynamic>?, Y extends core::List<self::C::X%>? = core::List<dynamic>?> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X*, self::C::Y*>*
+ ;
+ method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic
+ ;
+}
+class D<X extends self::D::Y% = dynamic, Y extends self::D::Z% = dynamic, Z extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X*, self::D::Y*, self::D::Z*>*
+ ;
+ method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect
new file mode 100644
index 0000000..83c7544
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.expect
@@ -0,0 +1,53 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = core::Object, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*, self::A::Y*>*
+ : super core::Object::•()
+ ;
+ method foo() → self::A::X
+ return null;
+ method bar() → self::A::X?
+ return null;
+ method baz() → self::A::Y%
+ return null;
+}
+class B<X extends core::List<self::B::Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*, self::B::Y*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic {}
+}
+class C<X extends core::List<self::C::Y%>? = core::List<dynamic>?, Y extends core::List<self::C::X%>? = core::List<dynamic>?> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X*, self::C::Y*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic {}
+}
+class D<X extends self::D::Y% = dynamic, Y extends self::D::Z% = dynamic, Z extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X*, self::D::Y*, self::D::Z*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic {}
+}
+static method main() → dynamic {
+ function fun1<X extends core::Object = core::Object, Y extends core::Object? = core::Object?>() → X
+ return null;
+ function fun2<X extends core::Object = core::Object, Y extends core::Object? = core::Object?>() → Y%
+ return null;
+ function fun3<X extends core::List<Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?>() → X
+ return null;
+ function fun4<X extends core::List<Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?>() → Y%
+ return null;
+ function fun5<X extends core::List<Y%>? = core::List<dynamic>?, Y extends core::List<X%>? = core::List<dynamic>?>() → X%
+ return null;
+ function fun6<X extends core::List<Y%>? = core::List<dynamic>?, Y extends core::List<X%>? = core::List<dynamic>?>() → Y%
+ return null;
+ function fun7<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → X%
+ return null;
+ function fun8<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → Y%
+ return null;
+ function fun9<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → Z%
+ return null;
+}
diff --git a/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..83c7544
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/type_parameter_types.dart.strong.transformed.expect
@@ -0,0 +1,53 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object = core::Object, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*, self::A::Y*>*
+ : super core::Object::•()
+ ;
+ method foo() → self::A::X
+ return null;
+ method bar() → self::A::X?
+ return null;
+ method baz() → self::A::Y%
+ return null;
+}
+class B<X extends core::List<self::B::Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*, self::B::Y*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::B::X x, generic-covariant-impl self::B::Y% y) → dynamic {}
+}
+class C<X extends core::List<self::C::Y%>? = core::List<dynamic>?, Y extends core::List<self::C::X%>? = core::List<dynamic>?> extends core::Object {
+ synthetic constructor •() → self::C<self::C::X*, self::C::Y*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::C::X% x, generic-covariant-impl self::C::Y% y) → dynamic {}
+}
+class D<X extends self::D::Y% = dynamic, Y extends self::D::Z% = dynamic, Z extends core::Object? = dynamic> extends core::Object {
+ synthetic constructor •() → self::D<self::D::X*, self::D::Y*, self::D::Z*>*
+ : super core::Object::•()
+ ;
+ method foo(generic-covariant-impl self::D::X% x, generic-covariant-impl self::D::Y% y, generic-covariant-impl self::D::Z% z) → dynamic {}
+}
+static method main() → dynamic {
+ function fun1<X extends core::Object = core::Object, Y extends core::Object? = core::Object?>() → X
+ return null;
+ function fun2<X extends core::Object = core::Object, Y extends core::Object? = core::Object?>() → Y%
+ return null;
+ function fun3<X extends core::List<Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?>() → X
+ return null;
+ function fun4<X extends core::List<Y%> = core::List<core::Object?>, Y extends core::Object? = core::Object?>() → Y%
+ return null;
+ function fun5<X extends core::List<Y%>? = core::List<dynamic>?, Y extends core::List<X%>? = core::List<dynamic>?>() → X%
+ return null;
+ function fun6<X extends core::List<Y%>? = core::List<dynamic>?, Y extends core::List<X%>? = core::List<dynamic>?>() → Y%
+ return null;
+ function fun7<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → X%
+ return null;
+ function fun8<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → Y%
+ return null;
+ function fun9<X extends Y% = dynamic, Y extends Z% = dynamic, Z extends core::Object? = dynamic>() → Z%
+ return null;
+}
diff --git a/pkg/front_end/testcases/old_dills/dart2js.version.33.compile.1.dill b/pkg/front_end/testcases/old_dills/dart2js.version.33.compile.1.dill
new file mode 100644
index 0000000..95c4245
--- /dev/null
+++ b/pkg/front_end/testcases/old_dills/dart2js.version.33.compile.1.dill
Binary files differ
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
index c7e3f5b..c501ddc 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
@@ -48,10 +48,6 @@
// C notEvenAConstructor(a) = h;
// ^
//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
-// C notEvenAConstructor(a) = h;
-// ^
-//
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
index 2430f63..54451d2 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.transformed.expect
@@ -48,10 +48,6 @@
// C notEvenAConstructor(a) = h;
// ^
//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
-// C notEvenAConstructor(a) = h;
-// ^
-//
// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
// - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
// Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
diff --git a/pkg/front_end/testcases/rasta/super.dart.strong.expect b/pkg/front_end/testcases/rasta/super.dart.strong.expect
index 7ac227e..ac97d8e 100644
--- a/pkg/front_end/testcases/rasta/super.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.strong.expect
@@ -589,12 +589,12 @@
self::use(let final dynamic #t46 = super.{self::A::h} in #t46.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : #t46);
super.{self::A::i}.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : null;
self::use(let final dynamic #t47 = super.{self::A::i} in #t47.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : #t47);
- let final core::int* #t48 = 87 in super.{self::A::[]}(#t48).{core::Object::==}(null) ?{dynamic} let final core::int* #t49 = 42 in let final void #t50 = super.{self::A::[]=}(#t48, #t49) in #t49 : null;
- self::use(let final core::int* #t51 = 87 in let final dynamic #t52 = super.{self::A::[]}(#t51) in #t52.{core::Object::==}(null) ?{dynamic} let final core::int* #t53 = 42 in let final void #t54 = super.{self::A::[]=}(#t51, #t53) in #t53 : #t52);
+ let final core::int* #t48 = 87 in super.{self::A::[]}(#t48).{core::Object::==}(null) ?{dynamic} super.{self::A::[]=}(#t48, 42) : null;
+ self::use(let final core::int* #t49 = 87 in let final dynamic #t50 = super.{self::A::[]}(#t49) in #t50.{core::Object::==}(null) ?{dynamic} let final core::int* #t51 = 42 in let final void #t52 = super.{self::A::[]=}(#t49, #t51) in #t51 : #t50);
super.{self::A::m}.{core::Object::==}(null) ?{core::Object*} super.m = 42 : null;
- self::use(let final () →* void #t55 = super.{self::A::m} in #t55.{core::Object::==}(null) ?{core::Object*} super.m = 42 : #t55);
+ self::use(let final () →* void #t53 = super.{self::A::m} in #t53.{core::Object::==}(null) ?{core::Object*} super.m = 42 : #t53);
super.{self::A::n}.{core::Object::==}(null) ?{core::Object*} super.{self::A::n} = 42 : null;
- self::use(let final () →* void #t56 = super.{self::A::n} in #t56.{core::Object::==}(null) ?{core::Object*} super.{self::A::n} = 42 : #t56);
+ self::use(let final () →* void #t54 = super.{self::A::n} in #t54.{core::Object::==}(null) ?{core::Object*} super.{self::A::n} = 42 : #t54);
super.{self::A::a} = super.{self::A::a}.+(42);
self::use(super.{self::A::a} = super.{self::A::a}.+(42));
super.{self::A::b} = super.{self::B::b}.+(42);
@@ -613,8 +613,8 @@
self::use(super.{self::A::h} = super.{self::A::h}.+(42));
super.{self::B::i} = super.{self::A::i}.+(42);
self::use(super.{self::B::i} = super.{self::A::i}.+(42));
- let final core::int* #t57 = 87 in super.{self::A::[]=}(#t57, super.{self::A::[]}(#t57).+(42));
- self::use(let final core::int* #t58 = 87 in let final dynamic #t59 = super.{self::A::[]}(#t58).+(42) in let final void #t60 = super.{self::A::[]=}(#t58, #t59) in #t59);
+ let final core::int* #t55 = 87 in super.{self::A::[]=}(#t55, super.{self::A::[]}(#t55).+(42));
+ self::use(let final core::int* #t56 = 87 in let final dynamic #t57 = super.{self::A::[]}(#t56).+(42) in let final void #t58 = super.{self::A::[]=}(#t56, #t57) in #t57);
super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:222:13: Error: The method '+' isn't defined for the class 'void Function()'.
Try correcting the name to the name of an existing method, or defining a method named '+'.
super.m += 42;
@@ -649,8 +649,8 @@
self::use(super.{self::A::h} = super.{self::A::h}.-(42));
super.{self::B::i} = super.{self::A::i}.-(42);
self::use(super.{self::B::i} = super.{self::A::i}.-(42));
- let final core::int* #t61 = 87 in super.{self::A::[]=}(#t61, super.{self::A::[]}(#t61).-(42));
- self::use(let final core::int* #t62 = 87 in let final dynamic #t63 = super.{self::A::[]}(#t62).-(42) in let final void #t64 = super.{self::A::[]=}(#t62, #t63) in #t63);
+ let final core::int* #t59 = 87 in super.{self::A::[]=}(#t59, super.{self::A::[]}(#t59).-(42));
+ self::use(let final core::int* #t60 = 87 in let final dynamic #t61 = super.{self::A::[]}(#t60).-(42) in let final void #t62 = super.{self::A::[]=}(#t60, #t61) in #t61);
super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:247:13: Error: The method '-' isn't defined for the class 'void Function()'.
Try correcting the name to the name of an existing method, or defining a method named '-'.
super.m -= 42;
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
index 47838e6..76fc4ed 100644
--- a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
@@ -343,172 +343,172 @@
self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
use(Func = 42);
^^^^");
- let final dynamic #t1 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
C++;
^";
- self::use(let final dynamic #t2 = self::C<dynamic>* in let final dynamic #t3 = #t2 in let final dynamic #t4 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
use(C++);
- ^" in #t3);
- let final dynamic #t5 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
dynamic++;
^^^^^^^";
- self::use(let final dynamic #t6 = dynamic in let final dynamic #t7 = #t6 in let final dynamic #t8 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
use(dynamic++);
- ^^^^^^^" in #t7);
- let final dynamic #t9 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
T++;
^";
- self::use(let final dynamic #t10 = self::C::T* in let final dynamic #t11 = #t10 in let final dynamic #t12 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
use(T++);
- ^" in #t11);
- let final dynamic #t13 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
Func++;
^^^^";
- self::use(let final dynamic #t14 = () →* void in let final dynamic #t15 = #t14 in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
use(Func++);
- ^^^^" in #t15);
- let final dynamic #t17 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
++C;
^";
- self::use(let final dynamic #t18 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
use(++C);
^");
- let final dynamic #t19 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
++dynamic;
^^^^^^^";
- self::use(let final dynamic #t20 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
use(++dynamic);
^^^^^^^");
- let final dynamic #t21 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
++T;
^";
- self::use(let final dynamic #t22 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
use(++T);
^");
- let final dynamic #t23 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
++Func;
^^^^";
- self::use(let final dynamic #t24 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
use(++Func);
^^^^");
- let final dynamic #t25 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
C--;
^";
- self::use(let final dynamic #t26 = self::C<dynamic>* in let final dynamic #t27 = #t26 in let final dynamic #t28 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
use(C--);
- ^" in #t27);
- let final dynamic #t29 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
dynamic--;
^^^^^^^";
- self::use(let final dynamic #t30 = dynamic in let final dynamic #t31 = #t30 in let final dynamic #t32 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
use(dynamic--);
- ^^^^^^^" in #t31);
- let final dynamic #t33 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
T--;
^";
- self::use(let final dynamic #t34 = self::C::T* in let final dynamic #t35 = #t34 in let final dynamic #t36 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
use(T--);
- ^" in #t35);
- let final dynamic #t37 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
Func--;
^^^^";
- self::use(let final dynamic #t38 = () →* void in let final dynamic #t39 = #t38 in let final dynamic #t40 = invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
use(Func--);
- ^^^^" in #t39);
- let final dynamic #t41 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
--C;
^";
- self::use(let final dynamic #t42 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
use(--C);
^");
- let final dynamic #t43 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
--dynamic;
^^^^^^^";
- self::use(let final dynamic #t44 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
use(--dynamic);
^^^^^^^");
- let final dynamic #t45 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
--T;
^";
- self::use(let final dynamic #t46 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
use(--T);
^");
- let final dynamic #t47 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
--Func;
^^^^";
- self::use(let final dynamic #t48 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
use(--Func);
^^^^");
- let final dynamic #t49 = self::C<dynamic>* in #t49.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+ self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
C ??= 42;
^" : null;
- self::use(let final dynamic #t50 = self::C<dynamic>* in let final dynamic #t51 = #t50 in #t51.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+ self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
use(C ??= 42);
- ^" : #t51);
- let final dynamic #t52 = dynamic in #t52.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+ ^" : #t1);
+ dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
dynamic ??= 42;
^^^^^^^" : null;
- self::use(let final dynamic #t53 = dynamic in let final dynamic #t54 = #t53 in #t54.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+ self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
use(dynamic ??= 42);
- ^^^^^^^" : #t54);
- let final dynamic #t55 = self::C::T* in #t55.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+ ^^^^^^^" : #t2);
+ self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
T ??= 42;
^" : null;
- self::use(let final dynamic #t56 = self::C::T* in let final dynamic #t57 = #t56 in #t57.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+ self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
use(T ??= 42);
- ^" : #t57);
- let final dynamic #t58 = () →* void in #t58.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+ ^" : #t3);
+ () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
Func ??= 42;
^^^^" : null;
- self::use(let final dynamic #t59 = () →* void in let final dynamic #t60 = #t59 in #t60.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+ self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
use(Func ??= 42);
- ^^^^" : #t60);
- let final dynamic #t61 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+ ^^^^" : #t4);
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
C += 42;
^";
- self::use(let final dynamic #t62 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
use(C += 42);
^");
- let final dynamic #t63 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
dynamic += 42;
^^^^^^^";
- self::use(let final dynamic #t64 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
use(dynamic += 42);
^^^^^^^");
- let final dynamic #t65 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
T += 42;
^";
- self::use(let final dynamic #t66 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
use(T += 42);
^");
- let final dynamic #t67 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
Func += 42;
^^^^";
- self::use(let final dynamic #t68 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
use(Func += 42);
^^^^");
- let final dynamic #t69 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
C -= 42;
^";
- self::use(let final dynamic #t70 = self::C<dynamic>* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
use(C -= 42);
^");
- let final dynamic #t71 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
dynamic -= 42;
^^^^^^^";
- self::use(let final dynamic #t72 = dynamic in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
use(dynamic -= 42);
^^^^^^^");
- let final dynamic #t73 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
T -= 42;
^";
- self::use(let final dynamic #t74 = self::C::T* in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
use(T -= 42);
^");
- let final dynamic #t75 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
Func -= 42;
^^^^";
- self::use(let final dynamic #t76 = () →* void in invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
use(Func -= 42);
^^^^");
}
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..76fc4ed
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect
@@ -0,0 +1,522 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:22:5: Error: Method not found: 'dynamic'.
+// dynamic();
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:23:9: Error: Method not found: 'dynamic'.
+// use(dynamic());
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:24:5: Error: Method not found: 'T'.
+// T();
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:25:9: Error: Method not found: 'T'.
+// use(T());
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:26:5: Error: Method not found: 'Func'.
+// Func();
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:27:9: Error: Method not found: 'Func'.
+// use(Func());
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+// C = 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+// use(C = 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+// dynamic = 42;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+// use(dynamic = 42);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+// T = 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+// use(T = 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+// Func = 42;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+// use(Func = 42);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+// C++;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+// use(C++);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+// dynamic++;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+// use(dynamic++);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+// T++;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+// use(T++);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+// Func++;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+// use(Func++);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+// ++C;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+// use(++C);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+// ++dynamic;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+// use(++dynamic);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+// ++T;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+// use(++T);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+// ++Func;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+// use(++Func);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+// C--;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+// use(C--);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+// dynamic--;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+// use(dynamic--);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+// T--;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+// use(T--);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+// Func--;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+// use(Func--);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+// --C;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+// use(--C);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+// --dynamic;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+// use(--dynamic);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+// --T;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+// use(--T);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+// --Func;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+// use(--Func);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+// C ??= 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+// use(C ??= 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+// dynamic ??= 42;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+// use(dynamic ??= 42);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+// T ??= 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+// use(T ??= 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+// Func ??= 42;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+// use(Func ??= 42);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+// C += 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+// use(C += 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+// dynamic += 42;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+// use(dynamic += 42);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+// T += 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+// use(T += 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+// Func += 42;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+// use(Func += 42);
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+// C -= 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+// use(C -= 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+// dynamic -= 42;
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+// use(dynamic -= 42);
+// ^^^^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+// T -= 42;
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+// use(T -= 42);
+// ^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+// Func -= 42;
+// ^^^^
+//
+// pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+// use(Func -= 42);
+// ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef Func = () →* void;
+class C<T extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T*>*
+ : super core::Object::•()
+ ;
+ method test() → dynamic {
+ self::C<dynamic>*;
+ self::use(self::C<dynamic>*);
+ dynamic;
+ self::use(dynamic);
+ self::C::T*;
+ self::use(self::C::T*);
+ () →* void;
+ self::use(() →* void);
+ new self::C::•<dynamic>();
+ self::use(new self::C::•<dynamic>());
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:22:5: Error: Method not found: 'dynamic'.
+ dynamic();
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:23:9: Error: Method not found: 'dynamic'.
+ use(dynamic());
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:24:5: Error: Method not found: 'T'.
+ T();
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:25:9: Error: Method not found: 'T'.
+ use(T());
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:26:5: Error: Method not found: 'Func'.
+ Func();
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:27:9: Error: Method not found: 'Func'.
+ use(Func());
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+ C = 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+ use(C = 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+ dynamic = 42;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+ use(dynamic = 42);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+ T = 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+ use(T = 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+ Func = 42;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+ use(Func = 42);
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+ C++;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+ use(C++);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+ dynamic++;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+ use(dynamic++);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+ T++;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+ use(T++);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+ Func++;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+ use(Func++);
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+ ++C;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+ use(++C);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+ ++dynamic;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+ use(++dynamic);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+ ++T;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+ use(++T);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+ ++Func;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+ use(++Func);
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+ C--;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+ use(C--);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+ dynamic--;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+ use(dynamic--);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+ T--;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+ use(T--);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+ Func--;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+ use(Func--);
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+ --C;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+ use(--C);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+ --dynamic;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+ use(--dynamic);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+ --T;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+ use(--T);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+ --Func;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+ use(--Func);
+ ^^^^");
+ self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+ C ??= 42;
+ ^" : null;
+ self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+ use(C ??= 42);
+ ^" : #t1);
+ dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+ dynamic ??= 42;
+ ^^^^^^^" : null;
+ self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+ use(dynamic ??= 42);
+ ^^^^^^^" : #t2);
+ self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+ T ??= 42;
+ ^" : null;
+ self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+ use(T ??= 42);
+ ^" : #t3);
+ () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+ Func ??= 42;
+ ^^^^" : null;
+ self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+ use(Func ??= 42);
+ ^^^^" : #t4);
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+ C += 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+ use(C += 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+ dynamic += 42;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+ use(dynamic += 42);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+ T += 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+ use(T += 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+ Func += 42;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+ use(Func += 42);
+ ^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+ C -= 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+ use(C -= 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+ dynamic -= 42;
+ ^^^^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+ use(dynamic -= 42);
+ ^^^^^^^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+ T -= 42;
+ ^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+ use(T -= 42);
+ ^");
+ invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+ Func -= 42;
+ ^^^^";
+ self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+ use(Func -= 42);
+ ^^^^");
+ }
+}
+static method use(dynamic x) → dynamic {
+ if(x.{core::Object::==}(new core::DateTime::now().{core::DateTime::millisecondsSinceEpoch}))
+ throw "Shouldn't happen";
+}
+static method main() → dynamic {
+ new self::C::•<dynamic>().{self::C::test}();
+}
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
index 92d39b4..eccfc19 100644
--- a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
@@ -23,7 +23,7 @@
invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
Foo = null;
^^^";
- let final dynamic #t1 = () →* void in #t1.==(null) ? invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+ () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
Foo ??= null;
^^^" : null;
invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..eccfc19
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+// Foo = null;
+// ^^^
+//
+// pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+// Foo ??= null;
+// ^^^
+//
+// pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
+// Foo();
+// ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef Foo = () →* void;
+static method main() → dynamic {
+ core::print(() →* void);
+ invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+ Foo = null;
+ ^^^";
+ () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+ Foo ??= null;
+ ^^^" : null;
+ invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
+ Foo();
+ ^^^";
+}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
index ad3c1dc..c41f760 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
@@ -2,14 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
-// print(key);
-// ^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: Setter not found: 'key'.
-// for (key in x) {
-// ^^^
-//
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
// for (Fisk in x) {
// ^^^^
@@ -30,10 +22,6 @@
// for (1 in x) {
// ^
//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: Getter not found: 'key'.
-// print(key);
-// ^^^
-//
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
// for (1 in x) {
// ^
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
index ad3c1dc..c41f760 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
@@ -2,14 +2,6 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
-// print(key);
-// ^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: Setter not found: 'key'.
-// for (key in x) {
-// ^^^
-//
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
// for (Fisk in x) {
// ^^^^
@@ -30,10 +22,6 @@
// for (1 in x) {
// ^
//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: Getter not found: 'key'.
-// print(key);
-// ^^^
-//
// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
// for (1 in x) {
// ^
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
index ff2cc72..932bc89 100644
--- a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
@@ -6,18 +6,18 @@
// super[4] = 42;
// ^
//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
-// super[4] += 5;
-// ^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
-// super[4] += 5;
-// ^
-//
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
// return super[2];
// ^
//
+// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
+// super[4] += 5;
+// ^^
+//
+// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
+// super[4] += 5;
+// ^^^
+//
// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
// on Exception catch (e) { }
// ^^
@@ -51,7 +51,9 @@
;
method foo() → dynamic {
super.[]=(4, 42);
- let final core::int* #t1 = 4 in super.[]=(#t1, super.[](#t1).+(5));
+ let final core::int* #t1 = 4 in invalid-expression "pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
+ super[4] += 5;
+ ^^^";
return super.[](2);
}
}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31181.dart.outline.expect
index bff625e..91c2fcb 100644
--- a/pkg/front_end/testcases/regress/issue_31181.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef Foo<T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
+typedef Foo<invariant T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
static field <T extends core::Object* = dynamic>(T*) →* T* x;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31181.dart.strong.expect
index c685791..34ce4a3b 100644
--- a/pkg/front_end/testcases/regress/issue_31181.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.strong.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef Foo<T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
+typedef Foo<invariant T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
static field <T extends core::Object* = dynamic>(T*) →* T* x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect
index c685791..34ce4a3b 100644
--- a/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect
@@ -2,6 +2,6 @@
import self as self;
import "dart:core" as core;
-typedef Foo<T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
+typedef Foo<invariant T extends core::Object* = dynamic> = <T extends core::Object* = dynamic>(T*) →* T*;
static field <T extends core::Object* = dynamic>(T*) →* T* x;
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
index cf09cb2..4723bc6 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
@@ -23,9 +23,9 @@
self::i;
}
static method test2() → core::int* {
- return (let final dynamic #t3 = self::i in let final dynamic #t4 = #t3 in let final dynamic #t5 = invalid-expression "pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
+ return invalid-expression "pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
return (i) ++ (i);
- ^" in #t4) as{TypeError} core::int*;
+ ^" as{TypeError} core::int*;
self::i;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
index 3d41703..4723bc6 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
@@ -23,9 +23,9 @@
self::i;
}
static method test2() → core::int* {
- return (let final core::int* #t3 = self::i in let final core::int* #t4 = #t3 in let final dynamic #t5 = invalid-expression "pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
+ return invalid-expression "pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
return (i) ++ (i);
- ^" in #t4) as{TypeError} core::int*;
+ ^" as{TypeError} core::int*;
self::i;
}
static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
index 52693de..a734b9c 100644
--- a/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef C<A extends core::Object* = dynamic, K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
-typedef D<K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef C<contravariant A extends core::Object* = dynamic, contravariant K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef D<unrelated K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
static method producer<K extends core::Object* = dynamic>() → dynamic
;
static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
index cc1d463..69a285c 100644
--- a/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef C<A extends core::Object* = dynamic, K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
-typedef D<K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef C<contravariant A extends core::Object* = dynamic, contravariant K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef D<unrelated K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
static method producer<K extends core::Object* = dynamic>() → dynamic {
return <A extends core::Object* = dynamic>(core::int* v1) → <B extends core::Object* = dynamic>(A*, self::producer::K*, B*) →* core::int* {
return <B extends core::Object* = dynamic>(A* v2, self::producer::K* v3, B* v4) → core::int* => 0;
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect
index cc1d463..69a285c 100644
--- a/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef C<A extends core::Object* = dynamic, K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
-typedef D<K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef C<contravariant A extends core::Object* = dynamic, contravariant K extends core::Object* = dynamic> = <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
+typedef D<unrelated K extends core::Object* = dynamic> = <A extends core::Object* = dynamic>(core::int*) →* <B extends core::Object* = dynamic>(A*, K*, B*) →* core::int*;
static method producer<K extends core::Object* = dynamic>() → dynamic {
return <A extends core::Object* = dynamic>(core::int* v1) → <B extends core::Object* = dynamic>(A*, self::producer::K*, B*) →* core::int* {
return <B extends core::Object* = dynamic>(A* v2, self::producer::K* v3, B* v4) → core::int* => 0;
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
index e4d2c10..f28e322 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.outline.expect
@@ -2,25 +2,25 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Error: The implementation of 'foo' in the non-abstract class 'E' does not conform to its interface.
+// class E extends D {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Context: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
// foo(int x, {int y});
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
-// class E extends D {
-// ^
//
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Error: The implementation of 'foo' in the non-abstract class 'C' does not conform to its interface.
+// class C extends A implements B {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Context: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
// foo(int x, {int y}) => y;
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
index 6827b4c..b9e0bd5 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
@@ -2,25 +2,25 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Error: The implementation of 'foo' in the non-abstract class 'E' does not conform to its interface.
+// class E extends D {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Context: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
// foo(int x, {int y});
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
-// class E extends D {
-// ^
//
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Error: The implementation of 'foo' in the non-abstract class 'C' does not conform to its interface.
+// class C extends A implements B {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Context: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
// foo(int x, {int y}) => y;
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
index 6827b4c..b9e0bd5 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
@@ -2,25 +2,25 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Error: The implementation of 'foo' in the non-abstract class 'E' does not conform to its interface.
+// class E extends D {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Context: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
// foo(int x, {int y});
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
-// class E extends D {
-// ^
//
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Error: The implementation of 'foo' in the non-abstract class 'C' does not conform to its interface.
+// class C extends A implements B {
+// ^
+// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Context: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
// foo(int x) => x;
// ^
// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
// foo(int x, {int y}) => y;
// ^
-// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
-// class C extends A implements B {
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect
index e75c3f5..1e1f818 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect
index a570c3b..af9bd50 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect
index a570c3b..af9bd50 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.outline.expect
index e13202c..5c8b74d 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
index ce550cf..e3448ed 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
index ce550cf..e3448ed 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.outline.expect
index e0dbc15..1debb50 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.expect
index 45979f9..81ef72b 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect
index 45979f9..81ef72b 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.outline.expect
index e0dbc15..1debb50 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
index 77140dc..75a8771 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
index 77140dc..75a8771 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.outline.expect
index 20694a1..3ab6c88 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic> = () →* (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<unrelated T extends core::Object* = dynamic> = () →* (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void _x;
constructor •((self::C::T*) →* void _x) → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.expect
index 70de15e..b6cfaea 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic> = () →* (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<unrelated T extends core::Object* = dynamic> = () →* (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void _x;
constructor •((self::C::T*) →* void _x) → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect
index 70de15e..b6cfaea 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic> = () →* (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<unrelated T extends core::Object* = dynamic> = () →* (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void _x;
constructor •((self::C::T*) →* void _x) → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.outline.expect
index 1a27346..3f570d1 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.expect
index 98d67c0..4fe5da3 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect
index 98d67c0..4fe5da3 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
field (self::C::T*) →* void y = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.outline.expect
index a2ffb5b..7dbf41e 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.expect
index 20544dd..30b8696 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect
index 20544dd..30b8696 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.outline.expect
index a2ffb5b..7dbf41e 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
index b534829..2e4bee0 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
index b534829..2e4bee0 100644
--- a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.outline.expect
index 0362716..97dc71c 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect
index 80bd16a..eb2c2fb 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect
index 80bd16a..eb2c2fb 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-typedef G<T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+typedef G<contravariant T extends core::Object* = dynamic, U extends core::Object* = dynamic> = (T*) →* U*;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
index bbf9deb..015b873 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
;
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.expect
index c335d83..db6c80a 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect
index c335d83..db6c80a 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C extends core::Object {
synthetic constructor •() → self::C*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.outline.expect
index 8f154d7..f94fe8d 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field self::C::T* x;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.expect
index 771601a..60677cd 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field self::C::T* x = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect
index 771601a..60677cd 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
generic-covariant-impl field self::C::T* x = null;
synthetic constructor •() → self::C<self::C::T*>*
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
index 44e4b15..a300d04 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.expect
index 1bbff9a..023e6058 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect
index 1bbff9a..023e6058 100644
--- a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* dynamic;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* dynamic;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.outline.expect
index 3c7dca2..da8f309 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.outline.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (dynamic) →* void> extends core::Object {
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (core::Null?) →* void> extends core::Object {
synthetic constructor •() → self::B<self::B::T*, self::B::U*>*
;
operator +(dynamic other) → self::B<self::B::T*, (self::B::T*) →* void>*
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.expect
index 2eba38e..873a975 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (dynamic) →* void> extends core::Object {
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (core::Null?) →* void> extends core::Object {
synthetic constructor •() → self::B<self::B::T*, self::B::U*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect
index 2eba38e..873a975 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect
@@ -2,8 +2,8 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
-class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (dynamic) →* void> extends core::Object {
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
+class B<T extends core::Object* = dynamic, U extends (self::B::T*) →* void = (core::Null?) →* void> extends core::Object {
synthetic constructor •() → self::B<self::B::T*, self::B::U*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.outline.expect
index 49528d6..e778017 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
index 4a65ddd..26a02ad 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
@@ -29,7 +29,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
index 4a65ddd..26a02ad 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
@@ -29,7 +29,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.outline.expect
index cc2df81..f87990c 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
index 53d1c58..41e53d1 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
index 53d1c58..41e53d1 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class B<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::B<self::B::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.outline.expect
index 2a81a13..bf7f7d00 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.expect
index d4e90dc..a351f22 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect
index d4e90dc..a351f22 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-typedef F<T extends core::Object* = dynamic> = (T*) →* void;
+typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
synthetic constructor •() → self::C<self::C::T*>*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
index 45e4a38..f26c179 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.outline.expect
@@ -2,16 +2,16 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Error: The field 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'I.y'.
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:51:7: Error: The mixin application class 'C' introduces an erroneous override of 'y'.
+// class C = B with M implements I<int>;
+// ^
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Context: The field 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'I.y'.
// - 'Object' is from 'dart:core'.
// int y;
// ^
// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:43:12: Context: This is the overridden method ('y').
// void set y(covariant Object value);
// ^
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:51:7: Context: Override was introduced in the mixin application class 'C'.
-// class C = B with M implements I<int>;
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
index 9587cd5..5c70f1e 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
@@ -2,16 +2,16 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Error: The field 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'I.y'.
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:51:7: Error: The mixin application class 'C' introduces an erroneous override of 'y'.
+// class C = B with M implements I<int>;
+// ^
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Context: The field 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden setter, 'I.y'.
// - 'Object' is from 'dart:core'.
// int y;
// ^
// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:43:12: Context: This is the overridden method ('y').
// void set y(covariant Object value);
// ^
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:51:7: Context: Override was introduced in the mixin application class 'C'.
-// class C = B with M implements I<int>;
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
index e7cad7c..f230923 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.outline.expect
@@ -2,7 +2,10 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Error: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden method, 'I.y'.
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:58:7: Error: The mixin application class 'C' introduces an erroneous override of 'y'.
+// class C = B with M implements I<int>;
+// ^
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Context: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden method, 'I.y'.
// - 'Object' is from 'dart:core'.
// Change to a supertype of 'Object', or, for a covariant parameter, a subtype.
// void set y(int value) {
@@ -10,9 +13,6 @@
// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:43:12: Context: This is the overridden method ('y').
// void set y(covariant Object value);
// ^
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:58:7: Context: Override was introduced in the mixin application class 'C'.
-// class C = B with M implements I<int>;
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
index 067ee48..96c8e8b 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
@@ -2,7 +2,10 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Error: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden method, 'I.y'.
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:58:7: Error: The mixin application class 'C' introduces an erroneous override of 'y'.
+// class C = B with M implements I<int>;
+// ^
+// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Context: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type, 'Object', in the overridden method, 'I.y'.
// - 'Object' is from 'dart:core'.
// Change to a supertype of 'Object', or, for a covariant parameter, a subtype.
// void set y(int value) {
@@ -10,9 +13,6 @@
// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:43:12: Context: This is the overridden method ('y').
// void set y(covariant Object value);
// ^
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:58:7: Context: Override was introduced in the mixin application class 'C'.
-// class C = B with M implements I<int>;
-// ^
//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index c52e649..91148be 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -28,6 +28,8 @@
general/error_locations/error_location_01: RuntimeError
general/error_locations/error_location_02: RuntimeError
general/error_locations/error_location_03: RuntimeError
+general/error_locations/error_location_05: RuntimeError
+general/error_locations/error_location_06: RuntimeError
general/expressions: RuntimeError
general/external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
general/fallthrough: ExpectationFileMismatch
@@ -92,7 +94,6 @@
inference/mixin_inference_unification_1: TypeCheckError
inference/mixin_inference_unification_2: TypeCheckError
inference/override_equals: RuntimeError
-inference/unresolved_super: TypeCheckError
inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: InstrumentationMismatch # Issue #25824
inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1: InstrumentationMismatch # Issue #25824
inference_new/dependency_only_if_overloaded: TypeCheckError
@@ -146,8 +147,8 @@
rasta/super_initializer: RuntimeError
rasta/super_mixin: TypeCheckError
rasta/super_operator: TypeCheckError
-rasta/type_literals: Crash
-rasta/typedef: Crash
+rasta/type_literals: RuntimeError
+rasta/typedef: RuntimeError
rasta/unresolved: RuntimeError
rasta/unresolved_constructor: RuntimeError
rasta/unresolved_for_in: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 8d0e382..95610cc 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -6,19 +6,29 @@
# the round trip for Kernel textual serialization where the initial binary
# Kernel files are produced by compiling Dart code via Fasta.
+all_variances: TextSerializationFailure
expression/eval: TextSerializationFailure # Was: Pass
expression/main: TextSerializationFailure # Was: Pass
+extensions/annotations: TextSerializationFailure
extensions/compounds: TextSerializationFailure
+extensions/conflicts: TextSerializationFailure
+extensions/default_values: TextSerializationFailure
extensions/direct_instance_access: TextSerializationFailure
extensions/direct_static_access: TextSerializationFailure
+extensions/dynamic_invoke: TextSerializationFailure
extensions/explicit_extension_access: TextSerializationFailure
extensions/explicit_extension_inference: TextSerializationFailure
extensions/explicit_generic_extension_access: TextSerializationFailure
+extensions/explicit_invalid_access: TextSerializationFailure
extensions/explicit_this: TextSerializationFailure
extensions/extension_methods: TextSerializationFailure
+extensions/extension_setter: TextSerializationFailure
+extensions/getter_setter_conflict: TextSerializationFailure
+extensions/if_null: TextSerializationFailure
extensions/implicit_extension_inference: TextSerializationFailure
extensions/implicit_this: TextSerializationFailure
extensions/index: TextSerializationFailure
+extensions/internal_resolution: TextSerializationFailure
extensions/instance_access: TextSerializationFailure
extensions/instance_access_of_static: TextSerializationFailure
extensions/instance_members: TextSerializationFailure
@@ -26,6 +36,7 @@
extensions/invalid_explicit_access: TextSerializationFailure
extensions/nested_on_types: TextSerializationFailure
extensions/null_aware: TextSerializationFailure
+extensions/on_function_type: TextSerializationFailure
extensions/on_type_inference: TextSerializationFailure
extensions/on_type_variable_inference: TextSerializationFailure
extensions/operators: TextSerializationFailure
@@ -35,10 +46,7 @@
extensions/type_variables: TextSerializationFailure
extensions/unnamed_extensions: TextSerializationFailure
extensions/use_this: TextSerializationFailure
-general/error_locations/error_location_01: TextSerializationFailure
-general/error_locations/error_location_02: TextSerializationFailure
-general/error_locations/error_location_03: TextSerializationFailure
-general/error_locations/error_location_04: TextSerializationFailure
+general/DeltaBlue: TextSerializationFailure # Was: Pass
general/abstract_members: TypeCheckError
general/abstract_overrides_concrete_with_no_such_method: TextSerializationFailure
general/accessors: TextSerializationFailure # Was: RuntimeError
@@ -112,7 +120,6 @@
general/default_values: TextSerializationFailure # Was: Pass
general/deferred_lib: TextSerializationFailure # Was: Pass
general/deferred_type_annotation: TextSerializationFailure # Was: Pass
-general/DeltaBlue: TextSerializationFailure # Was: Pass
general/duplicated_bad_prefix: TextSerializationFailure # Was: Pass
general/duplicated_bad_prefix_lib1: TextSerializationFailure # Was: Pass
general/duplicated_bad_prefix_lib2: TextSerializationFailure # Was: Pass
@@ -122,6 +129,12 @@
general/duplicated_field_initializer: TextSerializationFailure # Was: RuntimeError
general/duplicated_named_args_3: TextSerializationFailure # Was: Pass
general/dynamic_and_void: InstrumentationMismatch # Test assumes Dart 1.0 semantics
+general/error_locations/error_location_01: TextSerializationFailure
+general/error_locations/error_location_02: TextSerializationFailure
+general/error_locations/error_location_03: TextSerializationFailure
+general/error_locations/error_location_04: TextSerializationFailure
+general/error_locations/error_location_05: TextSerializationFailure
+general/error_locations/error_location_06: TextSerializationFailure
general/escape: TextSerializationFailure # Was: Pass
general/export_main: TextSerializationFailure # Was: Pass
general/export_test: TextSerializationFailure # Was: Pass
@@ -194,6 +207,7 @@
general/non_covariant_checks: TextSerializationFailure
general/null_aware: TextSerializationFailure # Was: Pass
general/null_aware_for_in: TextSerializationFailure
+general/null_aware_postfix: TextSerializationFailure
general/operator_method_not_found: TextSerializationFailure
general/operators: TextSerializationFailure # Was: Pass
general/optional: TypeCheckError
@@ -254,9 +268,9 @@
general/top_level_accessors_part: TextSerializationFailure # Was: Pass
general/top_level_library_method: TextSerializationFailure # Was: Pass
general/type_of_null: TextSerializationFailure
-general/type_variable_bound_access: TypeCheckError
general/type_parameter_type_named_int: TextSerializationFailure
general/type_variable_as_super: TextSerializationFailure # Was: RuntimeError
+general/type_variable_bound_access: TypeCheckError
general/type_variable_prefix: TextSerializationFailure # Was: RuntimeError
general/type_variable_uses: TextSerializationFailure # Was: Pass
general/typedef: TextSerializationFailure # Was: Pass
@@ -681,7 +695,7 @@
inference/type_promotion_stopped_by_access_in_a_closure: TextSerializationFailure # Was: Pass
inference/type_promotion_stopped_by_assignment_in_scope: TextSerializationFailure # Was: Pass
inference/type_promotion_stopped_by_mutation_in_a_closure: TextSerializationFailure # Was: Pass
-inference/unresolved_super: TypeCheckError
+inference/unresolved_super: TextSerializationFailure
inference/unsafe_block_closure_inference_closure_call: TextSerializationFailure # Was: Pass
inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param: TextSerializationFailure # Was: Pass
inference/unsafe_block_closure_inference_constructor_call_explicit_type_param: TextSerializationFailure # Was: Pass
@@ -835,11 +849,14 @@
instantiate_to_bound/typedef_omitted_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_raw_in_bound: TextSerializationFailure # Was: Pass
instantiate_to_bound/typedef_super_bounded_type: TextSerializationFailure # Was: Pass
+nested_variance_test: TextSerializationFailure
new_const_insertion/simple: TextSerializationFailure # Was: Pass
nnbd/function_types: TextSerializationFailure
nnbd/late: TextSerializationFailure
+nnbd/null_check: TextSerializationFailure
nnbd/nullable_param: TextSerializationFailure
nnbd/required: TextSerializationFailure
+nnbd/type_parameter_types: TextSerializationFailure
no_such_method_forwarders/abstract_accessors_from_field: TextSerializationFailure # Was: Pass
no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in: TextSerializationFailure # Was: Pass
no_such_method_forwarders/abstract_accessors_from_field_one_defined: TextSerializationFailure # Was: Pass
@@ -939,9 +956,9 @@
rasta/switch_fall_through: TextSerializationFailure # Was: Pass
rasta/this_invoke: TextSerializationFailure # Was: Pass
rasta/try_label: TextSerializationFailure
-rasta/type_literals: Crash
+rasta/type_literals: TextSerializationFailure
rasta/type_with_parse_error: TextSerializationFailure # Was: Pass
-rasta/typedef: Crash
+rasta/typedef: TextSerializationFailure
rasta/unresolved: TextSerializationFailure # Was: RuntimeError
rasta/unresolved_constructor: TextSerializationFailure # Was: RuntimeError
rasta/unresolved_for_in: TextSerializationFailure # Was: RuntimeError
@@ -1089,10 +1106,11 @@
runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
-runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_covariantImpl_from_class: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_covariantImpl_from_interface: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_covariantImpl_from_super: TextSerializationFailure # Was: Pass
runtime_checks_new/stub_from_interface_covariantInterface_from_class: TextSerializationFailure # Was: Pass
+runtime_checks_new/stub_from_interface_covariant_from_interface: TextSerializationFailure # Was: Pass
+runtime_checks_new/stub_from_interface_covariant_from_super: TextSerializationFailure # Was: Pass
set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
+top_level_variance_test: TextSerializationFailure
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart b/pkg/front_end/testcases/top_level_variance_test.dart
new file mode 100644
index 0000000..ff36737
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart
@@ -0,0 +1,166 @@
+// Copyright (c) 2019, 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.
+
+// Testing that instantiate-to-bound and super-bounded types take the
+// variance of formal type parameters into account when a type alias is
+// used as a raw type.
+
+// Standard type comparison support.
+
+typedef F<X> = void Function<Y extends X>();
+F<X> toF<X>(X x) => null;
+
+// Material specific to this test.
+
+typedef Fcov<X> = X Function();
+typedef Fcon<X> = Function(X);
+typedef Finv<X> = X Function(X);
+
+typedef FcovBound<X extends num> = X Function();
+typedef FconBound<X extends num> = Function(X);
+typedef FinvBound<X extends num> = X Function(X);
+
+class A<X> {}
+
+typedef FcovCyclicBound<X extends A<X>> = X Function();
+typedef FconCyclicBound<X extends A<X>> = Function(X);
+typedef FinvCyclicBound<X extends A<X>> = X Function(X);
+
+typedef FcovCyclicCoBound<X extends Function(X)> = X Function();
+typedef FconCyclicCoBound<X extends Function(X)> = Function(X);
+typedef FinvCyclicCoBound<X extends Function(X)> = X Function(X);
+
+class B<X> {}
+
+void testTopLevel() {
+ // I2b initial value for a covariant type parameter w/o bound: dynamic.
+ Fcov source1;
+ var fsource1 = toF(source1);
+ F<Fcov<dynamic>> target1 = fsource1;
+
+ // I2b initial value for a contravariant type parameter w/o bound: dynamic.
+ Fcon source2;
+ var fsource2 = toF(source2);
+ F<Fcon<dynamic>> target2 = fsource2;
+
+ // I2b initial value for an invariant type parameter w/o bound: dynamic.
+ Finv source3;
+ var fsource3 = toF(source3);
+ F<Finv<dynamic>> target3 = fsource3;
+
+ // I2b initial value for a covariant type parameter: bound.
+ FcovBound source4;
+ var fsource4 = toF(source4);
+ F<FcovBound<num>> target4 = fsource4;
+
+ // I2b initial value for a contravariant type parameter: bound.
+ FconBound source5;
+ var fsource5 = toF(source5);
+ F<FconBound<num>> target5 = fsource5;
+
+ // I2b initial value for an invariant type parameter: bound.
+ FinvBound source6;
+ var fsource6 = toF(source6);
+ F<FinvBound<num>> target6 = fsource6;
+
+ // I2b for a covariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing covariant occurrence by `dynamic`. Resulting type
+ // is super-bounded: FcovCyclicBound<A<Null>> is regular-bounded.
+ FcovCyclicBound source7;
+ var fsource7 = toF(source7);
+ F<FcovCyclicBound<A<dynamic>>> target7 = fsource7;
+
+ // I2b for a contravariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing contravariant occurrence by `Null`. Resulting type
+ // is super-bounded: FconCyclicBound<A<Object>> is regular-bounded.
+ FconCyclicBound source8;
+ var fsource8 = toF(source8);
+ F<FconCyclicBound<A<Null>>> target8 = fsource8;
+
+ // I2b for an invariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing invariant occurrence by `dynamic`. Resulting type is
+ // _not_ super-bounded: FinvCyclicBound<A<dynamic>> not regular-bounded.
+ FinvCyclicBound source9; //# 01: compile-time error
+ // var fsource9 = toF(source9);
+ // F<FinvCyclicBound<A<dynamic>>> target9 = fsource9;
+
+ // I2b for a covariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing contravariant occurrence by `Null`. Resulting type
+ // is super-bounded: FcovCyclicBound<Function(Object)> is regular-bounded.
+ FcovCyclicCoBound source10;
+ var fsource10 = toF(source10);
+ F<FcovCyclicCoBound<Function(Null)>> target10 = fsource10;
+
+ // I2b for a contravariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing covariant occurrence by `dynamic`. Resulting type
+ // FconCyclicCoBound<Function(dynamic)> is regular-bounded.
+ FconCyclicCoBound source11;
+ var fsource11 = toF(source11);
+ F<FconCyclicCoBound<Function(dynamic)>> target11 = fsource11;
+
+ // I2b for an invariant type parameter w F-bound: Use bound, then break
+ // cycle by replacing invariant occurrence by `dynamic`. Resulting type
+ // F<FinvCyclicCoBound<Function(dynamic)>> is regular-bounded.
+ FinvCyclicCoBound source12;
+ var fsource12 = toF(source12);
+ F<FinvCyclicCoBound<Function(dynamic)>> target12 = fsource12;
+}
+
+void testNested() {
+ // Everything gets the same treatment when the cases from
+ // `testTopLevel` are duplicated at the nested level.
+
+ B<Fcov> source1;
+ var fsource1 = toF(source1);
+ F<B<Fcov<dynamic>>> target1 = fsource1;
+
+ B<Fcon> source2;
+ var fsource2 = toF(source2);
+ F<B<Fcon<dynamic>>> target2 = fsource2;
+
+ B<Finv> source3;
+ var fsource3 = toF(source3);
+ F<B<Finv<dynamic>>> target3 = fsource3;
+
+ B<FcovBound> source4;
+ var fsource4 = toF(source4);
+ F<B<FcovBound<num>>> target4 = fsource4;
+
+ B<FconBound> source5;
+ var fsource5 = toF(source5);
+ F<B<FconBound<num>>> target5 = fsource5;
+
+ B<FinvBound> source6;
+ var fsource6 = toF(source6);
+ F<B<FinvBound<num>>> target6 = fsource6;
+
+ B<FcovCyclicBound> source7;
+ var fsource7 = toF(source7);
+ F<B<FcovCyclicBound<A<dynamic>>>> target7 = fsource7;
+
+ B<FconCyclicBound> source8;
+ var fsource8 = toF(source8);
+ F<B<FconCyclicBound<A<Null>>>> target8 = fsource8;
+
+ B<FinvCyclicBound> source9; //# 02: compile-time error
+ // var fsource9 = toF(source9);
+ // F<B<FinvCyclicBound<A<dynamic>>>> target9 = fsource9;
+
+ B<FcovCyclicCoBound> source10;
+ var fsource10 = toF(source10);
+ F<B<FcovCyclicCoBound<Function(Null)>>> target10 = fsource10;
+
+ B<FconCyclicCoBound> source11;
+ var fsource11 = toF(source11);
+ F<B<FconCyclicCoBound<Function(dynamic)>>> target11 = fsource11;
+
+ B<FinvCyclicCoBound> source12;
+ var fsource12 = toF(source12);
+ F<B<FinvCyclicCoBound<Function(dynamic)>>> target12 = fsource12;
+}
+
+main() {
+ testTopLevel();
+ testNested();
+}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.hierarchy.expect b/pkg/front_end/testcases/top_level_variance_test.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.legacy.expect b/pkg/front_end/testcases/top_level_variance_test.dart.legacy.expect
new file mode 100644
index 0000000..32ef6e6
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.legacy.expect
@@ -0,0 +1,105 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object = dynamic> = <Y extends X = dynamic>() → void;
+typedef Fcov<X extends core::Object = dynamic> = () → X;
+typedef Fcon<contravariant X extends core::Object = dynamic> = (X) → dynamic;
+typedef Finv<invariant X extends core::Object = dynamic> = (X) → X;
+typedef FcovBound<X extends core::num = dynamic> = () → X;
+typedef FconBound<contravariant X extends core::num = dynamic> = (X) → dynamic;
+typedef FinvBound<invariant X extends core::num = dynamic> = (X) → X;
+typedef FcovCyclicBound<X extends self::A<X> = dynamic> = () → X;
+typedef FconCyclicBound<contravariant X extends self::A<X> = dynamic> = (X) → dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X> = dynamic> = (X) → X;
+typedef FcovCyclicCoBound<X extends (X) → dynamic = dynamic> = () → X;
+typedef FconCyclicCoBound<contravariant X extends (X) → dynamic = dynamic> = (X) → dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X) → dynamic = dynamic> = (X) → X;
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X>
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object = dynamic>(self::toF::X x) → <Y extends self::toF::X = dynamic>() → void
+ return null;
+static method testTopLevel() → void {
+ () → dynamic source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends () → dynamic = dynamic>() → void target1 = fsource1;
+ (dynamic) → dynamic source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends (dynamic) → dynamic = dynamic>() → void target2 = fsource2;
+ (dynamic) → dynamic source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends (dynamic) → dynamic = dynamic>() → void target3 = fsource3;
+ () → dynamic source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends () → core::num = dynamic>() → void target4 = fsource4;
+ (dynamic) → dynamic source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends (core::num) → dynamic = dynamic>() → void target5 = fsource5;
+ (dynamic) → dynamic source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends (core::num) → core::num = dynamic>() → void target6 = fsource6;
+ () → dynamic source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends () → self::A<dynamic> = dynamic>() → void target7 = fsource7;
+ (dynamic) → dynamic source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends (self::A<core::Null>) → dynamic = dynamic>() → void target8 = fsource8;
+ (dynamic) → dynamic source9;
+ () → dynamic source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends () → (core::Null) → dynamic = dynamic>() → void target10 = fsource10;
+ (dynamic) → dynamic source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends ((dynamic) → dynamic) → dynamic = dynamic>() → void target11 = fsource11;
+ (dynamic) → dynamic source12;
+ dynamic fsource12 = self::toF<dynamic>(source12);
+ <Y extends ((dynamic) → dynamic) → (dynamic) → dynamic = dynamic>() → void target12 = fsource12;
+}
+static method testNested() → void {
+ self::B<() → dynamic> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::B<() → dynamic> = dynamic>() → void target1 = fsource1;
+ self::B<(dynamic) → dynamic> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::B<(dynamic) → dynamic> = dynamic>() → void target2 = fsource2;
+ self::B<(dynamic) → dynamic> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::B<(dynamic) → dynamic> = dynamic>() → void target3 = fsource3;
+ self::B<() → dynamic> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::B<() → core::num> = dynamic>() → void target4 = fsource4;
+ self::B<(dynamic) → dynamic> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::B<(core::num) → dynamic> = dynamic>() → void target5 = fsource5;
+ self::B<(dynamic) → dynamic> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::B<(core::num) → core::num> = dynamic>() → void target6 = fsource6;
+ self::B<() → dynamic> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::B<() → self::A<dynamic>> = dynamic>() → void target7 = fsource7;
+ self::B<(dynamic) → dynamic> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::B<(self::A<core::Null>) → dynamic> = dynamic>() → void target8 = fsource8;
+ self::B<(dynamic) → dynamic> source9;
+ self::B<() → dynamic> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::B<() → (core::Null) → dynamic> = dynamic>() → void target10 = fsource10;
+ self::B<(dynamic) → dynamic> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::B<((dynamic) → dynamic) → dynamic> = dynamic>() → void target11 = fsource11;
+ self::B<(dynamic) → dynamic> source12;
+ dynamic fsource12 = self::toF<dynamic>(source12);
+ <Y extends self::B<((dynamic) → dynamic) → (dynamic) → dynamic> = dynamic>() → void target12 = fsource12;
+}
+static method main() → dynamic {
+ self::testTopLevel();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.legacy.transformed.expect b/pkg/front_end/testcases/top_level_variance_test.dart.legacy.transformed.expect
new file mode 100644
index 0000000..32ef6e6
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.legacy.transformed.expect
@@ -0,0 +1,105 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object = dynamic> = <Y extends X = dynamic>() → void;
+typedef Fcov<X extends core::Object = dynamic> = () → X;
+typedef Fcon<contravariant X extends core::Object = dynamic> = (X) → dynamic;
+typedef Finv<invariant X extends core::Object = dynamic> = (X) → X;
+typedef FcovBound<X extends core::num = dynamic> = () → X;
+typedef FconBound<contravariant X extends core::num = dynamic> = (X) → dynamic;
+typedef FinvBound<invariant X extends core::num = dynamic> = (X) → X;
+typedef FcovCyclicBound<X extends self::A<X> = dynamic> = () → X;
+typedef FconCyclicBound<contravariant X extends self::A<X> = dynamic> = (X) → dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X> = dynamic> = (X) → X;
+typedef FcovCyclicCoBound<X extends (X) → dynamic = dynamic> = () → X;
+typedef FconCyclicCoBound<contravariant X extends (X) → dynamic = dynamic> = (X) → dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X) → dynamic = dynamic> = (X) → X;
+class A<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X>
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object = dynamic>(self::toF::X x) → <Y extends self::toF::X = dynamic>() → void
+ return null;
+static method testTopLevel() → void {
+ () → dynamic source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends () → dynamic = dynamic>() → void target1 = fsource1;
+ (dynamic) → dynamic source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends (dynamic) → dynamic = dynamic>() → void target2 = fsource2;
+ (dynamic) → dynamic source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends (dynamic) → dynamic = dynamic>() → void target3 = fsource3;
+ () → dynamic source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends () → core::num = dynamic>() → void target4 = fsource4;
+ (dynamic) → dynamic source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends (core::num) → dynamic = dynamic>() → void target5 = fsource5;
+ (dynamic) → dynamic source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends (core::num) → core::num = dynamic>() → void target6 = fsource6;
+ () → dynamic source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends () → self::A<dynamic> = dynamic>() → void target7 = fsource7;
+ (dynamic) → dynamic source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends (self::A<core::Null>) → dynamic = dynamic>() → void target8 = fsource8;
+ (dynamic) → dynamic source9;
+ () → dynamic source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends () → (core::Null) → dynamic = dynamic>() → void target10 = fsource10;
+ (dynamic) → dynamic source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends ((dynamic) → dynamic) → dynamic = dynamic>() → void target11 = fsource11;
+ (dynamic) → dynamic source12;
+ dynamic fsource12 = self::toF<dynamic>(source12);
+ <Y extends ((dynamic) → dynamic) → (dynamic) → dynamic = dynamic>() → void target12 = fsource12;
+}
+static method testNested() → void {
+ self::B<() → dynamic> source1;
+ dynamic fsource1 = self::toF<dynamic>(source1);
+ <Y extends self::B<() → dynamic> = dynamic>() → void target1 = fsource1;
+ self::B<(dynamic) → dynamic> source2;
+ dynamic fsource2 = self::toF<dynamic>(source2);
+ <Y extends self::B<(dynamic) → dynamic> = dynamic>() → void target2 = fsource2;
+ self::B<(dynamic) → dynamic> source3;
+ dynamic fsource3 = self::toF<dynamic>(source3);
+ <Y extends self::B<(dynamic) → dynamic> = dynamic>() → void target3 = fsource3;
+ self::B<() → dynamic> source4;
+ dynamic fsource4 = self::toF<dynamic>(source4);
+ <Y extends self::B<() → core::num> = dynamic>() → void target4 = fsource4;
+ self::B<(dynamic) → dynamic> source5;
+ dynamic fsource5 = self::toF<dynamic>(source5);
+ <Y extends self::B<(core::num) → dynamic> = dynamic>() → void target5 = fsource5;
+ self::B<(dynamic) → dynamic> source6;
+ dynamic fsource6 = self::toF<dynamic>(source6);
+ <Y extends self::B<(core::num) → core::num> = dynamic>() → void target6 = fsource6;
+ self::B<() → dynamic> source7;
+ dynamic fsource7 = self::toF<dynamic>(source7);
+ <Y extends self::B<() → self::A<dynamic>> = dynamic>() → void target7 = fsource7;
+ self::B<(dynamic) → dynamic> source8;
+ dynamic fsource8 = self::toF<dynamic>(source8);
+ <Y extends self::B<(self::A<core::Null>) → dynamic> = dynamic>() → void target8 = fsource8;
+ self::B<(dynamic) → dynamic> source9;
+ self::B<() → dynamic> source10;
+ dynamic fsource10 = self::toF<dynamic>(source10);
+ <Y extends self::B<() → (core::Null) → dynamic> = dynamic>() → void target10 = fsource10;
+ self::B<(dynamic) → dynamic> source11;
+ dynamic fsource11 = self::toF<dynamic>(source11);
+ <Y extends self::B<((dynamic) → dynamic) → dynamic> = dynamic>() → void target11 = fsource11;
+ self::B<(dynamic) → dynamic> source12;
+ dynamic fsource12 = self::toF<dynamic>(source12);
+ <Y extends self::B<((dynamic) → dynamic) → (dynamic) → dynamic> = dynamic>() → void target12 = fsource12;
+}
+static method main() → dynamic {
+ self::testTopLevel();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.outline.expect b/pkg/front_end/testcases/top_level_variance_test.dart.outline.expect
new file mode 100644
index 0000000..e6c10ea
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.outline.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ ;
+static method testTopLevel() → void
+ ;
+static method testNested() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.strong.expect b/pkg/front_end/testcases/top_level_variance_test.dart.strong.expect
new file mode 100644
index 0000000..28ca428
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.strong.expect
@@ -0,0 +1,105 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ return null;
+static method testTopLevel() → void {
+ () →* dynamic source1;
+ <Y extends () →* dynamic = dynamic>() →* void fsource1 = self::toF<() →* dynamic>(source1);
+ <Y extends () →* dynamic = dynamic>() →* void target1 = fsource1;
+ (dynamic) →* dynamic source2;
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void fsource2 = self::toF<(dynamic) →* dynamic>(source2);
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void target2 = fsource2;
+ (dynamic) →* dynamic source3;
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void fsource3 = self::toF<(dynamic) →* dynamic>(source3);
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void target3 = fsource3;
+ () →* core::num* source4;
+ <Y extends () →* core::num* = dynamic>() →* void fsource4 = self::toF<() →* core::num*>(source4);
+ <Y extends () →* core::num* = dynamic>() →* void target4 = fsource4;
+ (core::num*) →* dynamic source5;
+ <Y extends (core::num*) →* dynamic = dynamic>() →* void fsource5 = self::toF<(core::num*) →* dynamic>(source5);
+ <Y extends (core::num*) →* dynamic = dynamic>() →* void target5 = fsource5;
+ (core::num*) →* core::num* source6;
+ <Y extends (core::num*) →* core::num* = dynamic>() →* void fsource6 = self::toF<(core::num*) →* core::num*>(source6);
+ <Y extends (core::num*) →* core::num* = dynamic>() →* void target6 = fsource6;
+ () →* self::A<dynamic>* source7;
+ <Y extends () →* self::A<dynamic>* = dynamic>() →* void fsource7 = self::toF<() →* self::A<dynamic>*>(source7);
+ <Y extends () →* self::A<dynamic>* = dynamic>() →* void target7 = fsource7;
+ (self::A<core::Null?>*) →* dynamic source8;
+ <Y extends (self::A<core::Null?>*) →* dynamic = dynamic>() →* void fsource8 = self::toF<(self::A<core::Null?>*) →* dynamic>(source8);
+ <Y extends (self::A<core::Null*>*) →* dynamic = dynamic>() →* void target8 = fsource8;
+ (self::A<dynamic>*) →* self::A<dynamic>* source9;
+ () →* (core::Null?) →* dynamic source10;
+ <Y extends () →* (core::Null?) →* dynamic = dynamic>() →* void fsource10 = self::toF<() →* (core::Null?) →* dynamic>(source10);
+ <Y extends () →* (core::Null*) →* dynamic = dynamic>() →* void target10 = fsource10;
+ ((dynamic) →* dynamic) →* dynamic source11;
+ <Y extends ((dynamic) →* dynamic) →* dynamic = dynamic>() →* void fsource11 = self::toF<((dynamic) →* dynamic) →* dynamic>(source11);
+ <Y extends ((dynamic) →* dynamic) →* dynamic = dynamic>() →* void target11 = fsource11;
+ ((dynamic) →* dynamic) →* (dynamic) →* dynamic source12;
+ <Y extends ((dynamic) →* dynamic) →* (dynamic) →* dynamic = dynamic>() →* void fsource12 = self::toF<((dynamic) →* dynamic) →* (dynamic) →* dynamic>(source12);
+ <Y extends ((dynamic) →* dynamic) →* (dynamic) →* dynamic = dynamic>() →* void target12 = fsource12;
+}
+static method testNested() → void {
+ self::B<() →* dynamic>* source1;
+ <Y extends self::B<() →* dynamic>* = dynamic>() →* void fsource1 = self::toF<self::B<() →* dynamic>*>(source1);
+ <Y extends self::B<() →* dynamic>* = dynamic>() →* void target1 = fsource1;
+ self::B<(dynamic) →* dynamic>* source2;
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void fsource2 = self::toF<self::B<(dynamic) →* dynamic>*>(source2);
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void target2 = fsource2;
+ self::B<(dynamic) →* dynamic>* source3;
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void fsource3 = self::toF<self::B<(dynamic) →* dynamic>*>(source3);
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void target3 = fsource3;
+ self::B<() →* core::num*>* source4;
+ <Y extends self::B<() →* core::num*>* = dynamic>() →* void fsource4 = self::toF<self::B<() →* core::num*>*>(source4);
+ <Y extends self::B<() →* core::num*>* = dynamic>() →* void target4 = fsource4;
+ self::B<(core::num*) →* dynamic>* source5;
+ <Y extends self::B<(core::num*) →* dynamic>* = dynamic>() →* void fsource5 = self::toF<self::B<(core::num*) →* dynamic>*>(source5);
+ <Y extends self::B<(core::num*) →* dynamic>* = dynamic>() →* void target5 = fsource5;
+ self::B<(core::num*) →* core::num*>* source6;
+ <Y extends self::B<(core::num*) →* core::num*>* = dynamic>() →* void fsource6 = self::toF<self::B<(core::num*) →* core::num*>*>(source6);
+ <Y extends self::B<(core::num*) →* core::num*>* = dynamic>() →* void target6 = fsource6;
+ self::B<() →* self::A<dynamic>*>* source7;
+ <Y extends self::B<() →* self::A<dynamic>*>* = dynamic>() →* void fsource7 = self::toF<self::B<() →* self::A<dynamic>*>*>(source7);
+ <Y extends self::B<() →* self::A<dynamic>*>* = dynamic>() →* void target7 = fsource7;
+ self::B<(self::A<core::Null?>*) →* dynamic>* source8;
+ <Y extends self::B<(self::A<core::Null?>*) →* dynamic>* = dynamic>() →* void fsource8 = self::toF<self::B<(self::A<core::Null?>*) →* dynamic>*>(source8);
+ <Y extends self::B<(self::A<core::Null*>*) →* dynamic>* = dynamic>() →* void target8 = fsource8;
+ self::B<(self::A<dynamic>*) →* self::A<dynamic>*>* source9;
+ self::B<() →* (core::Null?) →* dynamic>* source10;
+ <Y extends self::B<() →* (core::Null?) →* dynamic>* = dynamic>() →* void fsource10 = self::toF<self::B<() →* (core::Null?) →* dynamic>*>(source10);
+ <Y extends self::B<() →* (core::Null*) →* dynamic>* = dynamic>() →* void target10 = fsource10;
+ self::B<((dynamic) →* dynamic) →* dynamic>* source11;
+ <Y extends self::B<((dynamic) →* dynamic) →* dynamic>* = dynamic>() →* void fsource11 = self::toF<self::B<((dynamic) →* dynamic) →* dynamic>*>(source11);
+ <Y extends self::B<((dynamic) →* dynamic) →* dynamic>* = dynamic>() →* void target11 = fsource11;
+ self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* source12;
+ <Y extends self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* = dynamic>() →* void fsource12 = self::toF<self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>*>(source12);
+ <Y extends self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* = dynamic>() →* void target12 = fsource12;
+}
+static method main() → dynamic {
+ self::testTopLevel();
+ self::testNested();
+}
diff --git a/pkg/front_end/testcases/top_level_variance_test.dart.strong.transformed.expect b/pkg/front_end/testcases/top_level_variance_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..28ca428
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_variance_test.dart.strong.transformed.expect
@@ -0,0 +1,105 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef F<invariant X extends core::Object* = dynamic> = <Y extends X* = dynamic>() →* void;
+typedef Fcov<X extends core::Object* = dynamic> = () →* X*;
+typedef Fcon<contravariant X extends core::Object* = dynamic> = (X*) →* dynamic;
+typedef Finv<invariant X extends core::Object* = dynamic> = (X*) →* X*;
+typedef FcovBound<X extends core::num* = core::num*> = () →* X*;
+typedef FconBound<contravariant X extends core::num* = core::num*> = (X*) →* dynamic;
+typedef FinvBound<invariant X extends core::num* = core::num*> = (X*) →* X*;
+typedef FcovCyclicBound<X extends self::A<X*>* = self::A<dynamic>*> = () →* X*;
+typedef FconCyclicBound<contravariant X extends self::A<X*>* = self::A<core::Null?>*> = (X*) →* dynamic;
+typedef FinvCyclicBound<invariant X extends self::A<X*>* = self::A<dynamic>*> = (X*) →* X*;
+typedef FcovCyclicCoBound<X extends (X*) →* dynamic = (core::Null?) →* dynamic> = () →* X*;
+typedef FconCyclicCoBound<contravariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* dynamic;
+typedef FinvCyclicCoBound<invariant X extends (X*) →* dynamic = (dynamic) →* dynamic> = (X*) →* X*;
+class A<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X*>*
+ : super core::Object::•()
+ ;
+}
+class B<X extends core::Object* = dynamic> extends core::Object {
+ synthetic constructor •() → self::B<self::B::X*>*
+ : super core::Object::•()
+ ;
+}
+static method toF<X extends core::Object* = dynamic>(self::toF::X* x) → <Y extends self::toF::X* = dynamic>() →* void
+ return null;
+static method testTopLevel() → void {
+ () →* dynamic source1;
+ <Y extends () →* dynamic = dynamic>() →* void fsource1 = self::toF<() →* dynamic>(source1);
+ <Y extends () →* dynamic = dynamic>() →* void target1 = fsource1;
+ (dynamic) →* dynamic source2;
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void fsource2 = self::toF<(dynamic) →* dynamic>(source2);
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void target2 = fsource2;
+ (dynamic) →* dynamic source3;
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void fsource3 = self::toF<(dynamic) →* dynamic>(source3);
+ <Y extends (dynamic) →* dynamic = dynamic>() →* void target3 = fsource3;
+ () →* core::num* source4;
+ <Y extends () →* core::num* = dynamic>() →* void fsource4 = self::toF<() →* core::num*>(source4);
+ <Y extends () →* core::num* = dynamic>() →* void target4 = fsource4;
+ (core::num*) →* dynamic source5;
+ <Y extends (core::num*) →* dynamic = dynamic>() →* void fsource5 = self::toF<(core::num*) →* dynamic>(source5);
+ <Y extends (core::num*) →* dynamic = dynamic>() →* void target5 = fsource5;
+ (core::num*) →* core::num* source6;
+ <Y extends (core::num*) →* core::num* = dynamic>() →* void fsource6 = self::toF<(core::num*) →* core::num*>(source6);
+ <Y extends (core::num*) →* core::num* = dynamic>() →* void target6 = fsource6;
+ () →* self::A<dynamic>* source7;
+ <Y extends () →* self::A<dynamic>* = dynamic>() →* void fsource7 = self::toF<() →* self::A<dynamic>*>(source7);
+ <Y extends () →* self::A<dynamic>* = dynamic>() →* void target7 = fsource7;
+ (self::A<core::Null?>*) →* dynamic source8;
+ <Y extends (self::A<core::Null?>*) →* dynamic = dynamic>() →* void fsource8 = self::toF<(self::A<core::Null?>*) →* dynamic>(source8);
+ <Y extends (self::A<core::Null*>*) →* dynamic = dynamic>() →* void target8 = fsource8;
+ (self::A<dynamic>*) →* self::A<dynamic>* source9;
+ () →* (core::Null?) →* dynamic source10;
+ <Y extends () →* (core::Null?) →* dynamic = dynamic>() →* void fsource10 = self::toF<() →* (core::Null?) →* dynamic>(source10);
+ <Y extends () →* (core::Null*) →* dynamic = dynamic>() →* void target10 = fsource10;
+ ((dynamic) →* dynamic) →* dynamic source11;
+ <Y extends ((dynamic) →* dynamic) →* dynamic = dynamic>() →* void fsource11 = self::toF<((dynamic) →* dynamic) →* dynamic>(source11);
+ <Y extends ((dynamic) →* dynamic) →* dynamic = dynamic>() →* void target11 = fsource11;
+ ((dynamic) →* dynamic) →* (dynamic) →* dynamic source12;
+ <Y extends ((dynamic) →* dynamic) →* (dynamic) →* dynamic = dynamic>() →* void fsource12 = self::toF<((dynamic) →* dynamic) →* (dynamic) →* dynamic>(source12);
+ <Y extends ((dynamic) →* dynamic) →* (dynamic) →* dynamic = dynamic>() →* void target12 = fsource12;
+}
+static method testNested() → void {
+ self::B<() →* dynamic>* source1;
+ <Y extends self::B<() →* dynamic>* = dynamic>() →* void fsource1 = self::toF<self::B<() →* dynamic>*>(source1);
+ <Y extends self::B<() →* dynamic>* = dynamic>() →* void target1 = fsource1;
+ self::B<(dynamic) →* dynamic>* source2;
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void fsource2 = self::toF<self::B<(dynamic) →* dynamic>*>(source2);
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void target2 = fsource2;
+ self::B<(dynamic) →* dynamic>* source3;
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void fsource3 = self::toF<self::B<(dynamic) →* dynamic>*>(source3);
+ <Y extends self::B<(dynamic) →* dynamic>* = dynamic>() →* void target3 = fsource3;
+ self::B<() →* core::num*>* source4;
+ <Y extends self::B<() →* core::num*>* = dynamic>() →* void fsource4 = self::toF<self::B<() →* core::num*>*>(source4);
+ <Y extends self::B<() →* core::num*>* = dynamic>() →* void target4 = fsource4;
+ self::B<(core::num*) →* dynamic>* source5;
+ <Y extends self::B<(core::num*) →* dynamic>* = dynamic>() →* void fsource5 = self::toF<self::B<(core::num*) →* dynamic>*>(source5);
+ <Y extends self::B<(core::num*) →* dynamic>* = dynamic>() →* void target5 = fsource5;
+ self::B<(core::num*) →* core::num*>* source6;
+ <Y extends self::B<(core::num*) →* core::num*>* = dynamic>() →* void fsource6 = self::toF<self::B<(core::num*) →* core::num*>*>(source6);
+ <Y extends self::B<(core::num*) →* core::num*>* = dynamic>() →* void target6 = fsource6;
+ self::B<() →* self::A<dynamic>*>* source7;
+ <Y extends self::B<() →* self::A<dynamic>*>* = dynamic>() →* void fsource7 = self::toF<self::B<() →* self::A<dynamic>*>*>(source7);
+ <Y extends self::B<() →* self::A<dynamic>*>* = dynamic>() →* void target7 = fsource7;
+ self::B<(self::A<core::Null?>*) →* dynamic>* source8;
+ <Y extends self::B<(self::A<core::Null?>*) →* dynamic>* = dynamic>() →* void fsource8 = self::toF<self::B<(self::A<core::Null?>*) →* dynamic>*>(source8);
+ <Y extends self::B<(self::A<core::Null*>*) →* dynamic>* = dynamic>() →* void target8 = fsource8;
+ self::B<(self::A<dynamic>*) →* self::A<dynamic>*>* source9;
+ self::B<() →* (core::Null?) →* dynamic>* source10;
+ <Y extends self::B<() →* (core::Null?) →* dynamic>* = dynamic>() →* void fsource10 = self::toF<self::B<() →* (core::Null?) →* dynamic>*>(source10);
+ <Y extends self::B<() →* (core::Null*) →* dynamic>* = dynamic>() →* void target10 = fsource10;
+ self::B<((dynamic) →* dynamic) →* dynamic>* source11;
+ <Y extends self::B<((dynamic) →* dynamic) →* dynamic>* = dynamic>() →* void fsource11 = self::toF<self::B<((dynamic) →* dynamic) →* dynamic>*>(source11);
+ <Y extends self::B<((dynamic) →* dynamic) →* dynamic>* = dynamic>() →* void target11 = fsource11;
+ self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* source12;
+ <Y extends self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* = dynamic>() →* void fsource12 = self::toF<self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>*>(source12);
+ <Y extends self::B<((dynamic) →* dynamic) →* (dynamic) →* dynamic>* = dynamic>() →* void target12 = fsource12;
+}
+static method main() → dynamic {
+ self::testTopLevel();
+ self::testNested();
+}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index f9178e3..4fb21cc 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -18,7 +18,9 @@
import 'package:kernel/type_environment.dart' show SubtypeTester;
-import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+import 'package:vm/bytecode/gen_bytecode.dart'
+ show createFreshComponentWithBytecode, generateBytecode;
+
import 'package:vm/bytecode/options.dart' show BytecodeOptions;
import 'package:front_end/src/api_prototype/compiler_options.dart'
@@ -330,16 +332,18 @@
new File.fromUri(outlineOutput).writeAsBytesSync(result.summary);
c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
+ Component component = result.component;
if (c.options.bytecode) {
- generateBytecode(result.component,
+ generateBytecode(component,
options: new BytecodeOptions(
enableAsserts: true,
emitSourceFiles: true,
emitSourcePositions: true,
environmentDefines: c.options.environmentDefines));
+ component = createFreshComponentWithBytecode(component);
}
- await writeComponentToFile(result.component, fullOutput,
+ await writeComponentToFile(component, fullOutput,
filter: (lib) => !lib.isExternal);
c.options.ticker.logMs("Wrote component to ${fullOutput.toFilePath()}");
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 337d47d..5152615 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -143,7 +143,7 @@
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
- UInt32 formatVersion = 32;
+ UInt32 formatVersion = 33;
List<String> problemsAsJson; // Described in problems.md.
Library[] libraries;
UriSource sourceMap;
@@ -703,6 +703,12 @@
Expression operand;
}
+type NullCheck extends Expression {
+ Byte tag = 117;
+ FileOffset fileOffset;
+ Expression operand;
+}
+
/*
enum LogicalOperator { &&, || }
*/
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ae961e9..1f1835c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -2739,9 +2739,9 @@
// Treat the properties of Object specially.
String nameString = name.name;
if (nameString == 'hashCode') {
- return types.intType;
+ return types.coreTypes.intLegacyRawType;
} else if (nameString == 'runtimeType') {
- return types.typeType;
+ return types.coreTypes.typeLegacyRawType;
}
return const DynamicType();
}
@@ -3257,7 +3257,7 @@
}
if (name.name == '==') {
// We use this special case to simplify generation of '==' checks.
- return types.boolType;
+ return types.coreTypes.boolLegacyRawType;
}
return const DynamicType();
}
@@ -3497,7 +3497,8 @@
operand?.parent = this;
}
- DartType getStaticType(TypeEnvironment types) => types.boolType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.boolLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitNot(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) => v.visitNot(this, arg);
@@ -3525,7 +3526,8 @@
right?.parent = this;
}
- DartType getStaticType(TypeEnvironment types) => types.boolType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.boolLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitLogicalExpression(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3610,7 +3612,8 @@
setParents(expressions, this);
}
- DartType getStaticType(TypeEnvironment types) => types.stringType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.stringLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitStringConcatenation(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3838,7 +3841,8 @@
operand?.parent = this;
}
- DartType getStaticType(TypeEnvironment types) => types.boolType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.boolLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitIsExpression(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3901,6 +3905,37 @@
}
}
+/// Null check expression of form `x!`.
+///
+/// This expression was added as part of NNBD and is currently only created when
+/// the 'non-nullable' experimental feature is enabled.
+class NullCheck extends Expression {
+ Expression operand;
+
+ NullCheck(this.operand) {
+ operand?.parent = this;
+ }
+
+ DartType getStaticType(TypeEnvironment types) =>
+ // TODO(johnniwinther): Return `NonNull(operand.getStaticType(types))`.
+ operand.getStaticType(types);
+
+ R accept<R>(ExpressionVisitor<R> v) => v.visitNullCheck(this);
+ R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
+ v.visitNullCheck(this, arg);
+
+ visitChildren(Visitor v) {
+ operand?.accept(v);
+ }
+
+ transformChildren(Transformer v) {
+ if (operand != null) {
+ operand = operand.accept<TreeNode>(v);
+ operand?.parent = this;
+ }
+ }
+}
+
/// An integer, double, boolean, string, or null constant.
abstract class BasicLiteral extends Expression {
Object get value;
@@ -3914,7 +3949,8 @@
StringLiteral(this.value);
- DartType getStaticType(TypeEnvironment types) => types.stringType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.stringLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitStringLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3930,7 +3966,8 @@
IntLiteral(this.value);
- DartType getStaticType(TypeEnvironment types) => types.intType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.intLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitIntLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3942,7 +3979,8 @@
DoubleLiteral(this.value);
- DartType getStaticType(TypeEnvironment types) => types.doubleType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.doubleLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitDoubleLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3954,7 +3992,8 @@
BoolLiteral(this.value);
- DartType getStaticType(TypeEnvironment types) => types.boolType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.boolLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitBoolLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3976,7 +4015,8 @@
SymbolLiteral(this.value);
- DartType getStaticType(TypeEnvironment types) => types.symbolType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.symbolLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitSymbolLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -3991,7 +4031,8 @@
TypeLiteral(this.type);
- DartType getStaticType(TypeEnvironment types) => types.typeType;
+ DartType getStaticType(TypeEnvironment types) =>
+ types.coreTypes.typeLegacyRawType;
R accept<R>(ExpressionVisitor<R> v) => v.visitTypeLiteral(this);
R accept1<R, A>(ExpressionVisitor1<R, A> v, A arg) =>
@@ -4364,7 +4405,7 @@
CheckLibraryIsLoaded(this.import);
DartType getStaticType(TypeEnvironment types) {
- return types.objectType;
+ return types.coreTypes.objectLegacyRawType;
}
R accept<R>(ExpressionVisitor<R> v) => v.visitCheckLibraryIsLoaded(this);
@@ -5580,7 +5621,7 @@
return new FunctionType(positionalParameters, returnType,
requiredParameterCount: requiredParameterCount,
namedParameters: namedParameters,
- typedefType: typedefType);
+ typedefType: null);
}
/// Looks up the type of the named parameter with the given name.
@@ -5733,14 +5774,21 @@
/// A type variable has an optional bound because type promotion can change the
/// bound. A bound of `null` indicates that the bound has not been promoted and
/// is the same as the [TypeParameter]'s bound. This allows one to detect
-/// whether the bound has been promoted.
+/// whether the bound has been promoted. The case of promoted bound can be
+/// viewed as representing an intersection type between the type-parameter type
+/// and the promoted bound.
class TypeParameterType extends DartType {
- /// The nullability declared on the type.
+ /// Nullability of the type-parameter type or of its part of the intersection.
///
- /// Declarations of type-parameter types can set it to [Nullability.nullable]
- /// or [Nullability.legacy]. Otherwise, it's computed from the nullability
- /// of the type parameter bound.
- Nullability declaredNullability;
+ /// Declarations of type-parameter types can set the nullability of a
+ /// type-parameter type to [Nullability.nullable] (if the `?` marker is used)
+ /// or [Nullability.legacy] (if the type comes from a library opted out from
+ /// NNBD). Otherwise, it's defined indirectly via the nullability of the
+ /// bound of [parameter]. In cases when the [TypeParameterType] represents an
+ /// intersection between a type-parameter type and [promotedBound],
+ /// [typeParameterTypeNullability] represents the nullability of the left-hand
+ /// side of the intersection.
+ Nullability typeParameterTypeNullability;
TypeParameter parameter;
@@ -5751,7 +5799,8 @@
DartType promotedBound;
TypeParameterType(this.parameter,
- [this.promotedBound, this.declaredNullability = Nullability.legacy]);
+ [this.promotedBound,
+ this.typeParameterTypeNullability = Nullability.legacy]);
R accept<R>(DartTypeVisitor<R> v) => v.visitTypeParameterType(this);
R accept1<R, A>(DartTypeVisitor1<R, A> v, A arg) =>
@@ -5768,97 +5817,108 @@
/// Returns the bound of the type parameter, accounting for promotions.
DartType get bound => promotedBound ?? parameter.bound;
- /// Actual nullability of the type, calculated from its parts.
+ /// Nullability of the type, calculated from its parts.
///
- /// [nullability] is calculated from [declaredNullability] and the
- /// nullabilities of [promotedBound] and the bound of [parameter].
+ /// [nullability] is calculated from [typeParameterTypeNullability] and the
+ /// nullability of [promotedBound] if it's present.
///
- /// For example, in the following program [declaredNullability] both `x` and
- /// `y` is [Nullability.nullable], because it's copied from that of `bar`.
- /// However, despite [nullability] of `x` is [Nullability.nullable],
- /// [nullability] of `y` is [Nullability.nonNullable] because of its
- /// [promotedBound].
+ /// For example, in the following program [typeParameterTypeNullability] of
+ /// both `x` and `y` is [Nullability.neither], because it's copied from that
+ /// of `bar` and T has a nullable type as its bound. However, despite
+ /// [nullability] of `x` is [Nullability.neither], [nullability] of `y` is
+ /// [Nullability.nonNullable] because of its [promotedBound].
///
/// class A<T extends Object?> {
- /// foo(T? bar) {
+ /// foo(T bar) {
/// var x = bar;
/// if (bar is int) {
/// var y = bar;
/// }
/// }
/// }
- Nullability get nullability =>
- getNullability(parameter, promotedBound, declaredNullability);
+ Nullability get nullability {
+ return getNullability(
+ typeParameterTypeNullability ?? computeNullabilityFromBound(parameter),
+ promotedBound);
+ }
+ /// Gets the nullability of a type-parameter type based on the bound.
+ ///
+ /// This is a helper function to be used when the bound of the type parameter
+ /// is changing or is being set for the first time, and the update on some
+ /// type-parameter types is required.
static Nullability computeNullabilityFromBound(TypeParameter typeParameter) {
- // If the bound is nullable, both nullable and non-nullable types can be
- // passed in for the type parameter, making the corresponding type
- // parameter types 'neither.' Otherwise, the nullability matches that of
- // the bound.
+ // If the bound is nullable or 'neither', both nullable and non-nullable
+ // types can be passed in for the type parameter, making the corresponding
+ // type parameter types 'neither.' Otherwise, the nullability matches that
+ // of the bound.
DartType bound = typeParameter.bound;
if (bound == null) {
- throw new StateError("Can't compute nullability from absent bound.");
+ throw new StateError("Can't compute nullability from an absent bound.");
}
Nullability boundNullability =
bound is InvalidType ? Nullability.neither : bound.nullability;
- return boundNullability == Nullability.nullable
+ return boundNullability == Nullability.nullable ||
+ boundNullability == Nullability.neither
? Nullability.neither
: boundNullability;
}
- /// Get nullability of [TypeParameterType] from arguments to its constructor.
+ /// Gets nullability of [TypeParameterType] from arguments to its constructor.
///
- /// This method is supposed to be used only in the constructor of
- /// [TypeParameterType] to compute the value of
- /// [TypeParameterType.nullability] from the arguments passed to the constructor.
- static Nullability getNullability(TypeParameter parameter,
- DartType promotedBound, Nullability declaredNullability) {
- // If promotedBound is null, getNullability returns the nullability of
- // either T or T? where T is parameter and the presence of '?' is determined
- // by nullability.
-
- // If promotedBound isn't null, getNullability returns the nullability of an
- // intersection of the left-hand side (referred to as LHS below) and the
- // right-hand side (referred to as RHS below). LHS is parameter followed by
- // nullability, and RHS is promotedBound. That is, getNullability returns
- // the nullability of either T & P or T? & P where T is parameter, P is
- // promotedBound, and the presence of '?' is determined by nullability.
- // Note that RHS is always a subtype of the bound of the type parameter.
-
- Nullability lhsNullability;
-
- // If the nullability is declared explicitly, use it as the nullability of
- // the LHS of the intersection. Otherwise, compute it from the bound.
- if (declaredNullability != null) {
- lhsNullability = declaredNullability;
- } else {
- lhsNullability = computeNullabilityFromBound(parameter);
- }
+ /// The method combines [typeParameterTypeNullability] and the nullability of
+ /// [promotedBound] to yield the nullability of the intersection type. If the
+ /// right-hand side of the intersection is absent (that is, if [promotedBound]
+ /// is null), the nullability of the intersection type is simply
+ /// [typeParameterTypeNullability].
+ static Nullability getNullability(
+ Nullability typeParameterTypeNullability, DartType promotedBound) {
+ // If promotedBound is null, getNullability simply returns the nullability
+ // of the type parameter type.
+ Nullability lhsNullability = typeParameterTypeNullability;
if (promotedBound == null) {
return lhsNullability;
}
- // In practice a type parameter of legacy type can only be used in type
- // annotations within the corresponding class declaration. If it's legacy,
- // then the entire library containing the class is opt-out, and any RHS is
- // deemed to be legacy too. So, it's necessary to only check LHS for being
- // legacy.
- if (lhsNullability == Nullability.legacy) {
- return Nullability.legacy;
- }
+ // If promotedBound isn't null, getNullability returns the nullability of an
+ // intersection of the left-hand side (referred to as LHS below) and the
+ // right-hand side (referred to as RHS below). Note that RHS is always a
+ // subtype of the bound of the type parameter.
- // Intersection is non-nullable if and only if RHS is non-nullable.
+ // The code below implements the rule for the nullability of an intersection
+ // type as per the following table:
//
- // The proof is as follows. Intersection is non-nullable if at least one of
- // LHS or RHS is non-nullable. The case of non-nullable RHS is trivial. In
- // the case of non-nullable LHS, its bound should be non-nullable. RHS is
- // known to always be a subtype of the bound of LHS; therefore, RHS is
- // non-nullable.
+ // | LHS \ RHS | ! | ? | * | % |
+ // |-----------|-----|-----|-----|-----|
+ // | ! | ! | N/A | N/A | ! |
+ // | ? | N/A | N/A | N/A | N/A |
+ // | * | N/A | N/A | * | N/A |
+ // | % | ! | % | N/A | % |
//
- // Note that it also follows from the above that non-nullable RHS implies
- // non-nullable LHS, so the check below covers the case lhsNullability ==
- // Nullability.nonNullable.
- if (promotedBound.nullability == Nullability.nonNullable) {
+ // In the table, LHS corresponds to lhsNullability in the code below; RHS
+ // corresponds to promotedBound.nullability; !, ?, *, and % correspond to
+ // nonNullable, nullable, legacy, and neither values of the Nullability
+ // enum.
+ //
+ // Whenever there's N/A in the table, it means that the corresponding
+ // combination of the LHS and RHS nullability is not possible when compiling
+ // from Dart source files, so we can define it to be whatever is faster and
+ // more convenient to implement. The verifier should check that the cases
+ // marked as N/A never occur in the output of the CFE.
+ //
+ // The code below uses the following extension of the table function:
+ //
+ // | LHS \ RHS | ! | ? | * | % |
+ // |-----------|-----|-----|-----|-----|
+ // | ! | ! | ! | ! | ! |
+ // | ? | ! | * | * | % |
+ // | * | ! | * | * | % |
+ // | % | ! | % | % | % |
+
+ // Intersection with a non-nullable type always yields a non-nullable type,
+ // as it's the most restrictive kind of types.
+ if (lhsNullability == Nullability.nonNullable ||
+ promotedBound.nullability == Nullability.nonNullable) {
return Nullability.nonNullable;
}
@@ -5879,30 +5939,69 @@
// }
// }
// }
- //
- // Note that RHS can't be 'legacy' or non-nullable at this point due to the
- // checks above.
- if (lhsNullability == Nullability.neither) {
+ if (lhsNullability == Nullability.neither ||
+ promotedBound.nullability == Nullability.neither) {
return Nullability.neither;
}
- // At this point the only possibility for LHS is to be nullable, and for RHS
- // is to be either nullable or legacy. Both combinations for LHS and RHS
- // should yield the nullability of RHS as the nullability for the
- // intersection. Consider the following code for clarification:
- //
- // class A<X extends Object?, Y extends X> {
- // foo(X? x) {
- // if (x is Y) {
- // x = null; // Compile-time error. Consider X = Y = int.
- // Object a = x; // Compile-time error. Consider X = Y = int?.
- // }
- // if (x is int?) {
- // x = null; // Ok. Both X? and int? are nullable.
- // }
- // }
- // }
- return promotedBound.nullability;
+ return Nullability.legacy;
+ }
+}
+
+/// Value set for variance of a type parameter X in a type term T.
+class Variance {
+ /// Used when X does not occur free in T.
+ static const int unrelated = 0;
+
+ /// Used when X occurs free in T, and U <: V implies [U/X]T <: [V/X]T.
+ static const int covariant = 1;
+
+ /// Used when X occurs free in T, and U <: V implies [V/X]T <: [U/X]T.
+ static const int contravariant = 2;
+
+ /// Used when there exists a pair U and V such that U <: V, but [U/X]T and
+ /// [V/X]T are incomparable.
+ static const int invariant = 3;
+
+ /// Variance values form a lattice where [unrelated] is the top, [invariant]
+ /// is the bottom, and [covariant] and [contravariant] are incomparable.
+ /// [meet] calculates the meet of two elements of such lattice. It can be
+ /// used, for example, to calculate the variance of a typedef type parameter
+ /// if it's encountered on the r.h.s. of the typedef multiple times.
+ static int meet(int a, int b) => a | b;
+
+ /// Combines variances of X in T and Y in S into variance of X in [Y/T]S.
+ ///
+ /// Consider the following examples:
+ ///
+ /// * variance of X in Function(X) is [contravariant], variance of Y in
+ /// List<Y> is [covariant], so variance of X in List<Function(X)> is
+ /// [contravariant];
+ ///
+ /// * variance of X in List<X> is [covariant], variance of Y in Function(Y) is
+ /// [contravariant], so variance of X in Function(List<X>) is [contravariant];
+ ///
+ /// * variance of X in Function(X) is [contravariant], variance of Y in
+ /// Function(Y) is [contravariant], so variance of X in Function(Function(X))
+ /// is [covariant];
+ ///
+ /// * let the following be declared:
+ ///
+ /// typedef F<Z> = Function();
+ ///
+ /// then variance of X in F<X> is [unrelated], variance of Y in List<Y> is
+ /// [covariant], so variance of X in List<F<X>> is [unrelated];
+ ///
+ /// * let the following be declared:
+ ///
+ /// typedef G<Z> = Z Function(Z);
+ ///
+ /// then variance of X in List<X> is [covariant], variance of Y in G<Y> is
+ /// [invariant], so variance of `X` in `G<List<X>>` is [invariant].
+ static int combine(int a, int b) {
+ if (a == unrelated || b == unrelated) return unrelated;
+ if (a == invariant || b == invariant) return invariant;
+ return a == b ? covariant : contravariant;
}
}
@@ -5939,6 +6038,12 @@
/// argument of a dynamic invocation of a generic function.
DartType defaultType;
+ /// Describes variance of the type parameter w.r.t. declaration on which it is
+ /// defined. It's always [Variance.covariant] for classes, and for typedefs
+ /// it's the variance of the type parameters in the type term on the r.h.s. of
+ /// the typedef.
+ int variance = Variance.covariant;
+
TypeParameter([this.name, this.bound, this.defaultType]);
// Must match serialized bit positions.
@@ -6095,7 +6200,7 @@
R accept<R>(ConstantVisitor<R> v) => v.visitBoolConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitBoolConstantReference(this);
- DartType getType(TypeEnvironment types) => types.boolType;
+ DartType getType(TypeEnvironment types) => types.coreTypes.boolLegacyRawType;
}
/// An integer constant on a non-JS target.
@@ -6106,7 +6211,7 @@
R accept<R>(ConstantVisitor<R> v) => v.visitIntConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitIntConstantReference(this);
- DartType getType(TypeEnvironment types) => types.intType;
+ DartType getType(TypeEnvironment types) => types.coreTypes.intLegacyRawType;
}
/// A double constant on a non-JS target or any numeric constant on a JS target.
@@ -6121,7 +6226,8 @@
bool operator ==(Object other) =>
other is DoubleConstant && identical(value, other.value);
- DartType getType(TypeEnvironment types) => types.doubleType;
+ DartType getType(TypeEnvironment types) =>
+ types.coreTypes.doubleLegacyRawType;
}
class StringConstant extends PrimitiveConstant<String> {
@@ -6133,7 +6239,8 @@
R accept<R>(ConstantVisitor<R> v) => v.visitStringConstant(this);
R acceptReference<R>(Visitor<R> v) => v.visitStringConstantReference(this);
- DartType getType(TypeEnvironment types) => types.stringType;
+ DartType getType(TypeEnvironment types) =>
+ types.coreTypes.stringLegacyRawType;
}
class SymbolConstant extends Constant {
@@ -6161,7 +6268,8 @@
other.name == name &&
other.libraryReference == libraryReference);
- DartType getType(TypeEnvironment types) => types.symbolType;
+ DartType getType(TypeEnvironment types) =>
+ types.coreTypes.symbolLegacyRawType;
}
class MapConstant extends Constant {
@@ -6435,7 +6543,7 @@
return other is TypeLiteralConstant && other.type == type;
}
- DartType getType(TypeEnvironment types) => types.typeType;
+ DartType getType(TypeEnvironment types) => types.coreTypes.typeLegacyRawType;
}
class UnevaluatedConstant extends Constant {
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 32f2210..f8585a5 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -8,6 +8,7 @@
import 'dart:typed_data';
import '../ast.dart';
+import '../src/bounds_checks.dart' show computeVariance;
import '../transformations/flags.dart';
import 'tag.dart';
@@ -642,7 +643,7 @@
_byteOffset = index.binaryOffsetForSourceTable;
Map<Uri, Source> uriToSource = readUriToSource();
- component.uriToSource.addAll(uriToSource);
+ _mergeUriToSource(component.uriToSource, uriToSource);
_byteOffset = _componentStartOffset + componentFileSize;
}
@@ -683,7 +684,7 @@
_byteOffset = index.binaryOffsetForSourceTable;
Map<Uri, Source> uriToSource = readUriToSource();
- component.uriToSource.addAll(uriToSource);
+ _mergeUriToSource(component.uriToSource, uriToSource);
_byteOffset = index.binaryOffsetForConstantTable;
readConstantTable();
@@ -751,6 +752,23 @@
return uriToSource;
}
+ // Add everything from [src] into [dst], but don't overwrite a non-empty
+ // source with an empty source. Empty sources may be introduced by
+ // synthetic, copy-down implementations such as mixin applications or
+ // noSuchMethod forwarders.
+ void _mergeUriToSource(Map<Uri, Source> dst, Map<Uri, Source> src) {
+ if (dst.isEmpty) {
+ // Fast path for the common case of one component per binary.
+ dst.addAll(src);
+ } else {
+ src.forEach((Uri key, Source value) {
+ if (value.source.isNotEmpty || !dst.containsKey(key)) {
+ dst[key] = value;
+ }
+ });
+ }
+ }
+
CanonicalName readCanonicalNameReference() {
var index = readUInt();
if (index == 0) return null;
@@ -995,6 +1013,10 @@
node.namedParameters.addAll(readAndPushVariableDeclarationList());
typeParameterStack.length = 0;
variableStack.length = 0;
+ for (int i = 0; i < node.typeParameters.length; ++i) {
+ node.typeParameters[i].variance =
+ computeVariance(node.typeParameters[i], type);
+ }
if (shouldWriteData) {
node.fileOffset = fileOffset;
node.name = name;
@@ -1661,6 +1683,9 @@
..fileOffset = offset;
case Tag.Not:
return new Not(readExpression());
+ case Tag.NullCheck:
+ int offset = readOffset();
+ return new NullCheck(readExpression())..fileOffset = offset;
case Tag.LogicalExpression:
return new LogicalExpression(readExpression(),
logicalOperatorToString(readByte()), readExpression());
@@ -2162,6 +2187,7 @@
node.name = readStringOrNullIfEmpty();
node.bound = readDartType();
node.defaultType = readDartTypeOption();
+ node.variance = Variance.covariant;
}
Arguments readArguments() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index ac32edd..9e34e8c 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1495,6 +1495,13 @@
writeNode(node.operand);
}
+ @override
+ void visitNullCheck(NullCheck node) {
+ writeByte(Tag.NullCheck);
+ writeOffset(node.fileOffset);
+ writeNode(node.operand);
+ }
+
int logicalOperatorIndex(String operator) {
switch (operator) {
case '&&':
@@ -2097,7 +2104,7 @@
@override
void visitTypeParameterType(TypeParameterType node) {
writeByte(Tag.TypeParameterType);
- writeByte(node.declaredNullability.index);
+ writeByte(node.typeParameterTypeNullability.index);
writeUInt30(_typeParameterIndexer[node.parameter]);
writeOptionalNode(node.promotedBound);
}
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 0645cb9..33091c0 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -48,6 +48,7 @@
static const int ConstructorInvocation = 31;
static const int ConstConstructorInvocation = 32;
static const int Not = 33;
+ static const int NullCheck = 117;
static const int LogicalExpression = 34;
static const int ConditionalExpression = 35;
static const int StringConcatenation = 36;
@@ -130,6 +131,7 @@
/// 114 is occupied by [InstanceCreation] (expression).
/// 115 is occupied by [Extension].
/// 116 is occupied by [FileUriExpression] (expression).
+ /// 117 is occupied by [NullCheck] (expression).
static const int SpecializedTagHighBit = 0x80; // 10000000
static const int SpecializedTagMask = 0xF8; // 11111000
@@ -146,7 +148,7 @@
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
- static const int BinaryFormatVersion = 32;
+ static const int BinaryFormatVersion = 33;
}
abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index f80716e..1f846ce 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -180,6 +180,10 @@
return new Not(clone(node.operand));
}
+ visitNullCheck(NullCheck node) {
+ return new NullCheck(clone(node.operand));
+ }
+
visitLogicalExpression(LogicalExpression node) {
return new LogicalExpression(
clone(node.left), node.operator, clone(node.right));
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index 5924ca6..0e31d92 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -245,7 +245,7 @@
}
// Permit any invocation on Function type.
- if (receiver == environment.rawFunctionType &&
+ if (receiver == environment.coreTypes.functionLegacyRawType &&
where is MethodInvocation &&
where.name.name == 'call') {
return;
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 040d266..1e59288 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -15,6 +15,7 @@
TypeParameter,
TypeParameterType,
TypedefType,
+ Variance,
VoidType;
import '../type_algebra.dart' show Substitution, substitute;
@@ -398,7 +399,7 @@
return const BottomType();
} else if ((type is BottomType || isNull(typeEnvironment, type)) &&
!isCovariant) {
- return typeEnvironment.objectType;
+ return typeEnvironment.coreTypes.objectLegacyRawType;
} else if (type is InterfaceType && type.classNode.typeParameters != null) {
List<DartType> replacedTypeArguments =
new List<DartType>(type.typeArguments.length);
@@ -448,7 +449,7 @@
bool isObject(TypeEnvironment typeEnvironment, DartType type) {
return type is InterfaceType &&
- type.classNode == typeEnvironment.objectType.classNode;
+ type.classNode == typeEnvironment.coreTypes.objectClass;
}
bool isNull(TypeEnvironment typeEnvironment, DartType type) {
@@ -456,58 +457,84 @@
type.classNode == typeEnvironment.nullType.classNode;
}
-// Value set for variance of a type parameter X in a type term T.
-class Variance {
- // Used when X does not occur free in T.
- static const int unrelated = 0;
+int computeVariance(TypeParameter typeParameter, DartType type) {
+ return type.accept(new VarianceCalculator(typeParameter));
+}
- // Used when X occurs free in T, and U <: V implies [U/X]T <: [V/X]T.
- static const int covariant = 1;
+class VarianceCalculator implements DartTypeVisitor<int> {
+ final TypeParameter typeParameter;
- // Used when X occurs free in T, and U <: V implies [V/X]T <: [U/X]T.
- static const int contravariant = 2;
+ VarianceCalculator(this.typeParameter);
- // Used when there exists a pair U and V such that U <: V, but [U/X]T and
- // [V/X]T are incomparable.
- static const int invariant = 3;
+ @override
+ int defaultDartType(DartType node) => Variance.unrelated;
- // Variance values form a lattice where [unrelated] is the top, [invariant]
- // is the bottom, and [covariant] and [contravariant] are incomparable.
- // [meet] calculates the meet of two elements of such lattice. It can be
- // used, for example, to calculate the variance of a typedef type parameter
- // if it's encountered on the r.h.s. of the typedef multiple times.
- static int meet(int a, int b) => a | b;
-
- // Combines variances of X in T and Y in S into variance of X in [Y/T]S.
- //
- // Consider the following examples:
- //
- // * variance of X in Function(X) is [contravariant], variance of Y in List<Y>
- // is [covariant], so variance of X in List<Function(X)> is [contravariant];
- //
- // * variance of X in List<X> is [covariant], variance of Y in Function(Y) is
- // [contravariant], so variance of X in Function(List<X>) is [contravariant];
- //
- // * variance of X in Function(X) is [contravariant], variance of Y in
- // Function(Y) is [contravariant], so variance of X in Function(Function(X))
- // is [covariant];
- //
- // * let the following be declared:
- //
- // typedef F<Z> = Function();
- //
- // then variance of X in F<X> is [unrelated], variance of Y in List<Y> is
- // [covariant], so variance of X in List<F<X>> is [unrelated];
- //
- // * let the following be declared:
- //
- // typedef G<Z> = Z Function(Z);
- //
- // then variance of X in List<X> is [covariant], variance of Y in G<Y> is
- // [invariant], so variance of `X` in `G<List<X>>` is [invariant].
- static int combine(int a, int b) {
- if (a == unrelated || b == unrelated) return unrelated;
- if (a == invariant || b == invariant) return invariant;
- return a == b ? covariant : contravariant;
+ @override
+ int visitTypeParameterType(TypeParameterType node) {
+ if (node.parameter == typeParameter) return Variance.covariant;
+ return Variance.unrelated;
}
+
+ @override
+ int visitInterfaceType(InterfaceType node) {
+ int result = Variance.unrelated;
+ for (DartType argument in node.typeArguments) {
+ result = Variance.meet(result, argument.accept(this));
+ }
+ return result;
+ }
+
+ @override
+ int visitTypedefType(TypedefType node) {
+ int result = Variance.unrelated;
+ for (int i = 0; i < node.typeArguments.length; ++i) {
+ result = Variance.meet(
+ result,
+ Variance.combine(
+ node.typeArguments[i].accept(this),
+ node.typedefNode.type.accept(
+ new VarianceCalculator(node.typedefNode.typeParameters[i]))));
+ }
+ return result;
+ }
+
+ @override
+ int visitFunctionType(FunctionType node) {
+ int result = Variance.unrelated;
+ result = Variance.meet(result, node.returnType.accept(this));
+ for (TypeParameter functionTypeParameter in node.typeParameters) {
+ // If [typeParameter] is referenced in the bound at all, it makes the
+ // variance of [typeParameter] in the entire type invariant. The
+ // invocation of the visitor below is made to simply figure out if
+ // [typeParameter] occurs in the bound.
+ if (functionTypeParameter.bound.accept(this) != Variance.unrelated) {
+ result = Variance.invariant;
+ }
+ }
+ for (DartType positionalType in node.positionalParameters) {
+ result = Variance.meet(
+ result,
+ Variance.combine(
+ Variance.contravariant, positionalType.accept(this)));
+ }
+ for (NamedType namedType in node.namedParameters) {
+ result = Variance.meet(
+ result,
+ Variance.combine(
+ Variance.contravariant, namedType.type.accept(this)));
+ }
+ return result;
+ }
+
+ @override
+ int visitBottomType(BottomType node) => defaultDartType(node);
+
+ @override
+ int visitVoidType(VoidType node) => defaultDartType(node);
+
+ @override
+ int visitDynamicType(DynamicType node) => defaultDartType(node);
+
+ @override
+ int visitInvalidType(InvalidType node) => defaultDartType(node);
}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index ccff048..707b3a1 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1292,6 +1292,11 @@
writeExpression(node.operand, Precedence.PREFIX);
}
+ visitNullCheck(NullCheck node) {
+ writeExpression(node.operand, Precedence.POSTFIX);
+ writeSymbol('!');
+ }
+
visitLogicalExpression(LogicalExpression node) {
int precedence = Precedence.binaryPrecedence[node.operator];
writeExpression(node.left, precedence);
@@ -2119,13 +2124,13 @@
visitTypeParameterType(TypeParameterType node) {
writeTypeParameterReference(node.parameter);
- writeNullability(node.declaredNullability);
+ writeNullability(node.typeParameterTypeNullability);
if (node.promotedBound != null) {
writeSpaced('&');
writeType(node.promotedBound);
writeWord("/* '");
- writeNullability(node.declaredNullability, inComment: true);
+ writeNullability(node.typeParameterTypeNullability, inComment: true);
writeWord("' & '");
writeDartTypeNullability(node.promotedBound, inComment: true);
writeWord("' = '");
@@ -2137,6 +2142,14 @@
visitTypeParameter(TypeParameter node) {
writeModifier(node.isGenericCovariantImpl, 'generic-covariant-impl');
writeAnnotationList(node.annotations, separateLines: false);
+ if (node.variance != Variance.covariant) {
+ writeWord(const <String>[
+ "unrelated",
+ "covariant",
+ "contravariant",
+ "invariant"
+ ][node.variance]);
+ }
writeWord(getTypeParameterName(node));
writeSpaced('extends');
writeType(node.bound);
@@ -2329,6 +2342,7 @@
int visitStaticInvocation(StaticInvocation node) => CALLEE;
int visitConstructorInvocation(ConstructorInvocation node) => CALLEE;
int visitNot(Not node) => PREFIX;
+ int visitNullCheck(NullCheck node) => PRIMARY;
int visitLogicalExpression(LogicalExpression node) =>
binaryPrecedence[node.operator];
int visitConditionalExpression(ConditionalExpression node) => CONDITIONAL;
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 18e2cd5..f381ec2 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -942,6 +942,12 @@
}
@override
+ void visitNullCheck(NullCheck node) {
+ storeLastSeenUriAndOffset(node);
+ makeExpressionRoundTrip(node);
+ }
+
+ @override
void visitConstructorInvocation(ConstructorInvocation node) {
storeLastSeenUriAndOffset(node);
makeExpressionRoundTrip(node);
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 90fff29..a0f364a 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -406,13 +406,13 @@
@override
DartType visitBoolLiteral(BoolLiteral node) {
- return environment.boolType;
+ return environment.coreTypes.boolLegacyRawType;
}
@override
DartType visitConditionalExpression(ConditionalExpression node) {
- node.condition =
- checkAndDowncastExpression(node.condition, environment.boolType);
+ node.condition = checkAndDowncastExpression(
+ node.condition, environment.coreTypes.boolLegacyRawType);
node.then = checkAndDowncastExpression(node.then, node.staticType);
node.otherwise =
checkAndDowncastExpression(node.otherwise, node.staticType);
@@ -452,7 +452,7 @@
@override
DartType visitDoubleLiteral(DoubleLiteral node) {
- return environment.doubleType;
+ return environment.coreTypes.doubleLegacyRawType;
}
@override
@@ -463,7 +463,7 @@
@override
DartType visitIntLiteral(IntLiteral node) {
- return environment.intType;
+ return environment.coreTypes.intLegacyRawType;
}
@override
@@ -474,7 +474,7 @@
@override
DartType visitIsExpression(IsExpression node) {
visitExpression(node.operand);
- return environment.boolType;
+ return environment.coreTypes.boolLegacyRawType;
}
@override
@@ -529,9 +529,11 @@
@override
DartType visitLogicalExpression(LogicalExpression node) {
- node.left = checkAndDowncastExpression(node.left, environment.boolType);
- node.right = checkAndDowncastExpression(node.right, environment.boolType);
- return environment.boolType;
+ node.left = checkAndDowncastExpression(
+ node.left, environment.coreTypes.boolLegacyRawType);
+ node.right = checkAndDowncastExpression(
+ node.right, environment.coreTypes.boolLegacyRawType);
+ return environment.coreTypes.boolLegacyRawType;
}
@override
@@ -595,7 +597,7 @@
var receiver = visitExpression(node.receiver);
if (node.name.name == '==') {
visitExpression(node.arguments.positional.single);
- return environment.boolType;
+ return environment.coreTypes.boolLegacyRawType;
}
if (node.name.name == 'call' && receiver is FunctionType) {
return handleFunctionCall(node, receiver, node.arguments);
@@ -646,7 +648,13 @@
@override
DartType visitNot(Not node) {
visitExpression(node.operand);
- return environment.boolType;
+ return environment.coreTypes.boolLegacyRawType;
+ }
+
+ @override
+ DartType visitNullCheck(NullCheck node) {
+ // TODO(johnniwinther): Return `NonNull(visitExpression(types))`.
+ return visitExpression(node.operand);
}
@override
@@ -679,7 +687,7 @@
@override
DartType visitStringConcatenation(StringConcatenation node) {
node.expressions.forEach(visitExpression);
- return environment.stringType;
+ return environment.coreTypes.stringLegacyRawType;
}
@override
@@ -731,7 +739,7 @@
@override
DartType visitStringLiteral(StringLiteral node) {
- return environment.stringType;
+ return environment.coreTypes.stringLegacyRawType;
}
@override
@@ -774,7 +782,7 @@
@override
DartType visitSymbolLiteral(SymbolLiteral node) {
- return environment.symbolType;
+ return environment.coreTypes.symbolLegacyRawType;
}
@override
@@ -790,7 +798,7 @@
@override
DartType visitTypeLiteral(TypeLiteral node) {
- return environment.typeType;
+ return environment.coreTypes.typeLegacyRawType;
}
@override
@@ -812,7 +820,7 @@
@override
DartType visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
- return environment.objectType;
+ return environment.coreTypes.objectLegacyRawType;
}
@override
@@ -847,8 +855,8 @@
@override
visitDoStatement(DoStatement node) {
visitStatement(node.body);
- node.condition =
- checkAndDowncastExpression(node.condition, environment.boolType);
+ node.condition = checkAndDowncastExpression(
+ node.condition, environment.coreTypes.boolLegacyRawType);
}
@override
@@ -912,8 +920,8 @@
visitForStatement(ForStatement node) {
node.variables.forEach(visitVariableDeclaration);
if (node.condition != null) {
- node.condition =
- checkAndDowncastExpression(node.condition, environment.boolType);
+ node.condition = checkAndDowncastExpression(
+ node.condition, environment.coreTypes.boolLegacyRawType);
}
node.updates.forEach(visitExpression);
visitStatement(node.body);
@@ -926,8 +934,8 @@
@override
visitIfStatement(IfStatement node) {
- node.condition =
- checkAndDowncastExpression(node.condition, environment.boolType);
+ node.condition = checkAndDowncastExpression(
+ node.condition, environment.coreTypes.boolLegacyRawType);
visitStatement(node.then);
if (node.otherwise != null) {
visitStatement(node.otherwise);
@@ -987,8 +995,8 @@
@override
visitWhileStatement(WhileStatement node) {
- node.condition =
- checkAndDowncastExpression(node.condition, environment.boolType);
+ node.condition = checkAndDowncastExpression(
+ node.condition, environment.coreTypes.boolLegacyRawType);
visitStatement(node.body);
}
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index 98ef5f2..31518fa 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -32,23 +32,14 @@
return new HierarchyBasedTypeEnvironment(coreTypes, hierarchy);
}
- // TODO(dmitryas): Remove these getters, use the appropriate member of
- // CoreTypes at the call sites instead.
- InterfaceType get objectType => coreTypes.objectLegacyRawType;
- InterfaceType get nullType => coreTypes.nullType;
- InterfaceType get boolType => coreTypes.boolLegacyRawType;
- InterfaceType get intType => coreTypes.intLegacyRawType;
- InterfaceType get numType => coreTypes.numLegacyRawType;
- InterfaceType get doubleType => coreTypes.doubleLegacyRawType;
- InterfaceType get stringType => coreTypes.stringLegacyRawType;
- InterfaceType get symbolType => coreTypes.symbolLegacyRawType;
- InterfaceType get typeType => coreTypes.typeLegacyRawType;
- InterfaceType get rawFunctionType => coreTypes.functionLegacyRawType;
-
Class get intClass => coreTypes.intClass;
Class get numClass => coreTypes.numClass;
Class get futureOrClass => coreTypes.futureOrClass;
+ InterfaceType get objectLegacyRawType => coreTypes.objectLegacyRawType;
+ InterfaceType get nullType => coreTypes.nullType;
+ InterfaceType get functionLegacyRawType => coreTypes.functionLegacyRawType;
+
InterfaceType literalListType(DartType elementType) {
return new InterfaceType(coreTypes.listClass, <DartType>[elementType]);
}
@@ -144,8 +135,10 @@
/// Otherwise `num` is returned.
DartType getTypeOfOverloadedArithmetic(DartType type1, DartType type2) {
if (type1 == type2) return type1;
- if (type1 == doubleType || type2 == doubleType) return doubleType;
- return numType;
+ if (type1 == coreTypes.doubleLegacyRawType ||
+ type2 == coreTypes.doubleLegacyRawType)
+ return coreTypes.doubleLegacyRawType;
+ return coreTypes.numLegacyRawType;
}
}
@@ -153,9 +146,9 @@
///
/// This lives in a separate class so it can be tested independently of the SDK.
abstract class SubtypeTester {
- InterfaceType get objectType;
+ InterfaceType get objectLegacyRawType;
InterfaceType get nullType;
- InterfaceType get rawFunctionType;
+ InterfaceType get functionLegacyRawType;
Class get futureOrClass;
InterfaceType futureType(DartType type);
@@ -165,8 +158,11 @@
/// Determines if the given type is at the top of the type hierarchy. May be
/// overridden in subclasses.
- bool isTop(DartType type) =>
- type is DynamicType || type is VoidType || type == objectType;
+ bool isTop(DartType type) {
+ return type is DynamicType ||
+ type is VoidType ||
+ type == objectLegacyRawType;
+ }
/// Can be use to collect type checks. To use:
/// 1. Rename `isSubtypeOf` to `_isSubtypeOf`.
@@ -251,7 +247,7 @@
return isSubtypeOf(subtype.bound, supertype);
}
if (subtype is FunctionType) {
- if (supertype == rawFunctionType) return true;
+ if (supertype == functionLegacyRawType) return true;
if (supertype is FunctionType) {
return _isFunctionSubtypeOf(subtype, supertype);
}
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 4f95e65..b6007db 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -34,6 +34,7 @@
R visitConstructorInvocation(ConstructorInvocation node) =>
defaultExpression(node);
R visitNot(Not node) => defaultExpression(node);
+ R visitNullCheck(NullCheck node) => defaultExpression(node);
R visitLogicalExpression(LogicalExpression node) => defaultExpression(node);
R visitConditionalExpression(ConditionalExpression node) =>
defaultExpression(node);
@@ -162,6 +163,7 @@
R visitConstructorInvocation(ConstructorInvocation node) =>
defaultExpression(node);
R visitNot(Not node) => defaultExpression(node);
+ R visitNullCheck(NullCheck node) => defaultExpression(node);
R visitLogicalExpression(LogicalExpression node) => defaultExpression(node);
R visitConditionalExpression(ConditionalExpression node) =>
defaultExpression(node);
@@ -673,6 +675,7 @@
R visitConstructorInvocation(ConstructorInvocation node, T arg) =>
defaultExpression(node, arg);
R visitNot(Not node, T arg) => defaultExpression(node, arg);
+ R visitNullCheck(NullCheck node, T arg) => defaultExpression(node, arg);
R visitLogicalExpression(LogicalExpression node, T arg) =>
defaultExpression(node, arg);
R visitConditionalExpression(ConditionalExpression node, T arg) =>
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index b0b05b0..f190364 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
name: kernel
# Currently, kernel API is not stable and users should
# not depend on semver semantics when depending on this package.
-version: 0.3.25
+version: 0.3.26
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -9,6 +9,7 @@
sdk: '>=2.2.2 <3.0.0'
dependencies:
args: '>=0.13.4 <2.0.0'
+ meta: ^1.0.0
dev_dependencies:
expect: any
front_end: any
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 8bb4062..546590f 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -32,19 +32,12 @@
/// A message used by dartfix to indicate a fix has been applied.
final String appliedMessage;
- /// An import needs to be added.
- factory NullabilityFixDescription.addImport(String uri) =>
- NullabilityFixDescription._(appliedMessage: 'Add import $uri');
-
- /// A formal parameter needs to have a required modifier added.
+ /// A formal parameter needs to have a required keyword added.
factory NullabilityFixDescription.addRequired(
String className, String functionName, String paramName) =>
NullabilityFixDescription._(
- appliedMessage:
- "Add 'required' modifier to parameter $paramName in " +
- (className == null
- ? functionName
- : '$className.$functionName'));
+ appliedMessage: "Add 'required' keyword to parameter $paramName in " +
+ (className == null ? functionName : '$className.$functionName'));
/// An explicit type mentioned in the source program needs to be made
/// nullable.
diff --git a/pkg/nnbd_migration/lib/src/potential_modification.dart b/pkg/nnbd_migration/lib/src/potential_modification.dart
index ac60b15..a36315d 100644
--- a/pkg/nnbd_migration/lib/src/potential_modification.dart
+++ b/pkg/nnbd_migration/lib/src/potential_modification.dart
@@ -93,54 +93,6 @@
Iterable<FixReasonInfo> get reasons => discard.reasons;
}
-/// Records information about the possible addition of an import to the source
-/// code.
-class PotentiallyAddImport extends PotentialModification {
- final _usages = <PotentialModification>[];
-
- final int _offset;
- final String importPath;
-
- PotentiallyAddImport(
- AstNode beforeNode, String importPath, PotentialModification usage)
- : this.forOffset(beforeNode.offset, importPath, usage);
-
- PotentiallyAddImport.forOffset(
- this._offset, this.importPath, PotentialModification usage) {
- _usages.add(usage);
- }
-
- @override
- NullabilityFixDescription get description =>
- NullabilityFixDescription.addImport(importPath);
-
- @override
- bool get isEmpty {
- for (PotentialModification usage in _usages) {
- if (!usage.isEmpty) {
- return false;
- }
- }
- return true;
- }
-
- // TODO(danrubel): change all of dartfix NNBD to use DartChangeBuilder
- @override
- Iterable<SourceEdit> get modifications =>
- isEmpty ? const [] : [SourceEdit(_offset, 0, "import '$importPath';\n")];
-
- @override
- Iterable<FixReasonInfo> get reasons sync* {
- for (var usage in _usages) {
- if (!usage.isEmpty) yield* usage.reasons;
- }
- }
-
- void addUsage(PotentialModification usage) {
- _usages.add(usage);
- }
-}
-
/// Records information about the possible addition of a `?` suffix to a type in
/// the source code.
class PotentiallyAddQuestionSuffix extends PotentialModification {
@@ -165,7 +117,7 @@
Iterable<FixReasonInfo> get reasons => [node];
}
-/// Records information about the possible addition of a `@required` annotation
+/// Records information about the possible addition of a `required` keyword
/// to the source code.
class PotentiallyAddRequired extends PotentialModification {
final NullabilityNode _node;
@@ -197,7 +149,7 @@
@override
Iterable<SourceEdit> get modifications =>
- isEmpty ? const [] : [SourceEdit(_offset, 0, '@required ')];
+ isEmpty ? const [] : [SourceEdit(_offset, 0, 'required ')];
@override
Iterable<FixReasonInfo> get reasons => [_node];
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 8406cd4..5266dec 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -173,53 +173,6 @@
Source source, DefaultFormalParameter parameter, NullabilityNode node) {
var modification = PotentiallyAddRequired(parameter, node);
_addPotentialModification(source, modification);
- _addPotentialImport(
- source, parameter, modification, 'package:meta/meta.dart');
- }
-
- void _addPotentialImport(Source source, AstNode node,
- PotentialModification usage, String importPath) {
- // Get the compilation unit - assume not null
- while (node is! CompilationUnit) {
- node = node.parent;
- }
- var unit = node as CompilationUnit;
-
- // Find an existing import
- for (var directive in unit.directives) {
- if (directive is ImportDirective) {
- if (directive.uri.stringValue == importPath) {
- return;
- }
- }
- }
-
- // Add the usage to an existing modification if possible
- for (var modification in (_potentialModifications[source] ??= [])) {
- if (modification is PotentiallyAddImport) {
- if (modification.importPath == importPath) {
- modification.addUsage(usage);
- return;
- }
- }
- }
-
- // Create a new import modification
- AstNode beforeNode;
- for (var directive in unit.directives) {
- if (directive is ImportDirective || directive is ExportDirective) {
- beforeNode = directive;
- break;
- }
- }
- if (beforeNode == null) {
- for (var declaration in unit.declarations) {
- beforeNode = declaration;
- break;
- }
- }
- _addPotentialModification(
- source, PotentiallyAddImport(beforeNode, importPath, usage));
}
void _addPotentialModification(
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 6b01783..c0d90a0 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -76,7 +76,6 @@
/// Mixin containing test cases for the provisional API.
mixin _ProvisionalApiTestCases on _ProvisionalApiTestBase {
- @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/38461')
test_add_required() async {
var content = '''
int f({String s}) => s.length;
@@ -1939,6 +1938,20 @@
await _checkSingleFileChanges(content, expected);
}
+ test_named_parameter_add_required() async {
+ var content = '''
+void f({String s}) {
+ assert(s != null);
+}
+''';
+ var expected = '''
+void f({required String s}) {
+ assert(s != null);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
test_named_parameter_no_default_unused() async {
var content = '''
void f({String s}) {}
diff --git a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
index 39ba9f3..1ba7901 100644
--- a/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
+++ b/pkg/nnbd_migration/test/nullability_migration_impl_test.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/src/generated/timestamped_data.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:mockito/mockito.dart';
+import 'package:nnbd_migration/instrumentation.dart';
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/nullability_migration_impl.dart';
import 'package:nnbd_migration/src/potential_modification.dart';
@@ -28,46 +29,46 @@
}
void test_modification_columnLineInfo() {
- final innerModification = PotentialModificationMock();
- final potentialModification =
- PotentiallyAddImport.forOffset(10, 'foo', innerModification);
+ final text = 'void f() {}\nint g() => null;';
+ final offset = text.indexOf('int') + 3;
+ final potentialModification = _PotentialModificationMock(
+ _NullabilityFixDescriptionMock('Add ?'),
+ false,
+ [SourceEdit(offset, 0, '?')]);
final listener = NullabilityMigrationListenerMock();
- final source = SourceMock('0123456\n8910');
+ final source = SourceMock(text);
when(variables.getPotentialModifications()).thenReturn({
source: [potentialModification]
});
- when(innerModification.isEmpty).thenReturn(false);
-
NullabilityMigrationImpl.broadcast(variables, listener, null);
final fix = verify(listener.addFix(captureAny)).captured.single
as SingleNullabilityFix;
- expect(fix.description.appliedMessage, 'Add import foo');
+ expect(fix.description.appliedMessage, 'Add ?');
expect(fix.source, source);
- expect(fix.location.offset, 10);
+ expect(fix.location.offset, offset);
expect(fix.location.length, 0);
expect(fix.location.file, '/test.dart');
expect(fix.location.startLine, 2);
- expect(fix.location.startColumn, 3);
+ expect(fix.location.startColumn, 4);
verifyNever(listener.reportException(any, any, any, any));
final edit =
verify(listener.addEdit(fix, captureAny)).captured.single as SourceEdit;
- expect(edit.offset, 10);
+ expect(edit.offset, offset);
expect(edit.length, 0);
- expect(edit.replacement, "import 'foo';\n");
+ expect(edit.replacement, '?');
}
void test_noModifications_notReported() {
- final potentialModification = PotentialModificationMock();
+ final potentialModification =
+ _PotentialModificationMock.empty(_NullabilityFixDescriptionMock('foo'));
final listener = NullabilityMigrationListenerMock();
final source = SourceMock('');
when(variables.getPotentialModifications()).thenReturn({
source: [potentialModification]
});
- when(potentialModification.modifications).thenReturn([]);
-
NullabilityMigrationImpl.broadcast(variables, listener, null);
verifyNever(listener.addFix(any));
@@ -91,8 +92,6 @@
class NullabilityMigrationListenerMock extends Mock
implements NullabilityMigrationListener {}
-class PotentialModificationMock extends Mock implements PotentialModification {}
-
class SourceMock extends Mock implements Source {
final String _contents;
@@ -102,3 +101,31 @@
}
class VariablesMock extends Mock implements Variables {}
+
+class _NullabilityFixDescriptionMock implements NullabilityFixDescription {
+ @override
+ final String appliedMessage;
+
+ _NullabilityFixDescriptionMock(this.appliedMessage);
+}
+
+class _PotentialModificationMock extends PotentialModification {
+ @override
+ final NullabilityFixDescription description;
+
+ @override
+ final bool isEmpty;
+
+ @override
+ final Iterable<SourceEdit> modifications;
+
+ _PotentialModificationMock(
+ this.description, this.isEmpty, this.modifications);
+
+ _PotentialModificationMock.empty(this.description)
+ : isEmpty = false,
+ modifications = [];
+
+ @override
+ Iterable<FixReasonInfo> get reasons => throw UnimplementedError();
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 47913ba..61c2e71 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -75,6 +75,7 @@
dartfix/test/*: SkipByDesign # Only meant to run on vm
front_end/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
front_end/tool/*: SkipByDesign # Only meant to run on vm
+modular_test/test/memory_pipeline_test: Slow
nnbd_migration/test/*: SkipByDesign # Uses mirrors
smith/test/*: SkipByDesign # Only meant to run on vm
status_file/test/normalize_test: SkipByDesign # Uses dart:io
diff --git a/pkg/test_runner/lib/src/compiler_configuration.dart b/pkg/test_runner/lib/src/compiler_configuration.dart
index 62629db..5ac46ed 100644
--- a/pkg/test_runner/lib/src/compiler_configuration.dart
+++ b/pkg/test_runner/lib/src/compiler_configuration.dart
@@ -586,8 +586,12 @@
bool get _isArm => _configuration.architecture == Architecture.arm;
+ bool get _isSimArm => _configuration.architecture == Architecture.simarm;
+
bool get _isArm64 => _configuration.architecture == Architecture.arm64;
+ bool get _isSimArm64 => _configuration.architecture == Architecture.simarm64;
+
bool get _isX64 => _configuration.architecture == Architecture.x64;
bool get _isIA32 => _configuration.architecture == Architecture.ia32;
@@ -701,12 +705,12 @@
Command computeAssembleCommand(String tempDir, List arguments,
Map<String, String> environmentOverrides) {
String cc, shared, ldFlags;
- if (_isAndroid) {
+ if (_isAndroid || _isSimArm || _isSimArm64) {
var ndk = "third_party/android_tools/ndk";
String triple;
- if (_isArm) {
+ if (_isArm || _isSimArm) {
triple = "arm-linux-androideabi";
- } else if (_isArm64) {
+ } else if (_isArm64 || _isSimArm64) {
triple = "aarch64-linux-android";
}
String host;
diff --git a/pkg/test_runner/lib/src/update_errors.dart b/pkg/test_runner/lib/src/update_errors.dart
index f0fa6e4..83ab3b3 100644
--- a/pkg/test_runner/lib/src/update_errors.dart
+++ b/pkg/test_runner/lib/src/update_errors.dart
@@ -96,8 +96,9 @@
var comment = (" " * indent) + "//";
- // If the error can't fit in a line comment, use an explicit location.
- if (error.column <= 2) {
+ // If the error can't fit in a line comment, or no source location is
+ // sepcified, use an explicit location.
+ if (error.column <= 2 || error.length == 0) {
if (error.length == null) {
result.add("$comment [error line $codeLine, column "
"${error.column}]");
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index 8338073..803f10f 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -21,15 +21,7 @@
import 'error_handling.dart' show withErrorHandling;
-import 'log.dart'
- show
- logMessage,
- logStepComplete,
- logStepStart,
- logSuiteComplete,
- logTestComplete,
- logUnexpectedResult,
- splitLines;
+import 'log.dart' show Logger, StdoutLogger, splitLines;
import 'multitest.dart' show MultitestTransformer, isError;
@@ -112,7 +104,9 @@
ExpectationSet get expectationSet => ExpectationSet.Default;
Future<Null> run(Chain suite, Set<String> selectors,
- {int shards = 1, int shard = 0}) async {
+ {int shards = 1,
+ int shard = 0,
+ Logger logger: const StdoutLogger()}) async {
assert(shards >= 1, "Invalid shards count: $shards");
assert(0 <= shard && shard < shards,
"Invalid shard index: $shard, not in range [0,$shards[.");
@@ -182,8 +176,8 @@
Step step = iterator.current;
lastStepRun = step;
isAsync = step.isAsync;
- logStepStart(completed, unexpectedResults.length, descriptions.length,
- suite, description, step);
+ logger.logStepStart(completed, unexpectedResults.length,
+ descriptions.length, suite, description, step);
// TODO(ahe): It's important to share the zone error reporting zone
// between all the tasks. Otherwise, if a future completes with an
// error in one zone, and gets stored, it becomes an uncaught error
@@ -201,7 +195,7 @@
future = future.then((_currentResult) async {
Result currentResult = _currentResult;
if (currentResult != null) {
- logStepComplete(completed, unexpectedResults.length,
+ logger.logStepComplete(completed, unexpectedResults.length,
descriptions.length, suite, description, lastStepRun);
result = currentResult;
if (currentResult.outcome == Expectation.Pass) {
@@ -217,12 +211,13 @@
result.addLog("$sb");
unexpectedResults[description] = result;
unexpectedOutcomes[description] = expectedOutcomes;
- logUnexpectedResult(suite, description, result, expectedOutcomes);
+ logger.logUnexpectedResult(
+ suite, description, result, expectedOutcomes);
exitCode = 1;
} else {
- logMessage(sb);
+ logger.logMessage(sb);
}
- logTestComplete(++completed, unexpectedResults.length,
+ logger.logTestComplete(++completed, unexpectedResults.length,
descriptions.length, suite, description);
});
if (isAsync) {
@@ -233,14 +228,16 @@
}
}
+ logger.logTestStart(completed, unexpectedResults.length,
+ descriptions.length, suite, description);
// The input of the first step is [description].
await doStep(description);
}
await Future.wait(futures);
- logSuiteComplete();
+ logger.logSuiteComplete();
if (unexpectedResults.isNotEmpty) {
unexpectedResults.forEach((TestDescription description, Result result) {
- logUnexpectedResult(
+ logger.logUnexpectedResult(
suite, description, result, unexpectedOutcomes[description]);
});
print("${unexpectedResults.length} failed:");
diff --git a/pkg/testing/lib/src/log.dart b/pkg/testing/lib/src/log.dart
index edd36638..b15de14 100644
--- a/pkg/testing/lib/src/log.dart
+++ b/pkg/testing/lib/src/log.dart
@@ -38,106 +38,146 @@
_isVerbose = true;
}
-void logTestComplete(int completed, int failed, int total, Suite suite,
- TestDescription description) {
- String message = formatProgress(completed, failed, total);
- if (suite != null) {
- message += ": ${formatTestDescription(suite, description)}";
- }
- logProgress(message);
+abstract class Logger {
+ void logTestStart(int completed, int failed, int total, Suite suite,
+ TestDescription description);
+
+ void logTestComplete(int completed, int failed, int total, Suite suite,
+ TestDescription description);
+
+ void logStepStart(int completed, int failed, int total, Suite suite,
+ TestDescription description, Step step);
+
+ void logStepComplete(int completed, int failed, int total, Suite suite,
+ TestDescription description, Step step);
+
+ void logProgress(String message);
+
+ void logMessage(Object message);
+
+ void logNumberedLines(String text);
+
+ void logExpectedResult(Suite suite, TestDescription description,
+ Result result, Set<Expectation> expectedOutcomes);
+
+ void logUnexpectedResult(Suite suite, TestDescription description,
+ Result result, Set<Expectation> expectedOutcomes);
+
+ void logSuiteComplete();
+
+ void logUncaughtError(error, StackTrace stackTrace);
}
-void logStepStart(int completed, int failed, int total, Suite suite,
- TestDescription description, Step step) {
- String message = formatProgress(completed, failed, total);
- if (suite != null) {
- message += ": ${formatTestDescription(suite, description)} ${step.name}";
- if (step.isAsync) {
- message += "...";
+class StdoutLogger implements Logger {
+ const StdoutLogger();
+
+ void logTestStart(int completed, int failed, int total, Suite suite,
+ TestDescription description) {}
+
+ void logTestComplete(int completed, int failed, int total, Suite suite,
+ TestDescription description) {
+ String message = formatProgress(completed, failed, total);
+ if (suite != null) {
+ message += ": ${formatTestDescription(suite, description)}";
}
+ logProgress(message);
}
- logProgress(message);
-}
-void logStepComplete(int completed, int failed, int total, Suite suite,
- TestDescription description, Step step) {
- if (!step.isAsync) return;
- String message = formatProgress(completed, failed, total);
- if (suite != null) {
- message += ": ${formatTestDescription(suite, description)} ${step.name}!";
+ void logStepStart(int completed, int failed, int total, Suite suite,
+ TestDescription description, Step step) {
+ String message = formatProgress(completed, failed, total);
+ if (suite != null) {
+ message += ": ${formatTestDescription(suite, description)} ${step.name}";
+ if (step.isAsync) {
+ message += "...";
+ }
+ }
+ logProgress(message);
}
- logProgress(message);
-}
-void logProgress(String message) {
- if (isVerbose) {
- print(message);
- } else {
- print("$eraseLine$message$cursorUp");
+ void logStepComplete(int completed, int failed, int total, Suite suite,
+ TestDescription description, Step step) {
+ if (!step.isAsync) return;
+ String message = formatProgress(completed, failed, total);
+ if (suite != null) {
+ message += ": ${formatTestDescription(suite, description)} ${step.name}!";
+ }
+ logProgress(message);
}
-}
-String formatProgress(int completed, int failed, int total) {
- Duration elapsed = wallclock.elapsed;
- String percent = pad((completed / total * 100.0).toStringAsFixed(1), 5);
- String good = pad(completed - failed, 5);
- String bad = pad(failed, 5);
- String minutes = pad(elapsed.inMinutes, 2, filler: "0");
- String seconds = pad(elapsed.inSeconds % 60, 2, filler: "0");
- return "[ $minutes:$seconds | $percent% | +$good | -$bad ]";
-}
-
-String formatTestDescription(Suite suite, TestDescription description) {
- return "${suite.name}/${description.shortName}";
-}
-
-void logMessage(Object message) {
- if (isVerbose) {
- print("$message");
- }
-}
-
-void logNumberedLines(String text) {
- if (isVerbose) {
- print(numberedLines(text));
- }
-}
-
-void logUnexpectedResult(Suite suite, TestDescription description,
- Result result, Set<Expectation> expectedOutcomes) {
- print("${eraseLine}UNEXPECTED: ${suite.name}/${description.shortName}");
- Uri statusFile = suite.statusFile;
- if (statusFile != null) {
- String path = statusFile.toFilePath();
- if (result.outcome == Expectation.Pass) {
- print("The test unexpectedly passed, please update $path.");
+ void logProgress(String message) {
+ if (isVerbose) {
+ print(message);
} else {
- print("The test had the outcome ${result.outcome}, but the status file "
- "($path) allows these outcomes: ${expectedOutcomes.join(' ')}");
+ print("$eraseLine$message$cursorUp");
}
}
- String log = result.log;
- if (log.isNotEmpty) {
- print(log);
+
+ String formatProgress(int completed, int failed, int total) {
+ Duration elapsed = wallclock.elapsed;
+ String percent = pad((completed / total * 100.0).toStringAsFixed(1), 5);
+ String good = pad(completed - failed, 5);
+ String bad = pad(failed, 5);
+ String minutes = pad(elapsed.inMinutes, 2, filler: "0");
+ String seconds = pad(elapsed.inSeconds % 60, 2, filler: "0");
+ return "[ $minutes:$seconds | $percent% | +$good | -$bad ]";
}
- if (result.error != null) {
- print(result.error);
- if (result.trace != null) {
- print(result.trace);
+
+ String formatTestDescription(Suite suite, TestDescription description) {
+ return "${suite.name}/${description.shortName}";
+ }
+
+ void logMessage(Object message) {
+ if (isVerbose) {
+ print("$message");
}
}
-}
-void logSuiteComplete() {
- if (!isVerbose) {
- print("");
+ void logNumberedLines(String text) {
+ if (isVerbose) {
+ print(numberedLines(text));
+ }
}
-}
-void logUncaughtError(error, StackTrace stackTrace) {
- logMessage(error);
- if (stackTrace != null) {
- logMessage(stackTrace);
+ void logExpectedResult(Suite suite, TestDescription description,
+ Result result, Set<Expectation> expectedOutcomes) {}
+
+ void logUnexpectedResult(Suite suite, TestDescription description,
+ Result result, Set<Expectation> expectedOutcomes) {
+ print("${eraseLine}UNEXPECTED: ${suite.name}/${description.shortName}");
+ Uri statusFile = suite.statusFile;
+ if (statusFile != null) {
+ String path = statusFile.toFilePath();
+ if (result.outcome == Expectation.Pass) {
+ print("The test unexpectedly passed, please update $path.");
+ } else {
+ print("The test had the outcome ${result.outcome}, but the status file "
+ "($path) allows these outcomes: ${expectedOutcomes.join(' ')}");
+ }
+ }
+ String log = result.log;
+ if (log.isNotEmpty) {
+ print(log);
+ }
+ if (result.error != null) {
+ print(result.error);
+ if (result.trace != null) {
+ print(result.trace);
+ }
+ }
+ }
+
+ void logSuiteComplete() {
+ if (!isVerbose) {
+ print("");
+ }
+ }
+
+ void logUncaughtError(error, StackTrace stackTrace) {
+ logMessage(error);
+ if (stackTrace != null) {
+ logMessage(stackTrace);
+ }
}
}
diff --git a/pkg/testing/lib/src/run.dart b/pkg/testing/lib/src/run.dart
index d16cf30..12305ba 100644
--- a/pkg/testing/lib/src/run.dart
+++ b/pkg/testing/lib/src/run.dart
@@ -24,12 +24,7 @@
import 'analyze.dart' show Analyze;
import 'log.dart'
- show
- enableVerboseOutput,
- isVerbose,
- logMessage,
- logNumberedLines,
- splitLines;
+ show enableVerboseOutput, isVerbose, Logger, splitLines, StdoutLogger;
import 'suite.dart' show Dart, Suite;
@@ -55,7 +50,11 @@
/// `testing.json` isn't located in the current working directory and is a path
/// relative to [me] which defaults to `Platform.script`.
Future<Null> runMe(List<String> arguments, CreateContext f,
- {String configurationPath, Uri me, int shards = 1, int shard = 0}) {
+ {String configurationPath,
+ Uri me,
+ int shards = 1,
+ int shard = 0,
+ Logger logger: const StdoutLogger()}) {
me ??= Platform.script;
return withErrorHandling(() async {
TestRoot testRoot = await computeTestRoot(configurationPath, me);
@@ -66,7 +65,7 @@
print("Running suite ${suite.name}...");
ChainContext context = await f(suite, cl.environment);
await context.run(suite, new Set<String>.from(cl.selectors),
- shards: shards, shard: shard);
+ shards: shards, shard: shard, logger: logger);
}
}
});
@@ -117,8 +116,8 @@
}
Future<Null> runProgram(String program, Uri packages) async {
- logMessage("Running:");
- logNumberedLines(program);
+ const StdoutLogger().logMessage("Running:");
+ const StdoutLogger().logNumberedLines(program);
Uri dataUri = new Uri.dataFromString(program);
ReceivePort exitPort = new ReceivePort();
Isolate isolate = await Isolate.spawnUri(dataUri, <String>[], null,
diff --git a/pkg/testing/lib/src/run_tests.dart b/pkg/testing/lib/src/run_tests.dart
index 5d6e27d..ecb28d4 100644
--- a/pkg/testing/lib/src/run_tests.dart
+++ b/pkg/testing/lib/src/run_tests.dart
@@ -18,13 +18,7 @@
import 'zone_helper.dart' show runGuarded;
-import 'log.dart'
- show
- enableVerboseOutput,
- isVerbose,
- logMessage,
- logSuiteComplete,
- logTestComplete;
+import 'log.dart' show enableVerboseOutput, isVerbose, StdoutLogger;
import 'run.dart' show SuiteRunner, runProgram;
@@ -115,7 +109,8 @@
}
}
}
- logMessage("Reading configuration file '$configurationPath'.");
+ const StdoutLogger()
+ .logMessage("Reading configuration file '$configurationPath'.");
Uri configuration =
await Isolate.resolvePackageUri(Uri.base.resolve(configurationPath));
if (configuration == null ||
@@ -177,18 +172,21 @@
withErrorHandling<void>(() async {
int completed = 0;
for (String name in tests.keys) {
+ const StdoutLogger()
+ .logTestStart(completed, 0, tests.length, null, null);
StringBuffer sb = new StringBuffer();
try {
await runGuarded(() {
print("Running test $name");
return tests[name]();
}, printLineOnStdout: sb.writeln);
- logMessage(sb);
+ const StdoutLogger().logMessage(sb);
} catch (e) {
print(sb);
rethrow;
}
- logTestComplete(++completed, 0, tests.length, null, null);
+ const StdoutLogger()
+ .logTestComplete(++completed, 0, tests.length, null, null);
}
- logSuiteComplete();
+ const StdoutLogger().logSuiteComplete();
});
diff --git a/pkg/testing/lib/src/zone_helper.dart b/pkg/testing/lib/src/zone_helper.dart
index 5359c2e..e2d106d 100644
--- a/pkg/testing/lib/src/zone_helper.dart
+++ b/pkg/testing/lib/src/zone_helper.dart
@@ -11,7 +11,7 @@
import 'dart:isolate' show Capability, Isolate, ReceivePort;
-import 'log.dart' show logUncaughtError;
+import 'log.dart' show StdoutLogger;
Future runGuarded(Future f(),
{void printLineOnStdout(line),
@@ -26,7 +26,7 @@
Completer completer = new Completer();
handleUncaughtError(error, StackTrace stackTrace) {
- logUncaughtError(error, stackTrace);
+ StdoutLogger().logUncaughtError(error, stackTrace);
if (!completer.isCompleted) {
completer.completeError(error, stackTrace);
} else if (handleLateError != null) {
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index c14d3ab..5303161 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -19,6 +19,8 @@
import 'package:kernel/external_name.dart'
show getExternalName, getNativeExtensionUris;
import 'package:kernel/library_index.dart' show LibraryIndex;
+import 'package:kernel/text/ast_to_text.dart'
+ show globalDebuggingNames, NameSystem;
import 'package:kernel/type_algebra.dart'
show Substitution, containsTypeVariable;
import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -75,6 +77,16 @@
onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
libraries ??= component.libraries;
+
+ // Save/restore global NameSystem to avoid accumulating garbage.
+ // NameSystem holds the whole AST as it is strongly connected due to
+ // parent pointers. Objects are added to NameSystem when toString()
+ // is called from AST nodes. Bytecode generator widely uses
+ // Expression.getStaticType, which calls Expression.getStaticTypeAsInstanceOf,
+ // which uses toString() when it crashes due to http://dartbug.com/34496.
+ final savedGlobalDebuggingNames = globalDebuggingNames;
+ globalDebuggingNames = new NameSystem();
+
try {
final bytecodeGenerator = new BytecodeGenerator(
component, coreTypes, hierarchy, typeEnvironment, options);
@@ -85,6 +97,8 @@
CompilerContext.current.options.report(
templateIllegalRecursiveType.withArguments(e.type).withoutLocation(),
Severity.error);
+ } finally {
+ globalDebuggingNames = savedGlobalDebuggingNames;
}
}
@@ -2125,7 +2139,8 @@
asm.emitPushConstant(cp.addType(type));
_genPushInstantiatorAndFunctionTypeArguments([type]);
asm.emitPushConstant(cp.addString(name));
- bool isIntOk = typeEnvironment.isSubtypeOf(typeEnvironment.intType, type);
+ bool isIntOk = typeEnvironment.isSubtypeOf(
+ typeEnvironment.coreTypes.intLegacyRawType, type);
int subtypeTestCacheCpIndex = cp.addSubtypeTestCache();
asm.emitAssertAssignable(isIntOk ? 1 : 0, subtypeTestCacheCpIndex);
}
@@ -4167,7 +4182,7 @@
final newRepository = new BytecodeMetadataRepository();
newComponent.addMetadataRepository(newRepository);
- final oldRepository = component.metadata[newRepository.tag];
+ final oldRepository = component.metadata.remove(newRepository.tag);
final metadata = oldRepository.mapping[component];
newRepository.mapping[newComponent] = metadata;
diff --git a/pkg/vm/lib/bytecode/recognized_methods.dart b/pkg/vm/lib/bytecode/recognized_methods.dart
index 6b776cc..73033b6 100644
--- a/pkg/vm/lib/bytecode/recognized_methods.dart
+++ b/pkg/vm/lib/bytecode/recognized_methods.dart
@@ -47,9 +47,9 @@
DartType staticType(Expression expr) => getStaticType(expr, typeEnv);
- bool isInt(DartType type) => type == typeEnv.intType;
+ bool isInt(DartType type) => type == typeEnv.coreTypes.intLegacyRawType;
- bool isDouble(DartType type) => type == typeEnv.doubleType;
+ bool isDouble(DartType type) => type == typeEnv.coreTypes.doubleLegacyRawType;
Opcode specializedBytecodeFor(MethodInvocation node) {
final args = node.arguments;
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 13c4908..2b10f69 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -65,6 +65,11 @@
}
}
+ if (arguments.types.isNotEmpty &&
+ arguments.types.length != func.typeParameters.length) {
+ return false;
+ }
+
return true;
}
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 6b47324..c4e6800 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -253,9 +253,9 @@
if (nativeType is! InterfaceType) {
return null;
}
- InterfaceType native = nativeType;
- Class nativeClass = native.classNode;
- NativeType nativeType_ = getType(nativeClass);
+ final InterfaceType native = nativeType;
+ final Class nativeClass = native.classNode;
+ final NativeType nativeType_ = getType(nativeClass);
if (hierarchy.isSubclassOf(nativeClass, structClass)) {
return allowStructs ? nativeType : null;
@@ -281,17 +281,17 @@
return null;
}
- FunctionType fun = native.typeArguments[0];
+ final FunctionType fun = native.typeArguments[0];
if (fun.namedParameters.isNotEmpty) return null;
if (fun.positionalParameters.length != fun.requiredParameterCount) {
return null;
}
if (fun.typeParameters.length != 0) return null;
// TODO(36730): Structs cannot appear in native function signatures.
- DartType returnType =
+ final DartType returnType =
convertNativeTypeToDartType(fun.returnType, /*allowStructs=*/ false);
if (returnType == null) return null;
- List<DartType> argumentTypes = fun.positionalParameters
+ final List<DartType> argumentTypes = fun.positionalParameters
.map((t) => convertNativeTypeToDartType(t, /*allowStructs=*/ false))
.toList();
if (argumentTypes.contains(null)) return null;
@@ -299,7 +299,7 @@
}
NativeType getType(Class c) {
- int index = nativeTypesClasses.indexOf(c);
+ final int index = nativeTypesClasses.indexOf(c);
if (index == -1) {
return null;
}
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index c82b64f..0765dd5 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -128,7 +128,7 @@
}
// A struct classes "C" must extend "Struct<C>".
- DartType structTypeArg = node.supertype.typeArguments[0];
+ final DartType structTypeArg = node.supertype.typeArguments[0];
if (structTypeArg != InterfaceType(node)) {
diagnosticReporter.report(
templateFfiWrongStructInheritance.withArguments(node.name),
@@ -147,7 +147,7 @@
bool _checkFieldAnnotations(Class node) {
bool success = true;
- for (Field f in node.fields) {
+ for (final Field f in node.fields) {
if (f.initializer is! NullLiteral) {
diagnosticReporter.report(
templateFfiFieldInitializer.withArguments(f.name.name),
@@ -197,8 +197,8 @@
// Constructors cannot have initializers because initializers refer to
// fields, and the fields were replaced with getter/setter pairs.
- for (Constructor c in node.constructors) {
- for (Initializer i in c.initializers) {
+ for (final Constructor c in node.constructors) {
+ for (final Initializer i in c.initializers) {
if (i is FieldInitializer) {
toRemove.add(i);
diagnosticReporter.report(
@@ -210,7 +210,7 @@
}
}
// Remove initializers referring to fields to prevent cascading errors.
- for (Initializer i in toRemove) {
+ for (final Initializer i in toRemove) {
i.remove();
}
@@ -235,14 +235,14 @@
final fields = <Field>[];
final types = <NativeType>[];
- for (Field f in node.fields) {
+ for (final Field f in node.fields) {
if (_isPointerType(f)) {
fields.add(f);
types.add(NativeType.kPointer);
} else {
final nativeTypeAnnos = _getNativeTypeAnnotations(f).toList();
if (nativeTypeAnnos.length == 1) {
- NativeType t = nativeTypeAnnos.first;
+ final NativeType t = nativeTypeAnnos.first;
fields.add(f);
types.add(t);
}
@@ -250,7 +250,7 @@
}
final sizeAndOffsets = <Abi, SizeAndOffsets>{};
- for (Abi abi in Abi.values) {
+ for (final Abi abi in Abi.values) {
sizeAndOffsets[abi] = _calculateSizeAndOffsets(types, abi);
}
@@ -262,7 +262,7 @@
methods.forEach((p) => node.addMember(p));
}
- for (Field f in fields) {
+ for (final Field f in fields) {
f.remove();
}
@@ -391,7 +391,7 @@
SizeAndOffsets _calculateSizeAndOffsets(List<NativeType> types, Abi abi) {
int offset = 0;
final offsets = <int>[];
- for (NativeType t in types) {
+ for (final NativeType t in types) {
final int size = _sizeInBytes(t, abi);
final int alignment = _alignmentOf(t, abi);
offset = _alignOffset(offset, alignment);
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index d7cc4b5..0083c57 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -102,7 +102,7 @@
visitPropertyGet(PropertyGet node) {
super.visitPropertyGet(node);
- Procedure replacedWith = replacedGetters[node.interfaceTarget];
+ final Procedure replacedWith = replacedGetters[node.interfaceTarget];
if (replacedWith != null) {
node = PropertyGet(node.receiver, replacedWith.name, replacedWith);
}
@@ -114,7 +114,7 @@
visitPropertySet(PropertySet node) {
super.visitPropertySet(node);
- Procedure replacedWith = replacedSetters[node.interfaceTarget];
+ final Procedure replacedWith = replacedSetters[node.interfaceTarget];
if (replacedWith != null) {
node = PropertySet(
node.receiver, replacedWith.name, node.value, replacedWith);
@@ -127,7 +127,7 @@
visitStaticInvocation(StaticInvocation node) {
super.visitStaticInvocation(node);
- Member target = node.target;
+ final Member target = node.target;
try {
if (target == fromFunctionMethod) {
final DartType nativeType =
@@ -286,24 +286,24 @@
visitMethodInvocation(MethodInvocation node) {
super.visitMethodInvocation(node);
- Member target = node.interfaceTarget;
+ final Member target = node.interfaceTarget;
try {
// We will not detect dynamic invocations of 'asFunction' and
// 'lookupFunction' -- these are handled by the 'asFunctionInternal' stub
// in 'dynamic_library_patch.dart'. Dynamic invocations of 'asFunction'
// and 'lookupFunction' are not legal and throw a runtime exception.
if (target == lookupFunctionMethod) {
- DartType nativeType =
+ final DartType nativeType =
InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
- DartType dartType = node.arguments.types[1];
+ final DartType dartType = node.arguments.types[1];
_ensureNativeTypeValid(nativeType, node);
_ensureNativeTypeToDartType(nativeType, dartType, node);
return _replaceLookupFunction(node);
} else if (target == asFunctionMethod) {
- DartType dartType = node.arguments.types[0];
- DartType pointerType = node.receiver.getStaticType(env);
- DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+ final DartType dartType = node.arguments.types[0];
+ final DartType pointerType = node.receiver.getStaticType(env);
+ final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
_ensureNativeTypeValid(pointerType, node);
_ensureNativeTypeValid(nativeType, node);
@@ -316,9 +316,9 @@
} else if (target == loadMethod) {
// TODO(dacoharkes): should load and store be generic?
// https://github.com/dart-lang/sdk/issues/35902
- DartType dartType = node.arguments.types[0];
- DartType pointerType = node.receiver.getStaticType(env);
- DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+ final DartType dartType = node.arguments.types[0];
+ final DartType pointerType = node.receiver.getStaticType(env);
+ final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
_ensureNativeTypeValid(pointerType, node);
_ensureNativeTypeValid(nativeType, node, allowStructs: true);
@@ -328,9 +328,10 @@
} else if (target == storeMethod) {
// TODO(dacoharkes): should load and store permitted to be generic?
// https://github.com/dart-lang/sdk/issues/35902
- DartType dartType = node.arguments.positional[0].getStaticType(env);
- DartType pointerType = node.receiver.getStaticType(env);
- DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+ final DartType dartType =
+ node.arguments.positional[0].getStaticType(env);
+ final DartType pointerType = node.receiver.getStaticType(env);
+ final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
// TODO(36730): Allow storing an entire struct to memory.
// TODO(36780): Emit a better error message for the struct case.
@@ -407,7 +408,7 @@
if (nativeType is! InterfaceType) {
return false;
}
- Class nativeClass = (nativeType as InterfaceType).classNode;
+ final Class nativeClass = (nativeType as InterfaceType).classNode;
if (env.isSubtypeOf(
InterfaceType(nativeClass), InterfaceType(pointerClass))) {
return true;
@@ -415,7 +416,7 @@
if (hierarchy.isSubclassOf(nativeClass, structClass)) {
return true;
}
- NativeType nativeType_ = getType(nativeClass);
+ final NativeType nativeType_ = getType(nativeClass);
if (nativeType_ == null) {
return false;
}
@@ -465,7 +466,7 @@
}
void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
- Class extended = _extendsOrImplementsSealedClass(klass);
+ final Class extended = _extendsOrImplementsSealedClass(klass);
if (extended != null) {
diagnosticReporter.report(
templateFfiExtendsOrImplementsSealedClass
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 75a8332..285b3ac 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1093,10 +1093,10 @@
// TODO(alexmarkov): handle function types properly
if (subType is FunctionType) {
- subType = _typeFlowAnalysis.environment.rawFunctionType;
+ subType = _typeFlowAnalysis.environment.functionLegacyRawType;
}
if (superType is FunctionType) {
- superType = _typeFlowAnalysis.environment.rawFunctionType;
+ superType = _typeFlowAnalysis.environment.functionLegacyRawType;
}
// TODO(alexmarkov): handle generic types properly.
assertx(subType is! TypeParameterType);
@@ -1140,7 +1140,7 @@
// TODO(alexmarkov): handle function types properly
if (base is FunctionType) {
- base = _typeFlowAnalysis.environment.rawFunctionType;
+ base = _typeFlowAnalysis.environment.functionLegacyRawType;
}
if (base is TypeParameterType) {
@@ -1156,7 +1156,7 @@
// subtypes is too large
if (base == const DynamicType() ||
- base == _typeFlowAnalysis.environment.objectType ||
+ base == _typeFlowAnalysis.environment.coreTypes.objectLegacyRawType ||
// TODO(alexmarkov): handle FutureOr more precisely (requires generics).
baseClass == _typeFlowAnalysis.environment.futureOrClass) {
return const AnyType();
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index a5d3532..b3e7028 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -710,23 +710,24 @@
new Type.fromStatic(_staticDartType(node));
Type _cachedBoolType;
- Type get _boolType =>
- _cachedBoolType ??= new Type.cone(_environment.boolType);
+ Type get _boolType => _cachedBoolType ??=
+ new Type.cone(_environment.coreTypes.boolLegacyRawType);
Type _cachedDoubleType;
- Type get _doubleType =>
- _cachedDoubleType ??= new Type.cone(_environment.doubleType);
+ Type get _doubleType => _cachedDoubleType ??=
+ new Type.cone(_environment.coreTypes.doubleLegacyRawType);
Type _cachedIntType;
- Type get _intType => _cachedIntType ??= new Type.cone(_environment.intType);
+ Type get _intType =>
+ _cachedIntType ??= new Type.cone(_environment.coreTypes.intLegacyRawType);
Type _cachedStringType;
- Type get _stringType =>
- _cachedStringType ??= new Type.cone(_environment.stringType);
+ Type get _stringType => _cachedStringType ??=
+ new Type.cone(_environment.coreTypes.stringLegacyRawType);
Type _cachedSymbolType;
- Type get _symbolType =>
- _cachedSymbolType ??= new Type.cone(_environment.symbolType);
+ Type get _symbolType => _cachedSymbolType ??=
+ new Type.cone(_environment.coreTypes.symbolLegacyRawType);
Type _cachedNullType;
Type get _nullType => _cachedNullType ??= new Type.nullable(new Type.empty());
@@ -968,7 +969,7 @@
if (node.name.name == 'call') {
final recvType = _staticDartType(node.receiver);
if ((recvType is FunctionType) ||
- (recvType == _environment.rawFunctionType)) {
+ (recvType == _environment.functionLegacyRawType)) {
// Call to a Function.
return _staticType(node);
}
@@ -1192,7 +1193,7 @@
@override
TypeExpr visitTypeLiteral(TypeLiteral node) {
- return new Type.cone(_environment.typeType);
+ return new Type.cone(_environment.coreTypes.typeLegacyRawType);
}
@override
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index a33eb29..f634d26 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -130,7 +130,7 @@
_unreachableNodeMetadata = new UnreachableNodeMetadataRepository(),
_procedureAttributesMetadata =
new ProcedureAttributesMetadataRepository(),
- _intType = _typeFlowAnalysis.environment.intType {
+ _intType = _typeFlowAnalysis.environment.coreTypes.intLegacyRawType {
component.addMetadataRepository(_inferredTypeMetadata);
component.addMetadataRepository(_unreachableNodeMetadata);
component.addMetadataRepository(_procedureAttributesMetadata);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
index b679db8..6dc134a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/annotation.dart.expect
@@ -3,7 +3,7 @@
import "dart:core" as core;
@#C5
-typedef SomeType<T extends core::Object* = dynamic> = (core::List<T*>*) →* void;
+typedef SomeType<unrelated T extends core::Object* = dynamic> = (core::List<T*>*) →* void;
abstract class ClassAnnotation2 extends core::Object {
}
abstract class MethodAnnotation extends core::Object {
diff --git a/pkg/vm_service/java/.gitignore b/pkg/vm_service/java/.gitignore
index 5f9d198..b5f4f08 100644
--- a/pkg/vm_service/java/.gitignore
+++ b/pkg/vm_service/java/.gitignore
@@ -16,6 +16,7 @@
src/org/dartlang/vm/service/consumer/ReloadReportConsumer.java
src/org/dartlang/vm/service/consumer/RetainingPathConsumer.java
src/org/dartlang/vm/service/consumer/ScriptListConsumer.java
+src/org/dartlang/vm/service/consumer/SetFlagConsumer.java
src/org/dartlang/vm/service/consumer/SourceReportConsumer.java
src/org/dartlang/vm/service/consumer/StackConsumer.java
src/org/dartlang/vm/service/consumer/SuccessConsumer.java
diff --git a/pkg/vm_service/lib/vm_service.dart b/pkg/vm_service/lib/vm_service.dart
index 2850348..63ab8a8 100644
--- a/pkg/vm_service/lib/vm_service.dart
+++ b/pkg/vm_service/lib/vm_service.dart
@@ -197,7 +197,7 @@
'requestHeapSnapshot': const ['Success'],
'resume': const ['Success'],
'setExceptionPauseMode': const ['Success'],
- 'setFlag': const ['Success'],
+ 'setFlag': const ['Success', 'Error'],
'setLibraryDebuggable': const ['Success'],
'setName': const ['Success'],
'setVMName': const ['Success'],
@@ -767,7 +767,9 @@
/// value is of the wrong type for the flag.
///
/// The following flags may be set at runtime:
- Future<Success> setFlag(String name, String value);
+ ///
+ /// The return value can be one of [Success] or [Error].
+ Future<dynamic> setFlag(String name, String value);
/// The `setLibraryDebuggable` RPC is used to enable or disable whether
/// breakpoints and stepping work for a given library.
@@ -1616,7 +1618,7 @@
}
@override
- Future<Success> setFlag(String name, String value) {
+ Future<dynamic> setFlag(String name, String value) {
return _call('setFlag', {'name': name, 'value': value});
}
diff --git a/pkg/vm_service/test/get_allocation_profile_rpc_test.dart b/pkg/vm_service/test/get_allocation_profile_rpc_test.dart
new file mode 100644
index 0000000..4366092
--- /dev/null
+++ b/pkg/vm_service/test/get_allocation_profile_rpc_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, 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';
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/test_helper.dart';
+
+Future<void> sleep(int milliseconds) =>
+ Future.delayed(Duration(milliseconds: milliseconds));
+
+var tests = <IsolateTest>[
+ (VmService service, IsolateRef isolate) async {
+ AllocationProfile result = await service.getAllocationProfile(isolate.id);
+ expect(result.dateLastAccumulatorReset, isNull);
+ expect(result.dateLastServiceGC, isNull);
+ expect(result.members.length, isPositive);
+
+ ClassHeapStats member = result.members[0];
+ expect(member.instancesAccumulated, isNotNull);
+ expect(member.instancesCurrent, isNotNull);
+ expect(member.bytesCurrent, isNotNull);
+ expect(member.accumulatedSize, isNotNull);
+
+ // reset.
+ result = await service.getAllocationProfile(isolate.id, reset: true);
+ final firstReset = result.dateLastAccumulatorReset;
+ expect(firstReset, isNotNull);
+ expect(result.dateLastServiceGC, isNull);
+ expect(result.members.length, isPositive);
+
+ member = result.members[0];
+ expect(member.instancesAccumulated, isNotNull);
+ expect(member.instancesCurrent, isNotNull);
+ expect(member.bytesCurrent, isNotNull);
+ expect(member.accumulatedSize, isNotNull);
+
+ await sleep(1000);
+
+ result = await service.getAllocationProfile(isolate.id, reset: true);
+ final secondReset = result.dateLastAccumulatorReset;
+ expect(secondReset, isNot(firstReset));
+
+ // gc.
+ result = await service.getAllocationProfile(isolate.id, gc: true);
+ expect(result.dateLastAccumulatorReset, secondReset);
+ final firstGC = result.dateLastServiceGC;
+ expect(firstGC, isNotNull);
+ expect(result.members.length, isPositive);
+
+ member = result.members[0];
+ expect(member.instancesAccumulated, isNotNull);
+ expect(member.instancesCurrent, isNotNull);
+ expect(member.bytesCurrent, isNotNull);
+ expect(member.accumulatedSize, isNotNull);
+
+ await sleep(1000);
+
+ result = await service.getAllocationProfile(isolate.id, gc: true);
+ final secondGC = result.dateLastAccumulatorReset;
+ expect(secondGC, isNot(firstGC));
+ },
+];
+
+main(args) async => runIsolateTests(args, tests);
diff --git a/pkg/vm_service/test/get_flag_list_rpc_test.dart b/pkg/vm_service/test/get_flag_list_rpc_test.dart
new file mode 100644
index 0000000..ada2cfa
--- /dev/null
+++ b/pkg/vm_service/test/get_flag_list_rpc_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2019, 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';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/test_helper.dart';
+
+Future getFlagValue(VmService service, String flagName) async {
+ final result = await service.getFlagList();
+ final flags = result.flags;
+ for (final flag in flags) {
+ if (flag.name == flagName) {
+ return flag.valueAsString;
+ }
+ }
+}
+
+var tests = <VMTest>[
+ // Modify a flag which does not exist.
+ (VmService service) async {
+ final result = await service.setFlag('does_not_exist', 'true');
+ expect(result, TypeMatcher<Error>());
+ expect(result.message, 'Cannot set flag: flag not found');
+ },
+
+ // Modify a flag with the wrong value type.
+ (VmService service) async {
+ final result =
+ await service.setFlag('pause_isolates_on_start', 'not-boolean');
+ expect(result, TypeMatcher<Error>());
+ expect(result.message, equals('Cannot set flag: invalid value'));
+ },
+
+ // Modify a flag with the right value type.
+ (VmService service) async {
+ final result = await service.setFlag('pause_isolates_on_start', 'false');
+ expect(result, TypeMatcher<Success>());
+ },
+
+ // Modify a flag which cannot be set at runtime.
+ (VmService service) async {
+ final result = await service.setFlag('random_seed', '42');
+ expect(result, TypeMatcher<Error>());
+ expect(result.message, 'Cannot set flag: cannot change at runtime');
+ },
+
+ // Modify the profile_period at runtime.
+ (VmService service) async {
+ final kProfilePeriod = 'profile_period';
+ final kValue = 100;
+ expect(await getFlagValue(service, kProfilePeriod), '1000');
+ final completer = Completer();
+ final stream = await service.onVMEvent;
+ var subscription;
+ subscription = stream.listen((Event event) {
+ print(event);
+ if (event.kind == EventKind.kVMFlagUpdate) {
+ expect(event.flag, kProfilePeriod);
+ expect(event.newValue, kValue.toString());
+ subscription.cancel();
+ completer.complete();
+ }
+ });
+ await service.streamListen(EventStreams.kVM);
+ final result = await service.setFlag(kProfilePeriod, kValue.toString());
+ expect(result, TypeMatcher<Success>());
+ await completer.future;
+ expect(await getFlagValue(service, kProfilePeriod), kValue.toString());
+ await service.streamCancel(EventStreams.kVM);
+ }
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/pkg/vm_service/test/get_memory_usage.dart b/pkg/vm_service/test/get_memory_usage.dart
new file mode 100644
index 0000000..76cac44
--- /dev/null
+++ b/pkg/vm_service/test/get_memory_usage.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2019, 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 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/test_helper.dart';
+
+var tests = <VMTest>[
+ (VmService service) async {
+ final vm = await service.getVM();
+ final result = await service.getMemoryUsage(vm.isolates.first.id);
+ expect(result.heapUsage, isPositive);
+ expect(result.heapCapacity, isPositive);
+ expect(result.externalUsage, isPositive);
+ },
+ (VmService service) async {
+ bool caughtException;
+ try {
+ await service.getMemoryUsage('badid');
+ fail('Unreachable');
+ } on RPCError catch (e) {
+ caughtException = true;
+ expect(e.details,
+ contains("getMemoryUsage: invalid 'isolateId' parameter: badid"));
+ }
+ expect(caughtException, isTrue);
+ },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 4f60c40..6570f8b 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -117,6 +117,23 @@
}
}
+static_library("elf_loader") {
+ configs += [
+ "..:dart_arch_config",
+ "..:dart_config",
+ "..:dart_product_config",
+ "..:dart_os_fuchsia_config",
+ ]
+ include_dirs = [ ".." ]
+ sources = [
+ "elf_loader.cc",
+ "elf_loader.h",
+ ]
+ deps = [
+ ":libdart_builtin",
+ ]
+}
+
template("build_gen_snapshot") {
extra_configs = []
if (defined(invoker.extra_configs)) {
@@ -841,6 +858,9 @@
"main.cc",
"snapshot_empty.cc",
]
+
+ extra_deps += [ ":elf_loader" ]
+
if (dart_runtime_mode == "release") {
extra_sources += [ "observatory_assets_empty.cc" ]
}
@@ -862,6 +882,8 @@
"observatory_assets_empty.cc",
"snapshot_empty.cc",
]
+
+ extra_deps += [ ":elf_loader" ]
}
executable("process_test") {
diff --git a/runtime/bin/elf_loader.cc b/runtime/bin/elf_loader.cc
new file mode 100644
index 0000000..9672dbe
--- /dev/null
+++ b/runtime/bin/elf_loader.cc
@@ -0,0 +1,391 @@
+// Copyright (c) 2019, 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.
+
+#include <bin/elf_loader.h>
+#include <bin/file.h>
+#include <platform/elf.h>
+#include <platform/globals.h>
+#include <vm/cpu.h>
+#include <vm/virtual_memory.h>
+
+#include <memory>
+
+namespace dart {
+namespace bin {
+
+namespace elf {
+
+/// A loader for a subset of ELF which may be used to load objects produced by
+/// Dart_CreateAppAOTSnapshotAsElf.
+class LoadedElf {
+ public:
+ explicit LoadedElf(const char* filename)
+ : filename_(strdup(filename), std::free) {}
+ ~LoadedElf();
+
+ /// Loads the ELF object into memory. Returns whether the load was successful.
+ /// On failure, the error may be retrieved by 'error()'.
+ bool Load();
+
+ /// Reads Dart-specific symbols from the loaded ELF.
+ ///
+ /// Stores the address of the corresponding symbol in each non-null output
+ /// parameter.
+ ///
+ /// Fails if any output parameter is non-null but points to null and the
+ /// corresponding symbol was not found, or if the dynamic symbol table could
+ /// not be decoded.
+ ///
+ /// On failure, the error may be retrieved by 'error()'.
+ bool ResolveSymbols(const uint8_t** vm_data,
+ const uint8_t** vm_instrs,
+ const uint8_t** isolate_data,
+ const uint8_t** isolate_instrs);
+
+ const char* error() { return error_; }
+
+ private:
+ bool ReadHeader();
+ bool ReadProgramTable();
+ bool LoadSegments();
+ bool ReadSectionTable();
+ bool ReadSectionStringTable();
+ bool ReadSections();
+
+ static uword PageSize() { return VirtualMemory::PageSize(); }
+
+ // Unlike File::Map, allows non-aligned 'start' and 'length'.
+ MappedMemory* MapFilePiece(uword start,
+ uword length,
+ const void** mapping_start);
+
+ std::unique_ptr<char, decltype(std::free)*> filename_;
+
+ // Initialized on a successful Load().
+ File* file_;
+
+ // Initialized on error.
+ const char* error_ = nullptr;
+
+ // Initialized by ReadHeader().
+ dart::elf::ElfHeader header_;
+
+ // Initialized by ReadProgramTable().
+ std::unique_ptr<MappedMemory> program_table_mapping_;
+ const dart::elf::ProgramHeader* program_table_ = nullptr;
+
+ // Initialized by LoadSegments().
+ std::unique_ptr<VirtualMemory> base_;
+
+ // Initialized by ReadSectionTable().
+ std::unique_ptr<MappedMemory> section_table_mapping_;
+ const dart::elf::SectionHeader* section_table_ = nullptr;
+
+ // Initialized by ReadSectionStringTable().
+ std::unique_ptr<MappedMemory> section_string_table_mapping_;
+ const char* section_string_table_ = nullptr;
+
+ // Initialized by ReadSections().
+ const char* dynamic_string_table_ = nullptr;
+ const dart::elf::Symbol* dynamic_symbol_table_ = nullptr;
+ uword dynamic_symbol_count_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(LoadedElf);
+};
+
+#define CHECK(value) \
+ if (!(value)) { \
+ ASSERT(error_ != nullptr); \
+ return false; \
+ }
+
+#define ERROR(message) \
+ { \
+ error_ = (message); \
+ return false; \
+ }
+
+#define CHECK_ERROR(value, message) \
+ if (!(value)) { \
+ error_ = (message); \
+ return false; \
+ }
+
+bool LoadedElf::Load() {
+ VirtualMemory::Init();
+
+ if (error_ != nullptr) {
+ return false;
+ }
+
+ file_ = File::Open(/*namespc=*/nullptr, filename_.get(),
+ bin::File::FileOpenMode::kRead);
+ CHECK_ERROR(file_ != nullptr, "Cannot open ELF object file.");
+
+ CHECK(ReadHeader());
+ CHECK(ReadProgramTable());
+ CHECK(LoadSegments());
+ CHECK(ReadSectionTable());
+ CHECK(ReadSectionStringTable());
+ CHECK(ReadSections());
+
+ return true;
+}
+
+LoadedElf::~LoadedElf() {
+ // Unmap the image.
+ base_.reset();
+
+ // Explicitly destroy all the mappings before closing the file.
+ program_table_mapping_.reset();
+ section_table_mapping_.reset();
+ section_string_table_mapping_.reset();
+
+ if (file_ != nullptr) {
+ file_->Close();
+ file_->Release();
+ }
+}
+
+bool LoadedElf::ReadHeader() {
+ CHECK_ERROR(file_->ReadFully(&header_, sizeof(dart::elf::ElfHeader)),
+ "Could not read ELF file.");
+
+ CHECK_ERROR(header_.ident[dart::elf::EI_DATA] == dart::elf::ELFDATA2LSB,
+ "Expected little-endian ELF object.");
+
+ CHECK_ERROR(header_.type == dart::elf::ET_DYN,
+ "Can only load dynamic libraries.");
+
+#if defined(TARGET_ARCH_IA32)
+ CHECK_ERROR(header_.machine == dart::elf::EM_386, "Architecture mismatch.");
+#elif defined(TARGET_ARCH_X64)
+ CHECK_ERROR(header_.machine == dart::elf::EM_X86_64,
+ "Architecture mismatch.");
+#elif defined(TARGET_ARCH_ARM)
+ CHECK_ERROR(header_.machine == dart::elf::EM_ARM, "Architecture mismatch.");
+#elif defined(TARGET_ARCH_ARM64)
+ CHECK_ERROR(header_.machine == dart::elf::EM_AARCH64,
+ "Architecture mismatch.");
+#else
+#error Unsupported architecture architecture.
+#endif
+
+ CHECK_ERROR(header_.version == dart::elf::EV_CURRENT,
+ "Unexpected ELF version.");
+ CHECK_ERROR(header_.header_size == sizeof(dart::elf::ElfHeader),
+ "Unexpected header size.");
+ CHECK_ERROR(
+ header_.program_table_entry_size == sizeof(dart::elf::ProgramHeader),
+ "Unexpected program header size.");
+ CHECK_ERROR(
+ header_.section_table_entry_size == sizeof(dart::elf::SectionHeader),
+ "Unexpected section header size.");
+
+ return true;
+}
+
+bool LoadedElf::ReadProgramTable() {
+ const uword file_start = header_.program_table_offset;
+ const uword file_length =
+ header_.num_program_headers * sizeof(dart::elf::ProgramHeader);
+ program_table_mapping_.reset(
+ MapFilePiece(file_start, file_length,
+ reinterpret_cast<const void**>(&program_table_)));
+ CHECK_ERROR(program_table_mapping_ != nullptr,
+ "Could not mmap the program table.");
+ return true;
+}
+
+bool LoadedElf::ReadSectionTable() {
+ const uword file_start = header_.section_table_offset;
+ const uword file_length =
+ header_.num_section_headers * sizeof(dart::elf::SectionHeader);
+ section_table_mapping_.reset(
+ MapFilePiece(file_start, file_length,
+ reinterpret_cast<const void**>(§ion_table_)));
+ CHECK_ERROR(section_table_mapping_ != nullptr,
+ "Could not mmap the section table.");
+ return true;
+}
+
+bool LoadedElf::ReadSectionStringTable() {
+ const dart::elf::SectionHeader header =
+ section_table_[header_.shstrtab_section_index];
+ section_string_table_mapping_.reset(
+ MapFilePiece(header.file_offset, header.file_size,
+ reinterpret_cast<const void**>(§ion_string_table_)));
+ CHECK_ERROR(section_string_table_mapping_ != nullptr,
+ "Could not mmap the section string table.");
+ return true;
+}
+
+bool LoadedElf::LoadSegments() {
+ // Calculate the total amount of virtual memory needed.
+ uword total_memory = 0;
+ for (uword i = 0; i < header_.num_program_headers; ++i) {
+ const dart::elf::ProgramHeader header = program_table_[i];
+
+ // Only PT_LOAD segments need to be loaded.
+ if (header.type != dart::elf::ProgramHeaderType::PT_LOAD) continue;
+
+ total_memory = Utils::Maximum(
+ static_cast<uword>(header.memory_offset + header.memory_size),
+ total_memory);
+ CHECK_ERROR(Utils::IsPowerOfTwo(header.alignment),
+ "Alignment must be a power of two.");
+ CHECK_ERROR(header.alignment <= PageSize(),
+ "Cannot align greater than page size.")
+ }
+ total_memory = Utils::RoundUp(total_memory, PageSize());
+
+ base_.reset(VirtualMemory::AllocateAligned(
+ total_memory, /*alignment=*/PageSize(),
+ /*is_executable=*/false, /*mapping name=*/filename_.get()));
+ CHECK_ERROR(base_ != nullptr, "Could not reserve virtual memory.");
+
+ for (uword i = 0; i < header_.num_program_headers; ++i) {
+ const dart::elf::ProgramHeader header = program_table_[i];
+
+ // Only PT_LOAD segments need to be loaded.
+ if (header.type != dart::elf::ProgramHeaderType::PT_LOAD) continue;
+
+ const uword memory_offset = header.memory_offset,
+ file_offset = header.file_offset;
+ CHECK_ERROR(
+ (memory_offset % PageSize()) == (file_offset % PageSize()),
+ "Difference between file and memory offset must be page-aligned.");
+
+ const intptr_t adjustment = header.memory_offset % PageSize();
+
+ void* const memory_start =
+ static_cast<char*>(base_->address()) + memory_offset - adjustment;
+ const uword file_start = file_offset - adjustment;
+ const uword length = header.memory_size + adjustment;
+
+ File::MapType map_type = File::kReadOnly;
+ if (header.flags == (dart::elf::PF_R | dart::elf::PF_W)) {
+ map_type = File::kReadWrite;
+ } else if (header.flags == (dart::elf::PF_R | dart::elf::PF_X)) {
+ map_type = File::kReadExecute;
+ } else if (header.flags == dart::elf::PF_R) {
+ map_type = File::kReadOnly;
+ } else {
+ ERROR("Unsupported segment flag set.");
+ }
+
+ std::unique_ptr<MappedMemory> memory(
+ file_->Map(map_type, file_start, length, memory_start));
+ CHECK_ERROR(memory != nullptr, "Could not map segment.");
+ CHECK_ERROR(memory->address() == memory_start,
+ "Mapping not at requested address.");
+ }
+
+ return true;
+}
+
+bool LoadedElf::ReadSections() {
+ for (uword i = 0; i < header_.num_section_headers; ++i) {
+ const dart::elf::SectionHeader header = section_table_[i];
+ const char* const name = section_string_table_ + header.name;
+ if (strcmp(name, ".dynstr") == 0) {
+ CHECK_ERROR(header.memory_offset != 0, ".dynstr must be loaded.");
+ dynamic_string_table_ =
+ static_cast<const char*>(base_->address()) + header.memory_offset;
+ } else if (strcmp(name, ".dynsym") == 0) {
+ CHECK_ERROR(header.memory_offset != 0, ".dynsym must be loaded.");
+ dynamic_symbol_table_ = reinterpret_cast<const dart::elf::Symbol*>(
+ base_->start() + header.memory_offset);
+ dynamic_symbol_count_ = header.file_size / sizeof(dart::elf::Symbol);
+ }
+ }
+
+ CHECK_ERROR(dynamic_string_table_ != nullptr, "Couldn't find .dynstr.");
+ CHECK_ERROR(dynamic_symbol_table_ != nullptr, "Couldn't find .dynsym.");
+ return true;
+}
+
+bool LoadedElf::ResolveSymbols(const uint8_t** vm_data,
+ const uint8_t** vm_instrs,
+ const uint8_t** isolate_data,
+ const uint8_t** isolate_instrs) {
+ if (error_ != nullptr) {
+ return false;
+ }
+
+ // The first entry of the symbol table is reserved.
+ for (uword i = 1; i < dynamic_symbol_count_; ++i) {
+ const dart::elf::Symbol sym = dynamic_symbol_table_[i];
+ const char* name = dynamic_string_table_ + sym.name;
+ const uint8_t** output = nullptr;
+
+ if (strcmp(name, kVmSnapshotDataSymbolName) == 0) {
+ output = vm_data;
+ } else if (strcmp(name, kVmSnapshotInstructionsSymbolName) == 0) {
+ output = vm_instrs;
+ } else if (strcmp(name, kIsolateSnapshotDataSymbolName) == 0) {
+ output = isolate_data;
+ } else if (strcmp(name, kIsolateSnapshotInstructionsSymbolName) == 0) {
+ output = isolate_instrs;
+ }
+
+ if (output != nullptr) {
+ *output = reinterpret_cast<const uint8_t*>(base_->start() + sym.value);
+ }
+ }
+
+ CHECK_ERROR(vm_data == nullptr || *vm_data != nullptr,
+ "Could not find VM snapshot data.");
+ CHECK_ERROR(vm_instrs == nullptr || *vm_instrs != nullptr,
+ "Could not find VM snapshot instructions.");
+ CHECK_ERROR(isolate_data == nullptr || *isolate_data != nullptr,
+ "Could not find isolate snapshot data.");
+ CHECK_ERROR(isolate_instrs == nullptr || *isolate_instrs != nullptr,
+ "Could not find isolate instructions.");
+ return true;
+}
+
+MappedMemory* LoadedElf::MapFilePiece(uword file_start,
+ uword file_length,
+ const void** mem_start) {
+ const uword mapping_offset = Utils::RoundDown(file_start, PageSize());
+ const uword mapping_length =
+ Utils::RoundUp(file_length + file_start % PageSize(), PageSize());
+ MappedMemory* const mapping =
+ file_->Map(bin::File::kReadOnly, mapping_offset, mapping_length);
+
+ if (mapping != nullptr) {
+ *mem_start = reinterpret_cast<uint8_t*>(mapping->start() +
+ (file_start % PageSize()));
+ }
+
+ return mapping;
+}
+
+} // namespace elf
+} // namespace bin
+} // namespace dart
+
+DART_EXPORT void* Dart_LoadELF(const char* filename,
+ const char** error,
+ const uint8_t** vm_snapshot_data,
+ const uint8_t** vm_snapshot_instrs,
+ const uint8_t** vm_isolate_data,
+ const uint8_t** vm_isolate_instrs) {
+ std::unique_ptr<dart::bin::elf::LoadedElf> elf(
+ new dart::bin::elf::LoadedElf(filename));
+
+ if (!elf->Load() ||
+ !elf->ResolveSymbols(vm_snapshot_data, vm_snapshot_instrs,
+ vm_isolate_data, vm_isolate_instrs)) {
+ *error = elf->error();
+ return nullptr;
+ }
+
+ return elf.release();
+}
+
+DART_EXPORT void Dart_UnloadELF(void* loaded) {
+ delete reinterpret_cast<dart::bin::elf::LoadedElf*>(loaded);
+}
diff --git a/runtime/bin/elf_loader.h b/runtime/bin/elf_loader.h
new file mode 100644
index 0000000..b604ee6
--- /dev/null
+++ b/runtime/bin/elf_loader.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+#ifndef RUNTIME_BIN_ELF_LOADER_H_
+#define RUNTIME_BIN_ELF_LOADER_H_
+
+#include <include/dart_api.h>
+
+typedef void* LoadedElfLibrary;
+
+/// Loads an ELF object in 'filename'.
+///
+/// On success, returns a handle to the library which may be used to close it
+/// in Dart_UnloadELF. On error, returns 'nullptr' and sets 'error'. The error
+/// string should not be 'free'-d.
+///
+/// Looks up the Dart snapshot symbols "_kVmSnapshotData",
+/// "_kVmSnapshotInstructions", "_kVmIsoalteData" and "_kVmIsolateInstructions"
+/// into the respectively named out-parameters.
+DART_EXPORT LoadedElfLibrary Dart_LoadELF(const char* filename,
+ const char** error,
+ const uint8_t** vm_snapshot_data,
+ const uint8_t** vm_snapshot_instrs,
+ const uint8_t** vm_isolate_data,
+ const uint8_t** vm_isolate_instrs);
+
+DART_EXPORT void Dart_UnloadELF(LoadedElfLibrary loaded);
+
+#endif // RUNTIME_BIN_ELF_LOADER_H_
diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc
index 1b2f363..32c32a7 100644
--- a/runtime/bin/extensions_android.cc
+++ b/runtime/bin/extensions_android.cc
@@ -13,12 +13,6 @@
namespace dart {
namespace bin {
-const char* kVmSnapshotDataSymbolName = "_kDartVmSnapshotData";
-const char* kVmSnapshotInstructionsSymbolName = "_kDartVmSnapshotInstructions";
-const char* kIsolateSnapshotDataSymbolName = "_kDartIsolateSnapshotData";
-const char* kIsolateSnapshotInstructionsSymbolName =
- "_kDartIsolateSnapshotInstructions";
-
void* Extensions::LoadExtensionLibrary(const char* library_file) {
return dlopen(library_file, RTLD_LAZY);
}
diff --git a/runtime/bin/extensions_fuchsia.cc b/runtime/bin/extensions_fuchsia.cc
index 64df6b6..de71763 100644
--- a/runtime/bin/extensions_fuchsia.cc
+++ b/runtime/bin/extensions_fuchsia.cc
@@ -17,12 +17,6 @@
namespace dart {
namespace bin {
-const char* kVmSnapshotDataSymbolName = "_kDartVmSnapshotData";
-const char* kVmSnapshotInstructionsSymbolName = "_kDartVmSnapshotInstructions";
-const char* kIsolateSnapshotDataSymbolName = "_kDartIsolateSnapshotData";
-const char* kIsolateSnapshotInstructionsSymbolName =
- "_kDartIsolateSnapshotInstructions";
-
void* Extensions::LoadExtensionLibrary(const char* library_file) {
return dlopen(library_file, RTLD_LAZY);
}
diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc
index d8972a7..e2359d0 100644
--- a/runtime/bin/extensions_linux.cc
+++ b/runtime/bin/extensions_linux.cc
@@ -13,12 +13,6 @@
namespace dart {
namespace bin {
-const char* kVmSnapshotDataSymbolName = "_kDartVmSnapshotData";
-const char* kVmSnapshotInstructionsSymbolName = "_kDartVmSnapshotInstructions";
-const char* kIsolateSnapshotDataSymbolName = "_kDartIsolateSnapshotData";
-const char* kIsolateSnapshotInstructionsSymbolName =
- "_kDartIsolateSnapshotInstructions";
-
void* Extensions::LoadExtensionLibrary(const char* library_file) {
return dlopen(library_file, RTLD_LAZY);
}
diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc
index 7007f4a..f5436a0 100644
--- a/runtime/bin/extensions_macos.cc
+++ b/runtime/bin/extensions_macos.cc
@@ -13,12 +13,6 @@
namespace dart {
namespace bin {
-const char* kVmSnapshotDataSymbolName = "kDartVmSnapshotData";
-const char* kVmSnapshotInstructionsSymbolName = "kDartVmSnapshotInstructions";
-const char* kIsolateSnapshotDataSymbolName = "kDartIsolateSnapshotData";
-const char* kIsolateSnapshotInstructionsSymbolName =
- "kDartIsolateSnapshotInstructions";
-
void* Extensions::LoadExtensionLibrary(const char* library_file) {
return dlopen(library_file, RTLD_LAZY);
}
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 8baf714..d9fecd5 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -13,12 +13,6 @@
namespace dart {
namespace bin {
-const char* kVmSnapshotDataSymbolName = "_kDartVmSnapshotData";
-const char* kVmSnapshotInstructionsSymbolName = "_kDartVmSnapshotInstructions";
-const char* kIsolateSnapshotDataSymbolName = "_kDartIsolateSnapshotData";
-const char* kIsolateSnapshotInstructionsSymbolName =
- "_kDartIsolateSnapshotInstructions";
-
void* Extensions::LoadExtensionLibrary(const char* library_file) {
SetLastError(0);
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 928fbdd..eacd0ca 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -24,15 +24,23 @@
class MappedMemory {
public:
- MappedMemory(void* address, intptr_t size) : address_(address), size_(size) {}
- ~MappedMemory() { Unmap(); }
+ MappedMemory(void* address, intptr_t size, bool should_unmap = true)
+ : should_unmap_(should_unmap), address_(address), size_(size) {}
+ ~MappedMemory() {
+ if (should_unmap_) Unmap();
+ }
void* address() const { return address_; }
intptr_t size() const { return size_; }
+ uword start() const { return reinterpret_cast<uword>(address()); }
private:
void Unmap();
+ // False for mappings which reside inside another, and will be removed when
+ // the outer mapping is removed.
+ bool should_unmap_;
+
void* address_;
intptr_t size_;
@@ -100,8 +108,30 @@
enum MapType {
kReadOnly = 0,
kReadExecute = 1,
+ kReadWrite = 2,
};
- MappedMemory* Map(MapType type, int64_t position, int64_t length);
+
+ /// Maps or copies the file into memory.
+ ///
+ /// 'position' and 'length' should be page-aligned.
+ ///
+ /// If 'start' is zero, allocates virtual memory for the mapping. When the
+ /// returned 'MappedMemory' is destroyed, the mapping is removed.
+ ///
+ /// If 'start' is non-zero, it must point within a suitably sized existing
+ /// mapping. The returned 'MappedMemory' will not remove the mapping when it
+ /// is destroyed; rather, the mapping will be removed when the enclosing
+ /// mapping is removed. This mode is not supported on Fuchsia.
+ ///
+ /// If 'type' is 'kReadWrite', writes to the mapping are *not* copied back to
+ /// the file.
+ ///
+ /// 'position' + 'length' may be larger than the file size. In this case, the
+ /// extra memory is zero-filled.
+ MappedMemory* Map(MapType type,
+ int64_t position,
+ int64_t length,
+ void* start = nullptr);
// Read/Write attempt to transfer num_bytes to/from buffer. It returns
// the number of bytes read/written.
@@ -172,7 +202,7 @@
// reading. If mode contains kWrite the file is opened for both
// reading and writing. If mode contains kWrite and the file does
// not exist the file is created. The file is truncated to length 0 if
- // mode contains kTruncate. Assumes we are in an API scope.
+ // mode contains kTruncate.
static File* Open(Namespace* namespc, const char* path, FileOpenMode mode);
// Same as [File::Open], but attempts to convert uri to path before opening
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index c634b0d..6fa50ad 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -76,7 +76,10 @@
return handle_->fd() == kClosedFd;
}
-MappedMemory* File::Map(MapType type, int64_t position, int64_t length) {
+MappedMemory* File::Map(MapType type,
+ int64_t position,
+ int64_t length,
+ void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
int prot = PROT_NONE;
@@ -87,14 +90,16 @@
case kReadExecute:
prot = PROT_READ | PROT_EXEC;
break;
- default:
- return NULL;
+ case kReadWrite:
+ prot = PROT_READ | PROT_WRITE;
+ break;
}
- void* addr = mmap(NULL, length, prot, MAP_PRIVATE, handle_->fd(), position);
+ const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
+ void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
- return new MappedMemory(addr, length);
+ return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}
void MappedMemory::Unmap() {
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index 74e3c50..64cc848 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -75,7 +75,10 @@
return handle_->fd() == kClosedFd;
}
-MappedMemory* File::Map(MapType type, int64_t position, int64_t length) {
+MappedMemory* File::Map(MapType type,
+ int64_t position,
+ int64_t length,
+ void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
int prot = PROT_NONE;
@@ -86,14 +89,16 @@
case kReadExecute:
prot = PROT_READ | PROT_EXEC;
break;
- default:
- return NULL;
+ case kReadWrite:
+ prot = PROT_READ | PROT_WRITE;
+ break;
}
- void* addr = mmap(NULL, length, prot, MAP_PRIVATE, handle_->fd(), position);
+ const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
+ void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
- return new MappedMemory(addr, length);
+ return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}
void MappedMemory::Unmap() {
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index e6db3ad..190b195 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -75,7 +75,10 @@
return handle_->fd() == kClosedFd;
}
-MappedMemory* File::Map(MapType type, int64_t position, int64_t length) {
+MappedMemory* File::Map(MapType type,
+ int64_t position,
+ int64_t length,
+ void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
int prot = PROT_NONE;
@@ -86,14 +89,16 @@
case kReadExecute:
prot = PROT_READ | PROT_EXEC;
break;
- default:
- return NULL;
+ case kReadWrite:
+ prot = PROT_READ | PROT_WRITE;
+ break;
}
- void* addr = mmap(NULL, length, prot, MAP_PRIVATE, handle_->fd(), position);
+ const int flags = MAP_PRIVATE | (start != nullptr ? MAP_FIXED : 0);
+ void* addr = mmap(start, length, prot, flags, handle_->fd(), position);
if (addr == MAP_FAILED) {
return NULL;
}
- return new MappedMemory(addr, length);
+ return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}
void MappedMemory::Unmap() {
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 7315cfe..2e13282 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -76,7 +76,10 @@
return handle_->fd() == kClosedFd;
}
-MappedMemory* File::Map(MapType type, int64_t position, int64_t length) {
+MappedMemory* File::Map(MapType type,
+ int64_t position,
+ int64_t length,
+ void* start) {
ASSERT(handle_->fd() >= 0);
ASSERT(length > 0);
int prot = PROT_NONE;
@@ -91,34 +94,58 @@
map_flags |= (MAP_JIT | MAP_ANONYMOUS);
}
break;
- default:
- return NULL;
+ case kReadWrite:
+ prot = PROT_READ | PROT_WRITE;
+ break;
}
- void* addr = NULL;
+ if (start != nullptr) {
+ map_flags |= MAP_FIXED;
+ }
+ void* addr = start;
if ((type == kReadExecute) && IsAtLeastOS10_14()) {
- addr = mmap(NULL, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
- if (addr == MAP_FAILED) {
- Syslog::PrintErr("mmap failed %s\n", strerror(errno));
- return NULL;
+ // Due to codesigning restrictions, we cannot map the file as executable
+ // directly. We must first copy it into an anonymous mapping and then mark
+ // the mapping as executable.
+ if (addr == nullptr) {
+ addr = mmap(nullptr, length, (PROT_READ | PROT_WRITE), map_flags, -1, 0);
+ if (addr == MAP_FAILED) {
+ Syslog::PrintErr("mmap failed %s\n", strerror(errno));
+ return nullptr;
+ }
}
+
+ const int64_t remaining_length = Length() - position;
SetPosition(position);
- if (!ReadFully(addr, length)) {
+ if (!ReadFully(addr, Utils::Minimum(length, remaining_length))) {
Syslog::PrintErr("ReadFully failed\n");
- munmap(addr, length);
- return NULL;
+ if (start == nullptr) {
+ munmap(addr, length);
+ }
+ return nullptr;
}
+
+ // If the requested mapping is larger than the file size, we should fill the
+ // extra memory with zeros.
+ if (length > remaining_length) {
+ memset(reinterpret_cast<uint8_t*>(addr) + remaining_length, 0,
+ length - remaining_length);
+ }
+
if (mprotect(addr, length, prot) != 0) {
Syslog::PrintErr("mprotect failed %s\n", strerror(errno));
- munmap(addr, length);
- return NULL;
+ if (start == nullptr) {
+ munmap(addr, length);
+ }
+ return nullptr;
}
} else {
- addr = mmap(NULL, length, prot, map_flags, handle_->fd(), position);
+ addr = mmap(addr, length, prot, map_flags, handle_->fd(), position);
+ if (addr == MAP_FAILED) {
+ Syslog::PrintErr("mmap failed %s\n", strerror(errno));
+ return nullptr;
+ }
}
- if (addr == MAP_FAILED) {
- return NULL;
- }
- return new MappedMemory(addr, length);
+ return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}
void MappedMemory::Unmap() {
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index d0011be..f5c6010 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -73,7 +73,10 @@
return handle_->fd() == kClosedFd;
}
-MappedMemory* File::Map(File::MapType type, int64_t position, int64_t length) {
+MappedMemory* File::Map(File::MapType type,
+ int64_t position,
+ int64_t length,
+ void* start) {
DWORD prot_alloc;
DWORD prot_final;
switch (type) {
@@ -85,31 +88,48 @@
prot_alloc = PAGE_EXECUTE_READWRITE;
prot_final = PAGE_EXECUTE_READ;
break;
- default:
- return NULL;
+ case File::kReadWrite:
+ prot_alloc = PAGE_READWRITE;
+ prot_final = PAGE_READWRITE;
+ break;
}
- void* addr = VirtualAlloc(NULL, length, MEM_COMMIT | MEM_RESERVE, prot_alloc);
- if (addr == NULL) {
- Syslog::PrintErr("VirtualAlloc failed %d\n", GetLastError());
- return NULL;
+ void* addr = start;
+ if (addr == nullptr) {
+ addr = VirtualAlloc(nullptr, length, MEM_COMMIT | MEM_RESERVE, prot_alloc);
+ if (addr == nullptr) {
+ Syslog::PrintErr("VirtualAlloc failed %d\n", GetLastError());
+ return nullptr;
+ }
}
+ const int64_t remaining_length = Length() - position;
SetPosition(position);
- if (!ReadFully(addr, length)) {
+ if (!ReadFully(addr, Utils::Minimum(length, remaining_length))) {
Syslog::PrintErr("ReadFully failed %d\n", GetLastError());
- VirtualFree(addr, 0, MEM_RELEASE);
- return NULL;
+ if (start == nullptr) {
+ VirtualFree(addr, 0, MEM_RELEASE);
+ }
+ return nullptr;
+ }
+
+ // If the requested mapping is larger than the file size, we should fill the
+ // extra memory with zeros.
+ if (length > remaining_length) {
+ memset(reinterpret_cast<uint8_t*>(addr) + remaining_length, 0,
+ length - remaining_length);
}
DWORD old_prot;
bool result = VirtualProtect(addr, length, prot_final, &old_prot);
if (!result) {
Syslog::PrintErr("VirtualProtect failed %d\n", GetLastError());
- VirtualFree(addr, 0, MEM_RELEASE);
- return NULL;
+ if (start == nullptr) {
+ VirtualFree(addr, 0, MEM_RELEASE);
+ }
+ return nullptr;
}
- return new MappedMemory(addr, length);
+ return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}
void MappedMemory::Unmap() {
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index 673e556..aceba6c 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -8,6 +8,7 @@
#include "bin/dartutils.h"
#include "bin/dfe.h"
+#include "bin/elf_loader.h"
#include "bin/error_exit.h"
#include "bin/extensions.h"
#include "bin/file.h"
@@ -20,11 +21,6 @@
namespace dart {
namespace bin {
-extern const char* kVmSnapshotDataSymbolName;
-extern const char* kVmSnapshotInstructionsSymbolName;
-extern const char* kIsolateSnapshotDataSymbolName;
-extern const char* kIsolateSnapshotInstructionsSymbolName;
-
static const int64_t kAppSnapshotHeaderSize = 5 * kInt64Size;
static const int64_t kAppSnapshotPageSize = 4 * KB;
@@ -179,9 +175,12 @@
if (!file->ReadFully(&appended_header, sizeof(appended_header))) {
return nullptr;
}
+ // Length is always encoded as Little Endian.
+ const uint64_t appended_length =
+ Utils::LittleEndianToHost64(appended_header[0]);
if (memcmp(&appended_header[1], appjit_magic_number.bytes,
appjit_magic_number.length) != 0 ||
- appended_header[0] <= 0 || !file->SetPosition(appended_header[0])) {
+ appended_length <= 0 || !file->SetPosition(appended_length)) {
return nullptr;
}
@@ -189,6 +188,42 @@
}
#if defined(DART_PRECOMPILED_RUNTIME)
+
+#if defined(TARGET_OS_WINDOWS) || defined(USING_SIMULATOR)
+class ElfAppSnapshot : public AppSnapshot {
+ public:
+ ElfAppSnapshot(LoadedElfLibrary elf,
+ const uint8_t* vm_snapshot_data,
+ const uint8_t* vm_snapshot_instructions,
+ const uint8_t* isolate_snapshot_data,
+ const uint8_t* isolate_snapshot_instructions)
+ : elf_(elf),
+ vm_snapshot_data_(vm_snapshot_data),
+ vm_snapshot_instructions_(vm_snapshot_instructions),
+ isolate_snapshot_data_(isolate_snapshot_data),
+ isolate_snapshot_instructions_(isolate_snapshot_instructions) {}
+
+ virtual ~ElfAppSnapshot() { Dart_UnloadELF(elf_); }
+
+ void SetBuffers(const uint8_t** vm_data_buffer,
+ const uint8_t** vm_instructions_buffer,
+ const uint8_t** isolate_data_buffer,
+ const uint8_t** isolate_instructions_buffer) {
+ *vm_data_buffer = vm_snapshot_data_;
+ *vm_instructions_buffer = vm_snapshot_instructions_;
+ *isolate_data_buffer = isolate_snapshot_data_;
+ *isolate_instructions_buffer = isolate_snapshot_instructions_;
+ }
+
+ private:
+ LoadedElfLibrary elf_;
+ const uint8_t* vm_snapshot_data_;
+ const uint8_t* vm_snapshot_instructions_;
+ const uint8_t* isolate_snapshot_data_;
+ const uint8_t* isolate_snapshot_instructions_;
+};
+#endif // defined(TARGET_OS_WINDOWS) || defined(USING_SIMULATOR)
+
class DylibAppSnapshot : public AppSnapshot {
public:
DylibAppSnapshot(void* library,
@@ -258,17 +293,37 @@
return new DylibAppSnapshot(library, vm_data_buffer, vm_instructions_buffer,
isolate_data_buffer, isolate_instructions_buffer);
}
+
+static AppSnapshot* TryReadAppSnapshotElf(const char* script_name) {
+#if defined(TARGET_OS_WINDOWS) || defined(USING_SIMULATOR)
+ const char* error = nullptr;
+ const uint8_t *vm_data_buffer = nullptr, *vm_instructions_buffer = nullptr,
+ *isolate_data_buffer = nullptr,
+ *isolate_instructions_buffer = nullptr;
+ void* handle = Dart_LoadELF(script_name, &error, &vm_data_buffer,
+ &vm_instructions_buffer, &isolate_data_buffer,
+ &isolate_instructions_buffer);
+ if (handle == nullptr) {
+ Syslog::PrintErr("Loading failed: %s\n", error);
+ return nullptr;
+ }
+ return new ElfAppSnapshot(handle, vm_data_buffer, vm_instructions_buffer,
+ isolate_data_buffer, isolate_instructions_buffer);
+#else
+ return nullptr;
+#endif
+}
#endif // defined(DART_PRECOMPILED_RUNTIME)
AppSnapshot* Snapshot::TryReadAppSnapshot(const char* script_name) {
- if (File::GetType(NULL, script_name, true) != File::kIsFile) {
+ if (File::GetType(nullptr, script_name, true) != File::kIsFile) {
// If 'script_name' refers to a pipe, don't read to check for an app
// snapshot since we cannot rewind if it isn't (and couldn't mmap it in
// anyway if it was).
- return NULL;
+ return nullptr;
}
AppSnapshot* snapshot = TryReadAppSnapshotBlobs(script_name);
- if (snapshot != NULL) {
+ if (snapshot != nullptr) {
return snapshot;
}
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -284,12 +339,16 @@
#endif
snapshot = TryReadAppSnapshotDynamicLibrary(script_name);
+ if (snapshot != nullptr) {
+ return snapshot;
+ }
- if (snapshot != NULL) {
+ snapshot = TryReadAppSnapshotElf(script_name);
+ if (snapshot != nullptr) {
return snapshot;
}
#endif // defined(DART_PRECOMPILED_RUNTIME)
- return NULL;
+ return nullptr;
}
#if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 3d060be..d6d34c6 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1113,7 +1113,8 @@
* the vm isolate on startup and fast initialization of an isolate.
* A Snapshot of the heap is created before any dart code has executed.
*
- * Requires there to be a current isolate.
+ * Requires there to be a current isolate. Not available in the precompiled
+ * runtime (check Dart_IsPrecompiledRuntime).
*
* \param buffer Returns a pointer to a buffer containing the
* snapshot. This buffer is scope allocated and is only valid
@@ -3283,8 +3284,7 @@
* \return Returns true if the profile is successfully written and false
* otherwise.
*/
-DART_EXPORT bool Dart_WriteProfileToTimeline(Dart_Port main_port,
- char** error);
+DART_EXPORT bool Dart_WriteProfileToTimeline(Dart_Port main_port, char** error);
/*
* ====================
@@ -3360,16 +3360,30 @@
const uint8_t* buffer,
intptr_t size);
+#if defined(__APPLE__)
+#define kVmSnapshotDataSymbolName "kDartVmSnapshotData"
+#define kVmSnapshotInstructionsSymbolName "kDartVmSnapshotInstructions"
+#define kIsolateSnapshotDataSymbolName "kDartIsolateSnapshotData"
+#define kIsolateSnapshotInstructionsSymbolName \
+ "kDartIsolateSnapshotInstructions"
+#else
+#define kVmSnapshotDataSymbolName "_kDartVmSnapshotData"
+#define kVmSnapshotInstructionsSymbolName "_kDartVmSnapshotInstructions"
+#define kIsolateSnapshotDataSymbolName "_kDartIsolateSnapshotData"
+#define kIsolateSnapshotInstructionsSymbolName \
+ "_kDartIsolateSnapshotInstructions"
+#endif
+
/**
* Creates a precompiled snapshot.
* - A root library must have been loaded.
* - Dart_Precompile must have been called.
*
* Outputs an assembly file defining the symbols
- * - kDartVmSnapshotData
- * - kDartVmSnapshotInstructions
- * - kDartIsolateSnapshotData
- * - kDartIsolateSnapshotInstructions
+ * - _kDartVmSnapshotData
+ * - _kDartVmSnapshotInstructions
+ * - _kDartIsolateSnapshotData
+ * - _kDartIsolateSnapshotInstructions
*
* The assembly should be compiled as a static or shared library and linked or
* loaded by the embedder.
@@ -3392,10 +3406,10 @@
* - Dart_Precompile must have been called.
*
* Outputs an ELF shared library defining the symbols
- * - kDartVmSnapshotData
- * - kDartVmSnapshotInstructions
- * - kDartIsolateSnapshotData
- * - kDartIsolateSnapshotInstructions
+ * - _kDartVmSnapshotData
+ * - _kDartVmSnapshotInstructions
+ * - _kDartIsolateSnapshotData
+ * - _kDartIsolateSnapshotInstructions
*
* The shared library should be dynamically loaded by the embedder.
* Running this snapshot requires a VM compiled with DART_PRECOMPILED_SNAPSHOT.
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index deec036..24b65e3 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -46,7 +46,7 @@
virtual void VisitIsolate(Isolate* isolate) {
ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
- if (IsVMInternalIsolate(isolate)) {
+ if (!FLAG_show_invisible_isolates && IsVMInternalIsolate(isolate)) {
// We do not register the service (and descendants), the vm-isolate, or
// the kernel isolate.
return;
diff --git a/runtime/lib/wasm.cc b/runtime/lib/wasm.cc
index d4f315d..a94aac9 100644
--- a/runtime/lib/wasm.cc
+++ b/runtime/lib/wasm.cc
@@ -17,7 +17,6 @@
namespace dart {
static void ThrowWasmerError() {
- TransitionNativeToVM transition(Thread::Current());
String& error = String::Handle();
{
int len = wasmer_last_error_length();
@@ -27,6 +26,7 @@
error = String::NewFormatted("Wasmer error: %s", raw_error.get());
}
Exceptions::ThrowArgumentError(error);
+ UNREACHABLE();
}
template <typename T>
@@ -107,6 +107,57 @@
return ExternalTypedData::New(kExternalTypedDataUint8ArrayCid, data, size);
}
+std::ostream& operator<<(std::ostream& o, const wasmer_byte_array& str) {
+ for (uint32_t i = 0; i < str.bytes_len; ++i) {
+ o << str.bytes[i];
+ }
+ return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const wasmer_import_export_kind& io) {
+ switch (io) {
+ case wasmer_import_export_kind::WASM_FUNCTION:
+ return o << "WASM_FUNCTION";
+ case wasmer_import_export_kind::WASM_GLOBAL:
+ return o << "WASM_GLOBAL";
+ case wasmer_import_export_kind::WASM_MEMORY:
+ return o << "WASM_MEMORY";
+ case wasmer_import_export_kind::WASM_TABLE:
+ return o << "WASM_TABLE";
+ }
+}
+
+RawString* DescribeModule(const wasmer_module_t* module) {
+ std::stringstream desc;
+
+ desc << "Imports:\n";
+ wasmer_import_descriptors_t* imports;
+ wasmer_import_descriptors(module, &imports);
+ unsigned num_imports = wasmer_import_descriptors_len(imports);
+ for (unsigned i = 0; i < num_imports; ++i) {
+ wasmer_import_descriptor_t* imp = wasmer_import_descriptors_get(imports, i);
+ desc << "\t" << wasmer_import_descriptor_module_name(imp);
+ desc << "\t" << wasmer_import_descriptor_name(imp);
+ desc << "\t" << wasmer_import_descriptor_kind(imp);
+ desc << "\n";
+ }
+ wasmer_import_descriptors_destroy(imports);
+
+ desc << "\nExports:\n";
+ wasmer_export_descriptors_t* exports;
+ wasmer_export_descriptors(module, &exports);
+ unsigned num_exports = wasmer_export_descriptors_len(exports);
+ for (unsigned i = 0; i < num_exports; ++i) {
+ wasmer_export_descriptor_t* exp = wasmer_export_descriptors_get(exports, i);
+ desc << "\t" << wasmer_export_descriptor_name(exp);
+ desc << "\t" << wasmer_export_descriptor_kind(exp);
+ desc << "\n";
+ }
+ wasmer_export_descriptors_destroy(exports);
+
+ return String::New(desc.str().c_str());
+}
+
class WasmImports {
public:
explicit WasmImports(std::unique_ptr<char[]> module_name)
@@ -183,10 +234,9 @@
return dart_ret == _ret;
}
- bool Call(const wasmer_value_t* params, wasmer_value_t* result) {
+ wasmer_result_t Call(const wasmer_value_t* params, wasmer_value_t* result) {
return wasmer_export_func_call(_fn, params, _args.length(), result,
- IsVoid() ? 0 : 1) ==
- wasmer_result_t::WASMER_OK;
+ IsVoid() ? 0 : 1);
}
void Print(std::ostream& o, const char* name) const {
@@ -380,13 +430,15 @@
}
wasmer_module_t* module;
+ wasmer_result_t result;
{
TransitionVMToNative transition(thread);
- if (wasmer_compile(&module, data_copy.get(), len) !=
- wasmer_result_t::WASMER_OK) {
- data_copy.reset();
- ThrowWasmerError();
- }
+ result = wasmer_compile(&module, data_copy.get(), len);
+ }
+ if (result != wasmer_result_t::WASMER_OK) {
+ data_copy.reset();
+ ThrowWasmerError();
+ UNREACHABLE();
}
mod_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(module));
@@ -396,6 +448,17 @@
return Object::null();
}
+DEFINE_NATIVE_ENTRY(Wasm_describeModule, 0, 1) {
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, mod_wrap, arguments->NativeArgAt(0));
+
+ ASSERT(mod_wrap.NumNativeFields() == 1);
+
+ wasmer_module_t* module =
+ reinterpret_cast<wasmer_module_t*>(mod_wrap.GetNativeField(0));
+
+ return DescribeModule(module);
+}
+
DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(Instance, imp_wrap, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(String, module_name, arguments->NativeArgAt(1));
@@ -444,6 +507,7 @@
if (!ToWasmValue(value, type.type_class_id(), &wasm_value)) {
Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
"Can't convert dart value to WASM global variable")));
+ UNREACHABLE();
}
imports->AddGlobal(ToUTF8(name), wasm_value, mutable_.value());
@@ -458,19 +522,19 @@
ASSERT(mem_wrap.NumNativeFields() == 1);
const int64_t init_size = init.AsInt64Value();
- const int64_t max_size = max.AsInt64Value();
wasmer_memory_t* memory;
wasmer_limits_t descriptor;
descriptor.min = init_size;
- if (max_size < 0) {
+ if (max.IsNull()) {
descriptor.max.has_some = false;
} else {
descriptor.max.has_some = true;
- descriptor.max.some = max_size;
+ descriptor.max.some = max.AsInt64Value();
}
if (wasmer_memory_new(&memory, descriptor) != wasmer_result_t::WASMER_OK) {
ThrowWasmerError();
+ UNREACHABLE();
}
mem_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(memory));
FinalizablePersistentHandle::New(thread->isolate(), mem_wrap, memory,
@@ -489,6 +553,7 @@
if (wasmer_memory_grow(memory, delta.AsInt64Value()) !=
wasmer_result_t::WASMER_OK) {
ThrowWasmerError();
+ UNREACHABLE();
}
return WasmMemoryToExternalTypedData(memory);
}
@@ -518,6 +583,7 @@
}
if (inst == nullptr) {
ThrowWasmerError();
+ UNREACHABLE();
}
inst_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(inst));
@@ -560,6 +626,7 @@
if (fn == nullptr) {
Exceptions::ThrowArgumentError(error);
+ UNREACHABLE();
}
fn_wrap.SetNativeField(0, reinterpret_cast<intptr_t>(fn));
@@ -579,6 +646,7 @@
Exceptions::ThrowArgumentError(String::Handle(String::NewFormatted(
"Wrong number of args. Expected %" Pu " but found %" Pd ".",
fn->args().length(), args.Length())));
+ UNREACHABLE();
}
auto params = std::unique_ptr<wasmer_value_t[]>(
new wasmer_value_t[fn->args().length()]);
@@ -588,16 +656,20 @@
params.reset();
Exceptions::ThrowArgumentError(String::Handle(
String::NewFormatted("Arg %" Pd " is the wrong type.", i)));
+ UNREACHABLE();
}
}
wasmer_value_t ret;
+ wasmer_result_t result;
{
TransitionVMToNative transition(thread);
- if (!fn->Call(params.get(), &ret)) {
- params.reset();
- ThrowWasmerError();
- }
+ result = fn->Call(params.get(), &ret);
+ }
+ if (result != wasmer_result_t::WASMER_OK) {
+ params.reset();
+ ThrowWasmerError();
+ UNREACHABLE();
}
return fn->IsVoid() ? Object::null() : ToDartObject(ret);
}
@@ -617,6 +689,11 @@
return nullptr;
}
+DEFINE_NATIVE_ENTRY(Wasm_describeModule, 0, 1) {
+ Exceptions::ThrowUnsupportedError("WASM is disabled");
+ return nullptr;
+}
+
DEFINE_NATIVE_ENTRY(Wasm_initImports, 0, 2) {
Exceptions::ThrowUnsupportedError("WASM is disabled");
return nullptr;
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index fffb41c..e173438 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2222,8 +2222,8 @@
if (map['flag'] != null) {
flag = map['flag'];
}
- if (map['new_value'] != null) {
- newValue = map['new_value'];
+ if (map['newValue'] != null) {
+ newValue = map['newValue'];
}
}
diff --git a/runtime/observatory/tests/service/breakpoint_non_debuggable_library_test.dart b/runtime/observatory/tests/service/breakpoint_non_debuggable_library_test.dart
new file mode 100644
index 0000000..7656a7b
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_non_debuggable_library_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2019, 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:developer';
+import 'package:observatory/service_io.dart';
+import 'package:path/path.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const String file = 'package:path/path.dart';
+// At join() function
+const int LINE_A = 259;
+// At current getter function
+const int LINE_B = 84;
+
+testMain() {
+ print(join('test', 'test'));
+}
+
+var tests = <IsolateTest>[
+ hasPausedAtStart,
+ (Isolate isolate) async {
+ // Mark 'package:path/path.dart' as not debuggable.
+ await isolate.reload();
+ Library path =
+ isolate.libraries.firstWhere((Library library) => library.uri == file);
+ await path.load();
+ expect(path.debuggable, true);
+
+ // SetBreakpoint before setting library to non-debuggable.
+ // Breakpoints are allowed to be set (before marking library as non-debuggable) but are not hit when running (after marking library as non-debuggable).
+ Script script = path.scripts.single;
+ Breakpoint bpt = await isolate.addBreakpoint(script, LINE_A);
+ print("Breakpoint is $bpt");
+ expect(bpt, isNotNull);
+ expect(bpt is Breakpoint, isTrue);
+
+ // Set breakpoint and check later that this breakpoint won't be added if library is non-debuggable.
+ bpt = await isolate.addBreakpoint(script, LINE_B);
+ print("Breakpoint is $bpt");
+ expect(bpt, isNotNull);
+ expect(bpt is Breakpoint, isTrue);
+ await script.reload();
+ // Remove breakpoint.
+ var res = await isolate.removeBreakpoint(bpt);
+ expect(res.type, 'Success');
+
+ var setDebugParams = {
+ 'libraryId': path.id,
+ 'isDebuggable': false,
+ };
+ Map<String, dynamic> result = await isolate.invokeRpcNoUpgrade(
+ 'setLibraryDebuggable', setDebugParams);
+ expect(result['type'], 'Success');
+ await path.reload();
+ expect(path.debuggable, false);
+ print('$path is debuggable: ${path.debuggable}');
+
+ // Breakpoints are not allowed to set on non-debuggable libraries.
+ try {
+ await isolate.addBreakpoint(script, LINE_B);
+ } catch (e) {
+ expect(e is ServerRpcException, true);
+ expect(e.code == ServerRpcException.kCannotAddBreakpoint, true);
+ print("Set Breakpoint to non-debuggable library is not allowed");
+ }
+ },
+ resumeIsolate,
+ hasStoppedAtExit,
+ resumeIsolate
+];
+
+main(args) => runIsolateTests(args, tests,
+ testeeConcurrent: testMain, pause_on_start: true, pause_on_exit: true);
diff --git a/runtime/platform/elf.h b/runtime/platform/elf.h
new file mode 100644
index 0000000..729ac7d
--- /dev/null
+++ b/runtime/platform/elf.h
@@ -0,0 +1,170 @@
+// Copyright (c) 2019, 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.
+
+#ifndef RUNTIME_PLATFORM_ELF_H_
+#define RUNTIME_PLATFORM_ELF_H_
+
+#include "platform/globals.h"
+
+namespace dart {
+namespace elf {
+
+#pragma pack(push, 1)
+
+struct ElfHeader {
+ uint8_t ident[16];
+ uint16_t type;
+ uint16_t machine;
+ uint32_t version;
+#if defined(TARGET_ARCH_IS_32_BIT)
+ uint32_t entry_point;
+ uint32_t program_table_offset;
+ uint32_t section_table_offset;
+#else
+ uint64_t entry_point;
+ uint64_t program_table_offset;
+ uint64_t section_table_offset;
+#endif
+ uint32_t flags;
+ uint16_t header_size;
+ uint16_t program_table_entry_size;
+ uint16_t num_program_headers;
+ uint16_t section_table_entry_size;
+ uint16_t num_section_headers;
+ uint16_t shstrtab_section_index;
+};
+
+enum class ProgramHeaderType : uint32_t {
+ PT_LOAD = 1,
+ PT_DYNAMIC = 2,
+ PT_PHDR = 6,
+};
+
+struct ProgramHeader {
+#if defined(TARGET_ARCH_IS_32_BIT)
+ ProgramHeaderType type;
+ uint32_t file_offset;
+ uint32_t memory_offset;
+ uint32_t physical_memory_offset;
+ uint32_t file_size;
+ uint32_t memory_size;
+ uint32_t flags;
+ uint32_t alignment;
+#else
+ ProgramHeaderType type;
+ uint32_t flags;
+ uint64_t file_offset;
+ uint64_t memory_offset;
+ uint64_t physical_memory_offset;
+ uint64_t file_size;
+ uint64_t memory_size;
+ uint64_t alignment;
+#endif
+};
+
+struct SectionHeader {
+#if defined(TARGET_ARCH_IS_32_BIT)
+ uint32_t name;
+ uint32_t type;
+ uint32_t flags;
+ uint32_t memory_offset;
+ uint32_t file_offset;
+ uint32_t file_size;
+ uint32_t link;
+ uint32_t info;
+ uint32_t alignment;
+ uint32_t entry_size;
+#else
+ uint32_t name;
+ uint32_t type;
+ uint64_t flags;
+ uint64_t memory_offset;
+ uint64_t file_offset;
+ uint64_t file_size;
+ uint32_t link;
+ uint32_t info;
+ uint64_t alignment;
+ uint64_t entry_size;
+#endif
+};
+
+struct Symbol {
+#if defined(TARGET_ARCH_IS_32_BIT)
+ uint32_t name;
+ uint32_t value;
+ uint32_t size;
+ uint8_t info;
+ uint8_t other; // Reserved by ELF.
+ uint16_t section;
+#else
+ uint32_t name;
+ uint8_t info;
+ uint8_t other; // Reserved by ELF.
+ uint16_t section;
+ uint64_t value;
+ uint64_t size;
+#endif
+};
+
+#pragma pack(pop)
+
+static constexpr intptr_t ELFCLASS32 = 1;
+static constexpr intptr_t ELFCLASS64 = 2;
+
+static const intptr_t EI_DATA = 5;
+static const intptr_t ELFDATA2LSB = 1;
+
+static const intptr_t ELFOSABI_SYSV = 0;
+
+static const intptr_t ET_DYN = 3;
+
+static constexpr intptr_t EF_ARM_ABI_FLOAT_HARD = 0x00000400;
+static constexpr intptr_t EF_ARM_ABI_FLOAT_SOFT = 0x00000200;
+static constexpr intptr_t EF_ARM_ABI = 0x05000000;
+
+static constexpr intptr_t EM_386 = 3;
+static constexpr intptr_t EM_ARM = 40;
+static constexpr intptr_t EM_X86_64 = 62;
+static constexpr intptr_t EM_AARCH64 = 183;
+
+static const intptr_t EV_CURRENT = 1;
+
+static const intptr_t PF_X = 1;
+static const intptr_t PF_W = 2;
+static const intptr_t PF_R = 4;
+
+static const intptr_t SHT_PROGBITS = 1;
+static const intptr_t SHT_STRTAB = 3;
+static const intptr_t SHT_HASH = 5;
+static const intptr_t SHT_DYNSYM = 11;
+static const intptr_t SHT_DYNAMIC = 6;
+
+static const intptr_t SHF_WRITE = 0x1;
+static const intptr_t SHF_ALLOC = 0x2;
+static const intptr_t SHF_EXECINSTR = 0x4;
+
+static const intptr_t SHN_UNDEF = 0;
+
+static const intptr_t STN_UNDEF = 0;
+
+static const intptr_t PT_LOAD = 1;
+static const intptr_t PT_DYNAMIC = 2;
+static const intptr_t PT_PHDR = 6;
+
+static const intptr_t STB_GLOBAL = 1;
+
+static const intptr_t STT_OBJECT = 1; // I.e., data.
+static const intptr_t STT_FUNC = 2;
+
+static const intptr_t DT_NULL = 0;
+static const intptr_t DT_HASH = 4;
+static const intptr_t DT_STRTAB = 5;
+static const intptr_t DT_SYMTAB = 6;
+static const intptr_t DT_STRSZ = 10;
+static const intptr_t DT_SYMENT = 11;
+
+} // namespace elf
+} // namespace dart
+
+#endif // RUNTIME_PLATFORM_ELF_H_
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 7e7aabe..e0d145b 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -299,11 +299,14 @@
static uint32_t HostToLittleEndian32(uint32_t host_value);
static uint64_t HostToLittleEndian64(uint64_t host_value);
- static uint32_t BigEndianToHost32(uint32_t be_value) {
- // Going between Host <-> BE is the same operation for all practical
- // purposes.
+ // Going between Host <-> LE/BE is the same operation for all practical
+ // purposes.
+ static inline uint32_t BigEndianToHost32(uint32_t be_value) {
return HostToBigEndian32(be_value);
}
+ static inline uint64_t LittleEndianToHost64(uint64_t le_value) {
+ return HostToLittleEndian64(le_value);
+ }
static bool DoublesBitEqual(const double a, const double b) {
return bit_cast<int64_t, double>(a) == bit_cast<int64_t, double>(b);
diff --git a/runtime/platform/utils_win.h b/runtime/platform/utils_win.h
index ba5c9cc..9df3f6d 100644
--- a/runtime/platform/utils_win.h
+++ b/runtime/platform/utils_win.h
@@ -38,6 +38,8 @@
return static_cast<int>(result);
}
+// WARNING: The below functions assume host is always Little Endian!
+
inline uint16_t Utils::HostToBigEndian16(uint16_t value) {
return _byteswap_ushort(value);
}
diff --git a/runtime/tests/vm/dart/base_il_serialization_test.dart b/runtime/tests/vm/dart/base_il_serialization_test.dart
index f59b383..569b661 100644
--- a/runtime/tests/vm/dart/base_il_serialization_test.dart
+++ b/runtime/tests/vm/dart/base_il_serialization_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
+// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
diff --git a/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
index b0b2736..1594605 100644
--- a/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
+++ b/runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart
@@ -2,73 +2,57 @@
// 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";
-import "dart:io";
+import 'dart:async';
+import 'dart:io';
import 'dart:typed_data';
-import "package:path/path.dart" as path;
+import 'package:dart2native/dart2native.dart';
+import 'package:path/path.dart' as path;
+import 'package:expect/expect.dart';
-import "snapshot_test_helper.dart";
-
-final appSnapshotPageSize = 4096;
-const appjitMagicNumber = <int>[0xdc, 0xdc, 0xf6, 0xf6, 0, 0, 0, 0];
-
-Future writeAppendedExecutable(runtimePath, payloadPath, outputPath) async {
- final runtime = File(runtimePath);
- final int runtimeLength = runtime.lengthSync();
-
- final padding = (appSnapshotPageSize - (runtimeLength % appSnapshotPageSize));
- final padBytes = new List<int>.filled(padding, 0);
- final offset = runtimeLength + padding;
-
- final offsetBytes = new ByteData(8) // 64 bit in bytes.
- ..setUint64(0, offset, Endian.little);
-
- final outputFile = File(outputPath).openWrite();
- outputFile.add(runtime.readAsBytesSync());
- outputFile.add(padBytes);
- outputFile.add(File(payloadPath).readAsBytesSync());
- outputFile.add(offsetBytes.buffer.asUint8List());
- outputFile.add(appjitMagicNumber);
- await outputFile.close();
-}
+import 'snapshot_test_helper.dart';
Future<void> main(List<String> args) async {
- if (args.length == 1 && args[0] == "--child") {
- print("Hello, Appended AOT");
+ if (args.length == 1 && args[0] == '--child') {
+ print('Hello, Appended AOT');
return;
}
+ final String sourcePath = path.join(
+ 'runtime', 'tests', 'vm', 'dart', 'run_appended_aot_snapshot_test.dart');
+
await withTempDir((String tmp) async {
- final String dillPath = path.join(tmp, "test.dill");
- final String aotPath = path.join(tmp, "test.aot");
- final String exePath = path.join(tmp, "test.exe");
+ final String dillPath = path.join(tmp, 'test.dill');
+ final String aotPath = path.join(tmp, 'test.aot');
+ final String exePath = path.join(tmp, 'test.exe');
- final dillResult = await runGenKernel("generate dill", [
- "--aot",
- "-o",
- dillPath,
- "runtime/tests/vm/dart/run_appended_aot_snapshot_test.dart",
- ]);
- expectOutput("", dillResult);
+ {
+ final result = await generateAotKernel(checkedInDartVM, genKernel,
+ platformDill, sourcePath, dillPath, null, []);
+ Expect.equals(result.stderr, '');
+ Expect.equals(result.exitCode, 0);
+ Expect.equals(result.stdout, '');
+ }
- final aotResult = await runGenSnapshot("generate aot", [
- "--snapshot-kind=app-aot-blobs",
- "--blobs_container_filename=$aotPath",
- dillPath,
- ]);
- expectOutput("", aotResult);
+ {
+ final result =
+ await generateAotSnapshot(genSnapshot, dillPath, aotPath, false);
+ Expect.equals(result.stderr, '');
+ Expect.equals(result.exitCode, 0);
+ Expect.equals(result.stdout, '');
+ }
await writeAppendedExecutable(dartPrecompiledRuntime, aotPath, exePath);
if (Platform.isLinux || Platform.isMacOS) {
- final execResult =
- await runBinary("make executable", "chmod", ["+x", exePath]);
- expectOutput("", execResult);
+ final result = await markExecutable(exePath);
+ Expect.equals(result.stderr, '');
+ Expect.equals(result.exitCode, 0);
+ Expect.equals(result.stdout, '');
}
final runResult =
- await runBinary("run appended aot snapshot", exePath, ["--child"]);
- expectOutput("Hello, Appended AOT", runResult);
+ await runBinary('run appended aot snapshot', exePath, ['--child']);
+ expectOutput('Hello, Appended AOT', runResult);
});
}
diff --git a/runtime/tests/vm/dart/single_target_and_method_extractors2_test.dart b/runtime/tests/vm/dart/single_target_and_method_extractors2_test.dart
new file mode 100644
index 0000000..09d44a0
--- /dev/null
+++ b/runtime/tests/vm/dart/single_target_and_method_extractors2_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2019, 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.
+
+// This test verifies that AOT compiler is correctly handling method extractors
+// when resolving targets of method invocations.
+
+import "package:expect/expect.dart";
+
+abstract class MyQueue<E> {}
+
+class MyListQueue<E> implements MyQueue<E> {
+ String toString() => 'good';
+}
+
+class NextRound {
+ runNextRound() {
+ // During the 2nd iteration of precompilation loop (Precompiler::Iterate)
+ // we're going to discover a call to get:toString() which is only resolved
+ // to Object.get:toString at this time, as MyListQueue.get:toString method
+ // extractor is not created yet. Verify that compiler doesn't use that
+ // target.
+ MyQueue q = new MyListQueue();
+ dynamic x = q.toString;
+ Expect.equals("good", x.call());
+ }
+}
+
+class NextRound2 {
+ runNextRound() {}
+}
+
+getNextRound(i) => i > 5 ? new NextRound() : new NextRound2();
+
+void main() {
+ // During the 1st iteration of precompilation loop (Precompiler::Iterate)
+ // we need to create method extractor for Object.toString.
+ var x = new Object().toString;
+ x.call();
+ // Trigger the next round via new dynamic selector.
+ dynamic y = getNextRound(17);
+ y.runNextRound();
+}
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index 35accd4..162c2e0 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -16,10 +16,13 @@
where
- --help : prints help and exits
- --seed : defines random seed (system-set by default)
- --[no-]fp : enables/disables floating-point operations (default: on)
- --[no-]ffi : enables/disables FFI method calls (default: off)
+ --help : prints help and exits
+ --seed : defines random seed (system-set by default)
+ --[no-]fp : enables/disables floating-point operations (default: on)
+ --[no-]ffi : enables/disables FFI method calls (default: off)
+ --[no-]mini : enables minimization mode (default: off)
+ --smask : bitmask indicating which statements to omit (Bit=1 omits, defaults to "0")
+ --emask : bitmask indicating which expressions to omit (Bit=1 omits, defaults to "0")
The tool provides a runnable main isolate. A typical single
test run looks as:
diff --git a/runtime/tools/dartfuzz/README_minimize.md b/runtime/tools/dartfuzz/README_minimize.md
new file mode 100644
index 0000000..49d731d
--- /dev/null
+++ b/runtime/tools/dartfuzz/README_minimize.md
@@ -0,0 +1,88 @@
+Minimize
+========
+
+The `minimize.py` script minimizes a program generated by `dartfuzz.dart`.
+
+The Minimization is done in two phases:
+
+1. Minimize statements.
+2. Minimize expressions.
+
+
+### Example
+
+Generate a dart program that triggers a bug:
+
+```
+dart dartfuzz.dart --no-ffi --no-fp --seed 790976770 test.dart
+```
+
+Examine the bug (sample crash shown below):
+
+```
+dart --optimization_counter_threshold=1 test.dart
+
+...
+===== CRASH =====
+si_signo=Segmentation fault(11), si_code=1, si_addr=(nil)
+version=2.6.0-edge.de7ad46797d36a25e6d2800820f61f4af3bd1135 (Wed Sep 11 18:20:46 2019 +0000) on "linux_x64"
+thread=183944, isolate=main(0x559bd215cc00)
+...
+ pc 0x0000559bd0e40a69 fp 0x00007f73d7a7de70 ../../../../sdk/out/ReleaseX64/dart+0x190ca69
+-- End of DumpStackTrace
+```
+
+Pick a keyword identifying the bug in the output, e.g. "Segmentation".
+This will be the `--err` parameter.
+Determine whether the bug is deterministic.
+If not, set the `--tries` parameter such that the number of tries triggers
+the error at least once with high probability.
+
+
+Minimize statements of the generated program:
+
+#### Phase 1
+```
+python3 minimize.py \
+ --dartfuzz "dart dartfuzz.dart --no-ffi --no-fp --seed 790976770" \
+ --dart "dart --optimization_counter_threshold=1" \
+ --testfile mini.dart \
+ --err Segmentation \
+ --tries 4 \
+ --threads 4 \
+ --typ s \
+ --verbose
+
+3fffffffffffffffffffffffffffffffffffffffffffffffff
+error
+7fffffffffffffffffffffffffffffffffffffffffffffffff
+error
+STOP
+Best I could do is 198/198
+dart dartfuzz.dart --no-ffi --no-fp --seed 790976770 mini.dart --mini --smask 0x7fffffffffffffffffffffffffffffffffffffffffffffffff --emask 0
+```
+
+We were able to eliminate all of the statements.
+Taking a look at `mini.dart` we see that function parameters still remain.
+These can be minimized in phase 2.
+
+Minimize expressions of the generated program:
+
+#### Phase 2
+```
+python3 minimize.py \
+ --dartfuzz "dart dartfuzz.dart --no-ffi --no-fp --seed 790976770" \
+ --dart "dart --optimization_counter_threshold=1" \
+ --testfile mini.dart \
+ --err Segmentation \
+ --tries 4 \
+ --threads 4 \
+ --typ e \
+ --verbose \
+ --smask 0x7fffffffffffffffffffffffffffffffffffffffffffffffff
+..
+STOP
+Best I could do is 4626/4628
+dart dartfuzz.dart --no-ffi --no-fp --seed 790976770 mini.dart --mini --smask 0x7fffffffffffffffffffffffffffffffffffffffffffffffff \
+ --emask 0x1ff...ff2ff...fff
+```
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index ba9b779..56730f1 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -14,7 +14,7 @@
// Version of DartFuzz. Increase this each time changes are made
// to preserve the property that a given version of DartFuzz yields
// the same fuzzed program for a deterministic random seed.
-const String version = '1.49';
+const String version = '1.52';
// Restriction on statements and expressions.
const int stmtDepth = 1;
@@ -23,7 +23,6 @@
const int numGlobalVars = 4;
const int numLocalVars = 4;
const int numGlobalMethods = 4;
-const int numClassMethods = 3;
const int numMethodParams = 4;
const int numClasses = 4;
@@ -115,7 +114,8 @@
/// Class that generates a random, but runnable Dart program for fuzz testing.
class DartFuzz {
- DartFuzz(this.seed, this.fp, this.ffi, this.file);
+ DartFuzz(this.seed, this.fp, this.ffi, this.file,
+ {this.minimize = false, this.smask, this.emask});
void run() {
// Initialize program variables.
@@ -124,6 +124,8 @@
nest = 0;
currentClass = null;
currentMethod = null;
+ // Setup minimization parameters.
+ initMinimization();
// Setup the library and ffi api.
api = DartApi(ffi);
// Setup the types.
@@ -135,6 +137,7 @@
globalMethods =
fillTypes2(limit2: numGlobalMethods, limit1: numMethodParams);
classFields = fillTypes2(limit2: numClasses, limit1: numLocalVars);
+ final int numClassMethods = 1 + numClasses - classFields.length;
classMethods = fillTypes3(classFields.length,
limit2: numClassMethods, limit1: numMethodParams);
@@ -165,6 +168,135 @@
}
//
+ // Minimization components.
+ //
+
+ void initMinimization() {
+ stmtCntr = 0;
+ exprCntr = 0;
+ skipStmt = false;
+ skipExpr = false;
+ }
+
+ void emitMinimizedLiteral(DartType tp) {
+ switch (tp) {
+ case DartType.BOOL:
+ emit('true');
+ break;
+ case DartType.INT:
+ emit('1');
+ break;
+ case DartType.DOUBLE:
+ emit('1.0');
+ break;
+ case DartType.STRING:
+ emit('"a"');
+ break;
+ case DartType.INT_LIST:
+ emit('[1]');
+ break;
+ case DartType.INT_SET:
+ emit('{1}');
+ break;
+ case DartType.INT_STRING_MAP:
+ emit('{1: "a"}');
+ break;
+ default:
+ throw 'Unknown DartType ${tp}';
+ }
+ }
+
+ BigInt genMask(int m) => BigInt.from(1) << m;
+
+ // Process the opening of a statement.
+ // Determine whether the statement should be skipped based on the
+ // statement index stored in stmtCntr and the statement mask stored
+ // in smask.
+ // Returns true if the statement should be skipped.
+ bool processStmtOpen() {
+ // Do nothing if we are not in minimization mode.
+ if (!minimize) {
+ return false;
+ }
+ // Check whether the bit for the current statement number is set in the
+ // statement bitmap. If so skip this statement.
+ final newMask = genMask(stmtCntr);
+ final maskBitSet = (smask & newMask) != BigInt.zero;
+ // Statements are nested, therefore masking one statement like e.g.
+ // a for loop leads to other statements being omitted.
+ // Here we update the statement mask to include the additionally
+ // omitted statements.
+ if (skipStmt) {
+ smask |= newMask;
+ }
+ // Increase the statement counter.
+ stmtCntr++;
+ if (!skipStmt && maskBitSet) {
+ skipStmt = true;
+ return true;
+ }
+ return false;
+ }
+
+ // Process the closing of a statement.
+ // The variable resetSkipStmt indicates whether this
+ // statement closes the sequence of skipped statement.
+ // E.g. the end of a loop where all contained statements
+ // were skipped.
+ void processStmtClose(bool resetSkipStmt) {
+ if (!minimize) {
+ return;
+ }
+ if (resetSkipStmt) {
+ skipStmt = false;
+ }
+ }
+
+ // Process the opening of an expression.
+ // Determine whether the expression should be skipped based on the
+ // expression index stored in exprCntr and the expression mask stored
+ // in emask.
+ // Returns true is the expression is skipped.
+ bool processExprOpen(DartType tp) {
+ // Do nothing if we are not in minimization mode.
+ if (!minimize) {
+ return false;
+ }
+ // Check whether the bit for the current expression number is set in the
+ // expression bitmap. If so skip this expression.
+ final newMask = genMask(exprCntr);
+ final maskBitSet = (emask & newMask) != BigInt.zero;
+ // Expressions are nested, therefore masking one expression like e.g.
+ // a for loop leads to other expressions being omitted.
+ // Similarly, if the whole statement is skipped, all the expressions
+ // within that statement are implicitly masked.
+ // Here we update the expression mask to include the additionally
+ // omitted expressions.
+ if (skipExpr || skipStmt) {
+ emask |= newMask;
+ }
+ exprCntr++;
+ if (skipStmt) {
+ return false;
+ }
+ if (!skipExpr && maskBitSet) {
+ emitMinimizedLiteral(tp);
+ skipExpr = true;
+ return true;
+ }
+ return false;
+ }
+
+ void processExprClose(bool resetExprStmt) {
+ if (!minimize || skipStmt) {
+ return;
+ }
+ if (resetExprStmt) {
+ skipExpr = false;
+ }
+ }
+
+ //
// Program components.
//
@@ -346,6 +478,11 @@
tryBody();
emit(";", newline: true);
indent -= 2;
+ emitLn('} on OutOfMemoryError {');
+ indent += 2;
+ emitLn("print(\'oom\');");
+ emitLn("exit(${oomExitCode});");
+ indent -= 2;
emitLn('} catch (e, st) {');
indent += 2;
catchBody();
@@ -731,9 +868,8 @@
return true;
}
- // Emit a statement. Returns true if code *may* fall-through
- // (not made too advanced to avoid FE complaints).
- bool emitStatement(int depth) {
+ // Emit a single statement.
+ bool emitSingleStatement(int depth) {
// Throw in a comment every once in a while.
if (rand.nextInt(10) == 0) {
emitComment();
@@ -778,6 +914,16 @@
}
}
+ // Emit a statement (main entry).
+ // Returns true if code *may* fall-through
+ // (not made too advanced to avoid FE complaints).
+ bool emitStatement(int depth) {
+ final resetSkipStmt = processStmtOpen();
+ bool ret = emitSingleStatement(depth);
+ processStmtClose(resetSkipStmt);
+ return ret;
+ }
+
// Emit statements. Returns true if code may fall-through.
bool emitStatements(int depth) {
int s = 1 + rand.nextInt(numStatements);
@@ -869,7 +1015,7 @@
void emitCollectionElement(int depth, DartType tp, {RhsFilter rhsFilter}) {
int r = depth <= exprDepth ? rand.nextInt(10) : 10;
- switch (r) {
+ switch (r + 3) {
// Favors elements over control-flow collections.
case 0:
// TODO (ajcbik): Remove restriction once compiler is fixed.
@@ -958,7 +1104,9 @@
} else if (tp == DartType.INT_LIST ||
tp == DartType.INT_SET ||
tp == DartType.INT_STRING_MAP) {
+ final resetExprStmt = processExprOpen(tp);
emitCollection(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
+ processExprClose(resetExprStmt);
} else {
assert(false);
}
@@ -1231,35 +1379,38 @@
// Emit expression.
void emitExpr(int depth, DartType tp, {RhsFilter rhsFilter}) {
+ final resetExprStmt = processExprOpen(tp);
// Continuing nested expressions becomes less likely as the depth grows.
if (rand.nextInt(depth + 1) > exprDepth) {
emitTerminal(depth, tp, rhsFilter: rhsFilter);
- return;
+ } else {
+ // Possibly nested expression.
+ switch (rand.nextInt(7)) {
+ case 0:
+ emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
+ break;
+ case 1:
+ emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
+ break;
+ case 2:
+ emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
+ break;
+ case 3:
+ emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
+ break;
+ case 4:
+ emitLibraryCall(depth, tp,
+ rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
+ break;
+ case 5:
+ emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
+ break;
+ default:
+ emitTerminal(depth, tp, rhsFilter: rhsFilter);
+ break;
+ }
}
- // Possibly nested expression.
- switch (rand.nextInt(7)) {
- case 0:
- emitUnaryExpr(depth, tp, rhsFilter: rhsFilter);
- break;
- case 1:
- emitBinaryExpr(depth, tp, rhsFilter: rhsFilter);
- break;
- case 2:
- emitTernaryExpr(depth, tp, rhsFilter: rhsFilter);
- break;
- case 3:
- emitPreOrPostExpr(depth, tp, rhsFilter: rhsFilter);
- break;
- case 4:
- emitLibraryCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
- break;
- case 5:
- emitMethodCall(depth, tp, rhsFilter: RhsFilter.cloneEmpty(rhsFilter));
- break;
- default:
- emitTerminal(depth, tp, rhsFilter: rhsFilter);
- break;
- }
+ processExprClose(resetExprStmt);
}
//
@@ -1522,6 +1673,9 @@
// Emits text to append to program.
void emit(String txt, {bool newline = false}) {
+ if (skipStmt || skipExpr) {
+ return;
+ }
file.writeStringSync(txt);
if (newline) {
file.writeStringSync('\n');
@@ -1533,6 +1687,9 @@
return choices[rand.nextInt(choices.length)];
}
+ // Special return code to handle oom errors.
+ static const oomExitCode = 254;
+
// Random seed used to generate program.
final int seed;
@@ -1581,6 +1738,16 @@
// Parent class indices for all classes.
List<int> classParents;
+
+ // Minimization mode extensions.
+ final bool minimize;
+ BigInt smask;
+ BigInt emask;
+ bool skipStmt;
+ bool skipExpr;
+ bool skipExprCntr;
+ int stmtCntr;
+ int exprCntr;
}
// Generate seed. By default (no user-defined nonzero seed given),
@@ -1604,15 +1771,49 @@
help: 'random seed (0 forces time-based seed)', defaultsTo: '0')
..addFlag('fp', help: 'enables floating-point operations', defaultsTo: true)
..addFlag('ffi',
- help: 'enables FFI method calls (default: off)', defaultsTo: false);
+ help: 'enables FFI method calls (default: off)', defaultsTo: false)
+ // Minimization mode extensions.
+ ..addFlag('mini',
+ help: 'enables minimization mode (default: off)', defaultsTo: false)
+ ..addOption('smask',
+ help: 'Bitmask indicating which statements to omit'
+ '(Bit=1 omits)',
+ defaultsTo: '0')
+ ..addOption('emask',
+ help: 'Bitmask indicating which expressions to omit'
+ '(Bit=1 omits)',
+ defaultsTo: '0');
try {
final results = parser.parse(arguments);
final seed = getSeed(results['seed']);
final fp = results['fp'];
final ffi = results['ffi'];
final file = File(results.rest.single).openSync(mode: FileMode.write);
- DartFuzz(seed, fp, ffi, file).run();
+ final minimize = results['mini'];
+ final smask = BigInt.parse(results['smask']);
+ final emask = BigInt.parse(results['emask']);
+ final dartFuzz = DartFuzz(seed, fp, ffi, file,
+ minimize: minimize, smask: smask, emask: emask);
+ dartFuzz.run();
file.closeSync();
+ // Print information that will be parsed by minimize.py
+ if (minimize) {
+ // Updated statement mask.
+ // This might be different from the input parameter --smask
+ // since masking a statement that contains nested statements leads to
+ // those being masked as well.
+ print(dartFuzz.smask.toRadixString(10));
+ // Total number of statements in the generated program.
+ print(dartFuzz.stmtCntr);
+ // Updated expression mask.
+ // This might be different from the input parameter --emask
+ // since masking a statement that contains expressions or
+ // an expression that contains nested expressions leads to
+ // those being masked as well.
+ print(dartFuzz.emask.toRadixString(10));
+ // Total number of expressions in the generated program.
+ print(dartFuzz.exprCntr);
+ }
} catch (e) {
print('Usage: dart dartfuzz.dart [OPTIONS] FILENAME\n${parser.usage}\n$e');
exitCode = 255;
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index c1fcbe7..dc61138 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -13,6 +13,7 @@
const debug = false;
const sigkill = 9;
const timeout = 60; // in seconds
+const dartHeapSize = 128; // in Mb
// Status of divergence report.
enum ReportStatus { reported, ignored, rerun, no_divergence }
@@ -155,7 +156,12 @@
this.fileName, List<String> extraFlags) {
description = '$prefix-$tag';
dart = '$top/out/$tag/dart';
- cmd = [dart, ...extraFlags, fileName];
+ cmd = [
+ dart,
+ ...extraFlags,
+ '--old_gen_heap_size=${dartHeapSize}',
+ fileName
+ ];
}
TestResult run() {
@@ -189,7 +195,8 @@
if (result.exitCode != 0) {
return result;
}
- return runCommand([dart, snapshot], env);
+ return runCommand(
+ [dart, '--old_gen_heap_size=${dartHeapSize}', snapshot], env);
}
void printReproductionCommand() {
@@ -214,12 +221,17 @@
description = '$prefix-$tag';
dart = '$top/out/$tag/dart';
if (kbcSrc) {
- cmd = [dart, ...extraFlags, fileName];
+ cmd = [
+ dart,
+ ...extraFlags,
+ '--old_gen_heap_size=${dartHeapSize}',
+ fileName
+ ];
} else {
generate = '$top/pkg/vm/tool/gen_kernel';
platform = '--platform=$top/out/$tag/vm_platform_strong.dill';
dill = '$tmp/out.dill';
- cmd = [dart, ...extraFlags, dill];
+ cmd = [dart, ...extraFlags, '--old_gen_heap_size=${dartHeapSize}', dill];
}
}
@@ -445,11 +457,17 @@
// Divergence in result code.
if (trueDivergence) {
// When only true divergences are requested, any divergence
- // with at least one time out is treated as a regular time out.
+ // with at least one time out or out of memory error is
+ // treated as a regular time out or skipped test, respectively.
if (result1.exitCode == -sigkill || result2.exitCode == -sigkill) {
numTimeout++;
timeoutSeeds.add(seed);
return ReportStatus.ignored;
+ } else if (result1.exitCode == DartFuzz.oomExitCode ||
+ result2.exitCode == DartFuzz.oomExitCode) {
+ numSkipped++;
+ skippedSeeds.add(seed);
+ return ReportStatus.ignored;
}
}
reportDivergence(result1, result2);
diff --git a/runtime/tools/dartfuzz/minimize.py b/runtime/tools/dartfuzz/minimize.py
new file mode 100755
index 0000000..c9be86a
--- /dev/null
+++ b/runtime/tools/dartfuzz/minimize.py
@@ -0,0 +1,414 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019, 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.
+#
+"""
+This script minimizes a program generated by dartfuzz.dart.
+"""
+
+import argparse
+import multiprocessing as mp
+import re
+import shlex
+import subprocess
+
+STATEMENT_MASK_LINE = 0
+STATEMENT_NUMBER_LINE = 1
+EXPRESSION_MASK_LINE = 2
+EXPRESSION_NUMBER_LINE = 3
+
+
+class MaskGen(object):
+ """
+ Generates bitpatterns of <nbits> bits which indicate which
+ statements or expressions should be masked when passed as the
+ --smask or --emask parameter to dartfuzz.dart.
+ The patterns are generated in the following manner:
+ 11111111111111111111111111111111
+ 11111111111111110000000000000000
+ 00000000000000001111111111111111
+ 11111111111111111111111100000000
+ 11111111111111110000000011111111
+ 11111111000000001111111111111111
+ 00000000111111111111111111111111
+ ...
+ If the error persists with a given a pattern it is stored in the
+ parameter <mask>.
+ """
+
+ def __init__(self, nbits, mask):
+ # Mask bitlength.
+ self.nbits = nbits
+ # Mask determining which statements or expressions to skip.
+ self.mask = mask
+ # Current mask modification start index.
+ self.convolution_idx = 0
+ # Max mask with all bits set to 1.
+ self.max = (1 << (nbits + 1)) - 1
+ # Current number of bits set in the mask modification mask.
+ self.nbitsVar = int(nbits)
+ # Current mask modification mask.
+ # This will be folded over the current value of self.mask
+ # starting from 0.
+ self.filter_mask = (1 << self.nbitsVar) - 1
+ # All the masks already tested.
+ self.tested = set()
+ self.gen_new_mask = False
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ return self.next()
+
+ # Update the set of tested masks.
+ # This is used to keep track of tested masks that did not produce a crash.
+ def update_tested(self, new_mask):
+ self.tested.add(new_mask)
+
+ # Update the current mask with the new mask that produced a crash.
+ # Note: We assume that if mask
+ # 11110000 produces a crash and
+ # 00000011 produces a crash that
+ # 11110011 will also produce a crash.
+ # This might not be true for some cases.
+ def update_mask(self, new_mask):
+ new_mask = (self.mask | new_mask) & self.max
+ self.mask = new_mask
+
+ # Count the bits of the current mask.
+ # More bits mean more statements omitted, so this is used
+ # to determine the quality of the current mask.
+ def count_bits(self):
+ return bin(self.mask).count('1')
+
+ def inc_var(self):
+ self.convolution_idx = 0
+ self.nbitsVar = self.nbitsVar >> 1
+ self.filter_mask = (1 << self.nbitsVar) - 1
+ return self.filter_mask == 0
+
+ def stop(self):
+ if self.convolution_idx >= self.nbits and self.inc_var() > 0:
+ # Check if the last run generated a new mask.
+ if self.gen_new_mask:
+ # Restart mask generation from beginning.
+ self.nbitsVar = self.nbits >> 1
+ self.inc_var()
+ self.gen_new_mask = False
+ return False
+ print("STOP")
+ return True
+ return False
+
+ def next(self):
+ while not self.stop():
+ # Generate a new mask according to the mask generation algorithm.
+ new_mask = (self.mask |
+ (self.filter_mask << self.convolution_idx)) & self.max
+ # Update the counter variable for the mask generation algorithm.
+ self.convolution_idx += self.nbitsVar
+ # If the new_mask has new bits and has not been tested yet.
+ # We need to check both because only masks that produce an
+ # error are merged into self.mask.
+ if new_mask != self.mask and \
+ new_mask not in self.tested:
+ # Add new mask to the set of tested masks.
+ self.tested.add(new_mask)
+ # Mark that we generated a new mask on this run.
+ self.gen_new_mask = True
+ # Return the new mask to be tested.
+ return new_mask
+ raise StopIteration()
+
+
+# Generate a Dart program for the given statement (smask) and
+# expression (emask) masks. Dartfuzz parameters for seed, ffi and
+# fp are static and therefore contained in the dartfuzz_cmd parameter.
+def generate_dart(dartfuzz_cmd, dart_test, smask, mask, do_expr):
+ if do_expr:
+ # Minimizing expressions.
+ cmds = shlex.split(dartfuzz_cmd) + [dart_test] + \
+ ['--mini', '--smask', '%d' % smask, '--emask', '%d' % mask]
+ p = subprocess.Popen(cmds, stdout=subprocess.PIPE)
+ else:
+ # Minimizing statements.
+ cmds = shlex.split(dartfuzz_cmd) + [dart_test] + \
+ ['--mini', '--smask', '%d' % mask]
+ p = subprocess.Popen(cmds, stdout=subprocess.PIPE)
+ p_stdout, p_stderr = p.communicate()
+ if p.returncode != 0:
+ raise 'Invalid return code on generate %d' % p.returncode
+ mask_new = 0
+ if do_expr:
+ mask_new = int(p_stdout.decode().splitlines()[EXPRESSION_MASK_LINE])
+ else:
+ mask_new = int(p_stdout.decode().splitlines()[STATEMENT_MASK_LINE])
+ return mask_new
+
+
+# Run the Dart program and check for error (by matching error_match_p).
+def run_dart(dart_cmd, dart_test, error_match_p, timeout):
+ cmd = ['timeout', str(timeout)] + shlex.split(dart_cmd) + [dart_test]
+ p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
+ p_stdout, p_stderr = p.communicate()
+ if error_match_p.search(p_stdout.decode()) or \
+ error_match_p.search(p_stderr.decode()):
+ return True
+ if p.returncode != 0:
+ print("Warning: error return code %d" % p.returncode)
+ return False
+
+
+# Run multiple tries of the given dart_cmd and check for errors by matching
+# against error_match_p.
+def run_dart_mp(dart_cmd, dart_test, error_match_p, tries, nthreads, timeout):
+ if tries == 1:
+ return run_dart(dart_cmd, dart_test, error_match_p, timeout)
+ pool = mp.Pool(nthreads)
+ results = [
+ pool.apply_async(run_dart,
+ (dart_cmd, dart_test, error_match_p, timeout))
+ for i in range(tries)
+ ]
+ worker_done = [False for i in range(tries)]
+ while True:
+ all_done = True
+ for i, result in enumerate(results):
+ if worker_done[i]:
+ continue
+ try:
+ r = result.get(timeout=0.5)
+ worker_done[i] = True
+ if r:
+ pool.close()
+ pool.terminate()
+ pool.join()
+ return True
+ except mp.TimeoutError:
+ all_done = False
+ if all_done:
+ break
+ pool.close()
+ pool.join()
+ return False
+
+
+def minimize(dartfuzz_cmd,
+ dart_cmd,
+ dart_cmd_ref,
+ dart_test,
+ error_match1,
+ error_match2,
+ smask,
+ emask,
+ do_expr,
+ verbose,
+ tries,
+ tries_ref,
+ threads,
+ timeout,
+ print_every=32):
+ # Run dartfuzz command once to get the total number of statements
+ # and expressions in the generated program.
+ # Output will look like this:
+ # <Current Statement Mask>
+ # <Number of Statements>
+ # <Current Expression Mask>
+ # <Number of Expressions>
+ p = subprocess.Popen(
+ dartfuzz_cmd + " --mini " + dart_test,
+ shell=True,
+ stdout=subprocess.PIPE)
+ p_stdout, p_stderr = p.communicate()
+ if do_expr:
+ # Minimizing expressions.
+ nstmts = int(p_stdout.decode().splitlines()[EXPRESSION_NUMBER_LINE])
+ mask_gen = MaskGen(nstmts, emask)
+ else:
+ # Minimizing statements.
+ nstmts = int(p_stdout.decode().splitlines()[STATEMENT_NUMBER_LINE])
+ mask_gen = MaskGen(nstmts, smask)
+ # Best mask found so far.
+ min_mask = 0
+ # Maximum number of statements or expressions masked.
+ max_bits = 0
+ # Count number of iterations.
+ cntr = 0
+ # Result of the last run.
+ last_err = True
+ # Compile pattern to match standard output and error for a string
+ # identifying the crash.
+ error_match_p1 = re.compile(error_match1)
+ error_match_p2 = None
+ if error_match2 is not None:
+ error_match_p2 = re.compile(error_match2)
+ for mask in mask_gen:
+ if (verbose):
+ print("Mask: %x" % mask)
+ cntr += 1
+ if cntr % print_every == 0:
+ cntr = 0
+ print("Best I could do so far is mask %d/%d" \
+ % (max_bits, nstmts))
+ if do_expr:
+ print(dartfuzz_cmd + " " + dart_test +
+ " --mini --smask 0x%x --emask 0x%x" % (smask, min_mask))
+ else:
+ print(dartfuzz_cmd + " " + dart_test +
+ " --mini --smask 0x%x --emask 0" % (min_mask))
+ # The return value mask_new contains the actual mask applied by
+ # dartfuzz. Due to nesting, masking one statement might lead to other
+ # statements being masked as well; mask_new will contain this updated
+ # mask.
+ mask_new = generate_dart(dartfuzz_cmd, dart_test, smask, mask, do_expr)
+ # Run generated Dart program and check for error.
+ err = run_dart_mp(dart_cmd, dart_test, error_match_p1, tries, threads,
+ timeout)
+ if err and verbose:
+ print("Matched error 1 " + error_match1)
+ err_ref = True
+ if (dart_cmd_ref is not None) and (error_match_p2 is not None):
+ err_ref = run_dart_mp(dart_cmd_ref, dart_test, error_match_p2,
+ tries_ref, threads, timeout)
+ if err_ref and verbose:
+ print("Matched error 2 " + error_match2)
+ if err and err_ref:
+ # In case the mask used for generating the Dart program lead to an
+ # error, update the mask generator accordingly.
+ mask_gen.update_mask(mask)
+ # TODO (felih): this line should be enough but there seems to be a
+ # bug in dartfuzz.dart calculating mask_new.
+ mask_gen.update_mask(mask_new)
+ max_bits = mask_gen.count_bits()
+ min_mask = mask_gen.mask
+ elif last_err:
+ # If the last run removed the error try the inverse.
+ invMaskNew = mask_gen.mask | (mask_gen.max & ~mask_new)
+ if invMaskNew != mask_gen.mask and \
+ invMaskNew not in mask_gen.tested:
+ if (verbose):
+ print("Mask: %x (i)" % invMaskNew)
+ mask_new = generate_dart(dartfuzz_cmd, dart_test, smask,
+ invMaskNew, do_expr)
+ err = run_dart_mp(dart_cmd, dart_test, error_match_p1, tries,
+ threads, timeout)
+ if err and verbose:
+ print("Matched error 1 " + error_match1)
+ err_ref = True
+ if (dart_cmd_ref is not None) and (error_match_p2 is not None):
+ err_ref = run_dart_mp(dart_cmd_ref, dart_test,
+ error_match_p2, tries_ref, threads,
+ timeout)
+ if err_ref and verbose:
+ print("Matched error 2 " + error_match2)
+ if err and err_ref:
+ mask_gen.update_mask(invMaskNew)
+ mask_gen.update_mask(mask_new)
+ max_bits = mask_gen.count_bits()
+ min_mask = mask_gen.mask
+ last_err = err and err_ref
+ # Update the set of tested masks with the one we just tested.
+ mask_gen.update_tested(mask_new)
+
+ print("Best I could do is %d/%d" \
+ % (max_bits,nstmts))
+
+ if do_expr:
+ print(dartfuzz_cmd + " " + dart_test +
+ " --mini --smask 0x%x --emask 0x%x" % (smask, min_mask))
+ else:
+ print(dartfuzz_cmd + " " + dart_test +
+ " --mini --smask 0x%x --emask 0" % (min_mask))
+
+ return min_mask
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Minimize a generated Dart program ' +
+ ' while maintaining an identified crash or divergence. ' +
+ 'A second Dart program can be specified for divergence testing.')
+ parser.add_argument(
+ '--dartfuzz',
+ required=True,
+ help="dartfuzz command string "
+ "e.g. dart dartfuzz.dart --no-ffi --no-fp --seed 243123600")
+ parser.add_argument(
+ '--dart',
+ help="Dart command string "
+ "e.g. ./sdk/out/ReleaseX64/dart",
+ required=True)
+ parser.add_argument(
+ '--dart-ref',
+ dest="dart_ref",
+ help="Dart command string for reference build " +
+ "(in case of divergence testing) " + "e.g. ./sdk/out/ReleaseX64/dart",
+ default=None)
+ parser.add_argument(
+ '--testfile',
+ required=True,
+ help="output filename for program generated by "
+ "dartfuzz command and passed to Dart command "
+ "e.g fuzz.dart")
+ parser.add_argument(
+ '--err',
+ help="string indicating an error for Dart cmd (no multiline matches)",
+ required=True)
+ parser.add_argument(
+ '--err-ref',
+ dest="err_ref",
+ help="string matching the diverging output for the Dart " +
+ "reference command (no multiline matches)",
+ default=None)
+ parser.add_argument(
+ '--smask', help="hexadecimal statements mask", default="0")
+ parser.add_argument(
+ '--emask', help="hexadecimal expressions mask", default="0")
+ parser.add_argument(
+ '--typ',
+ choices=["s", "e", "se"],
+ required=True,
+ help="minimize statements (s) or expressions (e) or both (se)")
+ parser.add_argument(
+ '--tries',
+ type=int,
+ default=1,
+ help='number of retries per run for Dart cmd')
+ parser.add_argument(
+ '--tries-ref',
+ type=int,
+ dest='tries_ref',
+ default=1,
+ help='number of retries per run for Dart reference cmd')
+ parser.add_argument(
+ '--threads',
+ type=int,
+ default=4,
+ help='number of threads to use for retries')
+ parser.add_argument(
+ '--timeout', type=int, default=60, help='timeout for Dart command')
+ parser.add_argument(
+ '--verbose', help="print intermediate results", action="store_true")
+ args = parser.parse_args()
+ timeout = args.timeout
+ do_stmt = "s" in args.typ
+ do_expr = "e" in args.typ
+ smask = int(args.smask, 16)
+ if do_stmt:
+ print("Minimizing Statements")
+ smask = minimize(args.dartfuzz, args.dart, args.dart_ref,
+ args.testfile, args.err, args.err_ref, smask,
+ int(args.emask, 16), False, args.verbose, args.tries,
+ args.tries_ref, args.threads, timeout)
+ if do_expr:
+ print("Minimizing Expressions")
+ minimize(args.dartfuzz, args.dart, args.dart_ref,
+ args.testfile, args.err, args.err_ref, smask,
+ int(args.emask, 16), True, args.verbose, args.tries,
+ args.tries_ref, args.threads, timeout)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 5850a97..9223327 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -140,14 +140,13 @@
"-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks",
"-Ddart.isVM=true",
]
-
if (defined(invoker.exclude_source) && invoker.exclude_source) {
args += [ "--exclude-source" ]
}
- outline = "vm_outline" + output_postfix + ".dill"
- if (dart_platform_bytecode) {
+ if (defined(invoker.bytecode) && invoker.bytecode) {
args += [ "--bytecode" ]
}
+ outline = "vm_outline" + output_postfix + ".dill"
}
}
@@ -161,6 +160,10 @@
add_implicit_vm_platform_dependency = false
exclude_source = true
output_postfix = "_strong_stripped"
+
+ if (dart_platform_bytecode) {
+ bytecode = true
+ }
}
group("kernel_platform_files") {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index c947c02..336163a 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -392,6 +392,7 @@
V(TransferableTypedData_factory, 2) \
V(TransferableTypedData_materialize, 1) \
V(Wasm_initModule, 2) \
+ V(Wasm_describeModule, 1) \
V(Wasm_initImports, 2) \
V(Wasm_addMemoryImport, 3) \
V(Wasm_addGlobalImport, 5) \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 70459fd..634f9e7 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -90,6 +90,7 @@
#endif
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
void SerializationCluster::WriteAndMeasureAlloc(Serializer* serializer) {
if (LOG_SECTION_BOUNDARIES) {
OS::PrintErr("Data + %" Px ": Alloc %s\n", serializer->bytes_written(),
@@ -115,7 +116,6 @@
size_ += (stop - start);
}
-#if !defined(DART_PRECOMPILED_RUNTIME)
class ClassSerializationCluster : public SerializationCluster {
public:
explicit ClassSerializationCluster(intptr_t num_cids)
@@ -4336,6 +4336,10 @@
};
#endif // !DART_PRECOMPILED_RUNTIME
+#if defined(DEBUG)
+static const int32_t kSectionMarker = 0xABAB;
+#endif
+
Serializer::Serializer(Thread* thread,
Snapshot::Kind kind,
uint8_t** buffer,
@@ -4551,6 +4555,7 @@
#endif // !DART_PRECOMPILED_RUNTIME
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
void Serializer::WriteInstructions(RawInstructions* instr, RawCode* code) {
ASSERT(code != Code::null());
@@ -4740,11 +4745,6 @@
free(const_cast<char*>(expected_features));
}
-#if defined(DEBUG)
-static const int32_t kSectionMarker = 0xABAB;
-#endif
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
static int CompareClusters(SerializationCluster* const* a,
SerializationCluster* const* b) {
if ((*a)->size() > (*b)->size()) {
@@ -4755,7 +4755,6 @@
return 0;
}
}
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
void Serializer::Serialize() {
while (stack_.length() > 0) {
@@ -5019,6 +5018,7 @@
heap_->ResetObjectIdTable();
}
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
Deserializer::Deserializer(Thread* thread,
Snapshot::Kind kind,
@@ -5519,6 +5519,7 @@
"Write a snapshot profile in V8 format to a file.");
#endif
+#if !defined(DART_PRECOMPILED_RUNTIME)
FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
uint8_t** vm_snapshot_data_buffer,
uint8_t** isolate_snapshot_data_buffer,
@@ -5655,6 +5656,7 @@
}
#endif
}
+#endif // defined(DART_PRECOMPILED_RUNTIME)
FullSnapshotReader::FullSnapshotReader(const Snapshot* snapshot,
const uint8_t* instructions_buffer,
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 375e171..1697657 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -944,18 +944,9 @@
for (intptr_t i = 0; i < class_ids.length(); i++) {
const intptr_t cid = class_ids[i];
cls = isolate()->class_table()->At(cid);
- // Even if we are resolving get:M on a class that has method M
- // ResolveForReceiverClass would not inject a method extractor into
- // a class becuase FLAG_lazy_dispatchers is set to false during AOT
- // compilation. Precompiler however does inject method extractors
- // (see Precompiler::CheckForNewDynamicFunctions). This means that that
- // lookup for get:m might overlook a method M in subclass and return
- // get:m (method extractor for M) from a superclass.
- // For this reason we abort optimization if lookup returns any
- // artificial functions that can be inserted lazily.
target = instr->ResolveForReceiverClass(cls);
- if (target.IsNull() || target.IsMethodExtractor() ||
- target.IsInvokeFieldDispatcher()) {
+ ASSERT(target.IsNull() || !target.IsInvokeFieldDispatcher());
+ if (target.IsNull()) {
single_target = Function::null();
ic_data = ICData::null();
break;
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index b92b714..6be5427 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -17,6 +17,7 @@
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_serializer.h"
#include "vm/compiler/backend/inliner.h"
#include "vm/compiler/backend/linearscan.h"
#include "vm/compiler/backend/range_analysis.h"
@@ -67,10 +68,6 @@
max_speculative_inlining_attempts,
1,
"Max number of attempts with speculative inlining (precompilation only)");
-DEFINE_FLAG(charp,
- serialize_flow_graphs_to,
- nullptr,
- "Serialize flow graphs to the given file");
DECLARE_FLAG(bool, print_flow_graph);
DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -90,6 +87,17 @@
DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
DECLARE_FLAG(bool, print_instruction_stats);
+DEFINE_FLAG(charp,
+ serialize_flow_graphs_to,
+ nullptr,
+ "Serialize flow graphs to the given file");
+
+DEFINE_FLAG(bool,
+ populate_llvm_constant_pool,
+ false,
+ "Add constant pool entries from flow graphs to a special pool "
+ "serialized in AOT snapshots (with --serialize_flow_graphs_to)");
+
Precompiler* Precompiler::singleton_ = nullptr;
#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \
@@ -200,6 +208,16 @@
auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
set_il_serialization_stream(file);
}
+ if (FLAG_populate_llvm_constant_pool) {
+ auto const object_store = I->object_store();
+ auto& llvm_constants = GrowableObjectArray::Handle(
+ zone_, GrowableObjectArray::New(16, Heap::kOld));
+ auto& llvm_constants_hash_table = Array::Handle(
+ zone_, HashTables::New<FlowGraphSerializer::LLVMConstantsMap>(
+ 16, Heap::kOld));
+ object_store->set_llvm_constant_pool(llvm_constants);
+ object_store->set_llvm_constant_hash_table(llvm_constants_hash_table);
+ }
}
if (FLAG_use_bare_instructions) {
@@ -324,6 +342,19 @@
I->set_compilation_allowed(false);
+ if (FLAG_serialize_flow_graphs_to != nullptr &&
+ Dart::file_write_callback() != nullptr) {
+ if (auto file_close = Dart::file_close_callback()) {
+ file_close(il_serialization_stream());
+ set_il_serialization_stream(nullptr);
+ }
+ if (FLAG_populate_llvm_constant_pool) {
+ // We don't want the Array backing for the map from constants to
+ // indices in the snapshot, only the constant pool itself.
+ I->object_store()->set_llvm_constant_hash_table(Array::null_array());
+ }
+ }
+
TraceForRetainedFunctions();
DropFunctions();
DropFields();
@@ -364,13 +395,6 @@
ProgramVisitor::Dedup();
- if (il_serialization_stream() != nullptr) {
- auto file_close = Dart::file_close_callback();
- ASSERT(file_close != nullptr);
- file_close(il_serialization_stream());
- set_il_serialization_stream(nullptr);
- }
-
zone_ = NULL;
}
@@ -1410,6 +1434,7 @@
function ^= functions.At(j);
bool retain = functions_to_retain_.ContainsKey(function);
function.DropUncompiledImplicitClosureFunction();
+ function.ClearBytecode();
if (retain) {
retained_functions.Add(function);
} else {
@@ -1435,6 +1460,7 @@
for (intptr_t j = 0; j < closures.Length(); j++) {
function ^= closures.At(j);
bool retain = functions_to_retain_.ContainsKey(function);
+ function.ClearBytecode();
if (retain) {
retained_functions.Add(function);
} else {
@@ -1455,6 +1481,7 @@
Field& field = Field::Handle(Z);
GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
AbstractType& type = AbstractType::Handle(Z);
+ Function& initializer_function = Function::Handle(Z);
for (intptr_t i = 0; i < libraries_.Length(); i++) {
lib ^= libraries_.At(i);
@@ -1470,6 +1497,10 @@
for (intptr_t j = 0; j < fields.Length(); j++) {
field ^= fields.At(j);
bool retain = fields_to_retain_.HasKey(&field);
+ if (field.HasInitializerFunction()) {
+ initializer_function = field.InitializerFunction();
+ initializer_function.ClearBytecode();
+ }
if (retain) {
retained_fields.Add(field);
type = field.type();
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 7c52d628..afef14c 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1029,14 +1029,15 @@
VariableLivenessAnalysis* variable_liveness,
ZoneGrowableArray<Definition*>* inlining_parameters) {
ASSERT(!IsCompiledForOsr());
- const intptr_t parameter_count = num_direct_parameters_;
+ const intptr_t direct_parameter_count = num_direct_parameters_;
// Check if inlining_parameters include a type argument vector parameter.
const intptr_t inlined_type_args_param =
((inlining_parameters != NULL) && function().IsGeneric()) ? 1 : 0;
- ASSERT(parameter_count <= env->length());
- for (intptr_t i = 0; i < parameter_count; i++) {
+ ASSERT(variable_count() == env->length());
+ ASSERT(direct_parameter_count <= env->length());
+ for (intptr_t i = 0; i < direct_parameter_count; i++) {
ParameterInstr* param = new (zone()) ParameterInstr(i, function_entry);
param->set_ssa_temp_index(alloc_ssa_temp_index());
AddToInitialDefinitions(function_entry, param);
@@ -1097,8 +1098,7 @@
// passed as parameters. The latter mimics the incoming expression
// stack that was set up prior to triggering OSR.
const intptr_t parameter_count = osr_variable_count();
- ASSERT(env->length() == (parameter_count - osr_entry->stack_depth()));
- env->EnsureLength(parameter_count, constant_dead());
+ ASSERT(parameter_count == env->length());
for (intptr_t i = 0; i < parameter_count; i++) {
ParameterInstr* param = new (zone()) ParameterInstr(i, osr_entry);
param->set_ssa_temp_index(alloc_ssa_temp_index());
@@ -1120,7 +1120,7 @@
: -1;
// Add real definitions for all locals and parameters.
- ASSERT(variable_count() <= env->length());
+ ASSERT(variable_count() == env->length());
for (intptr_t i = 0, n = variable_count(); i < n; ++i) {
// Replace usages of the raw exception/stacktrace variables with
// [SpecialParameterInstr]s.
@@ -1288,7 +1288,7 @@
PushArgumentInstr* push_arg = current->PushArgumentAt(i);
ASSERT(push_arg->IsPushArgument());
ASSERT(reaching_defn->ssa_temp_index() != -1);
- ASSERT(reaching_defn->IsPhi());
+ ASSERT(reaching_defn->IsPhi() || reaching_defn == constant_dead());
push_arg->ReplaceUsesWith(push_arg->InputAt(0)->definition());
push_arg->UnuseAllInputs();
push_arg->previous()->LinkTo(push_arg->next());
@@ -1416,29 +1416,30 @@
// Update expression stack and remove current instruction from the graph.
Definition* definition = current->Cast<Definition>();
if (definition->HasTemp()) {
- ASSERT(result != NULL);
+ ASSERT(result != nullptr);
env->Add(result);
}
it.RemoveCurrentFromGraph();
}
// 3. Process dominated blocks.
- BlockEntryInstr* osr_succ =
- (block_entry == graph_entry() && IsCompiledForOsr())
- ? graph_entry()->osr_entry()->last_instruction()->SuccessorAt(0)
- : nullptr;
+ const bool set_stack = (block_entry == graph_entry()) && IsCompiledForOsr();
for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
BlockEntryInstr* block = block_entry->dominated_blocks()[i];
GrowableArray<Definition*> new_env(env->length());
new_env.AddArray(*env);
- ASSERT(block != nullptr);
- if (block == osr_succ) {
- // During OSR, when visiting the successor block of the OSR entry from
- // the graph entry (rather than going through the OSR entry first), we
- // must adjust the environment to mimic a non-empty incoming expression
- // stack to ensure temporaries refer to the right stack items.
- new_env.FillWith(constant_dead(), new_env.length(),
- graph_entry()->osr_entry()->stack_depth());
+ // During OSR, when traversing from the graph entry directly any block
+ // (which may be a non-entry), we must adjust the environment to mimic
+ // a non-empty incoming expression stack to ensure temporaries refer to
+ // the right stack items.
+ const intptr_t stack_depth = block->stack_depth();
+ ASSERT(stack_depth >= 0);
+ if (set_stack) {
+ ASSERT(variable_count() == new_env.length());
+ new_env.FillWith(constant_dead(), variable_count(), stack_depth);
+ } else if (!block->last_instruction()->IsTailCall()) {
+ // Assert environment integrity otherwise.
+ ASSERT((variable_count() + stack_depth) == new_env.length());
}
RenameRecursive(block, &new_env, live_phis, variable_liveness,
inlining_parameters);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index 7db6c39..af3e2f5 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -952,9 +952,7 @@
VisitBlocks();
-#if defined(DEBUG)
__ bkpt(0);
-#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 2e8362a..8c9f45d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -920,9 +920,7 @@
VisitBlocks();
-#if defined(DEBUG)
__ brk(0);
-#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index f311a34..5b1a9c3 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -839,9 +839,7 @@
VisitBlocks();
if (!skip_body_compilation()) {
-#if defined(DEBUG)
__ int3();
-#endif
GenerateDeferredCode();
}
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index fe4eace..78987ee 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -935,9 +935,7 @@
ASSERT(!block_order().is_empty());
VisitBlocks();
-#if defined(DEBUG)
__ int3();
-#endif
if (!skip_body_compilation()) {
ASSERT(assembler()->constant_pool_allowed());
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 2b1152a..b7adcf9 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -1129,7 +1129,10 @@
GraphEntryInstr::GraphEntryInstr(const ParsedFunction& parsed_function,
intptr_t osr_id,
intptr_t deopt_id)
- : BlockEntryWithInitialDefs(0, kInvalidTryIndex, deopt_id),
+ : BlockEntryWithInitialDefs(0,
+ kInvalidTryIndex,
+ deopt_id,
+ /*stack_depth*/ 0),
parsed_function_(parsed_function),
catch_entries_(),
indirect_entries_(),
@@ -1656,11 +1659,11 @@
// we can simply jump to the beginning of the block.
ASSERT(instr->previous() == this);
- const intptr_t stack_depth = instr->AsCheckStackOverflow()->stack_depth();
+ ASSERT(stack_depth() == instr->AsCheckStackOverflow()->stack_depth());
auto normal_entry = graph_entry->normal_entry();
- auto osr_entry = new OsrEntryInstr(graph_entry, normal_entry->block_id(),
- normal_entry->try_index(),
- normal_entry->deopt_id(), stack_depth);
+ auto osr_entry = new OsrEntryInstr(
+ graph_entry, normal_entry->block_id(), normal_entry->try_index(),
+ normal_entry->deopt_id(), stack_depth());
auto goto_join = new GotoInstr(AsJoinEntry(),
CompilerState::Current().GetNextDeoptId());
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 8128fb9..7d13712 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -1384,6 +1384,10 @@
intptr_t offset() const { return offset_; }
void set_offset(intptr_t offset) { offset_ = offset; }
+ // Stack-based IR bookkeeping.
+ intptr_t stack_depth() const { return stack_depth_; }
+ void set_stack_depth(intptr_t s) { stack_depth_ = s; }
+
// For all instruction in this block: Remove all inputs (including in the
// environment) from their definition's use lists for all instructions.
void ClearAllInstructions();
@@ -1395,12 +1399,16 @@
ADD_EXTRA_INFO_TO_S_EXPRESSION_SUPPORT
protected:
- BlockEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
+ BlockEntryInstr(intptr_t block_id,
+ intptr_t try_index,
+ intptr_t deopt_id,
+ intptr_t stack_depth)
: Instruction(deopt_id),
block_id_(block_id),
try_index_(try_index),
preorder_number_(-1),
postorder_number_(-1),
+ stack_depth_(stack_depth),
dominator_(nullptr),
dominated_blocks_(1),
last_instruction_(NULL),
@@ -1428,6 +1436,8 @@
intptr_t try_index_;
intptr_t preorder_number_;
intptr_t postorder_number_;
+ // Expected stack depth on entry (for stack-based IR only).
+ intptr_t stack_depth_;
// Starting and ending lifetime positions for this block. Used by
// the linear scan register allocator.
intptr_t start_pos_;
@@ -1512,8 +1522,9 @@
public:
BlockEntryWithInitialDefs(intptr_t block_id,
intptr_t try_index,
- intptr_t deopt_id)
- : BlockEntryInstr(block_id, try_index, deopt_id) {}
+ intptr_t deopt_id,
+ intptr_t stack_depth)
+ : BlockEntryInstr(block_id, try_index, deopt_id, stack_depth) {}
GrowableArray<Definition*>* initial_definitions() {
return &initial_definitions_;
@@ -1630,8 +1641,11 @@
class JoinEntryInstr : public BlockEntryInstr {
public:
- JoinEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
- : BlockEntryInstr(block_id, try_index, deopt_id),
+ JoinEntryInstr(intptr_t block_id,
+ intptr_t try_index,
+ intptr_t deopt_id,
+ intptr_t stack_depth = 0)
+ : BlockEntryInstr(block_id, try_index, deopt_id, stack_depth),
predecessors_(2), // Two is the assumed to be the common case.
phis_(NULL) {}
@@ -1698,8 +1712,11 @@
class TargetEntryInstr : public BlockEntryInstr {
public:
- TargetEntryInstr(intptr_t block_id, intptr_t try_index, intptr_t deopt_id)
- : BlockEntryInstr(block_id, try_index, deopt_id),
+ TargetEntryInstr(intptr_t block_id,
+ intptr_t try_index,
+ intptr_t deopt_id,
+ intptr_t stack_depth = 0)
+ : BlockEntryInstr(block_id, try_index, deopt_id, stack_depth),
predecessor_(NULL),
edge_weight_(0.0) {}
@@ -1749,7 +1766,10 @@
intptr_t block_id,
intptr_t try_index,
intptr_t deopt_id)
- : BlockEntryWithInitialDefs(block_id, try_index, deopt_id),
+ : BlockEntryWithInitialDefs(block_id,
+ try_index,
+ deopt_id,
+ /*stack_depth=*/0),
graph_entry_(graph_entry) {}
DECLARE_INSTRUCTION(FunctionEntry)
@@ -1815,8 +1835,7 @@
intptr_t try_index,
intptr_t deopt_id,
intptr_t stack_depth)
- : BlockEntryWithInitialDefs(block_id, try_index, deopt_id),
- stack_depth_(stack_depth),
+ : BlockEntryWithInitialDefs(block_id, try_index, deopt_id, stack_depth),
graph_entry_(graph_entry) {}
DECLARE_INSTRUCTION(OsrEntry)
@@ -1829,7 +1848,6 @@
return graph_entry_;
}
- intptr_t stack_depth() const { return stack_depth_; }
GraphEntryInstr* graph_entry() const { return graph_entry_; }
PRINT_TO_SUPPORT
@@ -1841,7 +1859,6 @@
graph_entry_ = predecessor->AsGraphEntry();
}
- const intptr_t stack_depth_;
GraphEntryInstr* graph_entry_;
DISALLOW_COPY_AND_ASSIGN(OsrEntryInstr);
@@ -1880,7 +1897,10 @@
const LocalVariable* stacktrace_var,
const LocalVariable* raw_exception_var,
const LocalVariable* raw_stacktrace_var)
- : BlockEntryWithInitialDefs(block_id, try_index, deopt_id),
+ : BlockEntryWithInitialDefs(block_id,
+ try_index,
+ deopt_id,
+ /*stack_depth=*/0),
graph_entry_(graph_entry),
predecessor_(NULL),
catch_handler_types_(Array::ZoneHandle(handler_types.raw())),
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index b6e2166..6ed9d5b 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -510,9 +510,7 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
-#if defined(DEBUG)
__ bkpt(0);
-#endif
__ Bind(&done);
}
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 74c983d..3f7f28f 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -499,9 +499,7 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
-#if defined(DEBUG)
__ brk(0);
-#endif
__ Bind(&done);
}
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index a290225..ff3df26 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -392,9 +392,7 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
-#if defined(DEBUG)
__ int3();
-#endif
__ Bind(&done);
}
diff --git a/runtime/vm/compiler/backend/il_serializer.cc b/runtime/vm/compiler/backend/il_serializer.cc
index 1ab17fd..486973b 100644
--- a/runtime/vm/compiler/backend/il_serializer.cc
+++ b/runtime/vm/compiler/backend/il_serializer.cc
@@ -9,6 +9,7 @@
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/method_recognizer.h"
+#include "vm/object_store.h"
#include "vm/os.h"
namespace dart {
@@ -16,23 +17,62 @@
DEFINE_FLAG(bool,
serialize_flow_graph_types,
true,
- "Serialize inferred type information in flow graphs"
- " (with --serialize_flow_graphs_to)");
+ "Serialize inferred type information in flow graphs");
DEFINE_FLAG(bool,
verbose_flow_graph_serialization,
false,
- "Serialize extra information useful for debugging"
- " (with --serialize_flow_graphs_to)");
+ "Serialize extra information useful for debugging");
DEFINE_FLAG(bool,
pretty_print_serialization,
false,
- "Format serialized output nicely"
- " (with --serialize_flow_graphs_to)");
+ "Format serialized output nicely");
+
+DECLARE_FLAG(bool, populate_llvm_constant_pool);
const char* const FlowGraphSerializer::initial_indent = "";
+FlowGraphSerializer::FlowGraphSerializer(Zone* zone,
+ const FlowGraph* flow_graph)
+ : flow_graph_(ASSERT_NOTNULL(flow_graph)),
+ zone_(zone),
+ object_store_(flow_graph->thread()->isolate()->object_store()),
+ open_recursive_types_(zone_),
+ llvm_pool_(
+ GrowableObjectArray::Handle(zone_,
+ object_store_->llvm_constant_pool())),
+ llvm_map_(zone_, object_store_->llvm_constant_hash_table()),
+ llvm_index_(Smi::Handle(zone_)),
+ tmp_string_(String::Handle(zone_)),
+ array_type_args_((TypeArguments::Handle(zone_))),
+ closure_context_(Context::Handle(zone_)),
+ closure_function_(Function::Handle(zone_)),
+ closure_type_args_(TypeArguments::Handle(zone_)),
+ code_owner_(Object::Handle(zone_)),
+ context_parent_(Context::Handle(zone_)),
+ context_elem_(Object::Handle(zone_)),
+ function_type_args_(TypeArguments::Handle(zone_)),
+ ic_data_target_(Function::Handle(zone_)),
+ ic_data_type_(AbstractType::Handle(zone_)),
+ instance_field_(Field::Handle(zone_)),
+ instance_type_args_(TypeArguments::Handle(zone_)),
+ serialize_library_(Library::Handle(zone_)),
+ serialize_owner_(Class::Handle(zone_)),
+ serialize_parent_(Function::Handle(zone_)),
+ type_arguments_elem_(AbstractType::Handle(zone_)),
+ type_class_(Class::Handle(zone_)),
+ type_function_(Function::Handle(zone_)),
+ type_ref_type_(AbstractType::Handle(zone_)) {
+ // Double-check that the zone in the flow graph is a parent of the
+ // zone we'll be using for serialization.
+ ASSERT(flow_graph->zone()->ContainsNestedZone(zone));
+}
+
+FlowGraphSerializer::~FlowGraphSerializer() {
+ object_store_->set_llvm_constant_hash_table(llvm_map_.Release());
+}
+
void FlowGraphSerializer::SerializeToBuffer(const FlowGraph* flow_graph,
TextBuffer* buffer) {
SerializeToBuffer(Thread::Current()->zone(), flow_graph, buffer);
@@ -695,7 +735,8 @@
AddSymbol(elem, "def");
elem->Add(UseToSExp(definition));
// Use ObjectToSExp here, not DartValueToSExp!
- elem->Add(ObjectToSExp(definition->AsConstant()->value()));
+ const auto& value = definition->AsConstant()->value();
+ elem->Add(ObjectToSExp(value));
// Check this first, otherwise Type() can have the side effect of setting
// a new CompileType!
if (definition->HasType()) {
@@ -704,6 +745,16 @@
elem->AddExtra("type", type->ToSExpression(this));
}
}
+ if (FLAG_populate_llvm_constant_pool) {
+ auto const pool_len = llvm_pool_.Length();
+ llvm_index_ = Smi::New(pool_len);
+ llvm_index_ =
+ Smi::RawCast(llvm_map_.InsertOrGetValue(value, llvm_index_));
+ if (llvm_index_.Value() == pool_len) {
+ llvm_pool_.Add(value);
+ }
+ AddExtraInteger(elem, "llvm_index", llvm_index_.Value());
+ }
constant_list->Add(elem);
}
return constant_list;
diff --git a/runtime/vm/compiler/backend/il_serializer.h b/runtime/vm/compiler/backend/il_serializer.h
index 94945e0..7fb3088 100644
--- a/runtime/vm/compiler/backend/il_serializer.h
+++ b/runtime/vm/compiler/backend/il_serializer.h
@@ -12,6 +12,7 @@
#include "vm/compiler/backend/flow_graph.h"
#include "vm/compiler/backend/il.h"
#include "vm/compiler/backend/sexpression.h"
+#include "vm/hash_table.h"
#include "vm/object.h"
#include "vm/zone.h"
@@ -108,34 +109,10 @@
void AddExtraSymbol(SExpList* sexp, const char* label, const char* cstr);
private:
- FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph)
- : flow_graph_(ASSERT_NOTNULL(flow_graph)),
- zone_(zone),
- open_recursive_types_(zone_),
- tmp_string_(String::Handle(zone_)),
- array_type_args_((TypeArguments::Handle(zone_))),
- closure_context_(Context::Handle(zone_)),
- closure_function_(Function::Handle(zone_)),
- closure_type_args_(TypeArguments::Handle(zone_)),
- code_owner_(Object::Handle(zone_)),
- context_parent_(Context::Handle(zone_)),
- context_elem_(Object::Handle(zone_)),
- function_type_args_(TypeArguments::Handle(zone_)),
- ic_data_target_(Function::Handle(zone_)),
- ic_data_type_(AbstractType::Handle(zone_)),
- instance_field_(Field::Handle(zone_)),
- instance_type_args_(TypeArguments::Handle(zone_)),
- serialize_library_(Library::Handle(zone_)),
- serialize_owner_(Class::Handle(zone_)),
- serialize_parent_(Function::Handle(zone_)),
- type_arguments_elem_(AbstractType::Handle(zone_)),
- type_class_(Class::Handle(zone_)),
- type_function_(Function::Handle(zone_)),
- type_ref_type_(AbstractType::Handle(zone_)) {
- // Double-check that the zone in the flow graph is a parent of the
- // zone we'll be using for serialization.
- ASSERT(flow_graph->zone()->ContainsNestedZone(zone));
- }
+ friend class Precompiler; // For LLVMConstantsMap.
+
+ FlowGraphSerializer(Zone* zone, const FlowGraph* flow_graph);
+ ~FlowGraphSerializer();
static const char* const initial_indent;
@@ -147,11 +124,33 @@
const FlowGraph* const flow_graph_;
Zone* const zone_;
+ ObjectStore* const object_store_;
// A map of currently open (being serialized) recursive types. We use this
// to determine whether to serialize the referred types in TypeRefs.
IntMap<const Type*> open_recursive_types_;
+ // Used for --populate-llvm-constant-pool in ConstantPoolToSExp.
+ class LLVMConstantMapKeyEqualsTraits : public AllStatic {
+ public:
+ static const char* Name() { return "LLVMConstantMapKeyEqualsTraits"; }
+ static bool ReportStats() { return false; }
+
+ static bool IsMatch(const Object& a, const Object& b) {
+ return a.raw() == b.raw();
+ }
+ static uword Hash(const Object& obj) {
+ if (obj.IsSmi()) return reinterpret_cast<uword>(obj.raw());
+ if (obj.IsInstance()) return Instance::Cast(obj).CanonicalizeHash();
+ return obj.GetClassId();
+ }
+ };
+ typedef UnorderedHashMap<LLVMConstantMapKeyEqualsTraits> LLVMConstantsMap;
+
+ GrowableObjectArray& llvm_pool_;
+ LLVMConstantsMap llvm_map_;
+ Smi& llvm_index_;
+
// Handles used across functions, where the contained value is used
// immediately and does not need to live across calls to other serializer
// functions.
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index b7cf98f..10face2 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -521,9 +521,7 @@
compiler->GenerateRuntimeCall(token_pos, deopt_id,
kNonBoolTypeErrorRuntimeEntry, 1, locs);
// We should never return here.
-#if defined(DEBUG)
__ int3();
-#endif
__ Bind(&done);
}
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 5e93802..2d10861 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -160,6 +160,7 @@
if (function.IsNull()) {
return false;
}
+ ASSERT(!function.IsInvokeFieldDispatcher());
// Update the CallTargets attached to the instruction with our speculative
// target. The next round of CallSpecializer::VisitInstanceCall will make
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index c6ac8e4..fad3c15 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -661,8 +661,8 @@
}
TargetEntryInstr* BaseFlowGraphBuilder::BuildTargetEntry() {
- return new (Z)
- TargetEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
+ return new (Z) TargetEntryInstr(AllocateBlockId(), CurrentTryIndex(),
+ GetNextDeoptId(), GetStackDepth());
}
FunctionEntryInstr* BaseFlowGraphBuilder::BuildFunctionEntry(
@@ -672,12 +672,13 @@
}
JoinEntryInstr* BaseFlowGraphBuilder::BuildJoinEntry(intptr_t try_index) {
- return new (Z) JoinEntryInstr(AllocateBlockId(), try_index, GetNextDeoptId());
+ return new (Z) JoinEntryInstr(AllocateBlockId(), try_index, GetNextDeoptId(),
+ GetStackDepth());
}
JoinEntryInstr* BaseFlowGraphBuilder::BuildJoinEntry() {
- return new (Z)
- JoinEntryInstr(AllocateBlockId(), CurrentTryIndex(), GetNextDeoptId());
+ return new (Z) JoinEntryInstr(AllocateBlockId(), CurrentTryIndex(),
+ GetNextDeoptId(), GetStackDepth());
}
ArgumentArray BaseFlowGraphBuilder::GetArguments(int count) {
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 034716b..349db75 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -2177,6 +2177,7 @@
B->stack_ = stack_state;
}
code_ = Fragment(join);
+ join->set_stack_depth(B->GetStackDepth());
B->SetCurrentTryIndex(join->try_index());
} else {
// Unreachable bytecode is not allowed.
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 787c06a..6f2240a 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -756,7 +756,7 @@
// of those cases require a dynamic invocation forwarder;
// * we assume that all closures are entered in a checked way.
if (isDynamic && (kind != InvocationKind::getter) &&
- !FLAG_precompiled_mode && I->should_emit_strong_mode_checks() &&
+ I->should_emit_strong_mode_checks() &&
(name.raw() != Symbols::EqualOperator().raw()) &&
(name.raw() != Symbols::Call().raw())) {
name = Function::CreateDynamicInvocationForwarderName(name);
@@ -894,8 +894,7 @@
// checked at the entry because the parameter is marked covariant,
// neither of those cases require a dynamic invocation forwarder;
// * we assume that all closures are entered in a checked way.
- if (!Field::IsGetterName(name) && !FLAG_precompiled_mode &&
- I->should_emit_strong_mode_checks() &&
+ if (!Field::IsGetterName(name) && I->should_emit_strong_mode_checks() &&
(name.raw() != Symbols::EqualOperator().raw()) &&
(name.raw() != Symbols::Call().raw())) {
name = Function::CreateDynamicInvocationForwarderName(name);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 9fb9b27..c142b3f 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1157,6 +1157,8 @@
return BuildConstructorInvocation(true, position);
case kNot:
return BuildNot(position);
+ case kNullCheck:
+ return BuildNullCheck(position);
case kLogicalExpression:
return BuildLogicalExpression(position);
case kConditionalExpression:
@@ -3245,6 +3247,17 @@
return instructions;
}
+Fragment StreamingFlowGraphBuilder::BuildNullCheck(TokenPosition* p) {
+ const TokenPosition position = ReadPosition(); // read position.
+ if (p != nullptr) *p = position;
+
+ TokenPosition operand_position = TokenPosition::kNoSource;
+ Fragment instructions =
+ BuildExpression(&operand_position); // read expression.
+ // TODO(37479): Implement null-check semantics.
+ return instructions;
+}
+
// Translate the logical expression (lhs && rhs or lhs || rhs) in a context
// where a value is required.
//
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 2cdbb28..e26f76d 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -301,6 +301,7 @@
Fragment BuildStaticInvocation(bool is_const, TokenPosition* position);
Fragment BuildConstructorInvocation(bool is_const, TokenPosition* position);
Fragment BuildNot(TokenPosition* position);
+ Fragment BuildNullCheck(TokenPosition* position);
Fragment BuildLogicalExpression(TokenPosition* position);
Fragment TranslateLogicalExpressionForValue(bool negated,
TestFragment* side_exits);
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 2f8fc9f..a6b9762 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -442,6 +442,10 @@
case kNot:
CalculateExpressionFingerprint(); // read expression.
return;
+ case kNullCheck:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
case kLogicalExpression:
CalculateExpressionFingerprint(); // read left.
SkipBytes(1); // read operator.
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 771d4ce..eb23c65 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2229,6 +2229,10 @@
case kNot:
SkipExpression(); // read expression.
return;
+ case kNullCheck:
+ ReadPosition(); // read position.
+ SkipExpression(); // read expression.
+ return;
case kLogicalExpression:
SkipExpression(); // read left.
SkipBytes(1); // read operator.
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index d4f7829..d9ce861 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -267,8 +267,6 @@
copy_args_prologue += Drop();
for (intptr_t i = 0; param < num_params; ++param, ++i) {
- JoinEntryInstr* join = BuildJoinEntry();
-
copy_args_prologue += IntConstant(
compiler::target::ArgumentsDescriptor::named_entry_size() /
compiler::target::kWordSize);
@@ -299,6 +297,9 @@
TargetEntryInstr *supplied, *missing;
copy_args_prologue += BranchIfStrictEqual(&supplied, &missing);
+ // Join good/not_good.
+ JoinEntryInstr* join = BuildJoinEntry();
+
// Let's load position from arg descriptor (to see which parameter is the
// name) and move kEntrySize forward in ArgDescriptopr names array.
Fragment good(supplied);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 2866061..d4e6473 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -33,7 +33,8 @@
// In AOT mode we don't dynamically generate such trampolines but instead rely
// on a static analysis to discover which methods can be invoked dynamically,
// and generate the necessary trampolines during precompilation.
- if (method.name() == Symbols::Call().raw()) {
+ if (method.name() == Symbols::Call().raw() ||
+ method.CanReceiveDynamicInvocation()) {
// Currently we consider all call methods to be invoked dynamically and
// don't mangle their names.
// TODO(vegorov) remove this once we also introduce special type checking
@@ -763,6 +764,10 @@
case kNot:
VisitExpression(); // read expression.
return;
+ case kNullCheck:
+ helper_.ReadPosition(); // read position.
+ VisitExpression(); // read expression.
+ return;
case kLogicalExpression:
needs_expr_temp_ = true;
VisitExpression(); // read left.
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 84b3baf..68217ef 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -187,7 +187,7 @@
return compiler->intrinsic_slow_path_label()->IsUnused();
}
-#if !defined(TARGET_HASH_IN_OBJECT_HEADER)
+#if !defined(HASH_IN_OBJECT_HEADER)
// These two are more complicated on 32 bit platforms, where the
// identity hash is not stored in the header of the object. We
// therefore don't intrinsify them, falling back on the native C++
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index feb31a3..af363e6 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -23,7 +23,7 @@
// The trampolines will have a 1-word object header in front of them.
const intptr_t kOffsetInTrampoline = kWordSize;
-const intptr_t kTrampolineSize = 32;
+const intptr_t kTrampolineSize = OS::kMaxPreferredCodeAlignment;
CodeRelocator::CodeRelocator(Thread* thread,
GrowableArray<RawCode*>* code_objects,
@@ -33,16 +33,7 @@
commands_(commands),
kind_type_and_offset_(Smi::Handle(thread->zone())),
target_(Object::Handle(thread->zone())),
- destination_(Code::Handle(thread->zone())) {
- // Trampolines will be disguised as FreeListElement objects.
- ASSERT(Utils::IsAligned(kTrampolineSize, kObjectAlignment));
- // Trampolines will be inserted between Instructions objects and must
- // preserve their alignment.
- ASSERT(Utils::IsAligned(kTrampolineSize, OS::PreferredCodeAlignment()));
- // Trampolines are big enough to hold a full-range call.
- ASSERT((kOffsetInTrampoline +
- PcRelativeTrampolineJumpPattern::kLengthInBytes) < kTrampolineSize);
-}
+ destination_(Code::Handle(thread->zone())) {}
void CodeRelocator::Relocate(bool is_vm_isolate) {
Zone* zone = Thread::Current()->zone();
@@ -417,12 +408,7 @@
static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
intptr_t trampoline_length) {
uint32_t tags = 0;
-#if defined(IS_SIMARM_X64)
- // Account for difference in kObjectAlignment between host and target.
- tags = RawObject::SizeTag::update(trampoline_length * 2, tags);
-#else
tags = RawObject::SizeTag::update(trampoline_length, tags);
-#endif
tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
tags = RawObject::OldBit::update(true, tags);
tags = RawObject::OldAndNotMarkedBit::update(true, tags);
@@ -478,6 +464,9 @@
// buffer.
auto trampoline_bytes = new uint8_t[kTrampolineSize];
memset(trampoline_bytes, 0x00, kTrampolineSize);
+ ASSERT((kOffsetInTrampoline +
+ PcRelativeTrampolineJumpPattern::kLengthInBytes) <
+ kTrampolineSize);
auto unresolved_trampoline = new UnresolvedTrampoline{
unresolved_call->callee,
unresolved_call->offset_into_target,
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 88ad78e..e7f6f80 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -508,6 +508,7 @@
intptr_t alignment = OS::PreferredCodeAlignment();
intptr_t aligned_size =
Utils::RoundUp(Instructions::UnalignedHeaderSize(), alignment);
+ ASSERT(aligned_size == alignment);
return aligned_size;
}
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 3e93b40..add5eab 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -355,7 +355,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 12;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
@@ -714,7 +714,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 24;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1065,7 +1065,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 12;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
@@ -1425,7 +1425,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 24;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1712,7 +1712,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 16;
+ 24;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
@@ -1996,7 +1996,7 @@
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
- 12;
+ 16;
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 0463a15..c771da7 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -53,6 +53,10 @@
DEFINE_FLAG(bool, trace_shutdown, false, "Trace VM shutdown on stderr");
DECLARE_FLAG(bool, strong);
+#if defined(DART_PRECOMPILED_RUNTIME)
+DEFINE_FLAG(bool, print_llvm_constant_pool, false, "Print LLVM constant pool");
+#endif
+
Isolate* Dart::vm_isolate_ = NULL;
int64_t Dart::start_time_micros_ = 0;
ThreadPool* Dart::thread_pool_ = NULL;
@@ -722,6 +726,32 @@
// AOT: The megamorphic miss function and code come from the snapshot.
ASSERT(I->object_store()->megamorphic_miss_code() != Code::null());
ASSERT(I->object_store()->build_method_extractor_code() != Code::null());
+ if (FLAG_print_llvm_constant_pool) {
+ StackZone printing_zone(T);
+ HandleScope printing_scope(T);
+ const auto& arr =
+ GrowableObjectArray::Handle(I->object_store()->llvm_constant_pool());
+ if (arr.IsNull()) {
+ THR_Print("No constant pool information in snapshot.\n");
+ } else {
+ auto const len = arr.Length();
+ THR_Print("Constant pool contents (length %" Pd "):\n", len);
+ auto& obj = Object::Handle();
+ for (intptr_t i = 0; i < len; i++) {
+ obj = arr.At(i);
+ THR_Print(" %5" Pd ": ", i);
+ if (obj.IsString()) {
+ auto& str = String::Cast(obj);
+ TextBuffer b(100);
+ b.AddEscapedString(str.ToCString());
+ THR_Print("\"%s\"\n", b.buf());
+ } else {
+ THR_Print("%s\n", obj.ToCString());
+ }
+ }
+ THR_Print("End of constant pool.\n\n");
+ }
+ }
#else
// JIT: The megamorphic miss function and code come from the snapshot in JIT
// app snapshot, otherwise create them.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 4c62313..7636aa3 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1627,6 +1627,7 @@
Thread::ExitIsolate();
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
static uint8_t* ApiReallocate(uint8_t* ptr,
intptr_t old_size,
intptr_t new_size) {
@@ -1634,12 +1635,16 @@
->zone()
->Realloc<uint8_t>(ptr, old_size, new_size);
}
+#endif
DART_EXPORT Dart_Handle
Dart_CreateSnapshot(uint8_t** vm_snapshot_data_buffer,
intptr_t* vm_snapshot_data_size,
uint8_t** isolate_snapshot_data_buffer,
intptr_t* isolate_snapshot_data_size) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return Api::NewError("Cannot create snapshots on an AOT runtime.");
+#else
DARTSCOPE(Thread::Current());
API_TIMELINE_DURATION(T);
Isolate* I = T->isolate();
@@ -1676,6 +1681,7 @@
}
*isolate_snapshot_data_size = writer.IsolateSnapshotSize();
return Api::Success();
+#endif
}
DART_EXPORT bool Dart_IsKernel(const uint8_t* buffer, intptr_t buffer_size) {
@@ -6182,10 +6188,6 @@
return Api::NewError("AOT compilation is not supported on IA32.");
#elif defined(TARGET_ARCH_DBC)
return Api::NewError("AOT compilation is not supported on DBC.");
-#elif defined(TARGET_OS_WINDOWS)
- return Api::NewError("Windows cannot load ELF.");
-#elif defined(TARGET_OS_MACOS)
- return Api::NewError("macOS/iOS cannot load ELF.");
#elif !defined(DART_PRECOMPILER)
return Api::NewError(
"This VM was built without support for AOT compilation.");
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 7ba428b..2271645 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -44,10 +44,6 @@
namespace dart {
DEFINE_FLAG(bool,
- show_invisible_frames,
- false,
- "Show invisible frames in debugger stack traces");
-DEFINE_FLAG(bool,
trace_debugger_stacktrace,
false,
"Trace debugger stacktrace collection");
@@ -3377,6 +3373,13 @@
Class& cls = Class::Handle(zone);
Library& lib = Library::Handle(zone, script.FindLibrary());
ASSERT(!lib.IsNull());
+ if (!lib.IsDebuggable()) {
+ if (FLAG_verbose_debug) {
+ OS::PrintErr("Library '%s' has been marked as non-debuggable\n",
+ lib.ToCString());
+ }
+ return false;
+ }
const GrowableObjectArray& closures = GrowableObjectArray::Handle(
zone, isolate_->object_store()->closure_functions());
Array& functions = Array::Handle(zone);
@@ -4534,6 +4537,10 @@
CodeBreakpoint* cbpt = GetCodeBreakpoint(top_frame->pc());
ASSERT(cbpt != NULL);
+ if (!Library::Handle(top_frame->Library()).IsDebuggable()) {
+ return Error::null();
+ }
+
Breakpoint* bpt_hit = FindHitBreakpoint(cbpt->bpt_location_, top_frame);
if (bpt_hit == NULL) {
return Error::null();
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 6306029..769f3d5 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -4,66 +4,13 @@
#include "vm/elf.h"
+#include "platform/elf.h"
#include "platform/text_buffer.h"
#include "vm/cpu.h"
#include "vm/thread.h"
namespace dart {
-#define ELFCLASS32 1
-#define ELFCLASS64 2
-
-static const intptr_t ELFDATA2LSB = 1;
-
-static const intptr_t ELFOSABI_SYSV = 0;
-
-#define EF_ARM_ABI_FLOAT_HARD 0x00000400
-#define EF_ARM_ABI_FLOAT_SOFT 0x00000200
-#define EF_ARM_ABI 0x05000000
-
-static const intptr_t ET_DYN = 3;
-
-#define EM_386 3
-#define EM_ARM 40
-#define EM_X86_64 62
-#define EM_AARCH64 183
-
-static const intptr_t EV_CURRENT = 1;
-
-static const intptr_t SHT_PROGBITS = 1;
-static const intptr_t SHT_STRTAB = 3;
-static const intptr_t SHT_HASH = 5;
-static const intptr_t SHT_DYNSYM = 11;
-static const intptr_t SHT_DYNAMIC = 6;
-
-static const intptr_t SHF_WRITE = 0x1;
-static const intptr_t SHF_ALLOC = 0x2;
-static const intptr_t SHF_EXECINSTR = 0x4;
-
-static const intptr_t SHN_UNDEF = 0;
-
-static const intptr_t STN_UNDEF = 0;
-
-static const intptr_t PT_LOAD = 1;
-static const intptr_t PT_DYNAMIC = 2;
-static const intptr_t PT_PHDR = 6;
-
-static const intptr_t PF_X = 1;
-static const intptr_t PF_W = 2;
-static const intptr_t PF_R = 4;
-
-static const intptr_t STB_GLOBAL = 1;
-
-static const intptr_t STT_OBJECT = 1; // I.e., data.
-static const intptr_t STT_FUNC = 2;
-
-static const intptr_t DT_NULL = 0;
-static const intptr_t DT_HASH = 4;
-static const intptr_t DT_STRTAB = 5;
-static const intptr_t DT_SYMTAB = 6;
-static const intptr_t DT_STRSZ = 10;
-static const intptr_t DT_SYMENT = 11;
-
#if defined(TARGET_ARCH_IS_32_BIT)
static const intptr_t kElfHeaderSize = 52;
static const intptr_t kElfSectionTableAlignment = 4;
@@ -94,7 +41,7 @@
intptr_t section_type = 0;
intptr_t section_flags = 0;
intptr_t section_index = -1;
- intptr_t section_link = SHN_UNDEF;
+ intptr_t section_link = elf::SHN_UNDEF;
intptr_t section_info = 0;
intptr_t section_entry_size = 0;
intptr_t file_size = 0;
@@ -119,16 +66,16 @@
intptr_t memsz = -1) {
if (memsz == -1) memsz = filesz;
- section_type = SHT_PROGBITS;
+ section_type = elf::SHT_PROGBITS;
if (allocate) {
- section_flags = SHF_ALLOC;
- if (executable) section_flags |= SHF_EXECINSTR;
- if (writable) section_flags |= SHF_WRITE;
+ section_flags = elf::SHF_ALLOC;
+ if (executable) section_flags |= elf::SHF_EXECINSTR;
+ if (writable) section_flags |= elf::SHF_WRITE;
- segment_type = PT_LOAD;
- segment_flags = PF_R;
- if (executable) segment_flags |= PF_X;
- if (writable) segment_flags |= PF_W;
+ segment_type = elf::PT_LOAD;
+ segment_flags = elf::PF_R;
+ if (executable) segment_flags |= elf::PF_X;
+ if (writable) segment_flags |= elf::PF_W;
}
bytes_ = bytes;
@@ -148,10 +95,10 @@
class StringTable : public Section {
public:
explicit StringTable(bool allocate) : text_(128) {
- section_type = SHT_STRTAB;
- section_flags = allocate ? SHF_ALLOC : 0;
- segment_type = PT_LOAD;
- segment_flags = PF_R;
+ section_type = elf::SHT_STRTAB;
+ section_flags = allocate ? elf::SHF_ALLOC : 0;
+ segment_type = elf::PT_LOAD;
+ segment_flags = elf::PF_R;
text_.AddChar('\0');
memory_size = file_size = text_.length();
@@ -186,10 +133,10 @@
class SymbolTable : public Section {
public:
SymbolTable() {
- section_type = SHT_DYNSYM;
- section_flags = SHF_ALLOC;
- segment_type = PT_LOAD;
- segment_flags = PF_R;
+ section_type = elf::SHT_DYNSYM;
+ section_flags = elf::SHF_ALLOC;
+ segment_type = elf::PT_LOAD;
+ segment_flags = elf::PF_R;
section_entry_size = kElfSymbolTableEntrySize;
AddSymbol(NULL);
@@ -268,24 +215,24 @@
class SymbolHashTable : public Section {
public:
SymbolHashTable(StringTable* strtab, SymbolTable* symtab) {
- section_type = SHT_HASH;
- section_flags = SHF_ALLOC;
+ section_type = elf::SHT_HASH;
+ section_flags = elf::SHF_ALLOC;
section_link = symtab->section_index;
section_entry_size = kElfSymbolHashTableEntrySize;
- segment_type = PT_LOAD;
- segment_flags = PF_R;
+ segment_type = elf::PT_LOAD;
+ segment_flags = elf::PF_R;
nchain_ = symtab->length();
nbucket_ = symtab->length();
bucket_ = Thread::Current()->zone()->Alloc<int32_t>(nbucket_);
for (intptr_t i = 0; i < nbucket_; i++) {
- bucket_[i] = STN_UNDEF;
+ bucket_[i] = elf::STN_UNDEF;
}
chain_ = Thread::Current()->zone()->Alloc<int32_t>(nchain_);
for (intptr_t i = 0; i < nchain_; i++) {
- chain_[i] = STN_UNDEF;
+ chain_[i] = elf::STN_UNDEF;
}
for (intptr_t i = 1; i < symtab->length(); i++) {
@@ -322,20 +269,20 @@
DynamicTable(StringTable* strtab,
SymbolTable* symtab,
SymbolHashTable* hash) {
- section_type = SHT_DYNAMIC;
+ section_type = elf::SHT_DYNAMIC;
section_link = strtab->section_index;
- section_flags = SHF_ALLOC | SHF_WRITE;
+ section_flags = elf::SHF_ALLOC | elf::SHF_WRITE;
section_entry_size = kElfDynamicTableEntrySize;
- segment_type = PT_LOAD;
- segment_flags = PF_R | PF_W;
+ segment_type = elf::PT_LOAD;
+ segment_flags = elf::PF_R | elf::PF_W;
- AddEntry(DT_HASH, hash->memory_offset);
- AddEntry(DT_STRTAB, strtab->memory_offset);
- AddEntry(DT_STRSZ, strtab->memory_size);
- AddEntry(DT_SYMTAB, symtab->memory_offset);
- AddEntry(DT_SYMENT, kElfSymbolTableEntrySize);
- AddEntry(DT_NULL, 0);
+ AddEntry(elf::DT_HASH, hash->memory_offset);
+ AddEntry(elf::DT_STRTAB, strtab->memory_offset);
+ AddEntry(elf::DT_STRSZ, strtab->memory_size);
+ AddEntry(elf::DT_SYMTAB, symtab->memory_offset);
+ AddEntry(elf::DT_SYMENT, kElfSymbolTableEntrySize);
+ AddEntry(elf::DT_NULL, 0);
}
void Write(Elf* stream) {
@@ -432,7 +379,7 @@
Symbol* symbol = new (zone_) Symbol();
symbol->cstr = name;
symbol->name = symstrtab_->AddString(name);
- symbol->info = (STB_GLOBAL << 4) | STT_FUNC;
+ symbol->info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
symbol->section = image->section_index;
// For shared libraries, this is the offset from the DSO base. For static
// libraries, this is section relative.
@@ -444,8 +391,16 @@
}
intptr_t Elf::AddBSSData(const char* name, intptr_t size) {
- ProgramBits* image = new (zone_)
- ProgramBits(true, false, true, nullptr, /*filesz=*/0, /*memsz=*/size);
+ // Ideally the BSS segment would take no space in the object, but Android's
+ // "strip" utility truncates the memory-size of our segments to their
+ // file-size.
+ //
+ // Therefore we must insert zero-filled pages for the BSS.
+ uint8_t* const bytes = Thread::Current()->zone()->Alloc<uint8_t>(size);
+ memset(bytes, 0, size);
+
+ ProgramBits* const image = new (zone_)
+ ProgramBits(true, false, true, bytes, /*filesz=*/size, /*memsz=*/size);
image->section_name = shstrtab_->AddString(".bss");
AddSection(image);
AddSegment(image);
@@ -453,7 +408,7 @@
Symbol* symbol = new (zone_) Symbol();
symbol->cstr = name;
symbol->name = symstrtab_->AddString(name);
- symbol->info = (STB_GLOBAL << 4) | STT_OBJECT;
+ symbol->info = (elf::STB_GLOBAL << 4) | elf::STT_OBJECT;
symbol->section = image->section_index;
// For shared libraries, this is the offset from the DSO base. For static
// libraries, this is section relative.
@@ -473,7 +428,7 @@
Symbol* symbol = new (zone_) Symbol();
symbol->cstr = name;
symbol->name = symstrtab_->AddString(name);
- symbol->info = (STB_GLOBAL << 4) | STT_OBJECT;
+ symbol->info = (elf::STB_GLOBAL << 4) | elf::STT_OBJECT;
symbol->section = image->section_index;
// For shared libraries, this is the offset from the DSO base. For static
// libraries, this is section relative.
@@ -550,39 +505,52 @@
void Elf::WriteHeader() {
#if defined(TARGET_ARCH_IS_32_BIT)
- uint8_t size = ELFCLASS32;
+ uint8_t size = elf::ELFCLASS32;
#else
- uint8_t size = ELFCLASS64;
+ uint8_t size = elf::ELFCLASS64;
#endif
- uint8_t e_ident[16] = {
- 0x7f, 'E', 'L', 'F', size, ELFDATA2LSB, EV_CURRENT, ELFOSABI_SYSV,
- 0, 0, 0, 0, 0, 0, 0, 0};
+ uint8_t e_ident[16] = {0x7f,
+ 'E',
+ 'L',
+ 'F',
+ size,
+ elf::ELFDATA2LSB,
+ elf::EV_CURRENT,
+ elf::ELFOSABI_SYSV,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0};
stream_->WriteBytes(e_ident, 16);
- WriteHalf(ET_DYN); // Shared library.
+ WriteHalf(elf::ET_DYN); // Shared library.
#if defined(TARGET_ARCH_IA32)
- WriteHalf(EM_386);
+ WriteHalf(elf::EM_386);
#elif defined(TARGET_ARCH_X64)
- WriteHalf(EM_X86_64);
+ WriteHalf(elf::EM_X86_64);
#elif defined(TARGET_ARCH_ARM)
- WriteHalf(EM_ARM);
+ WriteHalf(elf::EM_ARM);
#elif defined(TARGET_ARCH_ARM64)
- WriteHalf(EM_AARCH64);
+ WriteHalf(elf::EM_AARCH64);
#else
// E.g., DBC.
FATAL("Unknown ELF architecture");
#endif
- WriteWord(EV_CURRENT); // Version
+ WriteWord(elf::EV_CURRENT); // Version
WriteAddr(0); // "Entry point"
WriteOff(program_table_file_offset_);
WriteOff(section_table_file_offset_);
#if defined(TARGET_ARCH_ARM)
- uword flags = EF_ARM_ABI |
- (TargetCPUFeatures::hardfp_supported() ? EF_ARM_ABI_FLOAT_HARD
- : EF_ARM_ABI_FLOAT_SOFT);
+ uword flags = elf::EF_ARM_ABI | (TargetCPUFeatures::hardfp_supported()
+ ? elf::EF_ARM_ABI_FLOAT_HARD
+ : elf::EF_ARM_ABI_FLOAT_SOFT);
#else
uword flags = 0;
#endif
@@ -607,17 +575,17 @@
ASSERT(kNumImplicitSegments == 3);
const intptr_t start = stream_->position();
#if defined(TARGET_ARCH_IS_32_BIT)
- WriteWord(PT_PHDR);
+ WriteWord(elf::PT_PHDR);
WriteOff(program_table_file_offset_); // File offset.
WriteAddr(program_table_file_offset_); // Virtual address.
WriteAddr(program_table_file_offset_); // Physical address, not used.
WriteWord(program_table_file_size_);
WriteWord(program_table_file_size_);
- WriteWord(PF_R);
+ WriteWord(elf::PF_R);
WriteWord(kPageSize);
#else
- WriteWord(PT_PHDR);
- WriteWord(PF_R);
+ WriteWord(elf::PT_PHDR);
+ WriteWord(elf::PF_R);
WriteOff(program_table_file_offset_); // File offset.
WriteAddr(program_table_file_offset_); // Virtual address.
WriteAddr(program_table_file_offset_); // Physical address, not used.
@@ -642,17 +610,17 @@
ASSERT(kNumImplicitSegments == 3);
const intptr_t start = stream_->position();
#if defined(TARGET_ARCH_IS_32_BIT)
- WriteWord(PT_LOAD);
+ WriteWord(elf::PT_LOAD);
WriteOff(0); // File offset.
WriteAddr(0); // Virtual address.
WriteAddr(0); // Physical address, not used.
WriteWord(program_table_file_offset_ + program_table_file_size_);
WriteWord(program_table_file_offset_ + program_table_file_size_);
- WriteWord(PF_R);
+ WriteWord(elf::PF_R);
WriteWord(kPageSize);
#else
- WriteWord(PT_LOAD);
- WriteWord(PF_R);
+ WriteWord(elf::PT_LOAD);
+ WriteWord(elf::PF_R);
WriteOff(0); // File offset.
WriteAddr(0); // Virtual address.
WriteAddr(0); // Physical address, not used.
@@ -696,7 +664,7 @@
ASSERT(kNumImplicitSegments == 3);
const intptr_t start = stream_->position();
#if defined(TARGET_ARCH_IS_32_BIT)
- WriteWord(PT_DYNAMIC);
+ WriteWord(elf::PT_DYNAMIC);
WriteOff(dynamic_->file_offset);
WriteAddr(dynamic_->memory_offset); // Virtual address.
WriteAddr(dynamic_->memory_offset); // Physical address, not used.
@@ -705,7 +673,7 @@
WriteWord(dynamic_->segment_flags);
WriteWord(dynamic_->alignment);
#else
- WriteWord(PT_DYNAMIC);
+ WriteWord(elf::PT_DYNAMIC);
WriteWord(dynamic_->segment_flags);
WriteOff(dynamic_->file_offset);
WriteAddr(dynamic_->memory_offset); // Virtual address.
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 42d44cc..d7b0a9f 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -165,6 +165,10 @@
C(stress_async_stacks, false, false, bool, false, \
"Stress test async stack traces") \
P(use_bare_instructions, bool, true, "Enable bare instructions mode.") \
+ P(show_invisible_frames, bool, false, \
+ "Show invisible frames in stack traces.") \
+ R(show_invisible_isolates, false, bool, false, \
+ "Show invisible isolates in the vm-service.") \
R(support_disassembler, false, bool, true, "Support the disassembler.") \
R(support_il_printer, false, bool, true, "Support the IL printer.") \
C(support_reload, false, false, bool, true, "Support isolate reload.") \
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index bd6f62b..a926493 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -6,6 +6,7 @@
#include "platform/assert.h"
#include "vm/compiler/backend/code_statistics.h"
+#include "vm/compiler/runtime_api.h"
#include "vm/dwarf.h"
#include "vm/elf.h"
#include "vm/hash.h"
@@ -80,6 +81,7 @@
reinterpret_cast<const void*>(body_b), body_size);
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
ImageWriter::ImageWriter(Heap* heap,
const void* shared_objects,
const void* shared_instructions,
@@ -219,7 +221,7 @@
}
static constexpr intptr_t kSimarmX64InstructionsAlignment =
- compiler::target::ObjectAlignment::kObjectAlignment;
+ 2 * compiler::target::ObjectAlignment::kObjectAlignment;
static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
const intptr_t header_size = Utils::RoundUp(3 * compiler::target::kWordSize,
kSimarmX64InstructionsAlignment);
@@ -677,7 +679,8 @@
text_offset += WriteByteSequence(beginning, entry);
#endif // defined(IS_SIMARM_X64)
- ASSERT((text_offset - instr_start) == insns.HeaderSize());
+ ASSERT((text_offset - instr_start) ==
+ compiler::target::Instructions::HeaderSize());
}
// 2. Write a label at the entry point.
@@ -753,9 +756,9 @@
#else
text_offset += WriteByteSequence(entry, end);
#endif
+ ASSERT(kWordSize != compiler::target::kWordSize ||
+ (text_offset - instr_start) == insns.raw()->HeapSize());
}
-
- ASSERT((text_offset - instr_start) == insns.raw()->HeapSize());
}
FrameUnwindEpilogue();
@@ -1075,11 +1078,13 @@
instructions_blob_stream_.bytes_written());
ASSERT(segment_base == segment_base2);
- const intptr_t real_bss_base = elf_->AddBSSData("_kDartVMBSSData", 8);
+ const intptr_t real_bss_base =
+ elf_->AddBSSData("_kDartVMBSSData", sizeof(compiler::target::uword));
ASSERT(bss_base == real_bss_base);
}
#endif
}
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
ImageReader::ImageReader(const uint8_t* data_image,
const uint8_t* instructions_image,
@@ -1143,6 +1148,7 @@
return result;
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
void DropCodeWithoutReusableInstructions(const void* reused_instructions) {
class DropCodeVisitor : public FunctionVisitor, public ClassVisitor {
public:
@@ -1242,5 +1248,6 @@
ProgramVisitor::VisitClasses(&visitor);
ProgramVisitor::VisitFunctions(&visitor);
}
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
} // namespace dart
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 427163e..03415ac 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
// Both version numbers are inclusive.
static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 32;
+static const uint32_t kMaxSupportedKernelFormatVersion = 33;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \
@@ -60,6 +60,7 @@
V(ConstructorInvocation, 31) \
V(ConstConstructorInvocation, 32) \
V(Not, 33) \
+ V(NullCheck, 117) \
V(LogicalExpression, 34) \
V(ConditionalExpression, 35) \
V(StringConcatenation, 36) \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 007878e..e06b85a 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -84,7 +84,6 @@
DECLARE_FLAG(bool, dual_map_code);
DECLARE_FLAG(bool, intrinsify);
-DECLARE_FLAG(bool, show_invisible_frames);
DECLARE_FLAG(bool, trace_deoptimization);
DECLARE_FLAG(bool, trace_deoptimization_verbose);
DECLARE_FLAG(bool, trace_reload);
@@ -12495,21 +12494,6 @@
return "Instructions";
}
-CodeStatistics* Instructions::stats() const {
-#if defined(DART_PRECOMPILER)
- return reinterpret_cast<CodeStatistics*>(
- Thread::Current()->heap()->GetPeer(raw()));
-#else
- return nullptr;
-#endif
-}
-
-void Instructions::set_stats(CodeStatistics* stats) const {
-#if defined(DART_PRECOMPILER)
- Thread::Current()->heap()->SetPeer(raw(), stats);
-#endif
-}
-
// Encode integer |value| in SLEB128 format and store into |data|.
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
bool is_last_part = false;
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 33a9dad..81bc595 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4791,16 +4791,17 @@
}
static intptr_t InstanceSize(intptr_t size) {
- // OS::PreferredCodeAlignment() is smaller than kObjectAlignment for
- // simarm_x64.
- const intptr_t alignment =
- Utils::Maximum(OS::PreferredCodeAlignment(), kObjectAlignment);
- return Utils::RoundUp(HeaderSize() + size, alignment);
+ intptr_t instructions_size =
+ Utils::RoundUp(size, OS::PreferredCodeAlignment());
+ intptr_t result = instructions_size + HeaderSize();
+ ASSERT(result % OS::PreferredCodeAlignment() == 0);
+ return result;
}
static intptr_t HeaderSize() {
- intptr_t alignment = OS::PreferredCodeAlignment();
- intptr_t aligned_size = Utils::RoundUp(sizeof(RawInstructions), alignment);
+ const intptr_t alignment = OS::PreferredCodeAlignment();
+ const intptr_t aligned_size =
+ Utils::RoundUp(sizeof(RawInstructions), alignment);
return aligned_size;
}
@@ -4819,8 +4820,19 @@
return memcmp(a->ptr(), b->ptr(), InstanceSize(Size(a))) == 0;
}
- CodeStatistics* stats() const;
- void set_stats(CodeStatistics* stats) const;
+ CodeStatistics* stats() const {
+#if defined(DART_PRECOMPILER)
+ return raw_ptr()->stats_;
+#else
+ return nullptr;
+#endif
+ }
+
+ void set_stats(CodeStatistics* stats) const {
+#if defined(DART_PRECOMPILER)
+ StoreNonPointer(&raw_ptr()->stats_, stats);
+#endif
+ }
uword unchecked_entrypoint_pc_offset() const {
return raw_ptr()->unchecked_entrypoint_pc_offset_;
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 1fe1f7a..221a326 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -124,6 +124,8 @@
RW(Function, async_star_move_next_helper) \
RW(Function, complete_on_async_return) \
RW(Class, async_star_stream_controller) \
+ RW(GrowableObjectArray, llvm_constant_pool) \
+ RW(Array, llvm_constant_hash_table) \
RW(ObjectPool, global_object_pool) \
RW(Array, unique_dynamic_targets) \
RW(GrowableObjectArray, megamorphic_cache_table) \
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index f36bf2e..af98eb1 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -69,7 +69,7 @@
// This constant is guaranteed to be greater or equal to the
// preferred code alignment on all platforms.
- static const int kMaxPreferredCodeAlignment = 16;
+ static const int kMaxPreferredCodeAlignment = 32;
// Returns the preferred code alignment or zero if
// the platform doesn't care. Guaranteed to be a power of two.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 9c105a9..38168ad 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -204,9 +204,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 16;
+ const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM)
- const int kMinimumAlignment = 8;
+ const int kMinimumAlignment = 16;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 56dc743..4eaae29 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -153,9 +153,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 16;
+ const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM)
- const int kMinimumAlignment = 8;
+ const int kMinimumAlignment = 16;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 65541b0..9baba7e 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -516,9 +516,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 16;
+ const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM)
- const int kMinimumAlignment = 8;
+ const int kMinimumAlignment = 16;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 5518b4a..4788b6c 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -154,9 +154,9 @@
intptr_t OS::PreferredCodeAlignment() {
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- const int kMinimumAlignment = 16;
+ const int kMinimumAlignment = 32;
#elif defined(TARGET_ARCH_ARM)
- const int kMinimumAlignment = 8;
+ const int kMinimumAlignment = 16;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index fa7a880..c0f8e39 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -191,12 +191,12 @@
}
intptr_t OS::PreferredCodeAlignment() {
- ASSERT(16 <= OS::kMaxPreferredCodeAlignment);
+ ASSERT(32 <= OS::kMaxPreferredCodeAlignment);
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
- return 16;
+ return 32;
#elif defined(TARGET_ARCH_ARM)
- return 8;
+ return 16;
#else
#error Unsupported architecture.
#endif
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index db033d0..c8b057a 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -21,7 +21,6 @@
DECLARE_FLAG(int, max_profile_depth);
DECLARE_FLAG(int, profile_period);
-DECLARE_FLAG(bool, show_invisible_frames);
DECLARE_FLAG(bool, profile_vm);
#ifndef PRODUCT
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 1820fa8..9a33d1b 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1478,6 +1478,15 @@
uint32_t size_and_flags_;
uint32_t unchecked_entrypoint_pc_offset_;
+ // There is a gap between size_and_flags_ and the entry point
+ // because we align entry point by 4 words on all platforms.
+ // This allows us to have a free field here without affecting
+ // the aligned size of the Instructions object header.
+ // This also means that entry point offset is the same
+ // whether this field is included or excluded.
+ // TODO(37103): This field should be removed.
+ CodeStatistics* stats_;
+
// Variable length data follows here.
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 26d4946..9dec549 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -116,20 +116,18 @@
return function.raw();
}
// Getter invocation might actually be a method extraction.
- if (FLAG_lazy_dispatchers) {
- if (is_getter && function.IsNull()) {
- function = cls.LookupDynamicFunction(demangled);
- if (!function.IsNull()) {
- if (allow_add) {
- // We were looking for the getter but found a method with the same
- // name. Create a method extractor and return it.
- // The extractor does not exist yet, so using GetMethodExtractor is
- // not necessary here.
- function = function.CreateMethodExtractor(function_name);
- return function.raw();
- } else {
- return Function::null();
- }
+ if (is_getter && function.IsNull()) {
+ function = cls.LookupDynamicFunction(demangled);
+ if (!function.IsNull()) {
+ if (allow_add && FLAG_lazy_dispatchers) {
+ // We were looking for the getter but found a method with the same
+ // name. Create a method extractor and return it.
+ // The extractor does not exist yet, so using GetMethodExtractor is
+ // not necessary here.
+ function = function.CreateMethodExtractor(function_name);
+ return function.raw();
+ } else {
+ return Function::null();
}
}
}
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 68cc4a7..43225fb 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -950,7 +950,8 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
ASSERT(isolate != NULL);
- ASSERT(!Isolate::IsVMInternalIsolate(isolate));
+ ASSERT(FLAG_show_invisible_isolates ||
+ !Isolate::IsVMInternalIsolate(isolate));
if (FLAG_trace_service) {
OS::PrintErr(
@@ -4280,7 +4281,7 @@
virtual ~ServiceIsolateVisitor() {}
void VisitIsolate(Isolate* isolate) {
- if (!IsVMInternalIsolate(isolate)) {
+ if (FLAG_show_invisible_isolates || !IsVMInternalIsolate(isolate)) {
jsarr_->AddValue(isolate);
}
}
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index b91b660..c37a63f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1110,8 +1110,8 @@
### setFlag
```
-Success setFlag(string name,
- string value)
+Success|Error setFlag(string name,
+ string value)
```
The _setFlag_ RPC is used to set a VM flag at runtime. Returns an error if the
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 1587330..e7441e1 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -35,7 +35,8 @@
timestamp_(OS::GetCurrentTimeMillis()) {
// We should never generate events for the vm or service isolates.
ASSERT(isolate_ != Dart::vm_isolate());
- ASSERT(isolate == NULL || !Isolate::IsVMInternalIsolate(isolate));
+ ASSERT(isolate == NULL || FLAG_show_invisible_isolates ||
+ !Isolate::IsVMInternalIsolate(isolate));
if ((event_kind == ServiceEvent::kPauseStart) ||
(event_kind == ServiceEvent::kPauseExit)) {
@@ -180,7 +181,11 @@
PrintJSONHeader(&jsobj);
if (kind() == kVMFlagUpdate) {
jsobj.AddProperty("flag", flag_name());
+ // For backwards compatibility, "new_value" is also provided.
+ // TODO(bkonyi): remove when service protocol major version is incremented.
+ ASSERT(SERVICE_PROTOCOL_MAJOR_VERSION == 3);
jsobj.AddProperty("new_value", flag_new_value());
+ jsobj.AddProperty("newValue", flag_new_value());
}
if (kind() == kIsolateReload) {
if (reload_error_ == NULL) {
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index b01182b..6bd77f4 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -219,7 +219,7 @@
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
- if (Isolate::IsVMInternalIsolate(isolate)) {
+ if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
return false;
}
ASSERT(isolate != NULL);
@@ -245,7 +245,7 @@
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
- if (Isolate::IsVMInternalIsolate(isolate)) {
+ if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
return false;
}
ASSERT(isolate != NULL);
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 5a89221..394f45b 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -11,8 +11,6 @@
namespace dart {
-DECLARE_FLAG(bool, show_invisible_frames);
-
class StackTraceUtils : public AllStatic {
public:
/// Counts the number of stack frames.
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index ac2c84a..d4195bd 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -538,8 +538,9 @@
klass, declaration_type_args);
}
} else {
- // It can also be a phi node where the inputs are any of the above.
- ASSERT(type_arguments->IsPhi());
+ // It can also be a phi node where the inputs are any of the above,
+ // or it could be the result of _prependTypeArguments call.
+ ASSERT(type_arguments->IsPhi() || type_arguments->IsStaticCall());
}
}
diff --git a/runtime/vm/utils_test.cc b/runtime/vm/utils_test.cc
index 7234392..59d4b24 100644
--- a/runtime/vm/utils_test.cc
+++ b/runtime/vm/utils_test.cc
@@ -230,6 +230,7 @@
EXPECT_EQ(0x0, reinterpret_cast<uint8_t*>(&value32be)[1]);
EXPECT_EQ(0xf1, reinterpret_cast<uint8_t*>(&value32be)[2]);
EXPECT_EQ(0xf2, reinterpret_cast<uint8_t*>(&value32be)[3]);
+ EXPECT_EQ(0xf1f2u, Utils::BigEndianToHost32(value32be));
uint32_t value32le = Utils::HostToLittleEndian32(0xf1f2);
EXPECT_EQ(0xf2, reinterpret_cast<uint8_t*>(&value32le)[0]);
@@ -256,6 +257,7 @@
EXPECT_EQ(0x0, reinterpret_cast<uint8_t*>(&value64le)[5]);
EXPECT_EQ(0x0, reinterpret_cast<uint8_t*>(&value64le)[6]);
EXPECT_EQ(0x0, reinterpret_cast<uint8_t*>(&value64le)[7]);
+ EXPECT_EQ(0xf1f2f3f4ul, Utils::LittleEndianToHost64(value64le));
}
VM_UNIT_TEST_CASE(DoublesBitEqual) {
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 2eb4372..fcd0f5e 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -57,9 +57,9 @@
bool is_executable,
const char* name);
+ // Returns the cached page size. Use only if Init() has been called.
static intptr_t PageSize() {
ASSERT(page_size_ != 0);
- ASSERT(Utils::IsPowerOfTwo(page_size_));
return page_size_;
}
@@ -76,6 +76,8 @@
static VirtualMemory* ForImagePage(void* pointer, uword size);
private:
+ static intptr_t CalculatePageSize();
+
// Free a sub segment. On operating systems that support it this
// can give back the virtual memory to the system. Returns true on success.
static void FreeSubSegment(void* address, intptr_t size);
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index 09e946d..4f2aa78 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -40,8 +40,15 @@
uword VirtualMemory::page_size_ = 0;
+intptr_t VirtualMemory::CalculatePageSize() {
+ const intptr_t page_size = getpagesize();
+ ASSERT(page_size != 0);
+ ASSERT(Utils::IsPowerOfTwo(page_size));
+ return page_size;
+}
+
void VirtualMemory::Init() {
- page_size_ = getpagesize();
+ page_size_ = CalculatePageSize();
}
static void Unmap(zx_handle_t vmar, uword start, uword end) {
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 87cbc04..bf4fed7 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -42,8 +42,20 @@
uword VirtualMemory::page_size_ = 0;
+intptr_t VirtualMemory::CalculatePageSize() {
+ const intptr_t page_size = getpagesize();
+ ASSERT(page_size != 0);
+ ASSERT(Utils::IsPowerOfTwo(page_size));
+ return page_size;
+}
+
void VirtualMemory::Init() {
- page_size_ = getpagesize();
+ if (page_size_ != 0) {
+ // Already initialized.
+ return;
+ }
+
+ page_size_ = CalculatePageSize();
#if defined(DUAL_MAPPING_SUPPORTED)
// Perf is Linux-specific and the flags aren't defined in Product.
@@ -62,7 +74,7 @@
// such as on docker containers, and disable dual mapping in this case.
// Also detect for missing support of memfd_create syscall.
if (FLAG_dual_map_code) {
- intptr_t size = page_size_;
+ intptr_t size = PageSize();
intptr_t alignment = 256 * 1024; // e.g. heap page size.
VirtualMemory* vm = AllocateAligned(size, alignment, true, NULL);
if (vm == NULL) {
@@ -167,10 +179,10 @@
//
// If FLAG_dual_map_code is active, the executable mapping will be mapped RX
// immediately and never changes protection until it is eventually unmapped.
- ASSERT(Utils::IsAligned(size, page_size_));
+ ASSERT(Utils::IsAligned(size, PageSize()));
ASSERT(Utils::IsPowerOfTwo(alignment));
- ASSERT(Utils::IsAligned(alignment, page_size_));
- const intptr_t allocated_size = size + alignment - page_size_;
+ ASSERT(Utils::IsAligned(alignment, PageSize()));
+ const intptr_t allocated_size = size + alignment - PageSize();
#if defined(DUAL_MAPPING_SUPPORTED)
int fd = -1;
const bool dual_mapping =
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 33d4edbc..d52ea07 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -18,10 +18,17 @@
uword VirtualMemory::page_size_ = 0;
-void VirtualMemory::Init() {
+intptr_t VirtualMemory::CalculatePageSize() {
SYSTEM_INFO info;
GetSystemInfo(&info);
- page_size_ = info.dwPageSize;
+ const intptr_t page_size = info.dwPageSize;
+ ASSERT(page_size != 0);
+ ASSERT(Utils::IsPowerOfTwo(page_size));
+ return page_size;
+}
+
+void VirtualMemory::Init() {
+ page_size_ = CalculatePageSize();
}
bool VirtualMemory::DualMappingEnabled() {
@@ -35,10 +42,10 @@
// When FLAG_write_protect_code is active, code memory (indicated by
// is_executable = true) is allocated as non-executable and later
// changed to executable via VirtualMemory::Protect.
- ASSERT(Utils::IsAligned(size, page_size_));
+ ASSERT(Utils::IsAligned(size, PageSize()));
ASSERT(Utils::IsPowerOfTwo(alignment));
- ASSERT(Utils::IsAligned(alignment, page_size_));
- intptr_t reserved_size = size + alignment - page_size_;
+ ASSERT(Utils::IsAligned(alignment, PageSize()));
+ intptr_t reserved_size = size + alignment - PageSize();
int prot = (is_executable && !FLAG_write_protect_code)
? PAGE_EXECUTE_READWRITE
: PAGE_READWRITE;
diff --git a/sdk/bin/dartdevc_sdk b/sdk/bin/dartdevc_sdk
index 60d2fe1..6cba7d8 100755
--- a/sdk/bin/dartdevc_sdk
+++ b/sdk/bin/dartdevc_sdk
@@ -25,4 +25,14 @@
# We are running the snapshot in the built SDK.
DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$@"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+ read -a OPTIONS <<< "$DART_VM_OPTIONS"
+ EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
diff --git a/sdk/bin/dartdevc_sdk.bat b/sdk/bin/dartdevc_sdk.bat
index 5dbf707..ce027a9 100644
--- a/sdk/bin/dartdevc_sdk.bat
+++ b/sdk/bin/dartdevc_sdk.bat
@@ -22,7 +22,14 @@
set SDK_ARG=--dart-sdk=%SDK_DIR%
-"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+set EXTRA_VM_OPTIONS=
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+ set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+"%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart b/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
index 83421ab..49c7df3 100644
--- a/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
@@ -523,6 +523,7 @@
///
/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
+ if (!dart.isDartFunction(f)) return f;
var ret = _interopExpando[f];
if (ret == null) {
ret = JS(
@@ -547,6 +548,7 @@
///
/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
+ if (!dart.isDartFunction(f)) return f;
var ret = _interopCaptureThisExpando[f];
if (ret == null) {
ret = JS(
diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 3175eeb..f59c330 100644
--- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -92,6 +92,10 @@
return f;
}
+bool isDartFunction(obj) =>
+ JS<bool>('!', '# instanceof Function', obj) &&
+ JS<bool>('!', '#[#] != null', obj, _runtimeType);
+
/// The Dart type that represents a JavaScript class(/constructor) type.
///
/// The JavaScript type may not exist, either because it's not loaded yet, or
diff --git a/sdk/lib/_internal/js_runtime/lib/rti.dart b/sdk/lib/_internal/js_runtime/lib/rti.dart
index 780f6c0..15d13e2 100644
--- a/sdk/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/rti.dart
@@ -363,6 +363,11 @@
@pragma('dart2js:noInline')
Rti instantiatedGenericFunctionType(
Rti genericFunctionRti, Rti instantiationRti) {
+ // If --lax-runtime-type-to-string is enabled and we never check the function
+ // type, then the function won't have a signature, so its RTI will be null. In
+ // this case, there is nothing to instantiate, so we return `null` and the
+ // instantiation appears to be an interface type instead.
+ if (genericFunctionRti == null) return null;
var bounds = Rti._getGenericFunctionBounds(genericFunctionRti);
var typeArguments = Rti._getInterfaceTypeArguments(instantiationRti);
assert(_Utils.arrayLength(bounds) == _Utils.arrayLength(typeArguments));
diff --git a/sdk/lib/_internal/vm/lib/wasm_patch.dart b/sdk/lib/_internal/vm/lib/wasm_patch.dart
index f0c2794..1637384 100644
--- a/sdk/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk/lib/_internal/vm/lib/wasm_patch.dart
@@ -60,6 +60,7 @@
}
void _init(Uint8List data) native 'Wasm_initModule';
+ String describe() native 'Wasm_describeModule';
}
class _NativeWasmImports extends NativeFieldWrapperClass1
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 95a8b97..66df3dc 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1096,9 +1096,9 @@
* When subscribing using [drain], cancelOnError will be true. This means
* that the future will complete with the first error on this stream and then
* cancel the subscription.
- * If this stream emits an error, or the call to [combine] throws,
- * the returned future is completed with that error,
- * and processing is stopped.
+ *
+ * If this stream emits an error, the returned future is completed with
+ * that error, and processing is stopped.
*
* In case of a `done` event the future completes with the given
* [futureValue].
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index ce522be..7ebd1d5 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -35,18 +35,18 @@
/// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding.
///
-/// Shorthand for [base64.encode]. Useful if a local variable shadows the global
+/// Shorthand for `base64.encode`. Useful if a local variable shadows the global
/// [base64] constant.
String base64Encode(List<int> bytes) => base64.encode(bytes);
/// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding.
///
-/// Shorthand for [base64url.encode].
+/// Shorthand for `base64url.encode`.
String base64UrlEncode(List<int> bytes) => base64Url.encode(bytes);
/// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes.
///
-/// Shorthand for [base64.decode]. Useful if a local variable shadows the
+/// Shorthand for `base64.decode`. Useful if a local variable shadows the
/// global [base64] constant.
Uint8List base64Decode(String source) => base64.decode(source);
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 5746e52..97216f7 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -74,10 +74,10 @@
/// If [toEncodable] is omitted, it defaults to a function that returns the
/// result of calling `.toJson()` on the unencodable object.
///
-/// Shorthand for [json.encode]. Useful if a local variable shadows the global
+/// Shorthand for `json.encode`. Useful if a local variable shadows the global
/// [json] constant.
-String jsonEncode(Object object, {Object toEncodable(Object nonEncodable)}) =>
- json.encode(object, toEncodable: toEncodable);
+String jsonEncode(Object value, {Object toEncodable(Object nonEncodable)}) =>
+ json.encode(value, toEncodable: toEncodable);
/// Parses the string and returns the resulting Json object.
///
@@ -88,7 +88,7 @@
///
/// The default [reviver] (when not provided) is the identity function.
///
-/// Shorthand for [json.decode]. Useful if a local variable shadows the global
+/// Shorthand for `json.decode`. Useful if a local variable shadows the global
/// [json] constant.
dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) =>
json.decode(source, reviver: reviver);
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index f914fe1..21d3945 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -83,7 +83,7 @@
* Creates an identity map with the default implementation, [LinkedHashMap].
*
* An identity map uses [identical] for equality and [identityHashCode]
- * for hash codes of keys instead of the intrinsic [Object.operator==] and
+ * for hash codes of keys instead of the intrinsic [Object.==] and
* [Object.hashCode] of the keys.
*
* The returned map allows `null` as a key.
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index b3046cc..9bd68ba 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -152,7 +152,7 @@
* character is a line terminator. When true, then the "." character will
* match any single character including line terminators.
*
- * This feature is distinct from [isMultiline], as they affect the behavior
+ * This feature is distinct from [isMultiLine], as they affect the behavior
* of different pattern characters, and so they can be used together or
* separately.
*/
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 303ec9e..a8ce5d6 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -25457,15 +25457,7 @@
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
factory RtcIceCandidate(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS(
- '',
- 'window[#]',
- Device.isFirefox
- ? '${Device.propertyPrefix}RTCIceCandidate'
- : 'RTCIceCandidate');
+ var constructorName = JS('', 'window[#]', 'RTCIceCandidate');
return JS('RtcIceCandidate', 'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
}
@@ -25511,8 +25503,8 @@
@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
- var constructorName = JS('RtcPeerConnection', 'window[#]',
- '${Device.propertyPrefix}RTCPeerConnection');
+ var constructorName =
+ JS('RtcPeerConnection', 'window[#]', 'RTCPeerConnection');
if (mediaConstraints != null) {
return JS(
'RtcPeerConnection',
@@ -25847,15 +25839,7 @@
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
factory RtcSessionDescription(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS(
- '',
- 'window[#]',
- Device.isFirefox
- ? '${Device.propertyPrefix}RTCSessionDescription'
- : 'RTCSessionDescription');
+ var constructorName = JS('', 'window[#]', 'RTCSessionDescription');
return JS('RtcSessionDescription', 'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
}
@@ -34974,7 +34958,7 @@
// always dealing with pixels in this method.
var styles = _element.getComputedStyle();
- var val = 0;
+ num val = 0;
for (String measurement in dimensions) {
// The border-box and default box model both exclude margin in the regular
diff --git a/sdk/lib/html/html_sources.gni b/sdk/lib/html/html_sources.gni
new file mode 100644
index 0000000..524b6dd
--- /dev/null
+++ b/sdk/lib/html/html_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+html_sdk_sources = [ "dart2js/html_dart2js.dart" ]
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index df60490..d51c616 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -406,16 +406,16 @@
IPPROTO_UDP, // 6
}
-/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption] and
-/// [RawSocket.setRawOption] to set customize the behaviour of the underlying
-/// socket.
+/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption],
+/// [RawSocket.setRawOption], and [RawDatagramSocket.setRawOption] to customize
+/// the behaviour of the underlying socket.
///
-/// It allows for fine grained control of the socket options, and its values will
-/// be passed to the underlying platform's implementation of setsockopt and
-/// getsockopt.
+/// It allows for fine grained control of the socket options, and its values
+/// will be passed to the underlying platform's implementation of `setsockopt`
+/// and `getsockopt`.
@Since("2.2")
class RawSocketOption {
- /// Creates a RawSocketOption for getRawOption andSetRawOption.
+ /// Creates a [RawSocketOption] for `getRawOption` and `setRawOption`.
///
/// All arguments are required and must not be null.
///
@@ -425,10 +425,10 @@
/// The value argument and its length correspond to the optval and length
/// arguments on the native call.
///
- /// For a [getRawOption] call, the value parameter will be updated after a
+ /// For a `getRawOption` call, the value parameter will be updated after a
/// successful call (although its length will not be changed).
///
- /// For a [setRawOption] call, the value parameter will be used set the
+ /// For a `setRawOption` call, the value parameter will be used set the
/// option.
const RawSocketOption(this.level, this.option, this.value);
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 4086f08..cc8c7df 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -39,7 +39,7 @@
* Blocks until a full line is available.
*
* Lines my be terminated by either `<CR><LF>` or `<LF>`. On Windows in cases
- * where the [stdioType] of stdin is [StdioType.termimal] the terminator may
+ * where the [stdioType] of stdin is [StdioType.terminal] the terminator may
* also be a single `<CR>`.
*
* Input bytes are converted to a string by [encoding].
diff --git a/sdk/lib/js/dart2js/js_dart2js.dart b/sdk/lib/js/dart2js/js_dart2js.dart
index 23656d7..9c37ea8 100644
--- a/sdk/lib/js/dart2js/js_dart2js.dart
+++ b/sdk/lib/js/dart2js/js_dart2js.dart
@@ -56,7 +56,7 @@
/// Functions and closures are proxied in such a way that they are callable. A
/// Dart closure assigned to a JavaScript property is proxied by a function in
/// JavaScript. A JavaScript function accessed from Dart is proxied by a
-/// [JsFunction], which has a [apply] method to invoke it.
+/// [JsFunction], which has a [JsFunction.apply] method to invoke it.
///
/// The following types are transferred directly and not proxied:
///
diff --git a/sdk/lib/js/js_sources.gni b/sdk/lib/js/js_sources.gni
new file mode 100644
index 0000000..91f6d0c
--- /dev/null
+++ b/sdk/lib/js/js_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+js_sdk_sources = [ "dart2js/js_dart2js.dart" ]
diff --git a/sdk/lib/js_util/js_util_sources.gni b/sdk/lib/js_util/js_util_sources.gni
new file mode 100644
index 0000000..3b7c1b1
--- /dev/null
+++ b/sdk/lib/js_util/js_util_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+js_util_sdk_sources = [ "dart2js/js_util_dart2js.dart" ]
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index 80e588b..e2e9d91 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -9,7 +9,7 @@
/// The default implementation supplies a stream of pseudo-random bits that are
/// not suitable for cryptographic purposes.
///
-/// Use the [Random.secure]() constructor for cryptographic purposes.
+/// Use the [Random.secure] constructor for cryptographic purposes.
abstract class Random {
/// Creates a random number generator.
///
diff --git a/sdk/lib/wasm/wasm.dart b/sdk/lib/wasm/wasm.dart
index a9a09cc..9fe5ba1 100644
--- a/sdk/lib/wasm/wasm.dart
+++ b/sdk/lib/wasm/wasm.dart
@@ -30,6 +30,9 @@
// Instantiate the module with the given imports.
WasmInstance instantiate(WasmImports imports);
+
+ // Describes the imports and exports that the module expects, for debugging.
+ String describe();
}
// WasmImports holds all the imports for a WasmInstance.
diff --git a/sdk_nnbd/BUILD.gn b/sdk_nnbd/BUILD.gn
index 9a4a1c5..6d96000 100644
--- a/sdk_nnbd/BUILD.gn
+++ b/sdk_nnbd/BUILD.gn
@@ -9,8 +9,8 @@
#
# Warning:
# If you need to copy something into dart-sdk/lib/foo in addition to the stuff
-# copied there by :copy_libraries, then you must depend on ":copy_libraries",
-# or ":copy_libraries" may delete/overwrite your addition, and the build will
+# copied there by :copy_libraries_nnbd, then you must depend on ":copy_libraries_nnbd",
+# or ":copy_libraries_nnbd" may delete/overwrite your addition, and the build will
# fail.
import("../build/dart/copy_tree.gni")
@@ -18,12 +18,15 @@
declare_args() {
# Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries.
- dart_platform_sdk = true
+ dart_platform_sdk_nnbd = true
# Path to stripped dart binaries relative to build output directory.
- dart_stripped_binary = "dart"
- dartaotruntime_stripped_binary = "dartaotruntime"
- gen_snapshot_stripped_binary = "gen_snapshot"
+ # TODO(rnystrom): These should use different filenames once the runtime's
+ # BUILD.gn file has additional rules to generate the NNBD versions of these
+ # executables.
+ dart_stripped_binary_nnbd = "dart"
+ dartaotruntime_stripped_binary_nnbd = "dartaotruntime"
+ gen_snapshot_stripped_binary_nnbd = "gen_snapshot"
}
# The directory layout of the SDK is as follows:
@@ -252,10 +255,10 @@
# bin/resources/dartdoc/templates
copy_tree_specs += [
{
- target = "copy_dartdoc_templates"
- visibility = [ ":copy_dartdoc_files" ]
+ target = "copy_dartdoc_templates_nnbd"
+ visibility = [ ":copy_dartdoc_files_nnbd" ]
source = "../third_party/pkg/dartdoc/lib/templates"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/templates"
+ dest = "$root_out_dir/dart-sdk-nnbd/bin/resources/dartdoc/templates"
ignore_patterns = "{}"
},
]
@@ -264,10 +267,10 @@
# bin/resources/dartdoc/resources
copy_tree_specs += [
{
- target = "copy_dartdoc_resources"
- visibility = [ ":copy_dartdoc_files" ]
+ target = "copy_dartdoc_resources_nnbd"
+ visibility = [ ":copy_dartdoc_files_nnbd" ]
source = "../third_party/pkg/dartdoc/lib/resources"
- dest = "$root_out_dir/dart-sdk/bin/resources/dartdoc/resources"
+ dest = "$root_out_dir/dart-sdk-nnbd/bin/resources/dartdoc/resources"
ignore_patterns = "{}"
},
]
@@ -276,13 +279,13 @@
foreach(library, _full_sdk_libraries) {
copy_tree_specs += [
{
- target = "copy_${library}_library"
+ target = "copy_${library}_library_nnbd"
visibility = [
- ":copy_platform_sdk_libraries",
- ":copy_full_sdk_libraries",
+ ":copy_platform_sdk_libraries_nnbd",
+ ":copy_full_sdk_libraries_nnbd",
]
source = "lib/$library"
- dest = "$root_out_dir/dart-sdk/lib/$library"
+ dest = "$root_out_dir/dart-sdk-nnbd/lib/$library"
ignore_patterns = "*.svn,doc,*.py,*.gypi,*.sh,.gitignore"
},
]
@@ -291,13 +294,13 @@
if (is_win) {
copy_tree_specs += [
{
- target = "copy_7zip"
- visibility = [ ":create_common_sdk" ]
+ target = "copy_7zip_nnbd"
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
]
source = "../third_party/7zip"
- dest = "$root_out_dir/dart-sdk/lib/_internal/pub/asset/7zip"
+ dest = "$root_out_dir/dart-sdk-nnbd/lib/_internal/pub/asset/7zip"
ignore_patterns = ".svn"
},
]
@@ -306,23 +309,23 @@
if (target_cpu == "x64") {
copy_tree_specs += [
{
- target = "copy_language_model"
- visibility = [ ":create_common_sdk" ]
+ target = "copy_language_model_nnbd"
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
]
source = "../pkg/analysis_server/language_model"
- dest = "$root_out_dir/dart-sdk/model"
+ dest = "$root_out_dir/dart-sdk-nnbd/model"
ignore_patterns = "{}"
},
{
- target = "copy_libtensorflowlite_c"
- visibility = [ ":create_common_sdk" ]
+ target = "copy_libtensorflowlite_c_nnbd"
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
]
source = "../third_party/pkg/tflite_native/lib/src/blobs"
- dest = "$root_out_dir/dart-sdk/bin/snapshots"
+ dest = "$root_out_dir/dart-sdk-nnbd/bin/snapshots"
ignore_patterns = "{}"
},
]
@@ -330,7 +333,7 @@
# This generates targets for everything in copy_tree_specs. The targets have the
# same name as the "target" fields in the scopes of copy_tree_specs.
-copy_trees("copy_trees") {
+copy_trees("copy_trees_nnbd") {
sources = copy_tree_specs
}
@@ -348,18 +351,19 @@
# make a link to the symlink rather than the symlink's target, and the
# relative symlink interpreted from a different containing directory
# will not find the actual binary.
- action("copy_dart") {
- visibility = [ ":create_common_sdk" ]
+ action("copy_dart_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
dart_label = "../runtime/bin:dart"
deps = [
dart_label,
]
dart_out = get_label_info(dart_label, "root_out_dir")
sources = [
- "$dart_out/$dart_stripped_binary",
+ "$dart_out/$dart_stripped_binary_nnbd",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/$dart_stripped_binary",
+ "$root_out_dir/dart-sdk-nnbd/bin/$dart_stripped_binary_nnbd",
]
script = "/bin/ln"
args = [
@@ -369,31 +373,33 @@
]
}
} else {
- copy("copy_dart") {
- visibility = [ ":create_common_sdk" ]
+ copy("copy_dart_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"../runtime/bin:dart",
]
dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
if (is_win) {
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$dart_out/dart.exe",
]
} else {
sources = [
- "$dart_out/$dart_stripped_binary",
+ "$dart_out/$dart_stripped_binary_nnbd",
]
}
if (is_win) {
sources += [ "$dart_out/dart.lib" ]
}
outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/{{source_file_part}}",
]
}
}
-copy("copy_dartaotruntime") {
+copy("copy_dartaotruntime_nnbd") {
deps = [
"../runtime/bin:dartaotruntime",
]
@@ -405,38 +411,40 @@
]
} else {
sources = [
- "$dartaotruntime_out/$dartaotruntime_stripped_binary",
+ "$dartaotruntime_out/$dartaotruntime_stripped_binary_nnbd",
]
}
if (is_win) {
sources += [ "$dartaotruntime_out/dartaotruntime.lib" ]
}
outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/{{source_file_part}}",
]
}
-copy("copy_gen_snapshot") {
+copy("copy_gen_snapshot_nnbd") {
deps = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"../runtime/bin:gen_snapshot",
]
gen_snapshot_out =
get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
if (is_win) {
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_snapshot_out/gen_snapshot.exe",
]
} else {
sources = [
- "$gen_snapshot_out/$gen_snapshot_stripped_binary",
+ "$gen_snapshot_out/$gen_snapshot_stripped_binary_nnbd",
]
}
outputs = [
- "$root_out_dir/dart-sdk/bin/utils/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/utils/{{source_file_part}}",
]
}
-copy("copy_dart2aot") {
+copy("copy_dart2aot_nnbd") {
ext = ""
if (is_win) {
ext = ".bat"
@@ -445,14 +453,14 @@
"bin/dart2aot$ext",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/{{source_file_part}}",
]
}
-copy("copy_dart2native") {
+copy("copy_dart2native_nnbd") {
deps = [
- ":copy_gen_kernel_snapshot",
- ":copy_gen_snapshot",
+ ":copy_gen_kernel_snapshot_nnbd",
+ ":copy_gen_snapshot_nnbd",
]
ext = ""
if (is_win) {
@@ -462,26 +470,27 @@
"bin/dart2native$ext",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/{{source_file_part}}",
]
}
-copy("copy_gen_kernel_snapshot") {
+copy("copy_gen_kernel_snapshot_nnbd") {
deps = [
"../utils/gen_kernel",
]
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$root_gen_dir/gen_kernel.dart.snapshot",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/snapshots/{{source_file_part}}",
]
}
# A template for copying the things in _platform_sdk_scripts and
# _full_sdk_scripts into bin/
-template("copy_sdk_script") {
- assert(defined(invoker.name), "copy_sdk_script must define 'name'")
+template("copy_sdk_script_nnbd") {
+ assert(defined(invoker.name), "copy_sdk_script_nnbd must define 'name'")
name = invoker.name
ext = ""
if (is_win) {
@@ -489,29 +498,29 @@
}
copy(target_name) {
visibility = [
- ":copy_platform_sdk_scripts",
- ":copy_full_sdk_scripts",
+ ":copy_platform_sdk_scripts_nnbd",
+ ":copy_full_sdk_scripts_nnbd",
]
sources = [
"bin/${name}_sdk$ext",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/$name$ext",
+ "$root_out_dir/dart-sdk-nnbd/bin/$name$ext",
]
}
}
foreach(sdk_script, _full_sdk_scripts) {
- copy_sdk_script("copy_${sdk_script}_script") {
+ copy_sdk_script_nnbd("copy_${sdk_script}_script_nnbd") {
name = sdk_script
}
}
foreach(script, _scripts) {
- copy("copy_${script}_script") {
+ copy("copy_${script}_script_nnbd") {
visibility = [
- ":copy_platform_sdk_scripts",
- ":copy_full_sdk_scripts",
+ ":copy_platform_sdk_scripts_nnbd",
+ ":copy_full_sdk_scripts_nnbd",
]
ext = ""
if (is_win) {
@@ -521,159 +530,164 @@
"bin/$script$ext",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/{{source_file_part}}",
]
}
}
# This is the main target for copying scripts in _platform_sdk_scripts to bin/
-group("copy_platform_sdk_scripts") {
- visibility = [ ":create_platform_sdk" ]
+group("copy_platform_sdk_scripts_nnbd") {
+ visibility = [ ":create_platform_sdk_nnbd" ]
public_deps = []
foreach(sdk_script, _platform_sdk_scripts) {
- public_deps += [ ":copy_${sdk_script}_script" ]
+ public_deps += [ ":copy_${sdk_script}_script_nnbd" ]
}
foreach(script, _scripts) {
- public_deps += [ ":copy_${script}_script" ]
+ public_deps += [ ":copy_${script}_script_nnbd" ]
}
}
# This is the main target for copying scripts in _full_sdk_scripts to bin/
-group("copy_full_sdk_scripts") {
- visibility = [ ":create_full_sdk" ]
+group("copy_full_sdk_scripts_nnbd") {
+ visibility = [ ":create_full_sdk_nnbd" ]
public_deps = []
foreach(sdk_script, _full_sdk_scripts) {
- public_deps += [ ":copy_${sdk_script}_script" ]
+ public_deps += [ ":copy_${sdk_script}_script_nnbd" ]
}
foreach(script, _scripts) {
- public_deps += [ ":copy_${script}_script" ]
+ public_deps += [ ":copy_${script}_script_nnbd" ]
}
}
# This loop generates "copy" targets that put snapshots into bin/snapshots
foreach(snapshot, _full_sdk_snapshots) {
- copy("copy_${snapshot[0]}_snapshot") {
+ copy("copy_${snapshot[0]}_snapshot_nnbd") {
visibility = [
- ":copy_platform_sdk_snapshots",
- ":copy_full_sdk_snapshots",
+ ":copy_platform_sdk_snapshots_nnbd",
+ ":copy_full_sdk_snapshots_nnbd",
]
deps = [
snapshot[1],
]
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$root_gen_dir/${snapshot[0]}.dart.snapshot",
]
outputs = [
- "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/bin/snapshots/{{source_file_part}}",
]
}
}
# This is the main rule for copying snapshots from _platform_sdk_snapshots to
# bin/snapshots
-group("copy_platform_sdk_snapshots") {
- visibility = [ ":create_platform_sdk" ]
+group("copy_platform_sdk_snapshots_nnbd") {
+ visibility = [ ":create_platform_sdk_nnbd" ]
public_deps = []
foreach(snapshot, _platform_sdk_snapshots) {
- public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
+ public_deps += [ ":copy_${snapshot[0]}_snapshot_nnbd" ]
}
}
# This is the main rule for copying snapshots from _full_sdk_snapshots to
# bin/snapshots
-group("copy_full_sdk_snapshots") {
- visibility = [ ":create_full_sdk" ]
+group("copy_full_sdk_snapshots_nnbd") {
+ visibility = [ ":create_full_sdk_nnbd" ]
public_deps = []
foreach(snapshot, _full_sdk_snapshots) {
- public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
+ public_deps += [ ":copy_${snapshot[0]}_snapshot_nnbd" ]
}
}
# This rule writes the .packages file for dartdoc resources.
-write_file("$root_out_dir/dart-sdk/bin/resources/dartdoc/.packages",
+write_file("$root_out_dir/dart-sdk-nnbd/bin/resources/dartdoc/.packages",
"dartdoc:.")
# This is the main rule for copying the files that dartdoc needs.
-group("copy_dartdoc_files") {
- visibility = [ ":create_common_sdk" ]
+group("copy_dartdoc_files_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
public_deps = [
- ":copy_dartdoc_resources",
- ":copy_dartdoc_templates",
+ ":copy_dartdoc_resources_nnbd",
+ ":copy_dartdoc_templates_nnbd",
]
}
# This rule copies analyzer summaries to lib/_internal
-copy("copy_analysis_summaries") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_analysis_summaries_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
"../utils/dartanalyzer:generate_summary_strong",
]
sources = [
"$root_gen_dir/strong.sum",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/{{source_file_part}}",
]
}
# This rule copies dill files to lib/_internal.
-copy("copy_vm_dill_files") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_vm_dill_files_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
"../runtime/vm:kernel_platform_files",
]
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$root_out_dir/vm_platform_strong.dill",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/{{source_file_part}}",
]
}
-copy("copy_abi_dill_files") {
- visibility = [ ":create_sdk_with_abi_versions" ]
+copy("copy_abi_dill_files_nnbd") {
+ visibility = [ ":create_sdk_with_abi_versions_nnbd" ]
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"../tools/abiversions",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/abiversions",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/abiversions",
]
}
-copy("copy_dart2js_dill_files") {
- visibility = [ ":create_full_sdk" ]
+copy("copy_dart2js_dill_files_nnbd") {
+ visibility = [ ":create_full_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
"../utils/compiler:compile_dart2js_platform",
"../utils/compiler:compile_dart2js_server_platform",
]
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$root_out_dir/dart2js_platform.dill",
"$root_out_dir/dart2js_server_platform.dill",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/{{source_file_part}}",
]
}
# This rule copies ddc summaries to lib/_internal
-copy("copy_dev_compiler_summary") {
- visibility = [ ":copy_dev_compiler_sdk" ]
+copy("copy_dev_compiler_summary_nnbd") {
+ visibility = [ ":copy_dev_compiler_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
"../utils/dartdevc:dartdevc_kernel_sdk_outline",
"../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
# TODO(vsm): Remove post CFE.
"$gen_dir/ddc_sdk.sum",
"$gen_dir/kernel/ddc_sdk.dill",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/{{source_file_part}}",
]
}
@@ -681,129 +695,135 @@
# DDC to Kernel (DDK) migration.
# This rule copies DDC's JS SDK and require.js to lib/dev_compiler/amd.
-copy("copy_dev_compiler_js_amd") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_amd_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/js/amd/dart_sdk.js",
"$gen_dir/js/amd/dart_sdk.js.map",
"../third_party/requirejs/require.js",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/amd/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/amd/{{source_file_part}}",
]
}
# This rule copies DDC's JS SDK and run.js to lib/dev_compiler/common.
-copy("copy_dev_compiler_js_common") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_common_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/js/common/dart_sdk.js",
"$gen_dir/js/common/dart_sdk.js.map",
"../pkg/dev_compiler/lib/js/common/run.js",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/common/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/common/{{source_file_part}}",
]
}
# This rule copies DDC's JS SDK to lib/dev_compiler/es6.
-copy("copy_dev_compiler_js_es6") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_es6_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_sdk",
]
gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/js/es6/dart_sdk.js",
"$gen_dir/js/es6/dart_sdk.js.map",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/es6/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/es6/{{source_file_part}}",
]
}
# This rule copies DDK's JS SDK and require.js to lib/dev_compiler/kernel/amd.
-copy("copy_dev_compiler_js_amd_kernel") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_amd_kernel_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
gen_dir =
get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/kernel/amd/dart_sdk.js",
"$gen_dir/kernel/amd/dart_sdk.js.map",
"../third_party/requirejs/require.js",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/amd/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/kernel/amd/{{source_file_part}}",
]
}
# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/common.
-copy("copy_dev_compiler_js_common_kernel") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_common_kernel_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
gen_dir =
get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/kernel/common/dart_sdk.js",
"$gen_dir/kernel/common/dart_sdk.js.map",
"../pkg/dev_compiler/lib/js/common/run.js",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/common/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/kernel/common/{{source_file_part}}",
]
}
# This rule copies DDK's JS SDK to lib/dev_compiler/kernel/es6.
-copy("copy_dev_compiler_js_es6_kernel") {
- visibility = [ ":copy_dev_compiler_js" ]
+copy("copy_dev_compiler_js_es6_kernel_nnbd") {
+ visibility = [ ":copy_dev_compiler_js_nnbd" ]
deps = [
"../utils/dartdevc:dartdevc_kernel_sdk",
]
gen_dir =
get_label_info("../utils/dartdevc:dartdevc_kernel_sdk", "target_gen_dir")
sources = [
+ # TODO(rnystrom): This probably needs to be forked for NNBD.
"$gen_dir/kernel/es6/dart_sdk.js",
"$gen_dir/kernel/es6/dart_sdk.js.map",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/kernel/es6/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/kernel/es6/{{source_file_part}}",
]
}
# Copies all of the JS artifacts needed by DDC.
-group("copy_dev_compiler_js") {
+group("copy_dev_compiler_js_nnbd") {
visibility = [
- ":copy_dev_compiler_sdk",
- ":copy_dev_compiler_tools",
+ ":copy_dev_compiler_sdk_nnbd",
+ ":copy_dev_compiler_tools_nnbd",
]
public_deps = [
- ":copy_dev_compiler_js_amd",
- ":copy_dev_compiler_js_amd_kernel",
- ":copy_dev_compiler_js_common",
- ":copy_dev_compiler_js_common_kernel",
- ":copy_dev_compiler_js_es6",
- ":copy_dev_compiler_js_es6_kernel",
+ ":copy_dev_compiler_js_amd_nnbd",
+ ":copy_dev_compiler_js_amd_kernel_nnbd",
+ ":copy_dev_compiler_js_common_nnbd",
+ ":copy_dev_compiler_js_common_kernel_nnbd",
+ ":copy_dev_compiler_js_es6_nnbd",
+ ":copy_dev_compiler_js_es6_kernel_nnbd",
]
}
# This rule copies tools to go along with ddc.
-copy("copy_dev_compiler_tools") {
- visibility = [ ":copy_dev_compiler_sdk" ]
+copy("copy_dev_compiler_tools_nnbd") {
+ visibility = [ ":copy_dev_compiler_sdk_nnbd" ]
deps = [
- ":copy_dev_compiler_js",
+ ":copy_dev_compiler_js_nnbd",
"../utils/dartdevc:dartdevc_web",
"../utils/dartdevc:stack_trace_mapper",
]
@@ -813,91 +833,91 @@
"$dart_out/dev_compiler/build/web/ddc_web_compiler.js",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/dev_compiler/web/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/dev_compiler/web/{{source_file_part}}",
]
}
# This is the main rule for copying ddc's dependencies to lib/
-group("copy_dev_compiler_sdk") {
- visibility = [ ":create_full_sdk" ]
+group("copy_dev_compiler_sdk_nnbd") {
+ visibility = [ ":create_full_sdk_nnbd" ]
public_deps = [
- ":copy_dev_compiler_js",
- ":copy_dev_compiler_summary",
- ":copy_dev_compiler_tools",
+ ":copy_dev_compiler_js_nnbd",
+ ":copy_dev_compiler_summary_nnbd",
+ ":copy_dev_compiler_tools_nnbd",
]
}
# This rule copies header files to include/
-copy("copy_headers") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_headers_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
sources = [
"../runtime/include/dart_api.h",
"../runtime/include/dart_native_api.h",
"../runtime/include/dart_tools_api.h",
]
outputs = [
- "$root_out_dir/dart-sdk/include/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/include/{{source_file_part}}",
]
}
# This rule copies libraries.json files to lib/
-copy("copy_libraries_specification") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_libraries_specification_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
sources = [
"lib/libraries.json",
]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/{{source_file_part}}",
]
}
# This is the main rule to copy libraries in _platform_sdk_libraries to lib/
-group("copy_platform_sdk_libraries") {
+group("copy_platform_sdk_libraries_nnbd") {
visibility = [
- ":create_platform_sdk",
- ":copy_libraries",
+ ":create_platform_sdk_nnbd",
+ ":copy_libraries_nnbd",
]
public_deps = []
foreach(library, _platform_sdk_libraries) {
- public_deps += [ ":copy_${library}_library" ]
+ public_deps += [ ":copy_${library}_library_nnbd" ]
}
}
# This is the main rule to copy libraries in _full_sdk_libraries to lib/
-group("copy_full_sdk_libraries") {
+group("copy_full_sdk_libraries_nnbd") {
visibility = [
- ":create_full_sdk",
- ":copy_libraries",
+ ":create_full_sdk_nnbd",
+ ":copy_libraries_nnbd",
]
public_deps = []
foreach(library, _full_sdk_libraries) {
- public_deps += [ ":copy_${library}_library" ]
+ public_deps += [ ":copy_${library}_library_nnbd" ]
}
}
-group("copy_libraries") {
- if (dart_platform_sdk) {
+group("copy_libraries_nnbd") {
+ if (dart_platform_sdk_nnbd) {
public_deps = [
- ":copy_platform_sdk_libraries",
+ ":copy_platform_sdk_libraries_nnbd",
]
} else {
public_deps = [
- ":copy_full_sdk_libraries",
+ ":copy_full_sdk_libraries_nnbd",
]
}
}
# This rule writes the version file.
-action("write_version_file") {
- visibility = [ ":create_common_sdk" ]
+action("write_version_file_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
inputs = [
"../tools/VERSION",
"../.git/logs/HEAD",
]
- output = "$root_out_dir/dart-sdk/version"
+ output = "$root_out_dir/dart-sdk-nnbd/version"
outputs = [
output,
]
@@ -909,12 +929,12 @@
}
# This rule writes the revision file.
-action("write_revision_file") {
- visibility = [ ":create_common_sdk" ]
+action("write_revision_file_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
inputs = [
"../.git/logs/HEAD",
]
- output = "$root_out_dir/dart-sdk/revision"
+ output = "$root_out_dir/dart-sdk-nnbd/revision"
outputs = [
output,
]
@@ -932,48 +952,48 @@
# of the analyzer package do not support the new location of this file. We
# should be able to remove the old file once we release a newer version of
# analyzer and popular frameworks have migrated to use it.
-copy("copy_libraries_dart") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_libraries_dart_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
deps = [
- ":copy_libraries",
+ ":copy_libraries_nnbd",
]
sources = [
"lib/_internal/sdk_library_metadata/lib/libraries.dart",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
+ "$root_out_dir/dart-sdk-nnbd/lib/_internal/{{source_file_part}}",
]
}
# This rule copies the README file.
-copy("copy_readme") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_readme_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
sources = [
"../README.dart-sdk",
]
outputs = [
- "$root_out_dir/dart-sdk/README",
+ "$root_out_dir/dart-sdk-nnbd/README",
]
}
# This rule copies the LICENSE file.
-copy("copy_license") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_license_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
sources = [
"../LICENSE",
]
outputs = [
- "$root_out_dir/dart-sdk/LICENSE",
+ "$root_out_dir/dart-sdk-nnbd/LICENSE",
]
}
# This rule generates a custom dartdoc_options.yaml file.
-action("write_dartdoc_options") {
- visibility = [ ":create_common_sdk" ]
+action("write_dartdoc_options_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
inputs = [
"../.git/logs/HEAD",
]
- output = "$root_out_dir/dart-sdk/dartdoc_options.yaml"
+ output = "$root_out_dir/dart-sdk-nnbd/dartdoc_options.yaml"
outputs = [
output,
]
@@ -985,85 +1005,85 @@
}
# This rule copies the API readme file to lib/
-copy("copy_api_readme") {
- visibility = [ ":create_common_sdk" ]
+copy("copy_api_readme_nnbd") {
+ visibility = [ ":create_common_sdk_nnbd" ]
sources = [
"api_readme.md",
]
outputs = [
- "$root_out_dir/dart-sdk/lib/api_readme.md",
+ "$root_out_dir/dart-sdk-nnbd/lib/api_readme.md",
]
}
# Parts common to both platform and full SDKs.
-group("create_common_sdk") {
- visibility = [ ":create_sdk" ]
+group("create_common_sdk_nnbd") {
+ visibility = [ ":create_sdk_nnbd" ]
public_deps = [
- ":copy_analysis_summaries",
- ":copy_api_readme",
- ":copy_dart",
- ":copy_dart2native",
- ":copy_dartdoc_files",
- ":copy_headers",
- ":copy_libraries_dart",
- ":copy_libraries_specification",
- ":copy_license",
- ":copy_readme",
- ":copy_vm_dill_files",
- ":write_dartdoc_options",
- ":write_revision_file",
- ":write_version_file",
+ ":copy_analysis_summaries_nnbd",
+ ":copy_api_readme_nnbd",
+ ":copy_dart_nnbd",
+ ":copy_dart2native_nnbd",
+ ":copy_dartdoc_files_nnbd",
+ ":copy_headers_nnbd",
+ ":copy_libraries_dart_nnbd",
+ ":copy_libraries_specification_nnbd",
+ ":copy_license_nnbd",
+ ":copy_readme_nnbd",
+ ":copy_vm_dill_files_nnbd",
+ ":write_dartdoc_options_nnbd",
+ ":write_revision_file_nnbd",
+ ":write_version_file_nnbd",
]
if (is_win) {
- public_deps += [ ":copy_7zip" ]
+ public_deps += [ ":copy_7zip_nnbd" ]
}
if (target_cpu == "x64") {
public_deps += [
- ":copy_language_model",
- ":copy_libtensorflowlite_c",
+ ":copy_language_model_nnbd",
+ ":copy_libtensorflowlite_c_nnbd",
]
}
}
# Parts specific to the platform SDK.
-group("create_platform_sdk") {
- visibility = [ ":create_sdk" ]
+group("create_platform_sdk_nnbd") {
+ visibility = [ ":create_sdk_nnbd" ]
public_deps = [
- ":copy_platform_sdk_libraries",
- ":copy_platform_sdk_scripts",
- ":copy_platform_sdk_snapshots",
+ ":copy_platform_sdk_libraries_nnbd",
+ ":copy_platform_sdk_scripts_nnbd",
+ ":copy_platform_sdk_snapshots_nnbd",
]
}
# Parts specific to the full SDK.
-group("create_full_sdk") {
- visibility = [ ":create_sdk" ]
+group("create_full_sdk_nnbd") {
+ visibility = [ ":create_sdk_nnbd" ]
public_deps = [
- ":copy_dart2js_dill_files",
- ":copy_dev_compiler_sdk",
- ":copy_full_sdk_libraries",
- ":copy_full_sdk_scripts",
- ":copy_full_sdk_snapshots",
+ ":copy_dart2js_dill_files_nnbd",
+ ":copy_dev_compiler_sdk_nnbd",
+ ":copy_full_sdk_libraries_nnbd",
+ ":copy_full_sdk_scripts_nnbd",
+ ":copy_full_sdk_snapshots_nnbd",
]
}
# The main target to depend on from ../BUILD.gn
-group("create_sdk") {
+group("create_sdk_nnbd") {
public_deps = [
- ":create_common_sdk",
+ ":create_common_sdk_nnbd",
]
- if (dart_platform_sdk) {
- public_deps += [ ":create_platform_sdk" ]
+ if (dart_platform_sdk_nnbd) {
+ public_deps += [ ":create_platform_sdk_nnbd" ]
} else {
- public_deps += [ ":create_full_sdk" ]
+ public_deps += [ ":create_full_sdk_nnbd" ]
}
}
# Same as create_sdk, but with abi version files.
-group("create_sdk_with_abi_versions") {
+group("create_sdk_with_abi_versions_nnbd") {
public_deps = [
- ":copy_abi_dill_files",
- ":create_sdk",
+ ":copy_abi_dill_files_nnbd",
+ ":create_sdk_nnbd",
]
-}
+}
\ No newline at end of file
diff --git a/sdk_nnbd/bin/dartdevc_sdk b/sdk_nnbd/bin/dartdevc_sdk
index 60d2fe1..6cba7d8 100755
--- a/sdk_nnbd/bin/dartdevc_sdk
+++ b/sdk_nnbd/bin/dartdevc_sdk
@@ -25,4 +25,14 @@
# We are running the snapshot in the built SDK.
DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$@"
+
+unset EXTRA_VM_OPTIONS
+declare -a EXTRA_VM_OPTIONS
+
+# We allow extra vm options to be passed in through an environment variable.
+if [[ $DART_VM_OPTIONS ]]; then
+ read -a OPTIONS <<< "$DART_VM_OPTIONS"
+ EXTRA_VM_OPTIONS+=("${OPTIONS[@]}")
+fi
+
+exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$SNAPSHOT" "$@"
diff --git a/sdk_nnbd/bin/dartdevc_sdk.bat b/sdk_nnbd/bin/dartdevc_sdk.bat
index 5dbf707..ce027a9 100644
--- a/sdk_nnbd/bin/dartdevc_sdk.bat
+++ b/sdk_nnbd/bin/dartdevc_sdk.bat
@@ -22,7 +22,14 @@
set SDK_ARG=--dart-sdk=%SDK_DIR%
-"%DART%" "%SNAPSHOT%" "%SDK_ARG%" %*
+set EXTRA_VM_OPTIONS=
+
+rem We allow extra vm options to be passed in through an environment variable.
+if not "_%DART_VM_OPTIONS%_" == "__" (
+ set EXTRA_VM_OPTIONS=%EXTRA_VM_OPTIONS% %DART_VM_OPTIONS%
+)
+
+"%DART%" %EXTRA_VM_OPTIONS% "%SNAPSHOT%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
index 42d4c42..b194781 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/lib/js/dart2js/js_dart2js.dart
@@ -525,6 +525,7 @@
///
/// Calling this method repeatedly on a function will return the same result.
F allowInterop<F extends Function>(F f) {
+ if (!dart.isDartFunction(f)) return f;
var ret = _interopExpando[f];
if (ret == null) {
ret = JS(
@@ -549,6 +550,7 @@
///
/// When called from Dart, [null] will be passed as the first argument.
Function allowInteropCaptureThis(Function f) {
+ if (!dart.isDartFunction(f)) return f;
var ret = _interopCaptureThisExpando[f];
if (ret == null) {
ret = JS(
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
index 5dbff7f..7451365 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/ddc_runtime/types.dart
@@ -94,6 +94,10 @@
return f;
}
+bool isDartFunction(obj) =>
+ JS<bool>('!', '# instanceof Function', obj) &&
+ JS<bool>('!', '#[#] != null', obj, _runtimeType);
+
/// The Dart type that represents a JavaScript class(/constructor) type.
///
/// The JavaScript type may not exist, either because it's not loaded yet, or
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
index 5ad56dc..67f1d0b 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/rti.dart
@@ -365,6 +365,11 @@
@pragma('dart2js:noInline')
Rti instantiatedGenericFunctionType(
Rti genericFunctionRti, Rti instantiationRti) {
+ // If --lax-runtime-type-to-string is enabled and we never check the function
+ // type, then the function won't have a signature, so its RTI will be null. In
+ // this case, there is nothing to instantiate, so we return `null` and the
+ // instantiation appears to be an interface type instead.
+ if (genericFunctionRti == null) return null;
var bounds = Rti._getGenericFunctionBounds(genericFunctionRti);
var typeArguments = Rti._getInterfaceTypeArguments(instantiationRti);
assert(_Utils.arrayLength(bounds) == _Utils.arrayLength(typeArguments));
diff --git a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
index fc33afa..8339229 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/wasm_patch.dart
@@ -62,6 +62,7 @@
}
void _init(Uint8List data) native 'Wasm_initModule';
+ String describe() native 'Wasm_describeModule';
}
class _NativeWasmImports extends NativeFieldWrapperClass1
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index b5afe53..64aa8ab 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -25459,15 +25459,7 @@
@Native("RTCIceCandidate,mozRTCIceCandidate")
class RtcIceCandidate extends Interceptor {
factory RtcIceCandidate(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS(
- '',
- 'window[#]',
- Device.isFirefox
- ? '${Device.propertyPrefix}RTCIceCandidate'
- : 'RTCIceCandidate');
+ var constructorName = JS('', 'window[#]', 'RTCIceCandidate');
return JS('RtcIceCandidate', 'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
}
@@ -25513,8 +25505,8 @@
@Native("RTCPeerConnection,webkitRTCPeerConnection,mozRTCPeerConnection")
class RtcPeerConnection extends EventTarget {
factory RtcPeerConnection(Map rtcIceServers, [Map mediaConstraints]) {
- var constructorName = JS('RtcPeerConnection', 'window[#]',
- '${Device.propertyPrefix}RTCPeerConnection');
+ var constructorName =
+ JS('RtcPeerConnection', 'window[#]', 'RTCPeerConnection');
if (mediaConstraints != null) {
return JS(
'RtcPeerConnection',
@@ -25849,15 +25841,7 @@
@Native("RTCSessionDescription,mozRTCSessionDescription")
class RtcSessionDescription extends Interceptor {
factory RtcSessionDescription(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS(
- '',
- 'window[#]',
- Device.isFirefox
- ? '${Device.propertyPrefix}RTCSessionDescription'
- : 'RTCSessionDescription');
+ var constructorName = JS('', 'window[#]', 'RTCSessionDescription');
return JS('RtcSessionDescription', 'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
}
@@ -34976,7 +34960,7 @@
// always dealing with pixels in this method.
var styles = _element.getComputedStyle();
- var val = 0;
+ num val = 0;
for (String measurement in dimensions) {
// The border-box and default box model both exclude margin in the regular
diff --git a/sdk_nnbd/lib/html/html_common/conversions.dart b/sdk_nnbd/lib/html/html_common/conversions.dart
index ca118a9..64c7cb8 100644
--- a/sdk_nnbd/lib/html/html_common/conversions.dart
+++ b/sdk_nnbd/lib/html/html_common/conversions.dart
@@ -78,6 +78,9 @@
cleanupSlots() {} // Will be needed if we mark objects with a property.
bool cloneNotRequired(object);
+ JSObject newJsObject();
+ void forEachObjectKey(object, action(key, value));
+ void putIntoObject(object, key, value);
newJsMap();
List newJsList(length);
void putIntoMap(map, key, value);
@@ -136,6 +139,19 @@
return copy;
}
+ if (e is JSObject) {
+ var slot = findSlot(e);
+ var copy = readSlot(slot);
+ if (copy != null) return copy;
+ copy = newJsObject();
+ writeSlot(slot, copy);
+ // TODO: Consider inlining this so we don't allocate a closure.
+ forEachObjectKey(e, (key, value) {
+ putIntoObject(copy, key, walk(value));
+ });
+ return copy;
+ }
+
throw new UnimplementedError('structured clone of other type');
}
diff --git a/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
index 08ce947..c973a55 100644
--- a/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk_nnbd/lib/html/html_common/conversions_dart2js.dart
@@ -55,6 +55,18 @@
.convertNativeToDart_AcceptStructuredClone(object, mustCopy: mustCopy);
class _StructuredCloneDart2Js extends _StructuredClone {
+ JSObject newJsObject() => JS('JSObject', '{}');
+
+ void forEachObjectKey(object, action(key, value)) {
+ for (final key
+ in JS('returns:JSExtendableArray;new:true', 'Object.keys(#)', object)) {
+ action(key, JS('var', '#[#]', object, key));
+ }
+ }
+
+ void putIntoObject(object, key, value) =>
+ JS('void', '#[#] = #', object, key, value);
+
newJsMap() => JS('var', '{}');
putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
diff --git a/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart b/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
index 3a91281..710d1f1 100644
--- a/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk_nnbd/lib/html/html_common/html_common_dart2js.dart
@@ -15,7 +15,7 @@
import 'dart:_native_typed_data';
import 'dart:_js_helper' show Creates, Returns, convertDartClosureToJS;
import 'dart:_foreign_helper' show JS;
-import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+import 'dart:_interceptors' show Interceptor, JSExtendableArray, JSObject;
import 'dart:_metadata';
export 'dart:_metadata';
diff --git a/sdk_nnbd/lib/html/html_sources.gni b/sdk_nnbd/lib/html/html_sources.gni
new file mode 100644
index 0000000..524b6dd
--- /dev/null
+++ b/sdk_nnbd/lib/html/html_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+html_sdk_sources = [ "dart2js/html_dart2js.dart" ]
diff --git a/sdk_nnbd/lib/js/js_sources.gni b/sdk_nnbd/lib/js/js_sources.gni
new file mode 100644
index 0000000..91f6d0c
--- /dev/null
+++ b/sdk_nnbd/lib/js/js_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+js_sdk_sources = [ "dart2js/js_dart2js.dart" ]
diff --git a/sdk_nnbd/lib/js_util/js_util_sources.gni b/sdk_nnbd/lib/js_util/js_util_sources.gni
new file mode 100644
index 0000000..3b7c1b1
--- /dev/null
+++ b/sdk_nnbd/lib/js_util/js_util_sources.gni
@@ -0,0 +1,5 @@
+# Copyright (c) 2019, 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.
+
+js_util_sdk_sources = [ "dart2js/js_util_dart2js.dart" ]
diff --git a/sdk_nnbd/lib/wasm/wasm.dart b/sdk_nnbd/lib/wasm/wasm.dart
index 631dc22..3830d56 100644
--- a/sdk_nnbd/lib/wasm/wasm.dart
+++ b/sdk_nnbd/lib/wasm/wasm.dart
@@ -32,6 +32,9 @@
// Instantiate the module with the given imports.
WasmInstance instantiate(WasmImports imports);
+
+ // Describes the imports and exports that the module expects, for debugging.
+ String describe();
}
// WasmImports holds all the imports for a WasmInstance.
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 9afaf8b..28c1f67 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -6,17 +6,10 @@
analyses/api_dynamic_test: Slow
analyses/dart2js_dynamic_test: Slow
closure/closure_test: Slow
-codegen/gvn_dynamic_field_get_test: Fail # Issue 18519
-codegen/list_tracer_length_test: Fail # Issue 33051
codegen/load_elimination_test: Slow
-codegen/logical_expression_test: Fail # Issue 17027
codegen/model_test: Slow
-codegen/side_effect_tdiv_regression_test: Fail # Issue 33050
-codegen/simple_function_subtype_test: Fail # simple_function_subtype_test is temporarily(?) disabled due to new method for building function type tests.
deferred_loading/deferred_loading_test: Slow
end_to_end/dump_info_test: Slow
-end_to_end/generate_code_with_compile_time_errors_test: RuntimeError # not supported yet with the new FE.
-end_to_end/show_package_warnings_test: RuntimeError # missing errors from the FE
equivalence/id_equivalence1_test: Slow
equivalence/id_equivalence2_test: Slow
impact/impact_test: Slow
@@ -24,10 +17,7 @@
inference/inference1_test: Slow
inference/inference2_test: Slow
inference/inference3_test: Slow
-inference/simple_inferrer_const_closure2_test: Fail # Issue 16507
-inference/simple_inferrer_const_closure_test: Fail # Issue 16507
-inference/simple_inferrer_global_field_closure_test: Fail # Issue 16507
-inference/swarm_test: Slow, Pass, Fail #
+inference/swarm_test: Slow #
inlining/inlining_test: Slow
model/native_test: Slow
model/no_such_method_enabled_test: Slow
@@ -38,8 +28,6 @@
rti/rti_need0_test: Slow
rti/rti_need1_test: Slow
serialization/serialization_test: Slow
-sourcemaps/d2js_validity_test: RuntimeError # Issue 33072
-sourcemaps/deferred_d2js_validity_test: RuntimeError # Issue 33072
sourcemaps/source_mapping_invokes_test: Slow
sourcemaps/source_mapping_operators_test: Slow
sourcemaps/source_mapping_test: Slow
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace/extension_method.dart b/tests/compiler/dart2js/sourcemaps/stacktrace/extension_method.dart
new file mode 100644
index 0000000..fb4e466
--- /dev/null
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace/extension_method.dart
@@ -0,0 +1,72 @@
+class MyClass {
+ MyClass();
+
+ @pragma('dart2js:noInline')
+ set internalSetter(int v) {
+ /*7:MyClass.internalSetter*/ throw "error";
+ }
+}
+
+int q = 3;
+
+extension Ext on MyClass {
+ @pragma('dart2js:noInline')
+ int method() {
+ this./*6:Ext.method*/ internalSetter = 1;
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 29) return 3;
+ return 2;
+ }
+
+ @pragma('dart2js:noInline')
+ int get propertyB {
+ /*5:Ext.propertyB*/ method();
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 29) return 3;
+ return 2;
+ }
+
+ @pragma('dart2js:noInline')
+ set propertyA(int v) {
+ /*4:Ext.propertyA*/ propertyB;
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 29) return null;
+ return null;
+ }
+
+ @pragma('dart2js:noInline')
+ int operator+(int v) {
+ this./*3:Ext.+*/ propertyA = 2;
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 30) return 1;
+ return 3;
+ }
+
+ @pragma('dart2js:noInline')
+ int operator[](int v) {
+ this /*2:Ext.[]*/ + 2;
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 30) return 1;
+ return 3;
+ }
+}
+
+extension on MyClass {
+ @pragma('dart2js:noInline')
+ int method2() {
+ this/*1:MyClass.<anonymous extension>.method2*/[0];
+ // TODO(sigmund): remove once kernel preserves noInline pragmas. #38439
+ if (q > 29) return 3;
+ return 2;
+ }
+}
+
+@pragma('dart2js:noInline')
+confuse(x) => x;
+
+main() {
+ q++;
+ confuse(null);
+ MyClass x = confuse(new MyClass());
+ x. /*0:main*/method2();
+}
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
index a4a6fa0..6ea1a2a 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace_test.dart
@@ -85,6 +85,7 @@
'--libraries-spec=sdk/lib/libraries.json',
'--packages=${Platform.packageConfig}',
Flags.testMode,
+ '--enable-experiment=extension-methods',
input,
]..addAll(options);
print("Compiling dart2js ${arguments.join(' ')}");
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index efc2aea..29be72f 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -2,107 +2,40 @@
# 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.
-[ $compiler == dart2js ]
-bounds_check4a_test: RuntimeError # Issue 32741
-bounds_check4b_test: RuntimeError # Issue 32741
-generic_class_is_test: Fail # Issue 32004
-jsinterop_test/01: MissingCompileTimeError # Issue 34174
-jsinterop_test/02: MissingCompileTimeError # Issue 34174
-jsinterop_test/03: MissingCompileTimeError # Issue 34174
-jsinterop_test/04: MissingCompileTimeError # Issue 34174
-jsinterop_test/34: MissingCompileTimeError # Issue 33834
-jsinterop_test/35: MissingCompileTimeError # Issue 33834
-jsinterop_test/36: MissingCompileTimeError # Issue 33834
-jsinterop_test/37: MissingCompileTimeError # Issue 33834
-jsinterop_test/38: MissingCompileTimeError # Issue 34174
-jsinterop_test/42: MissingCompileTimeError # Issue 34174
-jsinterop_test/43: MissingCompileTimeError # Issue 34345
-jsinterop_test/44: MissingCompileTimeError # Issue 34345
-jsinterop_test/45: MissingCompileTimeError # Issue 34345
-jsinterop_test/46: MissingCompileTimeError # Issue 34174
-jsinterop_test/51: MissingCompileTimeError # Issue 34174
-jsinterop_test/52: MissingCompileTimeError # Issue 34345
-jsinterop_test/53: MissingCompileTimeError # Issue 34345
-jsinterop_test/54: MissingCompileTimeError # Issue 34345
-many_instantiations_test/01: Crash # Issue 33819
-no_such_method_test: Fail # Wrong Invocation.memberName.
-non_jsinterop_test/01: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/02: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/03: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/04: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/34: MissingCompileTimeError # Issue 33834
-non_jsinterop_test/35: MissingCompileTimeError # Issue 33834
-non_jsinterop_test/36: MissingCompileTimeError # Issue 33834
-non_jsinterop_test/37: MissingCompileTimeError # Issue 33834
-non_jsinterop_test/38: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/42: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/43: MissingCompileTimeError # Issue 34345
-non_jsinterop_test/44: MissingCompileTimeError # Issue 34345
-non_jsinterop_test/45: MissingCompileTimeError # Issue 34345
-non_jsinterop_test/46: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/51: MissingCompileTimeError # Issue 34174
-non_jsinterop_test/52: MissingCompileTimeError # Issue 34345
-non_jsinterop_test/53: MissingCompileTimeError # Issue 34345
-non_jsinterop_test/54: MissingCompileTimeError # Issue 34345
-
[ $compiler != dart2js ]
dummy_compiler_test: SkipByDesign # Issue 30773. Test should be migrated as a unit test of dart2js, is only intended to test self-hosting.
[ $runtime == jsshell ]
deferred/load_in_correct_order_test: SkipByDesign # jsshell preamble does not support this test.
-timer_test: Fail # Issue 7728.
-
-[ $runtime == none ]
-timer_negative_test: Fail, OK # A negative runtime test.
[ $compiler == dart2js && $mode == debug ]
operator_test: Skip
string_interpolation_test: Skip
[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-class_test: Pass, Slow # Issue 25940
-closure_capture3_test: Pass, Slow # Issue 25940
-closure_capture5_test: Pass, Slow # Issue 25940
-conditional_test: Pass, Slow # Issue 25940
-consistent_codeUnitAt_error_test: Pass, Slow # Issue 25940
-constant_javascript_semantics2_test: Pass, Slow # Issue 25940
-deferred_split_test: Pass, Slow # Issue 25940
+class_test: Slow # Issue 25940
+closure_capture3_test: Slow # Issue 25940
+closure_capture5_test: Slow # Issue 25940
+conditional_test: Slow # Issue 25940
+consistent_codeUnitAt_error_test: Slow # Issue 25940
+constant_javascript_semantics2_test: Slow # Issue 25940
+deferred_split_test: Slow # Issue 25940
[ $compiler == dart2js && $runtime == chrome && $csp ]
deferred/load_in_correct_order_test: SkipByDesign # Purposely uses `eval`
-[ $compiler == dart2js && $runtime == d8 ]
-deferred_fail_and_retry_test: RuntimeError # Uses XHR in dart:html
-deferred_with_csp_nonce_test: RuntimeError # Uses dart:html
-
[ $compiler == dart2js && $runtime == ff && $system == windows ]
-consistent_index_error_string_test: Pass, Slow # Issue 25940
-
-[ $compiler == dart2js && $runtime == none ]
-*: Fail, Pass # TODO(ahe): Triage these tests.
+consistent_index_error_string_test: Slow # Issue 25940
[ $compiler == dart2js && $csp ]
deferred_custom_loader_test: SkipByDesign # Issue 25683
deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
-js_interop_optional_arg_test: RuntimeError # Issue 31082
-js_interop_test: RuntimeError # Issue 31082
[ $compiler == dart2js && !$host_checked ]
-dummy_compiler_test: RuntimeError, Slow # Issue 32439. self-hosting doesn't work with CFE yet.
+dummy_compiler_test: Slow # Issue 32439. self-hosting doesn't work with CFE yet.
[ $compiler == dart2js && $minified ]
-closure_capture2_test: Pass # Passes for the wrong reason
code_motion_exception_test: Skip # Requires unminified operator names.
-deferred/reflect_multiple_annotations_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred/reflect_multiple_default_arg_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-mirrors_used_warning_test/minif: Fail, OK # Tests warning that minified code will be broken.
-runtime_type_test: Fail, OK # Tests extected output of Type.toString().
-to_string_test: Fail # Issue 7179.
-type_literal_test: Fail, OK # Tests expected output of Type.toString().
-typevariable_typedef_test: Fail, OK # Tests expected output of Type.toString().
-
-[ $compiler == dart2js && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari) ]
-isolate2_test/01: Fail # Issue 14458.
[ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == safari) ]
code_motion_exception_test: Skip # Required V8 specific format of JavaScript errors.
@@ -111,6 +44,5 @@
dummy_compiler_test: SkipByDesign # Issue 30773. Test should be migrated as a unit test of dart2js, is only intended to test self-hosting.
[ $compiler == none && $runtime == vm ]
-invalid_annotation_test/01: MissingCompileTimeError, OK # vm is lazy
new_from_env_test: SkipByDesign # dart2js only test
unconditional_dartio_import_test: SkipByDesign # dart2js only test
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index ad3e21a..fd86b1b 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -2,18 +2,6 @@
# 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.
-[ $compiler == dart2js ]
-fake_thing_test: RuntimeError # Issue 13010
-field_type2_test: CompileTimeError # Issue 33762
-field_type_test: CompileTimeError # Issue 33762
-native_exceptions1_frog_test: CompileTimeError # Issue 33762
-native_mixin_with_plain_test: CompileTimeError # Issue 33762
-native_window1_frog_test: CompileTimeError # Issue 33762
-native_window2_frog_test: CompileTimeError # Issue 33762
-subclassing_constructor_1_test: CompileTimeError # Issue 33762
-
[ $browser ]
*: Skip
-[ $compiler == dart2js && $minified ]
-optimization_hints_test: RuntimeError, OK # Test relies on unminified names.
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index a6caf81..868f098 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -5,15 +5,6 @@
[ $arch == simdbc || $arch == simdbc64 ]
*: Skip # SIMDBC will be deleted soon.
-# Issue 37295, not yet supported in blobs snapshots at present.
-[ $compiler == dartkp && $system == windows ]
-function_callbacks_test: Skip
-regress_37511_callbacks_test: Skip
-stacktrace_regress_37910_test: Skip
-
-[ $compiler != dartkp || $system != windows ]
-function_callbacks_unsupported_test: SkipByDesign # See above
-
[ $builder_tag == asan ]
data_not_asan_test: SkipByDesign # This test tries to allocate too much memory on purpose.
diff --git a/tests/ffi/function_callbacks_unsupported_test.dart b/tests/ffi/function_callbacks_unsupported_test.dart
deleted file mode 100644
index 5ac1b5d..0000000
--- a/tests/ffi/function_callbacks_unsupported_test.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2019, 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 test program for testing that FFI callbacks report an appropriate
-// runtime error for unsupported snapshot formats.
-
-import 'dart:ffi';
-
-import 'package:expect/expect.dart';
-
-bool checkError(UnsupportedError err) {
- return "$err".contains("callbacks are not yet supported in blobs");
-}
-
-void main() {
- Expect.throws<UnsupportedError>(
- () => Pointer.fromFunction<Void Function()>(main), checkError);
-}
diff --git a/tests/language_2/extension_methods/basic_static_extension_test.dart b/tests/language_2/extension_methods/basic_static_extension_test.dart
index ce4fb5f..39bb377 100644
--- a/tests/language_2/extension_methods/basic_static_extension_test.dart
+++ b/tests/language_2/extension_methods/basic_static_extension_test.dart
@@ -89,7 +89,7 @@
UnnamedGeneric<num> unnamedGenericNull = null;
Expect.equals("unnamed generic(non-null)", unnamedGeneric.name);
- Expect.equals("unnamed generic(null)", unnamedGeneric.name);
+ Expect.equals("unnamed generic(null)", unnamedGenericNull.name);
Expect.type<List<num>>(unnamedGeneric.list);
Expect.notType<List<int>>(unnamedGeneric.list);
Expect.type<List<num>>(unnamedGenericNull.list);
diff --git a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
index c24bc36..664916f 100644
--- a/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
+++ b/tests/language_2/extension_methods/static_extension_getter_setter_conflicts_test.dart
@@ -11,19 +11,21 @@
class C0 {
int get m1 => 0;
void set m2(int x) {}
+ int operator[](int index) => 0;
}
extension E0 on C0 {
void set m1(int x) {}
int get m2 => 0;
+ void operator[]=(int index, int value) {}
}
void test0() {
C0 c0 = C0();
c0.m1;
c0.m1 = 0;
- // ^^^^^^
- // [analyzer] unspecified
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
// [cfe] unspecified
E0(c0).m1 = 0;
E0(c0).m1;
@@ -32,20 +34,59 @@
// [cfe] unspecified
c0.m1 += 0;
- // ^^^^^^
- // [analyzer] unspecified
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
+ // [cfe] unspecified
+
+ c0.m1++;
+ // ^^
+ // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_NO_SETTER
// [cfe] unspecified
c0.m2 = 0;
c0.m2;
// ^^
- // [analyzer] unspecified
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
// [cfe] unspecified
c0.m2 += 0;
- // ^^^^^^^
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] unspecified
+ c0.m2++;
+ // ^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+ // [cfe] unspecified
+
+ E0(c0).m2;
+
+ c0[0];
+ c0[0] = 0;
+ // ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
- E0(c0).m2;
+ E0(c0)[0];
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ E0(c0)[0] = 0;
+
+ c0[0] += 0;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ c0[0]++;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ E0(c0)[0] += 0;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+ E0(c0)[0]++;
+ // ^^^^^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
}
// Conflicting extensions.
@@ -55,11 +96,13 @@
extension E1A<T> on C1<T> {
int get m1 => 0;
void set m2(int x) {}
+ int operator[](int index) => 0;
}
extension E1B on C1<Object> {
void set m1(int x) {}
int get m2 => 0;
+ void operator[]=(int index, int value) {}
}
void test1() {
@@ -78,6 +121,23 @@
c1a.m2 = 0;
+ c1a[0] = 0;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1a[0] += 0;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1a[0]++;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1a[0];
+
C1<Object> c1b = C1<Null>(); // Neither extension is more specific.
c1b.m1;
@@ -90,14 +150,40 @@
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] unspecified
+ c1b.m1 += 0;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] unspecified
+
+ c1b.m1++;
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [cfe] unspecified
+
c1b.m2;
// ^^
// [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] unspecified
- c1b.m2 = 0;
+
+ c1b[0];
// ^^
- // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1b[0] = 0;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1b[0] += 0;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ c1b[0]++;
+ // ^^
+ // [analyzer] unspecified
// [cfe] unspecified
}
@@ -106,12 +192,15 @@
int get m1 => 0;
void set m2(int x) {}
int get mc => 0;
+ void operator[]=(int index, int value) {}
}
extension E2 on C2 {
void set m1(int x) {}
int get m2 => 0;
String get me => "";
+ int operator[](int index) => 0;
+
void test2() {
// Using `this.member` means using the `on` type.
@@ -128,6 +217,22 @@
// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
// [cfe] unspecified
+ this[0] = 0;
+ this[0];
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ this[0] += 0;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
+ this[0] ++;
+ // ^^
+ // [analyzer] unspecified
+ // [cfe] unspecified
+
// Check that `this.mc` refers to `C2.mc`.
this.mc.toRadixString(16);
// Check that `this.me` refers to `E2.me`.
diff --git a/tests/language_2/extension_methods/static_extension_resolution_failures_test.dart b/tests/language_2/extension_methods/static_extension_resolution_failures_test.dart
index 0a70b9b..dc9b18c 100644
--- a/tests/language_2/extension_methods/static_extension_resolution_failures_test.dart
+++ b/tests/language_2/extension_methods/static_extension_resolution_failures_test.dart
@@ -62,8 +62,8 @@
// Both EIT.e1 and ELO.e1 apply, but their instantiated on
// types are incomparable, and hence this is an error.
ln.e1();
- // ^
- // [analyzer] unspecified
+ // ^^
+ // [analyzer] COMPILE_TIME_ERROR.AMBIGUOUS_EXTENSION_MEMBER_ACCESS
// [cfe] The method 'e1' isn't defined for the class 'List<num>'.
}
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index fb8135f..64bc2b8 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -4,75 +4,7 @@
# Sections in this file should contain "$compiler == dart2js".
[ $compiler == dart2js ]
-arithmetic_int64_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-async_star_cancel_while_paused_test: RuntimeError # Issue 22853
-bit_operations_test: RuntimeError, OK # non JS number semantics
-bit_operations_test/03: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-bit_operations_test/04: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-bit_operations_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-call_method_must_not_be_field_test/03: RuntimeError # Issue 32155
-call_method_must_not_be_getter_test/03: RuntimeError # Issue 32155
-canonical_const2_test: RuntimeError, OK # non JS number semantics
-closure_type_arguments_test: Crash # Issue 34272
-const_constructor3_test/04: MissingCompileTimeError # OK - Subtype check uses JS number semantics.
-const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
-const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
-const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
-covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
-deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
-deopt_inlined_function_lazy_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-deopt_smi_op_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
-double_int_to_string_test: RuntimeError, OK # non JS number semantics
-expect_test: RuntimeError, OK # Issue 13080
-full_stacktrace1_test: RuntimeError # Issue 12698
-full_stacktrace2_test: RuntimeError # Issue 12698
-full_stacktrace3_test: RuntimeError # Issue 12698
-guess_cid_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-identical_closure2_test: RuntimeError # non JS number semantics
-identical_closure2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-infinity_test: RuntimeError # non JS number semantics - Issue 4984
-int2_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/01: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/02: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/04: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/05: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/06: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/11: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/12: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/14: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/16: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/17: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/19: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-int64_literal_test/none: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-integer_division_by_zero_test: RuntimeError # Issue 8301
-issue23244_test: RuntimeError # Isolates - enum canonicalization - Issue 23244
-left_shift_test: RuntimeError # non JS number semantics
-library_env_test/has_io_support: RuntimeError, OK # dart2js doesn't support io when compiling on --categories=Client
-library_env_test/has_mirror_support: Fail # mirrors not supported on web
-library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
-mint_arithmetic_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-mint_arithmetic_test: RuntimeError # non JS number semantics
-mint_compares_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-mint_identical_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
mixin_method_override_test/G5: Skip # Issue 34354
-mock_writable_final_field_test: RuntimeError # Issue 30847
-modulo_test: RuntimeError # non JS number semantics
-nan_identical_test: RuntimeError # Issue 11551
-number_identity_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-numbers_test: RuntimeError, OK # non JS number semantics
-partial_instantiation_eager_bounds_check_test: RuntimeError # Issue #34295
-partial_tearoff_instantiation_test/05: Pass # for the wrong reason.
-partial_tearoff_instantiation_test/06: Pass # for the wrong reason.
-partial_tearoff_instantiation_test/07: Pass # for the wrong reason.
-partial_tearoff_instantiation_test/08: Pass # for the wrong reason.
-regress_24283_test: RuntimeError, OK # non JS number semantics
-stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/none: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
-stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
-truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
-type_constants_test/none: RuntimeError # Issue 35052
vm/*: SkipByDesign # Tests for the VM.
[ $compiler != dart2js ]
@@ -81,108 +13,19 @@
[ $builder_tag == dart2js_production && $compiler == dart2js ]
control_flow_collections/for_non_bool_condition_test: Crash # Issue 36442
-[ $compiler == dart2js && $runtime == chrome && $system == macos ]
-await_future_test: Pass, Timeout # Issue 26735
-
[ $compiler == dart2js && $runtime == chromeOnAndroid ]
-override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
+override_field_test/02: Slow # TODO(kasperl): Please triage.
[ $compiler == dart2js && $runtime == d8 ]
conditional_import_string_test: SkipByDesign # No XHR in d8
conditional_import_test: SkipByDesign # No XHR in d8
-[ $compiler == dart2js && $runtime == ff ]
-round_test: Pass, Fail, OK # Fixed in ff 35. Common JavaScript engine Math.round bug.
-
[ $compiler == dart2js && $runtime == jsshell ]
-async_call_test: RuntimeError # Timer interface not supported: Issue 7728.
-async_star_await_pauses_test: RuntimeError # Need triage
-async_star_no_cancel2_test: RuntimeError # Need triage
-async_star_no_cancel_test: RuntimeError # Need triage
await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
-regress_23996_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
-
-[ $compiler == dart2js && $runtime != none && $checked ]
-syncstar_covariant_type_test: RuntimeError # dart2js misplaces check in Iterator, not Iterable.
-syncstar_dcall_type_test: RuntimeError # dart2js misplaces check in Iterator, not Iterable.
-
-[ $compiler == dart2js && $runtime == safari ]
-round_test: Fail, OK # Common JavaScript engine Math.round bug.
[ $compiler == dart2js && $system == windows ]
canonicalization_hashing_memoize_array_test: Skip # Issue 37631
canonicalization_hashing_memoize_instance_test: Skip # Issue 37631
canonicalization_hashing_shallow_collision_array_test: Skip # Issue 37631
canonicalization_hashing_shallow_collision_instance_test: Skip # Issue 37631
-string_literals_test: Pass, RuntimeError # Failures on dart2js-win7-chrome-4-4-be and dart2js-win7-ie11ff-4-4-be
-[ $compiler == dart2js && $checked ]
-canonical_const2_test: RuntimeError, OK # non JS number semantics
-const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
-const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
-deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
-double_int_to_string_test: RuntimeError, OK # non JS number semantics
-expect_test: RuntimeError, OK # Issue 13080
-full_stacktrace1_test: RuntimeError # Issue 12698
-full_stacktrace2_test: RuntimeError # Issue 12698
-full_stacktrace3_test: RuntimeError # Issue 12698
-generalized_void_syntax_test: CompileTimeError # Issue #30176.
-generic_function_dcall_test/01: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_tearoff_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-identical_closure2_test: RuntimeError # non JS number semantics
-infinity_test: RuntimeError # non JS number semantics - Issue 4984
-integer_division_by_zero_test: RuntimeError # Issue 8301
-invocation_mirror2_test: RuntimeError # mirrors not supported
-left_shift_test: RuntimeError # non JS number semantics
-mint_arithmetic_test: RuntimeError # non JS number semantics
-mock_writable_final_field_test: RuntimeError # Issue 30847
-modulo_test: RuntimeError # non JS number semantics
-nan_identical_test: RuntimeError # Issue 11551
-numbers_test: RuntimeError, OK # non JS number semantics
-regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
-regress_31057_test: Crash # Unsupported operation: Unsupported type parameter type node B.
-stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/none: RuntimeError # Issue 12698
-stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
-stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
-stacktrace_test: RuntimeError # Issue 12698
-truncdiv_zero_test: RuntimeError # non JS number semantics - Issue 15246
-type_parameter_test/06: Crash # Internal Error: Unexpected type variable in static context.
-type_parameter_test/09: Crash # Internal Error: Unexpected type variable in static context.
-type_variable_scope_test/03: Crash # Internal Error: Unexpected type variable in static context.
-
-[ $compiler == dart2js && $host_checked ]
-async_return_types_test/nestedFuture: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
-async_star_cancel_while_paused_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
-await_not_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-closure_self_reference_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.
-issue23244_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
-partial_tearoff_instantiation_test/05: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-partial_tearoff_instantiation_test/06: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-partial_tearoff_instantiation_test/07: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-partial_tearoff_instantiation_test/08: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
-
-[ $compiler == dart2js && $minified ]
-async_return_types_test/nestedFuture: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
-async_star_cancel_while_paused_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
-await_not_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-cyclic_type2_test: RuntimeError # Issue 31054
-cyclic_type_test/0*: RuntimeError # Issue 31054
-f_bounded_quantification4_test: RuntimeError # Issue 31054
-f_bounded_quantification5_test: RuntimeError # Issue 31054
-generic_closure_test/01: RuntimeError # Uses runtimeType.toString()
-invocation_mirror2_test: RuntimeError # mirrors not supported
-issue23244_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
-mixin_generic_test: RuntimeError # Issue 12605
-mixin_mixin2_test: RuntimeError # Issue 31054
-mixin_mixin3_test: RuntimeError # Issue 31054
-mixin_mixin4_test: RuntimeError # Issue 31054
-mixin_mixin5_test: RuntimeError # Issue 31054
-mixin_mixin6_test: RuntimeError # Issue 31054
-mixin_mixin_bound2_test: RuntimeError # Issue 31054
-mixin_mixin_bound_test: RuntimeError # Issue 31054
-mixin_mixin_type_arguments_test: RuntimeError # Issue 31054
-regress_21795_test: RuntimeError # Issue 12605
-runtime_type_function_test: RuntimeError # Uses runtimeType.toString()
-stack_trace_test: RuntimeError, OK # Stack trace not preserved in minified code.
-symbol_conflict_test: RuntimeError # Issue 23857
diff --git a/tests/language_2/setter_no_getter_test.dart b/tests/language_2/setter_no_getter_test.dart
index 756ccb0..f2ea3e3 100644
--- a/tests/language_2/setter_no_getter_test.dart
+++ b/tests/language_2/setter_no_getter_test.dart
@@ -16,7 +16,7 @@
Example ex = new Example();
print(ex.foo++);
- // ^
- // [analyzer] unspecified
+ // ^^^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
// [cfe] The getter 'foo' isn't defined for the class 'Example'.
}
diff --git a/tests/language_2/variance/syntax/variance_disabled_keyword_identifier_syntax_test.dart b/tests/language_2/variance/syntax/variance_disabled_keyword_identifier_syntax_test.dart
new file mode 100644
index 0000000..0d6828c
--- /dev/null
+++ b/tests/language_2/variance/syntax/variance_disabled_keyword_identifier_syntax_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2019, 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.
+
+// Tests identifier usage of keywords `out` and `inout`, correct usage of `in`.
+
+import "package:expect/expect.dart";
+
+class A<out> {}
+
+class B<inout> {}
+
+class C<out, inout> {}
+
+F<inout, out>() {}
+
+mixin G<out, inout> {}
+
+typedef H<inout, out> = out Function(inout);
+
+class OutParameter {
+ var out = 3;
+ int func(int out) {
+ return out;
+ }
+}
+
+class inout {
+ void out(int x) {}
+}
+
+var out = 5;
+
+main() {
+ OutParameter x = new OutParameter();
+ Expect.equals(2, x.func(2));
+ Expect.equals(3, x.out);
+
+ inout foo = inout();
+ foo.out(4);
+
+ Expect.equals(5, out);
+
+ var collection = [0, 1, 2];
+ for (var x in collection) {
+ Expect.isTrue(x is int);
+ }
+}
diff --git a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
index 9230532..0ae03df 100644
--- a/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
+++ b/tests/language_2/variance/syntax/variance_disabled_syntax_test.dart
@@ -2,40 +2,75 @@
// 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.
-// Tests that since `variance` flag is disabled, correct variance modifier usage will issue an error.
+// Tests with `variance` flag disabled
+// Correct variance modifier usage will issue an error.
-class A<in X> {}
-// ^^
-// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
-// [cfe] Expected an identifier, but got 'in'.
-// ^^
-// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
+import 'package:expect/expect.dart';
+
+abstract class A<in X> {
+// ^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+ int foo(X bar);
+}
class B<out X, in Y, inout Z> {}
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
// ^^
-// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
-// [cfe] Expected an identifier, but got 'in'.
-// ^^
-// [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+// ^^^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
-mixin C<inout T> {}
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
+class C<in T> extends A<T> {
+// ^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+ @override
+ int foo(T bar) {
+ return 2;
+ }
+}
-typedef D<out T> = T Function();
-// ^
-// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
-// [cfe] Expected ',' before this.
+mixin D<out T> {}
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+
+class E1 {}
+
+mixin E<in T extends E1> {}
+// ^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+
+class F<out T> = Object with D<T>;
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+
+class G<out out> {}
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+
+class H<out inout> {}
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPERIMENT_NOT_ENABLED
+// [cfe] This requires the 'variance' experiment to be enabled.
+
+main() {
+ B<int, String, bool> b = B();
+
+ C<int> c = C();
+ Expect.equals(2, c.foo(3));
+
+ F<int> f = F();
+
+ G<int> g = G();
+
+ H<int> h = H();
+}
diff --git a/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart b/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart
index 5028b51..a0bf3d7 100644
--- a/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart
+++ b/tests/language_2/variance/syntax/variance_keyword_identifier_syntax_test.dart
@@ -2,10 +2,25 @@
// 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.
-// Tests identifier usage of keywords `out` and `inout`, correct usage of `in`.
+// Tests identifier usage of keywords `out` and `inout`, correct usage of `in`
+// with the experimental flag `variance` enabled.
+
+// SharedOptions=--enable-experiment=variance
import "package:expect/expect.dart";
+class A<out> {}
+
+class B<inout> {}
+
+class C<out, inout> {}
+
+F<inout, out>() {}
+
+mixin G<out, inout> {}
+
+typedef H<inout, out> = out Function(inout);
+
class OutParameter {
var out = 3;
int func(int out) {
diff --git a/tests/language_2/variance/syntax/variance_syntax_test.dart b/tests/language_2/variance/syntax/variance_syntax_test.dart
new file mode 100644
index 0000000..9a40965
--- /dev/null
+++ b/tests/language_2/variance/syntax/variance_syntax_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, 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.
+
+// SharedOptions=--enable-experiment=variance
+
+import 'package:expect/expect.dart';
+
+abstract class A<in X> {
+ int foo(X bar);
+}
+
+class B<out X, in Y, inout Z> {}
+
+class C<in T> extends A<T> {
+ @override
+ int foo(T bar) {
+ return 2;
+ }
+}
+
+mixin D<out T> {}
+
+class E1 {}
+
+mixin E<in T extends E1> {}
+
+class F<out T> = Object with D<T>;
+
+class G<out out> {}
+
+class H<out inout> {}
+
+main() {
+ B<int, String, bool> b = B();
+
+ C<int> c = C();
+ Expect.equals(2, c.foo(3));
+
+ F<int> f = F();
+
+ G<int> g = G();
+
+ H<int> h = H();
+}
diff --git a/tests/language_2/variance/syntax/variance_type_parameter_error_syntax_test.dart b/tests/language_2/variance/syntax/variance_type_parameter_error_syntax_test.dart
new file mode 100644
index 0000000..a2503b8
--- /dev/null
+++ b/tests/language_2/variance/syntax/variance_type_parameter_error_syntax_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, 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.
+
+// Tests erroneous usages of variance in unapplicable type parameters.
+
+// SharedOptions=--enable-experiment=variance
+
+void A(out int foo) {
+// ^^^
+// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE
+// [cfe] 'out' isn't a type.
+// ^
+// [cfe] Type 'out' not found.
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ')' before this.
+ List<out String> bar;
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The method '<' isn't defined for the class 'Type'.
+ // ^^^
+ // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ // [cfe] Expected ';' after this.
+ // ^^^
+ // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+ // [cfe] Getter not found: 'out'.
+ // ^
+ // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
+ // [cfe] The method '>' isn't defined for the class 'Type'.
+ // ^^^
+ // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+ // [cfe] Getter not found: 'bar'.
+}
+
+void B(out foo) {}
+// ^^^
+// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_AS_TYPE
+// [cfe] 'out' isn't a type.
+// ^
+// [cfe] Type 'out' not found.
+
+class C<in out X, out out Y> {}
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+
+class D<in out inout in out X> {}
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+// ^^^^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+// ^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+// ^^^
+// [analyzer] SYNTACTIC_ERROR.MULTIPLE_VARIANCE_MODIFIERS
+// [cfe] Each type parameter can have at most one variance modifier.
+
+typedef E<out T> = T Function(T a);
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ',' before this.
diff --git a/tests/language_2/vm/regression_38436.dart b/tests/language_2/vm/regression_38436.dart
new file mode 100644
index 0000000..ea5fafd
--- /dev/null
+++ b/tests/language_2/vm/regression_38436.dart
@@ -0,0 +1,2362 @@
+// Copyright (c) 2019, 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.
+
+// VMOptions=--optimization_counter_threshold=1
+
+import "package:expect/expect.dart";
+
+// Found by DartFuzzing: would sometimes crash on OSR
+// https://github.com/dart-lang/sdk/issues/38436
+
+import 'dart:async';
+import 'dart:cli';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:core';
+import 'dart:io';
+import 'dart:isolate';
+import 'dart:math';
+import 'dart:typed_data';
+
+String var0 = '';
+bool var1 = true;
+int var2 = -30;
+double var3 = 0.895077679110543;
+String var4 = '';
+List<int> var5 = [55, -70];
+Set<int> var6 = {
+ 1024,
+ for (int loc0 in [
+ 79,
+ ...[23],
+ ...[90, -89, -24],
+ -90,
+ 11,
+ -19,
+ -91
+ ])
+ -55,
+ 67,
+ -80,
+ for (int loc0 = 0; loc0 < 29; loc0++) 20,
+ for (int loc0 = 0; loc0 < 24; loc0++) ...{23, -41},
+ ...{
+ -75,
+ 128,
+ 9223372034707292159,
+ -56,
+ -59,
+ for (int loc0 in {
+ -67,
+ for (int loc1 in [-27, -59, 31, 32, -66, -87]) -9223372036854775680,
+ 85,
+ -45,
+ if (false) 70,
+ 13,
+ 43,
+ 48
+ })
+ if (true) 63,
+ ...{-90, -24, -9223372036854743041, -9223372032559808383, 86},
+ -25
+ }
+};
+Map<int, String> var7 = {
+ 6: '',
+ ...{56: 'B\u2665pwO', 73: 'ZJDi\u{1f600}m'},
+ ...{73: ')', 14: '93Q'},
+ 98: 'xA0jQL',
+ 21: ')\u2665TOy',
+ for (int loc0 = 0; loc0 < 82; loc0++) 34: 'Q3\u2665#61',
+ ...{70: 'XXRXl3O', 56: '\u2665lda2Zy', 38: 'Dr#mtz', 6: 'nx'},
+ 27: '('
+};
+
+Set<int> foo0() {
+ var3 += ((((var0 + var7[var5[88]])).isEmpty ? true : var1)
+ ? (var1 ? (var3 ?? var3) : var3)
+ : (var1 ? 0.24414824314186978 : var3));
+ var1 ??= true;
+ return {(var2--), Duration.secondsPerHour, var5[var2]};
+}
+
+Map<int, String> foo1(List<int> par1, bool par2) {
+ throw ((-(var3)) * (-(0.943305664017911)));
+}
+
+List<int> foo2(Set<int> par1, List<int> par2, Map<int, String> par3) {
+ switch (-49) {
+ case 4149672951:
+ {
+ for (int loc0 in foo0()) {
+ var6 = var6;
+ try {
+ for (int loc1 = 0; loc1 < 70; loc1++) {
+ switch (((var1
+ ? ((var1 ? var1 : true) ? Float32x4.xzzw : (--var2))
+ : (4295032831 % (loc1 + 93))))
+ .floor()) {
+ case 3294548737:
+ {
+ var5[Int32x4.xxwy] ^=
+ (loc0 * ('!').compareTo(((!(true)) ? var4 : 'S')));
+ }
+ break;
+ case 3294548738:
+ {
+ var0 = var4;
+ loc0 <<= Int32x4.zwxz;
+ }
+ break;
+ }
+ {
+ int loc2 = 0;
+ do {
+ var1 = ('Ncb\u2665P9K').isEmpty;
+ var1 ??= (!(true));
+ } while (++loc2 < 91);
+ }
+ }
+ par3 ??= {
+ 44: ((false
+ ? false
+ : ((true
+ ? var7
+ : {
+ 17: par3[(var5[-73] - -20)],
+ 80: var7[
+ ((++loc0) ~/ ((!(false)) ? 47 : var2))],
+ 30: '8Qvz3',
+ 36: '',
+ 10: (('@B!0bW6' + var4)).toLowerCase(),
+ 89: var7[-9223372036854775296],
+ 4: ') '
+ }) !=
+ var7))
+ ? ((var1 || (!(var1))) ? var7[Float32x4.wxzw] : var7[-7])
+ : '8h'),
+ for (int loc1 in [
+ (false
+ ? ((([
+ var2,
+ -39,
+ -74,
+ Float32x4.zzxy,
+ (~(var5[(67 + -86)])),
+ -53
+ ] +
+ [(var2++), var5[par2[(--loc0)]]]) !=
+ [
+ var5[var5[var5[(loc0++)]]],
+ loc0,
+ loc0,
+ -55,
+ -69,
+ loc0
+ ])
+ ? (loc0--)
+ : loc0)
+ : var2),
+ (75 ^ 93),
+ (false ? var5[Float32x4.xzyw] : (loc0++)),
+ ...[
+ for (int loc2 in {
+ -22,
+ (loc0 ^ 2),
+ var5[(-((par2[-79] * 86)))],
+ (++loc0),
+ ((par2[var5[-45]] ?? 55) >> (true ? Int32x4.wyww : -45)),
+ (~((++var2))),
+ par2[var2]
+ })
+ (loc0--),
+ if ((var7[(false ? (-(loc0)) : 19)]).endsWith(var4))
+ (++var2)
+ else
+ (var1 ? loc0 : 39),
+ (((var2++) & var2) & -26),
+ if (false) (var1 ? Float32x4.wzzw : var5[129]),
+ for (int loc2 in {
+ (loc0--),
+ (true ? loc0 : loc0),
+ var2,
+ var5[(0.4452451921266031).floor()],
+ (~(-4294967196)),
+ (loc0--),
+ (--var2)
+ })
+ (var1 ? -30 : (loc0++)),
+ (~((var1 ? 51 : var2))),
+ (((var3 ?? pi) < 0.9098824013356337)
+ ? ((true ? 57 : -48) << (--var2))
+ : par2[-59])
+ ]
+ ])
+ 84: var4,
+ 57: var4
+ };
+ } catch (exception, stackTrace) {
+ /**
+ ** Multi-line
+ ** documentation comment.
+ */
+ for (int loc1 = 0; loc1 < 89; loc1++) {
+ switch ((var2--)) {
+ case 3807258589:
+ {
+ print(({
+ (-34 ^
+ ((false || var1)
+ ? 24
+ : (-(((-((var1
+ ? par2[(-(71))]
+ : 9223372032559808768))) +
+ (~(loc1))))))),
+ (~((true ? loc0 : (false ? -75 : 33)))),
+ Float32x4.zxwz,
+ (false ? (15 * -83) : (var2--)),
+ ((var7 !=
+ ((true ? var1 : false)
+ ? var7
+ : {
+ 99: (true ? 'TobD' : var0),
+ 59: (var4 ?? var4),
+ 13: var4,
+ 58: Uri.encodeFull(var4),
+ 99: var7[loc1]
+ }))
+ ? loc1
+ : (var1
+ ? ((72 >> -15) ~/ (loc0--))
+ : -9223372030412324864)),
+ 32
+ } ??
+ par1));
+ }
+ break;
+ case 3807258592:
+ {
+ var1 ??= true;
+ try {
+ var7 = {9: (var1 ? 'ON' : 'f\u{1f600}b')};
+ par2 = (true
+ ? var5
+ : [
+ DateTime.january,
+ (40 - (~(var2))),
+ (var1 ? (--loc0) : 23),
+ var5[(--var2)]
+ ]);
+ } catch (exception, stackTrace) {
+ var3 /= 0.9998663372091022;
+ } finally {
+ par2 ??= ((var1
+ ? false
+ : (((par1 ??
+ {
+ -68,
+ 86,
+ -33,
+ var5[(-9223372034707292159 - 90)],
+ (24 - (++var2)),
+ (-(var2)),
+ (loc1 * Int32x4.wyxx)
+ }))
+ .difference({
+ (var1 ? Float32x4.yzyw : (loc1 % loc0)),
+ 6,
+ 22,
+ 91,
+ loc0,
+ (true ? loc1 : loc1)
+ }) ==
+ foo0()))
+ ? par2
+ : [
+ (var2--),
+ (-((++loc0))),
+ ((-(var5[-52])) ~/
+ (true ? Int32x4.wyyy : (loc0--))),
+ (var3).toInt()
+ ]);
+ var5[99] += (~(Float32x4.ywxw));
+ }
+ }
+ break;
+ }
+ var5 = (par2 ??
+ [
+ ...[72],
+ for (int loc2 in {Float32x4.xxwz, loc1})
+ ((loc0--) ~/ (var2++)),
+ par2[(++var2)],
+ (-((--var2))),
+ (var2++),
+ -56,
+ (~((~(loc0)))),
+ for (int loc2 in {
+ (-((~(17)))),
+ Float32x4.zzzw,
+ Float32x4.zyyz,
+ (var2--),
+ (Int32x4.wzwz % 78),
+ loc0
+ })
+ Int32x4.xzzy
+ ]);
+ }
+ {
+ int loc1 = 0;
+ do {
+ loc0 &= (-(4295000065));
+ } while (++loc1 < 94);
+ }
+ } finally {
+ var3 -= 0.020483900923215503;
+ try {
+ return [
+ ...[
+ (loc0--),
+ for (int loc1 in {Float32x4.yxyz})
+ if (var1) (~(-35)) else loc0,
+ (++loc0),
+ for (int loc1 = 0; loc1 < 43; loc1++)
+ (var5[var5[par2[var5[-9223372032559808384]]]] &
+ Int32x4.yzxy),
+ for (int loc1 = 0; loc1 < 98; loc1++) (-((~(Int32x4.xwwy)))),
+ Float32x4.yzzz
+ ],
+ (-(Int32x4.xzxz))
+ ];
+ } catch (exception, stackTrace) {
+ for (int loc1
+ in (((((!((((0.13101852551635873 == 0.4825498460563603)
+ ? var7
+ : var7) !=
+ var7)))
+ ? 1
+ : par2[var2]))
+ .isEven
+ ? {
+ (var2++),
+ (-48 | -54),
+ (~(par2[loc0])),
+ par2[var5[Int32x4.zyzz]],
+ -2,
+ (true ? (~((-(((!(false)) ? -11 : var2))))) : 73),
+ if ((0.15992181539430828).isInfinite) (++var2)
+ }
+ : (false ? {-6} : {((++loc0) % 27), 92})) ??
+ Set.identity())) {
+ var6 ??= foo0();
+ }
+ var5[(~(((true ? -10 : Float32x4.zzwy) -
+ Duration.millisecondsPerSecond)))] = (~((var2--)));
+ }
+ }
+ }
+ par3.forEach((loc0, loc1) {
+ // Single-line comment.
+ var6 = (var6 ?? foo0());
+ par1 = {
+ if (('X2yPgV').endsWith('b'))
+ Float32x4.yxxy
+ else if (true)
+ Int32x4.xzyw
+ else
+ for (int loc2 = 0; loc2 < 9; loc2++) (++loc0),
+ (4294967551 ?? (-((loc0--)))),
+ (-69 ~/
+ ((!(false))
+ ? ((((par2[Int32x4.zwzw]).isEven
+ ? (var3).truncateToDouble()
+ : 0.14035347150303745))
+ .isInfinite
+ ? Int32x4.yzxx
+ : par2[loc0])
+ : (var2++))),
+ ((loc0++) - ((++var2) >> (~(par2[(var2--)]))))
+ };
+ });
+ }
+ break;
+ case 4149672955:
+ {
+ par2[((var2 ^ (~((--var2)))) | -98)] *= -62;
+ {
+ int loc0 = 0;
+ do {
+ var0 = par3[(var5[4294967808] >> Float32x4.wwyx)];
+ } while (++loc0 < 46);
+ }
+ }
+ break;
+ }
+ var1 ??= (!((var3).isNaN));
+ return (var1
+ ? par2
+ : Uri.parseIPv6Address(
+ (var1 ? '' : '26DgiI'), (ZLibOption.maxMemLevel % 65), 68));
+}
+
+class X0 {
+ bool fld0_0 = true;
+ Set<int> fld0_1 = {
+ 31,
+ if (true) ...{
+ -93,
+ -4294967041,
+ -4294934527,
+ if (false) 92,
+ if (true) 69
+ } else
+ 85,
+ ...{
+ ...{73, 27},
+ for (int loc0 in {
+ for (int loc1 = 0; loc1 < 56; loc1++) -36,
+ -23,
+ -99,
+ 20,
+ 16,
+ 11,
+ if (false) -24,
+ if (true) 14
+ })
+ if (false) 69,
+ -9223372032559808513,
+ -9223372036854775553,
+ -9223372036854774784,
+ -22
+ },
+ 81,
+ ...{16, if (false) 67 else -30, if (true) 21 else -61, -84},
+ -69
+ };
+
+ List<int> foo0_0(Map<int, String> par1) {
+ if ((var1 ? ((!(fld0_0)) ? true : false) : true)) {
+ return ((var4).trim()).codeUnits;
+ } else {
+ for (int loc0 in var6) {
+ fld0_0 ??= var1;
+ for (int loc1 = 0; loc1 < 57; loc1++) {
+ {
+ Map<int, String> loc2 = Map.identity();
+ par1 ??= Map.unmodifiable(Map.unmodifiable(Map.unmodifiable((true
+ ? loc2
+ : ((true
+ ? loc2
+ : foo1(
+ [var5[-60], loc0, var5[-48], -80, var5[var5[37]]],
+ var1)) ??
+ {
+ 60: var0,
+ 93: ((false ? var0 : '') + 'r\u{1f600}2B#p')
+ })))));
+ var4 = ' ';
+ }
+ try {
+ var5 = foo2(
+ ({loc0, 37, Float32x4.wwyw} ?? var6),
+ ((fld0_0
+ ? [
+ for (int loc2 = 0; loc2 < 1; loc2++)
+ (~(Float32x4.zyzz)),
+ (~((true
+ ? (Float32x4.yyzw >> (48 - (-((var2--)))))
+ : (~(loc0))))),
+ ((var4 ==
+ String.fromEnvironment(
+ (var1 ? 'l9FM' : par1[var5[loc0]])))
+ ? (++loc0)
+ : 4),
+ ...[
+ (~((var5[-9223372032559808448] - (++var2)))),
+ ...[
+ for (int loc2 in [
+ ((-12 <= 55) ? 9223372032559841280 : loc0),
+ var5[var5[(~(var5[var5[loc1]]))]],
+ (var1 ? 67 : -74)
+ ])
+ (var5[var2]).sign,
+ var5[-65],
+ if (fld0_0)
+ var5[(var5[var5[-90]] ~/ 22)]
+ else
+ (-9223372036854775679 + var5[16]),
+ 76,
+ 7
+ ],
+ (++var2),
+ -9223372034707292160,
+ (var2--),
+ var5[(var2--)]
+ ],
+ loc1,
+ Float32x4.ywxz,
+ ((++loc0) + (--loc0)),
+ for (int loc2 in [
+ for (int loc3 = 0; loc3 < 4; loc3++) loc1,
+ ...[
+ Float32x4.zxwy,
+ Float32x4.xzwx,
+ var2,
+ (++var2),
+ Int32x4.xzyy,
+ (var5[loc1] | (true ? -97 : -93)),
+ Float32x4.xwyz,
+ ((true || var1)
+ ? (~((--loc0)))
+ : (~((var5[18] % (-55 + loc0)))))
+ ],
+ (~((++loc0))),
+ -85,
+ (~((var2++))),
+ (true
+ ? ZLibOption.maxMemLevel
+ : var5[var5[var5[var5[var2]]]]),
+ ((true
+ ? ((!((false
+ ? (true ? fld0_0 : (!(false)))
+ : fld0_0)))
+ ? fld0_0
+ : (({
+ 96: var4,
+ 60: '(0yBGn\u{1f600}',
+ 57: var4,
+ 73: var7[-43],
+ 38: var0
+ })
+ .isNotEmpty ||
+ ({
+ 67: var4,
+ 14: 'M\u{1f600}1HNbP',
+ 6: 's',
+ 85: 'uyq',
+ 95: var7[(-(Int32x4.wwxw))],
+ 33: ''
+ })
+ .isNotEmpty))
+ : false)
+ ? var2
+ : (++var2))
+ ]) ...[-27]
+ ]
+ : [
+ for (int loc2 = 0; loc2 < 87; loc2++)
+ (-47 * (~((((--var2) ^ loc0) ?? 78)))),
+ (-(((({
+ 14: (var3).toStringAsExponential(
+ (false ? var5[-62] : 33)),
+ 16: '',
+ 71: var4,
+ 78: (([var5[(-(91))]] == var5) ? var4 : var0),
+ 9: par1[loc1],
+ 51: '-8ht',
+ 26: ('(2l3\u2665h' ?? var0),
+ 79: var4
+ })
+ .isNotEmpty
+ ? var5[(var2 % loc0)]
+ : var2) %
+ ((!(NetworkInterface.listSupported))
+ ? -22
+ : ((var1
+ ? ([
+ ZLibOption.STRATEGY_DEFAULT,
+ 21,
+ loc1,
+ loc1,
+ loc0,
+ 5,
+ loc0,
+ 98
+ ] ==
+ Uri.parseIPv4Address(
+ var7[loc1]))
+ : var1)
+ ? (~((-20 %
+ (var5).removeAt(Float32x4.wyxw))))
+ : var5[var5[82]]))))),
+ (-(Float32x4.wwwz)),
+ Int32x4.wxxz,
+ ...[
+ (loc0++),
+ ...[
+ (--loc0),
+ -2,
+ ZLibOption.DEFAULT_WINDOW_BITS,
+ -42,
+ for (int loc2 = 0; loc2 < 2; loc2++) (-(-22)),
+ (~(-81))
+ ],
+ (--var2)
+ ],
+ (++var2),
+ ((!(false)) ? (--var2) : (((~(34)) >> 48) << 79)),
+ loc1
+ ]) +
+ foo2(
+ foo0(),
+ ([
+ (((~(var5[(-(var5[(87 % var5[(++var2)])]))])) ??
+ -11) ~/
+ (var2++)),
+ ((((!(var1)) && true) ? loc1 : 98) <<
+ ((!((true != (var4 == par1[var5[(~(-83))]]))))
+ ? -44
+ : var5[88])),
+ Float32x4.yyyz,
+ -44,
+ Int32x4.xzyx,
+ (++loc0)
+ ] ??
+ [
+ ((foo1([((!(var1)) ? 24 : 81), -93], true))
+ .isEmpty
+ ? 52
+ : (~(Int32x4.zyww))),
+ Int32x4.xxwz,
+ (-(-11)),
+ (loc0--),
+ ((!(bool.fromEnvironment('U\u2665')))
+ ? (loc0++)
+ : (++var2))
+ ]),
+ {
+ 70: var7[7],
+ 18: '\u2665(#&c\u{1f600}-',
+ 58: 'KuNr',
+ 96: '\u{1f600}2\u2665YY',
+ 94: var0,
+ 28: 'l-'
+ })),
+ par1);
+ {
+ double loc2 = double.infinity;
+ /*
+ * Multi-line
+ * comment.
+ */
+ return ('a!wNh!').codeUnits;
+ }
+ } catch (exception, stackTrace) {
+ continue;
+ } finally {
+ fld0_0 = (!(fld0_0));
+ var5 ??= ((Uri.parseIPv4Address('H') ??
+ (foo2({
+ loc1,
+ ([
+ if (((true ? loc0 : (loc0++)) <
+ ((!(var1)) ? -90 : Int32x4.yyzx)))
+ (~(var2))
+ else
+ for (int loc2 in {
+ if (SecurityContext.alpnSupported)
+ var2
+ else
+ Int32x4.wzzy,
+ -9223372036754112763,
+ (-((var1
+ ? var5[62]
+ : (-(Float32x4.wzwz))))),
+ (~(Float32x4.yxzy))
+ })
+ ((((true && (false ? fld0_0 : var1))
+ ? fld0_0
+ : false)
+ ? true
+ : (fld0_0 && var1))
+ ? (true ? (~(loc1)) : var5[-16])
+ : loc0),
+ for (int loc2 = 0; loc2 < 1; loc2++)
+ ((false && var1) ? Float32x4.yzyy : 50)
+ ][var2] *
+ [
+ ...[
+ (((-10 >> Int32x4.wxzw) *
+ ((0.42979687169554437 >=
+ 0.17848133910264385)
+ ? -4
+ : var5[-15])) |
+ var5[(loc0++)]),
+ ...[
+ (('@jcNl\u2665P')
+ .compareTo(var7[(loc0--)]) &
+ (~((~(loc0))))),
+ if ((!(((!(true)) && true)))) 2,
+ loc1,
+ ((var5[(loc0--)] | -38) & (loc0++)),
+ var2,
+ (~(-22)),
+ if (false) loc0 else 80,
+ (--loc0)
+ ],
+ ...[15],
+ ((~((~(-5)))) ^ Int32x4.xxxz),
+ 79,
+ for (int loc2 in [
+ (fld0_0 ? -0 : (loc0++)),
+ -49,
+ for (int loc3 in [
+ -16,
+ (var2--),
+ 35,
+ ((14 * -68) ~/ Int32x4.wwyy)
+ ])
+ var5[(fld0_0 ? 28 : (-41 ?? 19))],
+ loc0,
+ (var3).round(),
+ if ((!((!((!(false))))))) loc1,
+ (loc0++),
+ Int32x4.wyww
+ ])
+ ((--var2) * var5[(6 & var5[(~(-53))])]),
+ (loc0++),
+ Float32x4.xwxx
+ ],
+ Int32x4.ywyw,
+ (-(ZLibOption.strategyFixed)),
+ (80 % (loc0--)),
+ var5[Int32x4.zxww]
+ ][var5[50]]),
+ (false ? -71 : 39),
+ (var5[-61]).toSigned(loc0),
+ -50,
+ 4294967296
+ }, [
+ (16 *
+ (~(((var1 ? ZLibOption.STRATEGY_FIXED : -66) *
+ 4)))),
+ Float32x4.wwwx
+ ], {
+ 63: var0,
+ 52: (fld0_0 ? 'uG\u2665V@4' : '62'),
+ 98: var7[var5[-83]],
+ 70: (false
+ ? 'bSg'
+ : base64UrlEncode(([
+ (~(var2)),
+ -52,
+ 68,
+ [
+ 10,
+ loc1,
+ 92,
+ 53,
+ Int32x4.zzyw,
+ (true ? 12 : 19),
+ (~(var5[(++var2)]))
+ ][-64],
+ (++loc0),
+ (loc0 << -26)
+ ] +
+ [
+ var5[(--loc0)],
+ (((var1 ? var5[var5[(var2--)]] : loc1) +
+ (--var2)) <<
+ Int32x4.wyyx)
+ ]))),
+ 16: 'YsD\u2665\u2665K',
+ 0: var0,
+ 93: var7[(-(var5[-43]))]
+ }) ??
+ var5)) ??
+ [
+ if (fld0_0) -90,
+ (--var2),
+ ...[
+ for (int loc2 in [
+ (false ? (~(-9)) : -4294901760),
+ (-(-7)),
+ -51,
+ (var1 ? -75 : [Float32x4.wwxw, Int32x4.zxyx][-7]),
+ Float32x4.xyww,
+ Int32x4.wwzx,
+ (loc0++),
+ (NetworkInterface.listSupported
+ ? [1000][Float32x4.zzyx]
+ : -71)
+ ])
+ -27,
+ Float32x4.wyzy,
+ (++var2)
+ ]
+ ]);
+ }
+ }
+ }
+ throw Map.unmodifiable(foo1(
+ (MapBase.mapToString(foo1((false ? [var2] : var5), false))).codeUnits,
+ true));
+ }
+ }
+
+ void run() {}
+}
+
+class X1 extends X0 {
+ double fld1_0 = 0.47694301047645304;
+ bool fld1_1 = true;
+
+ Map<int, String> foo1_0(
+ Map<int, String> par1, Map<int, String> par2, double par3) {
+ // Single-line comment.
+ for (int loc0 = 0; loc0 < 91; loc0++) {
+ par2.forEach((loc1, loc2) {
+ {
+ bool loc3 = (fld1_1 || ('U\u2665').isEmpty);
+ var3 /= 0.8504341352135224;
+ }
+ });
+ {
+ int loc1 = 66;
+ while (--loc1 > 0) {
+ if (((!((true || fld1_1))) == true)) {
+ var0 ??= par2[var5[(~((false ? ((!(var1)) ? -95 : var2) : -37)))]];
+ /**
+ ** Multi-line
+ ** documentation comment.
+ */
+ return Map.unmodifiable({
+ 55: var4,
+ 73: 'c#',
+ 17: (fld1_1
+ ? '7\u{1f600}e'
+ : ((!(var1)) ? '8E7AK2e' : 'Fm\u{1f600} F')),
+ 40: 'mb(\u{1f600}\u2665l',
+ 36: Uri.decodeFull((true ? par2[-32769] : var7[Float32x4.zyxz])),
+ 51: ((false &&
+ (((var1 ? true : true) || false)
+ ? (var7[(var2--)]).isEmpty
+ : true))
+ ? (fld1_1
+ ? (fld1_1 ? (var1).toString() : 'r9M')
+ : ((true ? (0.2863696758528199 != par3) : false)
+ ? (fld1_1 ? par1[Int32x4.zwyz] : var4)
+ : var4))
+ : var4),
+ 8: '6G',
+ 62: '+z@Gp'
+ });
+ } else {
+ var5[Int32x4.zzyy] ??= (-(var5[((!(false)) ? loc1 : -34)]));
+ {
+ int loc2 = (-(7));
+ var3 /= (true
+ ? (-(((-9223372032459145467).isEven
+ ? fld1_0
+ : (-((-(0.7008573255099826)))))))
+ : par3);
+ }
+ }
+ for (int loc2 in foo2(var6, var5, {
+ if (false) 11: par1[((var4).isEmpty ? 55 : -61)],
+ 12: 'f5j2v\u{1f600}',
+ 52: (((foo1(
+ (((var1
+ ? {var5[-66], var2, 88, 12, 6, -96}
+ : (var1
+ ? {-25, 84, (var2--), var5[83]}
+ : {-36, var5[51], var2})) !=
+ {var5[(++var2)]})
+ ? [-2147483648, 46, loc0, var5[loc0], -21]
+ : foo2(
+ {var5[var5[loc0]]},
+ (true
+ ? var5
+ : [
+ -30,
+ var5[(-(-42))],
+ var2,
+ Float32x4.zywx,
+ loc1,
+ 63,
+ -25,
+ -28
+ ]),
+ {30: 'j\u2665U', 98: var4})),
+ false))
+ .isNotEmpty
+ ? (false ? fld1_0 : 0.3202297128057393)
+ : 0.1301025669674245))
+ .toStringAsFixed(((fld1_1 ? 79 : -88) + Int32x4.xyzw)),
+ 88: (false ? var7[(var2++)] : (var4 ?? '')),
+ 31: (var1
+ ? (var1 ? par2[-87] : (true ? par2[-14] : var4))
+ : ((fld1_1 != true) ? '3nd9t&' : var4)),
+ 22: ('(Czi' + '-Y')
+ })) {
+ var7[(loc2--)] = 's';
+ }
+ }
+ }
+ }
+ return par1;
+ }
+
+ String foo1_1(int par1) => var0;
+ Set<int> foo1_2(String par1) {
+ for (int loc0 = 0; loc0 < 58; loc0++) {
+ switch ((~(13))) {
+ case 746492976:
+ {
+ switch (Duration.millisecondsPerDay) {
+ case 3635015902:
+ {
+ var7[var5[(var5[var2] * (-(var5[Float32x4.yxxz])))]] ??=
+ (var7[-79] + '(O@');
+ var7[loc0] ??= String.fromCharCode(var5[(true
+ ? (var5[((var1 ? true : (false ? fld1_1 : var1))
+ ? var5[Float32x4.wyyz]
+ : 73)] ~/
+ (-(84)))
+ : -15)]);
+ }
+ break;
+ case 3635015905:
+ {
+ var1 = (var1
+ ? (foo1_0(
+ (((!(false)) || fld1_1) ? var7 : var7),
+ foo1_0(
+ {74: '\u2665e', 10: 'tw8jc0R'},
+ foo1_0(
+ var7,
+ foo1_0(
+ ({
+ 17: var7[Int32x4.zyxy],
+ 82: var7[64],
+ 27: 'VEtj',
+ 90: Uri.encodeQueryComponent(
+ foo1_1(var2)),
+ 68: 'wew0\u{1f600}'
+ } ??
+ foo1_0(var7, var7, var3)),
+ ({
+ 65: 'mBeBfUj',
+ 81: var4,
+ 35: (var7[-43] + 'l'),
+ 68: var4
+ } ??
+ {
+ 33: ('N\u{1f600}xaY+' ?? par1),
+ 44: var7[var5[var2]],
+ 83: var4,
+ 86: 'k'
+ }),
+ asin(0.4245871535895427)),
+ (-(0.2913717674787144))),
+ 0.9439800024935644),
+ (-((true
+ ? ((var1 ? false : var1)
+ ? 0.09441225978923817
+ : 0.42622157485045953)
+ : (-(0.29370792038584836)))))))
+ .isNotEmpty
+ : (false && true));
+ var3 += (-(fld1_0));
+ }
+ break;
+ }
+ }
+ break;
+ case 746492979:
+ {
+ var4 = var0;
+ for (int loc1 = 0; loc1 < 88; loc1++) {
+ var2 += 32;
+ }
+ }
+ break;
+ }
+ }
+ {
+ int loc0 = 0;
+ do {
+ return foo0();
+ } while (++loc0 < 57);
+ }
+ return foo0();
+ }
+
+ String foo1_3() {
+ if ((0.42144855521066793).isNegative) {
+ print((false ? (-(fld1_0)) : (-((-((-(0.26854952952179667))))))));
+ switch (30) {
+ case 3830102525:
+ {
+ try {
+ var7.forEach((loc0, loc1) {
+ var1 = (!(true));
+ var6 = (foo1_2(var7[99]) ?? var6);
+ });
+ var6 ??= var6;
+ } catch (exception, stackTrace) {
+ var4 ??= ListBase.listToString([
+ (Duration.microsecondsPerSecond + -82),
+ (true
+ ? var5[(var2 ~/ (false ? (~((var1 ? 46 : var2))) : var2))]
+ : (-9223372034707292161 >> var5[var5[-86]])),
+ Float32x4.wxyx
+ ]);
+ } finally {
+ /**
+ ** Multi-line
+ ** documentation comment.
+ */
+ fld1_1 = (var5[var5[var2]]).isOdd;
+ }
+ /*
+ * Multi-line
+ * comment.
+ */
+ if ((SetBase.setToString((fld1_1
+ ? {12, (fld1_1 ? (-(-22)) : (-(4395630341)))}
+ : var6)))
+ .isNotEmpty) {
+ try {
+ {
+ int loc0 = 86;
+ while (--loc0 > 0) {
+ {
+ int loc1 = 0;
+ do {
+ var0 = var7[(-(((--var2) &
+ ((var1 ? (fld1_0).isNaN : true)
+ ? (-16 | -20)
+ : ((0.7513819161190503).isNaN ? 45 : loc1)))))];
+
+ /// Single-line documentation comment.
+ var5[(true ? loc0 : Float32x4.zxzx)] %= loc0;
+ } while (++loc1 < 17);
+ }
+ for (int loc1 = 0; loc1 < 25; loc1++) {
+ var5[Float32x4.zywy] <<= Int32x4.ywwx;
+ }
+ }
+ }
+ } catch (exception, stackTrace) {
+ var7 = Map.from(foo1_0({
+ 81: (foo1_1(((++var2) * (-(var5[21])))) +
+ (var7[8] + (var7[var5[53]] ?? var0))),
+ for (int loc0 in [
+ (true ? 58 : Float32x4.wyww),
+ var5[(fld1_1 ? 46 : var2)]
+ ])
+ 63: var7[(false
+ ? var5[((24 >> -9223372036854710272) & var2)]
+ : var5[(80 << var5[-31])])],
+ 67: var0,
+ 1: '3mlOA',
+ 30: ('OQbG').substring((var2--), (--var2)),
+ 93: ((var7[74] ?? var7[(++var2)])).toLowerCase(),
+ ...{
+ 85: foo1_1(-21),
+ if ((!((!(false))))) 86: var0,
+ 49: '62+v',
+ 59: foo1_1((--var2)),
+ for (int loc0 in [
+ -10,
+ -65,
+ (var2++),
+ (var2++),
+ ((({
+ ((var7[60] == var7[-30])
+ ? var5[(-((var2++)))]
+ : (var2--))
+ } ==
+ {var5[var2], -40, -81, (var2++), 93, 26})
+ ? 38
+ : (var1 ? var5[97] : -82)) *
+ (--var2)),
+ (~((true ? 5 : Float32x4.yxyy))),
+ (var2++),
+ ((++var2) << ((var2 % Int32x4.yxxw) >> (++var2)))
+ ])
+ 54: (var0 + 'ANyqN'),
+ 94: (var1 ? '0T\u2665#w' : (var0).toUpperCase()),
+ 68: '@n',
+ 67: base64UrlEncode(((0.07857744084458451).isInfinite
+ ? ([
+ var2,
+ var5[70],
+ -32,
+ Float32x4.yxwz,
+ 31,
+ (~(var2)),
+ (var2 ?? (-70 + 57)),
+ -91
+ ] +
+ [
+ var2,
+ var5[((!(var1))
+ ? var5[(var2 ~/ Float32x4.zwyw)]
+ : var5[var5[(var5[(~(var2))] % var2)]])],
+ (var2 | (false ? (-(var2)) : var5[80])),
+ (var2--),
+ DateTime.daysPerWeek,
+ (var2 ~/ var2)
+ ])
+ : (var1 ? var5 : [(var2++)])))
+ },
+ if (false)
+ if (false)
+ 26: (Uri.encodeComponent(foo1_1(var2)) + var7[var5[var2]])
+ else ...{
+ 4: (double.negativeInfinity).toStringAsFixed(var2),
+ 46: Uri.decodeQueryComponent('bst3jz'),
+ 5: ((true
+ ? (true ? '(-f' : var7[(-(Int32x4.yzxz))])
+ : var7[(var5[(fld1_1 ? (var2--) : var2)] >>
+ (-((false ? 8589934591 : 33))))]) ??
+ '4ov'),
+ 37: var7[var5[100663045]],
+ 13: '2B'
+ }
+ }, {
+ 71: 'Hxbq',
+ 22: ('\u{1f600}Jtj').substring(
+ (-36 | var5[(~((var2++)))]), 9223372032559874048)
+ }, 0.3710694748818374));
+ fld1_0 ??= 0.010604823956237519;
+ } finally {
+ for (int loc0 = 0; loc0 < 84; loc0++) {
+ var5[Float32x4.xwwz] <<=
+ ((((fld1_1 ? false : ('e\u{1f600}O+Vc').isNotEmpty) &&
+ (!(fld1_1)))
+ ? (-73 | var5[Int32x4.yzwx])
+ : Uint16List.bytesPerElement) ~/
+ var2);
+ }
+ }
+ }
+ }
+ break;
+ case 3830102528:
+ {
+ fld1_1 ??= true;
+ throw (-((-17).ceilToDouble()));
+ }
+ break;
+ }
+ }
+ return var0;
+ }
+
+ void run() {
+ super.run();
+ {
+ int loc0 = 61;
+ while (--loc0 > 0) {
+ {
+ int loc1 = 77;
+ while (--loc1 > 0) {
+ {
+ int loc2 = 0;
+ do {
+ break;
+ } while (++loc2 < 84);
+ }
+ }
+ }
+ if (((var1 || fld1_1) && (!((!((!((!((!(true)))))))))))) {
+ switch (Int32x4.yyzx) {
+ case 900727295:
+ {
+ /// Single-line documentation comment.
+ fld1_1 ??= (!(true));
+ for (int loc1 in ((var5 ??
+ Uri.parseIPv6Address(
+ foo1_3(), var5[(loc0 + var5[4096])], -34)) ??
+ var5)) {
+ var7[(38 << (false ? (~(-58)) : Float32x4.yyxy))] =
+ Uri.decodeFull(foo1_3());
+ var5 ??= var5;
+ }
+ }
+ break;
+ case 900727304:
+ {
+ fld1_1 =
+ (SecurityContext.alpnSupported ? (var3).isFinite : var1);
+ fld1_0 += 0.3154406798513474;
+ }
+ break;
+ }
+ var2 ^= var2;
+ } else {
+ if (((-(var3)) <= (-(fld1_0)))) {
+ var6 = foo1_2('0vsDWF9');
+ } else {
+ var6 ??= ((fld1_0 <= 0.16230005903410238)
+ ? ((!((0.5144029832155854 > (0.8199455895430549 / var3))))
+ ? foo1_2('ken')
+ : var6)
+ : (fld1_1 ? {56, 6442450945, 2} : {34}));
+ }
+ var5[Float32x4.zwzw] += (true ? var2 : (~(Float32x4.wyyx)));
+ }
+ }
+ }
+ }
+}
+
+class X2 extends X0 with X1 {
+ Set<int> fld2_0 = {for (int loc0 = 0; loc0 < 60; loc0++) -56, 29};
+
+ bool foo2_0(int par1) => var1;
+ bool foo2_1(bool par1) {
+ for (int loc0 in var6) {
+ var2 ~/= ((((((fld2_0 ?? (true ? var6 : var6)) ?? fld2_0))
+ .union({(~(-21)), 10}) !=
+ {(var5[90] ~/ (-(-90)))})
+ ? par1
+ : (var7[(~(82))]).isNotEmpty)
+ ? ((~(loc0)) *
+ ((true ? (-4294966272 ?? -21) : var2) +
+ Duration.millisecondsPerMinute))
+ : (-9223372032559807488 ~/ 4294968296));
+ }
+ if (('DeAm#f' ==
+ ((Uri.encodeQueryComponent((0.3687340601979223).toString()) ??
+ var7[-23]) ??
+ foo1_3()))) {
+ throw (([Float32x4.wyyz, -9223372036854743039])
+ .sublist((--var2), (--var2)) +
+ ((true ? var1 : (!(false)))
+ ? foo2(
+ foo1_2('JLXt'),
+ [
+ var5[Int32x4.zxzx],
+ Int32x4.xxwy,
+ (var2++),
+ Float32x4.yzxx,
+ (var2++),
+ -15
+ ],
+ foo1_0(var7, var7, 0.7904389283184639))
+ : (var1
+ ? [Float32x4.yzyz, Int32x4.wxxy, var2, (~(var5[-47]))]
+ : var5)));
+ } else {
+ var7[var2] ??= ((({
+ ...{
+ for (int loc0 = 0; loc0 < 19; loc0++)
+ 36: (var7[var2] ?? (par1 ? ('ccb9z' + 'iM') : var0)),
+ 3: ('1sG' + var0),
+ for (int loc0 in {
+ (-(var5[var2])),
+ if (var1) Int32x4.zxxx,
+ -4294967168,
+ -61,
+ (~((par1 ? (~(-70)) : (var2--)))),
+ (-(7)),
+ -96,
+ Uint32List.bytesPerElement
+ })
+ 85: var4
+ },
+ if (foo2_0(-91)) 38: (var3).toString() else 30: 'uI\u2665\u{1f600}',
+ 72: '@'
+ }[(par1 ? 14 : var2)])
+ .trim())
+ .substring((36 ~/ var5[(++var2)]), var5[((-(25)) * -53)]) ??
+ foo1_3());
+ /*
+ * Multi-line
+ * comment.
+ */
+ {
+ int loc0 = 0;
+ do {
+ {
+ String loc1 = 'jG7t';
+ /**
+ ** Multi-line
+ ** documentation comment.
+ */
+ {
+ int loc2 = 57;
+ while (--loc2 > 0) {
+ print((var6 ??
+ (foo1_2(var0)).union(foo1_2(('n' + var7[(++var2)])))));
+ }
+ }
+ }
+ } while (++loc0 < 69);
+ }
+ }
+ return (!(((!((par1 && false)))
+ ? (true && foo2_0(-9223372036854771712))
+ : (!(par1)))));
+ }
+
+ double foo2_2(Map<int, String> par1, int par2) {
+ switch (var2) {
+ case 3816231196:
+ {
+ throw (-(Int32x4.xxwx));
+ }
+ break;
+ case 3816231204:
+ {
+ var7.forEach((loc0, loc1) {
+ switch ((-43 ^ (-(Float32x4.wwxx)))) {
+ case 2839002105:
+ {
+ var0 ??= (SetBase.setToString(((var1 ? var1 : (true || var1))
+ ? fld2_0
+ : {
+ Int32x4.yyzw,
+ Int32x4.yyxy,
+ (2 >> Int32x4.ywzx),
+ (var1
+ ? ((foo2_1(var1) ? 17 : loc0) ~/
+ (-(var5[var2])))
+ : par2),
+ Float32x4.zwwx,
+ par2,
+ Int32x4.wzzz,
+ Int32x4.zyzw
+ })) ??
+ (loc1 +
+ var7[((true
+ ? (var1 &&
+ bool.fromEnvironment(var7[(var2--)]))
+ : foo2_1(false))
+ ? 35
+ : (-(66)))]));
+ for (int loc2 = 0; loc2 < 23; loc2++) {
+ switch ((-73 ^ (Int32x4.xyzz >> Float32x4.yzzz))) {
+ case 1710454916:
+ {
+ var3 = 0.3372913861348876;
+ print(((-(var3)) * var3));
+ }
+ break;
+ case 1710454922:
+ {
+ var4 ??= ((false
+ ? (var1
+ ? var1
+ : (fld2_0 ==
+ {
+ (false ? -27 : (-(92))),
+ loc2,
+ var5[loc2],
+ (var1
+ ? Float32x4.yywy
+ : (false ? -74 : 2)),
+ ((-(-50)) ^ 32),
+ (var2++)
+ }))
+ : var1)
+ ? base64UrlEncode([
+ for (int loc3 in {
+ (-(par2)),
+ loc0,
+ (-((par2++))),
+ Float32x4.yyyx
+ })
+ (par2--),
+ (-((-(var5[var5[var5[-41]]])))),
+ if (({
+ loc2,
+ Duration.microsecondsPerSecond,
+ (([
+ (par2++),
+ (-90 ^ -5),
+ var5[(~(0))],
+ loc2
+ ] !=
+ var5)
+ ? -9223372032559808512
+ : (par2++))
+ } ==
+ {
+ (var1 ? (-((loc2 % loc2))) : loc2),
+ -94,
+ -62
+ }))
+ (++var2),
+ loc2,
+ for (int loc3 in {
+ 55,
+ (~(var5[var5[(++par2)]])),
+ ((var1
+ ? (-((++var2)))
+ : var5[(true ? var5[68] : 10)]) -
+ par2),
+ (-(Float32x4.wzxx))
+ })
+ (Int32x4.yxzy | var5[-1]),
+ (foo2_1(false) ? (-(32)) : loc0),
+ (--par2),
+ if ((!(false))) (var1 ? var5[loc0] : 30)
+ ])
+ : ('b1TKp3' ??
+ (var4 +
+ var7[(~(var5[
+ ((var1 ? var2 : loc2) - 72)]))])));
+ }
+ break;
+ }
+ fld2_0 = ((!((false
+ ? false
+ : (false ? (!((var7[-28] != ''))) : var1))))
+ ? (((var1
+ ? (true ? Set.identity() : var6)
+ : {
+ -63,
+ Int32x4.xxyx,
+ var5[((var1
+ ? (var5[-9223372032559808496] >>
+ 59)
+ : Int32x4.wxxy) ~/
+ var5[var5[-48]])],
+ (par2 ?? par2),
+ 44,
+ var5[(var1 ? -26 : (-(par2)))]
+ }) ??
+ ({
+ loc2,
+ var2,
+ ZLibOption.defaultMemLevel,
+ (true ? Int32x4.wyzz : 40),
+ (false ? loc2 : var5[42]),
+ -16
+ } ??
+ var6)))
+ .union({loc0, (var2++), (-1 * (~(var2)))})
+ : (bool.fromEnvironment((var3)
+ .toStringAsFixed(Uint64List.bytesPerElement))
+ ? fld2_0
+ : {
+ (par2++),
+ (var1 ? loc2 : (++var2)),
+ ((false || false) ? Int32x4.xyyz : (++par2)),
+ var5[-98],
+ Float32x4.zwwy,
+ var5[var5[62]],
+ (~(Float32x4.ywww))
+ }));
+ }
+ }
+ break;
+ case 2839002106:
+ {
+ for (int loc2 = 0; loc2 < 13; loc2++) {
+ {
+ int loc3 = 0;
+ do {
+ switch ((loc3 | -76)) {
+ case 2164097105:
+ {
+ var4 ??= (var1).toString();
+ var5 = ((!(((true || var1) !=
+ (false ? var1 : (!(foo2_1(var1)))))))
+ ? foo2(
+ ((var6).union(foo1_2(loc1))).toSet(),
+ [
+ -67,
+ if (((var1
+ ? 59
+ : (-((false ? -97 : par2)))) !=
+ (false
+ ? ((var1 || var1)
+ ? (-((par2++)))
+ : 4)
+ : (--var2)))) ...[
+ ((92 ~/ Int32x4.yzwx) << 70),
+ Float32x4.xxyz,
+ Int8List.bytesPerElement
+ ] else
+ 69
+ ],
+ var7)
+ : foo2(foo0(), Uri.parseIPv4Address(var0),
+ var7));
+ }
+ break;
+ case 2164097111:
+ {
+ var4 ??= var7[Float32x4.zxzw];
+ }
+ break;
+ }
+ } while (++loc3 < 96);
+ }
+ fld2_0 = var6;
+ }
+ }
+ break;
+ }
+ });
+ for (int loc0 in (foo2_1((var5 !=
+ (false
+ ? [par2]
+ : foo2(
+ var6,
+ [20],
+ ({
+ 21: var0,
+ 68: foo1_3(),
+ 24: ('1MF' + '8s\u2665yx+ ')
+ } ??
+ {
+ 9: var7[var2],
+ 48: 'mB(wW\u{1f600}',
+ 74: 'ojEw\u{1f600}\u{1f600}',
+ 80: '\u26655E-hj\u{1f600}',
+ 10: (false ? 'W7i5\u2665YX' : '! Ed9&'),
+ 88: (false ? var0 : 'N0D9(H\u{1f600}'),
+ 5: 'QZ'
+ })))))
+ ? foo1_2('XP')
+ : {
+ if ((foo2_1(var1)
+ ? (foo2_1((fld2_0).add(-9223372036854774784)) || var1)
+ : var1))
+ (~(Float32x4.zyww)),
+ Float32x4.xwyw,
+ ((((var1 ? true : var1) ? 0.3447071353935154 : var3) >=
+ 0.5995056331958718)
+ ? ZLibOption.MAX_LEVEL
+ : 16),
+ 9223372032559841279,
+ Int32x4.zwyy
+ })) {
+ for (int loc1 = 0; loc1 < 19; loc1++) {
+ var1 = (!(bool.fromEnvironment(MapBase.mapToString({
+ 1: '4',
+ 56: var0,
+ 85: var0,
+ 51: var7[-4],
+ 42: ((!((!(false)))) ? par1[72] : MapBase.mapToString(var7))
+ }))));
+ }
+ }
+ }
+ break;
+ }
+ print((((var1 ? 'kP' : (var1 ? 'irjF' : var7[var5[90]])) ??
+ ((!(false)) ? 'vWa\u{1f600}' : var0)) +
+ 'xzpK'));
+ return var3;
+ }
+
+ void run() {
+ super.run();
+ {
+ int loc0 = (~(-24));
+ var0 ??= ((false
+ ? foo2_1((true
+ ? (var1 && (var2).isOdd)
+ : (('dTYR' ?? 'G\u{1f600}P14\u{1f600}a')).isEmpty))
+ : ((var1 && true) || (!(var1))))
+ ? (var4 ?? 'I')
+ : 'QO');
+ }
+ }
+}
+
+class X3 extends X1 {
+ Map<int, String> fld3_0 = {
+ if (true) if (false) 45: 'ynEn\u2665nG' else 70: 'c\u{1f600}mN4\u2665a',
+ if (true) 30: '6\u2665P!Pbi',
+ 81: 't',
+ 82: '17fx#!',
+ 92: 'H',
+ if (true) 69: ')Ls'
+ };
+ Set<int> fld3_1 = {27};
+ int fld3_2 = 34;
+
+ String foo1_1(int par1) {
+ throw (ListBase.listToString(foo2({
+ -4294967169,
+ par1
+ }, [
+ -97,
+ (var5[(var1 ? var5[87] : Int32x4.yxxy)] * Int32x4.yyxx),
+ var2,
+ (false ? 10 : var5[var5[(par1++)]])
+ ], var7)) ??
+ 'o');
+ }
+
+ bool foo3_0(double par1) {
+ {
+ Set<int> loc0 = (true ? fld3_1 : var6);
+ {
+ Set<int> loc1 = (false
+ ? foo0()
+ : {
+ for (int loc2 in [var2, (-(Float32x4.xzzw))])
+ if (false) Float32x4.wxyz else (++fld3_2),
+ ((var1
+ ? 5
+ : var5[(((var5[(true ? fld3_2 : fld3_2)] ~/ 48) | 56) %
+ var5[-4])]) ??
+ (var2++))
+ });
+ for (int loc2 = 0; loc2 < 90; loc2++) {
+ {
+ int loc3 = 95;
+ while (--loc3 > 0) {
+ return (((0.7073184699576396).isNaN
+ ? var7
+ : (Map.of(Map.from(var7)) ??
+ Map.unmodifiable(Map.identity()))))
+ .isEmpty;
+ }
+ }
+ try {
+ var1 = (((12 >= Int32x4.ywxx) ? true : true)
+ ? false
+ : (((var1 ? fld3_0[Int32x4.wyxy] : '') ?? var7[Float32x4.xwwx]))
+ .isEmpty);
+ var2 |= ((fld3_2++) ?? (fld3_2--));
+ } catch (exception, stackTrace) {
+ var5 ??= var5;
+ } finally {
+ var4 = 'A';
+ break;
+ }
+ }
+ {
+ double loc2 = (-(exp((acos(0.06129144867031855) ?? var3))));
+ fld3_0 = (((({Int32x4.ywxw, 6442450943}).union(foo0()))
+ .add((++fld3_2))
+ ? false
+ : false)
+ ? foo1_0(
+ (foo1([var5[var2], var5[75], 42], false) ?? var7), var7, loc2)
+ : (var1
+ ? {
+ for (int loc3 = 0; loc3 < 48; loc3++) 78: 'dWek8',
+ 40: fld3_0[(var5[-81] & Int32x4.xzyw)],
+ 73: (' )G\u2665-d(').substring(
+ (NetworkInterface.listSupported
+ ? (~(((++var2) ?? (fld3_2 * fld3_2))))
+ : var5[-75]),
+ fld3_2),
+ 74: ('k9O\u2665').trimLeft(),
+ 88: var7[(++var2)],
+ for (int loc3 = 0; loc3 < 27; loc3++)
+ 60: ((false || var1) ? var7[46] : var0),
+ 99: ((var3).isNaN
+ ? (Uri.decodeComponent(foo1_3()) + var4)
+ : var7[-77]),
+ 92: (true
+ ? ('').padLeft(82, '')
+ : ('' ?? var7[(false ? 94 : 58)]))
+ }
+ : var7));
+
+ /// Single-line documentation comment.
+ fld3_1 ??= ((loc1 ?? foo1_2(fld3_0[(var2--)])) ?? foo1_2(foo1_3()));
+ }
+ }
+ }
+ return (var1 ? (!(var1)) : var1);
+ }
+
+ String foo3_1(int par1, String par2, String par3) {
+ switch (var2) {
+ case 3768780679:
+ {
+ {
+ int loc0 = (++par1);
+ var0 ??= ListBase.listToString(var5);
+ if (true) {
+ var5 = [
+ Float32x4.xyxz,
+ (var1
+ ? ((!(false)) ? Float32x4.xyyw : (++fld3_2))
+ : var5[fld3_2]),
+ par1,
+ (~(Float32x4.zxwy)),
+ if ((foo3_0(var3)
+ ? ([
+ (++fld3_2),
+ ...[
+ ...[
+ var5[(true ? Float32x4.xxzx : (--fld3_2))],
+ 54,
+ (-((((foo3_0(var3)
+ ? (!(false))
+ : ((var1 ? (~(-63)) : var5[-40]))
+ .isOdd)
+ ? ((0.8329420640871532 != var3) && var1)
+ : var1)
+ ? 43
+ : (Float32x4.zxxy - Float32x4.zxxw)))),
+ Int32x4.zzwx
+ ],
+ ...[
+ (var5[-48] * (fld3_2++)),
+ Int32x4.wyyw,
+ (~(-76)),
+ ((par1).isEven ? (--par1) : -13),
+ Float32x4.wxyx
+ ],
+ for (int loc1 in [
+ (++fld3_2),
+ -15,
+ (SecurityContext.alpnSupported
+ ? Int32x4.yxyw
+ : Float32x4.yxxw),
+ if (true) var5[(var1 ? -32768 : par1)],
+ ((--var2) ^ (++fld3_2))
+ ])
+ (fld3_2--),
+ 93,
+ (~((-(ZLibOption.minMemLevel)))),
+ ((Float32x4.zyzx >> -14) & Float32x4.yxxw)
+ ],
+ (var1
+ ? (++par1)
+ : ((var3).isInfinite ? Float32x4.zwww : -84)),
+ var2
+ ] ==
+ [
+ 9223372032559808639,
+ -85,
+ Float32x4.wzyy,
+ loc0,
+ [
+ ((-(36)) <<
+ ((var1
+ ? var1
+ : ({
+ 45: 'ay',
+ 7: par3,
+ 69: Uri.decodeFull(
+ (foo1_3() + 'LX+'))
+ })
+ .isEmpty)
+ ? (~((13 | 64)))
+ : (-(var2)))),
+ (par1--),
+ ((~((true ? (var2--) : -31))) >> 9),
+ (-((35 % (~(var5[var5[39]]))))),
+ 4395630341,
+ Int32x4.zxxy,
+ if ((var1
+ ? foo3_0(var3)
+ : (0.6201792653929837).isInfinite)) ...[
+ Int32x4.wxxx,
+ (fld3_2 * (--fld3_2)),
+ var5[((~(var5[var5[var5[(-(-23))]]])) +
+ (~(-4294966296)))],
+ loc0,
+ for (int loc1 in [var5[Float32x4.yzww]]) 17,
+ (~(var5[(++par1)])),
+ -58,
+ ((!(('').isEmpty))
+ ? ((-(Float32x4.ywwx)) * (++par1))
+ : Int32x4.yxyz)
+ ]
+ ][((var1 ? var1 : var1) ? var5[0] : par1)],
+ ((~(70)) +
+ (par1 + (-77 | ZLibOption.MAX_WINDOW_BITS))),
+ (-(Int32x4.zywy)),
+ (~(Float32x4.zywz))
+ ])
+ : (var1 ? true : true)))
+ fld3_2
+ ];
+ }
+ }
+ var3 *= ((var3 + 0.6761038672016147) ?? (-(double.minPositive)));
+ }
+ break;
+ case 3768780685:
+ {
+ {
+ int loc0 = 67;
+ while (--loc0 > 0) {
+ {
+ Map<int, String> loc1 = foo1(
+ Uri.parseIPv4Address(('E Hu\u{1f600}' + '\u2665l&#!')),
+ (!(false)));
+ var3 ??= var3;
+ }
+ var5 = (var5 +
+ ((({
+ 79: (foo1_3() ?? 'eD'),
+ 73: (var1 ? par2 : ' xdXgW'),
+ 4: 'pUc(q',
+ 15: 'K\u{1f600}hmdZ\u2665',
+ 95: (var1 ? var4 : (var1 ? fld3_0[-45] : foo1_3()))
+ })
+ .isNotEmpty
+ ? ((var1 ? var1 : (var1 ? var1 : foo3_0(var3))) ||
+ foo3_0(var3))
+ : (!(((false || true) ? var1 : false))))
+ ? [
+ (~((-61 ??
+ (~((-(var5[(var1 ? fld3_2 : var5[34])]))))))),
+ (var5[13] ^ (var1 ? 35 : -76)),
+ (-(((~(-47)) ~/ (--par1))))
+ ]
+ : foo2({
+ -36,
+ ((0.3910802543332075).isNegative
+ ? (~((var2++)))
+ : (var2 &
+ (var1
+ ? [
+ -67,
+ (fld3_2++),
+ if ((!((!((var1
+ ? true
+ : (!(false))))))))
+ (false
+ ? (~(Float32x4.wyyy))
+ : (var1
+ ? (1 ^ (-(16)))
+ : var5[94])),
+ fld3_2,
+ var2,
+ 67
+ ][-12]
+ : Float32x4.wwxw))),
+ 26,
+ [
+ (var1
+ ? (--fld3_2)
+ : (((!(var1))
+ ? (~((foo3_0(0.9959805940480148)
+ ? (33 ~/ loc0)
+ : Float32x4.xywx)))
+ : (15 % var5[var5[-47]])) <<
+ -86)),
+ (-((~(RawSocketOption.levelIPv6))))
+ ][var5[var5[(ZLibOption.maxMemLevel ^ -3)]]],
+ -29
+ }, [
+ (var1 ? Float32x4.wxxw : (--par1)),
+ ...[
+ 52,
+ (-((true ? -12 : 44))),
+ var5[((var5[34] * 30) >> 4294967360)],
+ ((--var2) <<
+ (true
+ ? var5[(-4 ~/ Int32x4.yyww)]
+ : (bool.fromEnvironment(var7[fld3_2])
+ ? (~((false ? loc0 : var5[(++par1)])))
+ : ((!(false))
+ ? (var5[var5[loc0]] ^ Int32x4.wxzz)
+ : par1)))),
+ (((false ? var0 : '') !=
+ (true
+ ? MapBase.mapToString(({
+ 7: 'WTT7\u{1f600}e3',
+ 22: '',
+ 36: (var1
+ ? 'F'
+ : (var1 ? fld3_0[var2] : '')),
+ 37: 'l@a',
+ 85: (var1 ? '' : par3),
+ 82: 'eb',
+ 37: '11',
+ 41: var7[94]
+ } ??
+ var7))
+ : (var1 ? var4 : par2)))
+ ? (~(var5[-71]))
+ : 9),
+ 32,
+ if (bool.fromEnvironment(
+ fld3_0[var5[ZLibOption.MIN_MEM_LEVEL]]))
+ var5[(--par1)],
+ (par1--)
+ ],
+ for (int loc1 in {
+ for (int loc2 in [
+ ((!((Map.unmodifiable({
+ 86: var4,
+ 31: var0,
+ 85: (par3 + ''),
+ 91: (var1
+ ? fld3_0[4]
+ : '!M\u{1f600}!vOw'),
+ 45: '7T',
+ 19: 'fha+',
+ 38: (false ? '' : fld3_0[70])
+ }) !=
+ {
+ 92: '@4',
+ 41: var7[loc0],
+ 24: (foo3_0(0.06591134699771606)
+ ? '\u2665)\u2665NnO+'
+ : 'JM3Hn\u{1f600}'),
+ 26: 'aQ51Yz',
+ 64: var7[
+ (-((var5[18] & (36).bitLength)))]
+ })))
+ ? (89 ^
+ (((44 - par1) * -9223372034707292160) &
+ var5[128]))
+ : -46),
+ (fld3_2++),
+ ((([
+ -89,
+ var2,
+ (fld3_2++),
+ var5[-4294967264],
+ -25,
+ var2,
+ var5[((!(var1))
+ ? (var1 ? -3 : -81)
+ : var5[loc0])],
+ (var1
+ ? par1
+ : ((~((fld3_2++))) >>
+ (-((-(-64))))))
+ ] ??
+ foo2(var6, [
+ 4295032831
+ ], {
+ 53: foo1_3(),
+ 94: var7[13],
+ 82: var7[-60],
+ 30: fld3_0[-9223372032559742976],
+ 98: foo1_3()
+ })) !=
+ var5)
+ ? (--par1)
+ : loc0),
+ 56,
+ if (((var5[21]).isOdd ? true : false))
+ ((++par1) -
+ (var1 ? var5[DateTime.january] : (par1--)))
+ else
+ fld3_2,
+ if ((!(var1))) 74,
+ (par1 ^ var5[26])
+ ])
+ (~(var2)),
+ for (int loc2 in {
+ 6442450944,
+ Float32x4.ywyw,
+ -9223372032559804416,
+ (~(var5[var5[26]])),
+ Float32x4.xyxy,
+ (--fld3_2),
+ var5[98]
+ })
+ if (false) -26,
+ (~((-((-((-48 - -9223372036854775680))))))),
+ ...{
+ (-((var2--))),
+ if (true) -100663046 else var5[(~(par1))]
+ },
+ (~((~((fld3_2++))))),
+ ...{
+ ((List.filled(0, 26) ==
+ [
+ (-(-52)),
+ -29,
+ (--fld3_2),
+ (0.22302566014161784).floor(),
+ (par1 % -56)
+ ])
+ ? (var1
+ ? (var2++)
+ : ((!((!(true))))
+ ? ((var1 || foo3_0(var3)) ? 76 : par1)
+ : (-(-13))))
+ : ((foo1_0((var1 ? fld3_0 : var7), var7,
+ var3))
+ .isEmpty
+ ? 97
+ : (var1 ? var2 : -9223372036854774784))),
+ (-(Float32x4.zyzw)),
+ (--var2)
+ }
+ })
+ ((var3 < (-(var3))) ? -9223372032559808000 : -71),
+ -100663046,
+ if ((var1
+ ? bool.fromEnvironment('vV0')
+ : (Map.from({
+ 78: '',
+ 49: '\u{1f600}\u{1f600}4Mz',
+ 70: fld3_0[par1],
+ 95: '\u{1f600}2tIYqE',
+ 43: (true ? 'baf-\u2665' : var4),
+ 30: var7[(-((-68 % ZLibOption.defaultLevel)))]
+ }))
+ .isNotEmpty))
+ -13
+ else
+ (var1 ? (-((-(var5[56])))) : (var2--)),
+ (~((~((-((var2++)))))))
+ ], {
+ 88: ('bV\u{1f600}iqO').toLowerCase(),
+ 42: '(hZ4S',
+ 37: var7[-79],
+ 36: var0
+ })));
+ }
+ }
+ {
+ int loc0 = 0;
+ do {
+ try {
+ print(foo2(
+ fld3_1,
+ (fld3_0[var5[-12]]).codeUnits,
+ (({
+ 36: var4,
+ 30: '0\u{1f600}EYWqr',
+ 66: 'S',
+ 3: '+J3Gj',
+ 71: '\u{1f600}-q',
+ 13: 'V3QN',
+ 34: ''
+ } ??
+ {
+ 54: fld3_0[(var2--)],
+ 74: (foo3_0(
+ ((-(var3)) * (0.8613045491468889 + var3)))
+ ? var7[78]
+ : (((var1 ? (47).isEven : var1) ? true : true)
+ ? (var4 ?? 'UzK')
+ : 'fH1smd')),
+ 12: '\u2665',
+ 18: 'V'
+ }) ??
+ var7)));
+ } catch (exception, stackTrace) {
+ fld3_1 = foo0();
+ for (int loc1 = 0; loc1 < 29; loc1++) {
+ if (var1) {
+ {
+ int loc2 = 0;
+ do {
+ var5 = (foo3_0(var3)
+ ? [
+ ((--par1) ^ (~(93))),
+ if ((var3).isFinite)
+ for (int loc3 in [
+ -5,
+ Int32x4.zxyy,
+ (true
+ ? var5[var5[(var1 ? -23 : var5[68])]]
+ : -99),
+ ((!(var1))
+ ? ((false
+ ? var1
+ : foo3_0(0.3133865362301862))
+ ? Float64List.bytesPerElement
+ : [
+ Float32x4.yxzx,
+ if (var1)
+ (false ? 40 : 85)
+ else
+ ((String.fromCharCode((foo3_0(
+ 0.414460580942719)
+ ? var5[-14]
+ : var2)) ==
+ 'mII\u{1f600}zkM')
+ ? var5[(~(-51))]
+ : ((var1
+ ? (!(var1))
+ : var1)
+ ? var5[0]
+ : (-(var2))))
+ ][5])
+ : fld3_2),
+ (par1++),
+ -72,
+ Int32x4.zzxy
+ ])
+ Int32x4.zyww
+ else
+ Int32x4.wxyz
+ ]
+ : [
+ ...[
+ if ((false ? false : var1)) (-(52)),
+ (++par1),
+ (par1--),
+ (-((-([
+ (((var0 + fld3_0[(++var2)])).isNotEmpty
+ ? Float32x4.yzxw
+ : var5[35])
+ ][loc0])))),
+ (~(-17))
+ ],
+ 38,
+ ...[
+ (var1 ? (par1++) : -10),
+ if (true) -62 else var2,
+ if ((!((var3).isFinite)))
+ Int32x4.xxzz
+ else
+ -45
+ ],
+ if ((true || false)) (-(-93)),
+ (--fld3_2),
+ ([
+ (fld3_2--),
+ if ((base64UrlEncode(var5) == 'RY'))
+ (++fld3_2)
+ else
+ -9223372032559808383,
+ Float32x4.zyxy,
+ loc0,
+ -55,
+ if (('O \u{1f600}e\u2665').isNotEmpty)
+ if (var1)
+ (--var2)
+ else
+ for (int loc3 in {
+ loc0,
+ (~((--var2))),
+ (-(-35)),
+ Float32x4.xxyw,
+ 65,
+ -4,
+ -4194304251,
+ -54
+ })
+ (((0.671280258888436 ==
+ (0.16535430333243706 *
+ 0.18316039550464436)) ||
+ var1)
+ ? var5[12]
+ : (~((--var2))))
+ else if (false)
+ if (var1) (-(Int32x4.zzwx)) else loc2
+ else
+ Int32x4.yzyw
+ ][loc1] *
+ (--par1)),
+ (-71 * 38)
+ ]);
+ } while (++loc2 < 89);
+ }
+ } else {
+ {
+ int loc2 = 0;
+ do {
+ fld3_0 ??= ((((Map.unmodifiable(var7)).isEmpty ||
+ (!(({
+ 11: 'v+MHeiB',
+ 48: var7[(true
+ ? ((var2--) ?? fld3_2)
+ : var5[(fld3_2--)])],
+ 52: '(('
+ })
+ .isEmpty)))
+ ? fld3_0
+ : {
+ 39: foo1_3(),
+ 21: 'IXzJ+',
+ 76: 'K2C#',
+ 16: ('\u{1f600}Gh' + '#i'),
+ 62: foo1_3(),
+ 19: foo1_3(),
+ 32: par3,
+ for (int loc3 in [
+ (par1--),
+ -66,
+ -96,
+ -35,
+ Float32x4.zzyz
+ ])
+ 72: 'y vxi'
+ }) ??
+ {13: par2});
+ switch (4096) {
+ case 3159134388:
+ {
+ /// Single-line documentation comment.
+ {
+ int loc3 = 0;
+ do {
+ fld3_0 ??= foo1(
+ var5,
+ ((((true ? par2 : var7[var5[loc1]]))
+ .isNotEmpty
+ ? 9
+ : -55) !=
+ var5[-36]));
+ fld3_1 = foo0();
+ } while (++loc3 < 79);
+ }
+ }
+ break;
+ case 3159134393:
+ {
+ throw Int32x4.zxxw;
+ }
+ break;
+ }
+ } while (++loc2 < 77);
+ }
+ }
+ }
+ }
+ } while (++loc0 < 98);
+ }
+ }
+ break;
+ }
+ /*
+ * Multi-line
+ * comment.
+ */
+ return ((0.7728524536008519).isNaN ? 'BjzeSsJ' : foo1_3());
+ }
+
+ void run() {
+ super.run();
+ var5 ??= var5;
+ print({4294968296});
+ }
+}
+
+main() {
+ int count = 0;
+ try {
+ foo0();
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ foo1((' MQz').codeUnits, var1);
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ foo2(
+ (var6).toSet(),
+ (var1
+ ? [-9223372036854775681, -66, 9223372032559874047, -3, 74]
+ : var5),
+ Map.identity());
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X0().foo0_0(var7);
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X1().foo1_0(
+ (false
+ ? {
+ 7: 'QMNg',
+ 12: 'wzc5-Iq',
+ 63: '29an-z',
+ 86: 'sF5',
+ 59: '\u2665L',
+ 43: 'k',
+ 62: 'NvF\u{1f600}k',
+ 84: 'ZW 1-o'
+ }
+ : var7),
+ {
+ 28: '@smXqKl',
+ 66: 'oL',
+ if (false) 74: 'B' else 81: 'X',
+ if (false) 18: 'j' else 25: 'N',
+ 44: '\u{1f600}lrx8m',
+ 20: 'hC',
+ 73: 'q',
+ 63: '\u{1f600}nE'
+ },
+ 0.18875619647922648);
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X1().foo1_1((-((++var2))));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X1().foo1_2((var1
+ ? (false
+ ? (true ? var7[((!(var1)) ? var5[Int32x4.xxyx] : 3)] : var4)
+ : Uri.encodeComponent(('yd' ?? (var0).padLeft(1, 'Q'))))
+ : var7[-2147483649]));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X1().foo1_3();
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X2().foo2_0(Int32x4.xyyw);
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X2().foo2_1((!(((!(var1)) && (!((var1 ? false : var1)))))));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X2().foo2_2(var7, ((-(var5[(--var2)])) << 98));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X3().foo3_0(0.37767598562234317);
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X3().foo3_1(
+ -6, var0, (Uri.decodeComponent('yQg') + ((var4 ?? var4) + var0)));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X3().foo1_0(
+ Map.unmodifiable({77: 'hG'}),
+ ((false
+ ? {
+ 88: 'Sv-EbnG',
+ 73: 'G',
+ 46: 'O#',
+ 16: 'm1nf(',
+ 91: 'F',
+ 11: 'Q+O@K',
+ 70: '3q\u2665BJ'
+ }
+ : Map.identity()) ??
+ {
+ 68: 'r',
+ 56: 'IH&',
+ 31: '9cqu',
+ 49: '8ug',
+ 84: 'mR2VyC',
+ 41: 'gk&(asy'
+ }),
+ (var3 * sin(var3)));
+ } catch (e, st) {
+ count++;
+ }
+ try {
+ X3().run();
+ } catch (e, st) {
+ count++;
+ } finally {}
+ Expect.equals(-47639, var2);
+ Expect.equals(9, count);
+}
diff --git a/tests/legacy_status_dart2js.csv b/tests/legacy_status_dart2js.csv
new file mode 100644
index 0000000..5736318
--- /dev/null
+++ b/tests/legacy_status_dart2js.csv
@@ -0,0 +1,411 @@
+Condition,Test,Expectations,Comment,Issue,Issue state
+,codegen/gvn_dynamic_field_get_test,Fail,Issue 18519,https://dartbug.com/18519,open
+,codegen/list_tracer_length_test,Fail,Issue 33051,https://dartbug.com/33051,open
+,codegen/logical_expression_test,Fail,Issue 17027,https://dartbug.com/17027,open
+,codegen/side_effect_tdiv_regression_test,Fail,Issue 33050,https://dartbug.com/33050,open
+,codegen/simple_function_subtype_test,Fail,simple_function_subtype_test is temporarily(?) disabled due to new method for building function type tests.,,
+,end_to_end/generate_code_with_compile_time_errors_test,RuntimeError,not supported yet with the new FE.,,
+,end_to_end/show_package_warnings_test,RuntimeError,missing errors from the FE,,
+,inference/simple_inferrer_const_closure2_test,Fail,Issue 16507,https://dartbug.com/16507,open
+,inference/simple_inferrer_const_closure_test,Fail,Issue 16507,https://dartbug.com/16507,open
+,inference/simple_inferrer_global_field_closure_test,Fail,Issue 16507,https://dartbug.com/16507,open
+,sourcemaps/d2js_validity_test,RuntimeError,Issue 33072,https://dartbug.com/33072,open
+,sourcemaps/deferred_d2js_validity_test,RuntimeError,Issue 33072,https://dartbug.com/33072,open
+$compiler == dart2js,bounds_check4a_test,RuntimeError,Issue 32741,https://dartbug.com/32741,open
+$compiler == dart2js,bounds_check4b_test,RuntimeError,Issue 32741,https://dartbug.com/32741,open
+$compiler == dart2js,generic_class_is_test,Fail,Issue 32004,https://dartbug.com/32004,open
+$compiler == dart2js,jsinterop_test/01,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/02,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/03,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/04,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/34,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,jsinterop_test/35,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,jsinterop_test/36,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,jsinterop_test/37,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,jsinterop_test/38,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/42,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/43,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,jsinterop_test/44,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,jsinterop_test/45,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,jsinterop_test/46,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/51,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,jsinterop_test/52,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,jsinterop_test/53,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,jsinterop_test/54,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,many_instantiations_test/01,Crash,Issue 33819,https://dartbug.com/33819,open
+$compiler == dart2js,no_such_method_test,Fail,Wrong Invocation.memberName.,,
+$compiler == dart2js,non_jsinterop_test/01,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/02,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/03,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/04,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/34,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,non_jsinterop_test/35,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,non_jsinterop_test/36,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,non_jsinterop_test/37,MissingCompileTimeError,Issue 33834,https://dartbug.com/33834,open
+$compiler == dart2js,non_jsinterop_test/38,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/42,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/43,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,non_jsinterop_test/44,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,non_jsinterop_test/45,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,non_jsinterop_test/46,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/51,MissingCompileTimeError,Issue 34174,https://dartbug.com/34174,open
+$compiler == dart2js,non_jsinterop_test/52,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,non_jsinterop_test/53,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$compiler == dart2js,non_jsinterop_test/54,MissingCompileTimeError,Issue 34345,https://dartbug.com/34345,open
+$runtime == jsshell,timer_test,Fail,Issue 7728.,https://dartbug.com/7728,closed
+$runtime == none,timer_negative_test,"Fail, OK",A negative runtime test.,,
+$compiler == dart2js && $runtime == d8,deferred_fail_and_retry_test,RuntimeError,Uses XHR in dart:html,,
+$compiler == dart2js && $runtime == d8,deferred_with_csp_nonce_test,RuntimeError,Uses dart:html,,
+$compiler == dart2js && $runtime == none,*,"Fail, Pass",TODO(ahe): Triage these tests.,,
+$compiler == dart2js && $csp,js_interop_optional_arg_test,RuntimeError,Issue 31082,https://dartbug.com/31082,open
+$compiler == dart2js && $csp,js_interop_test,RuntimeError,Issue 31082,https://dartbug.com/31082,open
+$compiler == dart2js && $minified,closure_capture2_test,Pass,Passes for the wrong reason,,
+$compiler == dart2js && $minified,deferred/reflect_multiple_annotations_test,Crash,NoSuchMethodError: The getter 'closureClassEntity' was called on null.,,
+$compiler == dart2js && $minified,deferred/reflect_multiple_default_arg_test,Crash,NoSuchMethodError: The getter 'closureClassEntity' was called on null.,,
+$compiler == dart2js && $minified,mirrors_used_warning_test/minif,"Fail, OK",Tests warning that minified code will be broken.,,
+$compiler == dart2js && $minified,runtime_type_test,"Fail, OK",Tests extected output of Type.toString().,,
+$compiler == dart2js && $minified,to_string_test,Fail,Issue 7179.,https://dartbug.com/7179,closed
+$compiler == dart2js && $minified,type_literal_test,"Fail, OK",Tests expected output of Type.toString().,,
+$compiler == dart2js && $minified,typevariable_typedef_test,"Fail, OK",Tests expected output of Type.toString().,,
+$compiler == dart2js && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari),isolate2_test/01,Fail,Issue 14458.,https://dartbug.com/14458,closed
+$compiler == none && $runtime == vm,invalid_annotation_test/01,"MissingCompileTimeError, OK",vm is lazy,,
+$compiler == dart2js,fake_thing_test,RuntimeError,Issue 13010,https://dartbug.com/13010,open
+$compiler == dart2js,field_type2_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,field_type_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,native_exceptions1_frog_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,native_mixin_with_plain_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,native_window1_frog_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,native_window2_frog_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js,subclassing_constructor_1_test,CompileTimeError,Issue 33762,https://dartbug.com/33762,open
+$compiler == dart2js && $minified,optimization_hints_test,"RuntimeError, OK",Test relies on unminified names.,,
+$compiler == dart2js,arithmetic_int64_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,async_star_cancel_while_paused_test,RuntimeError,Issue 22853,https://dartbug.com/22853,open
+$compiler == dart2js,bit_operations_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js,bit_operations_test/03,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,bit_operations_test/04,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,bit_operations_test/none,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,call_method_must_not_be_field_test/03,RuntimeError,Issue 32155,https://dartbug.com/32155,closed
+$compiler == dart2js,call_method_must_not_be_getter_test/03,RuntimeError,Issue 32155,https://dartbug.com/32155,closed
+$compiler == dart2js,canonical_const2_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js,closure_type_arguments_test,Crash,Issue 34272,https://dartbug.com/34272,open
+$compiler == dart2js,config_import_corelib_test,CompileTimeError,"we need a special platform.dill file for categories=all. Once we fix that, all dart:* are supported when using '--categories=all' so this will become a RuntimeError, OK.",,
+$compiler == dart2js,config_import_test,RuntimeError,Test flag is not passed to the compiler.,,
+$compiler == dart2js,const_constructor3_test/04,MissingCompileTimeError,OK - Subtype check uses JS number semantics.,,
+$compiler == dart2js,const_dynamic_type_literal_test/03,Pass,but it shouldn't until we fix issue 17207,https://dartbug.com/17207,open
+$compiler == dart2js,const_switch_test/02,"RuntimeError, OK",constant identity based on JS constants,,
+$compiler == dart2js,const_switch_test/04,"RuntimeError, OK",constant identity based on JS constants,,
+$compiler == dart2js,covariant_subtyping_test,Crash,Unsupported operation: Unsupported type parameter type node E.,,
+$compiler == dart2js,deferred_not_loaded_check_test,RuntimeError,Test out of date. Issue 31933,https://dartbug.com/31933,open
+$compiler == dart2js,deopt_inlined_function_lazy_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,deopt_smi_op_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,double_identical_test,RuntimeError,"Negative and positive zero are distinct, but not in dart2js; bug #11551.",https://dartbug.com/11551,open
+$compiler == dart2js,double_int_to_string_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js,expect_test,"RuntimeError, OK",Issue 13080,https://dartbug.com/13080,closed
+$compiler == dart2js,external_test/10,CompileTimeError,External non-js-interop function are treated as compile-time errors.,,
+$compiler == dart2js,external_test/13,CompileTimeError,External non-js-interop function are treated as compile-time errors.,,
+$compiler == dart2js,external_test/20,CompileTimeError,External non-js-interop function are treated as compile-time errors.,,
+$compiler == dart2js,full_stacktrace1_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,full_stacktrace2_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,full_stacktrace3_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,guess_cid_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,identical_closure2_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js,identical_closure2_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,infinity_test,RuntimeError,non JS number semantics - Issue 4984,https://dartbug.com/4984,closed
+$compiler == dart2js,int2_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/01,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/02,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/04,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/05,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/06,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/11,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/12,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/14,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/16,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/17,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/19,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,int64_literal_test/none,"RuntimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,integer_division_by_zero_test,RuntimeError,Issue 8301,https://dartbug.com/8301,closed
+$compiler == dart2js,issue23244_test,RuntimeError,Isolates - enum canonicalization - Issue 23244,https://dartbug.com/23244,closed
+$compiler == dart2js,left_shift_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js,library_env_test/has_io_support,"RuntimeError, OK",dart2js doesn't support io when compiling on --categories=Client,,
+$compiler == dart2js,library_env_test/has_mirror_support,Fail,mirrors not supported on web,,
+$compiler == dart2js,library_env_test/has_no_mirror_support,Pass,fails for the wrong reason.,,
+$compiler == dart2js,mint_arithmetic_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,mint_arithmetic_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js,mint_compares_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,mint_identical_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,mock_writable_final_field_test,RuntimeError,Issue 30847,https://dartbug.com/30847,closed
+$compiler == dart2js,modulo_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js,nan_identical_test,RuntimeError,Issue 11551,https://dartbug.com/11551,open
+$compiler == dart2js,number_identity_test,"CompileTimeError, OK","Error if web int literal cannot be represented exactly, see http://dartbug.com/33351",https://dartbug.com/33351,closed
+$compiler == dart2js,numbers_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js,partial_instantiation_eager_bounds_check_test,RuntimeError,Issue #34295,https://dartbug.com/34295,open
+$compiler == dart2js,partial_tearoff_instantiation_test/05,Pass,for the wrong reason.,,
+$compiler == dart2js,partial_tearoff_instantiation_test/06,Pass,for the wrong reason.,,
+$compiler == dart2js,partial_tearoff_instantiation_test/07,Pass,for the wrong reason.,,
+$compiler == dart2js,partial_tearoff_instantiation_test/08,Pass,for the wrong reason.,,
+$compiler == dart2js,regress_24283_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js,stacktrace_demangle_ctors_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,stacktrace_rethrow_error_test/none,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,stacktrace_rethrow_error_test/withtraceparameter,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,stacktrace_rethrow_nonerror_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js,truncdiv_zero_test,RuntimeError,non JS number semantics - Issue 15246,https://dartbug.com/15246,closed
+$compiler == dart2js,type_constants_test/none,RuntimeError,Issue 35052,https://dartbug.com/35052,open
+$builder_tag == dart2js_production && $compiler == dart2js,control_flow_collections/for_non_bool_condition_test,Crash,Issue 36442,https://dartbug.com/36442,
+$compiler == dart2js && $runtime == chrome && $system == macos,await_future_test,"Pass, Timeout",Issue 26735,https://dartbug.com/26735,closed
+$compiler == dart2js && $runtime == ff,round_test,"Pass, Fail, OK",Fixed in ff 35. Common JavaScript engine Math.round bug.,,
+$compiler == dart2js && $runtime == jsshell,async_call_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async_star_await_pauses_test,RuntimeError,Need triage,,
+$compiler == dart2js && $runtime == jsshell,async_star_no_cancel2_test,RuntimeError,Need triage,,
+$compiler == dart2js && $runtime == jsshell,async_star_no_cancel_test,RuntimeError,Need triage,,
+$compiler == dart2js && $runtime == jsshell,regress_23996_test,RuntimeError,"Jsshell does not provide non-zero timers, Issue 7728",https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime != none && $checked,syncstar_covariant_type_test,RuntimeError,"dart2js misplaces check in Iterator, not Iterable.",,
+$compiler == dart2js && $runtime != none && $checked,syncstar_dcall_type_test,RuntimeError,"dart2js misplaces check in Iterator, not Iterable.",,
+$compiler == dart2js && $runtime == safari,round_test,"Fail, OK",Common JavaScript engine Math.round bug.,,
+$compiler == dart2js && $system == windows,string_literals_test,"Pass, RuntimeError",Failures on dart2js-win7-chrome-4-4-be and dart2js-win7-ie11ff-4-4-be,,
+$compiler == dart2js && $checked,canonical_const2_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js && $checked,const_switch_test/02,"RuntimeError, OK",constant identity based on JS constants,,
+$compiler == dart2js && $checked,const_switch_test/04,"RuntimeError, OK",constant identity based on JS constants,,
+$compiler == dart2js && $checked,deferred_not_loaded_check_test,RuntimeError,Test out of date. Issue 31933,https://dartbug.com/31933,open
+$compiler == dart2js && $checked,double_int_to_string_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js && $checked,expect_test,"RuntimeError, OK",Issue 13080,https://dartbug.com/13080,closed
+$compiler == dart2js && $checked,full_stacktrace1_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,full_stacktrace2_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,full_stacktrace3_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,generalized_void_syntax_test,CompileTimeError,Issue #30176.,https://dartbug.com/30176,open
+$compiler == dart2js && $checked,generic_function_dcall_test/01,Crash,Unsupported operation: Unsupported type parameter type node T.,,
+$compiler == dart2js && $checked,generic_tearoff_test,Crash,Unsupported operation: Unsupported type parameter type node T.,,
+$compiler == dart2js && $checked,identical_closure2_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js && $checked,infinity_test,RuntimeError,non JS number semantics - Issue 4984,https://dartbug.com/4984,closed
+$compiler == dart2js && $checked,integer_division_by_zero_test,RuntimeError,Issue 8301,https://dartbug.com/8301,closed
+$compiler == dart2js && $checked,invocation_mirror2_test,RuntimeError,mirrors not supported,,
+$compiler == dart2js && $checked,left_shift_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js && $checked,mint_arithmetic_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js && $checked,mock_writable_final_field_test,RuntimeError,Issue 30847,https://dartbug.com/30847,closed
+$compiler == dart2js && $checked,modulo_test,RuntimeError,non JS number semantics,,
+$compiler == dart2js && $checked,nan_identical_test,RuntimeError,Issue 11551,https://dartbug.com/11551,open
+$compiler == dart2js && $checked,numbers_test,"RuntimeError, OK",non JS number semantics,,
+$compiler == dart2js && $checked,regress_27617_test/1,Crash,Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant,,
+$compiler == dart2js && $checked,regress_30339_test,RuntimeError,Issue 26429,https://dartbug.com/26429,closed
+$compiler == dart2js && $checked,regress_31057_test,Crash,Unsupported operation: Unsupported type parameter type node B.,,
+$compiler == dart2js && $checked,stacktrace_demangle_ctors_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,stacktrace_rethrow_error_test/none,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,stacktrace_rethrow_error_test/withtraceparameter,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,stacktrace_rethrow_nonerror_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,stacktrace_test,RuntimeError,Issue 12698,https://dartbug.com/12698,closed
+$compiler == dart2js && $checked,truncdiv_zero_test,RuntimeError,non JS number semantics - Issue 15246,https://dartbug.com/15246,closed
+$compiler == dart2js && $checked,type_parameter_test/06,Crash,Internal Error: Unexpected type variable in static context.,,
+$compiler == dart2js && $checked,type_parameter_test/09,Crash,Internal Error: Unexpected type variable in static context.,,
+$compiler == dart2js && $checked,type_variable_scope_test/03,Crash,Internal Error: Unexpected type variable in static context.,,
+$compiler == dart2js && $host_checked,async_return_types_test/nestedFuture,Crash,file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||,,
+$compiler == dart2js && $host_checked,async_star_cancel_while_paused_test,Crash,file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||,,
+$compiler == dart2js && $host_checked,await_not_started_immediately_test,Crash,Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).,,
+$compiler == dart2js && $host_checked,closure_self_reference_test,Crash,file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.,,
+$compiler == dart2js && $host_checked,issue23244_test,Crash,file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||,,
+$compiler == dart2js && $host_checked,partial_tearoff_instantiation_test/05,Crash,"Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)",,
+$compiler == dart2js && $host_checked,partial_tearoff_instantiation_test/06,Crash,"Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)",,
+$compiler == dart2js && $host_checked,partial_tearoff_instantiation_test/07,Crash,"Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)",,
+$compiler == dart2js && $host_checked,partial_tearoff_instantiation_test/08,Crash,"Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)",,
+$compiler == dart2js && $minified,async_return_types_test/nestedFuture,Crash,"Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]",https://dartbug.com/1,closed
+$compiler == dart2js && $minified,async_star_cancel_while_paused_test,Crash,"Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]",https://dartbug.com/1,closed
+$compiler == dart2js && $minified,await_not_started_immediately_test,Crash,Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).,,
+$compiler == dart2js && $minified,cyclic_type2_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,cyclic_type_test/0*,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,f_bounded_quantification4_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,f_bounded_quantification5_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,generic_closure_test/01,RuntimeError,Uses runtimeType.toString(),,
+$compiler == dart2js && $minified,invocation_mirror2_test,RuntimeError,mirrors not supported,,
+$compiler == dart2js && $minified,issue23244_test,Crash,"Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]",https://dartbug.com/1,closed
+$compiler == dart2js && $minified,mixin_generic_test,RuntimeError,Issue 12605,https://dartbug.com/12605,closed
+$compiler == dart2js && $minified,mixin_mixin2_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin3_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin4_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin5_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin6_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin_bound2_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin_bound_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,mixin_mixin_type_arguments_test,RuntimeError,Issue 31054,https://dartbug.com/31054,open
+$compiler == dart2js && $minified,regress_21795_test,RuntimeError,Issue 12605,https://dartbug.com/12605,closed
+$compiler == dart2js && $minified,runtime_type_function_test,RuntimeError,Uses runtimeType.toString(),,
+$compiler == dart2js && $minified,stack_trace_test,"RuntimeError, OK",Stack trace not preserved in minified code.,,
+$compiler == dart2js && $minified,symbol_conflict_test,RuntimeError,Issue 23857,https://dartbug.com/23857,open
+$compiler == dart2js && $runtime == chrome,html/element_types_keygen_test,RuntimeError,Issue 29055,https://dartbug.com/29055,open
+$compiler == dart2js && $runtime == chrome,html/media_stream_test,RuntimeError,Please triage.,,
+$compiler == dart2js && $runtime == chrome,html/speechrecognition_test,RuntimeError,Please triage.,,
+$compiler == dart2js && $runtime == chrome && $csp,html/worker_test/functional,RuntimeError,Issue 32261,https://dartbug.com/32261,closed
+$compiler == dart2js && $runtime == chromeOnAndroid,html/audiobuffersourcenode_test/supported,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/audiocontext_test/supported,RuntimeError,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/canvasrenderingcontext2d_test/drawImage_video_element,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/canvasrenderingcontext2d_test/fillText,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/element_types_datalist_test,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/input_element_week_test,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/media_stream_test,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/rtc_test,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/speechrecognition_test,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,html/xhr_test/json,Fail,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,typed_data/setRange_2_test,RuntimeError,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime == chromeOnAndroid,typed_data/setRange_3_test,RuntimeError,TODO(dart2js-team): Please triage this failure.,,
+$compiler == dart2js && $runtime != d8,html/html_mock_test,RuntimeError,Issue 31038,https://dartbug.com/31038,open
+$compiler == dart2js && $runtime == ff,html/element_animate_test/timing_dict,RuntimeError,Issue 26730,https://dartbug.com/26730,open
+$compiler == dart2js && $runtime == ff,html/element_types_content_test,"Pass, RuntimeError","Issues 28983, 29922",,
+$compiler == dart2js && $runtime == ff,html/element_types_keygen_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ff,html/element_types_shadow_test,"Pass, RuntimeError","Issues 28983, 29922",,
+$compiler == dart2js && $runtime == ff,html/fontface_test,Fail,Fontface not supported on ff,,
+$compiler == dart2js && $runtime == ff,html/interactive_media_test,RuntimeError,Not supported in FF,,
+$compiler == dart2js && $runtime == ff,html/messageevent_test,"Pass, RuntimeError",Issue 28983,https://dartbug.com/28983,closed
+$compiler == dart2js && $runtime == ff,html/serialized_script_value_test,"Pass, RuntimeError",Issue 28983,https://dartbug.com/28983,closed
+$compiler == dart2js && $runtime == ff,html/speechrecognition_test,RuntimeError,Please triage.,,
+$compiler == dart2js && $runtime == ff,html/text_event_test,Fail,Issue 17893,https://dartbug.com/17893,closed
+$compiler == dart2js && $runtime == ff,html/webgl_1_test,"Pass, Fail",Issue 8219,https://dartbug.com/8219,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_content_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_datalist_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_details_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_embed_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_keygen_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_meter_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_object_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_output_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_progress_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_shadow_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_template_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == ie11,html/element_types_track_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors12_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors13_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors14_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors15_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors18_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors19_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors20_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors22_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors28_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/catch_errors8_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/future_constructor2_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/future_test,RuntimeError,Timer interface not supported; Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/multiple_timer_test,"RuntimeError, OK",Needs Timer to run.,,
+$compiler == dart2js && $runtime == jsshell,async/periodic_timer2_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/periodic_timer3_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/periodic_timer4_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/run_zoned7_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/run_zoned8_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/schedule_microtask_test,Fail,Preamble file does not correctly implement scheduleImmediate.,,
+$compiler == dart2js && $runtime == jsshell,async/slow_consumer2_test,RuntimeError,Timer interface not supported; Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/slow_consumer3_test,RuntimeError,Timer interface not supported; Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/slow_consumer_test,RuntimeError,Timer interface not supported; Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_controller_async_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_controller_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_from_iterable_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic2_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic3_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic4_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic5_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic6_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_periodic_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_state_nonzero_timer_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_subscription_cancel_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_take_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_timeout_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/stream_transformation_broadcast_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_cancel1_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_cancel2_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_cancel_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_isActive_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_repeat_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/timer_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/zone_bind_test,Fail,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/zone_create_periodic_timer_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/zone_create_timer2_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == jsshell,async/zone_empty_description2_test,RuntimeError,Timer interface not supported: Issue 7728.,https://dartbug.com/7728,closed
+$compiler == dart2js && $runtime == safari,html/css_test/functional/functional,RuntimeError,Issue 32576,https://dartbug.com/32576,closed
+$compiler == dart2js && $runtime == safari,html/element_types_content_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == safari,html/element_types_datalist_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == safari,html/element_types_shadow_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $runtime == safari,html/notification_test,"Pass, RuntimeError",Safari doesn't let us access the fields of the Notification to verify them.,,
+$compiler == dart2js && $runtime == safari,html/storage_promise_test,RuntimeError,Not supported on Safari,,
+$compiler == dart2js && $browser,html/notification_permission_test,"Timeout, Pass",Issue 32002,https://dartbug.com/32002,open
+$compiler == dart2js && $browser,js/null_test,RuntimeError,Issue 30652,https://dartbug.com/30652,open
+$compiler == dart2js && $browser && $csp,html/custom/element_upgrade_test,Fail,Issue 17298,https://dartbug.com/17298,closed
+$compiler == dart2js && $browser && $csp,html/custom/js_custom_test,Fail,Issue 14643,https://dartbug.com/14643,open
+$compiler == dart2js && !$csp && $minified,html/audiobuffersourcenode_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/audiocontext_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/cache_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/custom_element_method_clash_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/custom_element_name_clash_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/custom_elements_23127_test,Crash,"Assertion failure: Cannot find value local(B2T.created#a) in (type_variable_local(B2T.T), local(C2T.created#a), local(C2T.created#b), local(C2T.created#c), BoxLocal(_box_0)) for j:constructor(C2T.created).",,
+$compiler == dart2js && !$csp && $minified,html/custom_tags_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/dart_object_local_storage_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/datalistelement_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/document_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/documentfragment_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/dom_constructors_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/domparser_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_add_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_animate_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_constructor_1_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_dimensions_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_offset_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_constructors2_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_constructors3_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_constructors4_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_constructors5_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_constructors6_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/element_types_content_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_datalist_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_details_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_embed_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_meter_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_object_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_output_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_progress_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_shadow_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_template_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/element_types_track_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && !$csp && $minified,html/form_data_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/history_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/indexeddb_1_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/keyboard_event_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/mediasource_test,"RuntimeError, Crash",NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/mutationobserver_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/node_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/node_validator_important_if_you_suppress_make_the_bug_critical_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/notification_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/performance_api_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/range_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/request_animation_frame_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/rtc_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/shadow_dom_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/svg_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/svgelement_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/transition_event_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/trusted_html_tree_sanitizer_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/typed_arrays_1_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/webgl_extensions_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/websocket_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && !$csp && $minified,html/websql_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $host_checked,html/custom/mirrors_2_test,Crash,file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.,,
+$compiler == dart2js && $host_checked,html/custom/mirrors_test,Crash,file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.,,
+$compiler == dart2js && $host_checked,html/indexeddb_3_test,Crash,file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.,,
+$compiler == dart2js && $host_checked,html/indexeddb_5_test,Crash,file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.,,
+$compiler == dart2js && $host_checked,html/js_function_getter_test/call getter as function,Crash,FileSystemException(uri=file:///usr/local/google/home/efortuna/dart2/sdk/sdk/lib/_internal/dart2js_platform.dill; message=Error reading 'sdk/lib/_internal/dart2js_platform.dill' (No such file or directory)),,
+$compiler == dart2js && $host_checked,html/js_typed_interop_side_cast_exp_test,Crash,file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.,,
+$compiler == dart2js && $ie,html/fontface_loaded_test,RuntimeError,FontFace polyfill?,,
+$compiler == dart2js && $ie,html/fontface_test,Fail,Fontface not supported on ie,,
+$compiler == dart2js && $minified,html/canvas_pixel_array_type_alias_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/canvas_pixel_array_type_alias_test/types2_runtimeTypeName,"Fail, OK",Issue 12605,https://dartbug.com/12605,closed
+$compiler == dart2js && $minified,html/custom/mirrors_2_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/custom/mirrors_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/custom_elements_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/element_classes_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/element_types_keygen_test,RuntimeError,Issue 29922,https://dartbug.com/29922,closed
+$compiler == dart2js && $minified,html/js_function_getter_trust_types_test,Crash,NoSuchMethodError: Class 'InterfaceType' has no instance getter 'isObject'.,,
+$compiler == dart2js && $minified,html/js_typed_interop_bind_this_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/js_typed_interop_side_cast_exp_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/js_typed_interop_window_property_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/js_util_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/media_stream_test,"RuntimeError, Crash",NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/postmessage_structured_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/speechrecognition_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && $minified,html/webgl_1_test,Crash,NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.,,
+$compiler == dart2js && ($runtime == ff || $runtime == safari || $ie),html/custom/attribute_changed_callback_test/unsupported_on_polyfill,Fail,Polyfill does not support,,
+$compiler == dart2js && ($runtime == ff || $runtime == safari || $ie),html/custom/entered_left_view_test/viewless_document,Fail,Polyfill does not handle this,,
diff --git a/tests/lib_2/html/rtc_test.dart b/tests/lib_2/html/rtc_test.dart
index 8819d22..6b3c3581 100644
--- a/tests/lib_2/html/rtc_test.dart
+++ b/tests/lib_2/html/rtc_test.dart
@@ -27,10 +27,7 @@
]
});
expect(pc is RtcPeerConnection, isTrue);
- // TODO(efortuna): Uncomment this test when RTCPeerConnection correctly
- // implements EventListener in Firefox (works correctly in nightly, so
- // it's coming!).
- //pc.onIceCandidate.listen((candidate) {});
+ pc.onIceCandidate.listen((candidate) {});
});
test('ice candidate', () {
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index e1c07ea..cc91517 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -23,6 +23,7 @@
isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
profiler/metrics_num_test: Skip # Because of an int / double type test.
+wasm/*: SkipByDesign # dart:wasm not currently supported on web.
[ $compiler != dart2js ]
async/dart2js_uncaught_error_test: Skip # JS-integration only test
@@ -32,36 +33,14 @@
convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
-html/element_types_keygen_test: RuntimeError # Issue 29055
-html/media_stream_test: RuntimeError # Please triage.
-html/speechrecognition_test: RuntimeError # Please triage.
-
-[ $compiler == dart2js && $runtime == chrome && $csp ]
-html/worker_test/functional: RuntimeError # Issue 32261
[ $compiler == dart2js && $runtime == chromeOnAndroid ]
-html/audiobuffersourcenode_test/supported: Fail # TODO(dart2js-team): Please triage this failure.
-html/audiocontext_test/supported: RuntimeError # TODO(dart2js-team): Please triage this failure.
-html/canvasrenderingcontext2d_test/drawImage_video_element: Fail # TODO(dart2js-team): Please triage this failure.
-html/canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # TODO(dart2js-team): Please triage this failure.
-html/canvasrenderingcontext2d_test/fillText: Fail # TODO(dart2js-team): Please triage this failure.
-html/crypto_test/functional: Pass, Slow # TODO(dart2js-team): Please triage this failure.
-html/element_types_datalist_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/input_element_datetime_test: Pass, Slow # TODO(dart2js-team): Please triage this failure.
-html/input_element_week_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/media_stream_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/rtc_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/speechrecognition_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/xhr_test/json: Fail # TODO(dart2js-team): Please triage this failure.
-typed_data/setRange_2_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
-typed_data/setRange_3_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
+html/crypto_test/functional: Slow # TODO(dart2js-team): Please triage this failure.
+html/input_element_datetime_test: Slow # TODO(dart2js-team): Please triage this failure.
[ $compiler == dart2js && $runtime == d8 ]
html/event_callback_test: Skip # Browser test
-[ $compiler == dart2js && $runtime != d8 ]
-html/html_mock_test: RuntimeError # Issue 31038
-
[ $compiler == dart2js && $runtime == ff ]
async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
@@ -73,110 +52,23 @@
html/custom/created_callback_test: Skip # Times out
html/custom/document_register_basic_test: Skip # Times out, or unittest times out
html/dart_object_local_storage_test: Skip # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
-html/element_animate_test/timing_dict: RuntimeError # Issue 26730
-html/element_types_content_test: Pass, RuntimeError # Issues 28983, 29922
-html/element_types_keygen_test: RuntimeError # Issue 29922
-html/element_types_shadow_test: Pass, RuntimeError # Issues 28983, 29922
html/file_sample_test: Skip # FileSystem not supported on FireFox.
html/fileapi_supported_test: Skip # FileSystem not supported on FireFox.
html/fileapi_supported_throws_test: Skip # FileSystem not supported on FireFox.
-html/fontface_test: Fail # Fontface not supported on ff
html/history_test/history: Skip # Issue 22050
-html/interactive_media_test: RuntimeError # Not supported in FF
-html/messageevent_test: Pass, RuntimeError # Issue 28983
html/request_animation_frame_test: Skip # Async test hangs.
-html/serialized_script_value_test: Pass, RuntimeError # Issue 28983
-html/speechrecognition_test: RuntimeError # Please triage.
-html/text_event_test: Fail # Issue 17893
-html/webgl_1_test: Pass, Fail # Issue 8219
-
-[ $compiler == dart2js && $runtime == ie11 ]
-html/element_types_content_test: RuntimeError # Issue 29922
-html/element_types_datalist_test: RuntimeError # Issue 29922
-html/element_types_details_test: RuntimeError # Issue 29922
-html/element_types_embed_test: RuntimeError # Issue 29922
-html/element_types_keygen_test: RuntimeError # Issue 29922
-html/element_types_meter_test: RuntimeError # Issue 29922
-html/element_types_object_test: RuntimeError # Issue 29922
-html/element_types_output_test: RuntimeError # Issue 29922
-html/element_types_progress_test: RuntimeError # Issue 29922
-html/element_types_shadow_test: RuntimeError # Issue 29922
-html/element_types_template_test: RuntimeError # Issue 29922
-html/element_types_track_test: RuntimeError # Issue 29922
-
-[ $compiler == dart2js && $runtime == jsshell ]
-async/catch_errors12_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors13_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors14_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors15_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors18_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors19_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors20_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors22_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/catch_errors28_test: Fail # Timer interface not supported: Issue 7728.
-async/catch_errors8_test: Fail # Timer interface not supported: Issue 7728.
-async/future_constructor2_test: Fail # Timer interface not supported: Issue 7728.
-async/future_test: RuntimeError # Timer interface not supported; Issue 7728.
-async/multiple_timer_test: RuntimeError, OK # Needs Timer to run.
-async/periodic_timer2_test: Fail # Timer interface not supported: Issue 7728.
-async/periodic_timer3_test: Fail # Timer interface not supported: Issue 7728.
-async/periodic_timer4_test: Fail # Timer interface not supported: Issue 7728.
-async/run_zoned7_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/run_zoned8_test: Fail # Timer interface not supported: Issue 7728.
-async/schedule_microtask_test: Fail # Preamble file does not correctly implement scheduleImmediate.
-async/slow_consumer2_test: RuntimeError # Timer interface not supported; Issue 7728.
-async/slow_consumer3_test: RuntimeError # Timer interface not supported; Issue 7728.
-async/slow_consumer_test: RuntimeError # Timer interface not supported; Issue 7728.
-async/stream_controller_async_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_controller_test: Fail # Timer interface not supported: Issue 7728.
-async/stream_from_iterable_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic2_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic3_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic4_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic5_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic6_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_periodic_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_state_nonzero_timer_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_subscription_cancel_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_take_test: Fail # Timer interface not supported: Issue 7728.
-async/stream_timeout_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/stream_transformation_broadcast_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_cancel1_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_cancel2_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_cancel_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_isActive_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_repeat_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/timer_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/zone_bind_test: Fail # Timer interface not supported: Issue 7728.
-async/zone_create_periodic_timer_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/zone_create_timer2_test: RuntimeError # Timer interface not supported: Issue 7728.
-async/zone_empty_description2_test: RuntimeError # Timer interface not supported: Issue 7728.
[ $compiler == dart2js && $runtime == safari ]
html/callback_list_test: SkipByDesign # FileSystem not supported in Safari.
-html/css_test/functional/functional: RuntimeError # Issue 32576
-html/element_types_content_test: RuntimeError # Issue 29922
-html/element_types_datalist_test: RuntimeError # Issue 29922
-html/element_types_shadow_test: RuntimeError # Issue 29922
html/file_sample_test: Skip # FileSystem not supported on Safari.
html/fileapi_supported_throws_test: Skip # FileSystem not supported on Safari
html/interactive_media_test: SkipSlow
-html/notification_test: Pass, RuntimeError # Safari doesn't let us access the fields of the Notification to verify them.
-html/storage_promise_test: RuntimeError # Not supported on Safari
[ $compiler == dart2js && $system == linux ]
html/interactive_geolocation_test: Skip # Requires allowing geo location.
-[ $compiler == dart2js && $browser ]
-html/notification_permission_test: Timeout, Pass # Issue 32002
-js/null_test: RuntimeError # Issue 30652
-
-[ $compiler == dart2js && $browser && $csp ]
-html/custom/element_upgrade_test: Fail # Issue 17298
-html/custom/js_custom_test: Fail # Issue 14643
-
[ $compiler == dart2js && $checked ]
-convert/utf85_test: Pass, Slow # Issue 12029.
+convert/utf85_test: Slow # Issue 12029.
html/js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
[ $compiler == dart2js && $csp && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari) ]
@@ -198,101 +90,9 @@
html/mirrors_js_typed_interop_test: SkipByDesign
html/postmessage_structured_test: SkipByDesign
-[ $compiler == dart2js && !$csp && $minified ]
-html/audiobuffersourcenode_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/audiocontext_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/cache_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/custom_element_method_clash_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/custom_element_name_clash_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/custom_elements_23127_test: Crash # Assertion failure: Cannot find value local(B2T.created#a) in (type_variable_local(B2T.T), local(C2T.created#a), local(C2T.created#b), local(C2T.created#c), BoxLocal(_box_0)) for j:constructor(C2T.created).
-html/custom_tags_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/dart_object_local_storage_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/datalistelement_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/document_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/documentfragment_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/dom_constructors_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/domparser_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_add_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_animate_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_constructor_1_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_dimensions_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_offset_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_constructors2_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_constructors3_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_constructors4_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_constructors5_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_constructors6_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_content_test: RuntimeError # Issue 29922
-html/element_types_datalist_test: RuntimeError # Issue 29922
-html/element_types_details_test: RuntimeError # Issue 29922
-html/element_types_embed_test: RuntimeError # Issue 29922
-html/element_types_meter_test: RuntimeError # Issue 29922
-html/element_types_object_test: RuntimeError # Issue 29922
-html/element_types_output_test: RuntimeError # Issue 29922
-html/element_types_progress_test: RuntimeError # Issue 29922
-html/element_types_shadow_test: RuntimeError # Issue 29922
-html/element_types_template_test: RuntimeError # Issue 29922
-html/element_types_track_test: RuntimeError # Issue 29922
-html/form_data_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/history_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/indexeddb_1_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/keyboard_event_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/mediasource_test: RuntimeError, Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/mutationobserver_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/node_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/node_validator_important_if_you_suppress_make_the_bug_critical_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/notification_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/performance_api_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/range_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/request_animation_frame_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/rtc_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/shadow_dom_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/svg_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/svgelement_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/transition_event_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/trusted_html_tree_sanitizer_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/typed_arrays_1_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/webgl_extensions_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/websocket_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/websql_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-
-[ $compiler == dart2js && $host_checked ]
-html/custom/mirrors_2_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-html/custom/mirrors_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-html/indexeddb_3_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-html/indexeddb_5_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-html/js_function_getter_test/call getter as function: Crash # FileSystemException(uri=file:///usr/local/google/home/efortuna/dart2/sdk/sdk/lib/_internal/dart2js_platform.dill; message=Error reading 'sdk/lib/_internal/dart2js_platform.dill' (No such file or directory))
-html/js_typed_interop_side_cast_exp_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
-
-[ $compiler == dart2js && $ie ]
-html/fontface_loaded_test: RuntimeError # FontFace polyfill?
-html/fontface_test: Fail # Fontface not supported on ie
-
-[ $compiler == dart2js && $minified ]
-html/canvas_pixel_array_type_alias_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/canvas_pixel_array_type_alias_test/types2_runtimeTypeName: Fail, OK # Issue 12605
-html/custom/mirrors_2_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/custom/mirrors_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/custom_elements_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_classes_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/element_types_keygen_test: RuntimeError # Issue 29922
-html/js_function_getter_trust_types_test: Crash # NoSuchMethodError: Class 'InterfaceType' has no instance getter 'isObject'.
-html/js_typed_interop_bind_this_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/js_typed_interop_side_cast_exp_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/js_typed_interop_window_property_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/js_util_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/media_stream_test: RuntimeError, Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/postmessage_structured_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/speechrecognition_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-html/webgl_1_test: Crash # NoSuchMethodError: Class 'JMethod' has no instance getter 'implementation'.
-
[ $compiler == dart2js && ($runtime == chrome || $runtime == ff) ]
async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_json_utf8_decode_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
-[ $compiler == dart2js && ($runtime == ff || $runtime == safari || $ie) ]
-html/custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Polyfill does not support
-html/custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
diff --git a/tests/lib_2/wasm/fn_mismatch_error_test.dart b/tests/lib_2/wasm/fn_mismatch_error_test.dart
index 308a829..b12d515 100644
--- a/tests/lib_2/wasm/fn_mismatch_error_test.dart
+++ b/tests/lib_2/wasm/fn_mismatch_error_test.dart
@@ -34,4 +34,8 @@
() => inst.lookupFunction<Void Function(Int64)>("square"));
Expect.throwsArgumentError(
() => inst.lookupFunction<Void Function(dynamic)>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Int64 Function(Float)>("square"));
+ Expect.throwsArgumentError(
+ () => inst.lookupFunction<Float Function(Int64)>("square"));
}
diff --git a/tests/lib_2/wasm/memory_test.dart b/tests/lib_2/wasm/memory_test.dart
new file mode 100644
index 0000000..1160aca
--- /dev/null
+++ b/tests/lib_2/wasm/memory_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, 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.
+
+// Test that we can create a WasmMemory, edit it, and grow it.
+
+import "package:expect/expect.dart";
+import "dart:wasm";
+import "dart:typed_data";
+
+void main() {
+ var mem = WasmMemory(1000);
+ Expect.equals(1000, mem.lengthInPages);
+ Expect.equals(1000 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
+
+ mem[123] = 45;
+ Expect.equals(45, mem[123]);
+
+ mem.grow(100);
+ Expect.equals(1100, mem.lengthInPages);
+ Expect.equals(1100 * WasmMemory.kPageSizeInBytes, mem.lengthInBytes);
+ Expect.equals(45, mem[123]);
+}
diff --git a/tests/modular/extension_methods/def.dart b/tests/modular/extension_methods/def.dart
index 665da3d8..d58df3b4 100644
--- a/tests/modular/extension_methods/def.dart
+++ b/tests/modular/extension_methods/def.dart
@@ -11,6 +11,8 @@
extension Extension on Class {
int method() => this.field;
+ int methodWithOptionals([int a = 42]) => a;
+
int get property => this.field;
void set property(int value) {
diff --git a/tests/modular/extension_methods/main.dart b/tests/modular/extension_methods/main.dart
index 760cc85..cb18018 100644
--- a/tests/modular/extension_methods/main.dart
+++ b/tests/modular/extension_methods/main.dart
@@ -24,10 +24,15 @@
testImplicitAccess(Class c) {
Expect.equals(c.field, c.method());
+ Expect.equals(42, c.methodWithOptionals());
+ Expect.equals(123, c.methodWithOptionals(123));
Expect.equals(c.field, c.property);
Expect.equals(123, c.property = 123);
var f = c.method;
Expect.equals(c.field, f());
+ var f2 = c.methodWithOptionals;
+ Expect.equals(42, f2());
+ Expect.equals(87, f2(87));
}
testStaticAccess() {
diff --git a/tests/standalone_2/dwarf_stack_trace_test.dart b/tests/standalone_2/dwarf_stack_trace_test.dart
index 23a35ef..32a80bb 100644
--- a/tests/standalone_2/dwarf_stack_trace_test.dart
+++ b/tests/standalone_2/dwarf_stack_trace_test.dart
@@ -66,7 +66,7 @@
throw "'file' failed";
return;
}
- if (!result.stdout.contains("shared object")) {
+ if (!result.stdout.contains("Mach-O")) {
print("Skipping test because we are not running from a dylib");
return;
}
diff --git a/tools/VERSION b/tools/VERSION
index be73740..e6b0140 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
MAJOR 2
MINOR 6
PATCH 0
-PRERELEASE 2
+PRERELEASE 3
PRERELEASE_PATCH 0
ABI_VERSION 16
OLDEST_SUPPORTED_ABI_VERSION 16
diff --git a/tools/bots/aot_smoke_tests.dart b/tools/bots/aot_smoke_tests.dart
index bb92379..a035361 100755
--- a/tools/bots/aot_smoke_tests.dart
+++ b/tools/bots/aot_smoke_tests.dart
@@ -13,57 +13,120 @@
import 'dart:convert';
import 'package:args/args.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
-get_dart2aot() {
- if (Platform.isLinux) {
- return 'out/ReleaseX64/dart-sdk/bin/dart2aot';
- } else if (Platform.isMacOS) {
- return 'xcodebuild/ReleaseX64/dart-sdk/bin/dart2aot';
- } else if (Platform.isWindows) {
- return 'out\\ReleaseX64\\dart-sdk\\bin\\dart2aot.bat';
- } else {
- throw 'Unsupported host platform!';
+final String newline = Platform.isWindows ? '\r\n' : '\n';
+final String scriptSuffix = Platform.isWindows ? ".bat" : "";
+final String executableSuffix = Platform.isWindows ? ".exe" : "";
+final String sdkBinDir = path.dirname(Platform.executable);
+final String dart2aot = path.join(sdkBinDir, 'dart2aot${scriptSuffix}');
+final String dartaotruntime =
+ path.join(sdkBinDir, 'dartaotruntime${executableSuffix}');
+final String dart2native = path.join(sdkBinDir, 'dart2native${scriptSuffix}');
+
+Future<void> withTempDir(Future fun(String dir)) async {
+ final Directory tempDir = Directory.systemTemp.createTempSync();
+ try {
+ await fun(tempDir.path);
+ } finally {
+ tempDir.deleteSync(recursive: true);
}
}
-get_dartaotruntime() {
- if (Platform.isLinux) {
- return 'out/ReleaseX64/dart-sdk/bin/dartaotruntime';
- } else if (Platform.isMacOS) {
- return 'xcodebuild/ReleaseX64/dart-sdk/bin/dartaotruntime';
- } else if (Platform.isWindows) {
- return 'out\\ReleaseX64\\dart-sdk\\bin\\dartaotruntime.exe';
- } else {
- throw 'Unsupported host platform!';
- }
-}
+void main(List<String> args) {
+ test("dart2aot: Can compile and run AOT", () async {
+ await withTempDir((String tmp) async {
+ final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
+ final String tmpAot = path.join(tmp, 'dart_aot_test.dart.aot');
-assert_equals(var expected, var actual) {
- if (expected != actual) {
- print('Test failed! Expected \'$expected\', got \'$actual\'');
- exit(1);
- }
-}
+ {
+ final ProcessResult result =
+ await Process.run(dart2aot, [testCode, tmpAot]);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ expect(result.stdout, '');
+ }
-main(List<String> args) async {
- ProcessResult result;
+ {
+ const String testStr = 'Dart AOT';
+ final ProcessResult result =
+ await Process.run(dartaotruntime, [tmpAot, testStr]);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ expect(result.stdout, 'Hello, ${testStr}.${newline}');
+ }
+ });
+ });
- result = Process.runSync(get_dart2aot(),
- ['tools/bots/dart_aot_test.dart', 'tools/bots/dart_aot_test.dart.aot'],
- stdoutEncoding: utf8, stderrEncoding: utf8);
- stdout.write(result.stdout);
- if (result.exitCode != 0 || result.stderr != '') {
- stderr.write(result.stderr);
- exit(1);
- }
+ test("dart2native: Can compile and run AOT", () async {
+ await withTempDir((String tmp) async {
+ final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
+ final String tmpAot = path.join(tmp, 'dart_aot_test.dart.aot');
- result = Process.runSync(
- get_dartaotruntime(), ['tools/bots/dart_aot_test.dart.aot'],
- stdoutEncoding: utf8, stderrEncoding: utf8);
- if (result.exitCode != 0 || result.stderr != '') {
- stderr.write(result.stderr);
- exit(1);
- }
+ {
+ final ProcessResult result = await Process.run(dart2native,
+ [testCode, '--output', tmpAot, '--output-kind', 'aot']);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ }
- assert_equals('Hello, 世界.', result.stdout.trim());
+ {
+ const String testStr = 'Dart AOT';
+ final ProcessResult result =
+ await Process.run(dartaotruntime, [tmpAot, testStr]);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ expect(result.stdout, 'Hello, ${testStr}.${newline}');
+ }
+ });
+ });
+
+ test("dart2native: Can compile and run exe", () async {
+ await withTempDir((String tmp) async {
+ final String testCode = path.join('tools', 'bots', 'dart_aot_test.dart');
+ final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
+
+ {
+ final ProcessResult result =
+ await Process.run(dart2native, [testCode, '--output', tmpExe]);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ }
+
+ {
+ const String testStr = 'Dart AOT';
+ final ProcessResult result = await Process.run(tmpExe, [testStr]);
+ expect(result.stderr, '');
+ expect(result.exitCode, 0);
+ expect(result.stdout, 'Hello, ${testStr}.${newline}');
+ }
+ });
+ });
+
+ test("dart2native: Returns non-zero on missing file.", () async {
+ await withTempDir((String tmp) async {
+ final String testCode = path.join(tmp, 'does_not_exist.dart');
+ final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
+
+ {
+ final ProcessResult result =
+ await Process.run(dart2native, [testCode, '--output', tmpExe]);
+ expect(result.exitCode, isNonZero);
+ }
+ });
+ });
+
+ test("dart2native: Returns non-zero on non-file.", () async {
+ await withTempDir((String tmp) async {
+ final String testCode = tmp; // This is a directory, not a file.
+ final String tmpExe = path.join(tmp, 'dart_aot_test.exe');
+
+ {
+ final ProcessResult result =
+ await Process.run(dart2native, [testCode, '--output', tmpExe]);
+ expect(result.exitCode, isNonZero);
+ }
+ });
+ });
}
diff --git a/tools/bots/dart_aot_test.dart b/tools/bots/dart_aot_test.dart
index 0a626f4..36abe33 100755
--- a/tools/bots/dart_aot_test.dart
+++ b/tools/bots/dart_aot_test.dart
@@ -5,6 +5,7 @@
// Test program for Dart AOT (dart2aot, dartaotruntime).
-main(List<String> args) async {
- print('Hello, 世界.');
+void main(List<String> args) async {
+ final String who = !args.isEmpty ? args[0] : '世界';
+ print('Hello, ${who}.');
}
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index acd6fcf..aca2268 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -341,26 +341,26 @@
"use-elf": true
}},
"dartk-android-(debug|product|release)-(arm|arm64)": {},
- "dartkp-linux-(debug|product|release)-(simarm|simarm64)": {
+ "dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)": {
"options": {
"use-blobs": true
}},
- "dartkp-(win|mac)-(debug|product|release)-(simarm|simarm64)": {
+ "dartkp-linux-(debug|product|release)-(simarm|simarm64)-crossword": {
"options": {
- "use-blobs": true
+ "builder-tag": "crossword"
}},
- "dartkp-(linux|win|mac)-(debug|product|release)-(simarm|simarm64)-crossword": {
+ "dartkp-(win|mac)-(debug|product|release)-(simarm|simarm64)-crossword": {
"options": {
"builder-tag": "crossword",
"use-blobs": true
}},
"dartkp-win-(product|release)-x64": {
"options": {
- "use-blobs": true
+ "use-elf": true
}},
"dartkp-win-debug-x64": {
"options": {
- "use-blobs": true,
+ "use-elf": true,
"vm-options": ["--no-enable-malloc-hooks"]
}},
"dartkp-(linux|mac)-(product|release)-x64": { },
@@ -380,7 +380,7 @@
"dartkp-no-bare-(linux|mac|win)-(debug|product|release)-(simarm|simarm64)": {
"options": {
"vm-options": ["--no-enable-malloc-hooks", "--no-use-bare-instructions"],
- "use-blobs": true
+ "use-elf": true
}},
"dartk-(linux|mac|win)-(debug|product|release)-(ia32|x64)": { },
"dartk-checked-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {
@@ -1611,8 +1611,8 @@
"script": "tools/bots/dart_sdk.py"
},
{
- "name": "run smoke tests",
- "script": "out/ReleaseX64/dart",
+ "name": "run AOT and Exe smoke tests",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart",
"arguments": [
"tools/bots/aot_smoke_tests.dart"
]
@@ -1661,8 +1661,8 @@
"script": "tools/bots/dart_sdk.py"
},
{
- "name": "run smoke tests",
- "script": "xcodebuild/ReleaseX64/dart",
+ "name": "run AOT and Exe smoke tests",
+ "script": "xcodebuild/ReleaseX64/dart-sdk/bin/dart",
"arguments": [
"tools/bots/aot_smoke_tests.dart"
]
@@ -1698,8 +1698,8 @@
"script": "tools/bots/dart_sdk.py"
},
{
- "name": "run smoke tests",
- "script": "out/ReleaseX64/dart.exe",
+ "name": "run AOT and Exe smoke tests",
+ "script": "out/ReleaseX64/dart-sdk/bin/dart.exe",
"arguments": [
"tools/bots/aot_smoke_tests.dart"
]
@@ -2278,7 +2278,7 @@
},
{
"builders": [
- "vm-kernel-precomp-mac-debug-simarm_x64",
+ "vm-kernel-precomp-linux-debug-simarm_x64",
"vm-kernel-precomp-mac-release-simarm_x64"
],
"meta": {
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index e3c30d5..882e1d3 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -216,6 +216,8 @@
third_party/d8/linux/ia32/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
out/ReleaseIA32/dart-sdk/bin/dart2js --use-kernel --packages=.packages --out=out.js -m hello.dart
third_party/d8/linux/ia32/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
+ out/ReleaseIA32/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/ia32/d8 hello.dart
+ out/ReleaseIA32/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/ia32/d8 --kernel hello.dart
out/ReleaseIA32/dart pkg/front_end/tool/perf.dart parse hello.dart
out/ReleaseIA32/dart pkg/front_end/tool/perf.dart scan hello.dart
out/ReleaseIA32/dart pkg/front_end/tool/fasta_perf.dart kernel_gen_e2e hello.dart
@@ -395,6 +397,8 @@
out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter --compilation-counter-threshold=-1 hello.dart
out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler hello.dart
out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler --optimization-counter-threshold=-1 hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/ia32/d8 --mode=compile --compile-vm-options=--print-metrics --packages=.packages --out out.js hello.dart
+ out/ReleaseX64/dart-sdk/bin/dart pkg/dev_compiler/tool/ddb -r d8 -b third_party/d8/linux/ia32/d8 --mode=compile --compile-vm-options=--print-metrics --packages=.packages --out out.js --kernel hello.dart
out/ReleaseX64/dart pkg/front_end/tool/perf.dart parse hello.dart
out/ReleaseX64/dart pkg/front_end/tool/perf.dart scan hello.dart
out/ReleaseX64/dart pkg/front_end/tool/fasta_perf.dart kernel_gen_e2e hello.dart
diff --git a/tools/dom/src/CssRectangle.dart b/tools/dom/src/CssRectangle.dart
index b7967ec..ebe497a 100644
--- a/tools/dom/src/CssRectangle.dart
+++ b/tools/dom/src/CssRectangle.dart
@@ -238,7 +238,7 @@
// always dealing with pixels in this method.
var styles = _element.getComputedStyle();
- var val = 0;
+ num val = 0;
for (String measurement in dimensions) {
// The border-box and default box model both exclude margin in the regular
diff --git a/tools/dom/templates/html/dart2js/impl_RTCIceCandidate.darttemplate b/tools/dom/templates/html/dart2js/impl_RTCIceCandidate.darttemplate
index 06b5456..24cc438 100644
--- a/tools/dom/templates/html/dart2js/impl_RTCIceCandidate.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_RTCIceCandidate.darttemplate
@@ -6,12 +6,7 @@
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
factory $CLASSNAME(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS('', 'window[#]',
- Device.isFirefox ? '${Device.propertyPrefix}RTCIceCandidate' :
- 'RTCIceCandidate');
+ var constructorName = JS('', 'window[#]', 'RTCIceCandidate');
return JS('RtcIceCandidate', 'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
}
diff --git a/tools/dom/templates/html/dart2js/impl_RTCSessionDescription.darttemplate b/tools/dom/templates/html/dart2js/impl_RTCSessionDescription.darttemplate
index 9ca8ceb..fd57f16 100644
--- a/tools/dom/templates/html/dart2js/impl_RTCSessionDescription.darttemplate
+++ b/tools/dom/templates/html/dart2js/impl_RTCSessionDescription.darttemplate
@@ -6,12 +6,7 @@
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
factory $CLASSNAME(Map dictionary) {
- // TODO(efortuna): Remove this check if when you can actually construct with
- // the unprefixed RTCIceCandidate in Firefox (currently both are defined,
- // but one can't be used as a constructor).
- var constructorName = JS('', 'window[#]',
- Device.isFirefox ? '${Device.propertyPrefix}RTCSessionDescription' :
- 'RTCSessionDescription');
+ var constructorName = JS('', 'window[#]', 'RTCSessionDescription');
return JS('RtcSessionDescription',
'new #(#)', constructorName,
convertDartToNative_SerializedScriptValue(dictionary));
diff --git a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
index 868d215..4af23ea 100644
--- a/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
+++ b/tools/dom/templates/html/impl/impl_RTCPeerConnection.darttemplate
@@ -6,8 +6,8 @@
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
factory $CLASSNAME(Map rtcIceServers, [Map mediaConstraints]) {
- var constructorName = JS('RtcPeerConnection', 'window[#]',
- '${Device.propertyPrefix}RTCPeerConnection');
+ var constructorName =
+ JS('RtcPeerConnection', 'window[#]', 'RTCPeerConnection');
if (mediaConstraints != null) {
return JS('RtcPeerConnection', 'new #(#,#)', constructorName,
convertDartToNative_SerializedScriptValue(rtcIceServers),